aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1921
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs30
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs353
16 files changed, 1648 insertions, 873 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 30fb252..f5b7f5f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -81,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 82 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 84 {
84 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 86 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 87 protected SceneObjectPart m_host;
87 protected uint m_localID; 88 protected uint m_localID;
@@ -99,6 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 100 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 101 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 102 protected bool m_scriptConsoleChannelEnabled = false;
103 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 104 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 105 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 106 new Dictionary<UUID, UserInfoCacheEntry>();
@@ -109,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
109 m_host = host; 111 m_host = host;
110 m_localID = localID; 112 m_localID = localID;
111 m_itemID = itemID; 113 m_itemID = itemID;
114 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 115
113 m_ScriptDelayFactor = 116 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 117 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 164 get { return m_ScriptEngine.World; }
162 } 165 }
163 166
167 [DebuggerNonUserCode]
164 public void state(string newState) 168 public void state(string newState)
165 { 169 {
166 m_ScriptEngine.SetState(m_itemID, newState); 170 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 174 /// Reset the named script. The script must be present
171 /// in the same prim. 175 /// in the same prim.
172 /// </summary> 176 /// </summary>
177 [DebuggerNonUserCode]
173 public void llResetScript() 178 public void llResetScript()
174 { 179 {
175 m_host.AddScriptLPS(1); 180 m_host.AddScriptLPS(1);
@@ -226,9 +231,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 231 }
227 } 232 }
228 233
234 public List<ScenePresence> GetLinkAvatars(int linkType)
235 {
236 List<ScenePresence> ret = new List<ScenePresence>();
237 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
238 return ret;
239
240 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
241
242 switch (linkType)
243 {
244 case ScriptBaseClass.LINK_SET:
245 return avs;
246
247 case ScriptBaseClass.LINK_ROOT:
248 return ret;
249
250 case ScriptBaseClass.LINK_ALL_OTHERS:
251 return avs;
252
253 case ScriptBaseClass.LINK_ALL_CHILDREN:
254 return avs;
255
256 case ScriptBaseClass.LINK_THIS:
257 return ret;
258
259 default:
260 if (linkType < 0)
261 return ret;
262
263 int partCount = m_host.ParentGroup.GetPartCount();
264
265 if (linkType <= partCount)
266 {
267 return ret;
268 }
269 else
270 {
271 linkType = linkType - partCount;
272 if (linkType > avs.Count)
273 {
274 return ret;
275 }
276 else
277 {
278 ret.Add(avs[linkType-1]);
279 return ret;
280 }
281 }
282 }
283 }
284
229 public List<SceneObjectPart> GetLinkParts(int linkType) 285 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 286 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 287 List<SceneObjectPart> ret = new List<SceneObjectPart>();
288 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
289 return ret;
232 ret.Add(m_host); 290 ret.Add(m_host);
233 291
234 switch (linkType) 292 switch (linkType)
@@ -288,40 +346,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 346 protected UUID InventorySelf()
289 { 347 {
290 UUID invItemID = new UUID(); 348 UUID invItemID = new UUID();
291 349 bool unlock = false;
292 lock (m_host.TaskInventory) 350 if (!m_host.TaskInventory.IsReadLockedByMe())
351 {
352 m_host.TaskInventory.LockItemsForRead(true);
353 unlock = true;
354 }
355 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
293 { 356 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 357 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 358 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 359 invItemID = inv.Key;
297 { 360 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 361 }
302 } 362 }
303 363 if (unlock)
364 {
365 m_host.TaskInventory.LockItemsForRead(false);
366 }
304 return invItemID; 367 return invItemID;
305 } 368 }
306 369
307 protected UUID InventoryKey(string name, int type) 370 protected UUID InventoryKey(string name, int type)
308 { 371 {
309 m_host.AddScriptLPS(1); 372 m_host.AddScriptLPS(1);
310 373 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 374
375 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 376 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 377 if (inv.Value.Name == name)
314 { 378 {
315 if (inv.Value.Name == name) 379 m_host.TaskInventory.LockItemsForRead(false);
380
381 if (inv.Value.Type != type)
316 { 382 {
317 if (inv.Value.Type != type) 383 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 384 }
385
386 return inv.Value.AssetID;
322 } 387 }
323 } 388 }
324 389
390 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 391 return UUID.Zero;
326 } 392 }
327 393
@@ -329,17 +395,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 395 {
330 m_host.AddScriptLPS(1); 396 m_host.AddScriptLPS(1);
331 397
332 lock (m_host.TaskInventory) 398
399 m_host.TaskInventory.LockItemsForRead(true);
400
401 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 402 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 403 if (inv.Value.Name == name)
335 { 404 {
336 if (inv.Value.Name == name) 405 m_host.TaskInventory.LockItemsForRead(false);
337 { 406 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 407 }
341 } 408 }
342 409
410 m_host.TaskInventory.LockItemsForRead(false);
411
412
343 return UUID.Zero; 413 return UUID.Zero;
344 } 414 }
345 415
@@ -481,26 +551,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 551
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 552 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 553
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 554 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 555
556 // normalize an angle between -PI and PI (-180 to +180 degrees)
557 protected double NormalizeAngle(double angle)
558 {
559 if (angle > -Math.PI && angle < Math.PI)
560 return angle;
561
562 int numPis = (int)(Math.PI / angle);
563 double remainder = angle - Math.PI * numPis;
564 if (numPis % 2 == 1)
565 return Math.PI - angle;
566 return remainder;
567 }
486 568
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 569 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 570 {
489 m_host.AddScriptLPS(1); 571 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 572 LSL_Vector eul = new LSL_Vector();
491 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 573
492 double m = (t.x + t.y + t.z + t.s); 574 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 575 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 576 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 577 double sqz = q1.y*q1.y;
496 if (p > 0) 578 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
497 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 579 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 580 if (test > 0.4999*unit) { // singularity at north pole
499 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 581 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 582 eul.y = Math.PI/2;
501 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 583 eul.x = 0;
502 else 584 return eul;
503 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 585 }
586 if (test < -0.4999*unit) { // singularity at south pole
587 eul.z = -2 * Math.Atan2(q1.x,q1.s);
588 eul.y = -Math.PI/2;
589 eul.x = 0;
590 return eul;
591 }
592 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
593 eul.y = Math.Asin(2*test/unit);
594 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
595 return eul;
504 } 596 }
505 597
506 /* From wiki: 598 /* From wiki:
@@ -702,77 +794,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 794 {
703 //A and B should both be normalized 795 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 796 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 797 /* This method is more accurate than the SL one, and thus causes problems
706 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 798 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 799
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 800 double dotProduct = LSL_Vector.Dot(a, b);
709 { 801 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 802 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
711 } 803 double angle = Math.Acos(dotProduct / magProduct);
712 else 804 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
713 { 805 double s = Math.Sin(angle / 2);
714 a = LSL_Vector.Norm(a); 806
715 b = LSL_Vector.Norm(b); 807 double x = axis.x * s;
716 double dotProduct = LSL_Vector.Dot(a, b); 808 double y = axis.y * s;
717 // There are two degenerate cases possible. These are for vectors 180 or 809 double z = axis.z * s;
718 // 0 degrees apart. These have to be detected and handled individually. 810 double w = Math.Cos(angle / 2);
719 // 811
720 // Check for vectors 180 degrees apart. 812 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
721 // A dot product of -1 would mean the angle between vectors is 180 degrees. 813 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
722 if (dotProduct < -0.9999999f) 814
723 { 815 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
724 // First assume X axis is orthogonal to the vectors. 816 */
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 817
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 818 // This method mimics the 180 errors found in SL
727 // Check for near zero vector. A very small non-zero number here will create 819 // See www.euclideanspace.com... angleBetween
728 // a rotation in an undesired direction. 820 LSL_Vector vec_a = a;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 821 LSL_Vector vec_b = b;
730 { 822
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 823 // Eliminate zero length
732 } 824 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
733 // If the magnitude of the vector was near zero, then assume the X axis is not 825 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
734 // orthogonal and use the Z axis instead. 826 if (vec_a_mag < 0.00001 ||
735 else 827 vec_b_mag < 0.00001)
736 { 828 {
737 // Set 180 z rotation. 829 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
738 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 830 }
739 } 831
740 } 832 // Normalize
741 // Check for parallel vectors. 833 vec_a = llVecNorm(vec_a);
742 // A dot product of 1 would mean the angle between vectors is 0 degrees. 834 vec_b = llVecNorm(vec_b);
743 else if (dotProduct > 0.9999999f) 835
744 { 836 // Calculate axis and rotation angle
745 // Set zero rotation. 837 LSL_Vector axis = vec_a % vec_b;
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 838 LSL_Float cos_theta = vec_a * vec_b;
747 } 839
748 else 840 // Check if parallel
749 { 841 if (cos_theta > 0.99999)
750 // All special checks have been performed so get the axis of rotation. 842 {
751 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
752 // Quarternion s value is the length of the unit vector + dot product. 844 }
753 double qs = 1.0 + dotProduct; 845
754 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 846 // Check if anti-parallel
755 // Normalize the rotation. 847 else if (cos_theta < -0.99999)
756 double mag = LSL_Rotation.Mag(rotBetween); 848 {
757 // We shouldn't have to worry about a divide by zero here. The qs value will be 849 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
758 // non-zero because we already know if we're here, then the dotProduct is not -1 so 850 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
759 // qs will not be zero. Also, we've already handled the input vectors being zero so the 851 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
760 // crossProduct vector should also not be zero. 852 }
761 rotBetween.x = rotBetween.x / mag; 853 else // other rotation
762 rotBetween.y = rotBetween.y / mag; 854 {
763 rotBetween.z = rotBetween.z / mag; 855 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
764 rotBetween.s = rotBetween.s / mag; 856 axis = llVecNorm(axis);
765 // Check for undefined values and set zero rotation if any found. This code might not actually be required 857 double x, y, z, s, t;
766 // any longer since zero vectors are checked for at the top. 858 s = Math.Cos(theta);
767 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 859 t = Math.Sin(theta);
768 { 860 x = axis.x * t;
769 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 861 y = axis.y * t;
770 } 862 z = axis.z * t;
771 } 863 return new LSL_Rotation(x,y,z,s);
772 } 864 }
773 return rotBetween; 865 }
774 } 866
775
776 public void llWhisper(int channelID, string text) 867 public void llWhisper(int channelID, string text)
777 { 868 {
778 m_host.AddScriptLPS(1); 869 m_host.AddScriptLPS(1);
@@ -1096,10 +1187,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1187 return detectedParams.TouchUV;
1097 } 1188 }
1098 1189
1190 [DebuggerNonUserCode]
1099 public virtual void llDie() 1191 public virtual void llDie()
1100 { 1192 {
1101 m_host.AddScriptLPS(1); 1193 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1194 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1195 }
1104 1196
1105 public LSL_Float llGround(LSL_Vector offset) 1197 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1264,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1264
1173 public void llSetStatus(int status, int value) 1265 public void llSetStatus(int status, int value)
1174 { 1266 {
1267 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1268 return;
1175 m_host.AddScriptLPS(1); 1269 m_host.AddScriptLPS(1);
1176 1270
1177 int statusrotationaxis = 0; 1271 int statusrotationaxis = 0;
@@ -1402,6 +1496,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1496 {
1403 m_host.AddScriptLPS(1); 1497 m_host.AddScriptLPS(1);
1404 1498
1499 SetColor(m_host, color, face);
1500 }
1501
1502 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1503 {
1504 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1505 return;
1506
1507 Primitive.TextureEntry tex = part.Shape.Textures;
1508 Color4 texcolor;
1509 if (face >= 0 && face < GetNumberOfSides(part))
1510 {
1511 texcolor = tex.CreateFace((uint)face).RGBA;
1512 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1513 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1514 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1515 tex.FaceTextures[face].RGBA = texcolor;
1516 part.UpdateTexture(tex);
1517 return;
1518 }
1519 else if (face == ScriptBaseClass.ALL_SIDES)
1520 {
1521 for (uint i = 0; i < GetNumberOfSides(part); i++)
1522 {
1523 if (tex.FaceTextures[i] != null)
1524 {
1525 texcolor = tex.FaceTextures[i].RGBA;
1526 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1527 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1528 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1529 tex.FaceTextures[i].RGBA = texcolor;
1530 }
1531 texcolor = tex.DefaultTexture.RGBA;
1532 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1533 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1534 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1535 tex.DefaultTexture.RGBA = texcolor;
1536 }
1537 part.UpdateTexture(tex);
1538 return;
1539 }
1540
1405 if (face == ScriptBaseClass.ALL_SIDES) 1541 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1542 face = SceneObjectPart.ALL_SIDES;
1407 1543
@@ -1410,6 +1546,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1546
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1547 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1548 {
1549 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1550 return;
1551
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1552 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1553 MappingType textype;
1415 textype = MappingType.Default; 1554 textype = MappingType.Default;
@@ -1440,6 +1579,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1579
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1580 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1581 {
1582 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1583 return;
1584
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1585 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1586 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1587 {
@@ -1465,6 +1607,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1607
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1608 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1609 {
1610 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1611 return;
1468 1612
1469 Shininess sval = new Shininess(); 1613 Shininess sval = new Shininess();
1470 1614
@@ -1515,6 +1659,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1659
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1660 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1661 {
1662 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1663 return;
1664
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1665 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1666 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1667 {
@@ -1575,13 +1722,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1722 m_host.AddScriptLPS(1);
1576 1723
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1724 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1725 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1726 {
1580 SetAlpha(part, alpha, face); 1727 try
1728 {
1729 parts[0].ParentGroup.areUpdatesSuspended = true;
1730 foreach (SceneObjectPart part in parts)
1731 SetAlpha(part, alpha, face);
1732 }
1733 finally
1734 {
1735 parts[0].ParentGroup.areUpdatesSuspended = false;
1736 }
1737 }
1581 } 1738 }
1582 1739
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1740 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1741 {
1742 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1743 return;
1744
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1745 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1746 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1747 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1787 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1788 float wind, float tension, LSL_Vector Force)
1629 { 1789 {
1630 if (part == null) 1790 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1791 return;
1632 1792
1633 if (flexi) 1793 if (flexi)
@@ -1662,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1822 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1823 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1824 {
1665 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1826 return;
1667 1827
1668 if (light) 1828 if (light)
@@ -1739,15 +1899,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1899 m_host.AddScriptLPS(1);
1740 1900
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1901 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1902 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1903 {
1744 SetTexture(part, texture, face); 1904 try
1745 1905 {
1906 parts[0].ParentGroup.areUpdatesSuspended = true;
1907 foreach (SceneObjectPart part in parts)
1908 SetTexture(part, texture, face);
1909 }
1910 finally
1911 {
1912 parts[0].ParentGroup.areUpdatesSuspended = false;
1913 }
1914 }
1746 ScriptSleep(200); 1915 ScriptSleep(200);
1747 } 1916 }
1748 1917
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1918 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1919 {
1920 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1921 return;
1922
1751 UUID textureID=new UUID(); 1923 UUID textureID=new UUID();
1752 1924
1753 if (!UUID.TryParse(texture, out textureID)) 1925 if (!UUID.TryParse(texture, out textureID))
@@ -1793,6 +1965,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1793 1965
1794 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1966 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1795 { 1967 {
1968 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1969 return;
1970
1796 Primitive.TextureEntry tex = part.Shape.Textures; 1971 Primitive.TextureEntry tex = part.Shape.Textures;
1797 if (face >= 0 && face < GetNumberOfSides(part)) 1972 if (face >= 0 && face < GetNumberOfSides(part))
1798 { 1973 {
@@ -1829,6 +2004,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1829 2004
1830 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2005 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1831 { 2006 {
2007 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2008 return;
2009
1832 Primitive.TextureEntry tex = part.Shape.Textures; 2010 Primitive.TextureEntry tex = part.Shape.Textures;
1833 if (face >= 0 && face < GetNumberOfSides(part)) 2011 if (face >= 0 && face < GetNumberOfSides(part))
1834 { 2012 {
@@ -1865,6 +2043,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1865 2043
1866 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2044 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1867 { 2045 {
2046 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2047 return;
2048
1868 Primitive.TextureEntry tex = part.Shape.Textures; 2049 Primitive.TextureEntry tex = part.Shape.Textures;
1869 if (face >= 0 && face < GetNumberOfSides(part)) 2050 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2051 {
@@ -1935,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1935 2116
1936 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2117 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1937 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1938 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2122 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1939 LSL_Vector currentPos = GetPartLocalPos(part); 2123 LSL_Vector currentPos = GetPartLocalPos(part);
1940 2124
@@ -1951,7 +2135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1951 } 2135 }
1952 else 2136 else
1953 { 2137 {
1954 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2138 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1955 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2139 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1956 SceneObjectGroup parent = part.ParentGroup; 2140 SceneObjectGroup parent = part.ParentGroup;
1957 parent.HasGroupChanged = true; 2141 parent.HasGroupChanged = true;
@@ -2003,9 +2187,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2003 m_host.AddScriptLPS(1); 2187 m_host.AddScriptLPS(1);
2004 2188
2005 // try to let this work as in SL... 2189 // try to let this work as in SL...
2006 if (m_host.ParentID == 0) 2190 if (m_host.LinkNum < 2)
2007 { 2191 {
2008 // special case: If we are root, rotate complete SOG to new rotation 2192 // Special case: If we are root, rotate complete SOG to new
2193 // rotation.
2194 // We are root if the link number is 0 (single prim) or 1
2195 // (root prim). ParentID may be nonzero in attachments and
2196 // using it would cause attachments and HUDs to rotate
2197 // to the wrong positions.
2009 SetRot(m_host, Rot2Quaternion(rot)); 2198 SetRot(m_host, Rot2Quaternion(rot));
2010 } 2199 }
2011 else 2200 else
@@ -2034,6 +2223,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2034 2223
2035 protected void SetRot(SceneObjectPart part, Quaternion rot) 2224 protected void SetRot(SceneObjectPart part, Quaternion rot)
2036 { 2225 {
2226 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2227 return;
2228
2037 part.UpdateRotation(rot); 2229 part.UpdateRotation(rot);
2038 // Update rotation does not move the object in the physics scene if it's a linkset. 2230 // Update rotation does not move the object in the physics scene if it's a linkset.
2039 2231
@@ -2653,12 +2845,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2653 2845
2654 m_host.AddScriptLPS(1); 2846 m_host.AddScriptLPS(1);
2655 2847
2848 m_host.TaskInventory.LockItemsForRead(true);
2656 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2849 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2657 2850 m_host.TaskInventory.LockItemsForRead(false);
2658 lock (m_host.TaskInventory)
2659 {
2660 item = m_host.TaskInventory[invItemID];
2661 }
2662 2851
2663 if (item.PermsGranter == UUID.Zero) 2852 if (item.PermsGranter == UUID.Zero)
2664 return 0; 2853 return 0;
@@ -2733,6 +2922,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2733 if (dist > m_ScriptDistanceFactor * 10.0f) 2922 if (dist > m_ScriptDistanceFactor * 10.0f)
2734 return; 2923 return;
2735 2924
2925 //Clone is thread-safe
2736 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2926 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2737 2927
2738 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2795,6 +2985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2795 2985
2796 public void llLookAt(LSL_Vector target, double strength, double damping) 2986 public void llLookAt(LSL_Vector target, double strength, double damping)
2797 { 2987 {
2988 /*
2798 m_host.AddScriptLPS(1); 2989 m_host.AddScriptLPS(1);
2799 // Determine where we are looking from 2990 // Determine where we are looking from
2800 LSL_Vector from = llGetPos(); 2991 LSL_Vector from = llGetPos();
@@ -2814,10 +3005,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2814 // the angles of rotation in radians into rotation value 3005 // the angles of rotation in radians into rotation value
2815 3006
2816 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3007 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2817 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3008
2818 m_host.startLookAt(rotation, (float)damping, (float)strength); 3009 // This would only work if your physics system contains an APID controller:
3010 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3011 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3012
2819 // Orient the object to the angle calculated 3013 // Orient the object to the angle calculated
2820 //llSetRot(rot); 3014 llSetRot(rot);
3015 */
3016
3017 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3018 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3019 // http://bugs.meta7.com/view.php?id=28
3020 // - Tom
3021
3022 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
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 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3027 {
3028 // Part is non-phys, convert this to a llSetRot()
3029 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3030 Vector3 dir = tgt - m_host.GroupPosition;
3031 dir.Normalize();
3032 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3033 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3034 float terot = (float)Math.Atan2(-dir.Z, txy);
3035 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3036 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3037 LSL_Types.Quaternion spin = llEuler2Rot(az);
3038 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3039 llSetRot(rot);
3040 }
3041 else
3042 {
3043 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3044 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3045 m_host.RotLookAt(q, (float)strength, (float)damping);
3046 }
3047
3048 }
3049
3050 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3051 {
3052 m_host.AddScriptLPS(1);
3053// NotImplemented("llRotLookAt");
3054 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3055
2821 } 3056 }
2822 3057
2823 public void llStopLookAt() 3058 public void llStopLookAt()
@@ -2866,13 +3101,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2866 { 3101 {
2867 TaskInventoryItem item; 3102 TaskInventoryItem item;
2868 3103
2869 lock (m_host.TaskInventory) 3104 m_host.TaskInventory.LockItemsForRead(true);
3105 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2870 { 3106 {
2871 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3107 m_host.TaskInventory.LockItemsForRead(false);
2872 return; 3108 return;
2873 else
2874 item = m_host.TaskInventory[InventorySelf()];
2875 } 3109 }
3110 else
3111 {
3112 item = m_host.TaskInventory[InventorySelf()];
3113 }
3114 m_host.TaskInventory.LockItemsForRead(false);
2876 3115
2877 if (item.PermsGranter != UUID.Zero) 3116 if (item.PermsGranter != UUID.Zero)
2878 { 3117 {
@@ -2894,13 +3133,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2894 { 3133 {
2895 TaskInventoryItem item; 3134 TaskInventoryItem item;
2896 3135
3136 m_host.TaskInventory.LockItemsForRead(true);
2897 lock (m_host.TaskInventory) 3137 lock (m_host.TaskInventory)
2898 { 3138 {
3139
2899 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3140 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3141 {
3142 m_host.TaskInventory.LockItemsForRead(false);
2900 return; 3143 return;
3144 }
2901 else 3145 else
3146 {
2902 item = m_host.TaskInventory[InventorySelf()]; 3147 item = m_host.TaskInventory[InventorySelf()];
3148 }
2903 } 3149 }
3150 m_host.TaskInventory.LockItemsForRead(false);
2904 3151
2905 m_host.AddScriptLPS(1); 3152 m_host.AddScriptLPS(1);
2906 3153
@@ -2932,19 +3179,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 { 3179 {
2933 m_host.AddScriptLPS(1); 3180 m_host.AddScriptLPS(1);
2934 3181
2935 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2936 return;
2937
2938 TaskInventoryItem item; 3182 TaskInventoryItem item;
2939 3183
2940 lock (m_host.TaskInventory) 3184 m_host.TaskInventory.LockItemsForRead(true);
3185
3186 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2941 { 3187 {
2942 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3188 m_host.TaskInventory.LockItemsForRead(false);
2943 return; 3189 return;
2944 else 3190 }
2945 item = m_host.TaskInventory[InventorySelf()]; 3191 else
3192 {
3193 item = m_host.TaskInventory[InventorySelf()];
2946 } 3194 }
2947 3195
3196 m_host.TaskInventory.LockItemsForRead(false);
3197
2948 if (item.PermsGranter != m_host.OwnerID) 3198 if (item.PermsGranter != m_host.OwnerID)
2949 return; 3199 return;
2950 3200
@@ -2954,10 +3204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2954 3204
2955 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3205 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2956 3206
2957 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3207 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2958 if (attachmentsModule != null)
2959 attachmentsModule.AttachObject(presence.ControllingClient,
2960 grp, (uint)attachment, false);
2961 } 3208 }
2962 } 3209 }
2963 3210
@@ -2970,13 +3217,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2970 3217
2971 TaskInventoryItem item; 3218 TaskInventoryItem item;
2972 3219
2973 lock (m_host.TaskInventory) 3220 m_host.TaskInventory.LockItemsForRead(true);
3221
3222 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2974 { 3223 {
2975 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3224 m_host.TaskInventory.LockItemsForRead(false);
2976 return; 3225 return;
2977 else 3226 }
2978 item = m_host.TaskInventory[InventorySelf()]; 3227 else
3228 {
3229 item = m_host.TaskInventory[InventorySelf()];
2979 } 3230 }
3231 m_host.TaskInventory.LockItemsForRead(false);
3232
2980 3233
2981 if (item.PermsGranter != m_host.OwnerID) 3234 if (item.PermsGranter != m_host.OwnerID)
2982 return; 3235 return;
@@ -3023,6 +3276,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3023 3276
3024 public void llInstantMessage(string user, string message) 3277 public void llInstantMessage(string user, string message)
3025 { 3278 {
3279 UUID result;
3280 if (!UUID.TryParse(user, out result))
3281 {
3282 ShoutError("An invalid key was passed to llInstantMessage");
3283 ScriptSleep(2000);
3284 return;
3285 }
3286
3287
3026 m_host.AddScriptLPS(1); 3288 m_host.AddScriptLPS(1);
3027 3289
3028 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3290 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3037,14 +3299,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 UUID friendTransactionID = UUID.Random(); 3299 UUID friendTransactionID = UUID.Random();
3038 3300
3039 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3301 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3040 3302
3041 GridInstantMessage msg = new GridInstantMessage(); 3303 GridInstantMessage msg = new GridInstantMessage();
3042 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3304 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3043 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3305 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3044 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3306 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3045// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3307// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3046// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3308// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3047 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3309// DateTime dt = DateTime.UtcNow;
3310//
3311// // Ticks from UtcNow, but make it look like local. Evil, huh?
3312// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3313//
3314// try
3315// {
3316// // Convert that to the PST timezone
3317// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3318// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3319// }
3320// catch
3321// {
3322// // No logging here, as it could be VERY spammy
3323// }
3324//
3325// // And make it look local again to fool the unix time util
3326// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3327
3328 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3329
3048 //if (client != null) 3330 //if (client != null)
3049 //{ 3331 //{
3050 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3332 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3058,13 +3340,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3058 msg.message = message.Substring(0, 1024); 3340 msg.message = message.Substring(0, 1024);
3059 else 3341 else
3060 msg.message = message; 3342 msg.message = message;
3061 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3343 msg.dialog = (byte)19; // MessageFromObject
3062 msg.fromGroup = false;// fromGroup; 3344 msg.fromGroup = false;// fromGroup;
3063 msg.offline = (byte)0; //offline; 3345 msg.offline = (byte)0; //offline;
3064 msg.ParentEstateID = 0; //ParentEstateID; 3346 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3065 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3347 msg.Position = new Vector3(m_host.AbsolutePosition);
3066 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3348 msg.RegionID = World.RegionInfo.RegionID.Guid;
3067 msg.binaryBucket = new byte[0];// binaryBucket; 3349 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3068 3350
3069 if (m_TransferModule != null) 3351 if (m_TransferModule != null)
3070 { 3352 {
@@ -3084,7 +3366,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3084 } 3366 }
3085 3367
3086 emailModule.SendEmail(m_host.UUID, address, subject, message); 3368 emailModule.SendEmail(m_host.UUID, address, subject, message);
3087 ScriptSleep(20000); 3369 ScriptSleep(15000);
3088 } 3370 }
3089 3371
3090 public void llGetNextEmail(string address, string subject) 3372 public void llGetNextEmail(string address, string subject)
@@ -3186,13 +3468,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3186 m_host.AddScriptLPS(1); 3468 m_host.AddScriptLPS(1);
3187 } 3469 }
3188 3470
3189 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3190 {
3191 m_host.AddScriptLPS(1);
3192 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3193 m_host.RotLookAt(rot, (float)strength, (float)damping);
3194 }
3195
3196 public LSL_Integer llStringLength(string str) 3471 public LSL_Integer llStringLength(string str)
3197 { 3472 {
3198 m_host.AddScriptLPS(1); 3473 m_host.AddScriptLPS(1);
@@ -3216,14 +3491,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3216 3491
3217 TaskInventoryItem item; 3492 TaskInventoryItem item;
3218 3493
3219 lock (m_host.TaskInventory) 3494 m_host.TaskInventory.LockItemsForRead(true);
3495 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3220 { 3496 {
3221 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3497 m_host.TaskInventory.LockItemsForRead(false);
3222 return; 3498 return;
3223 else
3224 item = m_host.TaskInventory[InventorySelf()];
3225 } 3499 }
3226 3500 else
3501 {
3502 item = m_host.TaskInventory[InventorySelf()];
3503 }
3504 m_host.TaskInventory.LockItemsForRead(false);
3227 if (item.PermsGranter == UUID.Zero) 3505 if (item.PermsGranter == UUID.Zero)
3228 return; 3506 return;
3229 3507
@@ -3253,13 +3531,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3253 3531
3254 TaskInventoryItem item; 3532 TaskInventoryItem item;
3255 3533
3256 lock (m_host.TaskInventory) 3534 m_host.TaskInventory.LockItemsForRead(true);
3535 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3257 { 3536 {
3258 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3537 m_host.TaskInventory.LockItemsForRead(false);
3259 return; 3538 return;
3260 else
3261 item = m_host.TaskInventory[InventorySelf()];
3262 } 3539 }
3540 else
3541 {
3542 item = m_host.TaskInventory[InventorySelf()];
3543 }
3544 m_host.TaskInventory.LockItemsForRead(false);
3545
3263 3546
3264 if (item.PermsGranter == UUID.Zero) 3547 if (item.PermsGranter == UUID.Zero)
3265 return; 3548 return;
@@ -3330,10 +3613,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3330 3613
3331 TaskInventoryItem item; 3614 TaskInventoryItem item;
3332 3615
3333 lock (m_host.TaskInventory) 3616
3617 m_host.TaskInventory.LockItemsForRead(true);
3618 if (!m_host.TaskInventory.ContainsKey(invItemID))
3619 {
3620 m_host.TaskInventory.LockItemsForRead(false);
3621 return;
3622 }
3623 else
3334 { 3624 {
3335 item = m_host.TaskInventory[invItemID]; 3625 item = m_host.TaskInventory[invItemID];
3336 } 3626 }
3627 m_host.TaskInventory.LockItemsForRead(false);
3337 3628
3338 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3629 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3339 { 3630 {
@@ -3365,11 +3656,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3365 3656
3366 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3657 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3367 { 3658 {
3368 lock (m_host.TaskInventory) 3659 m_host.TaskInventory.LockItemsForWrite(true);
3369 { 3660 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3370 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3661 m_host.TaskInventory[invItemID].PermsMask = perm;
3371 m_host.TaskInventory[invItemID].PermsMask = perm; 3662 m_host.TaskInventory.LockItemsForWrite(false);
3372 }
3373 3663
3374 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3664 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3375 "run_time_permissions", new Object[] { 3665 "run_time_permissions", new Object[] {
@@ -3389,11 +3679,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3679
3390 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3680 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3391 { 3681 {
3392 lock (m_host.TaskInventory) 3682 m_host.TaskInventory.LockItemsForWrite(true);
3393 { 3683 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3394 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3684 m_host.TaskInventory[invItemID].PermsMask = perm;
3395 m_host.TaskInventory[invItemID].PermsMask = perm; 3685 m_host.TaskInventory.LockItemsForWrite(false);
3396 }
3397 3686
3398 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3687 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3399 "run_time_permissions", new Object[] { 3688 "run_time_permissions", new Object[] {
@@ -3414,11 +3703,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3414 3703
3415 if (!m_waitingForScriptAnswer) 3704 if (!m_waitingForScriptAnswer)
3416 { 3705 {
3417 lock (m_host.TaskInventory) 3706 m_host.TaskInventory.LockItemsForWrite(true);
3418 { 3707 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3419 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3708 m_host.TaskInventory[invItemID].PermsMask = 0;
3420 m_host.TaskInventory[invItemID].PermsMask = 0; 3709 m_host.TaskInventory.LockItemsForWrite(false);
3421 }
3422 3710
3423 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3711 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3424 m_waitingForScriptAnswer=true; 3712 m_waitingForScriptAnswer=true;
@@ -3453,10 +3741,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3453 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3741 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3454 llReleaseControls(); 3742 llReleaseControls();
3455 3743
3456 lock (m_host.TaskInventory) 3744
3457 { 3745 m_host.TaskInventory.LockItemsForWrite(true);
3458 m_host.TaskInventory[invItemID].PermsMask = answer; 3746 m_host.TaskInventory[invItemID].PermsMask = answer;
3459 } 3747 m_host.TaskInventory.LockItemsForWrite(false);
3748
3460 3749
3461 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3750 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3462 "run_time_permissions", new Object[] { 3751 "run_time_permissions", new Object[] {
@@ -3468,16 +3757,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3468 { 3757 {
3469 m_host.AddScriptLPS(1); 3758 m_host.AddScriptLPS(1);
3470 3759
3471 lock (m_host.TaskInventory) 3760 m_host.TaskInventory.LockItemsForRead(true);
3761
3762 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3472 { 3763 {
3473 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3764 if (item.Type == 10 && item.ItemID == m_itemID)
3474 { 3765 {
3475 if (item.Type == 10 && item.ItemID == m_itemID) 3766 m_host.TaskInventory.LockItemsForRead(false);
3476 { 3767 return item.PermsGranter.ToString();
3477 return item.PermsGranter.ToString();
3478 }
3479 } 3768 }
3480 } 3769 }
3770 m_host.TaskInventory.LockItemsForRead(false);
3481 3771
3482 return UUID.Zero.ToString(); 3772 return UUID.Zero.ToString();
3483 } 3773 }
@@ -3486,19 +3776,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3486 { 3776 {
3487 m_host.AddScriptLPS(1); 3777 m_host.AddScriptLPS(1);
3488 3778
3489 lock (m_host.TaskInventory) 3779 m_host.TaskInventory.LockItemsForRead(true);
3780
3781 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3490 { 3782 {
3491 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3783 if (item.Type == 10 && item.ItemID == m_itemID)
3492 { 3784 {
3493 if (item.Type == 10 && item.ItemID == m_itemID) 3785 int perms = item.PermsMask;
3494 { 3786 if (m_automaticLinkPermission)
3495 int perms = item.PermsMask; 3787 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3496 if (m_automaticLinkPermission) 3788 m_host.TaskInventory.LockItemsForRead(false);
3497 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3789 return perms;
3498 return perms;
3499 }
3500 } 3790 }
3501 } 3791 }
3792 m_host.TaskInventory.LockItemsForRead(false);
3502 3793
3503 return 0; 3794 return 0;
3504 } 3795 }
@@ -3520,9 +3811,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3520 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3811 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3521 { 3812 {
3522 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3813 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3523 3814 if (parts.Count > 0)
3524 foreach (SceneObjectPart part in parts) 3815 {
3525 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3816 try
3817 {
3818 parts[0].ParentGroup.areUpdatesSuspended = true;
3819 foreach (SceneObjectPart part in parts)
3820 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3821 }
3822 finally
3823 {
3824 parts[0].ParentGroup.areUpdatesSuspended = false;
3825 }
3826 }
3526 } 3827 }
3527 3828
3528 public void llCreateLink(string target, int parent) 3829 public void llCreateLink(string target, int parent)
@@ -3535,11 +3836,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3535 return; 3836 return;
3536 3837
3537 TaskInventoryItem item; 3838 TaskInventoryItem item;
3538 lock (m_host.TaskInventory) 3839 m_host.TaskInventory.LockItemsForRead(true);
3539 { 3840 item = m_host.TaskInventory[invItemID];
3540 item = m_host.TaskInventory[invItemID]; 3841 m_host.TaskInventory.LockItemsForRead(false);
3541 } 3842
3542
3543 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3843 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3544 && !m_automaticLinkPermission) 3844 && !m_automaticLinkPermission)
3545 { 3845 {
@@ -3560,7 +3860,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3560 3860
3561 if (targetPart != null) 3861 if (targetPart != null)
3562 { 3862 {
3563 if (parent != 0) { 3863 if (parent != 0)
3864 {
3564 parentPrim = m_host.ParentGroup; 3865 parentPrim = m_host.ParentGroup;
3565 childPrim = targetPart.ParentGroup; 3866 childPrim = targetPart.ParentGroup;
3566 } 3867 }
@@ -3592,16 +3893,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3592 m_host.AddScriptLPS(1); 3893 m_host.AddScriptLPS(1);
3593 UUID invItemID = InventorySelf(); 3894 UUID invItemID = InventorySelf();
3594 3895
3595 lock (m_host.TaskInventory) 3896 m_host.TaskInventory.LockItemsForRead(true);
3596 {
3597 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3897 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3598 && !m_automaticLinkPermission) 3898 && !m_automaticLinkPermission)
3599 { 3899 {
3600 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3900 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3901 m_host.TaskInventory.LockItemsForRead(false);
3601 return; 3902 return;
3602 } 3903 }
3603 } 3904 m_host.TaskInventory.LockItemsForRead(false);
3604 3905
3605 if (linknum < ScriptBaseClass.LINK_THIS) 3906 if (linknum < ScriptBaseClass.LINK_THIS)
3606 return; 3907 return;
3607 3908
@@ -3640,10 +3941,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3640 // Restructuring Multiple Prims. 3941 // Restructuring Multiple Prims.
3641 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3942 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3642 parts.Remove(parentPrim.RootPart); 3943 parts.Remove(parentPrim.RootPart);
3643 foreach (SceneObjectPart part in parts) 3944 if (parts.Count > 0)
3644 { 3945 {
3645 parentPrim.DelinkFromGroup(part.LocalId, true); 3946 try
3947 {
3948 parts[0].ParentGroup.areUpdatesSuspended = true;
3949 foreach (SceneObjectPart part in parts)
3950 {
3951 parentPrim.DelinkFromGroup(part.LocalId, true);
3952 }
3953 }
3954 finally
3955 {
3956 parts[0].ParentGroup.areUpdatesSuspended = false;
3957 }
3646 } 3958 }
3959
3647 parentPrim.HasGroupChanged = true; 3960 parentPrim.HasGroupChanged = true;
3648 parentPrim.ScheduleGroupForFullUpdate(); 3961 parentPrim.ScheduleGroupForFullUpdate();
3649 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3962 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3652,11 +3965,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3652 { 3965 {
3653 SceneObjectPart newRoot = parts[0]; 3966 SceneObjectPart newRoot = parts[0];
3654 parts.Remove(newRoot); 3967 parts.Remove(newRoot);
3655 foreach (SceneObjectPart part in parts) 3968
3969 try
3656 { 3970 {
3657 part.UpdateFlag = 0; 3971 parts[0].ParentGroup.areUpdatesSuspended = true;
3658 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3972 foreach (SceneObjectPart part in parts)
3973 {
3974 part.UpdateFlag = 0;
3975 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3976 }
3659 } 3977 }
3978 finally
3979 {
3980 parts[0].ParentGroup.areUpdatesSuspended = false;
3981 }
3982
3983
3660 newRoot.ParentGroup.HasGroupChanged = true; 3984 newRoot.ParentGroup.HasGroupChanged = true;
3661 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3985 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3662 } 3986 }
@@ -3702,6 +4026,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3702 } 4026 }
3703 else 4027 else
3704 { 4028 {
4029 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4030 {
4031 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4032
4033 if (linknum < 0)
4034 return UUID.Zero.ToString();
4035
4036 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4037 if (avatars.Count > linknum)
4038 {
4039 return avatars[linknum].UUID.ToString();
4040 }
4041 }
3705 return UUID.Zero.ToString(); 4042 return UUID.Zero.ToString();
3706 } 4043 }
3707 } 4044 }
@@ -3778,17 +4115,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3778 m_host.AddScriptLPS(1); 4115 m_host.AddScriptLPS(1);
3779 int count = 0; 4116 int count = 0;
3780 4117
3781 lock (m_host.TaskInventory) 4118 m_host.TaskInventory.LockItemsForRead(true);
4119 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3782 { 4120 {
3783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4121 if (inv.Value.Type == type || type == -1)
3784 { 4122 {
3785 if (inv.Value.Type == type || type == -1) 4123 count = count + 1;
3786 {
3787 count = count + 1;
3788 }
3789 } 4124 }
3790 } 4125 }
3791 4126
4127 m_host.TaskInventory.LockItemsForRead(false);
3792 return count; 4128 return count;
3793 } 4129 }
3794 4130
@@ -3797,16 +4133,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3797 m_host.AddScriptLPS(1); 4133 m_host.AddScriptLPS(1);
3798 ArrayList keys = new ArrayList(); 4134 ArrayList keys = new ArrayList();
3799 4135
3800 lock (m_host.TaskInventory) 4136 m_host.TaskInventory.LockItemsForRead(true);
4137 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3801 { 4138 {
3802 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4139 if (inv.Value.Type == type || type == -1)
3803 { 4140 {
3804 if (inv.Value.Type == type || type == -1) 4141 keys.Add(inv.Value.Name);
3805 {
3806 keys.Add(inv.Value.Name);
3807 }
3808 } 4142 }
3809 } 4143 }
4144 m_host.TaskInventory.LockItemsForRead(false);
3810 4145
3811 if (keys.Count == 0) 4146 if (keys.Count == 0)
3812 { 4147 {
@@ -3843,20 +4178,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 } 4178 }
3844 4179
3845 // move the first object found with this inventory name 4180 // move the first object found with this inventory name
3846 lock (m_host.TaskInventory) 4181 m_host.TaskInventory.LockItemsForRead(true);
4182 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3847 { 4183 {
3848 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4184 if (inv.Value.Name == inventory)
3849 { 4185 {
3850 if (inv.Value.Name == inventory) 4186 found = true;
3851 { 4187 objId = inv.Key;
3852 found = true; 4188 assetType = inv.Value.Type;
3853 objId = inv.Key; 4189 objName = inv.Value.Name;
3854 assetType = inv.Value.Type; 4190 break;
3855 objName = inv.Value.Name;
3856 break;
3857 }
3858 } 4191 }
3859 } 4192 }
4193 m_host.TaskInventory.LockItemsForRead(false);
3860 4194
3861 if (!found) 4195 if (!found)
3862 { 4196 {
@@ -3864,9 +4198,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3864 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4198 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3865 } 4199 }
3866 4200
3867 // check if destination is an avatar 4201 // check if destination is an object
3868 if (World.GetScenePresence(destId) != null) 4202 if (World.GetSceneObjectPart(destId) != null)
4203 {
4204 // destination is an object
4205 World.MoveTaskInventoryItem(destId, m_host, objId);
4206 }
4207 else
3869 { 4208 {
4209 ScenePresence presence = World.GetScenePresence(destId);
4210
4211 if (presence == null)
4212 {
4213 UserAccount account =
4214 World.UserAccountService.GetUserAccount(
4215 World.RegionInfo.ScopeID,
4216 destId);
4217
4218 if (account == null)
4219 {
4220 llSay(0, "Can't find destination "+destId.ToString());
4221 return;
4222 }
4223 }
4224
3870 // destination is an avatar 4225 // destination is an avatar
3871 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4226 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3872 4227
@@ -3890,31 +4245,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 4245
3891 if (m_TransferModule != null) 4246 if (m_TransferModule != null)
3892 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4247 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4248
4249 //This delay should only occur when giving inventory to avatars.
4250 ScriptSleep(3000);
3893 } 4251 }
3894 else
3895 {
3896 // destination is an object
3897 World.MoveTaskInventoryItem(destId, m_host, objId);
3898 }
3899 ScriptSleep(3000);
3900 } 4252 }
3901 4253
4254 [DebuggerNonUserCode]
3902 public void llRemoveInventory(string name) 4255 public void llRemoveInventory(string name)
3903 { 4256 {
3904 m_host.AddScriptLPS(1); 4257 m_host.AddScriptLPS(1);
3905 4258
3906 lock (m_host.TaskInventory) 4259 List<TaskInventoryItem> inv;
4260 try
3907 { 4261 {
3908 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4262 m_host.TaskInventory.LockItemsForRead(true);
4263 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4264 }
4265 finally
4266 {
4267 m_host.TaskInventory.LockItemsForRead(false);
4268 }
4269 foreach (TaskInventoryItem item in inv)
4270 {
4271 if (item.Name == name)
3909 { 4272 {
3910 if (item.Name == name) 4273 if (item.ItemID == m_itemID)
3911 { 4274 throw new ScriptDeleteException();
3912 if (item.ItemID == m_itemID) 4275 else
3913 throw new ScriptDeleteException(); 4276 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3914 else 4277 return;
3915 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3916 return;
3917 }
3918 } 4278 }
3919 } 4279 }
3920 } 4280 }
@@ -3980,6 +4340,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3980 ce.time = Util.EnvironmentTickCount(); 4340 ce.time = Util.EnvironmentTickCount();
3981 ce.account = account; 4341 ce.account = account;
3982 ce.pinfo = pinfo; 4342 ce.pinfo = pinfo;
4343 m_userInfoCache[uuid] = ce;
3983 } 4344 }
3984 else 4345 else
3985 { 4346 {
@@ -4055,6 +4416,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4055 { 4416 {
4056 m_host.AddScriptLPS(1); 4417 m_host.AddScriptLPS(1);
4057 4418
4419 //Clone is thread safe
4058 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4420 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4059 4421
4060 foreach (TaskInventoryItem item in itemDictionary.Values) 4422 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4108,6 +4470,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4108 ScenePresence presence = World.GetScenePresence(agentId); 4470 ScenePresence presence = World.GetScenePresence(agentId);
4109 if (presence != null) 4471 if (presence != null)
4110 { 4472 {
4473 // agent must not be a god
4474 if (presence.GodLevel >= 200) return;
4475
4111 // agent must be over the owners land 4476 // agent must be over the owners land
4112 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4477 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4113 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4478 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4130,7 +4495,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4130 UUID av = new UUID(); 4495 UUID av = new UUID();
4131 if (!UUID.TryParse(agent,out av)) 4496 if (!UUID.TryParse(agent,out av))
4132 { 4497 {
4133 LSLError("First parameter to llDialog needs to be a key"); 4498 //LSLError("First parameter to llDialog needs to be a key");
4134 return; 4499 return;
4135 } 4500 }
4136 4501
@@ -4167,17 +4532,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4167 UUID soundId = UUID.Zero; 4532 UUID soundId = UUID.Zero;
4168 if (!UUID.TryParse(impact_sound, out soundId)) 4533 if (!UUID.TryParse(impact_sound, out soundId))
4169 { 4534 {
4170 lock (m_host.TaskInventory) 4535 m_host.TaskInventory.LockItemsForRead(true);
4536 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4171 { 4537 {
4172 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4538 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4173 { 4539 {
4174 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4540 soundId = item.AssetID;
4175 { 4541 break;
4176 soundId = item.AssetID;
4177 break;
4178 }
4179 } 4542 }
4180 } 4543 }
4544 m_host.TaskInventory.LockItemsForRead(false);
4181 } 4545 }
4182 m_host.CollisionSound = soundId; 4546 m_host.CollisionSound = soundId;
4183 m_host.CollisionSoundVolume = (float)impact_volume; 4547 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4223,6 +4587,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4223 UUID partItemID; 4587 UUID partItemID;
4224 foreach (SceneObjectPart part in parts) 4588 foreach (SceneObjectPart part in parts)
4225 { 4589 {
4590 //Clone is thread safe
4226 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4591 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4227 4592
4228 foreach (TaskInventoryItem item in itemsDictionary.Values) 4593 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4437,17 +4802,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4437 4802
4438 m_host.AddScriptLPS(1); 4803 m_host.AddScriptLPS(1);
4439 4804
4440 lock (m_host.TaskInventory) 4805 m_host.TaskInventory.LockItemsForRead(true);
4806 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4441 { 4807 {
4442 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4808 if (item.Type == 10 && item.ItemID == m_itemID)
4443 { 4809 {
4444 if (item.Type == 10 && item.ItemID == m_itemID) 4810 result = item.Name!=null?item.Name:String.Empty;
4445 { 4811 break;
4446 result = item.Name != null ? item.Name : String.Empty;
4447 break;
4448 }
4449 } 4812 }
4450 } 4813 }
4814 m_host.TaskInventory.LockItemsForRead(false);
4451 4815
4452 return result; 4816 return result;
4453 } 4817 }
@@ -4600,23 +4964,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4600 { 4964 {
4601 m_host.AddScriptLPS(1); 4965 m_host.AddScriptLPS(1);
4602 4966
4603 lock (m_host.TaskInventory) 4967 m_host.TaskInventory.LockItemsForRead(true);
4968 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4604 { 4969 {
4605 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4970 if (inv.Value.Name == name)
4606 { 4971 {
4607 if (inv.Value.Name == name) 4972 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4608 { 4973 {
4609 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4974 m_host.TaskInventory.LockItemsForRead(false);
4610 { 4975 return inv.Value.AssetID.ToString();
4611 return inv.Value.AssetID.ToString(); 4976 }
4612 } 4977 else
4613 else 4978 {
4614 { 4979 m_host.TaskInventory.LockItemsForRead(false);
4615 return UUID.Zero.ToString(); 4980 return UUID.Zero.ToString();
4616 }
4617 } 4981 }
4618 } 4982 }
4619 } 4983 }
4984 m_host.TaskInventory.LockItemsForRead(false);
4620 4985
4621 return UUID.Zero.ToString(); 4986 return UUID.Zero.ToString();
4622 } 4987 }
@@ -4769,14 +5134,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4769 { 5134 {
4770 m_host.AddScriptLPS(1); 5135 m_host.AddScriptLPS(1);
4771 5136
4772 if (src == null) 5137 return src.Length;
4773 {
4774 return 0;
4775 }
4776 else
4777 {
4778 return src.Length;
4779 }
4780 } 5138 }
4781 5139
4782 public LSL_Integer llList2Integer(LSL_List src, int index) 5140 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4822,7 +5180,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4822 else if (src.Data[index] is LSL_Float) 5180 else if (src.Data[index] is LSL_Float)
4823 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5181 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4824 else if (src.Data[index] is LSL_String) 5182 else if (src.Data[index] is LSL_String)
4825 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5183 {
5184 string str = ((LSL_String) src.Data[index]).m_string;
5185 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5186 if (m != Match.Empty)
5187 {
5188 str = m.Value;
5189 double d = 0.0;
5190 if (!Double.TryParse(str, out d))
5191 return 0.0;
5192
5193 return d;
5194 }
5195 return 0.0;
5196 }
4826 return Convert.ToDouble(src.Data[index]); 5197 return Convert.ToDouble(src.Data[index]);
4827 } 5198 }
4828 catch (FormatException) 5199 catch (FormatException)
@@ -5095,7 +5466,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5095 } 5466 }
5096 } 5467 }
5097 } 5468 }
5098 else { 5469 else
5470 {
5099 object[] array = new object[src.Length]; 5471 object[] array = new object[src.Length];
5100 Array.Copy(src.Data, 0, array, 0, src.Length); 5472 Array.Copy(src.Data, 0, array, 0, src.Length);
5101 result = new LSL_List(array); 5473 result = new LSL_List(array);
@@ -5507,7 +5879,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5507 public void llSetSoundQueueing(int queue) 5879 public void llSetSoundQueueing(int queue)
5508 { 5880 {
5509 m_host.AddScriptLPS(1); 5881 m_host.AddScriptLPS(1);
5510 NotImplemented("llSetSoundQueueing");
5511 } 5882 }
5512 5883
5513 public void llSetSoundRadius(double radius) 5884 public void llSetSoundRadius(double radius)
@@ -5552,10 +5923,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5552 m_host.AddScriptLPS(1); 5923 m_host.AddScriptLPS(1);
5553 5924
5554 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5925 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5555 5926 if (parts.Count > 0)
5556 foreach (var part in parts)
5557 { 5927 {
5558 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5928 try
5929 {
5930 parts[0].ParentGroup.areUpdatesSuspended = true;
5931 foreach (var part in parts)
5932 {
5933 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5934 }
5935 }
5936 finally
5937 {
5938 parts[0].ParentGroup.areUpdatesSuspended = false;
5939 }
5559 } 5940 }
5560 } 5941 }
5561 5942
@@ -5609,6 +5990,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5609 ScriptSleep(5000); 5990 ScriptSleep(5000);
5610 } 5991 }
5611 5992
5993 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5994 {
5995 return ParseString2List(str, separators, in_spacers, false);
5996 }
5997
5612 public LSL_Integer llOverMyLand(string id) 5998 public LSL_Integer llOverMyLand(string id)
5613 { 5999 {
5614 m_host.AddScriptLPS(1); 6000 m_host.AddScriptLPS(1);
@@ -5809,7 +6195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5809 return m_host.ParentGroup.RootPart.AttachmentPoint; 6195 return m_host.ParentGroup.RootPart.AttachmentPoint;
5810 } 6196 }
5811 6197
5812 public LSL_Integer llGetFreeMemory() 6198 public virtual LSL_Integer llGetFreeMemory()
5813 { 6199 {
5814 m_host.AddScriptLPS(1); 6200 m_host.AddScriptLPS(1);
5815 // Make scripts designed for LSO happy 6201 // Make scripts designed for LSO happy
@@ -5926,7 +6312,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5926 SetParticleSystem(m_host, rules); 6312 SetParticleSystem(m_host, rules);
5927 } 6313 }
5928 6314
5929 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6315 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6316 {
5930 6317
5931 6318
5932 if (rules.Length == 0) 6319 if (rules.Length == 0)
@@ -6120,14 +6507,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6120 6507
6121 protected UUID GetTaskInventoryItem(string name) 6508 protected UUID GetTaskInventoryItem(string name)
6122 { 6509 {
6123 lock (m_host.TaskInventory) 6510 m_host.TaskInventory.LockItemsForRead(true);
6511 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6124 { 6512 {
6125 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6513 if (inv.Value.Name == name)
6126 { 6514 {
6127 if (inv.Value.Name == name) 6515 m_host.TaskInventory.LockItemsForRead(false);
6128 return inv.Key; 6516 return inv.Key;
6129 } 6517 }
6130 } 6518 }
6519 m_host.TaskInventory.LockItemsForRead(false);
6131 6520
6132 return UUID.Zero; 6521 return UUID.Zero;
6133 } 6522 }
@@ -6377,13 +6766,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6377 UUID av = new UUID(); 6766 UUID av = new UUID();
6378 if (!UUID.TryParse(avatar,out av)) 6767 if (!UUID.TryParse(avatar,out av))
6379 { 6768 {
6380 LSLError("First parameter to llDialog needs to be a key"); 6769 //LSLError("First parameter to llDialog needs to be a key");
6381 return; 6770 return;
6382 } 6771 }
6383 if (buttons.Length < 1) 6772 if (buttons.Length < 1)
6384 { 6773 {
6385 LSLError("No less than 1 button can be shown"); 6774 buttons.Add("OK");
6386 return;
6387 } 6775 }
6388 if (buttons.Length > 12) 6776 if (buttons.Length > 12)
6389 { 6777 {
@@ -6400,7 +6788,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6400 } 6788 }
6401 if (buttons.Data[i].ToString().Length > 24) 6789 if (buttons.Data[i].ToString().Length > 24)
6402 { 6790 {
6403 LSLError("button label cannot be longer than 24 characters"); 6791 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6404 return; 6792 return;
6405 } 6793 }
6406 buts[i] = buttons.Data[i].ToString(); 6794 buts[i] = buttons.Data[i].ToString();
@@ -6464,22 +6852,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6464 } 6852 }
6465 6853
6466 // copy the first script found with this inventory name 6854 // copy the first script found with this inventory name
6467 lock (m_host.TaskInventory) 6855 m_host.TaskInventory.LockItemsForRead(true);
6856 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6468 { 6857 {
6469 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6858 if (inv.Value.Name == name)
6470 { 6859 {
6471 if (inv.Value.Name == name) 6860 // make sure the object is a script
6861 if (10 == inv.Value.Type)
6472 { 6862 {
6473 // make sure the object is a script 6863 found = true;
6474 if (10 == inv.Value.Type) 6864 srcId = inv.Key;
6475 { 6865 break;
6476 found = true;
6477 srcId = inv.Key;
6478 break;
6479 }
6480 } 6866 }
6481 } 6867 }
6482 } 6868 }
6869 m_host.TaskInventory.LockItemsForRead(false);
6483 6870
6484 if (!found) 6871 if (!found)
6485 { 6872 {
@@ -6551,18 +6938,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6551 public LSL_String llMD5String(string src, int nonce) 6938 public LSL_String llMD5String(string src, int nonce)
6552 { 6939 {
6553 m_host.AddScriptLPS(1); 6940 m_host.AddScriptLPS(1);
6554 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 6941 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6555 } 6942 }
6556 6943
6557 public LSL_String llSHA1String(string src) 6944 public LSL_String llSHA1String(string src)
6558 { 6945 {
6559 m_host.AddScriptLPS(1); 6946 m_host.AddScriptLPS(1);
6560 return Util.SHA1Hash(src).ToLower(); 6947 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6561 } 6948 }
6562 6949
6563 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6950 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6564 { 6951 {
6565 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6952 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6953 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6954 return shapeBlock;
6566 6955
6567 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6956 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6568 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6957 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6638,6 +7027,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6638 7027
6639 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7028 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6640 { 7029 {
7030 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7031 return;
7032
6641 ObjectShapePacket.ObjectDataBlock shapeBlock; 7033 ObjectShapePacket.ObjectDataBlock shapeBlock;
6642 7034
6643 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7035 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6687,6 +7079,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6687 7079
6688 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7080 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6689 { 7081 {
7082 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7083 return;
7084
6690 ObjectShapePacket.ObjectDataBlock shapeBlock; 7085 ObjectShapePacket.ObjectDataBlock shapeBlock;
6691 7086
6692 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7087 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6729,6 +7124,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6729 7124
6730 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) 7125 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)
6731 { 7126 {
7127 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7128 return;
7129
6732 ObjectShapePacket.ObjectDataBlock shapeBlock; 7130 ObjectShapePacket.ObjectDataBlock shapeBlock;
6733 7131
6734 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7132 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6855,6 +7253,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6855 7253
6856 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7254 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6857 { 7255 {
7256 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7257 return;
7258
6858 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7259 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6859 UUID sculptId; 7260 UUID sculptId;
6860 7261
@@ -6870,13 +7271,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6870 shapeBlock.PathScaleX = 100; 7271 shapeBlock.PathScaleX = 100;
6871 shapeBlock.PathScaleY = 150; 7272 shapeBlock.PathScaleY = 150;
6872 7273
6873 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7274 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6874 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7275 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6875 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7276 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6876 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7277 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6877 { 7278 {
6878 // default 7279 // default
6879 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7280 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6880 } 7281 }
6881 7282
6882 // retain pathcurve 7283 // retain pathcurve
@@ -6895,30 +7296,82 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6895 ScriptSleep(200); 7296 ScriptSleep(200);
6896 } 7297 }
6897 7298
6898 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7299 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6899 { 7300 {
6900 m_host.AddScriptLPS(1); 7301 m_host.AddScriptLPS(1);
6901 7302
6902 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7303 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7304 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7305 if (parts.Count>0)
7306 {
7307 try
7308 {
7309 parts[0].ParentGroup.areUpdatesSuspended = true;
7310 foreach (SceneObjectPart part in parts)
7311 SetPrimParams(part, rules);
7312 }
7313 finally
7314 {
7315 parts[0].ParentGroup.areUpdatesSuspended = false;
7316 }
7317 }
7318 if (avatars.Count > 0)
7319 {
7320 foreach (ScenePresence avatar in avatars)
7321 SetPrimParams(avatar, rules);
7322 }
7323 }
6903 7324
6904 foreach (SceneObjectPart part in parts) 7325 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6905 SetPrimParams(part, rules); 7326 {
6906 7327 llSetLinkPrimitiveParamsFast(linknumber, rules);
6907 ScriptSleep(200); 7328 ScriptSleep(200);
6908 } 7329 }
6909 7330
6910 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7331 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6911 { 7332 {
6912 m_host.AddScriptLPS(1); 7333 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7334 //We only support PRIM_POSITION and PRIM_ROTATION
6913 7335
6914 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7336 int idx = 0;
6915 7337
6916 foreach (SceneObjectPart part in parts) 7338 while (idx < rules.Length)
6917 SetPrimParams(part, rules); 7339 {
7340 int code = rules.GetLSLIntegerItem(idx++);
7341
7342 int remain = rules.Length - idx;
7343
7344
7345
7346 switch (code)
7347 {
7348 case (int)ScriptBaseClass.PRIM_POSITION:
7349 if (remain < 1)
7350 return;
7351 LSL_Vector v;
7352 v = rules.GetVector3Item(idx++);
7353 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7354 av.SendAvatarDataToAllAgents();
7355
7356 break;
7357
7358 case (int)ScriptBaseClass.PRIM_ROTATION:
7359 if (remain < 1)
7360 return;
7361 LSL_Rotation r;
7362 r = rules.GetQuaternionItem(idx++);
7363 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7364 av.SendAvatarDataToAllAgents();
7365 break;
7366 }
7367 }
6918 } 7368 }
6919 7369
6920 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7370 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6921 { 7371 {
7372 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7373 return;
7374
6922 int idx = 0; 7375 int idx = 0;
6923 7376
6924 while (idx < rules.Length) 7377 while (idx < rules.Length)
@@ -7453,13 +7906,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7453 public LSL_Integer llGetNumberOfPrims() 7906 public LSL_Integer llGetNumberOfPrims()
7454 { 7907 {
7455 m_host.AddScriptLPS(1); 7908 m_host.AddScriptLPS(1);
7456 int avatarCount = 0; 7909 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7457 World.ForEachScenePresence(delegate(ScenePresence presence) 7910
7458 {
7459 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7460 avatarCount++;
7461 });
7462
7463 return m_host.ParentGroup.PrimCount + avatarCount; 7911 return m_host.ParentGroup.PrimCount + avatarCount;
7464 } 7912 }
7465 7913
@@ -7475,55 +7923,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7475 m_host.AddScriptLPS(1); 7923 m_host.AddScriptLPS(1);
7476 UUID objID = UUID.Zero; 7924 UUID objID = UUID.Zero;
7477 LSL_List result = new LSL_List(); 7925 LSL_List result = new LSL_List();
7926
7927 // If the ID is not valid, return null result
7478 if (!UUID.TryParse(obj, out objID)) 7928 if (!UUID.TryParse(obj, out objID))
7479 { 7929 {
7480 result.Add(new LSL_Vector()); 7930 result.Add(new LSL_Vector());
7481 result.Add(new LSL_Vector()); 7931 result.Add(new LSL_Vector());
7482 return result; 7932 return result;
7483 } 7933 }
7934
7935 // Check if this is an attached prim. If so, replace
7936 // the UUID with the avatar UUID and report it's bounding box
7937 SceneObjectPart part = World.GetSceneObjectPart(objID);
7938 if (part != null && part.ParentGroup.IsAttachment)
7939 objID = part.ParentGroup.RootPart.AttachedAvatar;
7940
7941 // Find out if this is an avatar ID. If so, return it's box
7484 ScenePresence presence = World.GetScenePresence(objID); 7942 ScenePresence presence = World.GetScenePresence(objID);
7485 if (presence != null) 7943 if (presence != null)
7486 { 7944 {
7487 if (presence.ParentID == 0) // not sat on an object 7945 // As per LSL Wiki, there is no difference between sitting
7946 // and standing avatar since server 1.36
7947 LSL_Vector lower;
7948 LSL_Vector upper;
7949 if (presence.Animator.Animations.DefaultAnimation.AnimID
7950 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7488 { 7951 {
7489 LSL_Vector lower; 7952 // This is for ground sitting avatars
7490 LSL_Vector upper; 7953 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7491 if (presence.Animator.Animations.DefaultAnimation.AnimID 7954 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7492 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7955 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7493 {
7494 // This is for ground sitting avatars
7495 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7496 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7497 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7498 }
7499 else
7500 {
7501 // This is for standing/flying avatars
7502 float height = presence.Appearance.AvatarHeight / 2.0f;
7503 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7504 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7505 }
7506 result.Add(lower);
7507 result.Add(upper);
7508 return result;
7509 } 7956 }
7510 else 7957 else
7511 { 7958 {
7512 // sitting on an object so we need the bounding box of that 7959 // This is for standing/flying avatars
7513 // which should include the avatar so set the UUID to the 7960 float height = presence.Appearance.AvatarHeight / 2.0f;
7514 // UUID of the object the avatar is sat on and allow it to fall through 7961 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7515 // to processing an object 7962 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7516 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7517 objID = p.UUID;
7518 } 7963 }
7964
7965 // Adjust to the documented error offsets (see LSL Wiki)
7966 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7967 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7968
7969 if (lower.x > upper.x)
7970 lower.x = upper.x;
7971 if (lower.y > upper.y)
7972 lower.y = upper.y;
7973 if (lower.z > upper.z)
7974 lower.z = upper.z;
7975
7976 result.Add(lower);
7977 result.Add(upper);
7978 return result;
7519 } 7979 }
7520 SceneObjectPart part = World.GetSceneObjectPart(objID); 7980
7981 part = World.GetSceneObjectPart(objID);
7521 // Currently only works for single prims without a sitting avatar 7982 // Currently only works for single prims without a sitting avatar
7522 if (part != null) 7983 if (part != null)
7523 { 7984 {
7524 Vector3 halfSize = part.Scale / 2.0f; 7985 float minX;
7525 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7986 float maxX;
7526 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7987 float minY;
7988 float maxY;
7989 float minZ;
7990 float maxZ;
7991
7992 // This BBox is in sim coordinates, with the offset being
7993 // a contained point.
7994 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7995 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7996
7997 minX -= offsets[0].X;
7998 maxX -= offsets[0].X;
7999 minY -= offsets[0].Y;
8000 maxY -= offsets[0].Y;
8001 minZ -= offsets[0].Z;
8002 maxZ -= offsets[0].Z;
8003
8004 LSL_Vector lower;
8005 LSL_Vector upper;
8006
8007 // Adjust to the documented error offsets (see LSL Wiki)
8008 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8009 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8010
8011 if (lower.x > upper.x)
8012 lower.x = upper.x;
8013 if (lower.y > upper.y)
8014 lower.y = upper.y;
8015 if (lower.z > upper.z)
8016 lower.z = upper.z;
8017
7527 result.Add(lower); 8018 result.Add(lower);
7528 result.Add(upper); 8019 result.Add(upper);
7529 return result; 8020 return result;
@@ -7603,13 +8094,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7603 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8094 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7604 part.AbsolutePosition.Y, 8095 part.AbsolutePosition.Y,
7605 part.AbsolutePosition.Z); 8096 part.AbsolutePosition.Z);
7606 // For some reason, the part.AbsolutePosition.* values do not change if the
7607 // linkset is rotated; they always reflect the child prim's world position
7608 // as though the linkset is unrotated. This is incompatible behavior with SL's
7609 // implementation, so will break scripts imported from there (not to mention it
7610 // makes it more difficult to determine a child prim's actual inworld position).
7611 if (part.ParentID != 0)
7612 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7613 res.Add(v); 8097 res.Add(v);
7614 break; 8098 break;
7615 8099
@@ -7770,56 +8254,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7770 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8254 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7771 if (remain < 1) 8255 if (remain < 1)
7772 return res; 8256 return res;
7773 8257 face = (int)rules.GetLSLIntegerItem(idx++);
7774 face=(int)rules.GetLSLIntegerItem(idx++);
7775 8258
7776 tex = part.Shape.Textures; 8259 tex = part.Shape.Textures;
8260 int shiny;
7777 if (face == ScriptBaseClass.ALL_SIDES) 8261 if (face == ScriptBaseClass.ALL_SIDES)
7778 { 8262 {
7779 for (face = 0; face < GetNumberOfSides(part); face++) 8263 for (face = 0; face < GetNumberOfSides(part); face++)
7780 { 8264 {
7781 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8265 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7782 // Convert Shininess to PRIM_SHINY_* 8266 if (shinyness == Shininess.High)
7783 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8267 {
7784 // PRIM_BUMP_* 8268 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7785 res.Add(new LSL_Integer((int)texface.Bump)); 8269 }
8270 else if (shinyness == Shininess.Medium)
8271 {
8272 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8273 }
8274 else if (shinyness == Shininess.Low)
8275 {
8276 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8277 }
8278 else
8279 {
8280 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8281 }
8282 res.Add(new LSL_Integer(shiny));
8283 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7786 } 8284 }
7787 } 8285 }
7788 else 8286 else
7789 { 8287 {
7790 if (face >= 0 && face < GetNumberOfSides(part)) 8288 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8289 if (shinyness == Shininess.High)
7791 { 8290 {
7792 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8291 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7793 // Convert Shininess to PRIM_SHINY_*
7794 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7795 // PRIM_BUMP_*
7796 res.Add(new LSL_Integer((int)texface.Bump));
7797 } 8292 }
8293 else if (shinyness == Shininess.Medium)
8294 {
8295 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8296 }
8297 else if (shinyness == Shininess.Low)
8298 {
8299 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8300 }
8301 else
8302 {
8303 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8304 }
8305 res.Add(new LSL_Integer(shiny));
8306 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7798 } 8307 }
7799 break; 8308 break;
7800 8309
7801 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8310 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7802 if (remain < 1) 8311 if (remain < 1)
7803 return res; 8312 return res;
7804 8313 face = (int)rules.GetLSLIntegerItem(idx++);
7805 face=(int)rules.GetLSLIntegerItem(idx++);
7806 8314
7807 tex = part.Shape.Textures; 8315 tex = part.Shape.Textures;
8316 int fullbright;
7808 if (face == ScriptBaseClass.ALL_SIDES) 8317 if (face == ScriptBaseClass.ALL_SIDES)
7809 { 8318 {
7810 for (face = 0; face < GetNumberOfSides(part); face++) 8319 for (face = 0; face < GetNumberOfSides(part); face++)
7811 { 8320 {
7812 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8321 if (tex.GetFace((uint)face).Fullbright == true)
7813 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8322 {
8323 fullbright = ScriptBaseClass.TRUE;
8324 }
8325 else
8326 {
8327 fullbright = ScriptBaseClass.FALSE;
8328 }
8329 res.Add(new LSL_Integer(fullbright));
7814 } 8330 }
7815 } 8331 }
7816 else 8332 else
7817 { 8333 {
7818 if (face >= 0 && face < GetNumberOfSides(part)) 8334 if (tex.GetFace((uint)face).Fullbright == true)
7819 { 8335 {
7820 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8336 fullbright = ScriptBaseClass.TRUE;
7821 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8337 }
8338 else
8339 {
8340 fullbright = ScriptBaseClass.FALSE;
7822 } 8341 }
8342 res.Add(new LSL_Integer(fullbright));
7823 } 8343 }
7824 break; 8344 break;
7825 8345
@@ -7841,27 +8361,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7841 break; 8361 break;
7842 8362
7843 case (int)ScriptBaseClass.PRIM_TEXGEN: 8363 case (int)ScriptBaseClass.PRIM_TEXGEN:
8364 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7844 if (remain < 1) 8365 if (remain < 1)
7845 return res; 8366 return res;
7846 8367 face = (int)rules.GetLSLIntegerItem(idx++);
7847 face=(int)rules.GetLSLIntegerItem(idx++);
7848 8368
7849 tex = part.Shape.Textures; 8369 tex = part.Shape.Textures;
7850 if (face == ScriptBaseClass.ALL_SIDES) 8370 if (face == ScriptBaseClass.ALL_SIDES)
7851 { 8371 {
7852 for (face = 0; face < GetNumberOfSides(part); face++) 8372 for (face = 0; face < GetNumberOfSides(part); face++)
7853 { 8373 {
7854 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8374 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7855 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8375 {
7856 res.Add(new LSL_Integer((uint)texgen >> 1)); 8376 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8377 }
8378 else
8379 {
8380 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8381 }
7857 } 8382 }
7858 } 8383 }
7859 else 8384 else
7860 { 8385 {
7861 if (face >= 0 && face < GetNumberOfSides(part)) 8386 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8387 {
8388 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8389 }
8390 else
7862 { 8391 {
7863 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8392 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7864 res.Add(new LSL_Integer((uint)texgen >> 1));
7865 } 8393 }
7866 } 8394 }
7867 break; 8395 break;
@@ -7884,28 +8412,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7884 case (int)ScriptBaseClass.PRIM_GLOW: 8412 case (int)ScriptBaseClass.PRIM_GLOW:
7885 if (remain < 1) 8413 if (remain < 1)
7886 return res; 8414 return res;
7887 8415 face = (int)rules.GetLSLIntegerItem(idx++);
7888 face=(int)rules.GetLSLIntegerItem(idx++);
7889 8416
7890 tex = part.Shape.Textures; 8417 tex = part.Shape.Textures;
8418 float primglow;
7891 if (face == ScriptBaseClass.ALL_SIDES) 8419 if (face == ScriptBaseClass.ALL_SIDES)
7892 { 8420 {
7893 for (face = 0; face < GetNumberOfSides(part); face++) 8421 for (face = 0; face < GetNumberOfSides(part); face++)
7894 { 8422 {
7895 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8423 primglow = tex.GetFace((uint)face).Glow;
7896 res.Add(new LSL_Float(texface.Glow)); 8424 res.Add(new LSL_Float(primglow));
7897 } 8425 }
7898 } 8426 }
7899 else 8427 else
7900 { 8428 {
7901 if (face >= 0 && face < GetNumberOfSides(part)) 8429 primglow = tex.GetFace((uint)face).Glow;
7902 { 8430 res.Add(new LSL_Float(primglow));
7903 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7904 res.Add(new LSL_Float(texface.Glow));
7905 }
7906 } 8431 }
7907 break; 8432 break;
7908
7909 case (int)ScriptBaseClass.PRIM_TEXT: 8433 case (int)ScriptBaseClass.PRIM_TEXT:
7910 Color4 textColor = part.GetTextColor(); 8434 Color4 textColor = part.GetTextColor();
7911 res.Add(part.Text); 8435 res.Add(part.Text);
@@ -8454,8 +8978,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8454 // The function returns an ordered list 8978 // The function returns an ordered list
8455 // representing the tokens found in the supplied 8979 // representing the tokens found in the supplied
8456 // sources string. If two successive tokenizers 8980 // sources string. If two successive tokenizers
8457 // are encountered, then a NULL entry is added 8981 // are encountered, then a null-string entry is
8458 // to the list. 8982 // added to the list.
8459 // 8983 //
8460 // It is a precondition that the source and 8984 // It is a precondition that the source and
8461 // toekizer lisst are non-null. If they are null, 8985 // toekizer lisst are non-null. If they are null,
@@ -8463,7 +8987,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8463 // while their lengths are being determined. 8987 // while their lengths are being determined.
8464 // 8988 //
8465 // A small amount of working memoryis required 8989 // A small amount of working memoryis required
8466 // of approximately 8*#tokenizers. 8990 // of approximately 8*#tokenizers + 8*srcstrlen.
8467 // 8991 //
8468 // There are many ways in which this function 8992 // There are many ways in which this function
8469 // can be implemented, this implementation is 8993 // can be implemented, this implementation is
@@ -8479,155 +9003,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8479 // and eliminates redundant tokenizers as soon 9003 // and eliminates redundant tokenizers as soon
8480 // as is possible. 9004 // as is possible.
8481 // 9005 //
8482 // The implementation tries to avoid any copying 9006 // The implementation tries to minimize temporary
8483 // of arrays or other objects. 9007 // garbage generation.
8484 // </remarks> 9008 // </remarks>
8485 9009
8486 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9010 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8487 { 9011 {
8488 int beginning = 0; 9012 return ParseString2List(src, separators, spacers, true);
8489 int srclen = src.Length; 9013 }
8490 int seplen = separators.Length;
8491 object[] separray = separators.Data;
8492 int spclen = spacers.Length;
8493 object[] spcarray = spacers.Data;
8494 int mlen = seplen+spclen;
8495
8496 int[] offset = new int[mlen+1];
8497 bool[] active = new bool[mlen];
8498
8499 int best;
8500 int j;
8501
8502 // Initial capacity reduces resize cost
8503 9014
8504 LSL_List tokens = new LSL_List(); 9015 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9016 {
9017 int srclen = src.Length;
9018 int seplen = separators.Length;
9019 object[] separray = separators.Data;
9020 int spclen = spacers.Length;
9021 object[] spcarray = spacers.Data;
9022 int dellen = 0;
9023 string[] delarray = new string[seplen+spclen];
8505 9024
8506 // All entries are initially valid 9025 int outlen = 0;
9026 string[] outarray = new string[srclen*2+1];
8507 9027
8508 for (int i = 0; i < mlen; i++) 9028 int i, j;
8509 active[i] = true; 9029 string d;
8510 9030
8511 offset[mlen] = srclen; 9031 m_host.AddScriptLPS(1);
8512 9032
8513 while (beginning < srclen) 9033 /*
9034 * Convert separator and spacer lists to C# strings.
9035 * Also filter out null strings so we don't hang.
9036 */
9037 for (i = 0; i < seplen; i ++)
8514 { 9038 {
9039 d = separray[i].ToString();
9040 if (d.Length > 0)
9041 {
9042 delarray[dellen++] = d;
9043 }
9044 }
9045 seplen = dellen;
8515 9046
8516 best = mlen; // as bad as it gets 9047 for (i = 0; i < spclen; i ++)
9048 {
9049 d = spcarray[i].ToString();
9050 if (d.Length > 0)
9051 {
9052 delarray[dellen++] = d;
9053 }
9054 }
8517 9055
8518 // Scan for separators 9056 /*
9057 * Scan through source string from beginning to end.
9058 */
9059 for (i = 0;;)
9060 {
8519 9061
8520 for (j = 0; j < seplen; j++) 9062 /*
9063 * Find earliest delimeter in src starting at i (if any).
9064 */
9065 int earliestDel = -1;
9066 int earliestSrc = srclen;
9067 string earliestStr = null;
9068 for (j = 0; j < dellen; j ++)
8521 { 9069 {
8522 if (separray[j].ToString() == String.Empty) 9070 d = delarray[j];
8523 active[j] = false; 9071 if (d != null)
8524
8525 if (active[j])
8526 { 9072 {
8527 // scan all of the markers 9073 int index = src.IndexOf(d, i);
8528 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9074 if (index < 0)
8529 { 9075 {
8530 // not present at all 9076 delarray[j] = null; // delim nowhere in src, don't check it anymore
8531 active[j] = false;
8532 } 9077 }
8533 else 9078 else if (index < earliestSrc)
8534 { 9079 {
8535 // present and correct 9080 earliestSrc = index; // where delimeter starts in source string
8536 if (offset[j] < offset[best]) 9081 earliestDel = j; // where delimeter is in delarray[]
8537 { 9082 earliestStr = d; // the delimeter string from delarray[]
8538 // closest so far 9083 if (index == i) break; // can't do any better than found at beg of string
8539 best = j;
8540 if (offset[best] == beginning)
8541 break;
8542 }
8543 } 9084 }
8544 } 9085 }
8545 } 9086 }
8546 9087
8547 // Scan for spacers 9088 /*
8548 9089 * Output source string starting at i through start of earliest delimeter.
8549 if (offset[best] != beginning) 9090 */
9091 if (keepNulls || (earliestSrc > i))
8550 { 9092 {
8551 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9093 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8552 {
8553 if (spcarray[j-seplen].ToString() == String.Empty)
8554 active[j] = false;
8555
8556 if (active[j])
8557 {
8558 // scan all of the markers
8559 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8560 {
8561 // not present at all
8562 active[j] = false;
8563 }
8564 else
8565 {
8566 // present and correct
8567 if (offset[j] < offset[best])
8568 {
8569 // closest so far
8570 best = j;
8571 }
8572 }
8573 }
8574 }
8575 } 9094 }
8576 9095
8577 // This is the normal exit from the scanning loop 9096 /*
9097 * If no delimeter found at or after i, we're done scanning.
9098 */
9099 if (earliestDel < 0) break;
8578 9100
8579 if (best == mlen) 9101 /*
9102 * If delimeter was a spacer, output the spacer.
9103 */
9104 if (earliestDel >= seplen)
8580 { 9105 {
8581 // no markers were found on this pass 9106 outarray[outlen++] = earliestStr;
8582 // so we're pretty much done
8583 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8584 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8585 break;
8586 } 9107 }
8587 9108
8588 // Otherwise we just add the newly delimited token 9109 /*
8589 // and recalculate where the search should continue. 9110 * Look at rest of src string following delimeter.
8590 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9111 */
8591 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9112 i = earliestSrc + earliestStr.Length;
8592
8593 if (best < seplen)
8594 {
8595 beginning = offset[best] + (separray[best].ToString()).Length;
8596 }
8597 else
8598 {
8599 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8600 string str = spcarray[best - seplen].ToString();
8601 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8602 tokens.Add(new LSL_String(str));
8603 }
8604 } 9113 }
8605 9114
8606 // This an awkward an not very intuitive boundary case. If the 9115 /*
8607 // last substring is a tokenizer, then there is an implied trailing 9116 * Make up an exact-sized output array suitable for an LSL_List object.
8608 // null list entry. Hopefully the single comparison will not be too 9117 */
8609 // arduous. Alternatively the 'break' could be replced with a return 9118 object[] outlist = new object[outlen];
8610 // but that's shabby programming. 9119 for (i = 0; i < outlen; i ++)
8611
8612 if ((beginning == srclen) && (keepNulls))
8613 { 9120 {
8614 if (srclen != 0) 9121 outlist[i] = new LSL_String(outarray[i]);
8615 tokens.Add(new LSL_String(""));
8616 } 9122 }
8617 9123 return new LSL_List(outlist);
8618 return tokens;
8619 }
8620
8621 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8622 {
8623 m_host.AddScriptLPS(1);
8624 return this.ParseString(src, separators, spacers, false);
8625 }
8626
8627 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8628 {
8629 m_host.AddScriptLPS(1);
8630 return this.ParseString(src, separators, spacers, true);
8631 } 9124 }
8632 9125
8633 public LSL_Integer llGetObjectPermMask(int mask) 9126 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8704,28 +9197,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8704 { 9197 {
8705 m_host.AddScriptLPS(1); 9198 m_host.AddScriptLPS(1);
8706 9199
8707 lock (m_host.TaskInventory) 9200 m_host.TaskInventory.LockItemsForRead(true);
9201 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8708 { 9202 {
8709 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9203 if (inv.Value.Name == item)
8710 { 9204 {
8711 if (inv.Value.Name == item) 9205 m_host.TaskInventory.LockItemsForRead(false);
9206 switch (mask)
8712 { 9207 {
8713 switch (mask) 9208 case 0:
8714 { 9209 return (int)inv.Value.BasePermissions;
8715 case 0: 9210 case 1:
8716 return (int)inv.Value.BasePermissions; 9211 return (int)inv.Value.CurrentPermissions;
8717 case 1: 9212 case 2:
8718 return (int)inv.Value.CurrentPermissions; 9213 return (int)inv.Value.GroupPermissions;
8719 case 2: 9214 case 3:
8720 return (int)inv.Value.GroupPermissions; 9215 return (int)inv.Value.EveryonePermissions;
8721 case 3: 9216 case 4:
8722 return (int)inv.Value.EveryonePermissions; 9217 return (int)inv.Value.NextPermissions;
8723 case 4:
8724 return (int)inv.Value.NextPermissions;
8725 }
8726 } 9218 }
8727 } 9219 }
8728 } 9220 }
9221 m_host.TaskInventory.LockItemsForRead(false);
8729 9222
8730 return -1; 9223 return -1;
8731 } 9224 }
@@ -8772,16 +9265,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8772 { 9265 {
8773 m_host.AddScriptLPS(1); 9266 m_host.AddScriptLPS(1);
8774 9267
8775 lock (m_host.TaskInventory) 9268 m_host.TaskInventory.LockItemsForRead(true);
9269 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8776 { 9270 {
8777 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9271 if (inv.Value.Name == item)
8778 { 9272 {
8779 if (inv.Value.Name == item) 9273 m_host.TaskInventory.LockItemsForRead(false);
8780 { 9274 return inv.Value.CreatorID.ToString();
8781 return inv.Value.CreatorID.ToString();
8782 }
8783 } 9275 }
8784 } 9276 }
9277 m_host.TaskInventory.LockItemsForRead(false);
8785 9278
8786 llSay(0, "No item name '" + item + "'"); 9279 llSay(0, "No item name '" + item + "'");
8787 9280
@@ -8929,7 +9422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8929 } 9422 }
8930 9423
8931 /// <summary> 9424 /// <summary>
8932 /// illListReplaceList removes the sub-list defined by the inclusive indices 9425 /// llListReplaceList removes the sub-list defined by the inclusive indices
8933 /// start and end and inserts the src list in its place. The inclusive 9426 /// start and end and inserts the src list in its place. The inclusive
8934 /// nature of the indices means that at least one element must be deleted 9427 /// nature of the indices means that at least one element must be deleted
8935 /// if the indices are within the bounds of the existing list. I.e. 2,2 9428 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -8986,16 +9479,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8986 // based upon end. Note that if end exceeds the upper 9479 // based upon end. Note that if end exceeds the upper
8987 // bound in this case, the entire destination list 9480 // bound in this case, the entire destination list
8988 // is removed. 9481 // is removed.
8989 else 9482 else if (start == 0)
8990 { 9483 {
8991 if (end + 1 < dest.Length) 9484 if (end + 1 < dest.Length)
8992 {
8993 return src + dest.GetSublist(end + 1, -1); 9485 return src + dest.GetSublist(end + 1, -1);
8994 }
8995 else 9486 else
8996 {
8997 return src; 9487 return src;
8998 } 9488 }
9489 else // Start < 0
9490 {
9491 if (end + 1 < dest.Length)
9492 return dest.GetSublist(end + 1, -1);
9493 else
9494 return new LSL_List();
8999 } 9495 }
9000 } 9496 }
9001 // Finally, if start > end, we strip away a prefix and 9497 // Finally, if start > end, we strip away a prefix and
@@ -9046,17 +9542,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9046 int width = 0; 9542 int width = 0;
9047 int height = 0; 9543 int height = 0;
9048 9544
9049 ParcelMediaCommandEnum? commandToSend = null; 9545 uint commandToSend = 0;
9050 float time = 0.0f; // default is from start 9546 float time = 0.0f; // default is from start
9051 9547
9052 ScenePresence presence = null; 9548 ScenePresence presence = null;
9053 9549
9054 for (int i = 0; i < commandList.Data.Length; i++) 9550 for (int i = 0; i < commandList.Data.Length; i++)
9055 { 9551 {
9056 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9552 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9057 switch (command) 9553 switch (command)
9058 { 9554 {
9059 case ParcelMediaCommandEnum.Agent: 9555 case (uint)ParcelMediaCommandEnum.Agent:
9060 // we send only to one agent 9556 // we send only to one agent
9061 if ((i + 1) < commandList.Length) 9557 if ((i + 1) < commandList.Length)
9062 { 9558 {
@@ -9073,25 +9569,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9073 } 9569 }
9074 break; 9570 break;
9075 9571
9076 case ParcelMediaCommandEnum.Loop: 9572 case (uint)ParcelMediaCommandEnum.Loop:
9077 loop = 1; 9573 loop = 1;
9078 commandToSend = command; 9574 commandToSend = command;
9079 update = true; //need to send the media update packet to set looping 9575 update = true; //need to send the media update packet to set looping
9080 break; 9576 break;
9081 9577
9082 case ParcelMediaCommandEnum.Play: 9578 case (uint)ParcelMediaCommandEnum.Play:
9083 loop = 0; 9579 loop = 0;
9084 commandToSend = command; 9580 commandToSend = command;
9085 update = true; //need to send the media update packet to make sure it doesn't loop 9581 update = true; //need to send the media update packet to make sure it doesn't loop
9086 break; 9582 break;
9087 9583
9088 case ParcelMediaCommandEnum.Pause: 9584 case (uint)ParcelMediaCommandEnum.Pause:
9089 case ParcelMediaCommandEnum.Stop: 9585 case (uint)ParcelMediaCommandEnum.Stop:
9090 case ParcelMediaCommandEnum.Unload: 9586 case (uint)ParcelMediaCommandEnum.Unload:
9091 commandToSend = command; 9587 commandToSend = command;
9092 break; 9588 break;
9093 9589
9094 case ParcelMediaCommandEnum.Url: 9590 case (uint)ParcelMediaCommandEnum.Url:
9095 if ((i + 1) < commandList.Length) 9591 if ((i + 1) < commandList.Length)
9096 { 9592 {
9097 if (commandList.Data[i + 1] is LSL_String) 9593 if (commandList.Data[i + 1] is LSL_String)
@@ -9104,7 +9600,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9104 } 9600 }
9105 break; 9601 break;
9106 9602
9107 case ParcelMediaCommandEnum.Texture: 9603 case (uint)ParcelMediaCommandEnum.Texture:
9108 if ((i + 1) < commandList.Length) 9604 if ((i + 1) < commandList.Length)
9109 { 9605 {
9110 if (commandList.Data[i + 1] is LSL_String) 9606 if (commandList.Data[i + 1] is LSL_String)
@@ -9117,7 +9613,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9117 } 9613 }
9118 break; 9614 break;
9119 9615
9120 case ParcelMediaCommandEnum.Time: 9616 case (uint)ParcelMediaCommandEnum.Time:
9121 if ((i + 1) < commandList.Length) 9617 if ((i + 1) < commandList.Length)
9122 { 9618 {
9123 if (commandList.Data[i + 1] is LSL_Float) 9619 if (commandList.Data[i + 1] is LSL_Float)
@@ -9129,7 +9625,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9129 } 9625 }
9130 break; 9626 break;
9131 9627
9132 case ParcelMediaCommandEnum.AutoAlign: 9628 case (uint)ParcelMediaCommandEnum.AutoAlign:
9133 if ((i + 1) < commandList.Length) 9629 if ((i + 1) < commandList.Length)
9134 { 9630 {
9135 if (commandList.Data[i + 1] is LSL_Integer) 9631 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9143,7 +9639,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9143 } 9639 }
9144 break; 9640 break;
9145 9641
9146 case ParcelMediaCommandEnum.Type: 9642 case (uint)ParcelMediaCommandEnum.Type:
9147 if ((i + 1) < commandList.Length) 9643 if ((i + 1) < commandList.Length)
9148 { 9644 {
9149 if (commandList.Data[i + 1] is LSL_String) 9645 if (commandList.Data[i + 1] is LSL_String)
@@ -9156,7 +9652,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9156 } 9652 }
9157 break; 9653 break;
9158 9654
9159 case ParcelMediaCommandEnum.Desc: 9655 case (uint)ParcelMediaCommandEnum.Desc:
9160 if ((i + 1) < commandList.Length) 9656 if ((i + 1) < commandList.Length)
9161 { 9657 {
9162 if (commandList.Data[i + 1] is LSL_String) 9658 if (commandList.Data[i + 1] is LSL_String)
@@ -9169,7 +9665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9169 } 9665 }
9170 break; 9666 break;
9171 9667
9172 case ParcelMediaCommandEnum.Size: 9668 case (uint)ParcelMediaCommandEnum.Size:
9173 if ((i + 2) < commandList.Length) 9669 if ((i + 2) < commandList.Length)
9174 { 9670 {
9175 if (commandList.Data[i + 1] is LSL_Integer) 9671 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9239,7 +9735,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9239 } 9735 }
9240 } 9736 }
9241 9737
9242 if (commandToSend != null) 9738 if (commandToSend != 0)
9243 { 9739 {
9244 // the commandList contained a start/stop/... command, too 9740 // the commandList contained a start/stop/... command, too
9245 if (presence == null) 9741 if (presence == null)
@@ -9276,7 +9772,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9276 9772
9277 if (aList.Data[i] != null) 9773 if (aList.Data[i] != null)
9278 { 9774 {
9279 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9775 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9280 { 9776 {
9281 case ParcelMediaCommandEnum.Url: 9777 case ParcelMediaCommandEnum.Url:
9282 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9778 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9319,16 +9815,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9319 { 9815 {
9320 m_host.AddScriptLPS(1); 9816 m_host.AddScriptLPS(1);
9321 9817
9322 lock (m_host.TaskInventory) 9818 m_host.TaskInventory.LockItemsForRead(true);
9819 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9323 { 9820 {
9324 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9821 if (inv.Value.Name == name)
9325 { 9822 {
9326 if (inv.Value.Name == name) 9823 m_host.TaskInventory.LockItemsForRead(false);
9327 { 9824 return inv.Value.Type;
9328 return inv.Value.Type;
9329 }
9330 } 9825 }
9331 } 9826 }
9827 m_host.TaskInventory.LockItemsForRead(false);
9332 9828
9333 return -1; 9829 return -1;
9334 } 9830 }
@@ -9339,15 +9835,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9339 9835
9340 if (quick_pay_buttons.Data.Length < 4) 9836 if (quick_pay_buttons.Data.Length < 4)
9341 { 9837 {
9342 LSLError("List must have at least 4 elements"); 9838 int x;
9343 return; 9839 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9840 {
9841 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9842 }
9344 } 9843 }
9345 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9844 int[] nPrice = new int[5];
9346 9845 nPrice[0] = price;
9347 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9846 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9348 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9847 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9349 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9848 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9350 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9849 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9850 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9351 m_host.ParentGroup.HasGroupChanged = true; 9851 m_host.ParentGroup.HasGroupChanged = true;
9352 } 9852 }
9353 9853
@@ -9359,17 +9859,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9359 if (invItemID == UUID.Zero) 9859 if (invItemID == UUID.Zero)
9360 return new LSL_Vector(); 9860 return new LSL_Vector();
9361 9861
9362 lock (m_host.TaskInventory) 9862 m_host.TaskInventory.LockItemsForRead(true);
9863 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9363 { 9864 {
9364 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9865 m_host.TaskInventory.LockItemsForRead(false);
9365 return new LSL_Vector(); 9866 return new LSL_Vector();
9867 }
9366 9868
9367 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9869 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9368 { 9870 {
9369 ShoutError("No permissions to track the camera"); 9871 ShoutError("No permissions to track the camera");
9370 return new LSL_Vector(); 9872 m_host.TaskInventory.LockItemsForRead(false);
9371 } 9873 return new LSL_Vector();
9372 } 9874 }
9875 m_host.TaskInventory.LockItemsForRead(false);
9373 9876
9374 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9877 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9375 if (presence != null) 9878 if (presence != null)
@@ -9387,17 +9890,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9387 if (invItemID == UUID.Zero) 9890 if (invItemID == UUID.Zero)
9388 return new LSL_Rotation(); 9891 return new LSL_Rotation();
9389 9892
9390 lock (m_host.TaskInventory) 9893 m_host.TaskInventory.LockItemsForRead(true);
9894 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9391 { 9895 {
9392 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9896 m_host.TaskInventory.LockItemsForRead(false);
9393 return new LSL_Rotation(); 9897 return new LSL_Rotation();
9394
9395 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9396 {
9397 ShoutError("No permissions to track the camera");
9398 return new LSL_Rotation();
9399 }
9400 } 9898 }
9899 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9900 {
9901 ShoutError("No permissions to track the camera");
9902 m_host.TaskInventory.LockItemsForRead(false);
9903 return new LSL_Rotation();
9904 }
9905 m_host.TaskInventory.LockItemsForRead(false);
9401 9906
9402 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9907 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9403 if (presence != null) 9908 if (presence != null)
@@ -9459,8 +9964,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9459 { 9964 {
9460 m_host.AddScriptLPS(1); 9965 m_host.AddScriptLPS(1);
9461 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9966 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9462 if (detectedParams == null) return; // only works on the first detected avatar 9967 if (detectedParams == null)
9463 9968 {
9969 if (m_host.IsAttachment == true)
9970 {
9971 detectedParams = new DetectParams();
9972 detectedParams.Key = m_host.OwnerID;
9973 }
9974 else
9975 {
9976 return;
9977 }
9978 }
9979
9464 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9980 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9465 if (avatar != null) 9981 if (avatar != null)
9466 { 9982 {
@@ -9468,6 +9984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9468 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9984 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9469 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9985 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9470 } 9986 }
9987
9471 ScriptSleep(1000); 9988 ScriptSleep(1000);
9472 } 9989 }
9473 9990
@@ -9560,14 +10077,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9560 if (objectID == UUID.Zero) return; 10077 if (objectID == UUID.Zero) return;
9561 10078
9562 UUID agentID; 10079 UUID agentID;
9563 lock (m_host.TaskInventory) 10080 m_host.TaskInventory.LockItemsForRead(true);
9564 { 10081 // we need the permission first, to know which avatar we want to set the camera for
9565 // we need the permission first, to know which avatar we want to set the camera for 10082 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9566 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9567 10083
9568 if (agentID == UUID.Zero) return; 10084 if (agentID == UUID.Zero)
9569 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10085 {
10086 m_host.TaskInventory.LockItemsForRead(false);
10087 return;
9570 } 10088 }
10089 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10090 {
10091 m_host.TaskInventory.LockItemsForRead(false);
10092 return;
10093 }
10094 m_host.TaskInventory.LockItemsForRead(false);
9571 10095
9572 ScenePresence presence = World.GetScenePresence(agentID); 10096 ScenePresence presence = World.GetScenePresence(agentID);
9573 10097
@@ -9576,12 +10100,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9576 10100
9577 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10101 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9578 object[] data = rules.Data; 10102 object[] data = rules.Data;
9579 for (int i = 0; i < data.Length; ++i) { 10103 for (int i = 0; i < data.Length; ++i)
10104 {
9580 int type = Convert.ToInt32(data[i++].ToString()); 10105 int type = Convert.ToInt32(data[i++].ToString());
9581 if (i >= data.Length) break; // odd number of entries => ignore the last 10106 if (i >= data.Length) break; // odd number of entries => ignore the last
9582 10107
9583 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10108 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9584 switch (type) { 10109 switch (type)
10110 {
9585 case ScriptBaseClass.CAMERA_FOCUS: 10111 case ScriptBaseClass.CAMERA_FOCUS:
9586 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10112 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9587 case ScriptBaseClass.CAMERA_POSITION: 10113 case ScriptBaseClass.CAMERA_POSITION:
@@ -9617,12 +10143,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9617 10143
9618 // we need the permission first, to know which avatar we want to clear the camera for 10144 // we need the permission first, to know which avatar we want to clear the camera for
9619 UUID agentID; 10145 UUID agentID;
9620 lock (m_host.TaskInventory) 10146 m_host.TaskInventory.LockItemsForRead(true);
10147 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10148 if (agentID == UUID.Zero)
9621 { 10149 {
9622 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10150 m_host.TaskInventory.LockItemsForRead(false);
9623 if (agentID == UUID.Zero) return; 10151 return;
9624 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9625 } 10152 }
10153 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10154 {
10155 m_host.TaskInventory.LockItemsForRead(false);
10156 return;
10157 }
10158 m_host.TaskInventory.LockItemsForRead(false);
9626 10159
9627 ScenePresence presence = World.GetScenePresence(agentID); 10160 ScenePresence presence = World.GetScenePresence(agentID);
9628 10161
@@ -9689,19 +10222,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9689 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10222 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9690 { 10223 {
9691 m_host.AddScriptLPS(1); 10224 m_host.AddScriptLPS(1);
9692 string ret = String.Empty; 10225
9693 string src1 = llBase64ToString(str1); 10226 if (str1 == String.Empty)
9694 string src2 = llBase64ToString(str2); 10227 return String.Empty;
9695 int c = 0; 10228 if (str2 == String.Empty)
9696 for (int i = 0; i < src1.Length; i++) 10229 return str1;
10230
10231 int len = str2.Length;
10232 if ((len % 4) != 0) // LL is EVIL!!!!
10233 {
10234 while (str2.EndsWith("="))
10235 str2 = str2.Substring(0, str2.Length - 1);
10236
10237 len = str2.Length;
10238 int mod = len % 4;
10239
10240 if (mod == 1)
10241 str2 = str2.Substring(0, str2.Length - 1);
10242 else if (mod == 2)
10243 str2 += "==";
10244 else if (mod == 3)
10245 str2 += "=";
10246 }
10247
10248 byte[] data1;
10249 byte[] data2;
10250 try
10251 {
10252 data1 = Convert.FromBase64String(str1);
10253 data2 = Convert.FromBase64String(str2);
10254 }
10255 catch (Exception)
9697 { 10256 {
9698 ret += (char) (src1[i] ^ src2[c]); 10257 return new LSL_String(String.Empty);
10258 }
9699 10259
9700 c++; 10260 byte[] d2 = new Byte[data1.Length];
9701 if (c >= src2.Length) 10261 int pos = 0;
9702 c = 0; 10262
10263 if (data1.Length <= data2.Length)
10264 {
10265 Array.Copy(data2, 0, d2, 0, data1.Length);
9703 } 10266 }
9704 return llStringToBase64(ret); 10267 else
10268 {
10269 while (pos < data1.Length)
10270 {
10271 len = data1.Length - pos;
10272 if (len > data2.Length)
10273 len = data2.Length;
10274
10275 Array.Copy(data2, 0, d2, pos, len);
10276 pos += len;
10277 }
10278 }
10279
10280 for (pos = 0 ; pos < data1.Length ; pos++ )
10281 data1[pos] ^= d2[pos];
10282
10283 return Convert.ToBase64String(data1);
9705 } 10284 }
9706 10285
9707 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10286 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9760,12 +10339,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9760 Regex r = new Regex(authregex); 10339 Regex r = new Regex(authregex);
9761 int[] gnums = r.GetGroupNumbers(); 10340 int[] gnums = r.GetGroupNumbers();
9762 Match m = r.Match(url); 10341 Match m = r.Match(url);
9763 if (m.Success) { 10342 if (m.Success)
9764 for (int i = 1; i < gnums.Length; i++) { 10343 {
10344 for (int i = 1; i < gnums.Length; i++)
10345 {
9765 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10346 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9766 //CaptureCollection cc = g.Captures; 10347 //CaptureCollection cc = g.Captures;
9767 } 10348 }
9768 if (m.Groups.Count == 5) { 10349 if (m.Groups.Count == 5)
10350 {
9769 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10351 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9770 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10352 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9771 } 10353 }
@@ -10082,15 +10664,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10082 10664
10083 internal UUID ScriptByName(string name) 10665 internal UUID ScriptByName(string name)
10084 { 10666 {
10085 lock (m_host.TaskInventory) 10667 m_host.TaskInventory.LockItemsForRead(true);
10668
10669 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10086 { 10670 {
10087 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10671 if (item.Type == 10 && item.Name == name)
10088 { 10672 {
10089 if (item.Type == 10 && item.Name == name) 10673 m_host.TaskInventory.LockItemsForRead(false);
10090 return item.ItemID; 10674 return item.ItemID;
10091 } 10675 }
10092 } 10676 }
10093 10677
10678 m_host.TaskInventory.LockItemsForRead(false);
10679
10094 return UUID.Zero; 10680 return UUID.Zero;
10095 } 10681 }
10096 10682
@@ -10131,6 +10717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10131 { 10717 {
10132 m_host.AddScriptLPS(1); 10718 m_host.AddScriptLPS(1);
10133 10719
10720 //Clone is thread safe
10134 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10721 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10135 10722
10136 UUID assetID = UUID.Zero; 10723 UUID assetID = UUID.Zero;
@@ -10193,6 +10780,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10193 { 10780 {
10194 m_host.AddScriptLPS(1); 10781 m_host.AddScriptLPS(1);
10195 10782
10783 //Clone is thread safe
10196 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10784 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10197 10785
10198 UUID assetID = UUID.Zero; 10786 UUID assetID = UUID.Zero;
@@ -10272,6 +10860,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10272 10860
10273 return GetLinkPrimitiveParams(obj, rules); 10861 return GetLinkPrimitiveParams(obj, rules);
10274 } 10862 }
10863
10864 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10865 {
10866 List<SceneObjectPart> parts = GetLinkParts(link);
10867 if (parts.Count < 1)
10868 return 0;
10869
10870 return GetNumberOfSides(parts[0]);
10871 }
10275 } 10872 }
10276 10873
10277 public class NotecardCache 10874 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index bca08fb..3f0393d 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()
@@ -835,18 +844,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
835 if (target != null) 844 if (target != null)
836 { 845 {
837 UUID animID=UUID.Zero; 846 UUID animID=UUID.Zero;
838 lock (m_host.TaskInventory) 847 m_host.TaskInventory.LockItemsForRead(true);
848 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
839 { 849 {
840 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 850 if (inv.Value.Name == animation)
841 { 851 {
842 if (inv.Value.Name == animation) 852 if (inv.Value.Type == (int)AssetType.Animation)
843 { 853 animID = inv.Value.AssetID;
844 if (inv.Value.Type == (int)AssetType.Animation) 854 continue;
845 animID = inv.Value.AssetID;
846 continue;
847 }
848 } 855 }
849 } 856 }
857 m_host.TaskInventory.LockItemsForRead(false);
850 if (animID == UUID.Zero) 858 if (animID == UUID.Zero)
851 target.Animator.AddAnimation(animation, m_host.UUID); 859 target.Animator.AddAnimation(animation, m_host.UUID);
852 else 860 else
@@ -868,18 +876,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
868 if (target != null) 876 if (target != null)
869 { 877 {
870 UUID animID=UUID.Zero; 878 UUID animID=UUID.Zero;
871 lock (m_host.TaskInventory) 879 m_host.TaskInventory.LockItemsForRead(true);
880 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
872 { 881 {
873 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 882 if (inv.Value.Name == animation)
874 { 883 {
875 if (inv.Value.Name == animation) 884 if (inv.Value.Type == (int)AssetType.Animation)
876 { 885 animID = inv.Value.AssetID;
877 if (inv.Value.Type == (int)AssetType.Animation) 886 continue;
878 animID = inv.Value.AssetID;
879 continue;
880 }
881 } 887 }
882 } 888 }
889 m_host.TaskInventory.LockItemsForRead(false);
883 890
884 if (animID == UUID.Zero) 891 if (animID == UUID.Zero)
885 target.Animator.RemoveAnimation(animation); 892 target.Animator.RemoveAnimation(animation);
@@ -1772,6 +1779,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1779
1773 if (!UUID.TryParse(name, out assetID)) 1780 if (!UUID.TryParse(name, out assetID))
1774 { 1781 {
1782 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1783 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1784 {
1777 if (item.Type == 7 && item.Name == name) 1785 if (item.Type == 7 && item.Name == name)
@@ -1779,6 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1787 assetID = item.AssetID;
1780 } 1788 }
1781 } 1789 }
1790 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1791 }
1783 1792
1784 if (assetID == UUID.Zero) 1793 if (assetID == UUID.Zero)
@@ -1825,6 +1834,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1825 1834
1826 if (!UUID.TryParse(name, out assetID)) 1835 if (!UUID.TryParse(name, out assetID))
1827 { 1836 {
1837 m_host.TaskInventory.LockItemsForRead(true);
1828 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1838 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1829 { 1839 {
1830 if (item.Type == 7 && item.Name == name) 1840 if (item.Type == 7 && item.Name == name)
@@ -1832,6 +1842,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1832 assetID = item.AssetID; 1842 assetID = item.AssetID;
1833 } 1843 }
1834 } 1844 }
1845 m_host.TaskInventory.LockItemsForRead(false);
1835 } 1846 }
1836 1847
1837 if (assetID == UUID.Zero) 1848 if (assetID == UUID.Zero)
@@ -1882,6 +1893,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1882 1893
1883 if (!UUID.TryParse(name, out assetID)) 1894 if (!UUID.TryParse(name, out assetID))
1884 { 1895 {
1896 m_host.TaskInventory.LockItemsForRead(true);
1885 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1897 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1886 { 1898 {
1887 if (item.Type == 7 && item.Name == name) 1899 if (item.Type == 7 && item.Name == name)
@@ -1889,6 +1901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1889 assetID = item.AssetID; 1901 assetID = item.AssetID;
1890 } 1902 }
1891 } 1903 }
1904 m_host.TaskInventory.LockItemsForRead(false);
1892 } 1905 }
1893 1906
1894 if (assetID == UUID.Zero) 1907 if (assetID == UUID.Zero)
@@ -2368,9 +2381,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2368 { 2381 {
2369 if (avatar.IsChildAgent == false) 2382 if (avatar.IsChildAgent == false)
2370 { 2383 {
2371 result.Add(avatar.UUID); 2384 result.Add(new LSL_Key(avatar.UUID.ToString()));
2372 result.Add(avatar.AbsolutePosition); 2385 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2373 result.Add(avatar.Name); 2386 result.Add(new LSL_String(avatar.Name));
2374 } 2387 }
2375 } 2388 }
2376 }); 2389 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index fefbb35..c4f90d2 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
@@ -301,7 +301,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
301 float dy; 301 float dy;
302 float dz; 302 float dz;
303 303
304 Quaternion q = SensePoint.RotationOffset; 304// Quaternion q = SensePoint.RotationOffset;
305 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
305 if (SensePoint.ParentGroup.RootPart.IsAttachment) 306 if (SensePoint.ParentGroup.RootPart.IsAttachment)
306 { 307 {
307 // In attachments, the sensor cone always orients with the 308 // In attachments, the sensor cone always orients with the
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // in mouselook. 310 // in mouselook.
310 311
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -422,6 +424,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
422 SceneObjectPart SensePoint = ts.host; 424 SceneObjectPart SensePoint = ts.host;
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 425 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 Quaternion q = SensePoint.RotationOffset; 426 Quaternion q = SensePoint.RotationOffset;
427 if (SensePoint.ParentGroup.RootPart.IsAttachment)
428 {
429 // In attachments, the sensor cone always orients with the
430 // avatar rotation. This may include a nonzero elevation if
431 // in mouselook.
432
433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
434 fromRegionPos = avatar.AbsolutePosition;
435 q = avatar.Rotation;
436 }
425 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 437 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); 438 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
427 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 439 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 561e3b3..bae7d4b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -398,6 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
398 LSL_Vector llWind(LSL_Vector offset); 398 LSL_Vector llWind(LSL_Vector offset);
399 LSL_String llXorBase64Strings(string str1, string str2); 399 LSL_String llXorBase64Strings(string str1, string str2);
400 LSL_String llXorBase64StringsCorrect(string str1, string str2); 400 LSL_String llXorBase64StringsCorrect(string str1, string str2);
401 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
401 402
402 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 403 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
403 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 404 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 63007c6..c08ad3b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index b3c4d95..93d544b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -279,6 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
280 public const int CHANGED_MEDIA = 2048; 280 public const int CHANGED_MEDIA = 2048;
281 public const int CHANGED_ANIMATION = 16384; 281 public const int CHANGED_ANIMATION = 16384;
282 public const int CHANGED_POSITION = 32768;
282 public const int TYPE_INVALID = 0; 283 public const int TYPE_INVALID = 0;
283 public const int TYPE_INTEGER = 1; 284 public const int TYPE_INTEGER = 1;
284 public const int TYPE_FLOAT = 2; 285 public const int TYPE_FLOAT = 2;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 451163f..7c26824 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
@@ -1847,5 +1849,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1847 { 1849 {
1848 return m_LSL_Functions.llClearPrimMedia(face); 1850 return m_LSL_Functions.llClearPrimMedia(face);
1849 } 1851 }
1852
1853 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1854 {
1855 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1856 }
1850 } 1857 }
1851} 1858}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 3575889..e9edf6c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 783791f..9548253 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -434,14 +435,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
434 { 435 {
435 int permsMask; 436 int permsMask;
436 UUID permsGranter; 437 UUID permsGranter;
437 lock (part.TaskInventory) 438 part.TaskInventory.LockItemsForRead(true);
439 if (!part.TaskInventory.ContainsKey(m_ItemID))
438 { 440 {
439 if (!part.TaskInventory.ContainsKey(m_ItemID)) 441 part.TaskInventory.LockItemsForRead(false);
440 return; 442 return;
441
442 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
443 permsMask = part.TaskInventory[m_ItemID].PermsMask;
444 } 443 }
444 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
445 permsMask = part.TaskInventory[m_ItemID].PermsMask;
446 part.TaskInventory.LockItemsForRead(false);
445 447
446 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 448 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
447 { 449 {
@@ -550,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
550 return true; 552 return true;
551 } 553 }
552 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
553 public void SetState(string state) 556 public void SetState(string state)
554 { 557 {
555 if (state == State) 558 if (state == State)
@@ -561,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 new DetectParams[0])); 564 new DetectParams[0]));
562 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
563 new DetectParams[0])); 566 new DetectParams[0]));
564 567
565 throw new EventAbortException(); 568 throw new EventAbortException();
566 } 569 }
567 570
@@ -644,14 +647,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
644 /// <returns></returns> 647 /// <returns></returns>
645 public object EventProcessor() 648 public object EventProcessor()
646 { 649 {
647 if (m_Suspended) 650 EventParams data = null;
648 return 0;
649 651
650 lock (m_Script) 652 lock (m_EventQueue)
651 { 653 {
652 EventParams data = null; 654 if (m_Suspended)
655 return 0;
653 656
654 lock (m_EventQueue) 657 lock (m_Script)
655 { 658 {
656 data = (EventParams) m_EventQueue.Dequeue(); 659 data = (EventParams) m_EventQueue.Dequeue();
657 if (data == null) // Shouldn't happen 660 if (data == null) // Shouldn't happen
@@ -677,6 +680,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
677 if (data.EventName == "collision") 680 if (data.EventName == "collision")
678 m_CollisionInQueue = false; 681 m_CollisionInQueue = false;
679 } 682 }
683 }
684 lock(m_Script)
685 {
680 686
681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 687 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
682 688
@@ -833,6 +839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
833 new Object[0], new DetectParams[0])); 839 new Object[0], new DetectParams[0]));
834 } 840 }
835 841
842 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
836 public void ApiResetScript() 843 public void ApiResetScript()
837 { 844 {
838 // bool running = Running; 845 // bool running = Running;
@@ -864,10 +871,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
864 871
865 public Dictionary<string, object> GetVars() 872 public Dictionary<string, object> GetVars()
866 { 873 {
867 if (m_Script != null) 874 return m_Script.GetVars();
868 return m_Script.GetVars();
869 else
870 return new Dictionary<string, object>();
871 } 875 }
872 876
873 public void SetVars(Dictionary<string, object> vars) 877 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 298d664..f810fd8 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
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 8629674..6bdd4c8 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -103,6 +104,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
103 private Dictionary<UUID, IScriptInstance> m_Scripts = 104 private Dictionary<UUID, IScriptInstance> m_Scripts =
104 new Dictionary<UUID, IScriptInstance>(); 105 new Dictionary<UUID, IScriptInstance>();
105 106
107 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
108
106 // Maps the asset ID to the assembly 109 // Maps the asset ID to the assembly
107 110
108 private Dictionary<UUID, string> m_Assemblies = 111 private Dictionary<UUID, string> m_Assemblies =
@@ -125,6 +128,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
125 IWorkItemResult m_CurrentCompile = null; 128 IWorkItemResult m_CurrentCompile = null;
126 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 129 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
127 130
131 private void lockScriptsForRead(bool locked)
132 {
133 if (locked)
134 {
135 if (m_scriptsLock.RecursiveReadCount > 0)
136 {
137 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
138 m_scriptsLock.ExitReadLock();
139 }
140 if (m_scriptsLock.RecursiveWriteCount > 0)
141 {
142 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
143 m_scriptsLock.ExitWriteLock();
144 }
145
146 while (!m_scriptsLock.TryEnterReadLock(60000))
147 {
148 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
149 if (m_scriptsLock.IsWriteLockHeld)
150 {
151 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
152 }
153 }
154 }
155 else
156 {
157 if (m_scriptsLock.RecursiveReadCount > 0)
158 {
159 m_scriptsLock.ExitReadLock();
160 }
161 }
162 }
163 private void lockScriptsForWrite(bool locked)
164 {
165 if (locked)
166 {
167 if (m_scriptsLock.RecursiveReadCount > 0)
168 {
169 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
170 m_scriptsLock.ExitReadLock();
171 }
172 if (m_scriptsLock.RecursiveWriteCount > 0)
173 {
174 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
175 m_scriptsLock.ExitWriteLock();
176 }
177
178 while (!m_scriptsLock.TryEnterWriteLock(60000))
179 {
180 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
181 if (m_scriptsLock.IsWriteLockHeld)
182 {
183 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
184 }
185 }
186 }
187 else
188 {
189 if (m_scriptsLock.RecursiveWriteCount > 0)
190 {
191 m_scriptsLock.ExitWriteLock();
192 }
193 }
194 }
195
128 public string ScriptEngineName 196 public string ScriptEngineName
129 { 197 {
130 get { return "XEngine"; } 198 get { return "XEngine"; }
@@ -270,43 +338,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
270 338
271 public void RemoveRegion(Scene scene) 339 public void RemoveRegion(Scene scene)
272 { 340 {
273 lock (m_Scripts) 341 lockScriptsForRead(true);
342 foreach (IScriptInstance instance in m_Scripts.Values)
274 { 343 {
275 foreach (IScriptInstance instance in m_Scripts.Values) 344 // Force a final state save
345 //
346 if (m_Assemblies.ContainsKey(instance.AssetID))
276 { 347 {
277 // Force a final state save 348 string assembly = m_Assemblies[instance.AssetID];
278 // 349 instance.SaveState(assembly);
279 if (m_Assemblies.ContainsKey(instance.AssetID)) 350 }
280 {
281 string assembly = m_Assemblies[instance.AssetID];
282 instance.SaveState(assembly);
283 }
284 351
285 // Clear the event queue and abort the instance thread 352 // Clear the event queue and abort the instance thread
286 // 353 //
287 instance.ClearQueue(); 354 instance.ClearQueue();
288 instance.Stop(0); 355 instance.Stop(0);
289 356
290 // Release events, timer, etc 357 // Release events, timer, etc
291 // 358 //
292 instance.DestroyScriptInstance(); 359 instance.DestroyScriptInstance();
293 360
294 // Unload scripts and app domains 361 // Unload scripts and app domains
295 // Must be done explicitly because they have infinite 362 // Must be done explicitly because they have infinite
296 // lifetime 363 // lifetime
297 // 364 //
298 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 365 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
299 if (m_DomainScripts[instance.AppDomain].Count == 0) 366 if (m_DomainScripts[instance.AppDomain].Count == 0)
300 { 367 {
301 m_DomainScripts.Remove(instance.AppDomain); 368 m_DomainScripts.Remove(instance.AppDomain);
302 UnloadAppDomain(instance.AppDomain); 369 UnloadAppDomain(instance.AppDomain);
303 }
304 } 370 }
305 m_Scripts.Clear();
306 m_PrimObjects.Clear();
307 m_Assemblies.Clear();
308 m_DomainScripts.Clear();
309 } 371 }
372 lockScriptsForRead(false);
373 lockScriptsForWrite(true);
374 m_Scripts.Clear();
375 lockScriptsForWrite(false);
376 m_PrimObjects.Clear();
377 m_Assemblies.Clear();
378 m_DomainScripts.Clear();
379
310 lock (m_ScriptEngines) 380 lock (m_ScriptEngines)
311 { 381 {
312 m_ScriptEngines.Remove(this); 382 m_ScriptEngines.Remove(this);
@@ -365,22 +435,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
365 435
366 List<IScriptInstance> instances = new List<IScriptInstance>(); 436 List<IScriptInstance> instances = new List<IScriptInstance>();
367 437
368 lock (m_Scripts) 438 lockScriptsForRead(true);
369 { 439 foreach (IScriptInstance instance in m_Scripts.Values)
370 foreach (IScriptInstance instance in m_Scripts.Values)
371 instances.Add(instance); 440 instances.Add(instance);
372 } 441 lockScriptsForRead(false);
373 442
374 foreach (IScriptInstance i in instances) 443 foreach (IScriptInstance i in instances)
375 { 444 {
376 string assembly = String.Empty; 445 string assembly = String.Empty;
377 446
378 lock (m_Scripts) 447
379 {
380 if (!m_Assemblies.ContainsKey(i.AssetID)) 448 if (!m_Assemblies.ContainsKey(i.AssetID))
381 continue; 449 continue;
382 assembly = m_Assemblies[i.AssetID]; 450 assembly = m_Assemblies[i.AssetID];
383 } 451
384 452
385 i.SaveState(assembly); 453 i.SaveState(assembly);
386 } 454 }
@@ -709,92 +777,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
709 } 777 }
710 778
711 ScriptInstance instance = null; 779 ScriptInstance instance = null;
712 lock (m_Scripts) 780 // Create the object record
781 lockScriptsForRead(true);
782 if ((!m_Scripts.ContainsKey(itemID)) ||
783 (m_Scripts[itemID].AssetID != assetID))
713 { 784 {
714 // Create the object record 785 lockScriptsForRead(false);
715 786
716 if ((!m_Scripts.ContainsKey(itemID)) || 787 UUID appDomain = assetID;
717 (m_Scripts[itemID].AssetID != assetID))
718 {
719 UUID appDomain = assetID;
720 788
721 if (part.ParentGroup.IsAttachment) 789 if (part.ParentGroup.IsAttachment)
722 appDomain = part.ParentGroup.RootPart.UUID; 790 appDomain = part.ParentGroup.RootPart.UUID;
723 791
724 if (!m_AppDomains.ContainsKey(appDomain)) 792 if (!m_AppDomains.ContainsKey(appDomain))
793 {
794 try
725 { 795 {
726 try 796 AppDomainSetup appSetup = new AppDomainSetup();
727 { 797 appSetup.PrivateBinPath = Path.Combine(
728 AppDomainSetup appSetup = new AppDomainSetup(); 798 m_ScriptEnginesPath,
729 appSetup.PrivateBinPath = Path.Combine( 799 m_Scene.RegionInfo.RegionID.ToString());
730 m_ScriptEnginesPath, 800
731 m_Scene.RegionInfo.RegionID.ToString()); 801 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
732 802 Evidence evidence = new Evidence(baseEvidence);
733 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 803
734 Evidence evidence = new Evidence(baseEvidence); 804 AppDomain sandbox;
735 805 if (m_AppDomainLoading)
736 AppDomain sandbox; 806 sandbox = AppDomain.CreateDomain(
737 if (m_AppDomainLoading) 807 m_Scene.RegionInfo.RegionID.ToString(),
738 sandbox = AppDomain.CreateDomain( 808 evidence, appSetup);
739 m_Scene.RegionInfo.RegionID.ToString(), 809 else
740 evidence, appSetup); 810 sandbox = AppDomain.CurrentDomain;
741 else 811
742 sandbox = AppDomain.CurrentDomain; 812 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
743 813 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
744 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 814 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
745 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 815 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
746 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 816 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
747 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 817 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
748 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 818 //sandbox.SetAppDomainPolicy(sandboxPolicy);
749 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 819
750 //sandbox.SetAppDomainPolicy(sandboxPolicy); 820 m_AppDomains[appDomain] = sandbox;
751 821
752 m_AppDomains[appDomain] = sandbox; 822 m_AppDomains[appDomain].AssemblyResolve +=
753 823 new ResolveEventHandler(
754 m_AppDomains[appDomain].AssemblyResolve += 824 AssemblyResolver.OnAssemblyResolve);
755 new ResolveEventHandler( 825 m_DomainScripts[appDomain] = new List<UUID>();
756 AssemblyResolver.OnAssemblyResolve); 826 }
757 m_DomainScripts[appDomain] = new List<UUID>(); 827 catch (Exception e)
758 } 828 {
759 catch (Exception e) 829 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
830 m_ScriptErrorMessage += "Exception creating app domain:\n";
831 m_ScriptFailCount++;
832 lock (m_AddingAssemblies)
760 { 833 {
761 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 834 m_AddingAssemblies[assembly]--;
762 m_ScriptErrorMessage += "Exception creating app domain:\n";
763 m_ScriptFailCount++;
764 lock (m_AddingAssemblies)
765 {
766 m_AddingAssemblies[assembly]--;
767 }
768 return false;
769 } 835 }
836 return false;
770 } 837 }
771 m_DomainScripts[appDomain].Add(itemID); 838 }
772 839 m_DomainScripts[appDomain].Add(itemID);
773 instance = new ScriptInstance(this, part, 840
774 itemID, assetID, assembly, 841 instance = new ScriptInstance(this, part,
775 m_AppDomains[appDomain], 842 itemID, assetID, assembly,
776 part.ParentGroup.RootPart.Name, 843 m_AppDomains[appDomain],
777 item.Name, startParam, postOnRez, 844 part.ParentGroup.RootPart.Name,
778 stateSource, m_MaxScriptQueue); 845 item.Name, startParam, postOnRez,
779 846 stateSource, m_MaxScriptQueue);
780 m_log.DebugFormat( 847
848 m_log.DebugFormat(
781 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 849 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
782 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 850 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
783 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 851 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
784 852
785 if (presence != null) 853 if (presence != null)
786 { 854 {
787 ShowScriptSaveResponse(item.OwnerID, 855 ShowScriptSaveResponse(item.OwnerID,
788 assetID, "Compile successful", true); 856 assetID, "Compile successful", true);
789 }
790
791 instance.AppDomain = appDomain;
792 instance.LineMap = linemap;
793
794 m_Scripts[itemID] = instance;
795 } 857 }
796 }
797 858
859 instance.AppDomain = appDomain;
860 instance.LineMap = linemap;
861 lockScriptsForWrite(true);
862 m_Scripts[itemID] = instance;
863 lockScriptsForWrite(false);
864 }
865 else
866 {
867 lockScriptsForRead(false);
868 }
798 lock (m_PrimObjects) 869 lock (m_PrimObjects)
799 { 870 {
800 if (!m_PrimObjects.ContainsKey(localID)) 871 if (!m_PrimObjects.ContainsKey(localID))
@@ -813,9 +884,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
813 m_AddingAssemblies[assembly]--; 884 m_AddingAssemblies[assembly]--;
814 } 885 }
815 886
816 if (instance != null) 887 if (instance!=null)
817 instance.Init(); 888 instance.Init();
818 889
819 return true; 890 return true;
820 } 891 }
821 892
@@ -828,20 +899,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
828 m_CompileDict.Remove(itemID); 899 m_CompileDict.Remove(itemID);
829 } 900 }
830 901
831 IScriptInstance instance = null; 902 lockScriptsForRead(true);
832 903 // Do we even have it?
833 lock (m_Scripts) 904 if (!m_Scripts.ContainsKey(itemID))
834 { 905 {
835 // Do we even have it? 906 lockScriptsForRead(false);
836 if (!m_Scripts.ContainsKey(itemID)) 907 return;
837 return;
838
839 instance=m_Scripts[itemID];
840 m_Scripts.Remove(itemID);
841 } 908 }
909
842 910
911 IScriptInstance instance=m_Scripts[itemID];
912 lockScriptsForRead(false);
913 lockScriptsForWrite(true);
914 m_Scripts.Remove(itemID);
915 lockScriptsForWrite(false);
843 instance.ClearQueue(); 916 instance.ClearQueue();
844 instance.Stop(0); 917 instance.Stop(0);
918
845// bool objectRemoved = false; 919// bool objectRemoved = false;
846 920
847 lock (m_PrimObjects) 921 lock (m_PrimObjects)
@@ -877,11 +951,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
877 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 951 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
878 if (handlerObjectRemoved != null) 952 if (handlerObjectRemoved != null)
879 { 953 {
880 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 954 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
881 handlerObjectRemoved(part.UUID); 955 handlerObjectRemoved(part.UUID);
882 } 956 }
883 957
884 958 CleanAssemblies();
959
885 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 960 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
886 if (handlerScriptRemoved != null) 961 if (handlerScriptRemoved != null)
887 handlerScriptRemoved(itemID); 962 handlerScriptRemoved(itemID);
@@ -1023,7 +1098,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1023 return false; 1098 return false;
1024 1099
1025 uuids = m_PrimObjects[localID]; 1100 uuids = m_PrimObjects[localID];
1026 } 1101
1027 1102
1028 foreach (UUID itemID in uuids) 1103 foreach (UUID itemID in uuids)
1029 { 1104 {
@@ -1041,6 +1116,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1041 result = true; 1116 result = true;
1042 } 1117 }
1043 } 1118 }
1119 }
1044 1120
1045 return result; 1121 return result;
1046 } 1122 }
@@ -1140,12 +1216,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1140 private IScriptInstance GetInstance(UUID itemID) 1216 private IScriptInstance GetInstance(UUID itemID)
1141 { 1217 {
1142 IScriptInstance instance; 1218 IScriptInstance instance;
1143 lock (m_Scripts) 1219 lockScriptsForRead(true);
1220 if (!m_Scripts.ContainsKey(itemID))
1144 { 1221 {
1145 if (!m_Scripts.ContainsKey(itemID)) 1222 lockScriptsForRead(false);
1146 return null; 1223 return null;
1147 instance = m_Scripts[itemID];
1148 } 1224 }
1225 instance = m_Scripts[itemID];
1226 lockScriptsForRead(false);
1149 return instance; 1227 return instance;
1150 } 1228 }
1151 1229
@@ -1169,6 +1247,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1169 return false; 1247 return false;
1170 } 1248 }
1171 1249
1250 [DebuggerNonUserCode]
1172 public void ApiResetScript(UUID itemID) 1251 public void ApiResetScript(UUID itemID)
1173 { 1252 {
1174 IScriptInstance instance = GetInstance(itemID); 1253 IScriptInstance instance = GetInstance(itemID);
@@ -1220,6 +1299,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1220 return UUID.Zero; 1299 return UUID.Zero;
1221 } 1300 }
1222 1301
1302 [DebuggerNonUserCode]
1223 public void SetState(UUID itemID, string newState) 1303 public void SetState(UUID itemID, string newState)
1224 { 1304 {
1225 IScriptInstance instance = GetInstance(itemID); 1305 IScriptInstance instance = GetInstance(itemID);
@@ -1240,11 +1320,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1240 { 1320 {
1241 List<IScriptInstance> instances = new List<IScriptInstance>(); 1321 List<IScriptInstance> instances = new List<IScriptInstance>();
1242 1322
1243 lock (m_Scripts) 1323 lockScriptsForRead(true);
1244 { 1324 foreach (IScriptInstance instance in m_Scripts.Values)
1245 foreach (IScriptInstance instance in m_Scripts.Values)
1246 instances.Add(instance); 1325 instances.Add(instance);
1247 } 1326 lockScriptsForRead(false);
1248 1327
1249 foreach (IScriptInstance i in instances) 1328 foreach (IScriptInstance i in instances)
1250 { 1329 {
@@ -1616,5 +1695,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1616 1695
1617 instance.Resume(); 1696 instance.Resume();
1618 } 1697 }
1698
1699 public bool HasScript(UUID itemID, out bool running)
1700 {
1701 running = true;
1702
1703 IScriptInstance instance = GetInstance(itemID);
1704 if (instance == null)
1705 return false;
1706
1707 running = instance.Running;
1708 return true;
1709 }
1619 } 1710 }
1620} 1711}