aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1873
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
5 files changed, 1286 insertions, 705 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 b51b410..512957d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -81,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 82 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 84 {
84 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 86 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 87 protected SceneObjectPart m_host;
87 protected uint m_localID; 88 protected uint m_localID;
@@ -99,6 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 100 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 101 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 102 protected bool m_scriptConsoleChannelEnabled = false;
103 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 104 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 105 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 106 new Dictionary<UUID, UserInfoCacheEntry>();
@@ -109,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
109 m_host = host; 111 m_host = host;
110 m_localID = localID; 112 m_localID = localID;
111 m_itemID = itemID; 113 m_itemID = itemID;
114 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 115
113 m_ScriptDelayFactor = 116 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 117 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 164 get { return m_ScriptEngine.World; }
162 } 165 }
163 166
167 [DebuggerNonUserCode]
164 public void state(string newState) 168 public void state(string newState)
165 { 169 {
166 m_ScriptEngine.SetState(m_itemID, newState); 170 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 174 /// Reset the named script. The script must be present
171 /// in the same prim. 175 /// in the same prim.
172 /// </summary> 176 /// </summary>
177 [DebuggerNonUserCode]
173 public void llResetScript() 178 public void llResetScript()
174 { 179 {
175 m_host.AddScriptLPS(1); 180 m_host.AddScriptLPS(1);
@@ -226,9 +231,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 231 }
227 } 232 }
228 233
234 public List<ScenePresence> GetLinkAvatars(int linkType)
235 {
236 List<ScenePresence> ret = new List<ScenePresence>();
237 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
238 return ret;
239
240 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
241
242 switch (linkType)
243 {
244 case ScriptBaseClass.LINK_SET:
245 return avs;
246
247 case ScriptBaseClass.LINK_ROOT:
248 return ret;
249
250 case ScriptBaseClass.LINK_ALL_OTHERS:
251 return avs;
252
253 case ScriptBaseClass.LINK_ALL_CHILDREN:
254 return avs;
255
256 case ScriptBaseClass.LINK_THIS:
257 return ret;
258
259 default:
260 if (linkType < 0)
261 return ret;
262
263 int partCount = m_host.ParentGroup.GetPartCount();
264
265 if (linkType <= partCount)
266 {
267 return ret;
268 }
269 else
270 {
271 linkType = linkType - partCount;
272 if (linkType > avs.Count)
273 {
274 return ret;
275 }
276 else
277 {
278 ret.Add(avs[linkType-1]);
279 return ret;
280 }
281 }
282 }
283 }
284
229 public List<SceneObjectPart> GetLinkParts(int linkType) 285 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 286 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 287 List<SceneObjectPart> ret = new List<SceneObjectPart>();
288 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
289 return ret;
232 ret.Add(m_host); 290 ret.Add(m_host);
233 291
234 switch (linkType) 292 switch (linkType)
@@ -291,40 +349,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
291 protected UUID InventorySelf() 349 protected UUID InventorySelf()
292 { 350 {
293 UUID invItemID = new UUID(); 351 UUID invItemID = new UUID();
294 352 bool unlock = false;
295 lock (m_host.TaskInventory) 353 if (!m_host.TaskInventory.IsReadLockedByMe())
296 { 354 {
297 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 355 m_host.TaskInventory.LockItemsForRead(true);
356 unlock = true;
357 }
358 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
359 {
360 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
298 { 361 {
299 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 362 invItemID = inv.Key;
300 { 363 break;
301 invItemID = inv.Key;
302 break;
303 }
304 } 364 }
305 } 365 }
306 366 if (unlock)
367 {
368 m_host.TaskInventory.LockItemsForRead(false);
369 }
307 return invItemID; 370 return invItemID;
308 } 371 }
309 372
310 protected UUID InventoryKey(string name, int type) 373 protected UUID InventoryKey(string name, int type)
311 { 374 {
312 m_host.AddScriptLPS(1); 375 m_host.AddScriptLPS(1);
313 376 m_host.TaskInventory.LockItemsForRead(true);
314 lock (m_host.TaskInventory) 377
378 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 379 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 380 if (inv.Value.Name == name)
317 { 381 {
318 if (inv.Value.Name == name) 382 m_host.TaskInventory.LockItemsForRead(false);
383
384 if (inv.Value.Type != type)
319 { 385 {
320 if (inv.Value.Type != type) 386 return UUID.Zero;
321 return UUID.Zero;
322
323 return inv.Value.AssetID;
324 } 387 }
388
389 return inv.Value.AssetID;
325 } 390 }
326 } 391 }
327 392
393 m_host.TaskInventory.LockItemsForRead(false);
328 return UUID.Zero; 394 return UUID.Zero;
329 } 395 }
330 396
@@ -332,17 +398,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
332 { 398 {
333 m_host.AddScriptLPS(1); 399 m_host.AddScriptLPS(1);
334 400
335 lock (m_host.TaskInventory) 401
402 m_host.TaskInventory.LockItemsForRead(true);
403
404 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
336 { 405 {
337 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 406 if (inv.Value.Name == name)
338 { 407 {
339 if (inv.Value.Name == name) 408 m_host.TaskInventory.LockItemsForRead(false);
340 { 409 return inv.Value.AssetID;
341 return inv.Value.AssetID;
342 }
343 } 410 }
344 } 411 }
345 412
413 m_host.TaskInventory.LockItemsForRead(false);
414
415
346 return UUID.Zero; 416 return UUID.Zero;
347 } 417 }
348 418
@@ -484,26 +554,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
484 554
485 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 555 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
486 556
487 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 557 // Utility function for llRot2Euler
488 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 558
559 // normalize an angle between -PI and PI (-180 to +180 degrees)
560 protected double NormalizeAngle(double angle)
561 {
562 if (angle > -Math.PI && angle < Math.PI)
563 return angle;
564
565 int numPis = (int)(Math.PI / angle);
566 double remainder = angle - Math.PI * numPis;
567 if (numPis % 2 == 1)
568 return Math.PI - angle;
569 return remainder;
570 }
489 571
490 public LSL_Vector llRot2Euler(LSL_Rotation r) 572 public LSL_Vector llRot2Euler(LSL_Rotation q1)
491 { 573 {
492 m_host.AddScriptLPS(1); 574 m_host.AddScriptLPS(1);
493 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 575 LSL_Vector eul = new LSL_Vector();
494 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 576
495 double m = (t.x + t.y + t.z + t.s); 577 double sqw = q1.s*q1.s;
496 if (m == 0) return new LSL_Vector(); 578 double sqx = q1.x*q1.x;
497 double n = 2 * (r.y * r.s + r.x * r.z); 579 double sqy = q1.z*q1.z;
498 double p = m * m - n * n; 580 double sqz = q1.y*q1.y;
499 if (p > 0) 581 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
500 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 582 double test = q1.x*q1.z + q1.y*q1.s;
501 Math.Atan2(n, Math.Sqrt(p)), 583 if (test > 0.4999*unit) { // singularity at north pole
502 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 584 eul.z = 2 * Math.Atan2(q1.x,q1.s);
503 else if (n > 0) 585 eul.y = Math.PI/2;
504 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 586 eul.x = 0;
505 else 587 return eul;
506 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 588 }
589 if (test < -0.4999*unit) { // singularity at south pole
590 eul.z = -2 * Math.Atan2(q1.x,q1.s);
591 eul.y = -Math.PI/2;
592 eul.x = 0;
593 return eul;
594 }
595 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
596 eul.y = Math.Asin(2*test/unit);
597 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
598 return eul;
507 } 599 }
508 600
509 /* From wiki: 601 /* From wiki:
@@ -705,77 +797,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 797 {
706 //A and B should both be normalized 798 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 799 m_host.AddScriptLPS(1);
708 LSL_Rotation rotBetween; 800 /* This method is more accurate than the SL one, and thus causes problems
709 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 801 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
710 // continue calculation. 802
711 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 803 double dotProduct = LSL_Vector.Dot(a, b);
804 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
805 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
806 double angle = Math.Acos(dotProduct / magProduct);
807 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
808 double s = Math.Sin(angle / 2);
809
810 double x = axis.x * s;
811 double y = axis.y * s;
812 double z = axis.z * s;
813 double w = Math.Cos(angle / 2);
814
815 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
817
818 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
819 */
820
821 // This method mimics the 180 errors found in SL
822 // See www.euclideanspace.com... angleBetween
823 LSL_Vector vec_a = a;
824 LSL_Vector vec_b = b;
825
826 // Eliminate zero length
827 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
828 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
829 if (vec_a_mag < 0.00001 ||
830 vec_b_mag < 0.00001)
712 { 831 {
713 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 832 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
714 } 833 }
715 else 834
835 // Normalize
836 vec_a = llVecNorm(vec_a);
837 vec_b = llVecNorm(vec_b);
838
839 // Calculate axis and rotation angle
840 LSL_Vector axis = vec_a % vec_b;
841 LSL_Float cos_theta = vec_a * vec_b;
842
843 // Check if parallel
844 if (cos_theta > 0.99999)
716 { 845 {
717 a = LSL_Vector.Norm(a); 846 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
718 b = LSL_Vector.Norm(b); 847 }
719 double dotProduct = LSL_Vector.Dot(a, b); 848
720 // There are two degenerate cases possible. These are for vectors 180 or 849 // Check if anti-parallel
721 // 0 degrees apart. These have to be detected and handled individually. 850 else if (cos_theta < -0.99999)
722 // 851 {
723 // Check for vectors 180 degrees apart. 852 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
724 // A dot product of -1 would mean the angle between vectors is 180 degrees. 853 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
725 if (dotProduct < -0.9999999f) 854 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
726 { 855 }
727 // First assume X axis is orthogonal to the vectors. 856 else // other rotation
728 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 857 {
729 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 858 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
730 // Check for near zero vector. A very small non-zero number here will create 859 axis = llVecNorm(axis);
731 // a rotation in an undesired direction. 860 double x, y, z, s, t;
732 if (LSL_Vector.Mag(orthoVector) > 0.0001) 861 s = Math.Cos(theta);
733 { 862 t = Math.Sin(theta);
734 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 863 x = axis.x * t;
735 } 864 y = axis.y * t;
736 // If the magnitude of the vector was near zero, then assume the X axis is not 865 z = axis.z * t;
737 // orthogonal and use the Z axis instead. 866 return new LSL_Rotation(x,y,z,s);
738 else
739 {
740 // Set 180 z rotation.
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
742 }
743 }
744 // Check for parallel vectors.
745 // A dot product of 1 would mean the angle between vectors is 0 degrees.
746 else if (dotProduct > 0.9999999f)
747 {
748 // Set zero rotation.
749 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
750 }
751 else
752 {
753 // All special checks have been performed so get the axis of rotation.
754 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
755 // Quarternion s value is the length of the unit vector + dot product.
756 double qs = 1.0 + dotProduct;
757 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
758 // Normalize the rotation.
759 double mag = LSL_Rotation.Mag(rotBetween);
760 // We shouldn't have to worry about a divide by zero here. The qs value will be
761 // non-zero because we already know if we're here, then the dotProduct is not -1 so
762 // qs will not be zero. Also, we've already handled the input vectors being zero so the
763 // crossProduct vector should also not be zero.
764 rotBetween.x = rotBetween.x / mag;
765 rotBetween.y = rotBetween.y / mag;
766 rotBetween.z = rotBetween.z / mag;
767 rotBetween.s = rotBetween.s / mag;
768 // Check for undefined values and set zero rotation if any found. This code might not actually be required
769 // any longer since zero vectors are checked for at the top.
770 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
771 {
772 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
773 }
774 }
775 } 867 }
776 return rotBetween;
777 } 868 }
778 869
779 public void llWhisper(int channelID, string text) 870 public void llWhisper(int channelID, string text)
780 { 871 {
781 m_host.AddScriptLPS(1); 872 m_host.AddScriptLPS(1);
@@ -1099,10 +1190,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1099 return detectedParams.TouchUV; 1190 return detectedParams.TouchUV;
1100 } 1191 }
1101 1192
1193 [DebuggerNonUserCode]
1102 public virtual void llDie() 1194 public virtual void llDie()
1103 { 1195 {
1104 m_host.AddScriptLPS(1); 1196 m_host.AddScriptLPS(1);
1105 throw new SelfDeleteException(); 1197 if (!m_host.IsAttachment) throw new SelfDeleteException();
1106 } 1198 }
1107 1199
1108 public LSL_Float llGround(LSL_Vector offset) 1200 public LSL_Float llGround(LSL_Vector offset)
@@ -1175,6 +1267,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1175 1267
1176 public void llSetStatus(int status, int value) 1268 public void llSetStatus(int status, int value)
1177 { 1269 {
1270 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1271 return;
1178 m_host.AddScriptLPS(1); 1272 m_host.AddScriptLPS(1);
1179 1273
1180 int statusrotationaxis = 0; 1274 int statusrotationaxis = 0;
@@ -1408,6 +1502,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1408 { 1502 {
1409 m_host.AddScriptLPS(1); 1503 m_host.AddScriptLPS(1);
1410 1504
1505 SetColor(m_host, color, face);
1506 }
1507
1508 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1509 {
1510 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1511 return;
1512
1513 Primitive.TextureEntry tex = part.Shape.Textures;
1514 Color4 texcolor;
1515 if (face >= 0 && face < GetNumberOfSides(part))
1516 {
1517 texcolor = tex.CreateFace((uint)face).RGBA;
1518 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1519 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1520 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1521 tex.FaceTextures[face].RGBA = texcolor;
1522 part.UpdateTexture(tex);
1523 return;
1524 }
1525 else if (face == ScriptBaseClass.ALL_SIDES)
1526 {
1527 for (uint i = 0; i < GetNumberOfSides(part); i++)
1528 {
1529 if (tex.FaceTextures[i] != null)
1530 {
1531 texcolor = tex.FaceTextures[i].RGBA;
1532 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1533 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1534 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1535 tex.FaceTextures[i].RGBA = texcolor;
1536 }
1537 texcolor = tex.DefaultTexture.RGBA;
1538 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1539 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1540 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1541 tex.DefaultTexture.RGBA = texcolor;
1542 }
1543 part.UpdateTexture(tex);
1544 return;
1545 }
1546
1411 if (face == ScriptBaseClass.ALL_SIDES) 1547 if (face == ScriptBaseClass.ALL_SIDES)
1412 face = SceneObjectPart.ALL_SIDES; 1548 face = SceneObjectPart.ALL_SIDES;
1413 1549
@@ -1416,6 +1552,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1416 1552
1417 public void SetTexGen(SceneObjectPart part, int face,int style) 1553 public void SetTexGen(SceneObjectPart part, int face,int style)
1418 { 1554 {
1555 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1556 return;
1557
1419 Primitive.TextureEntry tex = part.Shape.Textures; 1558 Primitive.TextureEntry tex = part.Shape.Textures;
1420 MappingType textype; 1559 MappingType textype;
1421 textype = MappingType.Default; 1560 textype = MappingType.Default;
@@ -1446,6 +1585,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1446 1585
1447 public void SetGlow(SceneObjectPart part, int face, float glow) 1586 public void SetGlow(SceneObjectPart part, int face, float glow)
1448 { 1587 {
1588 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1589 return;
1590
1449 Primitive.TextureEntry tex = part.Shape.Textures; 1591 Primitive.TextureEntry tex = part.Shape.Textures;
1450 if (face >= 0 && face < GetNumberOfSides(part)) 1592 if (face >= 0 && face < GetNumberOfSides(part))
1451 { 1593 {
@@ -1471,6 +1613,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1471 1613
1472 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1614 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1473 { 1615 {
1616 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1617 return;
1474 1618
1475 Shininess sval = new Shininess(); 1619 Shininess sval = new Shininess();
1476 1620
@@ -1521,6 +1665,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1521 1665
1522 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1666 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1523 { 1667 {
1668 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1669 return;
1670
1524 Primitive.TextureEntry tex = part.Shape.Textures; 1671 Primitive.TextureEntry tex = part.Shape.Textures;
1525 if (face >= 0 && face < GetNumberOfSides(part)) 1672 if (face >= 0 && face < GetNumberOfSides(part))
1526 { 1673 {
@@ -1581,13 +1728,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1581 m_host.AddScriptLPS(1); 1728 m_host.AddScriptLPS(1);
1582 1729
1583 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1730 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1584 1731 if (parts.Count > 0)
1585 foreach (SceneObjectPart part in parts) 1732 {
1586 SetAlpha(part, alpha, face); 1733 try
1734 {
1735 parts[0].ParentGroup.areUpdatesSuspended = true;
1736 foreach (SceneObjectPart part in parts)
1737 SetAlpha(part, alpha, face);
1738 }
1739 finally
1740 {
1741 parts[0].ParentGroup.areUpdatesSuspended = false;
1742 }
1743 }
1587 } 1744 }
1588 1745
1589 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1746 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1590 { 1747 {
1748 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1749 return;
1750
1591 Primitive.TextureEntry tex = part.Shape.Textures; 1751 Primitive.TextureEntry tex = part.Shape.Textures;
1592 Color4 texcolor; 1752 Color4 texcolor;
1593 if (face >= 0 && face < GetNumberOfSides(part)) 1753 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1633,7 +1793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1633 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1793 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1634 float wind, float tension, LSL_Vector Force) 1794 float wind, float tension, LSL_Vector Force)
1635 { 1795 {
1636 if (part == null) 1796 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1637 return; 1797 return;
1638 1798
1639 if (flexi) 1799 if (flexi)
@@ -1668,7 +1828,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1668 /// <param name="falloff"></param> 1828 /// <param name="falloff"></param>
1669 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1829 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1670 { 1830 {
1671 if (part == null) 1831 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1672 return; 1832 return;
1673 1833
1674 if (light) 1834 if (light)
@@ -1745,15 +1905,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1745 m_host.AddScriptLPS(1); 1905 m_host.AddScriptLPS(1);
1746 1906
1747 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1907 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1748 1908 if (parts.Count > 0)
1749 foreach (SceneObjectPart part in parts) 1909 {
1750 SetTexture(part, texture, face); 1910 try
1751 1911 {
1912 parts[0].ParentGroup.areUpdatesSuspended = true;
1913 foreach (SceneObjectPart part in parts)
1914 SetTexture(part, texture, face);
1915 }
1916 finally
1917 {
1918 parts[0].ParentGroup.areUpdatesSuspended = false;
1919 }
1920 }
1752 ScriptSleep(200); 1921 ScriptSleep(200);
1753 } 1922 }
1754 1923
1755 protected void SetTexture(SceneObjectPart part, string texture, int face) 1924 protected void SetTexture(SceneObjectPart part, string texture, int face)
1756 { 1925 {
1926 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1927 return;
1928
1757 UUID textureID=new UUID(); 1929 UUID textureID=new UUID();
1758 1930
1759 if (!UUID.TryParse(texture, out textureID)) 1931 if (!UUID.TryParse(texture, out textureID))
@@ -1799,6 +1971,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 1971
1800 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1972 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1801 { 1973 {
1974 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1975 return;
1976
1802 Primitive.TextureEntry tex = part.Shape.Textures; 1977 Primitive.TextureEntry tex = part.Shape.Textures;
1803 if (face >= 0 && face < GetNumberOfSides(part)) 1978 if (face >= 0 && face < GetNumberOfSides(part))
1804 { 1979 {
@@ -1835,6 +2010,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1835 2010
1836 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2011 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1837 { 2012 {
2013 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2014 return;
2015
1838 Primitive.TextureEntry tex = part.Shape.Textures; 2016 Primitive.TextureEntry tex = part.Shape.Textures;
1839 if (face >= 0 && face < GetNumberOfSides(part)) 2017 if (face >= 0 && face < GetNumberOfSides(part))
1840 { 2018 {
@@ -1871,6 +2049,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1871 2049
1872 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2050 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1873 { 2051 {
2052 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2053 return;
2054
1874 Primitive.TextureEntry tex = part.Shape.Textures; 2055 Primitive.TextureEntry tex = part.Shape.Textures;
1875 if (face >= 0 && face < GetNumberOfSides(part)) 2056 if (face >= 0 && face < GetNumberOfSides(part))
1876 { 2057 {
@@ -1941,6 +2122,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1941 2122
1942 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2123 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1943 { 2124 {
2125 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2126 return;
2127
1944 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2128 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1945 LSL_Vector currentPos = GetPartLocalPos(part); 2129 LSL_Vector currentPos = GetPartLocalPos(part);
1946 2130
@@ -1957,7 +2141,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1957 } 2141 }
1958 else 2142 else
1959 { 2143 {
1960 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2144 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1961 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2145 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1962 SceneObjectGroup parent = part.ParentGroup; 2146 SceneObjectGroup parent = part.ParentGroup;
1963 parent.HasGroupChanged = true; 2147 parent.HasGroupChanged = true;
@@ -2040,6 +2224,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2040 2224
2041 protected void SetRot(SceneObjectPart part, Quaternion rot) 2225 protected void SetRot(SceneObjectPart part, Quaternion rot)
2042 { 2226 {
2227 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2228 return;
2229
2043 part.UpdateRotation(rot); 2230 part.UpdateRotation(rot);
2044 // Update rotation does not move the object in the physics scene if it's a linkset. 2231 // Update rotation does not move the object in the physics scene if it's a linkset.
2045 2232
@@ -2659,12 +2846,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2659 2846
2660 m_host.AddScriptLPS(1); 2847 m_host.AddScriptLPS(1);
2661 2848
2849 m_host.TaskInventory.LockItemsForRead(true);
2662 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2850 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2663 2851 m_host.TaskInventory.LockItemsForRead(false);
2664 lock (m_host.TaskInventory)
2665 {
2666 item = m_host.TaskInventory[invItemID];
2667 }
2668 2852
2669 if (item.PermsGranter == UUID.Zero) 2853 if (item.PermsGranter == UUID.Zero)
2670 return 0; 2854 return 0;
@@ -2739,6 +2923,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2739 if (dist > m_ScriptDistanceFactor * 10.0f) 2923 if (dist > m_ScriptDistanceFactor * 10.0f)
2740 return; 2924 return;
2741 2925
2926 //Clone is thread-safe
2742 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2927 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2743 2928
2744 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2801,6 +2986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2801 2986
2802 public void llLookAt(LSL_Vector target, double strength, double damping) 2987 public void llLookAt(LSL_Vector target, double strength, double damping)
2803 { 2988 {
2989 /*
2804 m_host.AddScriptLPS(1); 2990 m_host.AddScriptLPS(1);
2805 // Determine where we are looking from 2991 // Determine where we are looking from
2806 LSL_Vector from = llGetPos(); 2992 LSL_Vector from = llGetPos();
@@ -2820,10 +3006,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2820 // the angles of rotation in radians into rotation value 3006 // the angles of rotation in radians into rotation value
2821 3007
2822 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3008 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2823 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3009
2824 m_host.startLookAt(rotation, (float)damping, (float)strength); 3010 // This would only work if your physics system contains an APID controller:
3011 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3012 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3013
2825 // Orient the object to the angle calculated 3014 // Orient the object to the angle calculated
2826 //llSetRot(rot); 3015 llSetRot(rot);
3016 */
3017
3018 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3019 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3020 // http://bugs.meta7.com/view.php?id=28
3021 // - Tom
3022
3023 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3024 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3025
3026 }
3027
3028 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3029 {
3030 m_host.AddScriptLPS(1);
3031// NotImplemented("llRotLookAt");
3032 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3033
2827 } 3034 }
2828 3035
2829 public void llStopLookAt() 3036 public void llStopLookAt()
@@ -2872,13 +3079,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2872 { 3079 {
2873 TaskInventoryItem item; 3080 TaskInventoryItem item;
2874 3081
2875 lock (m_host.TaskInventory) 3082 m_host.TaskInventory.LockItemsForRead(true);
3083 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2876 { 3084 {
2877 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3085 m_host.TaskInventory.LockItemsForRead(false);
2878 return; 3086 return;
2879 else 3087 }
2880 item = m_host.TaskInventory[InventorySelf()]; 3088 else
3089 {
3090 item = m_host.TaskInventory[InventorySelf()];
2881 } 3091 }
3092 m_host.TaskInventory.LockItemsForRead(false);
2882 3093
2883 if (item.PermsGranter != UUID.Zero) 3094 if (item.PermsGranter != UUID.Zero)
2884 { 3095 {
@@ -2900,13 +3111,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2900 { 3111 {
2901 TaskInventoryItem item; 3112 TaskInventoryItem item;
2902 3113
3114 m_host.TaskInventory.LockItemsForRead(true);
2903 lock (m_host.TaskInventory) 3115 lock (m_host.TaskInventory)
2904 { 3116 {
3117
2905 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3118 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3119 {
3120 m_host.TaskInventory.LockItemsForRead(false);
2906 return; 3121 return;
3122 }
2907 else 3123 else
3124 {
2908 item = m_host.TaskInventory[InventorySelf()]; 3125 item = m_host.TaskInventory[InventorySelf()];
3126 }
2909 } 3127 }
3128 m_host.TaskInventory.LockItemsForRead(false);
2910 3129
2911 m_host.AddScriptLPS(1); 3130 m_host.AddScriptLPS(1);
2912 3131
@@ -2938,19 +3157,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 { 3157 {
2939 m_host.AddScriptLPS(1); 3158 m_host.AddScriptLPS(1);
2940 3159
2941 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2942 return;
2943
2944 TaskInventoryItem item; 3160 TaskInventoryItem item;
2945 3161
2946 lock (m_host.TaskInventory) 3162 m_host.TaskInventory.LockItemsForRead(true);
3163
3164 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2947 { 3165 {
2948 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3166 m_host.TaskInventory.LockItemsForRead(false);
2949 return; 3167 return;
2950 else 3168 }
2951 item = m_host.TaskInventory[InventorySelf()]; 3169 else
3170 {
3171 item = m_host.TaskInventory[InventorySelf()];
2952 } 3172 }
2953 3173
3174 m_host.TaskInventory.LockItemsForRead(false);
3175
2954 if (item.PermsGranter != m_host.OwnerID) 3176 if (item.PermsGranter != m_host.OwnerID)
2955 return; 3177 return;
2956 3178
@@ -2960,10 +3182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2960 3182
2961 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3183 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2962 3184
2963 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3185 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2964 if (attachmentsModule != null)
2965 attachmentsModule.AttachObject(presence.ControllingClient,
2966 grp, (uint)attachment, false);
2967 } 3186 }
2968 } 3187 }
2969 3188
@@ -2976,13 +3195,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2976 3195
2977 TaskInventoryItem item; 3196 TaskInventoryItem item;
2978 3197
2979 lock (m_host.TaskInventory) 3198 m_host.TaskInventory.LockItemsForRead(true);
3199
3200 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2980 { 3201 {
2981 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3202 m_host.TaskInventory.LockItemsForRead(false);
2982 return; 3203 return;
2983 else 3204 }
2984 item = m_host.TaskInventory[InventorySelf()]; 3205 else
3206 {
3207 item = m_host.TaskInventory[InventorySelf()];
2985 } 3208 }
3209 m_host.TaskInventory.LockItemsForRead(false);
3210
2986 3211
2987 if (item.PermsGranter != m_host.OwnerID) 3212 if (item.PermsGranter != m_host.OwnerID)
2988 return; 3213 return;
@@ -3021,6 +3246,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3021 3246
3022 public void llInstantMessage(string user, string message) 3247 public void llInstantMessage(string user, string message)
3023 { 3248 {
3249 UUID result;
3250 if (!UUID.TryParse(user, out result))
3251 {
3252 if (!m_debuggerSafe)
3253 {
3254 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3255 }
3256 return;
3257 }
3258
3259
3024 m_host.AddScriptLPS(1); 3260 m_host.AddScriptLPS(1);
3025 3261
3026 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3262 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3035,14 +3271,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3035 UUID friendTransactionID = UUID.Random(); 3271 UUID friendTransactionID = UUID.Random();
3036 3272
3037 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3273 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3038 3274
3039 GridInstantMessage msg = new GridInstantMessage(); 3275 GridInstantMessage msg = new GridInstantMessage();
3040 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3276 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3041 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3277 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3042 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3278 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3043// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3279// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3044// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3280// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3045 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3281 DateTime dt = DateTime.UtcNow;
3282
3283 // Ticks from UtcNow, but make it look like local. Evil, huh?
3284 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3285
3286 try
3287 {
3288 // Convert that to the PST timezone
3289 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3290 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3291 }
3292 catch
3293 {
3294 // No logging here, as it could be VERY spammy
3295 }
3296
3297 // And make it look local again to fool the unix time util
3298 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3299
3300 msg.timestamp = (uint)Util.ToUnixTime(dt);
3301
3046 //if (client != null) 3302 //if (client != null)
3047 //{ 3303 //{
3048 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3304 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3056,13 +3312,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3056 msg.message = message.Substring(0, 1024); 3312 msg.message = message.Substring(0, 1024);
3057 else 3313 else
3058 msg.message = message; 3314 msg.message = message;
3059 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3315 msg.dialog = (byte)19; // MessageFromObject
3060 msg.fromGroup = false;// fromGroup; 3316 msg.fromGroup = false;// fromGroup;
3061 msg.offline = (byte)0; //offline; 3317 msg.offline = (byte)0; //offline;
3062 msg.ParentEstateID = 0; //ParentEstateID; 3318 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3063 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3319 msg.Position = new Vector3(m_host.AbsolutePosition);
3064 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3320 msg.RegionID = World.RegionInfo.RegionID.Guid;
3065 msg.binaryBucket = new byte[0];// binaryBucket; 3321 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3066 3322
3067 if (m_TransferModule != null) 3323 if (m_TransferModule != null)
3068 { 3324 {
@@ -3082,7 +3338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3082 } 3338 }
3083 3339
3084 emailModule.SendEmail(m_host.UUID, address, subject, message); 3340 emailModule.SendEmail(m_host.UUID, address, subject, message);
3085 ScriptSleep(20000); 3341 ScriptSleep(15000);
3086 } 3342 }
3087 3343
3088 public void llGetNextEmail(string address, string subject) 3344 public void llGetNextEmail(string address, string subject)
@@ -3184,13 +3440,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3184 m_host.AddScriptLPS(1); 3440 m_host.AddScriptLPS(1);
3185 } 3441 }
3186 3442
3187 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3188 {
3189 m_host.AddScriptLPS(1);
3190 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3191 m_host.RotLookAt(rot, (float)strength, (float)damping);
3192 }
3193
3194 public LSL_Integer llStringLength(string str) 3443 public LSL_Integer llStringLength(string str)
3195 { 3444 {
3196 m_host.AddScriptLPS(1); 3445 m_host.AddScriptLPS(1);
@@ -3214,14 +3463,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3214 3463
3215 TaskInventoryItem item; 3464 TaskInventoryItem item;
3216 3465
3217 lock (m_host.TaskInventory) 3466 m_host.TaskInventory.LockItemsForRead(true);
3467 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3218 { 3468 {
3219 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3469 m_host.TaskInventory.LockItemsForRead(false);
3220 return; 3470 return;
3221 else
3222 item = m_host.TaskInventory[InventorySelf()];
3223 } 3471 }
3224 3472 else
3473 {
3474 item = m_host.TaskInventory[InventorySelf()];
3475 }
3476 m_host.TaskInventory.LockItemsForRead(false);
3225 if (item.PermsGranter == UUID.Zero) 3477 if (item.PermsGranter == UUID.Zero)
3226 return; 3478 return;
3227 3479
@@ -3251,13 +3503,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3251 3503
3252 TaskInventoryItem item; 3504 TaskInventoryItem item;
3253 3505
3254 lock (m_host.TaskInventory) 3506 m_host.TaskInventory.LockItemsForRead(true);
3507 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3255 { 3508 {
3256 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3509 m_host.TaskInventory.LockItemsForRead(false);
3257 return; 3510 return;
3258 else 3511 }
3259 item = m_host.TaskInventory[InventorySelf()]; 3512 else
3513 {
3514 item = m_host.TaskInventory[InventorySelf()];
3260 } 3515 }
3516 m_host.TaskInventory.LockItemsForRead(false);
3517
3261 3518
3262 if (item.PermsGranter == UUID.Zero) 3519 if (item.PermsGranter == UUID.Zero)
3263 return; 3520 return;
@@ -3328,10 +3585,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3328 3585
3329 TaskInventoryItem item; 3586 TaskInventoryItem item;
3330 3587
3331 lock (m_host.TaskInventory) 3588
3589 m_host.TaskInventory.LockItemsForRead(true);
3590 if (!m_host.TaskInventory.ContainsKey(invItemID))
3591 {
3592 m_host.TaskInventory.LockItemsForRead(false);
3593 return;
3594 }
3595 else
3332 { 3596 {
3333 item = m_host.TaskInventory[invItemID]; 3597 item = m_host.TaskInventory[invItemID];
3334 } 3598 }
3599 m_host.TaskInventory.LockItemsForRead(false);
3335 3600
3336 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3601 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3337 { 3602 {
@@ -3363,11 +3628,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3363 3628
3364 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3629 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3365 { 3630 {
3366 lock (m_host.TaskInventory) 3631 m_host.TaskInventory.LockItemsForWrite(true);
3367 { 3632 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3368 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3633 m_host.TaskInventory[invItemID].PermsMask = perm;
3369 m_host.TaskInventory[invItemID].PermsMask = perm; 3634 m_host.TaskInventory.LockItemsForWrite(false);
3370 }
3371 3635
3372 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3636 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3373 "run_time_permissions", new Object[] { 3637 "run_time_permissions", new Object[] {
@@ -3387,11 +3651,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3387 3651
3388 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3652 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3389 { 3653 {
3390 lock (m_host.TaskInventory) 3654 m_host.TaskInventory.LockItemsForWrite(true);
3391 { 3655 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3392 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3656 m_host.TaskInventory[invItemID].PermsMask = perm;
3393 m_host.TaskInventory[invItemID].PermsMask = perm; 3657 m_host.TaskInventory.LockItemsForWrite(false);
3394 }
3395 3658
3396 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3659 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3397 "run_time_permissions", new Object[] { 3660 "run_time_permissions", new Object[] {
@@ -3412,11 +3675,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3412 3675
3413 if (!m_waitingForScriptAnswer) 3676 if (!m_waitingForScriptAnswer)
3414 { 3677 {
3415 lock (m_host.TaskInventory) 3678 m_host.TaskInventory.LockItemsForWrite(true);
3416 { 3679 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3417 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3680 m_host.TaskInventory[invItemID].PermsMask = 0;
3418 m_host.TaskInventory[invItemID].PermsMask = 0; 3681 m_host.TaskInventory.LockItemsForWrite(false);
3419 }
3420 3682
3421 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3683 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3422 m_waitingForScriptAnswer=true; 3684 m_waitingForScriptAnswer=true;
@@ -3451,10 +3713,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3451 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3713 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3452 llReleaseControls(); 3714 llReleaseControls();
3453 3715
3454 lock (m_host.TaskInventory) 3716
3455 { 3717 m_host.TaskInventory.LockItemsForWrite(true);
3456 m_host.TaskInventory[invItemID].PermsMask = answer; 3718 m_host.TaskInventory[invItemID].PermsMask = answer;
3457 } 3719 m_host.TaskInventory.LockItemsForWrite(false);
3720
3458 3721
3459 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3722 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3460 "run_time_permissions", new Object[] { 3723 "run_time_permissions", new Object[] {
@@ -3466,16 +3729,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3466 { 3729 {
3467 m_host.AddScriptLPS(1); 3730 m_host.AddScriptLPS(1);
3468 3731
3469 lock (m_host.TaskInventory) 3732 m_host.TaskInventory.LockItemsForRead(true);
3733
3734 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3470 { 3735 {
3471 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3736 if (item.Type == 10 && item.ItemID == m_itemID)
3472 { 3737 {
3473 if (item.Type == 10 && item.ItemID == m_itemID) 3738 m_host.TaskInventory.LockItemsForRead(false);
3474 { 3739 return item.PermsGranter.ToString();
3475 return item.PermsGranter.ToString();
3476 }
3477 } 3740 }
3478 } 3741 }
3742 m_host.TaskInventory.LockItemsForRead(false);
3479 3743
3480 return UUID.Zero.ToString(); 3744 return UUID.Zero.ToString();
3481 } 3745 }
@@ -3484,19 +3748,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3484 { 3748 {
3485 m_host.AddScriptLPS(1); 3749 m_host.AddScriptLPS(1);
3486 3750
3487 lock (m_host.TaskInventory) 3751 m_host.TaskInventory.LockItemsForRead(true);
3752
3753 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3488 { 3754 {
3489 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3755 if (item.Type == 10 && item.ItemID == m_itemID)
3490 { 3756 {
3491 if (item.Type == 10 && item.ItemID == m_itemID) 3757 int perms = item.PermsMask;
3492 { 3758 if (m_automaticLinkPermission)
3493 int perms = item.PermsMask; 3759 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3494 if (m_automaticLinkPermission) 3760 m_host.TaskInventory.LockItemsForRead(false);
3495 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3761 return perms;
3496 return perms;
3497 }
3498 } 3762 }
3499 } 3763 }
3764 m_host.TaskInventory.LockItemsForRead(false);
3500 3765
3501 return 0; 3766 return 0;
3502 } 3767 }
@@ -3518,9 +3783,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3518 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3783 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3519 { 3784 {
3520 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3785 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3521 3786 if (parts.Count > 0)
3522 foreach (SceneObjectPart part in parts) 3787 {
3523 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3788 try
3789 {
3790 parts[0].ParentGroup.areUpdatesSuspended = true;
3791 foreach (SceneObjectPart part in parts)
3792 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3793 }
3794 finally
3795 {
3796 parts[0].ParentGroup.areUpdatesSuspended = false;
3797 }
3798 }
3524 } 3799 }
3525 3800
3526 public void llCreateLink(string target, int parent) 3801 public void llCreateLink(string target, int parent)
@@ -3533,11 +3808,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3533 return; 3808 return;
3534 3809
3535 TaskInventoryItem item; 3810 TaskInventoryItem item;
3536 lock (m_host.TaskInventory) 3811 m_host.TaskInventory.LockItemsForRead(true);
3537 { 3812 item = m_host.TaskInventory[invItemID];
3538 item = m_host.TaskInventory[invItemID]; 3813 m_host.TaskInventory.LockItemsForRead(false);
3539 } 3814
3540
3541 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3815 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3542 && !m_automaticLinkPermission) 3816 && !m_automaticLinkPermission)
3543 { 3817 {
@@ -3590,16 +3864,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3590 m_host.AddScriptLPS(1); 3864 m_host.AddScriptLPS(1);
3591 UUID invItemID = InventorySelf(); 3865 UUID invItemID = InventorySelf();
3592 3866
3593 lock (m_host.TaskInventory) 3867 m_host.TaskInventory.LockItemsForRead(true);
3594 {
3595 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3868 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3596 && !m_automaticLinkPermission) 3869 && !m_automaticLinkPermission)
3597 { 3870 {
3598 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3871 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3872 m_host.TaskInventory.LockItemsForRead(false);
3599 return; 3873 return;
3600 } 3874 }
3601 } 3875 m_host.TaskInventory.LockItemsForRead(false);
3602 3876
3603 if (linknum < ScriptBaseClass.LINK_THIS) 3877 if (linknum < ScriptBaseClass.LINK_THIS)
3604 return; 3878 return;
3605 3879
@@ -3639,30 +3913,50 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3639 if (linknum == ScriptBaseClass.LINK_ROOT) 3913 if (linknum == ScriptBaseClass.LINK_ROOT)
3640 { 3914 {
3641 // Restructuring Multiple Prims. 3915 // Restructuring Multiple Prims.
3642 lock (parentPrim.Children) 3916 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3917 parts.Remove(parentPrim.RootPart);
3918 if (parts.Count > 0)
3643 { 3919 {
3644 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3920 try
3645 parts.Remove(parentPrim.RootPart);
3646 foreach (SceneObjectPart part in parts)
3647 { 3921 {
3648 parentPrim.DelinkFromGroup(part.LocalId, true); 3922 parts[0].ParentGroup.areUpdatesSuspended = true;
3923 foreach (SceneObjectPart part in parts)
3924 {
3925 parentPrim.DelinkFromGroup(part.LocalId, true);
3926 }
3649 } 3927 }
3650 parentPrim.HasGroupChanged = true; 3928 finally
3651 parentPrim.ScheduleGroupForFullUpdate(); 3929 {
3652 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3930 parts[0].ParentGroup.areUpdatesSuspended = false;
3653 3931 }
3654 if (parts.Count > 0) 3932 }
3933
3934 parentPrim.HasGroupChanged = true;
3935 parentPrim.ScheduleGroupForFullUpdate();
3936 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3937
3938 if (parts.Count > 0)
3939 {
3940 SceneObjectPart newRoot = parts[0];
3941 parts.Remove(newRoot);
3942
3943 try
3655 { 3944 {
3656 SceneObjectPart newRoot = parts[0]; 3945 parts[0].ParentGroup.areUpdatesSuspended = true;
3657 parts.Remove(newRoot);
3658 foreach (SceneObjectPart part in parts) 3946 foreach (SceneObjectPart part in parts)
3659 { 3947 {
3660 part.UpdateFlag = 0; 3948 part.UpdateFlag = 0;
3661 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3949 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3662 } 3950 }
3663 newRoot.ParentGroup.HasGroupChanged = true;
3664 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3665 } 3951 }
3952 finally
3953 {
3954 parts[0].ParentGroup.areUpdatesSuspended = false;
3955 }
3956
3957
3958 newRoot.ParentGroup.HasGroupChanged = true;
3959 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3666 } 3960 }
3667 } 3961 }
3668 else 3962 else
@@ -3709,6 +4003,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3709 } 4003 }
3710 else 4004 else
3711 { 4005 {
4006 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4007 {
4008 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4009
4010 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4011 if (avatars.Count > linknum)
4012 {
4013 return avatars[linknum].UUID.ToString();
4014 }
4015 }
3712 return UUID.Zero.ToString(); 4016 return UUID.Zero.ToString();
3713 } 4017 }
3714 } 4018 }
@@ -3785,17 +4089,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3785 m_host.AddScriptLPS(1); 4089 m_host.AddScriptLPS(1);
3786 int count = 0; 4090 int count = 0;
3787 4091
3788 lock (m_host.TaskInventory) 4092 m_host.TaskInventory.LockItemsForRead(true);
4093 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3789 { 4094 {
3790 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4095 if (inv.Value.Type == type || type == -1)
3791 { 4096 {
3792 if (inv.Value.Type == type || type == -1) 4097 count = count + 1;
3793 {
3794 count = count + 1;
3795 }
3796 } 4098 }
3797 } 4099 }
3798 4100
4101 m_host.TaskInventory.LockItemsForRead(false);
3799 return count; 4102 return count;
3800 } 4103 }
3801 4104
@@ -3804,16 +4107,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3804 m_host.AddScriptLPS(1); 4107 m_host.AddScriptLPS(1);
3805 ArrayList keys = new ArrayList(); 4108 ArrayList keys = new ArrayList();
3806 4109
3807 lock (m_host.TaskInventory) 4110 m_host.TaskInventory.LockItemsForRead(true);
4111 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3808 { 4112 {
3809 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4113 if (inv.Value.Type == type || type == -1)
3810 { 4114 {
3811 if (inv.Value.Type == type || type == -1) 4115 keys.Add(inv.Value.Name);
3812 {
3813 keys.Add(inv.Value.Name);
3814 }
3815 } 4116 }
3816 } 4117 }
4118 m_host.TaskInventory.LockItemsForRead(false);
3817 4119
3818 if (keys.Count == 0) 4120 if (keys.Count == 0)
3819 { 4121 {
@@ -3850,20 +4152,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3850 } 4152 }
3851 4153
3852 // move the first object found with this inventory name 4154 // move the first object found with this inventory name
3853 lock (m_host.TaskInventory) 4155 m_host.TaskInventory.LockItemsForRead(true);
4156 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3854 { 4157 {
3855 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4158 if (inv.Value.Name == inventory)
3856 { 4159 {
3857 if (inv.Value.Name == inventory) 4160 found = true;
3858 { 4161 objId = inv.Key;
3859 found = true; 4162 assetType = inv.Value.Type;
3860 objId = inv.Key; 4163 objName = inv.Value.Name;
3861 assetType = inv.Value.Type; 4164 break;
3862 objName = inv.Value.Name;
3863 break;
3864 }
3865 } 4165 }
3866 } 4166 }
4167 m_host.TaskInventory.LockItemsForRead(false);
3867 4168
3868 if (!found) 4169 if (!found)
3869 { 4170 {
@@ -3871,9 +4172,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3871 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4172 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3872 } 4173 }
3873 4174
3874 // check if destination is an avatar 4175 // check if destination is an object
3875 if (World.GetScenePresence(destId) != null) 4176 if (World.GetSceneObjectPart(destId) != null)
4177 {
4178 // destination is an object
4179 World.MoveTaskInventoryItem(destId, m_host, objId);
4180 }
4181 else
3876 { 4182 {
4183 ScenePresence presence = World.GetScenePresence(destId);
4184
4185 if (presence == null)
4186 {
4187 UserAccount account =
4188 World.UserAccountService.GetUserAccount(
4189 World.RegionInfo.ScopeID,
4190 destId);
4191
4192 if (account == null)
4193 {
4194 llSay(0, "Can't find destination "+destId.ToString());
4195 return;
4196 }
4197 }
4198
3877 // destination is an avatar 4199 // destination is an avatar
3878 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4200 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3879 4201
@@ -3897,31 +4219,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 4219
3898 if (m_TransferModule != null) 4220 if (m_TransferModule != null)
3899 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4221 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4222
4223 //This delay should only occur when giving inventory to avatars.
4224 ScriptSleep(3000);
3900 } 4225 }
3901 else
3902 {
3903 // destination is an object
3904 World.MoveTaskInventoryItem(destId, m_host, objId);
3905 }
3906 ScriptSleep(3000);
3907 } 4226 }
3908 4227
4228 [DebuggerNonUserCode]
3909 public void llRemoveInventory(string name) 4229 public void llRemoveInventory(string name)
3910 { 4230 {
3911 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3912 4232
3913 lock (m_host.TaskInventory) 4233 List<TaskInventoryItem> inv;
4234 try
3914 { 4235 {
3915 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4236 m_host.TaskInventory.LockItemsForRead(true);
4237 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4238 }
4239 finally
4240 {
4241 m_host.TaskInventory.LockItemsForRead(false);
4242 }
4243 foreach (TaskInventoryItem item in inv)
4244 {
4245 if (item.Name == name)
3916 { 4246 {
3917 if (item.Name == name) 4247 if (item.ItemID == m_itemID)
3918 { 4248 throw new ScriptDeleteException();
3919 if (item.ItemID == m_itemID) 4249 else
3920 throw new ScriptDeleteException(); 4250 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3921 else 4251 return;
3922 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3923 return;
3924 }
3925 } 4252 }
3926 } 4253 }
3927 } 4254 }
@@ -3979,6 +4306,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3979 ce.time = Util.EnvironmentTickCount(); 4306 ce.time = Util.EnvironmentTickCount();
3980 ce.account = account; 4307 ce.account = account;
3981 ce.pinfo = pinfo; 4308 ce.pinfo = pinfo;
4309 m_userInfoCache[uuid] = ce;
3982 } 4310 }
3983 else 4311 else
3984 { 4312 {
@@ -4046,6 +4374,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4046 { 4374 {
4047 m_host.AddScriptLPS(1); 4375 m_host.AddScriptLPS(1);
4048 4376
4377 //Clone is thread safe
4049 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4378 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4050 4379
4051 foreach (TaskInventoryItem item in itemDictionary.Values) 4380 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4099,6 +4428,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4099 ScenePresence presence = World.GetScenePresence(agentId); 4428 ScenePresence presence = World.GetScenePresence(agentId);
4100 if (presence != null) 4429 if (presence != null)
4101 { 4430 {
4431 // agent must not be a god
4432 if (presence.GodLevel >= 200) return;
4433
4102 // agent must be over the owners land 4434 // agent must be over the owners land
4103 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4435 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4104 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4436 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4158,17 +4490,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4158 UUID soundId = UUID.Zero; 4490 UUID soundId = UUID.Zero;
4159 if (!UUID.TryParse(impact_sound, out soundId)) 4491 if (!UUID.TryParse(impact_sound, out soundId))
4160 { 4492 {
4161 lock (m_host.TaskInventory) 4493 m_host.TaskInventory.LockItemsForRead(true);
4494 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4162 { 4495 {
4163 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4496 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4164 { 4497 {
4165 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4498 soundId = item.AssetID;
4166 { 4499 break;
4167 soundId = item.AssetID;
4168 break;
4169 }
4170 } 4500 }
4171 } 4501 }
4502 m_host.TaskInventory.LockItemsForRead(false);
4172 } 4503 }
4173 m_host.CollisionSound = soundId; 4504 m_host.CollisionSound = soundId;
4174 m_host.CollisionSoundVolume = (float)impact_volume; 4505 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4214,6 +4545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4214 UUID partItemID; 4545 UUID partItemID;
4215 foreach (SceneObjectPart part in parts) 4546 foreach (SceneObjectPart part in parts)
4216 { 4547 {
4548 //Clone is thread safe
4217 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4549 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4218 4550
4219 foreach (TaskInventoryItem item in itemsDictionary.Values) 4551 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4428,17 +4760,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4428 4760
4429 m_host.AddScriptLPS(1); 4761 m_host.AddScriptLPS(1);
4430 4762
4431 lock (m_host.TaskInventory) 4763 m_host.TaskInventory.LockItemsForRead(true);
4764 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4432 { 4765 {
4433 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4766 if (item.Type == 10 && item.ItemID == m_itemID)
4434 { 4767 {
4435 if (item.Type == 10 && item.ItemID == m_itemID) 4768 result = item.Name!=null?item.Name:String.Empty;
4436 { 4769 break;
4437 result = item.Name != null ? item.Name : String.Empty;
4438 break;
4439 }
4440 } 4770 }
4441 } 4771 }
4772 m_host.TaskInventory.LockItemsForRead(false);
4442 4773
4443 return result; 4774 return result;
4444 } 4775 }
@@ -4591,23 +4922,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4591 { 4922 {
4592 m_host.AddScriptLPS(1); 4923 m_host.AddScriptLPS(1);
4593 4924
4594 lock (m_host.TaskInventory) 4925 m_host.TaskInventory.LockItemsForRead(true);
4926 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4595 { 4927 {
4596 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4928 if (inv.Value.Name == name)
4597 { 4929 {
4598 if (inv.Value.Name == name) 4930 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4599 { 4931 {
4600 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4932 m_host.TaskInventory.LockItemsForRead(false);
4601 { 4933 return inv.Value.AssetID.ToString();
4602 return inv.Value.AssetID.ToString(); 4934 }
4603 } 4935 else
4604 else 4936 {
4605 { 4937 m_host.TaskInventory.LockItemsForRead(false);
4606 return UUID.Zero.ToString(); 4938 return UUID.Zero.ToString();
4607 }
4608 } 4939 }
4609 } 4940 }
4610 } 4941 }
4942 m_host.TaskInventory.LockItemsForRead(false);
4611 4943
4612 return UUID.Zero.ToString(); 4944 return UUID.Zero.ToString();
4613 } 4945 }
@@ -4760,14 +5092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4760 { 5092 {
4761 m_host.AddScriptLPS(1); 5093 m_host.AddScriptLPS(1);
4762 5094
4763 if (src == null) 5095 return src.Length;
4764 {
4765 return 0;
4766 }
4767 else
4768 {
4769 return src.Length;
4770 }
4771 } 5096 }
4772 5097
4773 public LSL_Integer llList2Integer(LSL_List src, int index) 5098 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4813,7 +5138,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4813 else if (src.Data[index] is LSL_Float) 5138 else if (src.Data[index] is LSL_Float)
4814 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5139 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4815 else if (src.Data[index] is LSL_String) 5140 else if (src.Data[index] is LSL_String)
4816 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5141 {
5142 string str = ((LSL_String) src.Data[index]).m_string;
5143 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5144 if (m != Match.Empty)
5145 {
5146 str = m.Value;
5147 double d = 0.0;
5148 if (!Double.TryParse(str, out d))
5149 return 0.0;
5150
5151 return d;
5152 }
5153 return 0.0;
5154 }
4817 return Convert.ToDouble(src.Data[index]); 5155 return Convert.ToDouble(src.Data[index]);
4818 } 5156 }
4819 catch (FormatException) 5157 catch (FormatException)
@@ -5498,7 +5836,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5498 public void llSetSoundQueueing(int queue) 5836 public void llSetSoundQueueing(int queue)
5499 { 5837 {
5500 m_host.AddScriptLPS(1); 5838 m_host.AddScriptLPS(1);
5501 NotImplemented("llSetSoundQueueing");
5502 } 5839 }
5503 5840
5504 public void llSetSoundRadius(double radius) 5841 public void llSetSoundRadius(double radius)
@@ -5543,10 +5880,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5543 m_host.AddScriptLPS(1); 5880 m_host.AddScriptLPS(1);
5544 5881
5545 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5882 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5546 5883 if (parts.Count > 0)
5547 foreach (var part in parts)
5548 { 5884 {
5549 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5885 try
5886 {
5887 parts[0].ParentGroup.areUpdatesSuspended = true;
5888 foreach (var part in parts)
5889 {
5890 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5891 }
5892 }
5893 finally
5894 {
5895 parts[0].ParentGroup.areUpdatesSuspended = false;
5896 }
5550 } 5897 }
5551 } 5898 }
5552 5899
@@ -5602,74 +5949,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5602 5949
5603 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5950 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5604 { 5951 {
5605 m_host.AddScriptLPS(1); 5952 return ParseString2List(str, separators, in_spacers, false);
5606 LSL_List ret = new LSL_List();
5607 LSL_List spacers = new LSL_List();
5608 if (in_spacers.Length > 0 && separators.Length > 0)
5609 {
5610 for (int i = 0; i < in_spacers.Length; i++)
5611 {
5612 object s = in_spacers.Data[i];
5613 for (int j = 0; j < separators.Length; j++)
5614 {
5615 if (separators.Data[j].ToString() == s.ToString())
5616 {
5617 s = null;
5618 break;
5619 }
5620 }
5621 if (s != null)
5622 {
5623 spacers.Add(s);
5624 }
5625 }
5626 }
5627 object[] delimiters = new object[separators.Length + spacers.Length];
5628 separators.Data.CopyTo(delimiters, 0);
5629 spacers.Data.CopyTo(delimiters, separators.Length);
5630 bool dfound = false;
5631 do
5632 {
5633 dfound = false;
5634 int cindex = -1;
5635 string cdeli = "";
5636 for (int i = 0; i < delimiters.Length; i++)
5637 {
5638 int index = str.IndexOf(delimiters[i].ToString());
5639 bool found = index != -1;
5640 if (found && String.Empty != delimiters[i].ToString())
5641 {
5642 if ((cindex > index) || (cindex == -1))
5643 {
5644 cindex = index;
5645 cdeli = delimiters[i].ToString();
5646 }
5647 dfound = dfound || found;
5648 }
5649 }
5650 if (cindex != -1)
5651 {
5652 if (cindex > 0)
5653 {
5654 ret.Add(new LSL_String(str.Substring(0, cindex)));
5655 }
5656 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5657 for (int j = 0; j < spacers.Length; j++)
5658 {
5659 if (spacers.Data[j].ToString() == cdeli)
5660 {
5661 ret.Add(new LSL_String(cdeli));
5662 break;
5663 }
5664 }
5665 str = str.Substring(cindex + cdeli.Length);
5666 }
5667 } while (dfound);
5668 if (str != "")
5669 {
5670 ret.Add(new LSL_String(str));
5671 }
5672 return ret;
5673 } 5953 }
5674 5954
5675 public LSL_Integer llOverMyLand(string id) 5955 public LSL_Integer llOverMyLand(string id)
@@ -5872,7 +6152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5872 return m_host.ParentGroup.RootPart.AttachmentPoint; 6152 return m_host.ParentGroup.RootPart.AttachmentPoint;
5873 } 6153 }
5874 6154
5875 public LSL_Integer llGetFreeMemory() 6155 public virtual LSL_Integer llGetFreeMemory()
5876 { 6156 {
5877 m_host.AddScriptLPS(1); 6157 m_host.AddScriptLPS(1);
5878 // Make scripts designed for LSO happy 6158 // Make scripts designed for LSO happy
@@ -6183,14 +6463,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6183 6463
6184 protected UUID GetTaskInventoryItem(string name) 6464 protected UUID GetTaskInventoryItem(string name)
6185 { 6465 {
6186 lock (m_host.TaskInventory) 6466 m_host.TaskInventory.LockItemsForRead(true);
6467 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6187 { 6468 {
6188 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6469 if (inv.Value.Name == name)
6189 { 6470 {
6190 if (inv.Value.Name == name) 6471 m_host.TaskInventory.LockItemsForRead(false);
6191 return inv.Key; 6472 return inv.Key;
6192 } 6473 }
6193 } 6474 }
6475 m_host.TaskInventory.LockItemsForRead(false);
6194 6476
6195 return UUID.Zero; 6477 return UUID.Zero;
6196 } 6478 }
@@ -6518,22 +6800,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6518 } 6800 }
6519 6801
6520 // copy the first script found with this inventory name 6802 // copy the first script found with this inventory name
6521 lock (m_host.TaskInventory) 6803 m_host.TaskInventory.LockItemsForRead(true);
6804 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6522 { 6805 {
6523 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6806 if (inv.Value.Name == name)
6524 { 6807 {
6525 if (inv.Value.Name == name) 6808 // make sure the object is a script
6809 if (10 == inv.Value.Type)
6526 { 6810 {
6527 // make sure the object is a script 6811 found = true;
6528 if (10 == inv.Value.Type) 6812 srcId = inv.Key;
6529 { 6813 break;
6530 found = true;
6531 srcId = inv.Key;
6532 break;
6533 }
6534 } 6814 }
6535 } 6815 }
6536 } 6816 }
6817 m_host.TaskInventory.LockItemsForRead(false);
6537 6818
6538 if (!found) 6819 if (!found)
6539 { 6820 {
@@ -6617,6 +6898,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6617 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6898 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6618 { 6899 {
6619 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6900 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6901 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6902 return shapeBlock;
6620 6903
6621 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6904 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6622 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6905 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6692,6 +6975,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6692 6975
6693 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6976 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6694 { 6977 {
6978 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6979 return;
6980
6695 ObjectShapePacket.ObjectDataBlock shapeBlock; 6981 ObjectShapePacket.ObjectDataBlock shapeBlock;
6696 6982
6697 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6983 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6741,6 +7027,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6741 7027
6742 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7028 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6743 { 7029 {
7030 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7031 return;
7032
6744 ObjectShapePacket.ObjectDataBlock shapeBlock; 7033 ObjectShapePacket.ObjectDataBlock shapeBlock;
6745 7034
6746 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7035 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6783,6 +7072,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6783 7072
6784 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) 7073 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)
6785 { 7074 {
7075 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7076 return;
7077
6786 ObjectShapePacket.ObjectDataBlock shapeBlock; 7078 ObjectShapePacket.ObjectDataBlock shapeBlock;
6787 7079
6788 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7080 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6909,6 +7201,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6909 7201
6910 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7202 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6911 { 7203 {
7204 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7205 return;
7206
6912 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7207 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6913 UUID sculptId; 7208 UUID sculptId;
6914 7209
@@ -6924,13 +7219,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6924 shapeBlock.PathScaleX = 100; 7219 shapeBlock.PathScaleX = 100;
6925 shapeBlock.PathScaleY = 150; 7220 shapeBlock.PathScaleY = 150;
6926 7221
6927 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7222 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6928 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7223 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6929 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7224 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6930 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7225 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6931 { 7226 {
6932 // default 7227 // default
6933 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7228 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6934 } 7229 }
6935 7230
6936 // retain pathcurve 7231 // retain pathcurve
@@ -6947,23 +7242,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6947 SetPrimParams(m_host, rules); 7242 SetPrimParams(m_host, rules);
6948 } 7243 }
6949 7244
6950 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7245 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6951 { 7246 {
6952 m_host.AddScriptLPS(1); 7247 m_host.AddScriptLPS(1);
6953 7248
6954 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7249 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7250 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7251 if (parts.Count>0)
7252 {
7253 try
7254 {
7255 parts[0].ParentGroup.areUpdatesSuspended = true;
7256 foreach (SceneObjectPart part in parts)
7257 SetPrimParams(part, rules);
7258 }
7259 finally
7260 {
7261 parts[0].ParentGroup.areUpdatesSuspended = false;
7262 }
7263 }
7264 if (avatars.Count > 0)
7265 {
7266 foreach (ScenePresence avatar in avatars)
7267 SetPrimParams(avatar, rules);
7268 }
7269 }
6955 7270
6956 foreach (SceneObjectPart part in parts) 7271 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6957 SetPrimParams(part, rules); 7272 {
7273 llSetLinkPrimitiveParamsFast(linknumber, rules);
7274 ScriptSleep(200);
6958 } 7275 }
6959 7276
6960 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7277 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6961 { 7278 {
6962 llSetLinkPrimitiveParams(linknumber, rules); 7279 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7280 //We only support PRIM_POSITION and PRIM_ROTATION
7281
7282 int idx = 0;
7283
7284 while (idx < rules.Length)
7285 {
7286 int code = rules.GetLSLIntegerItem(idx++);
7287
7288 int remain = rules.Length - idx;
7289
7290
7291
7292 switch (code)
7293 {
7294 case (int)ScriptBaseClass.PRIM_POSITION:
7295 if (remain < 1)
7296 return;
7297 LSL_Vector v;
7298 v = rules.GetVector3Item(idx++);
7299 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7300 av.SendFullUpdateToAllClients();
7301
7302 break;
7303
7304 case (int)ScriptBaseClass.PRIM_ROTATION:
7305 if (remain < 1)
7306 return;
7307 LSL_Rotation r;
7308 r = rules.GetQuaternionItem(idx++);
7309 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7310 av.SendFullUpdateToAllClients();
7311 break;
7312 }
7313 }
7314
6963 } 7315 }
6964 7316
6965 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7317 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6966 { 7318 {
7319 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7320 return;
7321
6967 int idx = 0; 7322 int idx = 0;
6968 7323
6969 while (idx < rules.Length) 7324 while (idx < rules.Length)
@@ -7480,13 +7835,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7480 public LSL_Integer llGetNumberOfPrims() 7835 public LSL_Integer llGetNumberOfPrims()
7481 { 7836 {
7482 m_host.AddScriptLPS(1); 7837 m_host.AddScriptLPS(1);
7483 int avatarCount = 0; 7838 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7484 World.ForEachScenePresence(delegate(ScenePresence presence) 7839
7485 {
7486 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7487 avatarCount++;
7488 });
7489
7490 return m_host.ParentGroup.PrimCount + avatarCount; 7840 return m_host.ParentGroup.PrimCount + avatarCount;
7491 } 7841 }
7492 7842
@@ -7502,55 +7852,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7502 m_host.AddScriptLPS(1); 7852 m_host.AddScriptLPS(1);
7503 UUID objID = UUID.Zero; 7853 UUID objID = UUID.Zero;
7504 LSL_List result = new LSL_List(); 7854 LSL_List result = new LSL_List();
7855
7856 // If the ID is not valid, return null result
7505 if (!UUID.TryParse(obj, out objID)) 7857 if (!UUID.TryParse(obj, out objID))
7506 { 7858 {
7507 result.Add(new LSL_Vector()); 7859 result.Add(new LSL_Vector());
7508 result.Add(new LSL_Vector()); 7860 result.Add(new LSL_Vector());
7509 return result; 7861 return result;
7510 } 7862 }
7863
7864 // Check if this is an attached prim. If so, replace
7865 // the UUID with the avatar UUID and report it's bounding box
7866 SceneObjectPart part = World.GetSceneObjectPart(objID);
7867 if (part != null && part.ParentGroup.IsAttachment)
7868 objID = part.ParentGroup.RootPart.AttachedAvatar;
7869
7870 // Find out if this is an avatar ID. If so, return it's box
7511 ScenePresence presence = World.GetScenePresence(objID); 7871 ScenePresence presence = World.GetScenePresence(objID);
7512 if (presence != null) 7872 if (presence != null)
7513 { 7873 {
7514 if (presence.ParentID == 0) // not sat on an object 7874 // As per LSL Wiki, there is no difference between sitting
7875 // and standing avatar since server 1.36
7876 LSL_Vector lower;
7877 LSL_Vector upper;
7878 if (presence.Animator.Animations.DefaultAnimation.AnimID
7879 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7515 { 7880 {
7516 LSL_Vector lower; 7881 // This is for ground sitting avatars
7517 LSL_Vector upper; 7882 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7518 if (presence.Animator.Animations.DefaultAnimation.AnimID 7883 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7519 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7884 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7520 {
7521 // This is for ground sitting avatars
7522 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7523 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7524 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7525 }
7526 else
7527 {
7528 // This is for standing/flying avatars
7529 float height = presence.Appearance.AvatarHeight / 2.0f;
7530 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7531 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7532 }
7533 result.Add(lower);
7534 result.Add(upper);
7535 return result;
7536 } 7885 }
7537 else 7886 else
7538 { 7887 {
7539 // sitting on an object so we need the bounding box of that 7888 // This is for standing/flying avatars
7540 // which should include the avatar so set the UUID to the 7889 float height = presence.Appearance.AvatarHeight / 2.0f;
7541 // UUID of the object the avatar is sat on and allow it to fall through 7890 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7542 // to processing an object 7891 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7543 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7544 objID = p.UUID;
7545 } 7892 }
7893
7894 // Adjust to the documented error offsets (see LSL Wiki)
7895 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7896 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7897
7898 if (lower.x > upper.x)
7899 lower.x = upper.x;
7900 if (lower.y > upper.y)
7901 lower.y = upper.y;
7902 if (lower.z > upper.z)
7903 lower.z = upper.z;
7904
7905 result.Add(lower);
7906 result.Add(upper);
7907 return result;
7546 } 7908 }
7547 SceneObjectPart part = World.GetSceneObjectPart(objID); 7909
7910 part = World.GetSceneObjectPart(objID);
7548 // Currently only works for single prims without a sitting avatar 7911 // Currently only works for single prims without a sitting avatar
7549 if (part != null) 7912 if (part != null)
7550 { 7913 {
7551 Vector3 halfSize = part.Scale / 2.0f; 7914 float minX;
7552 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7915 float maxX;
7553 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7916 float minY;
7917 float maxY;
7918 float minZ;
7919 float maxZ;
7920
7921 // This BBox is in sim coordinates, with the offset being
7922 // a contained point.
7923 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7924 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7925
7926 minX -= offsets[0].X;
7927 maxX -= offsets[0].X;
7928 minY -= offsets[0].Y;
7929 maxY -= offsets[0].Y;
7930 minZ -= offsets[0].Z;
7931 maxZ -= offsets[0].Z;
7932
7933 LSL_Vector lower;
7934 LSL_Vector upper;
7935
7936 // Adjust to the documented error offsets (see LSL Wiki)
7937 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7938 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7939
7940 if (lower.x > upper.x)
7941 lower.x = upper.x;
7942 if (lower.y > upper.y)
7943 lower.y = upper.y;
7944 if (lower.z > upper.z)
7945 lower.z = upper.z;
7946
7554 result.Add(lower); 7947 result.Add(lower);
7555 result.Add(upper); 7948 result.Add(upper);
7556 return result; 7949 return result;
@@ -7795,24 +8188,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7795 break; 8188 break;
7796 8189
7797 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8190 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7798 // TODO--------------
7799 if (remain < 1) 8191 if (remain < 1)
7800 return res; 8192 return res;
8193 face = (int)rules.GetLSLIntegerItem(idx++);
7801 8194
7802 face=(int)rules.GetLSLIntegerItem(idx++); 8195 tex = part.Shape.Textures;
7803 8196 int shiny;
7804 res.Add(new LSL_Integer(0)); 8197 if (face == ScriptBaseClass.ALL_SIDES)
7805 res.Add(new LSL_Integer(0)); 8198 {
8199 for (face = 0; face < GetNumberOfSides(part); face++)
8200 {
8201 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8202 if (shinyness == Shininess.High)
8203 {
8204 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8205 }
8206 else if (shinyness == Shininess.Medium)
8207 {
8208 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8209 }
8210 else if (shinyness == Shininess.Low)
8211 {
8212 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8213 }
8214 else
8215 {
8216 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8217 }
8218 res.Add(new LSL_Integer(shiny));
8219 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8220 }
8221 }
8222 else
8223 {
8224 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8225 if (shinyness == Shininess.High)
8226 {
8227 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8228 }
8229 else if (shinyness == Shininess.Medium)
8230 {
8231 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8232 }
8233 else if (shinyness == Shininess.Low)
8234 {
8235 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8236 }
8237 else
8238 {
8239 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8240 }
8241 res.Add(new LSL_Integer(shiny));
8242 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8243 }
7806 break; 8244 break;
7807 8245
7808 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8246 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7809 // TODO--------------
7810 if (remain < 1) 8247 if (remain < 1)
7811 return res; 8248 return res;
8249 face = (int)rules.GetLSLIntegerItem(idx++);
7812 8250
7813 face=(int)rules.GetLSLIntegerItem(idx++); 8251 tex = part.Shape.Textures;
7814 8252 int fullbright;
7815 res.Add(new LSL_Integer(0)); 8253 if (face == ScriptBaseClass.ALL_SIDES)
8254 {
8255 for (face = 0; face < GetNumberOfSides(part); face++)
8256 {
8257 if (tex.GetFace((uint)face).Fullbright == true)
8258 {
8259 fullbright = ScriptBaseClass.TRUE;
8260 }
8261 else
8262 {
8263 fullbright = ScriptBaseClass.FALSE;
8264 }
8265 res.Add(new LSL_Integer(fullbright));
8266 }
8267 }
8268 else
8269 {
8270 if (tex.GetFace((uint)face).Fullbright == true)
8271 {
8272 fullbright = ScriptBaseClass.TRUE;
8273 }
8274 else
8275 {
8276 fullbright = ScriptBaseClass.FALSE;
8277 }
8278 res.Add(new LSL_Integer(fullbright));
8279 }
7816 break; 8280 break;
7817 8281
7818 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8282 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7833,14 +8297,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7833 break; 8297 break;
7834 8298
7835 case (int)ScriptBaseClass.PRIM_TEXGEN: 8299 case (int)ScriptBaseClass.PRIM_TEXGEN:
7836 // TODO--------------
7837 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8300 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7838 if (remain < 1) 8301 if (remain < 1)
7839 return res; 8302 return res;
8303 face = (int)rules.GetLSLIntegerItem(idx++);
7840 8304
7841 face=(int)rules.GetLSLIntegerItem(idx++); 8305 tex = part.Shape.Textures;
7842 8306 if (face == ScriptBaseClass.ALL_SIDES)
7843 res.Add(new LSL_Integer(0)); 8307 {
8308 for (face = 0; face < GetNumberOfSides(part); face++)
8309 {
8310 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8311 {
8312 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8313 }
8314 else
8315 {
8316 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8317 }
8318 }
8319 }
8320 else
8321 {
8322 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8323 {
8324 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8325 }
8326 else
8327 {
8328 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8329 }
8330 }
7844 break; 8331 break;
7845 8332
7846 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8333 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7859,13 +8346,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7859 break; 8346 break;
7860 8347
7861 case (int)ScriptBaseClass.PRIM_GLOW: 8348 case (int)ScriptBaseClass.PRIM_GLOW:
7862 // TODO--------------
7863 if (remain < 1) 8349 if (remain < 1)
7864 return res; 8350 return res;
8351 face = (int)rules.GetLSLIntegerItem(idx++);
7865 8352
7866 face=(int)rules.GetLSLIntegerItem(idx++); 8353 tex = part.Shape.Textures;
7867 8354 float primglow;
7868 res.Add(new LSL_Float(0)); 8355 if (face == ScriptBaseClass.ALL_SIDES)
8356 {
8357 for (face = 0; face < GetNumberOfSides(part); face++)
8358 {
8359 primglow = tex.GetFace((uint)face).Glow;
8360 res.Add(new LSL_Float(primglow));
8361 }
8362 }
8363 else
8364 {
8365 primglow = tex.GetFace((uint)face).Glow;
8366 res.Add(new LSL_Float(primglow));
8367 }
7869 break; 8368 break;
7870 case (int)ScriptBaseClass.PRIM_TEXT: 8369 case (int)ScriptBaseClass.PRIM_TEXT:
7871 Color4 textColor = part.GetTextColor(); 8370 Color4 textColor = part.GetTextColor();
@@ -8406,8 +8905,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8406 // The function returns an ordered list 8905 // The function returns an ordered list
8407 // representing the tokens found in the supplied 8906 // representing the tokens found in the supplied
8408 // sources string. If two successive tokenizers 8907 // sources string. If two successive tokenizers
8409 // are encountered, then a NULL entry is added 8908 // are encountered, then a null-string entry is
8410 // to the list. 8909 // added to the list.
8411 // 8910 //
8412 // It is a precondition that the source and 8911 // It is a precondition that the source and
8413 // toekizer lisst are non-null. If they are null, 8912 // toekizer lisst are non-null. If they are null,
@@ -8415,7 +8914,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8415 // while their lengths are being determined. 8914 // while their lengths are being determined.
8416 // 8915 //
8417 // A small amount of working memoryis required 8916 // A small amount of working memoryis required
8418 // of approximately 8*#tokenizers. 8917 // of approximately 8*#tokenizers + 8*srcstrlen.
8419 // 8918 //
8420 // There are many ways in which this function 8919 // There are many ways in which this function
8421 // can be implemented, this implementation is 8920 // can be implemented, this implementation is
@@ -8431,136 +8930,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8431 // and eliminates redundant tokenizers as soon 8930 // and eliminates redundant tokenizers as soon
8432 // as is possible. 8931 // as is possible.
8433 // 8932 //
8434 // The implementation tries to avoid any copying 8933 // The implementation tries to minimize temporary
8435 // of arrays or other objects. 8934 // garbage generation.
8436 // </remarks> 8935 // </remarks>
8437 8936
8438 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8937 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8439 { 8938 {
8440 int beginning = 0; 8939 return ParseString2List(src, separators, spacers, true);
8441 int srclen = src.Length; 8940 }
8442 int seplen = separators.Length;
8443 object[] separray = separators.Data;
8444 int spclen = spacers.Length;
8445 object[] spcarray = spacers.Data;
8446 int mlen = seplen+spclen;
8447
8448 int[] offset = new int[mlen+1];
8449 bool[] active = new bool[mlen];
8450 8941
8451 int best; 8942 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8452 int j; 8943 {
8944 int srclen = src.Length;
8945 int seplen = separators.Length;
8946 object[] separray = separators.Data;
8947 int spclen = spacers.Length;
8948 object[] spcarray = spacers.Data;
8949 int dellen = 0;
8950 string[] delarray = new string[seplen+spclen];
8453 8951
8454 // Initial capacity reduces resize cost 8952 int outlen = 0;
8953 string[] outarray = new string[srclen*2+1];
8455 8954
8456 LSL_List tokens = new LSL_List(); 8955 int i, j;
8956 string d;
8457 8957
8458 m_host.AddScriptLPS(1); 8958 m_host.AddScriptLPS(1);
8459 8959
8460 // All entries are initially valid 8960 /*
8461 8961 * Convert separator and spacer lists to C# strings.
8462 for (int i = 0; i < mlen; i++) 8962 * Also filter out null strings so we don't hang.
8463 active[i] = true; 8963 */
8464 8964 for (i = 0; i < seplen; i ++) {
8465 offset[mlen] = srclen; 8965 d = separray[i].ToString();
8466 8966 if (d.Length > 0) {
8467 while (beginning < srclen) 8967 delarray[dellen++] = d;
8468 { 8968 }
8469 8969 }
8470 best = mlen; // as bad as it gets 8970 seplen = dellen;
8471
8472 // Scan for separators
8473 8971
8474 for (j = 0; j < seplen; j++) 8972 for (i = 0; i < spclen; i ++) {
8475 { 8973 d = spcarray[i].ToString();
8476 if (active[j]) 8974 if (d.Length > 0) {
8477 { 8975 delarray[dellen++] = d;
8478 // scan all of the markers
8479 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8480 {
8481 // not present at all
8482 active[j] = false;
8483 }
8484 else
8485 {
8486 // present and correct
8487 if (offset[j] < offset[best])
8488 {
8489 // closest so far
8490 best = j;
8491 if (offset[best] == beginning)
8492 break;
8493 }
8494 }
8495 }
8496 } 8976 }
8977 }
8497 8978
8498 // Scan for spacers 8979 /*
8980 * Scan through source string from beginning to end.
8981 */
8982 for (i = 0;;) {
8499 8983
8500 if (offset[best] != beginning) 8984 /*
8501 { 8985 * Find earliest delimeter in src starting at i (if any).
8502 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8986 */
8503 { 8987 int earliestDel = -1;
8504 if (active[j]) 8988 int earliestSrc = srclen;
8505 { 8989 string earliestStr = null;
8506 // scan all of the markers 8990 for (j = 0; j < dellen; j ++) {
8507 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8991 d = delarray[j];
8508 { 8992 if (d != null) {
8509 // not present at all 8993 int index = src.IndexOf(d, i);
8510 active[j] = false; 8994 if (index < 0) {
8511 } 8995 delarray[j] = null; // delim nowhere in src, don't check it anymore
8512 else 8996 } else if (index < earliestSrc) {
8513 { 8997 earliestSrc = index; // where delimeter starts in source string
8514 // present and correct 8998 earliestDel = j; // where delimeter is in delarray[]
8515 if (offset[j] < offset[best]) 8999 earliestStr = d; // the delimeter string from delarray[]
8516 { 9000 if (index == i) break; // can't do any better than found at beg of string
8517 // closest so far
8518 best = j;
8519 }
8520 }
8521 } 9001 }
8522 } 9002 }
8523 } 9003 }
8524 9004
8525 // This is the normal exit from the scanning loop 9005 /*
8526 9006 * Output source string starting at i through start of earliest delimeter.
8527 if (best == mlen) 9007 */
8528 { 9008 if (keepNulls || (earliestSrc > i)) {
8529 // no markers were found on this pass 9009 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8530 // so we're pretty much done
8531 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8532 break;
8533 } 9010 }
8534 9011
8535 // Otherwise we just add the newly delimited token 9012 /*
8536 // and recalculate where the search should continue. 9013 * If no delimeter found at or after i, we're done scanning.
8537 9014 */
8538 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9015 if (earliestDel < 0) break;
8539 9016
8540 if (best < seplen) 9017 /*
8541 { 9018 * If delimeter was a spacer, output the spacer.
8542 beginning = offset[best] + (separray[best].ToString()).Length; 9019 */
8543 } 9020 if (earliestDel >= seplen) {
8544 else 9021 outarray[outlen++] = earliestStr;
8545 {
8546 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8547 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8548 } 9022 }
8549 }
8550
8551 // This an awkward an not very intuitive boundary case. If the
8552 // last substring is a tokenizer, then there is an implied trailing
8553 // null list entry. Hopefully the single comparison will not be too
8554 // arduous. Alternatively the 'break' could be replced with a return
8555 // but that's shabby programming.
8556 9023
8557 if (beginning == srclen) 9024 /*
8558 { 9025 * Look at rest of src string following delimeter.
8559 if (srclen != 0) 9026 */
8560 tokens.Add(new LSL_String("")); 9027 i = earliestSrc + earliestStr.Length;
8561 } 9028 }
8562 9029
8563 return tokens; 9030 /*
9031 * Make up an exact-sized output array suitable for an LSL_List object.
9032 */
9033 object[] outlist = new object[outlen];
9034 for (i = 0; i < outlen; i ++) {
9035 outlist[i] = new LSL_String(outarray[i]);
9036 }
9037 return new LSL_List(outlist);
8564 } 9038 }
8565 9039
8566 public LSL_Integer llGetObjectPermMask(int mask) 9040 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8637,28 +9111,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8637 { 9111 {
8638 m_host.AddScriptLPS(1); 9112 m_host.AddScriptLPS(1);
8639 9113
8640 lock (m_host.TaskInventory) 9114 m_host.TaskInventory.LockItemsForRead(true);
9115 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8641 { 9116 {
8642 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9117 if (inv.Value.Name == item)
8643 { 9118 {
8644 if (inv.Value.Name == item) 9119 m_host.TaskInventory.LockItemsForRead(false);
9120 switch (mask)
8645 { 9121 {
8646 switch (mask) 9122 case 0:
8647 { 9123 return (int)inv.Value.BasePermissions;
8648 case 0: 9124 case 1:
8649 return (int)inv.Value.BasePermissions; 9125 return (int)inv.Value.CurrentPermissions;
8650 case 1: 9126 case 2:
8651 return (int)inv.Value.CurrentPermissions; 9127 return (int)inv.Value.GroupPermissions;
8652 case 2: 9128 case 3:
8653 return (int)inv.Value.GroupPermissions; 9129 return (int)inv.Value.EveryonePermissions;
8654 case 3: 9130 case 4:
8655 return (int)inv.Value.EveryonePermissions; 9131 return (int)inv.Value.NextPermissions;
8656 case 4:
8657 return (int)inv.Value.NextPermissions;
8658 }
8659 } 9132 }
8660 } 9133 }
8661 } 9134 }
9135 m_host.TaskInventory.LockItemsForRead(false);
8662 9136
8663 return -1; 9137 return -1;
8664 } 9138 }
@@ -8705,16 +9179,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8705 { 9179 {
8706 m_host.AddScriptLPS(1); 9180 m_host.AddScriptLPS(1);
8707 9181
8708 lock (m_host.TaskInventory) 9182 m_host.TaskInventory.LockItemsForRead(true);
9183 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8709 { 9184 {
8710 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9185 if (inv.Value.Name == item)
8711 { 9186 {
8712 if (inv.Value.Name == item) 9187 m_host.TaskInventory.LockItemsForRead(false);
8713 { 9188 return inv.Value.CreatorID.ToString();
8714 return inv.Value.CreatorID.ToString();
8715 }
8716 } 9189 }
8717 } 9190 }
9191 m_host.TaskInventory.LockItemsForRead(false);
8718 9192
8719 llSay(0, "No item name '" + item + "'"); 9193 llSay(0, "No item name '" + item + "'");
8720 9194
@@ -8765,8 +9239,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8765 return UUID.Zero.ToString(); 9239 return UUID.Zero.ToString();
8766 } 9240 }
8767 reply = new LSL_Vector( 9241 reply = new LSL_Vector(
8768 info.RegionLocX * Constants.RegionSize, 9242 info.RegionLocX,
8769 info.RegionLocY * Constants.RegionSize, 9243 info.RegionLocY,
8770 0).ToString(); 9244 0).ToString();
8771 break; 9245 break;
8772 case 6: // DATA_SIM_STATUS 9246 case 6: // DATA_SIM_STATUS
@@ -8979,17 +9453,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8979 int width = 0; 9453 int width = 0;
8980 int height = 0; 9454 int height = 0;
8981 9455
8982 ParcelMediaCommandEnum? commandToSend = null; 9456 uint commandToSend = 0;
8983 float time = 0.0f; // default is from start 9457 float time = 0.0f; // default is from start
8984 9458
8985 ScenePresence presence = null; 9459 ScenePresence presence = null;
8986 9460
8987 for (int i = 0; i < commandList.Data.Length; i++) 9461 for (int i = 0; i < commandList.Data.Length; i++)
8988 { 9462 {
8989 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9463 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8990 switch (command) 9464 switch (command)
8991 { 9465 {
8992 case ParcelMediaCommandEnum.Agent: 9466 case (uint)ParcelMediaCommandEnum.Agent:
8993 // we send only to one agent 9467 // we send only to one agent
8994 if ((i + 1) < commandList.Length) 9468 if ((i + 1) < commandList.Length)
8995 { 9469 {
@@ -9006,25 +9480,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9006 } 9480 }
9007 break; 9481 break;
9008 9482
9009 case ParcelMediaCommandEnum.Loop: 9483 case (uint)ParcelMediaCommandEnum.Loop:
9010 loop = 1; 9484 loop = 1;
9011 commandToSend = command; 9485 commandToSend = command;
9012 update = true; //need to send the media update packet to set looping 9486 update = true; //need to send the media update packet to set looping
9013 break; 9487 break;
9014 9488
9015 case ParcelMediaCommandEnum.Play: 9489 case (uint)ParcelMediaCommandEnum.Play:
9016 loop = 0; 9490 loop = 0;
9017 commandToSend = command; 9491 commandToSend = command;
9018 update = true; //need to send the media update packet to make sure it doesn't loop 9492 update = true; //need to send the media update packet to make sure it doesn't loop
9019 break; 9493 break;
9020 9494
9021 case ParcelMediaCommandEnum.Pause: 9495 case (uint)ParcelMediaCommandEnum.Pause:
9022 case ParcelMediaCommandEnum.Stop: 9496 case (uint)ParcelMediaCommandEnum.Stop:
9023 case ParcelMediaCommandEnum.Unload: 9497 case (uint)ParcelMediaCommandEnum.Unload:
9024 commandToSend = command; 9498 commandToSend = command;
9025 break; 9499 break;
9026 9500
9027 case ParcelMediaCommandEnum.Url: 9501 case (uint)ParcelMediaCommandEnum.Url:
9028 if ((i + 1) < commandList.Length) 9502 if ((i + 1) < commandList.Length)
9029 { 9503 {
9030 if (commandList.Data[i + 1] is LSL_String) 9504 if (commandList.Data[i + 1] is LSL_String)
@@ -9037,7 +9511,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9037 } 9511 }
9038 break; 9512 break;
9039 9513
9040 case ParcelMediaCommandEnum.Texture: 9514 case (uint)ParcelMediaCommandEnum.Texture:
9041 if ((i + 1) < commandList.Length) 9515 if ((i + 1) < commandList.Length)
9042 { 9516 {
9043 if (commandList.Data[i + 1] is LSL_String) 9517 if (commandList.Data[i + 1] is LSL_String)
@@ -9050,7 +9524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9050 } 9524 }
9051 break; 9525 break;
9052 9526
9053 case ParcelMediaCommandEnum.Time: 9527 case (uint)ParcelMediaCommandEnum.Time:
9054 if ((i + 1) < commandList.Length) 9528 if ((i + 1) < commandList.Length)
9055 { 9529 {
9056 if (commandList.Data[i + 1] is LSL_Float) 9530 if (commandList.Data[i + 1] is LSL_Float)
@@ -9062,7 +9536,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9062 } 9536 }
9063 break; 9537 break;
9064 9538
9065 case ParcelMediaCommandEnum.AutoAlign: 9539 case (uint)ParcelMediaCommandEnum.AutoAlign:
9066 if ((i + 1) < commandList.Length) 9540 if ((i + 1) < commandList.Length)
9067 { 9541 {
9068 if (commandList.Data[i + 1] is LSL_Integer) 9542 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9076,7 +9550,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9076 } 9550 }
9077 break; 9551 break;
9078 9552
9079 case ParcelMediaCommandEnum.Type: 9553 case (uint)ParcelMediaCommandEnum.Type:
9080 if ((i + 1) < commandList.Length) 9554 if ((i + 1) < commandList.Length)
9081 { 9555 {
9082 if (commandList.Data[i + 1] is LSL_String) 9556 if (commandList.Data[i + 1] is LSL_String)
@@ -9089,7 +9563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9089 } 9563 }
9090 break; 9564 break;
9091 9565
9092 case ParcelMediaCommandEnum.Desc: 9566 case (uint)ParcelMediaCommandEnum.Desc:
9093 if ((i + 1) < commandList.Length) 9567 if ((i + 1) < commandList.Length)
9094 { 9568 {
9095 if (commandList.Data[i + 1] is LSL_String) 9569 if (commandList.Data[i + 1] is LSL_String)
@@ -9102,7 +9576,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9102 } 9576 }
9103 break; 9577 break;
9104 9578
9105 case ParcelMediaCommandEnum.Size: 9579 case (uint)ParcelMediaCommandEnum.Size:
9106 if ((i + 2) < commandList.Length) 9580 if ((i + 2) < commandList.Length)
9107 { 9581 {
9108 if (commandList.Data[i + 1] is LSL_Integer) 9582 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9172,7 +9646,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9172 } 9646 }
9173 } 9647 }
9174 9648
9175 if (commandToSend != null) 9649 if (commandToSend != 0)
9176 { 9650 {
9177 // the commandList contained a start/stop/... command, too 9651 // the commandList contained a start/stop/... command, too
9178 if (presence == null) 9652 if (presence == null)
@@ -9209,7 +9683,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9209 9683
9210 if (aList.Data[i] != null) 9684 if (aList.Data[i] != null)
9211 { 9685 {
9212 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9686 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9213 { 9687 {
9214 case ParcelMediaCommandEnum.Url: 9688 case ParcelMediaCommandEnum.Url:
9215 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9689 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9252,16 +9726,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9252 { 9726 {
9253 m_host.AddScriptLPS(1); 9727 m_host.AddScriptLPS(1);
9254 9728
9255 lock (m_host.TaskInventory) 9729 m_host.TaskInventory.LockItemsForRead(true);
9730 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9256 { 9731 {
9257 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9732 if (inv.Value.Name == name)
9258 { 9733 {
9259 if (inv.Value.Name == name) 9734 m_host.TaskInventory.LockItemsForRead(false);
9260 { 9735 return inv.Value.Type;
9261 return inv.Value.Type;
9262 }
9263 } 9736 }
9264 } 9737 }
9738 m_host.TaskInventory.LockItemsForRead(false);
9265 9739
9266 return -1; 9740 return -1;
9267 } 9741 }
@@ -9272,15 +9746,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9272 9746
9273 if (quick_pay_buttons.Data.Length < 4) 9747 if (quick_pay_buttons.Data.Length < 4)
9274 { 9748 {
9275 LSLError("List must have at least 4 elements"); 9749 int x;
9276 return; 9750 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9751 {
9752 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9753 }
9277 } 9754 }
9278 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9755 int[] nPrice = new int[5];
9279 9756 nPrice[0]=price;
9280 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9757 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9281 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9758 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9282 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9759 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9283 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9760 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9761 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9284 m_host.ParentGroup.HasGroupChanged = true; 9762 m_host.ParentGroup.HasGroupChanged = true;
9285 } 9763 }
9286 9764
@@ -9292,17 +9770,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 if (invItemID == UUID.Zero) 9770 if (invItemID == UUID.Zero)
9293 return new LSL_Vector(); 9771 return new LSL_Vector();
9294 9772
9295 lock (m_host.TaskInventory) 9773 m_host.TaskInventory.LockItemsForRead(true);
9774 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9296 { 9775 {
9297 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9776 m_host.TaskInventory.LockItemsForRead(false);
9298 return new LSL_Vector(); 9777 return new LSL_Vector();
9778 }
9299 9779
9300 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9780 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9301 { 9781 {
9302 ShoutError("No permissions to track the camera"); 9782 ShoutError("No permissions to track the camera");
9303 return new LSL_Vector(); 9783 m_host.TaskInventory.LockItemsForRead(false);
9304 } 9784 return new LSL_Vector();
9305 } 9785 }
9786 m_host.TaskInventory.LockItemsForRead(false);
9306 9787
9307 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9788 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9308 if (presence != null) 9789 if (presence != null)
@@ -9320,17 +9801,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9320 if (invItemID == UUID.Zero) 9801 if (invItemID == UUID.Zero)
9321 return new LSL_Rotation(); 9802 return new LSL_Rotation();
9322 9803
9323 lock (m_host.TaskInventory) 9804 m_host.TaskInventory.LockItemsForRead(true);
9805 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9324 { 9806 {
9325 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9807 m_host.TaskInventory.LockItemsForRead(false);
9326 return new LSL_Rotation(); 9808 return new LSL_Rotation();
9327 9809 }
9328 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9810 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9329 { 9811 {
9330 ShoutError("No permissions to track the camera"); 9812 ShoutError("No permissions to track the camera");
9331 return new LSL_Rotation(); 9813 m_host.TaskInventory.LockItemsForRead(false);
9332 } 9814 return new LSL_Rotation();
9333 } 9815 }
9816 m_host.TaskInventory.LockItemsForRead(false);
9334 9817
9335 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9818 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9336 if (presence != null) 9819 if (presence != null)
@@ -9392,8 +9875,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9392 { 9875 {
9393 m_host.AddScriptLPS(1); 9876 m_host.AddScriptLPS(1);
9394 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9877 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9395 if (detectedParams == null) return; // only works on the first detected avatar 9878 if (detectedParams == null)
9396 9879 {
9880 if (m_host.IsAttachment == true)
9881 {
9882 detectedParams = new DetectParams();
9883 detectedParams.Key = m_host.OwnerID;
9884 }
9885 else
9886 {
9887 return;
9888 }
9889 }
9890
9397 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9891 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9398 if (avatar != null) 9892 if (avatar != null)
9399 { 9893 {
@@ -9401,6 +9895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9401 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9895 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9402 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9896 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9403 } 9897 }
9898
9404 ScriptSleep(1000); 9899 ScriptSleep(1000);
9405 } 9900 }
9406 9901
@@ -9480,14 +9975,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 if (objectID == UUID.Zero) return; 9975 if (objectID == UUID.Zero) return;
9481 9976
9482 UUID agentID; 9977 UUID agentID;
9483 lock (m_host.TaskInventory) 9978 m_host.TaskInventory.LockItemsForRead(true);
9484 { 9979 // we need the permission first, to know which avatar we want to set the camera for
9485 // we need the permission first, to know which avatar we want to set the camera for 9980 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9486 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9487 9981
9488 if (agentID == UUID.Zero) return; 9982 if (agentID == UUID.Zero)
9489 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9983 {
9984 m_host.TaskInventory.LockItemsForRead(false);
9985 return;
9986 }
9987 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9988 {
9989 m_host.TaskInventory.LockItemsForRead(false);
9990 return;
9490 } 9991 }
9992 m_host.TaskInventory.LockItemsForRead(false);
9491 9993
9492 ScenePresence presence = World.GetScenePresence(agentID); 9994 ScenePresence presence = World.GetScenePresence(agentID);
9493 9995
@@ -9537,12 +10039,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9537 10039
9538 // we need the permission first, to know which avatar we want to clear the camera for 10040 // we need the permission first, to know which avatar we want to clear the camera for
9539 UUID agentID; 10041 UUID agentID;
9540 lock (m_host.TaskInventory) 10042 m_host.TaskInventory.LockItemsForRead(true);
10043 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10044 if (agentID == UUID.Zero)
10045 {
10046 m_host.TaskInventory.LockItemsForRead(false);
10047 return;
10048 }
10049 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9541 { 10050 {
9542 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10051 m_host.TaskInventory.LockItemsForRead(false);
9543 if (agentID == UUID.Zero) return; 10052 return;
9544 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9545 } 10053 }
10054 m_host.TaskInventory.LockItemsForRead(false);
9546 10055
9547 ScenePresence presence = World.GetScenePresence(agentID); 10056 ScenePresence presence = World.GetScenePresence(agentID);
9548 10057
@@ -9609,19 +10118,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9609 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10118 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9610 { 10119 {
9611 m_host.AddScriptLPS(1); 10120 m_host.AddScriptLPS(1);
9612 string ret = String.Empty; 10121
9613 string src1 = llBase64ToString(str1); 10122 if (str1 == String.Empty)
9614 string src2 = llBase64ToString(str2); 10123 return String.Empty;
9615 int c = 0; 10124 if (str2 == String.Empty)
9616 for (int i = 0; i < src1.Length; i++) 10125 return str1;
10126
10127 byte[] data1 = Convert.FromBase64String(str1);
10128 byte[] data2 = Convert.FromBase64String(str2);
10129
10130 byte[] d2 = new Byte[data1.Length];
10131 int pos = 0;
10132
10133 if (data1.Length <= data2.Length)
10134 {
10135 Array.Copy(data2, 0, d2, 0, data1.Length);
10136 }
10137 else
9617 { 10138 {
9618 ret += (char) (src1[i] ^ src2[c]); 10139 while (pos < data1.Length)
10140 {
10141 int len = data1.Length - pos;
10142 if (len > data2.Length)
10143 len = data2.Length;
9619 10144
9620 c++; 10145 Array.Copy(data2, 0, d2, pos, len);
9621 if (c >= src2.Length) 10146 pos += len;
9622 c = 0; 10147 }
9623 } 10148 }
9624 return llStringToBase64(ret); 10149
10150 for (pos = 0 ; pos < data1.Length ; pos++ )
10151 data1[pos] ^= d2[pos];
10152
10153 return Convert.ToBase64String(data1);
9625 } 10154 }
9626 10155
9627 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10156 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9999,15 +10528,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9999 10528
10000 internal UUID ScriptByName(string name) 10529 internal UUID ScriptByName(string name)
10001 { 10530 {
10002 lock (m_host.TaskInventory) 10531 m_host.TaskInventory.LockItemsForRead(true);
10532
10533 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10003 { 10534 {
10004 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10535 if (item.Type == 10 && item.Name == name)
10005 { 10536 {
10006 if (item.Type == 10 && item.Name == name) 10537 m_host.TaskInventory.LockItemsForRead(false);
10007 return item.ItemID; 10538 return item.ItemID;
10008 } 10539 }
10009 } 10540 }
10010 10541
10542 m_host.TaskInventory.LockItemsForRead(false);
10543
10011 return UUID.Zero; 10544 return UUID.Zero;
10012 } 10545 }
10013 10546
@@ -10048,6 +10581,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10048 { 10581 {
10049 m_host.AddScriptLPS(1); 10582 m_host.AddScriptLPS(1);
10050 10583
10584 //Clone is thread safe
10051 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10585 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10052 10586
10053 UUID assetID = UUID.Zero; 10587 UUID assetID = UUID.Zero;
@@ -10110,6 +10644,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10110 { 10644 {
10111 m_host.AddScriptLPS(1); 10645 m_host.AddScriptLPS(1);
10112 10646
10647 //Clone is thread safe
10113 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10648 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10114 10649
10115 UUID assetID = UUID.Zero; 10650 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 a529a94..a08b135 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
130 internal float m_ScriptDelayFactor = 1.0f; 130 internal float m_ScriptDelayFactor = 1.0f;
131 internal float m_ScriptDistanceFactor = 1.0f; 131 internal float m_ScriptDistanceFactor = 1.0f;
132 internal bool m_debuggerSafe = false;
132 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 133 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
133 134
134 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 135 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 m_host = host; 138 m_host = host;
138 m_localID = localID; 139 m_localID = localID;
139 m_itemID = itemID; 140 m_itemID = itemID;
141 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
140 142
141 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 143 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
142 m_OSFunctionsEnabled = true; 144 m_OSFunctionsEnabled = true;
@@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
195 197
196 internal void OSSLError(string msg) 198 internal void OSSLError(string msg)
197 { 199 {
198 throw new Exception("OSSL Runtime Error: " + msg); 200 if (m_debuggerSafe)
201 {
202 OSSLShoutError(msg);
203 }
204 else
205 {
206 throw new Exception("OSSL Runtime Error: " + msg);
207 }
199 } 208 }
200 209
201 private void InitLSL() 210 private void InitLSL()
@@ -767,18 +776,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
767 if (target != null) 776 if (target != null)
768 { 777 {
769 UUID animID=UUID.Zero; 778 UUID animID=UUID.Zero;
770 lock (m_host.TaskInventory) 779 m_host.TaskInventory.LockItemsForRead(true);
780 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
771 { 781 {
772 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 782 if (inv.Value.Name == animation)
773 { 783 {
774 if (inv.Value.Name == animation) 784 if (inv.Value.Type == (int)AssetType.Animation)
775 { 785 animID = inv.Value.AssetID;
776 if (inv.Value.Type == (int)AssetType.Animation) 786 continue;
777 animID = inv.Value.AssetID;
778 continue;
779 }
780 } 787 }
781 } 788 }
789 m_host.TaskInventory.LockItemsForRead(false);
782 if (animID == UUID.Zero) 790 if (animID == UUID.Zero)
783 target.Animator.AddAnimation(animation, m_host.UUID); 791 target.Animator.AddAnimation(animation, m_host.UUID);
784 else 792 else
@@ -800,18 +808,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
800 if (target != null) 808 if (target != null)
801 { 809 {
802 UUID animID=UUID.Zero; 810 UUID animID=UUID.Zero;
803 lock (m_host.TaskInventory) 811 m_host.TaskInventory.LockItemsForRead(true);
812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
804 { 813 {
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 814 if (inv.Value.Name == animation)
806 { 815 {
807 if (inv.Value.Name == animation) 816 if (inv.Value.Type == (int)AssetType.Animation)
808 { 817 animID = inv.Value.AssetID;
809 if (inv.Value.Type == (int)AssetType.Animation) 818 continue;
810 animID = inv.Value.AssetID;
811 continue;
812 }
813 } 819 }
814 } 820 }
821 m_host.TaskInventory.LockItemsForRead(false);
815 822
816 if (animID == UUID.Zero) 823 if (animID == UUID.Zero)
817 target.Animator.RemoveAnimation(animation); 824 target.Animator.RemoveAnimation(animation);
@@ -1662,6 +1669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 1669
1663 if (!UUID.TryParse(name, out assetID)) 1670 if (!UUID.TryParse(name, out assetID))
1664 { 1671 {
1672 m_host.TaskInventory.LockItemsForRead(true);
1665 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1673 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1666 { 1674 {
1667 if (item.Type == 7 && item.Name == name) 1675 if (item.Type == 7 && item.Name == name)
@@ -1669,6 +1677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1669 assetID = item.AssetID; 1677 assetID = item.AssetID;
1670 } 1678 }
1671 } 1679 }
1680 m_host.TaskInventory.LockItemsForRead(false);
1672 } 1681 }
1673 1682
1674 if (assetID == UUID.Zero) 1683 if (assetID == UUID.Zero)
@@ -1715,6 +1724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 1724
1716 if (!UUID.TryParse(name, out assetID)) 1725 if (!UUID.TryParse(name, out assetID))
1717 { 1726 {
1727 m_host.TaskInventory.LockItemsForRead(true);
1718 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1728 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1719 { 1729 {
1720 if (item.Type == 7 && item.Name == name) 1730 if (item.Type == 7 && item.Name == name)
@@ -1722,6 +1732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 assetID = item.AssetID; 1732 assetID = item.AssetID;
1723 } 1733 }
1724 } 1734 }
1735 m_host.TaskInventory.LockItemsForRead(false);
1725 } 1736 }
1726 1737
1727 if (assetID == UUID.Zero) 1738 if (assetID == UUID.Zero)
@@ -1772,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1783
1773 if (!UUID.TryParse(name, out assetID)) 1784 if (!UUID.TryParse(name, out assetID))
1774 { 1785 {
1786 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1788 {
1777 if (item.Type == 7 && item.Name == name) 1789 if (item.Type == 7 && item.Name == name)
@@ -1779,6 +1791,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1791 assetID = item.AssetID;
1780 } 1792 }
1781 } 1793 }
1794 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1795 }
1783 1796
1784 if (assetID == UUID.Zero) 1797 if (assetID == UUID.Zero)
@@ -2216,9 +2229,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 { 2229 {
2217 if (avatar.IsChildAgent == false) 2230 if (avatar.IsChildAgent == false)
2218 { 2231 {
2219 result.Add(avatar.UUID); 2232 result.Add(new LSL_Key(avatar.UUID.ToString()));
2220 result.Add(avatar.AbsolutePosition); 2233 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2221 result.Add(avatar.Name); 2234 result.Add(new LSL_String(avatar.Name));
2222 } 2235 }
2223 } 2236 }
2224 }); 2237 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 5c2abd5..a5b1124 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 }