aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1842
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs15
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs47
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs28
13 files changed, 1364 insertions, 695 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 e6092d4..f55bd12 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -81,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 82 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 84 {
84 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 86 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 87 protected SceneObjectPart m_host;
87 protected uint m_localID; 88 protected uint m_localID;
@@ -99,6 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 100 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 101 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 102 protected bool m_scriptConsoleChannelEnabled = false;
103 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 104 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 105 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 106 new Dictionary<UUID, UserInfoCacheEntry>();
@@ -109,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
109 m_host = host; 111 m_host = host;
110 m_localID = localID; 112 m_localID = localID;
111 m_itemID = itemID; 113 m_itemID = itemID;
114 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 115
113 m_ScriptDelayFactor = 116 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 117 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 164 get { return m_ScriptEngine.World; }
162 } 165 }
163 166
167 [DebuggerNonUserCode]
164 public void state(string newState) 168 public void state(string newState)
165 { 169 {
166 m_ScriptEngine.SetState(m_itemID, newState); 170 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 174 /// Reset the named script. The script must be present
171 /// in the same prim. 175 /// in the same prim.
172 /// </summary> 176 /// </summary>
177 [DebuggerNonUserCode]
173 public void llResetScript() 178 public void llResetScript()
174 { 179 {
175 m_host.AddScriptLPS(1); 180 m_host.AddScriptLPS(1);
@@ -226,9 +231,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 231 }
227 } 232 }
228 233
234 public List<ScenePresence> GetLinkAvatars(int linkType)
235 {
236 List<ScenePresence> ret = new List<ScenePresence>();
237 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
238 return ret;
239
240 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
241
242 switch (linkType)
243 {
244 case ScriptBaseClass.LINK_SET:
245 return avs;
246
247 case ScriptBaseClass.LINK_ROOT:
248 return ret;
249
250 case ScriptBaseClass.LINK_ALL_OTHERS:
251 return avs;
252
253 case ScriptBaseClass.LINK_ALL_CHILDREN:
254 return avs;
255
256 case ScriptBaseClass.LINK_THIS:
257 return ret;
258
259 default:
260 if (linkType < 0)
261 return ret;
262
263 int partCount = m_host.ParentGroup.GetPartCount();
264
265 if (linkType <= partCount)
266 {
267 return ret;
268 }
269 else
270 {
271 linkType = linkType - partCount;
272 if (linkType > avs.Count)
273 {
274 return ret;
275 }
276 else
277 {
278 ret.Add(avs[linkType-1]);
279 return ret;
280 }
281 }
282 }
283 }
284
229 public List<SceneObjectPart> GetLinkParts(int linkType) 285 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 286 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 287 List<SceneObjectPart> ret = new List<SceneObjectPart>();
288 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
289 return ret;
232 ret.Add(m_host); 290 ret.Add(m_host);
233 291
234 switch (linkType) 292 switch (linkType)
@@ -288,40 +346,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 346 protected UUID InventorySelf()
289 { 347 {
290 UUID invItemID = new UUID(); 348 UUID invItemID = new UUID();
291 349 bool unlock = false;
292 lock (m_host.TaskInventory) 350 if (!m_host.TaskInventory.IsReadLockedByMe())
351 {
352 m_host.TaskInventory.LockItemsForRead(true);
353 unlock = true;
354 }
355 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
293 { 356 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 357 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 358 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 359 invItemID = inv.Key;
297 { 360 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 361 }
302 } 362 }
303 363 if (unlock)
364 {
365 m_host.TaskInventory.LockItemsForRead(false);
366 }
304 return invItemID; 367 return invItemID;
305 } 368 }
306 369
307 protected UUID InventoryKey(string name, int type) 370 protected UUID InventoryKey(string name, int type)
308 { 371 {
309 m_host.AddScriptLPS(1); 372 m_host.AddScriptLPS(1);
310 373 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 374
375 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 376 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 377 if (inv.Value.Name == name)
314 { 378 {
315 if (inv.Value.Name == name) 379 m_host.TaskInventory.LockItemsForRead(false);
380
381 if (inv.Value.Type != type)
316 { 382 {
317 if (inv.Value.Type != type) 383 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 384 }
385
386 return inv.Value.AssetID;
322 } 387 }
323 } 388 }
324 389
390 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 391 return UUID.Zero;
326 } 392 }
327 393
@@ -329,17 +395,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 395 {
330 m_host.AddScriptLPS(1); 396 m_host.AddScriptLPS(1);
331 397
332 lock (m_host.TaskInventory) 398
399 m_host.TaskInventory.LockItemsForRead(true);
400
401 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 402 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 403 if (inv.Value.Name == name)
335 { 404 {
336 if (inv.Value.Name == name) 405 m_host.TaskInventory.LockItemsForRead(false);
337 { 406 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 407 }
341 } 408 }
342 409
410 m_host.TaskInventory.LockItemsForRead(false);
411
412
343 return UUID.Zero; 413 return UUID.Zero;
344 } 414 }
345 415
@@ -481,26 +551,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 551
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 552 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 553
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 554 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
486 555
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 556 // normalize an angle between -PI and PI (-180 to +180 degrees)
557 protected double NormalizeAngle(double angle)
558 {
559 if (angle > -Math.PI && angle < Math.PI)
560 return angle;
561
562 int numPis = (int)(Math.PI / angle);
563 double remainder = angle - Math.PI * numPis;
564 if (numPis % 2 == 1)
565 return Math.PI - angle;
566 return remainder;
567 }
568
569 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 570 {
489 m_host.AddScriptLPS(1); 571 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 572 LSL_Vector eul = new LSL_Vector();
491 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 573
492 double m = (t.x + t.y + t.z + t.s); 574 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 575 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 576 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 577 double sqz = q1.y*q1.y;
496 if (p > 0) 578 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
497 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 579 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 580 if (test > 0.4999*unit) { // singularity at north pole
499 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 581 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 582 eul.y = Math.PI/2;
501 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 583 eul.x = 0;
502 else 584 return eul;
503 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 585 }
586 if (test < -0.4999*unit) { // singularity at south pole
587 eul.z = -2 * Math.Atan2(q1.x,q1.s);
588 eul.y = -Math.PI/2;
589 eul.x = 0;
590 return eul;
591 }
592 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
593 eul.y = Math.Asin(2*test/unit);
594 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
595 return eul;
504 } 596 }
505 597
506 /* From wiki: 598 /* From wiki:
@@ -702,77 +794,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 794 {
703 //A and B should both be normalized 795 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 796 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 797 /* This method is more accurate than the SL one, and thus causes problems
706 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 798 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 799
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 800 double dotProduct = LSL_Vector.Dot(a, b);
709 { 801 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 802 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
711 } 803 double angle = Math.Acos(dotProduct / magProduct);
712 else 804 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
713 { 805 double s = Math.Sin(angle / 2);
714 a = LSL_Vector.Norm(a); 806
715 b = LSL_Vector.Norm(b); 807 double x = axis.x * s;
716 double dotProduct = LSL_Vector.Dot(a, b); 808 double y = axis.y * s;
717 // There are two degenerate cases possible. These are for vectors 180 or 809 double z = axis.z * s;
718 // 0 degrees apart. These have to be detected and handled individually. 810 double w = Math.Cos(angle / 2);
719 // 811
720 // Check for vectors 180 degrees apart. 812 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
721 // A dot product of -1 would mean the angle between vectors is 180 degrees. 813 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
722 if (dotProduct < -0.9999999f) 814
723 { 815 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
724 // First assume X axis is orthogonal to the vectors. 816 */
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 817
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 818 // This method mimics the 180 errors found in SL
727 // Check for near zero vector. A very small non-zero number here will create 819 // See www.euclideanspace.com... angleBetween
728 // a rotation in an undesired direction. 820 LSL_Vector vec_a = a;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 821 LSL_Vector vec_b = b;
730 { 822
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 823 // Eliminate zero length
732 } 824 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
733 // If the magnitude of the vector was near zero, then assume the X axis is not 825 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
734 // orthogonal and use the Z axis instead. 826 if (vec_a_mag < 0.00001 ||
735 else 827 vec_b_mag < 0.00001)
736 { 828 {
737 // Set 180 z rotation. 829 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
738 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 830 }
739 } 831
740 } 832 // Normalize
741 // Check for parallel vectors. 833 vec_a = llVecNorm(vec_a);
742 // A dot product of 1 would mean the angle between vectors is 0 degrees. 834 vec_b = llVecNorm(vec_b);
743 else if (dotProduct > 0.9999999f) 835
744 { 836 // Calculate axis and rotation angle
745 // Set zero rotation. 837 LSL_Vector axis = vec_a % vec_b;
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 838 LSL_Float cos_theta = vec_a * vec_b;
747 } 839
748 else 840 // Check if parallel
749 { 841 if (cos_theta > 0.99999)
750 // All special checks have been performed so get the axis of rotation. 842 {
751 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
752 // Quarternion s value is the length of the unit vector + dot product. 844 }
753 double qs = 1.0 + dotProduct; 845
754 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 846 // Check if anti-parallel
755 // Normalize the rotation. 847 else if (cos_theta < -0.99999)
756 double mag = LSL_Rotation.Mag(rotBetween); 848 {
757 // We shouldn't have to worry about a divide by zero here. The qs value will be 849 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
758 // non-zero because we already know if we're here, then the dotProduct is not -1 so 850 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
759 // qs will not be zero. Also, we've already handled the input vectors being zero so the 851 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
760 // crossProduct vector should also not be zero. 852 }
761 rotBetween.x = rotBetween.x / mag; 853 else // other rotation
762 rotBetween.y = rotBetween.y / mag; 854 {
763 rotBetween.z = rotBetween.z / mag; 855 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
764 rotBetween.s = rotBetween.s / mag; 856 axis = llVecNorm(axis);
765 // Check for undefined values and set zero rotation if any found. This code might not actually be required 857 double x, y, z, s, t;
766 // any longer since zero vectors are checked for at the top. 858 s = Math.Cos(theta);
767 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 859 t = Math.Sin(theta);
768 { 860 x = axis.x * t;
769 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 861 y = axis.y * t;
770 } 862 z = axis.z * t;
771 } 863 return new LSL_Rotation(x,y,z,s);
772 } 864 }
773 return rotBetween; 865 }
774 } 866
775
776 public void llWhisper(int channelID, string text) 867 public void llWhisper(int channelID, string text)
777 { 868 {
778 m_host.AddScriptLPS(1); 869 m_host.AddScriptLPS(1);
@@ -1096,10 +1187,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1187 return detectedParams.TouchUV;
1097 } 1188 }
1098 1189
1190 [DebuggerNonUserCode]
1099 public virtual void llDie() 1191 public virtual void llDie()
1100 { 1192 {
1101 m_host.AddScriptLPS(1); 1193 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1194 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1195 }
1104 1196
1105 public LSL_Float llGround(LSL_Vector offset) 1197 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1264,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1264
1173 public void llSetStatus(int status, int value) 1265 public void llSetStatus(int status, int value)
1174 { 1266 {
1267 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1268 return;
1175 m_host.AddScriptLPS(1); 1269 m_host.AddScriptLPS(1);
1176 1270
1177 int statusrotationaxis = 0; 1271 int statusrotationaxis = 0;
@@ -1402,6 +1496,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1496 {
1403 m_host.AddScriptLPS(1); 1497 m_host.AddScriptLPS(1);
1404 1498
1499 SetColor(m_host, color, face);
1500 }
1501
1502 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1503 {
1504 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1505 return;
1506
1507 Primitive.TextureEntry tex = part.Shape.Textures;
1508 Color4 texcolor;
1509 if (face >= 0 && face < GetNumberOfSides(part))
1510 {
1511 texcolor = tex.CreateFace((uint)face).RGBA;
1512 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1513 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1514 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1515 tex.FaceTextures[face].RGBA = texcolor;
1516 part.UpdateTexture(tex);
1517 return;
1518 }
1519 else if (face == ScriptBaseClass.ALL_SIDES)
1520 {
1521 for (uint i = 0; i < GetNumberOfSides(part); i++)
1522 {
1523 if (tex.FaceTextures[i] != null)
1524 {
1525 texcolor = tex.FaceTextures[i].RGBA;
1526 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1527 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1528 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1529 tex.FaceTextures[i].RGBA = texcolor;
1530 }
1531 texcolor = tex.DefaultTexture.RGBA;
1532 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1533 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1534 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1535 tex.DefaultTexture.RGBA = texcolor;
1536 }
1537 part.UpdateTexture(tex);
1538 return;
1539 }
1540
1405 if (face == ScriptBaseClass.ALL_SIDES) 1541 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1542 face = SceneObjectPart.ALL_SIDES;
1407 1543
@@ -1410,6 +1546,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1546
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1547 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1548 {
1549 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1550 return;
1551
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1552 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1553 MappingType textype;
1415 textype = MappingType.Default; 1554 textype = MappingType.Default;
@@ -1440,6 +1579,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1579
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1580 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1581 {
1582 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1583 return;
1584
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1585 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1586 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1587 {
@@ -1465,6 +1607,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1607
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1608 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1609 {
1610 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1611 return;
1468 1612
1469 Shininess sval = new Shininess(); 1613 Shininess sval = new Shininess();
1470 1614
@@ -1515,6 +1659,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1659
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1660 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1661 {
1662 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1663 return;
1664
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1665 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1666 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1667 {
@@ -1575,13 +1722,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1722 m_host.AddScriptLPS(1);
1576 1723
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1724 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1725 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1726 {
1580 SetAlpha(part, alpha, face); 1727 try
1728 {
1729 parts[0].ParentGroup.areUpdatesSuspended = true;
1730 foreach (SceneObjectPart part in parts)
1731 SetAlpha(part, alpha, face);
1732 }
1733 finally
1734 {
1735 parts[0].ParentGroup.areUpdatesSuspended = false;
1736 }
1737 }
1581 } 1738 }
1582 1739
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1740 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1741 {
1742 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1743 return;
1744
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1745 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1746 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1747 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1787 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1788 float wind, float tension, LSL_Vector Force)
1629 { 1789 {
1630 if (part == null) 1790 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1791 return;
1632 1792
1633 if (flexi) 1793 if (flexi)
@@ -1662,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1822 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1823 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1824 {
1665 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1826 return;
1667 1827
1668 if (light) 1828 if (light)
@@ -1739,15 +1899,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1899 m_host.AddScriptLPS(1);
1740 1900
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1901 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1902 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1903 {
1744 SetTexture(part, texture, face); 1904 try
1745 1905 {
1906 parts[0].ParentGroup.areUpdatesSuspended = true;
1907 foreach (SceneObjectPart part in parts)
1908 SetTexture(part, texture, face);
1909 }
1910 finally
1911 {
1912 parts[0].ParentGroup.areUpdatesSuspended = false;
1913 }
1914 }
1746 ScriptSleep(200); 1915 ScriptSleep(200);
1747 } 1916 }
1748 1917
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1918 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1919 {
1920 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1921 return;
1922
1751 UUID textureID=new UUID(); 1923 UUID textureID=new UUID();
1752 1924
1753 if (!UUID.TryParse(texture, out textureID)) 1925 if (!UUID.TryParse(texture, out textureID))
@@ -1793,6 +1965,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1793 1965
1794 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1966 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1795 { 1967 {
1968 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1969 return;
1970
1796 Primitive.TextureEntry tex = part.Shape.Textures; 1971 Primitive.TextureEntry tex = part.Shape.Textures;
1797 if (face >= 0 && face < GetNumberOfSides(part)) 1972 if (face >= 0 && face < GetNumberOfSides(part))
1798 { 1973 {
@@ -1829,6 +2004,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1829 2004
1830 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2005 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1831 { 2006 {
2007 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2008 return;
2009
1832 Primitive.TextureEntry tex = part.Shape.Textures; 2010 Primitive.TextureEntry tex = part.Shape.Textures;
1833 if (face >= 0 && face < GetNumberOfSides(part)) 2011 if (face >= 0 && face < GetNumberOfSides(part))
1834 { 2012 {
@@ -1865,6 +2043,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1865 2043
1866 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2044 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1867 { 2045 {
2046 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2047 return;
2048
1868 Primitive.TextureEntry tex = part.Shape.Textures; 2049 Primitive.TextureEntry tex = part.Shape.Textures;
1869 if (face >= 0 && face < GetNumberOfSides(part)) 2050 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2051 {
@@ -1935,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1935 2116
1936 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2117 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1937 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1938 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2122 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1939 LSL_Vector currentPos = GetPartLocalPos(part); 2123 LSL_Vector currentPos = GetPartLocalPos(part);
1940 2124
@@ -1951,7 +2135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1951 } 2135 }
1952 else 2136 else
1953 { 2137 {
1954 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2138 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1955 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2139 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1956 SceneObjectGroup parent = part.ParentGroup; 2140 SceneObjectGroup parent = part.ParentGroup;
1957 parent.HasGroupChanged = true; 2141 parent.HasGroupChanged = true;
@@ -2034,6 +2218,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2034 2218
2035 protected void SetRot(SceneObjectPart part, Quaternion rot) 2219 protected void SetRot(SceneObjectPart part, Quaternion rot)
2036 { 2220 {
2221 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2222 return;
2223
2037 part.UpdateRotation(rot); 2224 part.UpdateRotation(rot);
2038 // Update rotation does not move the object in the physics scene if it's a linkset. 2225 // Update rotation does not move the object in the physics scene if it's a linkset.
2039 2226
@@ -2653,12 +2840,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2653 2840
2654 m_host.AddScriptLPS(1); 2841 m_host.AddScriptLPS(1);
2655 2842
2843 m_host.TaskInventory.LockItemsForRead(true);
2656 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2844 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2657 2845 m_host.TaskInventory.LockItemsForRead(false);
2658 lock (m_host.TaskInventory)
2659 {
2660 item = m_host.TaskInventory[invItemID];
2661 }
2662 2846
2663 if (item.PermsGranter == UUID.Zero) 2847 if (item.PermsGranter == UUID.Zero)
2664 return 0; 2848 return 0;
@@ -2733,6 +2917,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2733 if (dist > m_ScriptDistanceFactor * 10.0f) 2917 if (dist > m_ScriptDistanceFactor * 10.0f)
2734 return; 2918 return;
2735 2919
2920 //Clone is thread-safe
2736 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2921 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2737 2922
2738 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2923 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2795,6 +2980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2795 2980
2796 public void llLookAt(LSL_Vector target, double strength, double damping) 2981 public void llLookAt(LSL_Vector target, double strength, double damping)
2797 { 2982 {
2983 /*
2798 m_host.AddScriptLPS(1); 2984 m_host.AddScriptLPS(1);
2799 // Determine where we are looking from 2985 // Determine where we are looking from
2800 LSL_Vector from = llGetPos(); 2986 LSL_Vector from = llGetPos();
@@ -2814,10 +3000,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2814 // the angles of rotation in radians into rotation value 3000 // the angles of rotation in radians into rotation value
2815 3001
2816 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3002 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2817 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3003
2818 m_host.startLookAt(rotation, (float)damping, (float)strength); 3004 // This would only work if your physics system contains an APID controller:
3005 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3006 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3007
2819 // Orient the object to the angle calculated 3008 // Orient the object to the angle calculated
2820 //llSetRot(rot); 3009 llSetRot(rot);
3010 */
3011
3012 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3013 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3014 // http://bugs.meta7.com/view.php?id=28
3015 // - Tom
3016
3017 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3018 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3019
3020 }
3021
3022 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3023 {
3024 m_host.AddScriptLPS(1);
3025// NotImplemented("llRotLookAt");
3026 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3027
2821 } 3028 }
2822 3029
2823 public void llStopLookAt() 3030 public void llStopLookAt()
@@ -2866,13 +3073,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2866 { 3073 {
2867 TaskInventoryItem item; 3074 TaskInventoryItem item;
2868 3075
2869 lock (m_host.TaskInventory) 3076 m_host.TaskInventory.LockItemsForRead(true);
3077 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2870 { 3078 {
2871 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3079 m_host.TaskInventory.LockItemsForRead(false);
2872 return; 3080 return;
2873 else 3081 }
2874 item = m_host.TaskInventory[InventorySelf()]; 3082 else
3083 {
3084 item = m_host.TaskInventory[InventorySelf()];
2875 } 3085 }
3086 m_host.TaskInventory.LockItemsForRead(false);
2876 3087
2877 if (item.PermsGranter != UUID.Zero) 3088 if (item.PermsGranter != UUID.Zero)
2878 { 3089 {
@@ -2894,13 +3105,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2894 { 3105 {
2895 TaskInventoryItem item; 3106 TaskInventoryItem item;
2896 3107
3108 m_host.TaskInventory.LockItemsForRead(true);
2897 lock (m_host.TaskInventory) 3109 lock (m_host.TaskInventory)
2898 { 3110 {
3111
2899 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3112 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3113 {
3114 m_host.TaskInventory.LockItemsForRead(false);
2900 return; 3115 return;
3116 }
2901 else 3117 else
3118 {
2902 item = m_host.TaskInventory[InventorySelf()]; 3119 item = m_host.TaskInventory[InventorySelf()];
3120 }
2903 } 3121 }
3122 m_host.TaskInventory.LockItemsForRead(false);
2904 3123
2905 m_host.AddScriptLPS(1); 3124 m_host.AddScriptLPS(1);
2906 3125
@@ -2932,19 +3151,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 { 3151 {
2933 m_host.AddScriptLPS(1); 3152 m_host.AddScriptLPS(1);
2934 3153
2935 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2936 return;
2937
2938 TaskInventoryItem item; 3154 TaskInventoryItem item;
2939 3155
2940 lock (m_host.TaskInventory) 3156 m_host.TaskInventory.LockItemsForRead(true);
3157
3158 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2941 { 3159 {
2942 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3160 m_host.TaskInventory.LockItemsForRead(false);
2943 return; 3161 return;
2944 else 3162 }
2945 item = m_host.TaskInventory[InventorySelf()]; 3163 else
3164 {
3165 item = m_host.TaskInventory[InventorySelf()];
2946 } 3166 }
2947 3167
3168 m_host.TaskInventory.LockItemsForRead(false);
3169
2948 if (item.PermsGranter != m_host.OwnerID) 3170 if (item.PermsGranter != m_host.OwnerID)
2949 return; 3171 return;
2950 3172
@@ -2954,10 +3176,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2954 3176
2955 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3177 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2956 3178
2957 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3179 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 } 3180 }
2962 } 3181 }
2963 3182
@@ -2970,13 +3189,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2970 3189
2971 TaskInventoryItem item; 3190 TaskInventoryItem item;
2972 3191
2973 lock (m_host.TaskInventory) 3192 m_host.TaskInventory.LockItemsForRead(true);
3193
3194 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2974 { 3195 {
2975 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3196 m_host.TaskInventory.LockItemsForRead(false);
2976 return; 3197 return;
2977 else
2978 item = m_host.TaskInventory[InventorySelf()];
2979 } 3198 }
3199 else
3200 {
3201 item = m_host.TaskInventory[InventorySelf()];
3202 }
3203 m_host.TaskInventory.LockItemsForRead(false);
3204
2980 3205
2981 if (item.PermsGranter != m_host.OwnerID) 3206 if (item.PermsGranter != m_host.OwnerID)
2982 return; 3207 return;
@@ -3015,6 +3240,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3015 3240
3016 public void llInstantMessage(string user, string message) 3241 public void llInstantMessage(string user, string message)
3017 { 3242 {
3243 UUID result;
3244 if (!UUID.TryParse(user, out result))
3245 {
3246 ShoutError("An invalid key was passed to llInstantMessage");
3247 ScriptSleep(2000);
3248 return;
3249 }
3250
3251
3018 m_host.AddScriptLPS(1); 3252 m_host.AddScriptLPS(1);
3019 3253
3020 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3254 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3029,14 +3263,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3029 UUID friendTransactionID = UUID.Random(); 3263 UUID friendTransactionID = UUID.Random();
3030 3264
3031 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3265 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3032 3266
3033 GridInstantMessage msg = new GridInstantMessage(); 3267 GridInstantMessage msg = new GridInstantMessage();
3034 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3268 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3035 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3269 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3036 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3270 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3037// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3271// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3038// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3272// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3039 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3273 DateTime dt = DateTime.UtcNow;
3274
3275 // Ticks from UtcNow, but make it look like local. Evil, huh?
3276 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3277
3278 try
3279 {
3280 // Convert that to the PST timezone
3281 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3282 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3283 }
3284 catch
3285 {
3286 // No logging here, as it could be VERY spammy
3287 }
3288
3289 // And make it look local again to fool the unix time util
3290 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3291
3292 msg.timestamp = (uint)Util.ToUnixTime(dt);
3293
3040 //if (client != null) 3294 //if (client != null)
3041 //{ 3295 //{
3042 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3296 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3050,13 +3304,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 msg.message = message.Substring(0, 1024); 3304 msg.message = message.Substring(0, 1024);
3051 else 3305 else
3052 msg.message = message; 3306 msg.message = message;
3053 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3307 msg.dialog = (byte)19; // MessageFromObject
3054 msg.fromGroup = false;// fromGroup; 3308 msg.fromGroup = false;// fromGroup;
3055 msg.offline = (byte)0; //offline; 3309 msg.offline = (byte)0; //offline;
3056 msg.ParentEstateID = 0; //ParentEstateID; 3310 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3057 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3311 msg.Position = new Vector3(m_host.AbsolutePosition);
3058 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3312 msg.RegionID = World.RegionInfo.RegionID.Guid;
3059 msg.binaryBucket = new byte[0];// binaryBucket; 3313 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3060 3314
3061 if (m_TransferModule != null) 3315 if (m_TransferModule != null)
3062 { 3316 {
@@ -3076,7 +3330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3076 } 3330 }
3077 3331
3078 emailModule.SendEmail(m_host.UUID, address, subject, message); 3332 emailModule.SendEmail(m_host.UUID, address, subject, message);
3079 ScriptSleep(20000); 3333 ScriptSleep(15000);
3080 } 3334 }
3081 3335
3082 public void llGetNextEmail(string address, string subject) 3336 public void llGetNextEmail(string address, string subject)
@@ -3178,13 +3432,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3178 m_host.AddScriptLPS(1); 3432 m_host.AddScriptLPS(1);
3179 } 3433 }
3180 3434
3181 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3182 {
3183 m_host.AddScriptLPS(1);
3184 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3185 m_host.RotLookAt(rot, (float)strength, (float)damping);
3186 }
3187
3188 public LSL_Integer llStringLength(string str) 3435 public LSL_Integer llStringLength(string str)
3189 { 3436 {
3190 m_host.AddScriptLPS(1); 3437 m_host.AddScriptLPS(1);
@@ -3208,14 +3455,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3208 3455
3209 TaskInventoryItem item; 3456 TaskInventoryItem item;
3210 3457
3211 lock (m_host.TaskInventory) 3458 m_host.TaskInventory.LockItemsForRead(true);
3459 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3212 { 3460 {
3213 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3461 m_host.TaskInventory.LockItemsForRead(false);
3214 return; 3462 return;
3215 else
3216 item = m_host.TaskInventory[InventorySelf()];
3217 } 3463 }
3218 3464 else
3465 {
3466 item = m_host.TaskInventory[InventorySelf()];
3467 }
3468 m_host.TaskInventory.LockItemsForRead(false);
3219 if (item.PermsGranter == UUID.Zero) 3469 if (item.PermsGranter == UUID.Zero)
3220 return; 3470 return;
3221 3471
@@ -3245,13 +3495,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3245 3495
3246 TaskInventoryItem item; 3496 TaskInventoryItem item;
3247 3497
3248 lock (m_host.TaskInventory) 3498 m_host.TaskInventory.LockItemsForRead(true);
3499 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3249 { 3500 {
3250 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3501 m_host.TaskInventory.LockItemsForRead(false);
3251 return; 3502 return;
3252 else 3503 }
3253 item = m_host.TaskInventory[InventorySelf()]; 3504 else
3505 {
3506 item = m_host.TaskInventory[InventorySelf()];
3254 } 3507 }
3508 m_host.TaskInventory.LockItemsForRead(false);
3509
3255 3510
3256 if (item.PermsGranter == UUID.Zero) 3511 if (item.PermsGranter == UUID.Zero)
3257 return; 3512 return;
@@ -3322,10 +3577,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3322 3577
3323 TaskInventoryItem item; 3578 TaskInventoryItem item;
3324 3579
3325 lock (m_host.TaskInventory) 3580
3581 m_host.TaskInventory.LockItemsForRead(true);
3582 if (!m_host.TaskInventory.ContainsKey(invItemID))
3583 {
3584 m_host.TaskInventory.LockItemsForRead(false);
3585 return;
3586 }
3587 else
3326 { 3588 {
3327 item = m_host.TaskInventory[invItemID]; 3589 item = m_host.TaskInventory[invItemID];
3328 } 3590 }
3591 m_host.TaskInventory.LockItemsForRead(false);
3329 3592
3330 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3593 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3331 { 3594 {
@@ -3357,11 +3620,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3357 3620
3358 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3621 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3359 { 3622 {
3360 lock (m_host.TaskInventory) 3623 m_host.TaskInventory.LockItemsForWrite(true);
3361 { 3624 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3362 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3625 m_host.TaskInventory[invItemID].PermsMask = perm;
3363 m_host.TaskInventory[invItemID].PermsMask = perm; 3626 m_host.TaskInventory.LockItemsForWrite(false);
3364 }
3365 3627
3366 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3628 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3367 "run_time_permissions", new Object[] { 3629 "run_time_permissions", new Object[] {
@@ -3381,11 +3643,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3381 3643
3382 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3644 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3383 { 3645 {
3384 lock (m_host.TaskInventory) 3646 m_host.TaskInventory.LockItemsForWrite(true);
3385 { 3647 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3386 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3648 m_host.TaskInventory[invItemID].PermsMask = perm;
3387 m_host.TaskInventory[invItemID].PermsMask = perm; 3649 m_host.TaskInventory.LockItemsForWrite(false);
3388 }
3389 3650
3390 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3651 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3391 "run_time_permissions", new Object[] { 3652 "run_time_permissions", new Object[] {
@@ -3406,11 +3667,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3406 3667
3407 if (!m_waitingForScriptAnswer) 3668 if (!m_waitingForScriptAnswer)
3408 { 3669 {
3409 lock (m_host.TaskInventory) 3670 m_host.TaskInventory.LockItemsForWrite(true);
3410 { 3671 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3411 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3672 m_host.TaskInventory[invItemID].PermsMask = 0;
3412 m_host.TaskInventory[invItemID].PermsMask = 0; 3673 m_host.TaskInventory.LockItemsForWrite(false);
3413 }
3414 3674
3415 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3675 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3416 m_waitingForScriptAnswer=true; 3676 m_waitingForScriptAnswer=true;
@@ -3445,10 +3705,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3445 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3705 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3446 llReleaseControls(); 3706 llReleaseControls();
3447 3707
3448 lock (m_host.TaskInventory) 3708
3449 { 3709 m_host.TaskInventory.LockItemsForWrite(true);
3450 m_host.TaskInventory[invItemID].PermsMask = answer; 3710 m_host.TaskInventory[invItemID].PermsMask = answer;
3451 } 3711 m_host.TaskInventory.LockItemsForWrite(false);
3712
3452 3713
3453 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3714 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3454 "run_time_permissions", new Object[] { 3715 "run_time_permissions", new Object[] {
@@ -3460,16 +3721,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3460 { 3721 {
3461 m_host.AddScriptLPS(1); 3722 m_host.AddScriptLPS(1);
3462 3723
3463 lock (m_host.TaskInventory) 3724 m_host.TaskInventory.LockItemsForRead(true);
3725
3726 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3464 { 3727 {
3465 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3728 if (item.Type == 10 && item.ItemID == m_itemID)
3466 { 3729 {
3467 if (item.Type == 10 && item.ItemID == m_itemID) 3730 m_host.TaskInventory.LockItemsForRead(false);
3468 { 3731 return item.PermsGranter.ToString();
3469 return item.PermsGranter.ToString();
3470 }
3471 } 3732 }
3472 } 3733 }
3734 m_host.TaskInventory.LockItemsForRead(false);
3473 3735
3474 return UUID.Zero.ToString(); 3736 return UUID.Zero.ToString();
3475 } 3737 }
@@ -3478,19 +3740,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 { 3740 {
3479 m_host.AddScriptLPS(1); 3741 m_host.AddScriptLPS(1);
3480 3742
3481 lock (m_host.TaskInventory) 3743 m_host.TaskInventory.LockItemsForRead(true);
3744
3745 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3482 { 3746 {
3483 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3747 if (item.Type == 10 && item.ItemID == m_itemID)
3484 { 3748 {
3485 if (item.Type == 10 && item.ItemID == m_itemID) 3749 int perms = item.PermsMask;
3486 { 3750 if (m_automaticLinkPermission)
3487 int perms = item.PermsMask; 3751 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3488 if (m_automaticLinkPermission) 3752 m_host.TaskInventory.LockItemsForRead(false);
3489 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3753 return perms;
3490 return perms;
3491 }
3492 } 3754 }
3493 } 3755 }
3756 m_host.TaskInventory.LockItemsForRead(false);
3494 3757
3495 return 0; 3758 return 0;
3496 } 3759 }
@@ -3512,9 +3775,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3775 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3513 { 3776 {
3514 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3777 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3515 3778 if (parts.Count > 0)
3516 foreach (SceneObjectPart part in parts) 3779 {
3517 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3780 try
3781 {
3782 parts[0].ParentGroup.areUpdatesSuspended = true;
3783 foreach (SceneObjectPart part in parts)
3784 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3785 }
3786 finally
3787 {
3788 parts[0].ParentGroup.areUpdatesSuspended = false;
3789 }
3790 }
3518 } 3791 }
3519 3792
3520 public void llCreateLink(string target, int parent) 3793 public void llCreateLink(string target, int parent)
@@ -3527,11 +3800,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 return; 3800 return;
3528 3801
3529 TaskInventoryItem item; 3802 TaskInventoryItem item;
3530 lock (m_host.TaskInventory) 3803 m_host.TaskInventory.LockItemsForRead(true);
3531 { 3804 item = m_host.TaskInventory[invItemID];
3532 item = m_host.TaskInventory[invItemID]; 3805 m_host.TaskInventory.LockItemsForRead(false);
3533 } 3806
3534
3535 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3807 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3536 && !m_automaticLinkPermission) 3808 && !m_automaticLinkPermission)
3537 { 3809 {
@@ -3552,7 +3824,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3552 3824
3553 if (targetPart != null) 3825 if (targetPart != null)
3554 { 3826 {
3555 if (parent != 0) { 3827 if (parent != 0)
3828 {
3556 parentPrim = m_host.ParentGroup; 3829 parentPrim = m_host.ParentGroup;
3557 childPrim = targetPart.ParentGroup; 3830 childPrim = targetPart.ParentGroup;
3558 } 3831 }
@@ -3584,16 +3857,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3584 m_host.AddScriptLPS(1); 3857 m_host.AddScriptLPS(1);
3585 UUID invItemID = InventorySelf(); 3858 UUID invItemID = InventorySelf();
3586 3859
3587 lock (m_host.TaskInventory) 3860 m_host.TaskInventory.LockItemsForRead(true);
3588 {
3589 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3861 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3590 && !m_automaticLinkPermission) 3862 && !m_automaticLinkPermission)
3591 { 3863 {
3592 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3864 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3865 m_host.TaskInventory.LockItemsForRead(false);
3593 return; 3866 return;
3594 } 3867 }
3595 } 3868 m_host.TaskInventory.LockItemsForRead(false);
3596 3869
3597 if (linknum < ScriptBaseClass.LINK_THIS) 3870 if (linknum < ScriptBaseClass.LINK_THIS)
3598 return; 3871 return;
3599 3872
@@ -3632,10 +3905,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3632 // Restructuring Multiple Prims. 3905 // Restructuring Multiple Prims.
3633 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3906 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3634 parts.Remove(parentPrim.RootPart); 3907 parts.Remove(parentPrim.RootPart);
3635 foreach (SceneObjectPart part in parts) 3908 if (parts.Count > 0)
3636 { 3909 {
3637 parentPrim.DelinkFromGroup(part.LocalId, true); 3910 try
3911 {
3912 parts[0].ParentGroup.areUpdatesSuspended = true;
3913 foreach (SceneObjectPart part in parts)
3914 {
3915 parentPrim.DelinkFromGroup(part.LocalId, true);
3916 }
3917 }
3918 finally
3919 {
3920 parts[0].ParentGroup.areUpdatesSuspended = false;
3921 }
3638 } 3922 }
3923
3639 parentPrim.HasGroupChanged = true; 3924 parentPrim.HasGroupChanged = true;
3640 parentPrim.ScheduleGroupForFullUpdate(); 3925 parentPrim.ScheduleGroupForFullUpdate();
3641 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3926 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3644,11 +3929,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3644 { 3929 {
3645 SceneObjectPart newRoot = parts[0]; 3930 SceneObjectPart newRoot = parts[0];
3646 parts.Remove(newRoot); 3931 parts.Remove(newRoot);
3647 foreach (SceneObjectPart part in parts) 3932
3933 try
3648 { 3934 {
3649 part.UpdateFlag = 0; 3935 parts[0].ParentGroup.areUpdatesSuspended = true;
3650 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3936 foreach (SceneObjectPart part in parts)
3937 {
3938 part.UpdateFlag = 0;
3939 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3940 }
3651 } 3941 }
3942 finally
3943 {
3944 parts[0].ParentGroup.areUpdatesSuspended = false;
3945 }
3946
3947
3652 newRoot.ParentGroup.HasGroupChanged = true; 3948 newRoot.ParentGroup.HasGroupChanged = true;
3653 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3949 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3654 } 3950 }
@@ -3694,6 +3990,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3694 } 3990 }
3695 else 3991 else
3696 { 3992 {
3993 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
3994 {
3995 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3996
3997 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3998 if (avatars.Count > linknum)
3999 {
4000 return avatars[linknum].UUID.ToString();
4001 }
4002 }
3697 return UUID.Zero.ToString(); 4003 return UUID.Zero.ToString();
3698 } 4004 }
3699 } 4005 }
@@ -3770,17 +4076,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3770 m_host.AddScriptLPS(1); 4076 m_host.AddScriptLPS(1);
3771 int count = 0; 4077 int count = 0;
3772 4078
3773 lock (m_host.TaskInventory) 4079 m_host.TaskInventory.LockItemsForRead(true);
4080 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3774 { 4081 {
3775 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4082 if (inv.Value.Type == type || type == -1)
3776 { 4083 {
3777 if (inv.Value.Type == type || type == -1) 4084 count = count + 1;
3778 {
3779 count = count + 1;
3780 }
3781 } 4085 }
3782 } 4086 }
3783 4087
4088 m_host.TaskInventory.LockItemsForRead(false);
3784 return count; 4089 return count;
3785 } 4090 }
3786 4091
@@ -3789,16 +4094,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3789 m_host.AddScriptLPS(1); 4094 m_host.AddScriptLPS(1);
3790 ArrayList keys = new ArrayList(); 4095 ArrayList keys = new ArrayList();
3791 4096
3792 lock (m_host.TaskInventory) 4097 m_host.TaskInventory.LockItemsForRead(true);
4098 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3793 { 4099 {
3794 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4100 if (inv.Value.Type == type || type == -1)
3795 { 4101 {
3796 if (inv.Value.Type == type || type == -1) 4102 keys.Add(inv.Value.Name);
3797 {
3798 keys.Add(inv.Value.Name);
3799 }
3800 } 4103 }
3801 } 4104 }
4105 m_host.TaskInventory.LockItemsForRead(false);
3802 4106
3803 if (keys.Count == 0) 4107 if (keys.Count == 0)
3804 { 4108 {
@@ -3835,20 +4139,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3835 } 4139 }
3836 4140
3837 // move the first object found with this inventory name 4141 // move the first object found with this inventory name
3838 lock (m_host.TaskInventory) 4142 m_host.TaskInventory.LockItemsForRead(true);
4143 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3839 { 4144 {
3840 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4145 if (inv.Value.Name == inventory)
3841 { 4146 {
3842 if (inv.Value.Name == inventory) 4147 found = true;
3843 { 4148 objId = inv.Key;
3844 found = true; 4149 assetType = inv.Value.Type;
3845 objId = inv.Key; 4150 objName = inv.Value.Name;
3846 assetType = inv.Value.Type; 4151 break;
3847 objName = inv.Value.Name;
3848 break;
3849 }
3850 } 4152 }
3851 } 4153 }
4154 m_host.TaskInventory.LockItemsForRead(false);
3852 4155
3853 if (!found) 4156 if (!found)
3854 { 4157 {
@@ -3856,9 +4159,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3856 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4159 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3857 } 4160 }
3858 4161
3859 // check if destination is an avatar 4162 // check if destination is an object
3860 if (World.GetScenePresence(destId) != null) 4163 if (World.GetSceneObjectPart(destId) != null)
3861 { 4164 {
4165 // destination is an object
4166 World.MoveTaskInventoryItem(destId, m_host, objId);
4167 }
4168 else
4169 {
4170 ScenePresence presence = World.GetScenePresence(destId);
4171
4172 if (presence == null)
4173 {
4174 UserAccount account =
4175 World.UserAccountService.GetUserAccount(
4176 World.RegionInfo.ScopeID,
4177 destId);
4178
4179 if (account == null)
4180 {
4181 llSay(0, "Can't find destination "+destId.ToString());
4182 return;
4183 }
4184 }
4185
3862 // destination is an avatar 4186 // destination is an avatar
3863 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4187 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3864 4188
@@ -3882,31 +4206,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3882 4206
3883 if (m_TransferModule != null) 4207 if (m_TransferModule != null)
3884 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4208 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4209
4210 //This delay should only occur when giving inventory to avatars.
4211 ScriptSleep(3000);
3885 } 4212 }
3886 else
3887 {
3888 // destination is an object
3889 World.MoveTaskInventoryItem(destId, m_host, objId);
3890 }
3891 ScriptSleep(3000);
3892 } 4213 }
3893 4214
4215 [DebuggerNonUserCode]
3894 public void llRemoveInventory(string name) 4216 public void llRemoveInventory(string name)
3895 { 4217 {
3896 m_host.AddScriptLPS(1); 4218 m_host.AddScriptLPS(1);
3897 4219
3898 lock (m_host.TaskInventory) 4220 List<TaskInventoryItem> inv;
4221 try
3899 { 4222 {
3900 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4223 m_host.TaskInventory.LockItemsForRead(true);
4224 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4225 }
4226 finally
4227 {
4228 m_host.TaskInventory.LockItemsForRead(false);
4229 }
4230 foreach (TaskInventoryItem item in inv)
4231 {
4232 if (item.Name == name)
3901 { 4233 {
3902 if (item.Name == name) 4234 if (item.ItemID == m_itemID)
3903 { 4235 throw new ScriptDeleteException();
3904 if (item.ItemID == m_itemID) 4236 else
3905 throw new ScriptDeleteException(); 4237 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3906 else 4238 return;
3907 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3908 return;
3909 }
3910 } 4239 }
3911 } 4240 }
3912 } 4241 }
@@ -3972,6 +4301,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3972 ce.time = Util.EnvironmentTickCount(); 4301 ce.time = Util.EnvironmentTickCount();
3973 ce.account = account; 4302 ce.account = account;
3974 ce.pinfo = pinfo; 4303 ce.pinfo = pinfo;
4304 m_userInfoCache[uuid] = ce;
3975 } 4305 }
3976 else 4306 else
3977 { 4307 {
@@ -4047,6 +4377,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4047 { 4377 {
4048 m_host.AddScriptLPS(1); 4378 m_host.AddScriptLPS(1);
4049 4379
4380 //Clone is thread safe
4050 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4381 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4051 4382
4052 foreach (TaskInventoryItem item in itemDictionary.Values) 4383 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4100,6 +4431,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4100 ScenePresence presence = World.GetScenePresence(agentId); 4431 ScenePresence presence = World.GetScenePresence(agentId);
4101 if (presence != null) 4432 if (presence != null)
4102 { 4433 {
4434 // agent must not be a god
4435 if (presence.GodLevel >= 200) return;
4436
4103 // agent must be over the owners land 4437 // agent must be over the owners land
4104 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4438 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4105 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4439 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4159,17 +4493,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4159 UUID soundId = UUID.Zero; 4493 UUID soundId = UUID.Zero;
4160 if (!UUID.TryParse(impact_sound, out soundId)) 4494 if (!UUID.TryParse(impact_sound, out soundId))
4161 { 4495 {
4162 lock (m_host.TaskInventory) 4496 m_host.TaskInventory.LockItemsForRead(true);
4497 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4163 { 4498 {
4164 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4499 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4165 { 4500 {
4166 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4501 soundId = item.AssetID;
4167 { 4502 break;
4168 soundId = item.AssetID;
4169 break;
4170 }
4171 } 4503 }
4172 } 4504 }
4505 m_host.TaskInventory.LockItemsForRead(false);
4173 } 4506 }
4174 m_host.CollisionSound = soundId; 4507 m_host.CollisionSound = soundId;
4175 m_host.CollisionSoundVolume = (float)impact_volume; 4508 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4215,6 +4548,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4215 UUID partItemID; 4548 UUID partItemID;
4216 foreach (SceneObjectPart part in parts) 4549 foreach (SceneObjectPart part in parts)
4217 { 4550 {
4551 //Clone is thread safe
4218 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4552 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4219 4553
4220 foreach (TaskInventoryItem item in itemsDictionary.Values) 4554 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4429,17 +4763,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4429 4763
4430 m_host.AddScriptLPS(1); 4764 m_host.AddScriptLPS(1);
4431 4765
4432 lock (m_host.TaskInventory) 4766 m_host.TaskInventory.LockItemsForRead(true);
4767 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4433 { 4768 {
4434 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4769 if (item.Type == 10 && item.ItemID == m_itemID)
4435 { 4770 {
4436 if (item.Type == 10 && item.ItemID == m_itemID) 4771 result = item.Name!=null?item.Name:String.Empty;
4437 { 4772 break;
4438 result = item.Name != null ? item.Name : String.Empty;
4439 break;
4440 }
4441 } 4773 }
4442 } 4774 }
4775 m_host.TaskInventory.LockItemsForRead(false);
4443 4776
4444 return result; 4777 return result;
4445 } 4778 }
@@ -4592,23 +4925,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4592 { 4925 {
4593 m_host.AddScriptLPS(1); 4926 m_host.AddScriptLPS(1);
4594 4927
4595 lock (m_host.TaskInventory) 4928 m_host.TaskInventory.LockItemsForRead(true);
4929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4596 { 4930 {
4597 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4931 if (inv.Value.Name == name)
4598 { 4932 {
4599 if (inv.Value.Name == name) 4933 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4600 { 4934 {
4601 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4935 m_host.TaskInventory.LockItemsForRead(false);
4602 { 4936 return inv.Value.AssetID.ToString();
4603 return inv.Value.AssetID.ToString(); 4937 }
4604 } 4938 else
4605 else 4939 {
4606 { 4940 m_host.TaskInventory.LockItemsForRead(false);
4607 return UUID.Zero.ToString(); 4941 return UUID.Zero.ToString();
4608 }
4609 } 4942 }
4610 } 4943 }
4611 } 4944 }
4945 m_host.TaskInventory.LockItemsForRead(false);
4612 4946
4613 return UUID.Zero.ToString(); 4947 return UUID.Zero.ToString();
4614 } 4948 }
@@ -4761,14 +5095,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5095 {
4762 m_host.AddScriptLPS(1); 5096 m_host.AddScriptLPS(1);
4763 5097
4764 if (src == null) 5098 return src.Length;
4765 {
4766 return 0;
4767 }
4768 else
4769 {
4770 return src.Length;
4771 }
4772 } 5099 }
4773 5100
4774 public LSL_Integer llList2Integer(LSL_List src, int index) 5101 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4814,7 +5141,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4814 else if (src.Data[index] is LSL_Float) 5141 else if (src.Data[index] is LSL_Float)
4815 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5142 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4816 else if (src.Data[index] is LSL_String) 5143 else if (src.Data[index] is LSL_String)
4817 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5144 {
5145 string str = ((LSL_String) src.Data[index]).m_string;
5146 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5147 if (m != Match.Empty)
5148 {
5149 str = m.Value;
5150 double d = 0.0;
5151 if (!Double.TryParse(str, out d))
5152 return 0.0;
5153
5154 return d;
5155 }
5156 return 0.0;
5157 }
4818 return Convert.ToDouble(src.Data[index]); 5158 return Convert.ToDouble(src.Data[index]);
4819 } 5159 }
4820 catch (FormatException) 5160 catch (FormatException)
@@ -5087,7 +5427,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5087 } 5427 }
5088 } 5428 }
5089 } 5429 }
5090 else { 5430 else
5431 {
5091 object[] array = new object[src.Length]; 5432 object[] array = new object[src.Length];
5092 Array.Copy(src.Data, 0, array, 0, src.Length); 5433 Array.Copy(src.Data, 0, array, 0, src.Length);
5093 result = new LSL_List(array); 5434 result = new LSL_List(array);
@@ -5499,7 +5840,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5499 public void llSetSoundQueueing(int queue) 5840 public void llSetSoundQueueing(int queue)
5500 { 5841 {
5501 m_host.AddScriptLPS(1); 5842 m_host.AddScriptLPS(1);
5502 NotImplemented("llSetSoundQueueing");
5503 } 5843 }
5504 5844
5505 public void llSetSoundRadius(double radius) 5845 public void llSetSoundRadius(double radius)
@@ -5544,10 +5884,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5544 m_host.AddScriptLPS(1); 5884 m_host.AddScriptLPS(1);
5545 5885
5546 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5886 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5547 5887 if (parts.Count > 0)
5548 foreach (var part in parts)
5549 { 5888 {
5550 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5889 try
5890 {
5891 parts[0].ParentGroup.areUpdatesSuspended = true;
5892 foreach (var part in parts)
5893 {
5894 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5895 }
5896 }
5897 finally
5898 {
5899 parts[0].ParentGroup.areUpdatesSuspended = false;
5900 }
5551 } 5901 }
5552 } 5902 }
5553 5903
@@ -5601,6 +5951,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5601 ScriptSleep(5000); 5951 ScriptSleep(5000);
5602 } 5952 }
5603 5953
5954 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5955 {
5956 return ParseString2List(str, separators, in_spacers, false);
5957 }
5958
5604 public LSL_Integer llOverMyLand(string id) 5959 public LSL_Integer llOverMyLand(string id)
5605 { 5960 {
5606 m_host.AddScriptLPS(1); 5961 m_host.AddScriptLPS(1);
@@ -5801,7 +6156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5801 return m_host.ParentGroup.RootPart.AttachmentPoint; 6156 return m_host.ParentGroup.RootPart.AttachmentPoint;
5802 } 6157 }
5803 6158
5804 public LSL_Integer llGetFreeMemory() 6159 public virtual LSL_Integer llGetFreeMemory()
5805 { 6160 {
5806 m_host.AddScriptLPS(1); 6161 m_host.AddScriptLPS(1);
5807 // Make scripts designed for LSO happy 6162 // Make scripts designed for LSO happy
@@ -5918,7 +6273,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5918 SetParticleSystem(m_host, rules); 6273 SetParticleSystem(m_host, rules);
5919 } 6274 }
5920 6275
5921 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6276 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6277 {
5922 6278
5923 6279
5924 if (rules.Length == 0) 6280 if (rules.Length == 0)
@@ -6112,14 +6468,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6112 6468
6113 protected UUID GetTaskInventoryItem(string name) 6469 protected UUID GetTaskInventoryItem(string name)
6114 { 6470 {
6115 lock (m_host.TaskInventory) 6471 m_host.TaskInventory.LockItemsForRead(true);
6472 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6116 { 6473 {
6117 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6474 if (inv.Value.Name == name)
6118 { 6475 {
6119 if (inv.Value.Name == name) 6476 m_host.TaskInventory.LockItemsForRead(false);
6120 return inv.Key; 6477 return inv.Key;
6121 } 6478 }
6122 } 6479 }
6480 m_host.TaskInventory.LockItemsForRead(false);
6123 6481
6124 return UUID.Zero; 6482 return UUID.Zero;
6125 } 6483 }
@@ -6447,22 +6805,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6447 } 6805 }
6448 6806
6449 // copy the first script found with this inventory name 6807 // copy the first script found with this inventory name
6450 lock (m_host.TaskInventory) 6808 m_host.TaskInventory.LockItemsForRead(true);
6809 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6451 { 6810 {
6452 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6811 if (inv.Value.Name == name)
6453 { 6812 {
6454 if (inv.Value.Name == name) 6813 // make sure the object is a script
6814 if (10 == inv.Value.Type)
6455 { 6815 {
6456 // make sure the object is a script 6816 found = true;
6457 if (10 == inv.Value.Type) 6817 srcId = inv.Key;
6458 { 6818 break;
6459 found = true;
6460 srcId = inv.Key;
6461 break;
6462 }
6463 } 6819 }
6464 } 6820 }
6465 } 6821 }
6822 m_host.TaskInventory.LockItemsForRead(false);
6466 6823
6467 if (!found) 6824 if (!found)
6468 { 6825 {
@@ -6546,6 +6903,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6546 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6903 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6547 { 6904 {
6548 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6905 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6906 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6907 return shapeBlock;
6549 6908
6550 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6909 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6551 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6910 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6621,6 +6980,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6621 6980
6622 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6981 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6623 { 6982 {
6983 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6984 return;
6985
6624 ObjectShapePacket.ObjectDataBlock shapeBlock; 6986 ObjectShapePacket.ObjectDataBlock shapeBlock;
6625 6987
6626 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6988 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6670,6 +7032,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6670 7032
6671 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7033 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6672 { 7034 {
7035 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7036 return;
7037
6673 ObjectShapePacket.ObjectDataBlock shapeBlock; 7038 ObjectShapePacket.ObjectDataBlock shapeBlock;
6674 7039
6675 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7040 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6712,6 +7077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6712 7077
6713 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge) 7078 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte fudge)
6714 { 7079 {
7080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7081 return;
7082
6715 ObjectShapePacket.ObjectDataBlock shapeBlock; 7083 ObjectShapePacket.ObjectDataBlock shapeBlock;
6716 7084
6717 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7085 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6838,6 +7206,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6838 7206
6839 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7207 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6840 { 7208 {
7209 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7210 return;
7211
6841 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7212 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6842 UUID sculptId; 7213 UUID sculptId;
6843 7214
@@ -6853,13 +7224,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6853 shapeBlock.PathScaleX = 100; 7224 shapeBlock.PathScaleX = 100;
6854 shapeBlock.PathScaleY = 150; 7225 shapeBlock.PathScaleY = 150;
6855 7226
6856 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7227 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6857 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7228 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6858 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7229 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6859 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7230 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6860 { 7231 {
6861 // default 7232 // default
6862 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7233 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6863 } 7234 }
6864 7235
6865 // retain pathcurve 7236 // retain pathcurve
@@ -6878,30 +7249,82 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6878 ScriptSleep(200); 7249 ScriptSleep(200);
6879 } 7250 }
6880 7251
6881 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7252 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6882 { 7253 {
6883 m_host.AddScriptLPS(1); 7254 m_host.AddScriptLPS(1);
6884 7255
6885 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7256 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7257 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7258 if (parts.Count>0)
7259 {
7260 try
7261 {
7262 parts[0].ParentGroup.areUpdatesSuspended = true;
7263 foreach (SceneObjectPart part in parts)
7264 SetPrimParams(part, rules);
7265 }
7266 finally
7267 {
7268 parts[0].ParentGroup.areUpdatesSuspended = false;
7269 }
7270 }
7271 if (avatars.Count > 0)
7272 {
7273 foreach (ScenePresence avatar in avatars)
7274 SetPrimParams(avatar, rules);
7275 }
7276 }
6886 7277
6887 foreach (SceneObjectPart part in parts) 7278 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6888 SetPrimParams(part, rules); 7279 {
6889 7280 llSetLinkPrimitiveParamsFast(linknumber, rules);
6890 ScriptSleep(200); 7281 ScriptSleep(200);
6891 } 7282 }
6892 7283
6893 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7284 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6894 { 7285 {
6895 m_host.AddScriptLPS(1); 7286 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7287 //We only support PRIM_POSITION and PRIM_ROTATION
6896 7288
6897 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7289 int idx = 0;
6898 7290
6899 foreach (SceneObjectPart part in parts) 7291 while (idx < rules.Length)
6900 SetPrimParams(part, rules); 7292 {
7293 int code = rules.GetLSLIntegerItem(idx++);
7294
7295 int remain = rules.Length - idx;
7296
7297
7298
7299 switch (code)
7300 {
7301 case (int)ScriptBaseClass.PRIM_POSITION:
7302 if (remain < 1)
7303 return;
7304 LSL_Vector v;
7305 v = rules.GetVector3Item(idx++);
7306 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7307 av.SendFullUpdateToAllClients();
7308
7309 break;
7310
7311 case (int)ScriptBaseClass.PRIM_ROTATION:
7312 if (remain < 1)
7313 return;
7314 LSL_Rotation r;
7315 r = rules.GetQuaternionItem(idx++);
7316 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7317 av.SendFullUpdateToAllClients();
7318 break;
7319 }
7320 }
6901 } 7321 }
6902 7322
6903 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7323 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6904 { 7324 {
7325 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7326 return;
7327
6905 int idx = 0; 7328 int idx = 0;
6906 7329
6907 while (idx < rules.Length) 7330 while (idx < rules.Length)
@@ -7418,13 +7841,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7418 public LSL_Integer llGetNumberOfPrims() 7841 public LSL_Integer llGetNumberOfPrims()
7419 { 7842 {
7420 m_host.AddScriptLPS(1); 7843 m_host.AddScriptLPS(1);
7421 int avatarCount = 0; 7844 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7422 World.ForEachScenePresence(delegate(ScenePresence presence) 7845
7423 {
7424 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7425 avatarCount++;
7426 });
7427
7428 return m_host.ParentGroup.PrimCount + avatarCount; 7846 return m_host.ParentGroup.PrimCount + avatarCount;
7429 } 7847 }
7430 7848
@@ -7440,55 +7858,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7440 m_host.AddScriptLPS(1); 7858 m_host.AddScriptLPS(1);
7441 UUID objID = UUID.Zero; 7859 UUID objID = UUID.Zero;
7442 LSL_List result = new LSL_List(); 7860 LSL_List result = new LSL_List();
7861
7862 // If the ID is not valid, return null result
7443 if (!UUID.TryParse(obj, out objID)) 7863 if (!UUID.TryParse(obj, out objID))
7444 { 7864 {
7445 result.Add(new LSL_Vector()); 7865 result.Add(new LSL_Vector());
7446 result.Add(new LSL_Vector()); 7866 result.Add(new LSL_Vector());
7447 return result; 7867 return result;
7448 } 7868 }
7869
7870 // Check if this is an attached prim. If so, replace
7871 // the UUID with the avatar UUID and report it's bounding box
7872 SceneObjectPart part = World.GetSceneObjectPart(objID);
7873 if (part != null && part.ParentGroup.IsAttachment)
7874 objID = part.ParentGroup.RootPart.AttachedAvatar;
7875
7876 // Find out if this is an avatar ID. If so, return it's box
7449 ScenePresence presence = World.GetScenePresence(objID); 7877 ScenePresence presence = World.GetScenePresence(objID);
7450 if (presence != null) 7878 if (presence != null)
7451 { 7879 {
7452 if (presence.ParentID == 0) // not sat on an object 7880 // As per LSL Wiki, there is no difference between sitting
7881 // and standing avatar since server 1.36
7882 LSL_Vector lower;
7883 LSL_Vector upper;
7884 if (presence.Animator.Animations.DefaultAnimation.AnimID
7885 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7453 { 7886 {
7454 LSL_Vector lower; 7887 // This is for ground sitting avatars
7455 LSL_Vector upper; 7888 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7456 if (presence.Animator.Animations.DefaultAnimation.AnimID 7889 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7457 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7890 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7458 {
7459 // This is for ground sitting avatars
7460 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7461 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7462 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7463 }
7464 else
7465 {
7466 // This is for standing/flying avatars
7467 float height = presence.Appearance.AvatarHeight / 2.0f;
7468 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7469 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7470 }
7471 result.Add(lower);
7472 result.Add(upper);
7473 return result;
7474 } 7891 }
7475 else 7892 else
7476 { 7893 {
7477 // sitting on an object so we need the bounding box of that 7894 // This is for standing/flying avatars
7478 // which should include the avatar so set the UUID to the 7895 float height = presence.Appearance.AvatarHeight / 2.0f;
7479 // UUID of the object the avatar is sat on and allow it to fall through 7896 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7480 // to processing an object 7897 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7481 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7482 objID = p.UUID;
7483 } 7898 }
7899
7900 // Adjust to the documented error offsets (see LSL Wiki)
7901 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7902 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7903
7904 if (lower.x > upper.x)
7905 lower.x = upper.x;
7906 if (lower.y > upper.y)
7907 lower.y = upper.y;
7908 if (lower.z > upper.z)
7909 lower.z = upper.z;
7910
7911 result.Add(lower);
7912 result.Add(upper);
7913 return result;
7484 } 7914 }
7485 SceneObjectPart part = World.GetSceneObjectPart(objID); 7915
7916 part = World.GetSceneObjectPart(objID);
7486 // Currently only works for single prims without a sitting avatar 7917 // Currently only works for single prims without a sitting avatar
7487 if (part != null) 7918 if (part != null)
7488 { 7919 {
7489 Vector3 halfSize = part.Scale / 2.0f; 7920 float minX;
7490 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7921 float maxX;
7491 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7922 float minY;
7923 float maxY;
7924 float minZ;
7925 float maxZ;
7926
7927 // This BBox is in sim coordinates, with the offset being
7928 // a contained point.
7929 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7930 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7931
7932 minX -= offsets[0].X;
7933 maxX -= offsets[0].X;
7934 minY -= offsets[0].Y;
7935 maxY -= offsets[0].Y;
7936 minZ -= offsets[0].Z;
7937 maxZ -= offsets[0].Z;
7938
7939 LSL_Vector lower;
7940 LSL_Vector upper;
7941
7942 // Adjust to the documented error offsets (see LSL Wiki)
7943 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7944 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7945
7946 if (lower.x > upper.x)
7947 lower.x = upper.x;
7948 if (lower.y > upper.y)
7949 lower.y = upper.y;
7950 if (lower.z > upper.z)
7951 lower.z = upper.z;
7952
7492 result.Add(lower); 7953 result.Add(lower);
7493 result.Add(upper); 7954 result.Add(upper);
7494 return result; 7955 return result;
@@ -7733,24 +8194,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7733 break; 8194 break;
7734 8195
7735 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8196 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7736 // TODO--------------
7737 if (remain < 1) 8197 if (remain < 1)
7738 return res; 8198 return res;
8199 face = (int)rules.GetLSLIntegerItem(idx++);
7739 8200
7740 face=(int)rules.GetLSLIntegerItem(idx++); 8201 tex = part.Shape.Textures;
7741 8202 int shiny;
7742 res.Add(new LSL_Integer(0)); 8203 if (face == ScriptBaseClass.ALL_SIDES)
7743 res.Add(new LSL_Integer(0)); 8204 {
8205 for (face = 0; face < GetNumberOfSides(part); face++)
8206 {
8207 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8208 if (shinyness == Shininess.High)
8209 {
8210 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8211 }
8212 else if (shinyness == Shininess.Medium)
8213 {
8214 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8215 }
8216 else if (shinyness == Shininess.Low)
8217 {
8218 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8219 }
8220 else
8221 {
8222 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8223 }
8224 res.Add(new LSL_Integer(shiny));
8225 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8226 }
8227 }
8228 else
8229 {
8230 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8231 if (shinyness == Shininess.High)
8232 {
8233 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8234 }
8235 else if (shinyness == Shininess.Medium)
8236 {
8237 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8238 }
8239 else if (shinyness == Shininess.Low)
8240 {
8241 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8242 }
8243 else
8244 {
8245 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8246 }
8247 res.Add(new LSL_Integer(shiny));
8248 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8249 }
7744 break; 8250 break;
7745 8251
7746 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8252 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7747 // TODO--------------
7748 if (remain < 1) 8253 if (remain < 1)
7749 return res; 8254 return res;
8255 face = (int)rules.GetLSLIntegerItem(idx++);
7750 8256
7751 face=(int)rules.GetLSLIntegerItem(idx++); 8257 tex = part.Shape.Textures;
7752 8258 int fullbright;
7753 res.Add(new LSL_Integer(0)); 8259 if (face == ScriptBaseClass.ALL_SIDES)
8260 {
8261 for (face = 0; face < GetNumberOfSides(part); face++)
8262 {
8263 if (tex.GetFace((uint)face).Fullbright == true)
8264 {
8265 fullbright = ScriptBaseClass.TRUE;
8266 }
8267 else
8268 {
8269 fullbright = ScriptBaseClass.FALSE;
8270 }
8271 res.Add(new LSL_Integer(fullbright));
8272 }
8273 }
8274 else
8275 {
8276 if (tex.GetFace((uint)face).Fullbright == true)
8277 {
8278 fullbright = ScriptBaseClass.TRUE;
8279 }
8280 else
8281 {
8282 fullbright = ScriptBaseClass.FALSE;
8283 }
8284 res.Add(new LSL_Integer(fullbright));
8285 }
7754 break; 8286 break;
7755 8287
7756 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8288 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7771,14 +8303,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7771 break; 8303 break;
7772 8304
7773 case (int)ScriptBaseClass.PRIM_TEXGEN: 8305 case (int)ScriptBaseClass.PRIM_TEXGEN:
7774 // TODO--------------
7775 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8306 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7776 if (remain < 1) 8307 if (remain < 1)
7777 return res; 8308 return res;
8309 face = (int)rules.GetLSLIntegerItem(idx++);
7778 8310
7779 face=(int)rules.GetLSLIntegerItem(idx++); 8311 tex = part.Shape.Textures;
7780 8312 if (face == ScriptBaseClass.ALL_SIDES)
7781 res.Add(new LSL_Integer(0)); 8313 {
8314 for (face = 0; face < GetNumberOfSides(part); face++)
8315 {
8316 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8317 {
8318 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8319 }
8320 else
8321 {
8322 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8323 }
8324 }
8325 }
8326 else
8327 {
8328 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8329 {
8330 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8331 }
8332 else
8333 {
8334 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8335 }
8336 }
7782 break; 8337 break;
7783 8338
7784 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8339 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7797,13 +8352,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7797 break; 8352 break;
7798 8353
7799 case (int)ScriptBaseClass.PRIM_GLOW: 8354 case (int)ScriptBaseClass.PRIM_GLOW:
7800 // TODO--------------
7801 if (remain < 1) 8355 if (remain < 1)
7802 return res; 8356 return res;
8357 face = (int)rules.GetLSLIntegerItem(idx++);
7803 8358
7804 face=(int)rules.GetLSLIntegerItem(idx++); 8359 tex = part.Shape.Textures;
7805 8360 float primglow;
7806 res.Add(new LSL_Float(0)); 8361 if (face == ScriptBaseClass.ALL_SIDES)
8362 {
8363 for (face = 0; face < GetNumberOfSides(part); face++)
8364 {
8365 primglow = tex.GetFace((uint)face).Glow;
8366 res.Add(new LSL_Float(primglow));
8367 }
8368 }
8369 else
8370 {
8371 primglow = tex.GetFace((uint)face).Glow;
8372 res.Add(new LSL_Float(primglow));
8373 }
7807 break; 8374 break;
7808 case (int)ScriptBaseClass.PRIM_TEXT: 8375 case (int)ScriptBaseClass.PRIM_TEXT:
7809 Color4 textColor = part.GetTextColor(); 8376 Color4 textColor = part.GetTextColor();
@@ -8344,8 +8911,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8344 // The function returns an ordered list 8911 // The function returns an ordered list
8345 // representing the tokens found in the supplied 8912 // representing the tokens found in the supplied
8346 // sources string. If two successive tokenizers 8913 // sources string. If two successive tokenizers
8347 // are encountered, then a NULL entry is added 8914 // are encountered, then a null-string entry is
8348 // to the list. 8915 // added to the list.
8349 // 8916 //
8350 // It is a precondition that the source and 8917 // It is a precondition that the source and
8351 // toekizer lisst are non-null. If they are null, 8918 // toekizer lisst are non-null. If they are null,
@@ -8353,7 +8920,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8353 // while their lengths are being determined. 8920 // while their lengths are being determined.
8354 // 8921 //
8355 // A small amount of working memoryis required 8922 // A small amount of working memoryis required
8356 // of approximately 8*#tokenizers. 8923 // of approximately 8*#tokenizers + 8*srcstrlen.
8357 // 8924 //
8358 // There are many ways in which this function 8925 // There are many ways in which this function
8359 // can be implemented, this implementation is 8926 // can be implemented, this implementation is
@@ -8369,155 +8936,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8369 // and eliminates redundant tokenizers as soon 8936 // and eliminates redundant tokenizers as soon
8370 // as is possible. 8937 // as is possible.
8371 // 8938 //
8372 // The implementation tries to avoid any copying 8939 // The implementation tries to minimize temporary
8373 // of arrays or other objects. 8940 // garbage generation.
8374 // </remarks> 8941 // </remarks>
8375 8942
8376 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 8943 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8377 { 8944 {
8378 int beginning = 0; 8945 return ParseString2List(src, separators, spacers, true);
8379 int srclen = src.Length; 8946 }
8380 int seplen = separators.Length;
8381 object[] separray = separators.Data;
8382 int spclen = spacers.Length;
8383 object[] spcarray = spacers.Data;
8384 int mlen = seplen+spclen;
8385
8386 int[] offset = new int[mlen+1];
8387 bool[] active = new bool[mlen];
8388
8389 int best;
8390 int j;
8391
8392 // Initial capacity reduces resize cost
8393 8947
8394 LSL_List tokens = new LSL_List(); 8948 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8949 {
8950 int srclen = src.Length;
8951 int seplen = separators.Length;
8952 object[] separray = separators.Data;
8953 int spclen = spacers.Length;
8954 object[] spcarray = spacers.Data;
8955 int dellen = 0;
8956 string[] delarray = new string[seplen+spclen];
8395 8957
8396 // All entries are initially valid 8958 int outlen = 0;
8959 string[] outarray = new string[srclen*2+1];
8397 8960
8398 for (int i = 0; i < mlen; i++) 8961 int i, j;
8399 active[i] = true; 8962 string d;
8400 8963
8401 offset[mlen] = srclen; 8964 m_host.AddScriptLPS(1);
8402 8965
8403 while (beginning < srclen) 8966 /*
8967 * Convert separator and spacer lists to C# strings.
8968 * Also filter out null strings so we don't hang.
8969 */
8970 for (i = 0; i < seplen; i ++)
8404 { 8971 {
8972 d = separray[i].ToString();
8973 if (d.Length > 0)
8974 {
8975 delarray[dellen++] = d;
8976 }
8977 }
8978 seplen = dellen;
8405 8979
8406 best = mlen; // as bad as it gets 8980 for (i = 0; i < spclen; i ++)
8981 {
8982 d = spcarray[i].ToString();
8983 if (d.Length > 0)
8984 {
8985 delarray[dellen++] = d;
8986 }
8987 }
8407 8988
8408 // Scan for separators 8989 /*
8990 * Scan through source string from beginning to end.
8991 */
8992 for (i = 0;;)
8993 {
8409 8994
8410 for (j = 0; j < seplen; j++) 8995 /*
8996 * Find earliest delimeter in src starting at i (if any).
8997 */
8998 int earliestDel = -1;
8999 int earliestSrc = srclen;
9000 string earliestStr = null;
9001 for (j = 0; j < dellen; j ++)
8411 { 9002 {
8412 if (separray[j].ToString() == String.Empty) 9003 d = delarray[j];
8413 active[j] = false; 9004 if (d != null)
8414
8415 if (active[j])
8416 { 9005 {
8417 // scan all of the markers 9006 int index = src.IndexOf(d, i);
8418 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9007 if (index < 0)
8419 { 9008 {
8420 // not present at all 9009 delarray[j] = null; // delim nowhere in src, don't check it anymore
8421 active[j] = false;
8422 } 9010 }
8423 else 9011 else if (index < earliestSrc)
8424 { 9012 {
8425 // present and correct 9013 earliestSrc = index; // where delimeter starts in source string
8426 if (offset[j] < offset[best]) 9014 earliestDel = j; // where delimeter is in delarray[]
8427 { 9015 earliestStr = d; // the delimeter string from delarray[]
8428 // closest so far 9016 if (index == i) break; // can't do any better than found at beg of string
8429 best = j;
8430 if (offset[best] == beginning)
8431 break;
8432 }
8433 } 9017 }
8434 } 9018 }
8435 } 9019 }
8436 9020
8437 // Scan for spacers 9021 /*
8438 9022 * Output source string starting at i through start of earliest delimeter.
8439 if (offset[best] != beginning) 9023 */
9024 if (keepNulls || (earliestSrc > i))
8440 { 9025 {
8441 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9026 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8442 {
8443 if (spcarray[j-seplen].ToString() == String.Empty)
8444 active[j] = false;
8445
8446 if (active[j])
8447 {
8448 // scan all of the markers
8449 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8450 {
8451 // not present at all
8452 active[j] = false;
8453 }
8454 else
8455 {
8456 // present and correct
8457 if (offset[j] < offset[best])
8458 {
8459 // closest so far
8460 best = j;
8461 }
8462 }
8463 }
8464 }
8465 } 9027 }
8466 9028
8467 // This is the normal exit from the scanning loop 9029 /*
9030 * If no delimeter found at or after i, we're done scanning.
9031 */
9032 if (earliestDel < 0) break;
8468 9033
8469 if (best == mlen) 9034 /*
9035 * If delimeter was a spacer, output the spacer.
9036 */
9037 if (earliestDel >= seplen)
8470 { 9038 {
8471 // no markers were found on this pass 9039 outarray[outlen++] = earliestStr;
8472 // so we're pretty much done
8473 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8474 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8475 break;
8476 } 9040 }
8477 9041
8478 // Otherwise we just add the newly delimited token 9042 /*
8479 // and recalculate where the search should continue. 9043 * Look at rest of src string following delimeter.
8480 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9044 */
8481 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9045 i = earliestSrc + earliestStr.Length;
8482
8483 if (best < seplen)
8484 {
8485 beginning = offset[best] + (separray[best].ToString()).Length;
8486 }
8487 else
8488 {
8489 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8490 string str = spcarray[best - seplen].ToString();
8491 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8492 tokens.Add(new LSL_String(str));
8493 }
8494 } 9046 }
8495 9047
8496 // This an awkward an not very intuitive boundary case. If the 9048 /*
8497 // last substring is a tokenizer, then there is an implied trailing 9049 * Make up an exact-sized output array suitable for an LSL_List object.
8498 // null list entry. Hopefully the single comparison will not be too 9050 */
8499 // arduous. Alternatively the 'break' could be replced with a return 9051 object[] outlist = new object[outlen];
8500 // but that's shabby programming. 9052 for (i = 0; i < outlen; i ++)
8501
8502 if ((beginning == srclen) && (keepNulls))
8503 { 9053 {
8504 if (srclen != 0) 9054 outlist[i] = new LSL_String(outarray[i]);
8505 tokens.Add(new LSL_String(""));
8506 } 9055 }
8507 9056 return new LSL_List(outlist);
8508 return tokens;
8509 }
8510
8511 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8512 {
8513 m_host.AddScriptLPS(1);
8514 return this.ParseString(src, separators, spacers, false);
8515 }
8516
8517 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8518 {
8519 m_host.AddScriptLPS(1);
8520 return this.ParseString(src, separators, spacers, true);
8521 } 9057 }
8522 9058
8523 public LSL_Integer llGetObjectPermMask(int mask) 9059 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8594,28 +9130,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8594 { 9130 {
8595 m_host.AddScriptLPS(1); 9131 m_host.AddScriptLPS(1);
8596 9132
8597 lock (m_host.TaskInventory) 9133 m_host.TaskInventory.LockItemsForRead(true);
9134 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8598 { 9135 {
8599 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9136 if (inv.Value.Name == item)
8600 { 9137 {
8601 if (inv.Value.Name == item) 9138 m_host.TaskInventory.LockItemsForRead(false);
9139 switch (mask)
8602 { 9140 {
8603 switch (mask) 9141 case 0:
8604 { 9142 return (int)inv.Value.BasePermissions;
8605 case 0: 9143 case 1:
8606 return (int)inv.Value.BasePermissions; 9144 return (int)inv.Value.CurrentPermissions;
8607 case 1: 9145 case 2:
8608 return (int)inv.Value.CurrentPermissions; 9146 return (int)inv.Value.GroupPermissions;
8609 case 2: 9147 case 3:
8610 return (int)inv.Value.GroupPermissions; 9148 return (int)inv.Value.EveryonePermissions;
8611 case 3: 9149 case 4:
8612 return (int)inv.Value.EveryonePermissions; 9150 return (int)inv.Value.NextPermissions;
8613 case 4:
8614 return (int)inv.Value.NextPermissions;
8615 }
8616 } 9151 }
8617 } 9152 }
8618 } 9153 }
9154 m_host.TaskInventory.LockItemsForRead(false);
8619 9155
8620 return -1; 9156 return -1;
8621 } 9157 }
@@ -8662,16 +9198,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8662 { 9198 {
8663 m_host.AddScriptLPS(1); 9199 m_host.AddScriptLPS(1);
8664 9200
8665 lock (m_host.TaskInventory) 9201 m_host.TaskInventory.LockItemsForRead(true);
9202 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8666 { 9203 {
8667 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9204 if (inv.Value.Name == item)
8668 { 9205 {
8669 if (inv.Value.Name == item) 9206 m_host.TaskInventory.LockItemsForRead(false);
8670 { 9207 return inv.Value.CreatorID.ToString();
8671 return inv.Value.CreatorID.ToString();
8672 }
8673 } 9208 }
8674 } 9209 }
9210 m_host.TaskInventory.LockItemsForRead(false);
8675 9211
8676 llSay(0, "No item name '" + item + "'"); 9212 llSay(0, "No item name '" + item + "'");
8677 9213
@@ -8722,8 +9258,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8722 return UUID.Zero.ToString(); 9258 return UUID.Zero.ToString();
8723 } 9259 }
8724 reply = new LSL_Vector( 9260 reply = new LSL_Vector(
8725 info.RegionLocX * Constants.RegionSize, 9261 info.RegionLocX,
8726 info.RegionLocY * Constants.RegionSize, 9262 info.RegionLocY,
8727 0).ToString(); 9263 0).ToString();
8728 break; 9264 break;
8729 case 6: // DATA_SIM_STATUS 9265 case 6: // DATA_SIM_STATUS
@@ -8936,17 +9472,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8936 int width = 0; 9472 int width = 0;
8937 int height = 0; 9473 int height = 0;
8938 9474
8939 ParcelMediaCommandEnum? commandToSend = null; 9475 uint commandToSend = 0;
8940 float time = 0.0f; // default is from start 9476 float time = 0.0f; // default is from start
8941 9477
8942 ScenePresence presence = null; 9478 ScenePresence presence = null;
8943 9479
8944 for (int i = 0; i < commandList.Data.Length; i++) 9480 for (int i = 0; i < commandList.Data.Length; i++)
8945 { 9481 {
8946 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9482 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8947 switch (command) 9483 switch (command)
8948 { 9484 {
8949 case ParcelMediaCommandEnum.Agent: 9485 case (uint)ParcelMediaCommandEnum.Agent:
8950 // we send only to one agent 9486 // we send only to one agent
8951 if ((i + 1) < commandList.Length) 9487 if ((i + 1) < commandList.Length)
8952 { 9488 {
@@ -8963,25 +9499,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8963 } 9499 }
8964 break; 9500 break;
8965 9501
8966 case ParcelMediaCommandEnum.Loop: 9502 case (uint)ParcelMediaCommandEnum.Loop:
8967 loop = 1; 9503 loop = 1;
8968 commandToSend = command; 9504 commandToSend = command;
8969 update = true; //need to send the media update packet to set looping 9505 update = true; //need to send the media update packet to set looping
8970 break; 9506 break;
8971 9507
8972 case ParcelMediaCommandEnum.Play: 9508 case (uint)ParcelMediaCommandEnum.Play:
8973 loop = 0; 9509 loop = 0;
8974 commandToSend = command; 9510 commandToSend = command;
8975 update = true; //need to send the media update packet to make sure it doesn't loop 9511 update = true; //need to send the media update packet to make sure it doesn't loop
8976 break; 9512 break;
8977 9513
8978 case ParcelMediaCommandEnum.Pause: 9514 case (uint)ParcelMediaCommandEnum.Pause:
8979 case ParcelMediaCommandEnum.Stop: 9515 case (uint)ParcelMediaCommandEnum.Stop:
8980 case ParcelMediaCommandEnum.Unload: 9516 case (uint)ParcelMediaCommandEnum.Unload:
8981 commandToSend = command; 9517 commandToSend = command;
8982 break; 9518 break;
8983 9519
8984 case ParcelMediaCommandEnum.Url: 9520 case (uint)ParcelMediaCommandEnum.Url:
8985 if ((i + 1) < commandList.Length) 9521 if ((i + 1) < commandList.Length)
8986 { 9522 {
8987 if (commandList.Data[i + 1] is LSL_String) 9523 if (commandList.Data[i + 1] is LSL_String)
@@ -8994,7 +9530,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8994 } 9530 }
8995 break; 9531 break;
8996 9532
8997 case ParcelMediaCommandEnum.Texture: 9533 case (uint)ParcelMediaCommandEnum.Texture:
8998 if ((i + 1) < commandList.Length) 9534 if ((i + 1) < commandList.Length)
8999 { 9535 {
9000 if (commandList.Data[i + 1] is LSL_String) 9536 if (commandList.Data[i + 1] is LSL_String)
@@ -9007,7 +9543,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9007 } 9543 }
9008 break; 9544 break;
9009 9545
9010 case ParcelMediaCommandEnum.Time: 9546 case (uint)ParcelMediaCommandEnum.Time:
9011 if ((i + 1) < commandList.Length) 9547 if ((i + 1) < commandList.Length)
9012 { 9548 {
9013 if (commandList.Data[i + 1] is LSL_Float) 9549 if (commandList.Data[i + 1] is LSL_Float)
@@ -9019,7 +9555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9019 } 9555 }
9020 break; 9556 break;
9021 9557
9022 case ParcelMediaCommandEnum.AutoAlign: 9558 case (uint)ParcelMediaCommandEnum.AutoAlign:
9023 if ((i + 1) < commandList.Length) 9559 if ((i + 1) < commandList.Length)
9024 { 9560 {
9025 if (commandList.Data[i + 1] is LSL_Integer) 9561 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9033,7 +9569,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9033 } 9569 }
9034 break; 9570 break;
9035 9571
9036 case ParcelMediaCommandEnum.Type: 9572 case (uint)ParcelMediaCommandEnum.Type:
9037 if ((i + 1) < commandList.Length) 9573 if ((i + 1) < commandList.Length)
9038 { 9574 {
9039 if (commandList.Data[i + 1] is LSL_String) 9575 if (commandList.Data[i + 1] is LSL_String)
@@ -9046,7 +9582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9046 } 9582 }
9047 break; 9583 break;
9048 9584
9049 case ParcelMediaCommandEnum.Desc: 9585 case (uint)ParcelMediaCommandEnum.Desc:
9050 if ((i + 1) < commandList.Length) 9586 if ((i + 1) < commandList.Length)
9051 { 9587 {
9052 if (commandList.Data[i + 1] is LSL_String) 9588 if (commandList.Data[i + 1] is LSL_String)
@@ -9059,7 +9595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9059 } 9595 }
9060 break; 9596 break;
9061 9597
9062 case ParcelMediaCommandEnum.Size: 9598 case (uint)ParcelMediaCommandEnum.Size:
9063 if ((i + 2) < commandList.Length) 9599 if ((i + 2) < commandList.Length)
9064 { 9600 {
9065 if (commandList.Data[i + 1] is LSL_Integer) 9601 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9129,7 +9665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9129 } 9665 }
9130 } 9666 }
9131 9667
9132 if (commandToSend != null) 9668 if (commandToSend != 0)
9133 { 9669 {
9134 // the commandList contained a start/stop/... command, too 9670 // the commandList contained a start/stop/... command, too
9135 if (presence == null) 9671 if (presence == null)
@@ -9166,7 +9702,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9166 9702
9167 if (aList.Data[i] != null) 9703 if (aList.Data[i] != null)
9168 { 9704 {
9169 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9705 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9170 { 9706 {
9171 case ParcelMediaCommandEnum.Url: 9707 case ParcelMediaCommandEnum.Url:
9172 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9708 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9209,16 +9745,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9209 { 9745 {
9210 m_host.AddScriptLPS(1); 9746 m_host.AddScriptLPS(1);
9211 9747
9212 lock (m_host.TaskInventory) 9748 m_host.TaskInventory.LockItemsForRead(true);
9749 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9213 { 9750 {
9214 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9751 if (inv.Value.Name == name)
9215 { 9752 {
9216 if (inv.Value.Name == name) 9753 m_host.TaskInventory.LockItemsForRead(false);
9217 { 9754 return inv.Value.Type;
9218 return inv.Value.Type;
9219 }
9220 } 9755 }
9221 } 9756 }
9757 m_host.TaskInventory.LockItemsForRead(false);
9222 9758
9223 return -1; 9759 return -1;
9224 } 9760 }
@@ -9229,15 +9765,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9229 9765
9230 if (quick_pay_buttons.Data.Length < 4) 9766 if (quick_pay_buttons.Data.Length < 4)
9231 { 9767 {
9232 LSLError("List must have at least 4 elements"); 9768 int x;
9233 return; 9769 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9770 {
9771 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9772 }
9234 } 9773 }
9235 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9774 int[] nPrice = new int[5];
9236 9775 nPrice[0]=price;
9237 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9776 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9238 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9777 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9239 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9778 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9240 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9779 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9780 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9241 m_host.ParentGroup.HasGroupChanged = true; 9781 m_host.ParentGroup.HasGroupChanged = true;
9242 } 9782 }
9243 9783
@@ -9249,17 +9789,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9249 if (invItemID == UUID.Zero) 9789 if (invItemID == UUID.Zero)
9250 return new LSL_Vector(); 9790 return new LSL_Vector();
9251 9791
9252 lock (m_host.TaskInventory) 9792 m_host.TaskInventory.LockItemsForRead(true);
9793 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9253 { 9794 {
9254 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9795 m_host.TaskInventory.LockItemsForRead(false);
9255 return new LSL_Vector(); 9796 return new LSL_Vector();
9797 }
9256 9798
9257 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9799 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9258 { 9800 {
9259 ShoutError("No permissions to track the camera"); 9801 ShoutError("No permissions to track the camera");
9260 return new LSL_Vector(); 9802 m_host.TaskInventory.LockItemsForRead(false);
9261 } 9803 return new LSL_Vector();
9262 } 9804 }
9805 m_host.TaskInventory.LockItemsForRead(false);
9263 9806
9264 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9807 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9265 if (presence != null) 9808 if (presence != null)
@@ -9277,17 +9820,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9277 if (invItemID == UUID.Zero) 9820 if (invItemID == UUID.Zero)
9278 return new LSL_Rotation(); 9821 return new LSL_Rotation();
9279 9822
9280 lock (m_host.TaskInventory) 9823 m_host.TaskInventory.LockItemsForRead(true);
9824 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9281 { 9825 {
9282 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9826 m_host.TaskInventory.LockItemsForRead(false);
9283 return new LSL_Rotation(); 9827 return new LSL_Rotation();
9284 9828 }
9285 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9829 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9286 { 9830 {
9287 ShoutError("No permissions to track the camera"); 9831 ShoutError("No permissions to track the camera");
9288 return new LSL_Rotation(); 9832 m_host.TaskInventory.LockItemsForRead(false);
9289 } 9833 return new LSL_Rotation();
9290 } 9834 }
9835 m_host.TaskInventory.LockItemsForRead(false);
9291 9836
9292 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9837 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9293 if (presence != null) 9838 if (presence != null)
@@ -9349,8 +9894,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9349 { 9894 {
9350 m_host.AddScriptLPS(1); 9895 m_host.AddScriptLPS(1);
9351 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9896 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9352 if (detectedParams == null) return; // only works on the first detected avatar 9897 if (detectedParams == null)
9353 9898 {
9899 if (m_host.IsAttachment == true)
9900 {
9901 detectedParams = new DetectParams();
9902 detectedParams.Key = m_host.OwnerID;
9903 }
9904 else
9905 {
9906 return;
9907 }
9908 }
9909
9354 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9910 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9355 if (avatar != null) 9911 if (avatar != null)
9356 { 9912 {
@@ -9358,6 +9914,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9358 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9914 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9359 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9915 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9360 } 9916 }
9917
9361 ScriptSleep(1000); 9918 ScriptSleep(1000);
9362 } 9919 }
9363 9920
@@ -9437,14 +9994,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 if (objectID == UUID.Zero) return; 9994 if (objectID == UUID.Zero) return;
9438 9995
9439 UUID agentID; 9996 UUID agentID;
9440 lock (m_host.TaskInventory) 9997 m_host.TaskInventory.LockItemsForRead(true);
9441 { 9998 // we need the permission first, to know which avatar we want to set the camera for
9442 // we need the permission first, to know which avatar we want to set the camera for 9999 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9443 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9444 10000
9445 if (agentID == UUID.Zero) return; 10001 if (agentID == UUID.Zero)
9446 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10002 {
10003 m_host.TaskInventory.LockItemsForRead(false);
10004 return;
9447 } 10005 }
10006 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10007 {
10008 m_host.TaskInventory.LockItemsForRead(false);
10009 return;
10010 }
10011 m_host.TaskInventory.LockItemsForRead(false);
9448 10012
9449 ScenePresence presence = World.GetScenePresence(agentID); 10013 ScenePresence presence = World.GetScenePresence(agentID);
9450 10014
@@ -9453,12 +10017,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9453 10017
9454 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10018 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9455 object[] data = rules.Data; 10019 object[] data = rules.Data;
9456 for (int i = 0; i < data.Length; ++i) { 10020 for (int i = 0; i < data.Length; ++i)
10021 {
9457 int type = Convert.ToInt32(data[i++].ToString()); 10022 int type = Convert.ToInt32(data[i++].ToString());
9458 if (i >= data.Length) break; // odd number of entries => ignore the last 10023 if (i >= data.Length) break; // odd number of entries => ignore the last
9459 10024
9460 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10025 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9461 switch (type) { 10026 switch (type)
10027 {
9462 case ScriptBaseClass.CAMERA_FOCUS: 10028 case ScriptBaseClass.CAMERA_FOCUS:
9463 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10029 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9464 case ScriptBaseClass.CAMERA_POSITION: 10030 case ScriptBaseClass.CAMERA_POSITION:
@@ -9494,12 +10060,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9494 10060
9495 // we need the permission first, to know which avatar we want to clear the camera for 10061 // we need the permission first, to know which avatar we want to clear the camera for
9496 UUID agentID; 10062 UUID agentID;
9497 lock (m_host.TaskInventory) 10063 m_host.TaskInventory.LockItemsForRead(true);
10064 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10065 if (agentID == UUID.Zero)
9498 { 10066 {
9499 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10067 m_host.TaskInventory.LockItemsForRead(false);
9500 if (agentID == UUID.Zero) return; 10068 return;
9501 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9502 } 10069 }
10070 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10071 {
10072 m_host.TaskInventory.LockItemsForRead(false);
10073 return;
10074 }
10075 m_host.TaskInventory.LockItemsForRead(false);
9503 10076
9504 ScenePresence presence = World.GetScenePresence(agentID); 10077 ScenePresence presence = World.GetScenePresence(agentID);
9505 10078
@@ -9566,19 +10139,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9566 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10139 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9567 { 10140 {
9568 m_host.AddScriptLPS(1); 10141 m_host.AddScriptLPS(1);
9569 string ret = String.Empty; 10142
9570 string src1 = llBase64ToString(str1); 10143 if (str1 == String.Empty)
9571 string src2 = llBase64ToString(str2); 10144 return String.Empty;
9572 int c = 0; 10145 if (str2 == String.Empty)
9573 for (int i = 0; i < src1.Length; i++) 10146 return str1;
10147
10148 byte[] data1 = Convert.FromBase64String(str1);
10149 byte[] data2 = Convert.FromBase64String(str2);
10150
10151 byte[] d2 = new Byte[data1.Length];
10152 int pos = 0;
10153
10154 if (data1.Length <= data2.Length)
10155 {
10156 Array.Copy(data2, 0, d2, 0, data1.Length);
10157 }
10158 else
9574 { 10159 {
9575 ret += (char) (src1[i] ^ src2[c]); 10160 while (pos < data1.Length)
10161 {
10162 int len = data1.Length - pos;
10163 if (len > data2.Length)
10164 len = data2.Length;
9576 10165
9577 c++; 10166 Array.Copy(data2, 0, d2, pos, len);
9578 if (c >= src2.Length) 10167 pos += len;
9579 c = 0; 10168 }
9580 } 10169 }
9581 return llStringToBase64(ret); 10170
10171 for (pos = 0 ; pos < data1.Length ; pos++ )
10172 data1[pos] ^= d2[pos];
10173
10174 return Convert.ToBase64String(data1);
9582 } 10175 }
9583 10176
9584 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10177 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9637,12 +10230,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9637 Regex r = new Regex(authregex); 10230 Regex r = new Regex(authregex);
9638 int[] gnums = r.GetGroupNumbers(); 10231 int[] gnums = r.GetGroupNumbers();
9639 Match m = r.Match(url); 10232 Match m = r.Match(url);
9640 if (m.Success) { 10233 if (m.Success)
9641 for (int i = 1; i < gnums.Length; i++) { 10234 {
10235 for (int i = 1; i < gnums.Length; i++)
10236 {
9642 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10237 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9643 //CaptureCollection cc = g.Captures; 10238 //CaptureCollection cc = g.Captures;
9644 } 10239 }
9645 if (m.Groups.Count == 5) { 10240 if (m.Groups.Count == 5)
10241 {
9646 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10242 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9647 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10243 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9648 } 10244 }
@@ -9956,15 +10552,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9956 10552
9957 internal UUID ScriptByName(string name) 10553 internal UUID ScriptByName(string name)
9958 { 10554 {
9959 lock (m_host.TaskInventory) 10555 m_host.TaskInventory.LockItemsForRead(true);
10556
10557 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9960 { 10558 {
9961 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10559 if (item.Type == 10 && item.Name == name)
9962 { 10560 {
9963 if (item.Type == 10 && item.Name == name) 10561 m_host.TaskInventory.LockItemsForRead(false);
9964 return item.ItemID; 10562 return item.ItemID;
9965 } 10563 }
9966 } 10564 }
9967 10565
10566 m_host.TaskInventory.LockItemsForRead(false);
10567
9968 return UUID.Zero; 10568 return UUID.Zero;
9969 } 10569 }
9970 10570
@@ -10005,6 +10605,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10005 { 10605 {
10006 m_host.AddScriptLPS(1); 10606 m_host.AddScriptLPS(1);
10007 10607
10608 //Clone is thread safe
10008 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10609 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10009 10610
10010 UUID assetID = UUID.Zero; 10611 UUID assetID = UUID.Zero;
@@ -10067,6 +10668,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10067 { 10668 {
10068 m_host.AddScriptLPS(1); 10669 m_host.AddScriptLPS(1);
10069 10670
10671 //Clone is thread safe
10070 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10672 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10071 10673
10072 UUID assetID = UUID.Zero; 10674 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 8a98be7..5212e1b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
130 internal float m_ScriptDelayFactor = 1.0f; 130 internal float m_ScriptDelayFactor = 1.0f;
131 internal float m_ScriptDistanceFactor = 1.0f; 131 internal float m_ScriptDistanceFactor = 1.0f;
132 internal bool m_debuggerSafe = false;
132 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 133 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
133 134
134 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 135 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 m_host = host; 138 m_host = host;
138 m_localID = localID; 139 m_localID = localID;
139 m_itemID = itemID; 140 m_itemID = itemID;
141 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
140 142
141 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 143 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
142 m_OSFunctionsEnabled = true; 144 m_OSFunctionsEnabled = true;
@@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
195 197
196 internal void OSSLError(string msg) 198 internal void OSSLError(string msg)
197 { 199 {
198 throw new Exception("OSSL Runtime Error: " + msg); 200 if (m_debuggerSafe)
201 {
202 OSSLShoutError(msg);
203 }
204 else
205 {
206 throw new Exception("OSSL Runtime Error: " + msg);
207 }
199 } 208 }
200 209
201 private void InitLSL() 210 private void InitLSL()
@@ -767,18 +776,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
767 if (target != null) 776 if (target != null)
768 { 777 {
769 UUID animID=UUID.Zero; 778 UUID animID=UUID.Zero;
770 lock (m_host.TaskInventory) 779 m_host.TaskInventory.LockItemsForRead(true);
780 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
771 { 781 {
772 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 782 if (inv.Value.Name == animation)
773 { 783 {
774 if (inv.Value.Name == animation) 784 if (inv.Value.Type == (int)AssetType.Animation)
775 { 785 animID = inv.Value.AssetID;
776 if (inv.Value.Type == (int)AssetType.Animation) 786 continue;
777 animID = inv.Value.AssetID;
778 continue;
779 }
780 } 787 }
781 } 788 }
789 m_host.TaskInventory.LockItemsForRead(false);
782 if (animID == UUID.Zero) 790 if (animID == UUID.Zero)
783 target.Animator.AddAnimation(animation, m_host.UUID); 791 target.Animator.AddAnimation(animation, m_host.UUID);
784 else 792 else
@@ -800,18 +808,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
800 if (target != null) 808 if (target != null)
801 { 809 {
802 UUID animID=UUID.Zero; 810 UUID animID=UUID.Zero;
803 lock (m_host.TaskInventory) 811 m_host.TaskInventory.LockItemsForRead(true);
812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
804 { 813 {
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 814 if (inv.Value.Name == animation)
806 { 815 {
807 if (inv.Value.Name == animation) 816 if (inv.Value.Type == (int)AssetType.Animation)
808 { 817 animID = inv.Value.AssetID;
809 if (inv.Value.Type == (int)AssetType.Animation) 818 continue;
810 animID = inv.Value.AssetID;
811 continue;
812 }
813 } 819 }
814 } 820 }
821 m_host.TaskInventory.LockItemsForRead(false);
815 822
816 if (animID == UUID.Zero) 823 if (animID == UUID.Zero)
817 target.Animator.RemoveAnimation(animation); 824 target.Animator.RemoveAnimation(animation);
@@ -1662,6 +1669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 1669
1663 if (!UUID.TryParse(name, out assetID)) 1670 if (!UUID.TryParse(name, out assetID))
1664 { 1671 {
1672 m_host.TaskInventory.LockItemsForRead(true);
1665 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1673 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1666 { 1674 {
1667 if (item.Type == 7 && item.Name == name) 1675 if (item.Type == 7 && item.Name == name)
@@ -1669,6 +1677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1669 assetID = item.AssetID; 1677 assetID = item.AssetID;
1670 } 1678 }
1671 } 1679 }
1680 m_host.TaskInventory.LockItemsForRead(false);
1672 } 1681 }
1673 1682
1674 if (assetID == UUID.Zero) 1683 if (assetID == UUID.Zero)
@@ -1715,6 +1724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 1724
1716 if (!UUID.TryParse(name, out assetID)) 1725 if (!UUID.TryParse(name, out assetID))
1717 { 1726 {
1727 m_host.TaskInventory.LockItemsForRead(true);
1718 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1728 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1719 { 1729 {
1720 if (item.Type == 7 && item.Name == name) 1730 if (item.Type == 7 && item.Name == name)
@@ -1722,6 +1732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 assetID = item.AssetID; 1732 assetID = item.AssetID;
1723 } 1733 }
1724 } 1734 }
1735 m_host.TaskInventory.LockItemsForRead(false);
1725 } 1736 }
1726 1737
1727 if (assetID == UUID.Zero) 1738 if (assetID == UUID.Zero)
@@ -1772,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1783
1773 if (!UUID.TryParse(name, out assetID)) 1784 if (!UUID.TryParse(name, out assetID))
1774 { 1785 {
1786 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1788 {
1777 if (item.Type == 7 && item.Name == name) 1789 if (item.Type == 7 && item.Name == name)
@@ -1779,6 +1791,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1791 assetID = item.AssetID;
1780 } 1792 }
1781 } 1793 }
1794 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1795 }
1783 1796
1784 if (assetID == UUID.Zero) 1797 if (assetID == UUID.Zero)
@@ -2258,9 +2271,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2258 { 2271 {
2259 if (avatar.IsChildAgent == false) 2272 if (avatar.IsChildAgent == false)
2260 { 2273 {
2261 result.Add(avatar.UUID); 2274 result.Add(new LSL_Key(avatar.UUID.ToString()));
2262 result.Add(avatar.AbsolutePosition); 2275 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2263 result.Add(avatar.Name); 2276 result.Add(new LSL_String(avatar.Name));
2264 } 2277 }
2265 } 2278 }
2266 }); 2279 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index fefbb35..3b7de53 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
204 // Is the sensor type is AGENT and not SCRIPTED then include agents 204 // Is the sensor type is AGENT and not SCRIPTED then include agents
205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0)
206 { 206 {
207 sensedEntities.AddRange(doAgentSensor(ts)); 207 sensedEntities.AddRange(doAgentSensor(ts));
208 } 208 }
209 209
210 // If SCRIPTED or PASSIVE or ACTIVE check objects 210 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -309,6 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // in mouselook. 309 // in mouselook.
310 310
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
312 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 313 q = avatar.Rotation;
313 } 314 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 315 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -422,6 +423,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
422 SceneObjectPart SensePoint = ts.host; 423 SceneObjectPart SensePoint = ts.host;
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 424 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 Quaternion q = SensePoint.RotationOffset; 425 Quaternion q = SensePoint.RotationOffset;
426 if (SensePoint.ParentGroup.RootPart.IsAttachment)
427 {
428 // In attachments, the sensor cone always orients with the
429 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook.
431
432 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
433 fromRegionPos = avatar.AbsolutePosition;
434 q = avatar.Rotation;
435 }
425 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 436 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
426 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 437 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
427 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 438 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 630821b..fbf601a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -81,7 +81,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
81 // Avatar Info Commands 81 // Avatar Info Commands
82 string osGetAgentIP(string agent); 82 string osGetAgentIP(string agent);
83 LSL_List osGetAgents(); 83 LSL_List osGetAgents();
84 84
85 // Teleport commands 85 // Teleport commands
86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 86 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 87 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index 5da6bb9..6e8435d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -279,6 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
280 public const int CHANGED_MEDIA = 2048; 280 public const int CHANGED_MEDIA = 2048;
281 public const int CHANGED_ANIMATION = 16384; 281 public const int CHANGED_ANIMATION = 16384;
282 public const int CHANGED_POSITION = 32768;
282 public const int TYPE_INVALID = 0; 283 public const int TYPE_INVALID = 0;
283 public const int TYPE_INTEGER = 1; 284 public const int TYPE_INTEGER = 1;
284 public const int TYPE_FLOAT = 2; 285 public const int TYPE_FLOAT = 2;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 451163f..f14967e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index f8dbe03..8280ca5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,5 +72,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
76 public LSL_List cmGetWindlightScene(LSL_List rules)
77 {
78 return m_LS_Functions.lsGetWindlightScene(rules);
79 }
80
81 public int cmSetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsSetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
87 {
88 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
89 }
75 } 90 }
76} 91}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6663aa5..623cb7d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -429,14 +430,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
429 { 430 {
430 int permsMask; 431 int permsMask;
431 UUID permsGranter; 432 UUID permsGranter;
432 lock (part.TaskInventory) 433 part.TaskInventory.LockItemsForRead(true);
434 if (!part.TaskInventory.ContainsKey(m_ItemID))
433 { 435 {
434 if (!part.TaskInventory.ContainsKey(m_ItemID)) 436 part.TaskInventory.LockItemsForRead(false);
435 return; 437 return;
436
437 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
438 permsMask = part.TaskInventory[m_ItemID].PermsMask;
439 } 438 }
439 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
440 permsMask = part.TaskInventory[m_ItemID].PermsMask;
441 part.TaskInventory.LockItemsForRead(false);
440 442
441 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 443 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
442 { 444 {
@@ -545,6 +547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
545 return true; 547 return true;
546 } 548 }
547 549
550 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
548 public void SetState(string state) 551 public void SetState(string state)
549 { 552 {
550 if (state == State) 553 if (state == State)
@@ -556,7 +559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
556 new DetectParams[0])); 559 new DetectParams[0]));
557 PostEvent(new EventParams("state_entry", new Object[0], 560 PostEvent(new EventParams("state_entry", new Object[0],
558 new DetectParams[0])); 561 new DetectParams[0]));
559 562
560 throw new EventAbortException(); 563 throw new EventAbortException();
561 } 564 }
562 565
@@ -639,14 +642,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
639 /// <returns></returns> 642 /// <returns></returns>
640 public object EventProcessor() 643 public object EventProcessor()
641 { 644 {
642 if (m_Suspended) 645 EventParams data = null;
643 return 0;
644 646
645 lock (m_Script) 647 lock (m_EventQueue)
646 { 648 {
647 EventParams data = null; 649 if (m_Suspended)
650 return 0;
648 651
649 lock (m_EventQueue) 652 lock (m_Script)
650 { 653 {
651 data = (EventParams) m_EventQueue.Dequeue(); 654 data = (EventParams) m_EventQueue.Dequeue();
652 if (data == null) // Shouldn't happen 655 if (data == null) // Shouldn't happen
@@ -672,6 +675,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
672 if (data.EventName == "collision") 675 if (data.EventName == "collision")
673 m_CollisionInQueue = false; 676 m_CollisionInQueue = false;
674 } 677 }
678 }
679 lock(m_Script)
680 {
675 681
676 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 682 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
677 683
@@ -828,6 +834,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
828 new Object[0], new DetectParams[0])); 834 new Object[0], new DetectParams[0]));
829 } 835 }
830 836
837 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
831 public void ApiResetScript() 838 public void ApiResetScript()
832 { 839 {
833 // bool running = Running; 840 // bool running = Running;
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 91e03ac..a3a2fdf 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -613,24 +613,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 613
614 public static bool operator ==(list a, list b) 614 public static bool operator ==(list a, list b)
615 { 615 {
616 int la = -1; 616 int la = a.Length;
617 int lb = -1; 617 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 618
623 return la == lb; 619 return la == lb;
624 } 620 }
625 621
626 public static bool operator !=(list a, list b) 622 public static bool operator !=(list a, list b)
627 { 623 {
628 int la = -1; 624 int la = a.Length;
629 int lb = -1; 625 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 626
635 return la != lb; 627 return la != lb;
636 } 628 }