aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2069
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs7
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
12 files changed, 1458 insertions, 770 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 72ee495..673ea46 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
@@ -81,7 +82,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 82 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 83 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 84 {
84 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 85// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 86 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 87 protected SceneObjectPart m_host;
87 protected uint m_localID; 88 protected uint m_localID;
@@ -99,6 +100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 100 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 101 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 102 protected bool m_scriptConsoleChannelEnabled = false;
103 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 104 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 105 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 106 new Dictionary<UUID, UserInfoCacheEntry>();
@@ -109,6 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
109 m_host = host; 111 m_host = host;
110 m_localID = localID; 112 m_localID = localID;
111 m_itemID = itemID; 113 m_itemID = itemID;
114 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 115
113 m_ScriptDelayFactor = 116 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 117 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 164 get { return m_ScriptEngine.World; }
162 } 165 }
163 166
167 [DebuggerNonUserCode]
164 public void state(string newState) 168 public void state(string newState)
165 { 169 {
166 m_ScriptEngine.SetState(m_itemID, newState); 170 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +174,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 174 /// Reset the named script. The script must be present
171 /// in the same prim. 175 /// in the same prim.
172 /// </summary> 176 /// </summary>
177 [DebuggerNonUserCode]
173 public void llResetScript() 178 public void llResetScript()
174 { 179 {
175 m_host.AddScriptLPS(1); 180 m_host.AddScriptLPS(1);
@@ -226,9 +231,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 231 }
227 } 232 }
228 233
234 public List<ScenePresence> GetLinkAvatars(int linkType)
235 {
236 List<ScenePresence> ret = new List<ScenePresence>();
237 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
238 return ret;
239
240 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
241
242 switch (linkType)
243 {
244 case ScriptBaseClass.LINK_SET:
245 return avs;
246
247 case ScriptBaseClass.LINK_ROOT:
248 return ret;
249
250 case ScriptBaseClass.LINK_ALL_OTHERS:
251 return avs;
252
253 case ScriptBaseClass.LINK_ALL_CHILDREN:
254 return avs;
255
256 case ScriptBaseClass.LINK_THIS:
257 return ret;
258
259 default:
260 if (linkType < 0)
261 return ret;
262
263 int partCount = m_host.ParentGroup.GetPartCount();
264
265 if (linkType <= partCount)
266 {
267 return ret;
268 }
269 else
270 {
271 linkType = linkType - partCount;
272 if (linkType > avs.Count)
273 {
274 return ret;
275 }
276 else
277 {
278 ret.Add(avs[linkType-1]);
279 return ret;
280 }
281 }
282 }
283 }
284
229 public List<SceneObjectPart> GetLinkParts(int linkType) 285 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 286 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 287 List<SceneObjectPart> ret = new List<SceneObjectPart>();
288 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
289 return ret;
232 ret.Add(m_host); 290 ret.Add(m_host);
233 291
234 switch (linkType) 292 switch (linkType)
@@ -288,40 +346,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
288 protected UUID InventorySelf() 346 protected UUID InventorySelf()
289 { 347 {
290 UUID invItemID = new UUID(); 348 UUID invItemID = new UUID();
291 349 bool unlock = false;
292 lock (m_host.TaskInventory) 350 if (!m_host.TaskInventory.IsReadLockedByMe())
293 { 351 {
294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 352 m_host.TaskInventory.LockItemsForRead(true);
353 unlock = true;
354 }
355 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
356 {
357 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
295 { 358 {
296 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 359 invItemID = inv.Key;
297 { 360 break;
298 invItemID = inv.Key;
299 break;
300 }
301 } 361 }
302 } 362 }
303 363 if (unlock)
364 {
365 m_host.TaskInventory.LockItemsForRead(false);
366 }
304 return invItemID; 367 return invItemID;
305 } 368 }
306 369
307 protected UUID InventoryKey(string name, int type) 370 protected UUID InventoryKey(string name, int type)
308 { 371 {
309 m_host.AddScriptLPS(1); 372 m_host.AddScriptLPS(1);
310 373 m_host.TaskInventory.LockItemsForRead(true);
311 lock (m_host.TaskInventory) 374
375 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
312 { 376 {
313 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 377 if (inv.Value.Name == name)
314 { 378 {
315 if (inv.Value.Name == name) 379 m_host.TaskInventory.LockItemsForRead(false);
380
381 if (inv.Value.Type != type)
316 { 382 {
317 if (inv.Value.Type != type) 383 return UUID.Zero;
318 return UUID.Zero;
319
320 return inv.Value.AssetID;
321 } 384 }
385
386 return inv.Value.AssetID;
322 } 387 }
323 } 388 }
324 389
390 m_host.TaskInventory.LockItemsForRead(false);
325 return UUID.Zero; 391 return UUID.Zero;
326 } 392 }
327 393
@@ -329,17 +395,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 { 395 {
330 m_host.AddScriptLPS(1); 396 m_host.AddScriptLPS(1);
331 397
332 lock (m_host.TaskInventory) 398
399 m_host.TaskInventory.LockItemsForRead(true);
400
401 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
333 { 402 {
334 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 403 if (inv.Value.Name == name)
335 { 404 {
336 if (inv.Value.Name == name) 405 m_host.TaskInventory.LockItemsForRead(false);
337 { 406 return inv.Value.AssetID;
338 return inv.Value.AssetID;
339 }
340 } 407 }
341 } 408 }
342 409
410 m_host.TaskInventory.LockItemsForRead(false);
411
412
343 return UUID.Zero; 413 return UUID.Zero;
344 } 414 }
345 415
@@ -481,26 +551,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
481 551
482 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 552 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
483 553
484 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 554 // Utility function for llRot2Euler
485 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 555
556 // normalize an angle between -PI and PI (-180 to +180 degrees)
557 protected double NormalizeAngle(double angle)
558 {
559 if (angle > -Math.PI && angle < Math.PI)
560 return angle;
561
562 int numPis = (int)(Math.PI / angle);
563 double remainder = angle - Math.PI * numPis;
564 if (numPis % 2 == 1)
565 return Math.PI - angle;
566 return remainder;
567 }
486 568
487 public LSL_Vector llRot2Euler(LSL_Rotation r) 569 public LSL_Vector llRot2Euler(LSL_Rotation q1)
488 { 570 {
489 m_host.AddScriptLPS(1); 571 m_host.AddScriptLPS(1);
490 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 572 LSL_Vector eul = new LSL_Vector();
491 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 573
492 double m = (t.x + t.y + t.z + t.s); 574 double sqw = q1.s*q1.s;
493 if (m == 0) return new LSL_Vector(); 575 double sqx = q1.x*q1.x;
494 double n = 2 * (r.y * r.s + r.x * r.z); 576 double sqy = q1.z*q1.z;
495 double p = m * m - n * n; 577 double sqz = q1.y*q1.y;
496 if (p > 0) 578 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
497 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 579 double test = q1.x*q1.z + q1.y*q1.s;
498 Math.Atan2(n, Math.Sqrt(p)), 580 if (test > 0.4999*unit) { // singularity at north pole
499 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 581 eul.z = 2 * Math.Atan2(q1.x,q1.s);
500 else if (n > 0) 582 eul.y = Math.PI/2;
501 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 583 eul.x = 0;
502 else 584 return eul;
503 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 585 }
586 if (test < -0.4999*unit) { // singularity at south pole
587 eul.z = -2 * Math.Atan2(q1.x,q1.s);
588 eul.y = -Math.PI/2;
589 eul.x = 0;
590 return eul;
591 }
592 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
593 eul.y = Math.Asin(2*test/unit);
594 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
595 return eul;
504 } 596 }
505 597
506 /* From wiki: 598 /* From wiki:
@@ -702,77 +794,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
702 { 794 {
703 //A and B should both be normalized 795 //A and B should both be normalized
704 m_host.AddScriptLPS(1); 796 m_host.AddScriptLPS(1);
705 LSL_Rotation rotBetween; 797 /* This method is more accurate than the SL one, and thus causes problems
706 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 798 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
707 // continue calculation. 799
708 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 800 double dotProduct = LSL_Vector.Dot(a, b);
801 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
802 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
803 double angle = Math.Acos(dotProduct / magProduct);
804 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
805 double s = Math.Sin(angle / 2);
806
807 double x = axis.x * s;
808 double y = axis.y * s;
809 double z = axis.z * s;
810 double w = Math.Cos(angle / 2);
811
812 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
813 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
814
815 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
816 */
817
818 // This method mimics the 180 errors found in SL
819 // See www.euclideanspace.com... angleBetween
820 LSL_Vector vec_a = a;
821 LSL_Vector vec_b = b;
822
823 // Eliminate zero length
824 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
825 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
826 if (vec_a_mag < 0.00001 ||
827 vec_b_mag < 0.00001)
709 { 828 {
710 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 829 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
711 } 830 }
712 else 831
832 // Normalize
833 vec_a = llVecNorm(vec_a);
834 vec_b = llVecNorm(vec_b);
835
836 // Calculate axis and rotation angle
837 LSL_Vector axis = vec_a % vec_b;
838 LSL_Float cos_theta = vec_a * vec_b;
839
840 // Check if parallel
841 if (cos_theta > 0.99999)
713 { 842 {
714 a = LSL_Vector.Norm(a); 843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
715 b = LSL_Vector.Norm(b); 844 }
716 double dotProduct = LSL_Vector.Dot(a, b); 845
717 // There are two degenerate cases possible. These are for vectors 180 or 846 // Check if anti-parallel
718 // 0 degrees apart. These have to be detected and handled individually. 847 else if (cos_theta < -0.99999)
719 // 848 {
720 // Check for vectors 180 degrees apart. 849 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
721 // A dot product of -1 would mean the angle between vectors is 180 degrees. 850 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
722 if (dotProduct < -0.9999999f) 851 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
723 { 852 }
724 // First assume X axis is orthogonal to the vectors. 853 else // other rotation
725 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 854 {
726 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 855 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
727 // Check for near zero vector. A very small non-zero number here will create 856 axis = llVecNorm(axis);
728 // a rotation in an undesired direction. 857 double x, y, z, s, t;
729 if (LSL_Vector.Mag(orthoVector) > 0.0001) 858 s = Math.Cos(theta);
730 { 859 t = Math.Sin(theta);
731 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 860 x = axis.x * t;
732 } 861 y = axis.y * t;
733 // If the magnitude of the vector was near zero, then assume the X axis is not 862 z = axis.z * t;
734 // orthogonal and use the Z axis instead. 863 return new LSL_Rotation(x,y,z,s);
735 else
736 {
737 // Set 180 z rotation.
738 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
739 }
740 }
741 // Check for parallel vectors.
742 // A dot product of 1 would mean the angle between vectors is 0 degrees.
743 else if (dotProduct > 0.9999999f)
744 {
745 // Set zero rotation.
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
747 }
748 else
749 {
750 // All special checks have been performed so get the axis of rotation.
751 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
752 // Quarternion s value is the length of the unit vector + dot product.
753 double qs = 1.0 + dotProduct;
754 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
755 // Normalize the rotation.
756 double mag = LSL_Rotation.Mag(rotBetween);
757 // We shouldn't have to worry about a divide by zero here. The qs value will be
758 // non-zero because we already know if we're here, then the dotProduct is not -1 so
759 // qs will not be zero. Also, we've already handled the input vectors being zero so the
760 // crossProduct vector should also not be zero.
761 rotBetween.x = rotBetween.x / mag;
762 rotBetween.y = rotBetween.y / mag;
763 rotBetween.z = rotBetween.z / mag;
764 rotBetween.s = rotBetween.s / mag;
765 // Check for undefined values and set zero rotation if any found. This code might not actually be required
766 // any longer since zero vectors are checked for at the top.
767 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
768 {
769 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
770 }
771 }
772 } 864 }
773 return rotBetween;
774 } 865 }
775 866
776 public void llWhisper(int channelID, string text) 867 public void llWhisper(int channelID, string text)
777 { 868 {
778 m_host.AddScriptLPS(1); 869 m_host.AddScriptLPS(1);
@@ -1096,10 +1187,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1096 return detectedParams.TouchUV; 1187 return detectedParams.TouchUV;
1097 } 1188 }
1098 1189
1190 [DebuggerNonUserCode]
1099 public virtual void llDie() 1191 public virtual void llDie()
1100 { 1192 {
1101 m_host.AddScriptLPS(1); 1193 m_host.AddScriptLPS(1);
1102 throw new SelfDeleteException(); 1194 if (!m_host.IsAttachment) throw new SelfDeleteException();
1103 } 1195 }
1104 1196
1105 public LSL_Float llGround(LSL_Vector offset) 1197 public LSL_Float llGround(LSL_Vector offset)
@@ -1172,6 +1264,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1172 1264
1173 public void llSetStatus(int status, int value) 1265 public void llSetStatus(int status, int value)
1174 { 1266 {
1267 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1268 return;
1175 m_host.AddScriptLPS(1); 1269 m_host.AddScriptLPS(1);
1176 1270
1177 int statusrotationaxis = 0; 1271 int statusrotationaxis = 0;
@@ -1402,6 +1496,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1402 { 1496 {
1403 m_host.AddScriptLPS(1); 1497 m_host.AddScriptLPS(1);
1404 1498
1499 SetColor(m_host, color, face);
1500 }
1501
1502 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1503 {
1504 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1505 return;
1506
1507 Primitive.TextureEntry tex = part.Shape.Textures;
1508 Color4 texcolor;
1509 if (face >= 0 && face < GetNumberOfSides(part))
1510 {
1511 texcolor = tex.CreateFace((uint)face).RGBA;
1512 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1513 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1514 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1515 tex.FaceTextures[face].RGBA = texcolor;
1516 part.UpdateTexture(tex);
1517 return;
1518 }
1519 else if (face == ScriptBaseClass.ALL_SIDES)
1520 {
1521 for (uint i = 0; i < GetNumberOfSides(part); i++)
1522 {
1523 if (tex.FaceTextures[i] != null)
1524 {
1525 texcolor = tex.FaceTextures[i].RGBA;
1526 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1527 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1528 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1529 tex.FaceTextures[i].RGBA = texcolor;
1530 }
1531 texcolor = tex.DefaultTexture.RGBA;
1532 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1533 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1534 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1535 tex.DefaultTexture.RGBA = texcolor;
1536 }
1537 part.UpdateTexture(tex);
1538 return;
1539 }
1540
1405 if (face == ScriptBaseClass.ALL_SIDES) 1541 if (face == ScriptBaseClass.ALL_SIDES)
1406 face = SceneObjectPart.ALL_SIDES; 1542 face = SceneObjectPart.ALL_SIDES;
1407 1543
@@ -1410,6 +1546,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 1546
1411 public void SetTexGen(SceneObjectPart part, int face,int style) 1547 public void SetTexGen(SceneObjectPart part, int face,int style)
1412 { 1548 {
1549 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1550 return;
1551
1413 Primitive.TextureEntry tex = part.Shape.Textures; 1552 Primitive.TextureEntry tex = part.Shape.Textures;
1414 MappingType textype; 1553 MappingType textype;
1415 textype = MappingType.Default; 1554 textype = MappingType.Default;
@@ -1440,6 +1579,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1440 1579
1441 public void SetGlow(SceneObjectPart part, int face, float glow) 1580 public void SetGlow(SceneObjectPart part, int face, float glow)
1442 { 1581 {
1582 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1583 return;
1584
1443 Primitive.TextureEntry tex = part.Shape.Textures; 1585 Primitive.TextureEntry tex = part.Shape.Textures;
1444 if (face >= 0 && face < GetNumberOfSides(part)) 1586 if (face >= 0 && face < GetNumberOfSides(part))
1445 { 1587 {
@@ -1465,6 +1607,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1465 1607
1466 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1608 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1467 { 1609 {
1610 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1611 return;
1468 1612
1469 Shininess sval = new Shininess(); 1613 Shininess sval = new Shininess();
1470 1614
@@ -1515,6 +1659,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1515 1659
1516 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1660 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1517 { 1661 {
1662 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1663 return;
1664
1518 Primitive.TextureEntry tex = part.Shape.Textures; 1665 Primitive.TextureEntry tex = part.Shape.Textures;
1519 if (face >= 0 && face < GetNumberOfSides(part)) 1666 if (face >= 0 && face < GetNumberOfSides(part))
1520 { 1667 {
@@ -1575,13 +1722,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1575 m_host.AddScriptLPS(1); 1722 m_host.AddScriptLPS(1);
1576 1723
1577 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1724 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1578 1725 if (parts.Count > 0)
1579 foreach (SceneObjectPart part in parts) 1726 {
1580 SetAlpha(part, alpha, face); 1727 try
1728 {
1729 parts[0].ParentGroup.areUpdatesSuspended = true;
1730 foreach (SceneObjectPart part in parts)
1731 SetAlpha(part, alpha, face);
1732 }
1733 finally
1734 {
1735 parts[0].ParentGroup.areUpdatesSuspended = false;
1736 }
1737 }
1581 } 1738 }
1582 1739
1583 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1740 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1584 { 1741 {
1742 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1743 return;
1744
1585 Primitive.TextureEntry tex = part.Shape.Textures; 1745 Primitive.TextureEntry tex = part.Shape.Textures;
1586 Color4 texcolor; 1746 Color4 texcolor;
1587 if (face >= 0 && face < GetNumberOfSides(part)) 1747 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1627,7 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1627 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1787 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1628 float wind, float tension, LSL_Vector Force) 1788 float wind, float tension, LSL_Vector Force)
1629 { 1789 {
1630 if (part == null) 1790 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1631 return; 1791 return;
1632 1792
1633 if (flexi) 1793 if (flexi)
@@ -1662,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 /// <param name="falloff"></param> 1822 /// <param name="falloff"></param>
1663 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1823 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1664 { 1824 {
1665 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1666 return; 1826 return;
1667 1827
1668 if (light) 1828 if (light)
@@ -1739,15 +1899,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1739 m_host.AddScriptLPS(1); 1899 m_host.AddScriptLPS(1);
1740 1900
1741 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1901 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1742 1902 if (parts.Count > 0)
1743 foreach (SceneObjectPart part in parts) 1903 {
1744 SetTexture(part, texture, face); 1904 try
1745 1905 {
1906 parts[0].ParentGroup.areUpdatesSuspended = true;
1907 foreach (SceneObjectPart part in parts)
1908 SetTexture(part, texture, face);
1909 }
1910 finally
1911 {
1912 parts[0].ParentGroup.areUpdatesSuspended = false;
1913 }
1914 }
1746 ScriptSleep(200); 1915 ScriptSleep(200);
1747 } 1916 }
1748 1917
1749 protected void SetTexture(SceneObjectPart part, string texture, int face) 1918 protected void SetTexture(SceneObjectPart part, string texture, int face)
1750 { 1919 {
1920 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1921 return;
1922
1751 UUID textureID = new UUID(); 1923 UUID textureID = new UUID();
1752 1924
1753 textureID = InventoryKey(texture, (int)AssetType.Texture); 1925 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1792,6 +1964,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1964
1793 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1965 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1794 { 1966 {
1967 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1968 return;
1969
1795 Primitive.TextureEntry tex = part.Shape.Textures; 1970 Primitive.TextureEntry tex = part.Shape.Textures;
1796 if (face >= 0 && face < GetNumberOfSides(part)) 1971 if (face >= 0 && face < GetNumberOfSides(part))
1797 { 1972 {
@@ -1828,6 +2003,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1828 2003
1829 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2004 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1830 { 2005 {
2006 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2007 return;
2008
1831 Primitive.TextureEntry tex = part.Shape.Textures; 2009 Primitive.TextureEntry tex = part.Shape.Textures;
1832 if (face >= 0 && face < GetNumberOfSides(part)) 2010 if (face >= 0 && face < GetNumberOfSides(part))
1833 { 2011 {
@@ -1864,6 +2042,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1864 2042
1865 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2043 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1866 { 2044 {
2045 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2046 return;
2047
1867 Primitive.TextureEntry tex = part.Shape.Textures; 2048 Primitive.TextureEntry tex = part.Shape.Textures;
1868 if (face >= 0 && face < GetNumberOfSides(part)) 2049 if (face >= 0 && face < GetNumberOfSides(part))
1869 { 2050 {
@@ -1934,6 +2115,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1934 2115
1935 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2116 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1936 { 2117 {
2118 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2119 return;
2120
1937 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2121 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1938 LSL_Vector currentPos = GetPartLocalPos(part); 2122 LSL_Vector currentPos = GetPartLocalPos(part);
1939 2123
@@ -1950,7 +2134,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1950 } 2134 }
1951 else 2135 else
1952 { 2136 {
1953 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2137 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1954 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2138 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1955 SceneObjectGroup parent = part.ParentGroup; 2139 SceneObjectGroup parent = part.ParentGroup;
1956 parent.HasGroupChanged = true; 2140 parent.HasGroupChanged = true;
@@ -2002,9 +2186,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2002 m_host.AddScriptLPS(1); 2186 m_host.AddScriptLPS(1);
2003 2187
2004 // try to let this work as in SL... 2188 // try to let this work as in SL...
2005 if (m_host.ParentID == 0) 2189 if (m_host.LinkNum < 2)
2006 { 2190 {
2007 // special case: If we are root, rotate complete SOG to new rotation 2191 // Special case: If we are root, rotate complete SOG to new
2192 // rotation.
2193 // We are root if the link number is 0 (single prim) or 1
2194 // (root prim). ParentID may be nonzero in attachments and
2195 // using it would cause attachments and HUDs to rotate
2196 // to the wrong positions.
2008 SetRot(m_host, Rot2Quaternion(rot)); 2197 SetRot(m_host, Rot2Quaternion(rot));
2009 } 2198 }
2010 else 2199 else
@@ -2033,6 +2222,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2033 2222
2034 protected void SetRot(SceneObjectPart part, Quaternion rot) 2223 protected void SetRot(SceneObjectPart part, Quaternion rot)
2035 { 2224 {
2225 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2226 return;
2227
2036 part.UpdateRotation(rot); 2228 part.UpdateRotation(rot);
2037 // Update rotation does not move the object in the physics scene if it's a linkset. 2229 // Update rotation does not move the object in the physics scene if it's a linkset.
2038 2230
@@ -2652,12 +2844,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2652 2844
2653 m_host.AddScriptLPS(1); 2845 m_host.AddScriptLPS(1);
2654 2846
2847 m_host.TaskInventory.LockItemsForRead(true);
2655 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2848 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2656 2849 m_host.TaskInventory.LockItemsForRead(false);
2657 lock (m_host.TaskInventory)
2658 {
2659 item = m_host.TaskInventory[invItemID];
2660 }
2661 2850
2662 if (item.PermsGranter == UUID.Zero) 2851 if (item.PermsGranter == UUID.Zero)
2663 return 0; 2852 return 0;
@@ -2732,6 +2921,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2732 if (dist > m_ScriptDistanceFactor * 10.0f) 2921 if (dist > m_ScriptDistanceFactor * 10.0f)
2733 return; 2922 return;
2734 2923
2924 //Clone is thread-safe
2735 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2925 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2736 2926
2737 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2927 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2794,6 +2984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2794 2984
2795 public void llLookAt(LSL_Vector target, double strength, double damping) 2985 public void llLookAt(LSL_Vector target, double strength, double damping)
2796 { 2986 {
2987 /*
2797 m_host.AddScriptLPS(1); 2988 m_host.AddScriptLPS(1);
2798 // Determine where we are looking from 2989 // Determine where we are looking from
2799 LSL_Vector from = llGetPos(); 2990 LSL_Vector from = llGetPos();
@@ -2813,10 +3004,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 // the angles of rotation in radians into rotation value 3004 // the angles of rotation in radians into rotation value
2814 3005
2815 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3006 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2816 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3007
2817 m_host.startLookAt(rotation, (float)damping, (float)strength); 3008 // This would only work if your physics system contains an APID controller:
3009 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3010 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3011
2818 // Orient the object to the angle calculated 3012 // Orient the object to the angle calculated
2819 //llSetRot(rot); 3013 llSetRot(rot);
3014 */
3015
3016 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3017 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3018 // http://bugs.meta7.com/view.php?id=28
3019 // - Tom
3020
3021 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3022 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3023 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3024 */
3025 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3026 {
3027 // Part is non-phys, convert this to a llSetRot()
3028 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3029 Vector3 dir = tgt - m_host.GroupPosition;
3030 dir.Normalize();
3031 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3032 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3033 float terot = (float)Math.Atan2(-dir.Z, txy);
3034 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3035 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3036 LSL_Types.Quaternion spin = llEuler2Rot(az);
3037 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3038 llSetRot(rot);
3039 }
3040 else
3041 {
3042 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3043 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3044 m_host.RotLookAt(q, (float)strength, (float)damping);
3045 }
3046
3047 }
3048
3049 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3050 {
3051 m_host.AddScriptLPS(1);
3052// NotImplemented("llRotLookAt");
3053 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3054
2820 } 3055 }
2821 3056
2822 public void llStopLookAt() 3057 public void llStopLookAt()
@@ -2865,13 +3100,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2865 { 3100 {
2866 TaskInventoryItem item; 3101 TaskInventoryItem item;
2867 3102
2868 lock (m_host.TaskInventory) 3103 m_host.TaskInventory.LockItemsForRead(true);
3104 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2869 { 3105 {
2870 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3106 m_host.TaskInventory.LockItemsForRead(false);
2871 return; 3107 return;
2872 else
2873 item = m_host.TaskInventory[InventorySelf()];
2874 } 3108 }
3109 else
3110 {
3111 item = m_host.TaskInventory[InventorySelf()];
3112 }
3113 m_host.TaskInventory.LockItemsForRead(false);
2875 3114
2876 if (item.PermsGranter != UUID.Zero) 3115 if (item.PermsGranter != UUID.Zero)
2877 { 3116 {
@@ -2893,13 +3132,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2893 { 3132 {
2894 TaskInventoryItem item; 3133 TaskInventoryItem item;
2895 3134
3135 m_host.TaskInventory.LockItemsForRead(true);
2896 lock (m_host.TaskInventory) 3136 lock (m_host.TaskInventory)
2897 { 3137 {
3138
2898 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3139 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3140 {
3141 m_host.TaskInventory.LockItemsForRead(false);
2899 return; 3142 return;
3143 }
2900 else 3144 else
3145 {
2901 item = m_host.TaskInventory[InventorySelf()]; 3146 item = m_host.TaskInventory[InventorySelf()];
3147 }
2902 } 3148 }
3149 m_host.TaskInventory.LockItemsForRead(false);
2903 3150
2904 m_host.AddScriptLPS(1); 3151 m_host.AddScriptLPS(1);
2905 3152
@@ -2931,19 +3178,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2931 { 3178 {
2932 m_host.AddScriptLPS(1); 3179 m_host.AddScriptLPS(1);
2933 3180
2934 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2935 return;
2936
2937 TaskInventoryItem item; 3181 TaskInventoryItem item;
2938 3182
2939 lock (m_host.TaskInventory) 3183 m_host.TaskInventory.LockItemsForRead(true);
3184
3185 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2940 { 3186 {
2941 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3187 m_host.TaskInventory.LockItemsForRead(false);
2942 return; 3188 return;
2943 else 3189 }
2944 item = m_host.TaskInventory[InventorySelf()]; 3190 else
3191 {
3192 item = m_host.TaskInventory[InventorySelf()];
2945 } 3193 }
2946 3194
3195 m_host.TaskInventory.LockItemsForRead(false);
3196
2947 if (item.PermsGranter != m_host.OwnerID) 3197 if (item.PermsGranter != m_host.OwnerID)
2948 return; 3198 return;
2949 3199
@@ -2953,10 +3203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 3203
2954 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3204 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2955 3205
2956 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3206 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2957 if (attachmentsModule != null)
2958 attachmentsModule.AttachObject(presence.ControllingClient,
2959 grp, (uint)attachment, false);
2960 } 3207 }
2961 } 3208 }
2962 3209
@@ -2969,13 +3216,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2969 3216
2970 TaskInventoryItem item; 3217 TaskInventoryItem item;
2971 3218
2972 lock (m_host.TaskInventory) 3219 m_host.TaskInventory.LockItemsForRead(true);
3220
3221 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2973 { 3222 {
2974 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3223 m_host.TaskInventory.LockItemsForRead(false);
2975 return; 3224 return;
2976 else 3225 }
2977 item = m_host.TaskInventory[InventorySelf()]; 3226 else
3227 {
3228 item = m_host.TaskInventory[InventorySelf()];
2978 } 3229 }
3230 m_host.TaskInventory.LockItemsForRead(false);
3231
2979 3232
2980 if (item.PermsGranter != m_host.OwnerID) 3233 if (item.PermsGranter != m_host.OwnerID)
2981 return; 3234 return;
@@ -3022,6 +3275,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3022 3275
3023 public void llInstantMessage(string user, string message) 3276 public void llInstantMessage(string user, string message)
3024 { 3277 {
3278 UUID result;
3279 if (!UUID.TryParse(user, out result))
3280 {
3281 ShoutError("An invalid key was passed to llInstantMessage");
3282 ScriptSleep(2000);
3283 return;
3284 }
3285
3286
3025 m_host.AddScriptLPS(1); 3287 m_host.AddScriptLPS(1);
3026 3288
3027 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3289 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3036,14 +3298,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3036 UUID friendTransactionID = UUID.Random(); 3298 UUID friendTransactionID = UUID.Random();
3037 3299
3038 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3300 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3039 3301
3040 GridInstantMessage msg = new GridInstantMessage(); 3302 GridInstantMessage msg = new GridInstantMessage();
3041 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3303 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3042 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3304 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3043 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3305 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3044// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3306// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3045// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3307// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3046 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3308// DateTime dt = DateTime.UtcNow;
3309//
3310// // Ticks from UtcNow, but make it look like local. Evil, huh?
3311// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3312//
3313// try
3314// {
3315// // Convert that to the PST timezone
3316// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3317// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3318// }
3319// catch
3320// {
3321// // No logging here, as it could be VERY spammy
3322// }
3323//
3324// // And make it look local again to fool the unix time util
3325// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3326
3327 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3328
3047 //if (client != null) 3329 //if (client != null)
3048 //{ 3330 //{
3049 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3331 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3057,12 +3339,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 msg.message = message.Substring(0, 1024); 3339 msg.message = message.Substring(0, 1024);
3058 else 3340 else
3059 msg.message = message; 3341 msg.message = message;
3060 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3342 msg.dialog = (byte)19; // MessageFromObject
3061 msg.fromGroup = false;// fromGroup; 3343 msg.fromGroup = false;// fromGroup;
3062 msg.offline = (byte)0; //offline; 3344 msg.offline = (byte)0; //offline;
3063 msg.ParentEstateID = 0; //ParentEstateID; 3345 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3064 msg.Position = new Vector3(m_host.AbsolutePosition); 3346 msg.Position = new Vector3(m_host.AbsolutePosition);
3065 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3347 msg.RegionID = World.RegionInfo.RegionID.Guid;
3066 msg.binaryBucket 3348 msg.binaryBucket
3067 = Util.StringToBytes256( 3349 = Util.StringToBytes256(
3068 "{0}/{1}/{2}/{3}", 3350 "{0}/{1}/{2}/{3}",
@@ -3090,7 +3372,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3090 } 3372 }
3091 3373
3092 emailModule.SendEmail(m_host.UUID, address, subject, message); 3374 emailModule.SendEmail(m_host.UUID, address, subject, message);
3093 ScriptSleep(20000); 3375 ScriptSleep(15000);
3094 } 3376 }
3095 3377
3096 public void llGetNextEmail(string address, string subject) 3378 public void llGetNextEmail(string address, string subject)
@@ -3192,13 +3474,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 m_host.AddScriptLPS(1); 3474 m_host.AddScriptLPS(1);
3193 } 3475 }
3194 3476
3195 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3196 {
3197 m_host.AddScriptLPS(1);
3198 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3199 m_host.RotLookAt(rot, (float)strength, (float)damping);
3200 }
3201
3202 public LSL_Integer llStringLength(string str) 3477 public LSL_Integer llStringLength(string str)
3203 { 3478 {
3204 m_host.AddScriptLPS(1); 3479 m_host.AddScriptLPS(1);
@@ -3222,14 +3497,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3222 3497
3223 TaskInventoryItem item; 3498 TaskInventoryItem item;
3224 3499
3225 lock (m_host.TaskInventory) 3500 m_host.TaskInventory.LockItemsForRead(true);
3501 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3226 { 3502 {
3227 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3503 m_host.TaskInventory.LockItemsForRead(false);
3228 return; 3504 return;
3229 else
3230 item = m_host.TaskInventory[InventorySelf()];
3231 } 3505 }
3232 3506 else
3507 {
3508 item = m_host.TaskInventory[InventorySelf()];
3509 }
3510 m_host.TaskInventory.LockItemsForRead(false);
3233 if (item.PermsGranter == UUID.Zero) 3511 if (item.PermsGranter == UUID.Zero)
3234 return; 3512 return;
3235 3513
@@ -3259,13 +3537,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3259 3537
3260 TaskInventoryItem item; 3538 TaskInventoryItem item;
3261 3539
3262 lock (m_host.TaskInventory) 3540 m_host.TaskInventory.LockItemsForRead(true);
3541 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3263 { 3542 {
3264 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3543 m_host.TaskInventory.LockItemsForRead(false);
3265 return; 3544 return;
3266 else
3267 item = m_host.TaskInventory[InventorySelf()];
3268 } 3545 }
3546 else
3547 {
3548 item = m_host.TaskInventory[InventorySelf()];
3549 }
3550 m_host.TaskInventory.LockItemsForRead(false);
3551
3269 3552
3270 if (item.PermsGranter == UUID.Zero) 3553 if (item.PermsGranter == UUID.Zero)
3271 return; 3554 return;
@@ -3336,10 +3619,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3336 3619
3337 TaskInventoryItem item; 3620 TaskInventoryItem item;
3338 3621
3339 lock (m_host.TaskInventory) 3622
3623 m_host.TaskInventory.LockItemsForRead(true);
3624 if (!m_host.TaskInventory.ContainsKey(invItemID))
3625 {
3626 m_host.TaskInventory.LockItemsForRead(false);
3627 return;
3628 }
3629 else
3340 { 3630 {
3341 item = m_host.TaskInventory[invItemID]; 3631 item = m_host.TaskInventory[invItemID];
3342 } 3632 }
3633 m_host.TaskInventory.LockItemsForRead(false);
3343 3634
3344 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3635 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3345 { 3636 {
@@ -3371,11 +3662,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3371 3662
3372 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3663 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3373 { 3664 {
3374 lock (m_host.TaskInventory) 3665 m_host.TaskInventory.LockItemsForWrite(true);
3375 { 3666 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3376 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3667 m_host.TaskInventory[invItemID].PermsMask = perm;
3377 m_host.TaskInventory[invItemID].PermsMask = perm; 3668 m_host.TaskInventory.LockItemsForWrite(false);
3378 }
3379 3669
3380 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3670 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3381 "run_time_permissions", new Object[] { 3671 "run_time_permissions", new Object[] {
@@ -3395,11 +3685,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3395 3685
3396 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3686 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3397 { 3687 {
3398 lock (m_host.TaskInventory) 3688 m_host.TaskInventory.LockItemsForWrite(true);
3399 { 3689 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3400 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3690 m_host.TaskInventory[invItemID].PermsMask = perm;
3401 m_host.TaskInventory[invItemID].PermsMask = perm; 3691 m_host.TaskInventory.LockItemsForWrite(false);
3402 }
3403 3692
3404 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3693 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3405 "run_time_permissions", new Object[] { 3694 "run_time_permissions", new Object[] {
@@ -3420,11 +3709,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 3709
3421 if (!m_waitingForScriptAnswer) 3710 if (!m_waitingForScriptAnswer)
3422 { 3711 {
3423 lock (m_host.TaskInventory) 3712 m_host.TaskInventory.LockItemsForWrite(true);
3424 { 3713 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3425 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3714 m_host.TaskInventory[invItemID].PermsMask = 0;
3426 m_host.TaskInventory[invItemID].PermsMask = 0; 3715 m_host.TaskInventory.LockItemsForWrite(false);
3427 }
3428 3716
3429 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3717 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3430 m_waitingForScriptAnswer=true; 3718 m_waitingForScriptAnswer=true;
@@ -3459,10 +3747,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3459 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3747 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3460 llReleaseControls(); 3748 llReleaseControls();
3461 3749
3462 lock (m_host.TaskInventory) 3750
3463 { 3751 m_host.TaskInventory.LockItemsForWrite(true);
3464 m_host.TaskInventory[invItemID].PermsMask = answer; 3752 m_host.TaskInventory[invItemID].PermsMask = answer;
3465 } 3753 m_host.TaskInventory.LockItemsForWrite(false);
3754
3466 3755
3467 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3756 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3468 "run_time_permissions", new Object[] { 3757 "run_time_permissions", new Object[] {
@@ -3474,16 +3763,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3474 { 3763 {
3475 m_host.AddScriptLPS(1); 3764 m_host.AddScriptLPS(1);
3476 3765
3477 lock (m_host.TaskInventory) 3766 m_host.TaskInventory.LockItemsForRead(true);
3767
3768 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3478 { 3769 {
3479 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3770 if (item.Type == 10 && item.ItemID == m_itemID)
3480 { 3771 {
3481 if (item.Type == 10 && item.ItemID == m_itemID) 3772 m_host.TaskInventory.LockItemsForRead(false);
3482 { 3773 return item.PermsGranter.ToString();
3483 return item.PermsGranter.ToString();
3484 }
3485 } 3774 }
3486 } 3775 }
3776 m_host.TaskInventory.LockItemsForRead(false);
3487 3777
3488 return UUID.Zero.ToString(); 3778 return UUID.Zero.ToString();
3489 } 3779 }
@@ -3492,19 +3782,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3492 { 3782 {
3493 m_host.AddScriptLPS(1); 3783 m_host.AddScriptLPS(1);
3494 3784
3495 lock (m_host.TaskInventory) 3785 m_host.TaskInventory.LockItemsForRead(true);
3786
3787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3496 { 3788 {
3497 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3789 if (item.Type == 10 && item.ItemID == m_itemID)
3498 { 3790 {
3499 if (item.Type == 10 && item.ItemID == m_itemID) 3791 int perms = item.PermsMask;
3500 { 3792 if (m_automaticLinkPermission)
3501 int perms = item.PermsMask; 3793 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3502 if (m_automaticLinkPermission) 3794 m_host.TaskInventory.LockItemsForRead(false);
3503 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3795 return perms;
3504 return perms;
3505 }
3506 } 3796 }
3507 } 3797 }
3798 m_host.TaskInventory.LockItemsForRead(false);
3508 3799
3509 return 0; 3800 return 0;
3510 } 3801 }
@@ -3526,9 +3817,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3526 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3817 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3527 { 3818 {
3528 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3819 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3529 3820 if (parts.Count > 0)
3530 foreach (SceneObjectPart part in parts) 3821 {
3531 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3822 try
3823 {
3824 parts[0].ParentGroup.areUpdatesSuspended = true;
3825 foreach (SceneObjectPart part in parts)
3826 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3827 }
3828 finally
3829 {
3830 parts[0].ParentGroup.areUpdatesSuspended = false;
3831 }
3832 }
3532 } 3833 }
3533 3834
3534 public void llCreateLink(string target, int parent) 3835 public void llCreateLink(string target, int parent)
@@ -3541,11 +3842,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3541 return; 3842 return;
3542 3843
3543 TaskInventoryItem item; 3844 TaskInventoryItem item;
3544 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForRead(true);
3545 { 3846 item = m_host.TaskInventory[invItemID];
3546 item = m_host.TaskInventory[invItemID]; 3847 m_host.TaskInventory.LockItemsForRead(false);
3547 } 3848
3548
3549 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3849 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3550 && !m_automaticLinkPermission) 3850 && !m_automaticLinkPermission)
3551 { 3851 {
@@ -3566,7 +3866,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3566 3866
3567 if (targetPart != null) 3867 if (targetPart != null)
3568 { 3868 {
3569 if (parent != 0) { 3869 if (parent != 0)
3870 {
3570 parentPrim = m_host.ParentGroup; 3871 parentPrim = m_host.ParentGroup;
3571 childPrim = targetPart.ParentGroup; 3872 childPrim = targetPart.ParentGroup;
3572 } 3873 }
@@ -3598,16 +3899,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3598 m_host.AddScriptLPS(1); 3899 m_host.AddScriptLPS(1);
3599 UUID invItemID = InventorySelf(); 3900 UUID invItemID = InventorySelf();
3600 3901
3601 lock (m_host.TaskInventory) 3902 m_host.TaskInventory.LockItemsForRead(true);
3602 {
3603 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3903 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3604 && !m_automaticLinkPermission) 3904 && !m_automaticLinkPermission)
3605 { 3905 {
3606 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3906 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3907 m_host.TaskInventory.LockItemsForRead(false);
3607 return; 3908 return;
3608 } 3909 }
3609 } 3910 m_host.TaskInventory.LockItemsForRead(false);
3610 3911
3611 if (linknum < ScriptBaseClass.LINK_THIS) 3912 if (linknum < ScriptBaseClass.LINK_THIS)
3612 return; 3913 return;
3613 3914
@@ -3646,10 +3947,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3646 // Restructuring Multiple Prims. 3947 // Restructuring Multiple Prims.
3647 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3948 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3648 parts.Remove(parentPrim.RootPart); 3949 parts.Remove(parentPrim.RootPart);
3649 foreach (SceneObjectPart part in parts) 3950 if (parts.Count > 0)
3650 { 3951 {
3651 parentPrim.DelinkFromGroup(part.LocalId, true); 3952 try
3953 {
3954 parts[0].ParentGroup.areUpdatesSuspended = true;
3955 foreach (SceneObjectPart part in parts)
3956 {
3957 parentPrim.DelinkFromGroup(part.LocalId, true);
3958 }
3959 }
3960 finally
3961 {
3962 parts[0].ParentGroup.areUpdatesSuspended = false;
3963 }
3652 } 3964 }
3965
3653 parentPrim.HasGroupChanged = true; 3966 parentPrim.HasGroupChanged = true;
3654 parentPrim.ScheduleGroupForFullUpdate(); 3967 parentPrim.ScheduleGroupForFullUpdate();
3655 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3968 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3658,11 +3971,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3658 { 3971 {
3659 SceneObjectPart newRoot = parts[0]; 3972 SceneObjectPart newRoot = parts[0];
3660 parts.Remove(newRoot); 3973 parts.Remove(newRoot);
3661 foreach (SceneObjectPart part in parts) 3974
3975 try
3662 { 3976 {
3663 part.UpdateFlag = 0; 3977 parts[0].ParentGroup.areUpdatesSuspended = true;
3664 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3978 foreach (SceneObjectPart part in parts)
3979 {
3980 part.UpdateFlag = 0;
3981 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3982 }
3665 } 3983 }
3984 finally
3985 {
3986 parts[0].ParentGroup.areUpdatesSuspended = false;
3987 }
3988
3989
3666 newRoot.ParentGroup.HasGroupChanged = true; 3990 newRoot.ParentGroup.HasGroupChanged = true;
3667 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3991 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3668 } 3992 }
@@ -3708,6 +4032,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3708 } 4032 }
3709 else 4033 else
3710 { 4034 {
4035 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4036 {
4037 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4038
4039 if (linknum < 0)
4040 return UUID.Zero.ToString();
4041
4042 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4043 if (avatars.Count > linknum)
4044 {
4045 return avatars[linknum].UUID.ToString();
4046 }
4047 }
3711 return UUID.Zero.ToString(); 4048 return UUID.Zero.ToString();
3712 } 4049 }
3713 } 4050 }
@@ -3784,17 +4121,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3784 m_host.AddScriptLPS(1); 4121 m_host.AddScriptLPS(1);
3785 int count = 0; 4122 int count = 0;
3786 4123
3787 lock (m_host.TaskInventory) 4124 m_host.TaskInventory.LockItemsForRead(true);
4125 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3788 { 4126 {
3789 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4127 if (inv.Value.Type == type || type == -1)
3790 { 4128 {
3791 if (inv.Value.Type == type || type == -1) 4129 count = count + 1;
3792 {
3793 count = count + 1;
3794 }
3795 } 4130 }
3796 } 4131 }
3797 4132
4133 m_host.TaskInventory.LockItemsForRead(false);
3798 return count; 4134 return count;
3799 } 4135 }
3800 4136
@@ -3803,16 +4139,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3803 m_host.AddScriptLPS(1); 4139 m_host.AddScriptLPS(1);
3804 ArrayList keys = new ArrayList(); 4140 ArrayList keys = new ArrayList();
3805 4141
3806 lock (m_host.TaskInventory) 4142 m_host.TaskInventory.LockItemsForRead(true);
4143 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3807 { 4144 {
3808 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4145 if (inv.Value.Type == type || type == -1)
3809 { 4146 {
3810 if (inv.Value.Type == type || type == -1) 4147 keys.Add(inv.Value.Name);
3811 {
3812 keys.Add(inv.Value.Name);
3813 }
3814 } 4148 }
3815 } 4149 }
4150 m_host.TaskInventory.LockItemsForRead(false);
3816 4151
3817 if (keys.Count == 0) 4152 if (keys.Count == 0)
3818 { 4153 {
@@ -3849,20 +4184,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3849 } 4184 }
3850 4185
3851 // move the first object found with this inventory name 4186 // move the first object found with this inventory name
3852 lock (m_host.TaskInventory) 4187 m_host.TaskInventory.LockItemsForRead(true);
4188 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3853 { 4189 {
3854 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4190 if (inv.Value.Name == inventory)
3855 { 4191 {
3856 if (inv.Value.Name == inventory) 4192 found = true;
3857 { 4193 objId = inv.Key;
3858 found = true; 4194 assetType = inv.Value.Type;
3859 objId = inv.Key; 4195 objName = inv.Value.Name;
3860 assetType = inv.Value.Type; 4196 break;
3861 objName = inv.Value.Name;
3862 break;
3863 }
3864 } 4197 }
3865 } 4198 }
4199 m_host.TaskInventory.LockItemsForRead(false);
3866 4200
3867 if (!found) 4201 if (!found)
3868 { 4202 {
@@ -3870,9 +4204,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3870 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4204 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3871 } 4205 }
3872 4206
3873 // check if destination is an avatar 4207 // check if destination is an object
3874 if (World.GetScenePresence(destId) != null) 4208 if (World.GetSceneObjectPart(destId) != null)
3875 { 4209 {
4210 // destination is an object
4211 World.MoveTaskInventoryItem(destId, m_host, objId);
4212 }
4213 else
4214 {
4215 ScenePresence presence = World.GetScenePresence(destId);
4216
4217 if (presence == null)
4218 {
4219 UserAccount account =
4220 World.UserAccountService.GetUserAccount(
4221 World.RegionInfo.ScopeID,
4222 destId);
4223
4224 if (account == null)
4225 {
4226 llSay(0, "Can't find destination "+destId.ToString());
4227 return;
4228 }
4229 }
4230
3876 // destination is an avatar 4231 // destination is an avatar
3877 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4232 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3878 4233
@@ -3896,31 +4251,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3896 4251
3897 if (m_TransferModule != null) 4252 if (m_TransferModule != null)
3898 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4253 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4254
4255 //This delay should only occur when giving inventory to avatars.
4256 ScriptSleep(3000);
3899 } 4257 }
3900 else
3901 {
3902 // destination is an object
3903 World.MoveTaskInventoryItem(destId, m_host, objId);
3904 }
3905 ScriptSleep(3000);
3906 } 4258 }
3907 4259
4260 [DebuggerNonUserCode]
3908 public void llRemoveInventory(string name) 4261 public void llRemoveInventory(string name)
3909 { 4262 {
3910 m_host.AddScriptLPS(1); 4263 m_host.AddScriptLPS(1);
3911 4264
3912 lock (m_host.TaskInventory) 4265 List<TaskInventoryItem> inv;
4266 try
3913 { 4267 {
3914 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4268 m_host.TaskInventory.LockItemsForRead(true);
4269 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4270 }
4271 finally
4272 {
4273 m_host.TaskInventory.LockItemsForRead(false);
4274 }
4275 foreach (TaskInventoryItem item in inv)
4276 {
4277 if (item.Name == name)
3915 { 4278 {
3916 if (item.Name == name) 4279 if (item.ItemID == m_itemID)
3917 { 4280 throw new ScriptDeleteException();
3918 if (item.ItemID == m_itemID) 4281 else
3919 throw new ScriptDeleteException(); 4282 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3920 else 4283 return;
3921 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3922 return;
3923 }
3924 } 4284 }
3925 } 4285 }
3926 } 4286 }
@@ -3955,112 +4315,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3955 { 4315 {
3956 m_host.AddScriptLPS(1); 4316 m_host.AddScriptLPS(1);
3957 4317
3958 UUID uuid = (UUID)id; 4318 UUID uuid;
3959 PresenceInfo pinfo = null; 4319 if (UUID.TryParse(id, out uuid))
3960 UserAccount account;
3961
3962 UserInfoCacheEntry ce;
3963 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3964 { 4320 {
3965 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4321 PresenceInfo pinfo = null;
3966 if (account == null) 4322 UserAccount account;
4323
4324 UserInfoCacheEntry ce;
4325 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3967 { 4326 {
3968 m_userInfoCache[uuid] = null; // Cache negative 4327 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3969 return UUID.Zero.ToString(); 4328 if (account == null)
3970 } 4329 {
4330 m_userInfoCache[uuid] = null; // Cache negative
4331 return UUID.Zero.ToString();
4332 }
3971 4333
3972 4334
3973 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4335 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3974 if (pinfos != null && pinfos.Length > 0) 4336 if (pinfos != null && pinfos.Length > 0)
3975 {
3976 foreach (PresenceInfo p in pinfos)
3977 { 4337 {
3978 if (p.RegionID != UUID.Zero) 4338 foreach (PresenceInfo p in pinfos)
3979 { 4339 {
3980 pinfo = p; 4340 if (p.RegionID != UUID.Zero)
4341 {
4342 pinfo = p;
4343 }
3981 } 4344 }
3982 } 4345 }
3983 }
3984 4346
3985 ce = new UserInfoCacheEntry(); 4347 ce = new UserInfoCacheEntry();
3986 ce.time = Util.EnvironmentTickCount(); 4348 ce.time = Util.EnvironmentTickCount();
3987 ce.account = account; 4349 ce.account = account;
3988 ce.pinfo = pinfo; 4350 ce.pinfo = pinfo;
3989 } 4351 m_userInfoCache[uuid] = ce;
3990 else 4352 }
3991 { 4353 else
3992 if (ce == null) 4354 {
3993 return UUID.Zero.ToString(); 4355 if (ce == null)
4356 return UUID.Zero.ToString();
3994 4357
3995 account = ce.account; 4358 account = ce.account;
3996 pinfo = ce.pinfo; 4359 pinfo = ce.pinfo;
3997 } 4360 }
3998 4361
3999 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4362 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4000 {
4001 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4002 if (pinfos != null && pinfos.Length > 0)
4003 { 4363 {
4004 foreach (PresenceInfo p in pinfos) 4364 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4365 if (pinfos != null && pinfos.Length > 0)
4005 { 4366 {
4006 if (p.RegionID != UUID.Zero) 4367 foreach (PresenceInfo p in pinfos)
4007 { 4368 {
4008 pinfo = p; 4369 if (p.RegionID != UUID.Zero)
4370 {
4371 pinfo = p;
4372 }
4009 } 4373 }
4010 } 4374 }
4011 } 4375 else
4012 else 4376 pinfo = null;
4013 pinfo = null;
4014 4377
4015 ce.time = Util.EnvironmentTickCount(); 4378 ce.time = Util.EnvironmentTickCount();
4016 ce.pinfo = pinfo; 4379 ce.pinfo = pinfo;
4017 } 4380 }
4018 4381
4019 string reply = String.Empty; 4382 string reply = String.Empty;
4020 4383
4021 switch (data) 4384 switch (data)
4022 { 4385 {
4023 case 1: // DATA_ONLINE (0|1) 4386 case 1: // DATA_ONLINE (0|1)
4024 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4387 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4025 reply = "1"; 4388 reply = "1";
4026 else 4389 else
4027 reply = "0"; 4390 reply = "0";
4028 break; 4391 break;
4029 case 2: // DATA_NAME (First Last) 4392 case 2: // DATA_NAME (First Last)
4030 reply = account.FirstName + " " + account.LastName; 4393 reply = account.FirstName + " " + account.LastName;
4031 break; 4394 break;
4032 case 3: // DATA_BORN (YYYY-MM-DD) 4395 case 3: // DATA_BORN (YYYY-MM-DD)
4033 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4396 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4034 born = born.AddSeconds(account.Created); 4397 born = born.AddSeconds(account.Created);
4035 reply = born.ToString("yyyy-MM-dd"); 4398 reply = born.ToString("yyyy-MM-dd");
4036 break; 4399 break;
4037 case 4: // DATA_RATING (0,0,0,0,0,0) 4400 case 4: // DATA_RATING (0,0,0,0,0,0)
4038 reply = "0,0,0,0,0,0"; 4401 reply = "0,0,0,0,0,0";
4039 break; 4402 break;
4040 case 8: // DATA_PAYINFO (0|1|2|3) 4403 case 8: // DATA_PAYINFO (0|1|2|3)
4041 reply = "0"; 4404 reply = "0";
4042 break; 4405 break;
4043 default: 4406 default:
4044 return UUID.Zero.ToString(); // Raise no event 4407 return UUID.Zero.ToString(); // Raise no event
4045 } 4408 }
4046 4409
4047 UUID rq = UUID.Random(); 4410 UUID rq = UUID.Random();
4048 4411
4049 UUID tid = AsyncCommands. 4412 UUID tid = AsyncCommands.
4050 DataserverPlugin.RegisterRequest(m_localID, 4413 DataserverPlugin.RegisterRequest(m_localID,
4051 m_itemID, rq.ToString()); 4414 m_itemID, rq.ToString());
4052 4415
4053 AsyncCommands. 4416 AsyncCommands.
4054 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4417 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4055 4418
4056 ScriptSleep(100); 4419 ScriptSleep(100);
4057 return tid.ToString(); 4420 return tid.ToString();
4421 }
4422 else
4423 {
4424 ShoutError("Invalid UUID passed to llRequestAgentData.");
4425 }
4426 return "";
4058 } 4427 }
4059 4428
4060 public LSL_String llRequestInventoryData(string name) 4429 public LSL_String llRequestInventoryData(string name)
4061 { 4430 {
4062 m_host.AddScriptLPS(1); 4431 m_host.AddScriptLPS(1);
4063 4432
4433 //Clone is thread safe
4064 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4434 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4065 4435
4066 foreach (TaskInventoryItem item in itemDictionary.Values) 4436 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4114,6 +4484,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4114 ScenePresence presence = World.GetScenePresence(agentId); 4484 ScenePresence presence = World.GetScenePresence(agentId);
4115 if (presence != null) 4485 if (presence != null)
4116 { 4486 {
4487 // agent must not be a god
4488 if (presence.GodLevel >= 200) return;
4489
4117 // agent must be over the owners land 4490 // agent must be over the owners land
4118 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4491 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4119 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4492 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4136,7 +4509,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4136 UUID av = new UUID(); 4509 UUID av = new UUID();
4137 if (!UUID.TryParse(agent,out av)) 4510 if (!UUID.TryParse(agent,out av))
4138 { 4511 {
4139 LSLError("First parameter to llDialog needs to be a key"); 4512 //LSLError("First parameter to llDialog needs to be a key");
4140 return; 4513 return;
4141 } 4514 }
4142 4515
@@ -4173,17 +4546,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4173 UUID soundId = UUID.Zero; 4546 UUID soundId = UUID.Zero;
4174 if (!UUID.TryParse(impact_sound, out soundId)) 4547 if (!UUID.TryParse(impact_sound, out soundId))
4175 { 4548 {
4176 lock (m_host.TaskInventory) 4549 m_host.TaskInventory.LockItemsForRead(true);
4550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4177 { 4551 {
4178 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4552 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4179 { 4553 {
4180 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4554 soundId = item.AssetID;
4181 { 4555 break;
4182 soundId = item.AssetID;
4183 break;
4184 }
4185 } 4556 }
4186 } 4557 }
4558 m_host.TaskInventory.LockItemsForRead(false);
4187 } 4559 }
4188 m_host.CollisionSound = soundId; 4560 m_host.CollisionSound = soundId;
4189 m_host.CollisionSoundVolume = (float)impact_volume; 4561 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4229,6 +4601,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4229 UUID partItemID; 4601 UUID partItemID;
4230 foreach (SceneObjectPart part in parts) 4602 foreach (SceneObjectPart part in parts)
4231 { 4603 {
4604 //Clone is thread safe
4232 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4605 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4233 4606
4234 foreach (TaskInventoryItem item in itemsDictionary.Values) 4607 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4443,17 +4816,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4443 4816
4444 m_host.AddScriptLPS(1); 4817 m_host.AddScriptLPS(1);
4445 4818
4446 lock (m_host.TaskInventory) 4819 m_host.TaskInventory.LockItemsForRead(true);
4820 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4447 { 4821 {
4448 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4822 if (item.Type == 10 && item.ItemID == m_itemID)
4449 { 4823 {
4450 if (item.Type == 10 && item.ItemID == m_itemID) 4824 result = item.Name!=null?item.Name:String.Empty;
4451 { 4825 break;
4452 result = item.Name != null ? item.Name : String.Empty;
4453 break;
4454 }
4455 } 4826 }
4456 } 4827 }
4828 m_host.TaskInventory.LockItemsForRead(false);
4457 4829
4458 return result; 4830 return result;
4459 } 4831 }
@@ -4606,23 +4978,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4606 { 4978 {
4607 m_host.AddScriptLPS(1); 4979 m_host.AddScriptLPS(1);
4608 4980
4609 lock (m_host.TaskInventory) 4981 m_host.TaskInventory.LockItemsForRead(true);
4982 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4610 { 4983 {
4611 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4984 if (inv.Value.Name == name)
4612 { 4985 {
4613 if (inv.Value.Name == name) 4986 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4614 { 4987 {
4615 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4988 m_host.TaskInventory.LockItemsForRead(false);
4616 { 4989 return inv.Value.AssetID.ToString();
4617 return inv.Value.AssetID.ToString(); 4990 }
4618 } 4991 else
4619 else 4992 {
4620 { 4993 m_host.TaskInventory.LockItemsForRead(false);
4621 return UUID.Zero.ToString(); 4994 return UUID.Zero.ToString();
4622 }
4623 } 4995 }
4624 } 4996 }
4625 } 4997 }
4998 m_host.TaskInventory.LockItemsForRead(false);
4626 4999
4627 return UUID.Zero.ToString(); 5000 return UUID.Zero.ToString();
4628 } 5001 }
@@ -4775,14 +5148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4775 { 5148 {
4776 m_host.AddScriptLPS(1); 5149 m_host.AddScriptLPS(1);
4777 5150
4778 if (src == null) 5151 return src.Length;
4779 {
4780 return 0;
4781 }
4782 else
4783 {
4784 return src.Length;
4785 }
4786 } 5152 }
4787 5153
4788 public LSL_Integer llList2Integer(LSL_List src, int index) 5154 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4828,7 +5194,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4828 else if (src.Data[index] is LSL_Float) 5194 else if (src.Data[index] is LSL_Float)
4829 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5195 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4830 else if (src.Data[index] is LSL_String) 5196 else if (src.Data[index] is LSL_String)
4831 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5197 {
5198 string str = ((LSL_String) src.Data[index]).m_string;
5199 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5200 if (m != Match.Empty)
5201 {
5202 str = m.Value;
5203 double d = 0.0;
5204 if (!Double.TryParse(str, out d))
5205 return 0.0;
5206
5207 return d;
5208 }
5209 return 0.0;
5210 }
4832 return Convert.ToDouble(src.Data[index]); 5211 return Convert.ToDouble(src.Data[index]);
4833 } 5212 }
4834 catch (FormatException) 5213 catch (FormatException)
@@ -5101,7 +5480,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5101 } 5480 }
5102 } 5481 }
5103 } 5482 }
5104 else { 5483 else
5484 {
5105 object[] array = new object[src.Length]; 5485 object[] array = new object[src.Length];
5106 Array.Copy(src.Data, 0, array, 0, src.Length); 5486 Array.Copy(src.Data, 0, array, 0, src.Length);
5107 result = new LSL_List(array); 5487 result = new LSL_List(array);
@@ -5513,7 +5893,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5513 public void llSetSoundQueueing(int queue) 5893 public void llSetSoundQueueing(int queue)
5514 { 5894 {
5515 m_host.AddScriptLPS(1); 5895 m_host.AddScriptLPS(1);
5516 NotImplemented("llSetSoundQueueing");
5517 } 5896 }
5518 5897
5519 public void llSetSoundRadius(double radius) 5898 public void llSetSoundRadius(double radius)
@@ -5558,10 +5937,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5558 m_host.AddScriptLPS(1); 5937 m_host.AddScriptLPS(1);
5559 5938
5560 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5939 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5561 5940 if (parts.Count > 0)
5562 foreach (var part in parts)
5563 { 5941 {
5564 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5942 try
5943 {
5944 parts[0].ParentGroup.areUpdatesSuspended = true;
5945 foreach (var part in parts)
5946 {
5947 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5948 }
5949 }
5950 finally
5951 {
5952 parts[0].ParentGroup.areUpdatesSuspended = false;
5953 }
5565 } 5954 }
5566 } 5955 }
5567 5956
@@ -5615,6 +6004,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5615 ScriptSleep(5000); 6004 ScriptSleep(5000);
5616 } 6005 }
5617 6006
6007 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6008 {
6009 return ParseString2List(str, separators, in_spacers, false);
6010 }
6011
5618 public LSL_Integer llOverMyLand(string id) 6012 public LSL_Integer llOverMyLand(string id)
5619 { 6013 {
5620 m_host.AddScriptLPS(1); 6014 m_host.AddScriptLPS(1);
@@ -5815,7 +6209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5815 return m_host.ParentGroup.RootPart.AttachmentPoint; 6209 return m_host.ParentGroup.RootPart.AttachmentPoint;
5816 } 6210 }
5817 6211
5818 public LSL_Integer llGetFreeMemory() 6212 public virtual LSL_Integer llGetFreeMemory()
5819 { 6213 {
5820 m_host.AddScriptLPS(1); 6214 m_host.AddScriptLPS(1);
5821 // Make scripts designed for LSO happy 6215 // Make scripts designed for LSO happy
@@ -5932,7 +6326,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5932 SetParticleSystem(m_host, rules); 6326 SetParticleSystem(m_host, rules);
5933 } 6327 }
5934 6328
5935 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6329 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6330 {
5936 6331
5937 6332
5938 if (rules.Length == 0) 6333 if (rules.Length == 0)
@@ -6126,14 +6521,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6126 6521
6127 protected UUID GetTaskInventoryItem(string name) 6522 protected UUID GetTaskInventoryItem(string name)
6128 { 6523 {
6129 lock (m_host.TaskInventory) 6524 m_host.TaskInventory.LockItemsForRead(true);
6525 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6130 { 6526 {
6131 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6527 if (inv.Value.Name == name)
6132 { 6528 {
6133 if (inv.Value.Name == name) 6529 m_host.TaskInventory.LockItemsForRead(false);
6134 return inv.Key; 6530 return inv.Key;
6135 } 6531 }
6136 } 6532 }
6533 m_host.TaskInventory.LockItemsForRead(false);
6137 6534
6138 return UUID.Zero; 6535 return UUID.Zero;
6139 } 6536 }
@@ -6383,13 +6780,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6383 UUID av = new UUID(); 6780 UUID av = new UUID();
6384 if (!UUID.TryParse(avatar,out av)) 6781 if (!UUID.TryParse(avatar,out av))
6385 { 6782 {
6386 LSLError("First parameter to llDialog needs to be a key"); 6783 //LSLError("First parameter to llDialog needs to be a key");
6387 return; 6784 return;
6388 } 6785 }
6389 if (buttons.Length < 1) 6786 if (buttons.Length < 1)
6390 { 6787 {
6391 LSLError("No less than 1 button can be shown"); 6788 buttons.Add("OK");
6392 return;
6393 } 6789 }
6394 if (buttons.Length > 12) 6790 if (buttons.Length > 12)
6395 { 6791 {
@@ -6406,7 +6802,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6406 } 6802 }
6407 if (buttons.Data[i].ToString().Length > 24) 6803 if (buttons.Data[i].ToString().Length > 24)
6408 { 6804 {
6409 LSLError("button label cannot be longer than 24 characters"); 6805 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6410 return; 6806 return;
6411 } 6807 }
6412 buts[i] = buttons.Data[i].ToString(); 6808 buts[i] = buttons.Data[i].ToString();
@@ -6470,22 +6866,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6470 } 6866 }
6471 6867
6472 // copy the first script found with this inventory name 6868 // copy the first script found with this inventory name
6473 lock (m_host.TaskInventory) 6869 m_host.TaskInventory.LockItemsForRead(true);
6870 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6474 { 6871 {
6475 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6872 if (inv.Value.Name == name)
6476 { 6873 {
6477 if (inv.Value.Name == name) 6874 // make sure the object is a script
6875 if (10 == inv.Value.Type)
6478 { 6876 {
6479 // make sure the object is a script 6877 found = true;
6480 if (10 == inv.Value.Type) 6878 srcId = inv.Key;
6481 { 6879 break;
6482 found = true;
6483 srcId = inv.Key;
6484 break;
6485 }
6486 } 6880 }
6487 } 6881 }
6488 } 6882 }
6883 m_host.TaskInventory.LockItemsForRead(false);
6489 6884
6490 if (!found) 6885 if (!found)
6491 { 6886 {
@@ -6557,18 +6952,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6557 public LSL_String llMD5String(string src, int nonce) 6952 public LSL_String llMD5String(string src, int nonce)
6558 { 6953 {
6559 m_host.AddScriptLPS(1); 6954 m_host.AddScriptLPS(1);
6560 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 6955 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6561 } 6956 }
6562 6957
6563 public LSL_String llSHA1String(string src) 6958 public LSL_String llSHA1String(string src)
6564 { 6959 {
6565 m_host.AddScriptLPS(1); 6960 m_host.AddScriptLPS(1);
6566 return Util.SHA1Hash(src).ToLower(); 6961 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6567 } 6962 }
6568 6963
6569 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6964 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6570 { 6965 {
6571 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6966 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6967 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6968 return shapeBlock;
6572 6969
6573 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6970 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6574 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6971 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6644,6 +7041,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6644 7041
6645 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 7042 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6646 { 7043 {
7044 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7045 return;
7046
6647 ObjectShapePacket.ObjectDataBlock shapeBlock; 7047 ObjectShapePacket.ObjectDataBlock shapeBlock;
6648 7048
6649 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7049 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6693,6 +7093,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6693 7093
6694 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7094 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6695 { 7095 {
7096 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7097 return;
7098
6696 ObjectShapePacket.ObjectDataBlock shapeBlock; 7099 ObjectShapePacket.ObjectDataBlock shapeBlock;
6697 7100
6698 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7101 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6735,6 +7138,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6735 7138
6736 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) 7139 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)
6737 { 7140 {
7141 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7142 return;
7143
6738 ObjectShapePacket.ObjectDataBlock shapeBlock; 7144 ObjectShapePacket.ObjectDataBlock shapeBlock;
6739 7145
6740 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7146 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6861,6 +7267,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6861 7267
6862 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7268 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6863 { 7269 {
7270 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7271 return;
7272
6864 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7273 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6865 UUID sculptId; 7274 UUID sculptId;
6866 7275
@@ -6876,13 +7285,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6876 shapeBlock.PathScaleX = 100; 7285 shapeBlock.PathScaleX = 100;
6877 shapeBlock.PathScaleY = 150; 7286 shapeBlock.PathScaleY = 150;
6878 7287
6879 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7288 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6880 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7289 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6881 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7290 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6882 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7291 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6883 { 7292 {
6884 // default 7293 // default
6885 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7294 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6886 } 7295 }
6887 7296
6888 // retain pathcurve 7297 // retain pathcurve
@@ -6901,30 +7310,82 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6901 ScriptSleep(200); 7310 ScriptSleep(200);
6902 } 7311 }
6903 7312
6904 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7313 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6905 { 7314 {
6906 m_host.AddScriptLPS(1); 7315 m_host.AddScriptLPS(1);
6907 7316
6908 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7317 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7318 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7319 if (parts.Count>0)
7320 {
7321 try
7322 {
7323 parts[0].ParentGroup.areUpdatesSuspended = true;
7324 foreach (SceneObjectPart part in parts)
7325 SetPrimParams(part, rules);
7326 }
7327 finally
7328 {
7329 parts[0].ParentGroup.areUpdatesSuspended = false;
7330 }
7331 }
7332 if (avatars.Count > 0)
7333 {
7334 foreach (ScenePresence avatar in avatars)
7335 SetPrimParams(avatar, rules);
7336 }
7337 }
6909 7338
6910 foreach (SceneObjectPart part in parts) 7339 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6911 SetPrimParams(part, rules); 7340 {
6912 7341 llSetLinkPrimitiveParamsFast(linknumber, rules);
6913 ScriptSleep(200); 7342 ScriptSleep(200);
6914 } 7343 }
6915 7344
6916 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7345 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6917 { 7346 {
6918 m_host.AddScriptLPS(1); 7347 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7348 //We only support PRIM_POSITION and PRIM_ROTATION
6919 7349
6920 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7350 int idx = 0;
6921 7351
6922 foreach (SceneObjectPart part in parts) 7352 while (idx < rules.Length)
6923 SetPrimParams(part, rules); 7353 {
7354 int code = rules.GetLSLIntegerItem(idx++);
7355
7356 int remain = rules.Length - idx;
7357
7358
7359
7360 switch (code)
7361 {
7362 case (int)ScriptBaseClass.PRIM_POSITION:
7363 if (remain < 1)
7364 return;
7365 LSL_Vector v;
7366 v = rules.GetVector3Item(idx++);
7367 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7368 av.SendAvatarDataToAllAgents();
7369
7370 break;
7371
7372 case (int)ScriptBaseClass.PRIM_ROTATION:
7373 if (remain < 1)
7374 return;
7375 LSL_Rotation r;
7376 r = rules.GetQuaternionItem(idx++);
7377 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7378 av.SendAvatarDataToAllAgents();
7379 break;
7380 }
7381 }
6924 } 7382 }
6925 7383
6926 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7384 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6927 { 7385 {
7386 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7387 return;
7388
6928 int idx = 0; 7389 int idx = 0;
6929 7390
6930 while (idx < rules.Length) 7391 while (idx < rules.Length)
@@ -7459,13 +7920,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7459 public LSL_Integer llGetNumberOfPrims() 7920 public LSL_Integer llGetNumberOfPrims()
7460 { 7921 {
7461 m_host.AddScriptLPS(1); 7922 m_host.AddScriptLPS(1);
7462 int avatarCount = 0; 7923 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7463 World.ForEachScenePresence(delegate(ScenePresence presence) 7924
7464 {
7465 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7466 avatarCount++;
7467 });
7468
7469 return m_host.ParentGroup.PrimCount + avatarCount; 7925 return m_host.ParentGroup.PrimCount + avatarCount;
7470 } 7926 }
7471 7927
@@ -7481,55 +7937,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7481 m_host.AddScriptLPS(1); 7937 m_host.AddScriptLPS(1);
7482 UUID objID = UUID.Zero; 7938 UUID objID = UUID.Zero;
7483 LSL_List result = new LSL_List(); 7939 LSL_List result = new LSL_List();
7940
7941 // If the ID is not valid, return null result
7484 if (!UUID.TryParse(obj, out objID)) 7942 if (!UUID.TryParse(obj, out objID))
7485 { 7943 {
7486 result.Add(new LSL_Vector()); 7944 result.Add(new LSL_Vector());
7487 result.Add(new LSL_Vector()); 7945 result.Add(new LSL_Vector());
7488 return result; 7946 return result;
7489 } 7947 }
7948
7949 // Check if this is an attached prim. If so, replace
7950 // the UUID with the avatar UUID and report it's bounding box
7951 SceneObjectPart part = World.GetSceneObjectPart(objID);
7952 if (part != null && part.ParentGroup.IsAttachment)
7953 objID = part.ParentGroup.RootPart.AttachedAvatar;
7954
7955 // Find out if this is an avatar ID. If so, return it's box
7490 ScenePresence presence = World.GetScenePresence(objID); 7956 ScenePresence presence = World.GetScenePresence(objID);
7491 if (presence != null) 7957 if (presence != null)
7492 { 7958 {
7493 if (presence.ParentID == 0) // not sat on an object 7959 // As per LSL Wiki, there is no difference between sitting
7960 // and standing avatar since server 1.36
7961 LSL_Vector lower;
7962 LSL_Vector upper;
7963 if (presence.Animator.Animations.DefaultAnimation.AnimID
7964 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7494 { 7965 {
7495 LSL_Vector lower; 7966 // This is for ground sitting avatars
7496 LSL_Vector upper; 7967 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7497 if (presence.Animator.Animations.DefaultAnimation.AnimID 7968 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7498 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7969 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7499 {
7500 // This is for ground sitting avatars
7501 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7502 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7503 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7504 }
7505 else
7506 {
7507 // This is for standing/flying avatars
7508 float height = presence.Appearance.AvatarHeight / 2.0f;
7509 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7510 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7511 }
7512 result.Add(lower);
7513 result.Add(upper);
7514 return result;
7515 } 7970 }
7516 else 7971 else
7517 { 7972 {
7518 // sitting on an object so we need the bounding box of that 7973 // This is for standing/flying avatars
7519 // which should include the avatar so set the UUID to the 7974 float height = presence.Appearance.AvatarHeight / 2.0f;
7520 // UUID of the object the avatar is sat on and allow it to fall through 7975 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7521 // to processing an object 7976 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7522 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7523 objID = p.UUID;
7524 } 7977 }
7978
7979 // Adjust to the documented error offsets (see LSL Wiki)
7980 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7981 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7982
7983 if (lower.x > upper.x)
7984 lower.x = upper.x;
7985 if (lower.y > upper.y)
7986 lower.y = upper.y;
7987 if (lower.z > upper.z)
7988 lower.z = upper.z;
7989
7990 result.Add(lower);
7991 result.Add(upper);
7992 return result;
7525 } 7993 }
7526 SceneObjectPart part = World.GetSceneObjectPart(objID); 7994
7995 part = World.GetSceneObjectPart(objID);
7527 // Currently only works for single prims without a sitting avatar 7996 // Currently only works for single prims without a sitting avatar
7528 if (part != null) 7997 if (part != null)
7529 { 7998 {
7530 Vector3 halfSize = part.Scale / 2.0f; 7999 float minX;
7531 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8000 float maxX;
7532 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8001 float minY;
8002 float maxY;
8003 float minZ;
8004 float maxZ;
8005
8006 // This BBox is in sim coordinates, with the offset being
8007 // a contained point.
8008 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8009 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8010
8011 minX -= offsets[0].X;
8012 maxX -= offsets[0].X;
8013 minY -= offsets[0].Y;
8014 maxY -= offsets[0].Y;
8015 minZ -= offsets[0].Z;
8016 maxZ -= offsets[0].Z;
8017
8018 LSL_Vector lower;
8019 LSL_Vector upper;
8020
8021 // Adjust to the documented error offsets (see LSL Wiki)
8022 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8023 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8024
8025 if (lower.x > upper.x)
8026 lower.x = upper.x;
8027 if (lower.y > upper.y)
8028 lower.y = upper.y;
8029 if (lower.z > upper.z)
8030 lower.z = upper.z;
8031
7533 result.Add(lower); 8032 result.Add(lower);
7534 result.Add(upper); 8033 result.Add(upper);
7535 return result; 8034 return result;
@@ -7609,13 +8108,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7609 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8108 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7610 part.AbsolutePosition.Y, 8109 part.AbsolutePosition.Y,
7611 part.AbsolutePosition.Z); 8110 part.AbsolutePosition.Z);
7612 // For some reason, the part.AbsolutePosition.* values do not change if the
7613 // linkset is rotated; they always reflect the child prim's world position
7614 // as though the linkset is unrotated. This is incompatible behavior with SL's
7615 // implementation, so will break scripts imported from there (not to mention it
7616 // makes it more difficult to determine a child prim's actual inworld position).
7617 if (part.ParentID != 0)
7618 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7619 res.Add(v); 8111 res.Add(v);
7620 break; 8112 break;
7621 8113
@@ -7776,56 +8268,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7776 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8268 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7777 if (remain < 1) 8269 if (remain < 1)
7778 return res; 8270 return res;
7779 8271 face = (int)rules.GetLSLIntegerItem(idx++);
7780 face=(int)rules.GetLSLIntegerItem(idx++);
7781 8272
7782 tex = part.Shape.Textures; 8273 tex = part.Shape.Textures;
8274 int shiny;
7783 if (face == ScriptBaseClass.ALL_SIDES) 8275 if (face == ScriptBaseClass.ALL_SIDES)
7784 { 8276 {
7785 for (face = 0; face < GetNumberOfSides(part); face++) 8277 for (face = 0; face < GetNumberOfSides(part); face++)
7786 { 8278 {
7787 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8279 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7788 // Convert Shininess to PRIM_SHINY_* 8280 if (shinyness == Shininess.High)
7789 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8281 {
7790 // PRIM_BUMP_* 8282 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7791 res.Add(new LSL_Integer((int)texface.Bump)); 8283 }
8284 else if (shinyness == Shininess.Medium)
8285 {
8286 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8287 }
8288 else if (shinyness == Shininess.Low)
8289 {
8290 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8291 }
8292 else
8293 {
8294 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8295 }
8296 res.Add(new LSL_Integer(shiny));
8297 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7792 } 8298 }
7793 } 8299 }
7794 else 8300 else
7795 { 8301 {
7796 if (face >= 0 && face < GetNumberOfSides(part)) 8302 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8303 if (shinyness == Shininess.High)
7797 { 8304 {
7798 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8305 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7799 // Convert Shininess to PRIM_SHINY_* 8306 }
7800 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8307 else if (shinyness == Shininess.Medium)
7801 // PRIM_BUMP_* 8308 {
7802 res.Add(new LSL_Integer((int)texface.Bump)); 8309 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8310 }
8311 else if (shinyness == Shininess.Low)
8312 {
8313 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
7803 } 8314 }
8315 else
8316 {
8317 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8318 }
8319 res.Add(new LSL_Integer(shiny));
8320 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7804 } 8321 }
7805 break; 8322 break;
7806 8323
7807 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8324 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7808 if (remain < 1) 8325 if (remain < 1)
7809 return res; 8326 return res;
7810 8327 face = (int)rules.GetLSLIntegerItem(idx++);
7811 face=(int)rules.GetLSLIntegerItem(idx++);
7812 8328
7813 tex = part.Shape.Textures; 8329 tex = part.Shape.Textures;
8330 int fullbright;
7814 if (face == ScriptBaseClass.ALL_SIDES) 8331 if (face == ScriptBaseClass.ALL_SIDES)
7815 { 8332 {
7816 for (face = 0; face < GetNumberOfSides(part); face++) 8333 for (face = 0; face < GetNumberOfSides(part); face++)
7817 { 8334 {
7818 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8335 if (tex.GetFace((uint)face).Fullbright == true)
7819 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8336 {
8337 fullbright = ScriptBaseClass.TRUE;
8338 }
8339 else
8340 {
8341 fullbright = ScriptBaseClass.FALSE;
8342 }
8343 res.Add(new LSL_Integer(fullbright));
7820 } 8344 }
7821 } 8345 }
7822 else 8346 else
7823 { 8347 {
7824 if (face >= 0 && face < GetNumberOfSides(part)) 8348 if (tex.GetFace((uint)face).Fullbright == true)
7825 { 8349 {
7826 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8350 fullbright = ScriptBaseClass.TRUE;
7827 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8351 }
8352 else
8353 {
8354 fullbright = ScriptBaseClass.FALSE;
7828 } 8355 }
8356 res.Add(new LSL_Integer(fullbright));
7829 } 8357 }
7830 break; 8358 break;
7831 8359
@@ -7847,27 +8375,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7847 break; 8375 break;
7848 8376
7849 case (int)ScriptBaseClass.PRIM_TEXGEN: 8377 case (int)ScriptBaseClass.PRIM_TEXGEN:
8378 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7850 if (remain < 1) 8379 if (remain < 1)
7851 return res; 8380 return res;
7852 8381 face = (int)rules.GetLSLIntegerItem(idx++);
7853 face=(int)rules.GetLSLIntegerItem(idx++);
7854 8382
7855 tex = part.Shape.Textures; 8383 tex = part.Shape.Textures;
7856 if (face == ScriptBaseClass.ALL_SIDES) 8384 if (face == ScriptBaseClass.ALL_SIDES)
7857 { 8385 {
7858 for (face = 0; face < GetNumberOfSides(part); face++) 8386 for (face = 0; face < GetNumberOfSides(part); face++)
7859 { 8387 {
7860 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8388 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7861 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8389 {
7862 res.Add(new LSL_Integer((uint)texgen >> 1)); 8390 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8391 }
8392 else
8393 {
8394 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8395 }
7863 } 8396 }
7864 } 8397 }
7865 else 8398 else
7866 { 8399 {
7867 if (face >= 0 && face < GetNumberOfSides(part)) 8400 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7868 { 8401 {
7869 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8402 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
7870 res.Add(new LSL_Integer((uint)texgen >> 1)); 8403 }
8404 else
8405 {
8406 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7871 } 8407 }
7872 } 8408 }
7873 break; 8409 break;
@@ -7890,28 +8426,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7890 case (int)ScriptBaseClass.PRIM_GLOW: 8426 case (int)ScriptBaseClass.PRIM_GLOW:
7891 if (remain < 1) 8427 if (remain < 1)
7892 return res; 8428 return res;
7893 8429 face = (int)rules.GetLSLIntegerItem(idx++);
7894 face=(int)rules.GetLSLIntegerItem(idx++);
7895 8430
7896 tex = part.Shape.Textures; 8431 tex = part.Shape.Textures;
8432 float primglow;
7897 if (face == ScriptBaseClass.ALL_SIDES) 8433 if (face == ScriptBaseClass.ALL_SIDES)
7898 { 8434 {
7899 for (face = 0; face < GetNumberOfSides(part); face++) 8435 for (face = 0; face < GetNumberOfSides(part); face++)
7900 { 8436 {
7901 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8437 primglow = tex.GetFace((uint)face).Glow;
7902 res.Add(new LSL_Float(texface.Glow)); 8438 res.Add(new LSL_Float(primglow));
7903 } 8439 }
7904 } 8440 }
7905 else 8441 else
7906 { 8442 {
7907 if (face >= 0 && face < GetNumberOfSides(part)) 8443 primglow = tex.GetFace((uint)face).Glow;
7908 { 8444 res.Add(new LSL_Float(primglow));
7909 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
7910 res.Add(new LSL_Float(texface.Glow));
7911 }
7912 } 8445 }
7913 break; 8446 break;
7914
7915 case (int)ScriptBaseClass.PRIM_TEXT: 8447 case (int)ScriptBaseClass.PRIM_TEXT:
7916 Color4 textColor = part.GetTextColor(); 8448 Color4 textColor = part.GetTextColor();
7917 res.Add(part.Text); 8449 res.Add(part.Text);
@@ -8460,8 +8992,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8460 // The function returns an ordered list 8992 // The function returns an ordered list
8461 // representing the tokens found in the supplied 8993 // representing the tokens found in the supplied
8462 // sources string. If two successive tokenizers 8994 // sources string. If two successive tokenizers
8463 // are encountered, then a NULL entry is added 8995 // are encountered, then a null-string entry is
8464 // to the list. 8996 // added to the list.
8465 // 8997 //
8466 // It is a precondition that the source and 8998 // It is a precondition that the source and
8467 // toekizer lisst are non-null. If they are null, 8999 // toekizer lisst are non-null. If they are null,
@@ -8469,7 +9001,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8469 // while their lengths are being determined. 9001 // while their lengths are being determined.
8470 // 9002 //
8471 // A small amount of working memoryis required 9003 // A small amount of working memoryis required
8472 // of approximately 8*#tokenizers. 9004 // of approximately 8*#tokenizers + 8*srcstrlen.
8473 // 9005 //
8474 // There are many ways in which this function 9006 // There are many ways in which this function
8475 // can be implemented, this implementation is 9007 // can be implemented, this implementation is
@@ -8485,155 +9017,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8485 // and eliminates redundant tokenizers as soon 9017 // and eliminates redundant tokenizers as soon
8486 // as is possible. 9018 // as is possible.
8487 // 9019 //
8488 // The implementation tries to avoid any copying 9020 // The implementation tries to minimize temporary
8489 // of arrays or other objects. 9021 // garbage generation.
8490 // </remarks> 9022 // </remarks>
8491 9023
8492 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9024 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8493 { 9025 {
8494 int beginning = 0; 9026 return ParseString2List(src, separators, spacers, true);
8495 int srclen = src.Length; 9027 }
8496 int seplen = separators.Length;
8497 object[] separray = separators.Data;
8498 int spclen = spacers.Length;
8499 object[] spcarray = spacers.Data;
8500 int mlen = seplen+spclen;
8501
8502 int[] offset = new int[mlen+1];
8503 bool[] active = new bool[mlen];
8504
8505 int best;
8506 int j;
8507
8508 // Initial capacity reduces resize cost
8509 9028
8510 LSL_List tokens = new LSL_List(); 9029 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9030 {
9031 int srclen = src.Length;
9032 int seplen = separators.Length;
9033 object[] separray = separators.Data;
9034 int spclen = spacers.Length;
9035 object[] spcarray = spacers.Data;
9036 int dellen = 0;
9037 string[] delarray = new string[seplen+spclen];
8511 9038
8512 // All entries are initially valid 9039 int outlen = 0;
9040 string[] outarray = new string[srclen*2+1];
8513 9041
8514 for (int i = 0; i < mlen; i++) 9042 int i, j;
8515 active[i] = true; 9043 string d;
8516 9044
8517 offset[mlen] = srclen; 9045 m_host.AddScriptLPS(1);
8518 9046
8519 while (beginning < srclen) 9047 /*
9048 * Convert separator and spacer lists to C# strings.
9049 * Also filter out null strings so we don't hang.
9050 */
9051 for (i = 0; i < seplen; i ++)
8520 { 9052 {
9053 d = separray[i].ToString();
9054 if (d.Length > 0)
9055 {
9056 delarray[dellen++] = d;
9057 }
9058 }
9059 seplen = dellen;
8521 9060
8522 best = mlen; // as bad as it gets 9061 for (i = 0; i < spclen; i ++)
9062 {
9063 d = spcarray[i].ToString();
9064 if (d.Length > 0)
9065 {
9066 delarray[dellen++] = d;
9067 }
9068 }
8523 9069
8524 // Scan for separators 9070 /*
9071 * Scan through source string from beginning to end.
9072 */
9073 for (i = 0;;)
9074 {
8525 9075
8526 for (j = 0; j < seplen; j++) 9076 /*
9077 * Find earliest delimeter in src starting at i (if any).
9078 */
9079 int earliestDel = -1;
9080 int earliestSrc = srclen;
9081 string earliestStr = null;
9082 for (j = 0; j < dellen; j ++)
8527 { 9083 {
8528 if (separray[j].ToString() == String.Empty) 9084 d = delarray[j];
8529 active[j] = false; 9085 if (d != null)
8530
8531 if (active[j])
8532 { 9086 {
8533 // scan all of the markers 9087 int index = src.IndexOf(d, i);
8534 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9088 if (index < 0)
8535 { 9089 {
8536 // not present at all 9090 delarray[j] = null; // delim nowhere in src, don't check it anymore
8537 active[j] = false;
8538 } 9091 }
8539 else 9092 else if (index < earliestSrc)
8540 { 9093 {
8541 // present and correct 9094 earliestSrc = index; // where delimeter starts in source string
8542 if (offset[j] < offset[best]) 9095 earliestDel = j; // where delimeter is in delarray[]
8543 { 9096 earliestStr = d; // the delimeter string from delarray[]
8544 // closest so far 9097 if (index == i) break; // can't do any better than found at beg of string
8545 best = j;
8546 if (offset[best] == beginning)
8547 break;
8548 }
8549 } 9098 }
8550 } 9099 }
8551 } 9100 }
8552 9101
8553 // Scan for spacers 9102 /*
8554 9103 * Output source string starting at i through start of earliest delimeter.
8555 if (offset[best] != beginning) 9104 */
9105 if (keepNulls || (earliestSrc > i))
8556 { 9106 {
8557 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9107 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8558 {
8559 if (spcarray[j-seplen].ToString() == String.Empty)
8560 active[j] = false;
8561
8562 if (active[j])
8563 {
8564 // scan all of the markers
8565 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8566 {
8567 // not present at all
8568 active[j] = false;
8569 }
8570 else
8571 {
8572 // present and correct
8573 if (offset[j] < offset[best])
8574 {
8575 // closest so far
8576 best = j;
8577 }
8578 }
8579 }
8580 }
8581 } 9108 }
8582 9109
8583 // This is the normal exit from the scanning loop 9110 /*
9111 * If no delimeter found at or after i, we're done scanning.
9112 */
9113 if (earliestDel < 0) break;
8584 9114
8585 if (best == mlen) 9115 /*
9116 * If delimeter was a spacer, output the spacer.
9117 */
9118 if (earliestDel >= seplen)
8586 { 9119 {
8587 // no markers were found on this pass 9120 outarray[outlen++] = earliestStr;
8588 // so we're pretty much done
8589 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8590 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8591 break;
8592 } 9121 }
8593 9122
8594 // Otherwise we just add the newly delimited token 9123 /*
8595 // and recalculate where the search should continue. 9124 * Look at rest of src string following delimeter.
8596 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9125 */
8597 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9126 i = earliestSrc + earliestStr.Length;
8598
8599 if (best < seplen)
8600 {
8601 beginning = offset[best] + (separray[best].ToString()).Length;
8602 }
8603 else
8604 {
8605 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8606 string str = spcarray[best - seplen].ToString();
8607 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8608 tokens.Add(new LSL_String(str));
8609 }
8610 } 9127 }
8611 9128
8612 // This an awkward an not very intuitive boundary case. If the 9129 /*
8613 // last substring is a tokenizer, then there is an implied trailing 9130 * Make up an exact-sized output array suitable for an LSL_List object.
8614 // null list entry. Hopefully the single comparison will not be too 9131 */
8615 // arduous. Alternatively the 'break' could be replced with a return 9132 object[] outlist = new object[outlen];
8616 // but that's shabby programming. 9133 for (i = 0; i < outlen; i ++)
8617
8618 if ((beginning == srclen) && (keepNulls))
8619 { 9134 {
8620 if (srclen != 0) 9135 outlist[i] = new LSL_String(outarray[i]);
8621 tokens.Add(new LSL_String(""));
8622 } 9136 }
8623 9137 return new LSL_List(outlist);
8624 return tokens;
8625 }
8626
8627 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8628 {
8629 m_host.AddScriptLPS(1);
8630 return this.ParseString(src, separators, spacers, false);
8631 }
8632
8633 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8634 {
8635 m_host.AddScriptLPS(1);
8636 return this.ParseString(src, separators, spacers, true);
8637 } 9138 }
8638 9139
8639 public LSL_Integer llGetObjectPermMask(int mask) 9140 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8710,28 +9211,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8710 { 9211 {
8711 m_host.AddScriptLPS(1); 9212 m_host.AddScriptLPS(1);
8712 9213
8713 lock (m_host.TaskInventory) 9214 m_host.TaskInventory.LockItemsForRead(true);
9215 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8714 { 9216 {
8715 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9217 if (inv.Value.Name == item)
8716 { 9218 {
8717 if (inv.Value.Name == item) 9219 m_host.TaskInventory.LockItemsForRead(false);
9220 switch (mask)
8718 { 9221 {
8719 switch (mask) 9222 case 0:
8720 { 9223 return (int)inv.Value.BasePermissions;
8721 case 0: 9224 case 1:
8722 return (int)inv.Value.BasePermissions; 9225 return (int)inv.Value.CurrentPermissions;
8723 case 1: 9226 case 2:
8724 return (int)inv.Value.CurrentPermissions; 9227 return (int)inv.Value.GroupPermissions;
8725 case 2: 9228 case 3:
8726 return (int)inv.Value.GroupPermissions; 9229 return (int)inv.Value.EveryonePermissions;
8727 case 3: 9230 case 4:
8728 return (int)inv.Value.EveryonePermissions; 9231 return (int)inv.Value.NextPermissions;
8729 case 4:
8730 return (int)inv.Value.NextPermissions;
8731 }
8732 } 9232 }
8733 } 9233 }
8734 } 9234 }
9235 m_host.TaskInventory.LockItemsForRead(false);
8735 9236
8736 return -1; 9237 return -1;
8737 } 9238 }
@@ -8778,16 +9279,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8778 { 9279 {
8779 m_host.AddScriptLPS(1); 9280 m_host.AddScriptLPS(1);
8780 9281
8781 lock (m_host.TaskInventory) 9282 m_host.TaskInventory.LockItemsForRead(true);
9283 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8782 { 9284 {
8783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9285 if (inv.Value.Name == item)
8784 { 9286 {
8785 if (inv.Value.Name == item) 9287 m_host.TaskInventory.LockItemsForRead(false);
8786 { 9288 return inv.Value.CreatorID.ToString();
8787 return inv.Value.CreatorID.ToString();
8788 }
8789 } 9289 }
8790 } 9290 }
9291 m_host.TaskInventory.LockItemsForRead(false);
8791 9292
8792 llSay(0, "No item name '" + item + "'"); 9293 llSay(0, "No item name '" + item + "'");
8793 9294
@@ -8935,7 +9436,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8935 } 9436 }
8936 9437
8937 /// <summary> 9438 /// <summary>
8938 /// illListReplaceList removes the sub-list defined by the inclusive indices 9439 /// llListReplaceList removes the sub-list defined by the inclusive indices
8939 /// start and end and inserts the src list in its place. The inclusive 9440 /// start and end and inserts the src list in its place. The inclusive
8940 /// nature of the indices means that at least one element must be deleted 9441 /// nature of the indices means that at least one element must be deleted
8941 /// if the indices are within the bounds of the existing list. I.e. 2,2 9442 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -8992,16 +9493,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8992 // based upon end. Note that if end exceeds the upper 9493 // based upon end. Note that if end exceeds the upper
8993 // bound in this case, the entire destination list 9494 // bound in this case, the entire destination list
8994 // is removed. 9495 // is removed.
8995 else 9496 else if (start == 0)
8996 { 9497 {
8997 if (end + 1 < dest.Length) 9498 if (end + 1 < dest.Length)
8998 {
8999 return src + dest.GetSublist(end + 1, -1); 9499 return src + dest.GetSublist(end + 1, -1);
9000 }
9001 else 9500 else
9002 {
9003 return src; 9501 return src;
9004 } 9502 }
9503 else // Start < 0
9504 {
9505 if (end + 1 < dest.Length)
9506 return dest.GetSublist(end + 1, -1);
9507 else
9508 return new LSL_List();
9005 } 9509 }
9006 } 9510 }
9007 // Finally, if start > end, we strip away a prefix and 9511 // Finally, if start > end, we strip away a prefix and
@@ -9052,17 +9556,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9052 int width = 0; 9556 int width = 0;
9053 int height = 0; 9557 int height = 0;
9054 9558
9055 ParcelMediaCommandEnum? commandToSend = null; 9559 uint commandToSend = 0;
9056 float time = 0.0f; // default is from start 9560 float time = 0.0f; // default is from start
9057 9561
9058 ScenePresence presence = null; 9562 ScenePresence presence = null;
9059 9563
9060 for (int i = 0; i < commandList.Data.Length; i++) 9564 for (int i = 0; i < commandList.Data.Length; i++)
9061 { 9565 {
9062 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9566 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9063 switch (command) 9567 switch (command)
9064 { 9568 {
9065 case ParcelMediaCommandEnum.Agent: 9569 case (uint)ParcelMediaCommandEnum.Agent:
9066 // we send only to one agent 9570 // we send only to one agent
9067 if ((i + 1) < commandList.Length) 9571 if ((i + 1) < commandList.Length)
9068 { 9572 {
@@ -9079,25 +9583,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9079 } 9583 }
9080 break; 9584 break;
9081 9585
9082 case ParcelMediaCommandEnum.Loop: 9586 case (uint)ParcelMediaCommandEnum.Loop:
9083 loop = 1; 9587 loop = 1;
9084 commandToSend = command; 9588 commandToSend = command;
9085 update = true; //need to send the media update packet to set looping 9589 update = true; //need to send the media update packet to set looping
9086 break; 9590 break;
9087 9591
9088 case ParcelMediaCommandEnum.Play: 9592 case (uint)ParcelMediaCommandEnum.Play:
9089 loop = 0; 9593 loop = 0;
9090 commandToSend = command; 9594 commandToSend = command;
9091 update = true; //need to send the media update packet to make sure it doesn't loop 9595 update = true; //need to send the media update packet to make sure it doesn't loop
9092 break; 9596 break;
9093 9597
9094 case ParcelMediaCommandEnum.Pause: 9598 case (uint)ParcelMediaCommandEnum.Pause:
9095 case ParcelMediaCommandEnum.Stop: 9599 case (uint)ParcelMediaCommandEnum.Stop:
9096 case ParcelMediaCommandEnum.Unload: 9600 case (uint)ParcelMediaCommandEnum.Unload:
9097 commandToSend = command; 9601 commandToSend = command;
9098 break; 9602 break;
9099 9603
9100 case ParcelMediaCommandEnum.Url: 9604 case (uint)ParcelMediaCommandEnum.Url:
9101 if ((i + 1) < commandList.Length) 9605 if ((i + 1) < commandList.Length)
9102 { 9606 {
9103 if (commandList.Data[i + 1] is LSL_String) 9607 if (commandList.Data[i + 1] is LSL_String)
@@ -9110,7 +9614,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9110 } 9614 }
9111 break; 9615 break;
9112 9616
9113 case ParcelMediaCommandEnum.Texture: 9617 case (uint)ParcelMediaCommandEnum.Texture:
9114 if ((i + 1) < commandList.Length) 9618 if ((i + 1) < commandList.Length)
9115 { 9619 {
9116 if (commandList.Data[i + 1] is LSL_String) 9620 if (commandList.Data[i + 1] is LSL_String)
@@ -9123,7 +9627,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9123 } 9627 }
9124 break; 9628 break;
9125 9629
9126 case ParcelMediaCommandEnum.Time: 9630 case (uint)ParcelMediaCommandEnum.Time:
9127 if ((i + 1) < commandList.Length) 9631 if ((i + 1) < commandList.Length)
9128 { 9632 {
9129 if (commandList.Data[i + 1] is LSL_Float) 9633 if (commandList.Data[i + 1] is LSL_Float)
@@ -9135,7 +9639,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9135 } 9639 }
9136 break; 9640 break;
9137 9641
9138 case ParcelMediaCommandEnum.AutoAlign: 9642 case (uint)ParcelMediaCommandEnum.AutoAlign:
9139 if ((i + 1) < commandList.Length) 9643 if ((i + 1) < commandList.Length)
9140 { 9644 {
9141 if (commandList.Data[i + 1] is LSL_Integer) 9645 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9149,7 +9653,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9149 } 9653 }
9150 break; 9654 break;
9151 9655
9152 case ParcelMediaCommandEnum.Type: 9656 case (uint)ParcelMediaCommandEnum.Type:
9153 if ((i + 1) < commandList.Length) 9657 if ((i + 1) < commandList.Length)
9154 { 9658 {
9155 if (commandList.Data[i + 1] is LSL_String) 9659 if (commandList.Data[i + 1] is LSL_String)
@@ -9162,7 +9666,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9162 } 9666 }
9163 break; 9667 break;
9164 9668
9165 case ParcelMediaCommandEnum.Desc: 9669 case (uint)ParcelMediaCommandEnum.Desc:
9166 if ((i + 1) < commandList.Length) 9670 if ((i + 1) < commandList.Length)
9167 { 9671 {
9168 if (commandList.Data[i + 1] is LSL_String) 9672 if (commandList.Data[i + 1] is LSL_String)
@@ -9175,7 +9679,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9175 } 9679 }
9176 break; 9680 break;
9177 9681
9178 case ParcelMediaCommandEnum.Size: 9682 case (uint)ParcelMediaCommandEnum.Size:
9179 if ((i + 2) < commandList.Length) 9683 if ((i + 2) < commandList.Length)
9180 { 9684 {
9181 if (commandList.Data[i + 1] is LSL_Integer) 9685 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9245,7 +9749,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9245 } 9749 }
9246 } 9750 }
9247 9751
9248 if (commandToSend != null) 9752 if (commandToSend != 0)
9249 { 9753 {
9250 // the commandList contained a start/stop/... command, too 9754 // the commandList contained a start/stop/... command, too
9251 if (presence == null) 9755 if (presence == null)
@@ -9282,7 +9786,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9282 9786
9283 if (aList.Data[i] != null) 9787 if (aList.Data[i] != null)
9284 { 9788 {
9285 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9789 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9286 { 9790 {
9287 case ParcelMediaCommandEnum.Url: 9791 case ParcelMediaCommandEnum.Url:
9288 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9792 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9325,16 +9829,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9325 { 9829 {
9326 m_host.AddScriptLPS(1); 9830 m_host.AddScriptLPS(1);
9327 9831
9328 lock (m_host.TaskInventory) 9832 m_host.TaskInventory.LockItemsForRead(true);
9833 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9329 { 9834 {
9330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9835 if (inv.Value.Name == name)
9331 { 9836 {
9332 if (inv.Value.Name == name) 9837 m_host.TaskInventory.LockItemsForRead(false);
9333 { 9838 return inv.Value.Type;
9334 return inv.Value.Type;
9335 }
9336 } 9839 }
9337 } 9840 }
9841 m_host.TaskInventory.LockItemsForRead(false);
9338 9842
9339 return -1; 9843 return -1;
9340 } 9844 }
@@ -9345,15 +9849,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9345 9849
9346 if (quick_pay_buttons.Data.Length < 4) 9850 if (quick_pay_buttons.Data.Length < 4)
9347 { 9851 {
9348 LSLError("List must have at least 4 elements"); 9852 int x;
9349 return; 9853 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9854 {
9855 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9856 }
9350 } 9857 }
9351 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9858 int[] nPrice = new int[5];
9352 9859 nPrice[0] = price;
9353 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9860 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9354 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9861 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9355 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9862 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9356 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9863 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
9864 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9357 m_host.ParentGroup.HasGroupChanged = true; 9865 m_host.ParentGroup.HasGroupChanged = true;
9358 } 9866 }
9359 9867
@@ -9365,17 +9873,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9365 if (invItemID == UUID.Zero) 9873 if (invItemID == UUID.Zero)
9366 return new LSL_Vector(); 9874 return new LSL_Vector();
9367 9875
9368 lock (m_host.TaskInventory) 9876 m_host.TaskInventory.LockItemsForRead(true);
9877 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9369 { 9878 {
9370 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9879 m_host.TaskInventory.LockItemsForRead(false);
9371 return new LSL_Vector(); 9880 return new LSL_Vector();
9881 }
9372 9882
9373 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9883 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9374 { 9884 {
9375 ShoutError("No permissions to track the camera"); 9885 ShoutError("No permissions to track the camera");
9376 return new LSL_Vector(); 9886 m_host.TaskInventory.LockItemsForRead(false);
9377 } 9887 return new LSL_Vector();
9378 } 9888 }
9889 m_host.TaskInventory.LockItemsForRead(false);
9379 9890
9380 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9891 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9381 if (presence != null) 9892 if (presence != null)
@@ -9393,17 +9904,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9393 if (invItemID == UUID.Zero) 9904 if (invItemID == UUID.Zero)
9394 return new LSL_Rotation(); 9905 return new LSL_Rotation();
9395 9906
9396 lock (m_host.TaskInventory) 9907 m_host.TaskInventory.LockItemsForRead(true);
9908 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9397 { 9909 {
9398 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9910 m_host.TaskInventory.LockItemsForRead(false);
9399 return new LSL_Rotation(); 9911 return new LSL_Rotation();
9400 9912 }
9401 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9913 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9402 { 9914 {
9403 ShoutError("No permissions to track the camera"); 9915 ShoutError("No permissions to track the camera");
9404 return new LSL_Rotation(); 9916 m_host.TaskInventory.LockItemsForRead(false);
9405 } 9917 return new LSL_Rotation();
9406 } 9918 }
9919 m_host.TaskInventory.LockItemsForRead(false);
9407 9920
9408 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9921 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9409 if (presence != null) 9922 if (presence != null)
@@ -9465,8 +9978,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9465 { 9978 {
9466 m_host.AddScriptLPS(1); 9979 m_host.AddScriptLPS(1);
9467 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9980 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9468 if (detectedParams == null) return; // only works on the first detected avatar 9981 if (detectedParams == null)
9469 9982 {
9983 if (m_host.IsAttachment == true)
9984 {
9985 detectedParams = new DetectParams();
9986 detectedParams.Key = m_host.OwnerID;
9987 }
9988 else
9989 {
9990 return;
9991 }
9992 }
9993
9470 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9994 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9471 if (avatar != null) 9995 if (avatar != null)
9472 { 9996 {
@@ -9474,6 +9998,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9474 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9998 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9475 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9999 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9476 } 10000 }
10001
9477 ScriptSleep(1000); 10002 ScriptSleep(1000);
9478 } 10003 }
9479 10004
@@ -9566,14 +10091,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9566 if (objectID == UUID.Zero) return; 10091 if (objectID == UUID.Zero) return;
9567 10092
9568 UUID agentID; 10093 UUID agentID;
9569 lock (m_host.TaskInventory) 10094 m_host.TaskInventory.LockItemsForRead(true);
9570 { 10095 // we need the permission first, to know which avatar we want to set the camera for
9571 // we need the permission first, to know which avatar we want to set the camera for 10096 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9572 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9573 10097
9574 if (agentID == UUID.Zero) return; 10098 if (agentID == UUID.Zero)
9575 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10099 {
10100 m_host.TaskInventory.LockItemsForRead(false);
10101 return;
10102 }
10103 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10104 {
10105 m_host.TaskInventory.LockItemsForRead(false);
10106 return;
9576 } 10107 }
10108 m_host.TaskInventory.LockItemsForRead(false);
9577 10109
9578 ScenePresence presence = World.GetScenePresence(agentID); 10110 ScenePresence presence = World.GetScenePresence(agentID);
9579 10111
@@ -9582,12 +10114,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9582 10114
9583 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10115 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9584 object[] data = rules.Data; 10116 object[] data = rules.Data;
9585 for (int i = 0; i < data.Length; ++i) { 10117 for (int i = 0; i < data.Length; ++i)
10118 {
9586 int type = Convert.ToInt32(data[i++].ToString()); 10119 int type = Convert.ToInt32(data[i++].ToString());
9587 if (i >= data.Length) break; // odd number of entries => ignore the last 10120 if (i >= data.Length) break; // odd number of entries => ignore the last
9588 10121
9589 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10122 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9590 switch (type) { 10123 switch (type)
10124 {
9591 case ScriptBaseClass.CAMERA_FOCUS: 10125 case ScriptBaseClass.CAMERA_FOCUS:
9592 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10126 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9593 case ScriptBaseClass.CAMERA_POSITION: 10127 case ScriptBaseClass.CAMERA_POSITION:
@@ -9623,12 +10157,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9623 10157
9624 // we need the permission first, to know which avatar we want to clear the camera for 10158 // we need the permission first, to know which avatar we want to clear the camera for
9625 UUID agentID; 10159 UUID agentID;
9626 lock (m_host.TaskInventory) 10160 m_host.TaskInventory.LockItemsForRead(true);
10161 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10162 if (agentID == UUID.Zero)
9627 { 10163 {
9628 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10164 m_host.TaskInventory.LockItemsForRead(false);
9629 if (agentID == UUID.Zero) return; 10165 return;
9630 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9631 } 10166 }
10167 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10168 {
10169 m_host.TaskInventory.LockItemsForRead(false);
10170 return;
10171 }
10172 m_host.TaskInventory.LockItemsForRead(false);
9632 10173
9633 ScenePresence presence = World.GetScenePresence(agentID); 10174 ScenePresence presence = World.GetScenePresence(agentID);
9634 10175
@@ -9695,19 +10236,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9695 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10236 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9696 { 10237 {
9697 m_host.AddScriptLPS(1); 10238 m_host.AddScriptLPS(1);
9698 string ret = String.Empty; 10239
9699 string src1 = llBase64ToString(str1); 10240 if (str1 == String.Empty)
9700 string src2 = llBase64ToString(str2); 10241 return String.Empty;
9701 int c = 0; 10242 if (str2 == String.Empty)
9702 for (int i = 0; i < src1.Length; i++) 10243 return str1;
10244
10245 int len = str2.Length;
10246 if ((len % 4) != 0) // LL is EVIL!!!!
9703 { 10247 {
9704 ret += (char) (src1[i] ^ src2[c]); 10248 while (str2.EndsWith("="))
10249 str2 = str2.Substring(0, str2.Length - 1);
10250
10251 len = str2.Length;
10252 int mod = len % 4;
9705 10253
9706 c++; 10254 if (mod == 1)
9707 if (c >= src2.Length) 10255 str2 = str2.Substring(0, str2.Length - 1);
9708 c = 0; 10256 else if (mod == 2)
10257 str2 += "==";
10258 else if (mod == 3)
10259 str2 += "=";
10260 }
10261
10262 byte[] data1;
10263 byte[] data2;
10264 try
10265 {
10266 data1 = Convert.FromBase64String(str1);
10267 data2 = Convert.FromBase64String(str2);
10268 }
10269 catch (Exception)
10270 {
10271 return new LSL_String(String.Empty);
9709 } 10272 }
9710 return llStringToBase64(ret); 10273
10274 byte[] d2 = new Byte[data1.Length];
10275 int pos = 0;
10276
10277 if (data1.Length <= data2.Length)
10278 {
10279 Array.Copy(data2, 0, d2, 0, data1.Length);
10280 }
10281 else
10282 {
10283 while (pos < data1.Length)
10284 {
10285 len = data1.Length - pos;
10286 if (len > data2.Length)
10287 len = data2.Length;
10288
10289 Array.Copy(data2, 0, d2, pos, len);
10290 pos += len;
10291 }
10292 }
10293
10294 for (pos = 0 ; pos < data1.Length ; pos++ )
10295 data1[pos] ^= d2[pos];
10296
10297 return Convert.ToBase64String(data1);
9711 } 10298 }
9712 10299
9713 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10300 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9766,12 +10353,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9766 Regex r = new Regex(authregex); 10353 Regex r = new Regex(authregex);
9767 int[] gnums = r.GetGroupNumbers(); 10354 int[] gnums = r.GetGroupNumbers();
9768 Match m = r.Match(url); 10355 Match m = r.Match(url);
9769 if (m.Success) { 10356 if (m.Success)
9770 for (int i = 1; i < gnums.Length; i++) { 10357 {
10358 for (int i = 1; i < gnums.Length; i++)
10359 {
9771 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10360 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9772 //CaptureCollection cc = g.Captures; 10361 //CaptureCollection cc = g.Captures;
9773 } 10362 }
9774 if (m.Groups.Count == 5) { 10363 if (m.Groups.Count == 5)
10364 {
9775 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10365 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9776 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10366 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9777 } 10367 }
@@ -10088,15 +10678,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10088 10678
10089 internal UUID ScriptByName(string name) 10679 internal UUID ScriptByName(string name)
10090 { 10680 {
10091 lock (m_host.TaskInventory) 10681 m_host.TaskInventory.LockItemsForRead(true);
10682
10683 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10092 { 10684 {
10093 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10685 if (item.Type == 10 && item.Name == name)
10094 { 10686 {
10095 if (item.Type == 10 && item.Name == name) 10687 m_host.TaskInventory.LockItemsForRead(false);
10096 return item.ItemID; 10688 return item.ItemID;
10097 } 10689 }
10098 } 10690 }
10099 10691
10692 m_host.TaskInventory.LockItemsForRead(false);
10693
10100 return UUID.Zero; 10694 return UUID.Zero;
10101 } 10695 }
10102 10696
@@ -10137,6 +10731,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10137 { 10731 {
10138 m_host.AddScriptLPS(1); 10732 m_host.AddScriptLPS(1);
10139 10733
10734 //Clone is thread safe
10140 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10735 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10141 10736
10142 UUID assetID = UUID.Zero; 10737 UUID assetID = UUID.Zero;
@@ -10199,6 +10794,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10199 { 10794 {
10200 m_host.AddScriptLPS(1); 10795 m_host.AddScriptLPS(1);
10201 10796
10797 //Clone is thread safe
10202 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10798 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10203 10799
10204 UUID assetID = UUID.Zero; 10800 UUID assetID = UUID.Zero;
@@ -10278,6 +10874,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10278 10874
10279 return GetLinkPrimitiveParams(obj, rules); 10875 return GetLinkPrimitiveParams(obj, rules);
10280 } 10876 }
10877
10878 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10879 {
10880 List<SceneObjectPart> parts = GetLinkParts(link);
10881 if (parts.Count < 1)
10882 return 0;
10883
10884 return GetNumberOfSides(parts[0]);
10885 }
10281 } 10886 }
10282 10887
10283 public class NotecardCache 10888 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 3f8735e..4d299d6 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()
@@ -837,18 +846,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
837 if (target != null) 846 if (target != null)
838 { 847 {
839 UUID animID=UUID.Zero; 848 UUID animID=UUID.Zero;
840 lock (m_host.TaskInventory) 849 m_host.TaskInventory.LockItemsForRead(true);
850 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
841 { 851 {
842 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 852 if (inv.Value.Name == animation)
843 { 853 {
844 if (inv.Value.Name == animation) 854 if (inv.Value.Type == (int)AssetType.Animation)
845 { 855 animID = inv.Value.AssetID;
846 if (inv.Value.Type == (int)AssetType.Animation) 856 continue;
847 animID = inv.Value.AssetID;
848 continue;
849 }
850 } 857 }
851 } 858 }
859 m_host.TaskInventory.LockItemsForRead(false);
852 if (animID == UUID.Zero) 860 if (animID == UUID.Zero)
853 target.Animator.AddAnimation(animation, m_host.UUID); 861 target.Animator.AddAnimation(animation, m_host.UUID);
854 else 862 else
@@ -870,18 +878,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
870 if (target != null) 878 if (target != null)
871 { 879 {
872 UUID animID=UUID.Zero; 880 UUID animID=UUID.Zero;
873 lock (m_host.TaskInventory) 881 m_host.TaskInventory.LockItemsForRead(true);
882 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
874 { 883 {
875 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 884 if (inv.Value.Name == animation)
876 { 885 {
877 if (inv.Value.Name == animation) 886 if (inv.Value.Type == (int)AssetType.Animation)
878 { 887 animID = inv.Value.AssetID;
879 if (inv.Value.Type == (int)AssetType.Animation) 888 continue;
880 animID = inv.Value.AssetID;
881 continue;
882 }
883 } 889 }
884 } 890 }
891 m_host.TaskInventory.LockItemsForRead(false);
885 892
886 if (animID == UUID.Zero) 893 if (animID == UUID.Zero)
887 target.Animator.RemoveAnimation(animation); 894 target.Animator.RemoveAnimation(animation);
@@ -1774,6 +1781,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1774 1781
1775 if (!UUID.TryParse(name, out assetID)) 1782 if (!UUID.TryParse(name, out assetID))
1776 { 1783 {
1784 m_host.TaskInventory.LockItemsForRead(true);
1777 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1785 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1778 { 1786 {
1779 if (item.Type == 7 && item.Name == name) 1787 if (item.Type == 7 && item.Name == name)
@@ -1781,6 +1789,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1781 assetID = item.AssetID; 1789 assetID = item.AssetID;
1782 } 1790 }
1783 } 1791 }
1792 m_host.TaskInventory.LockItemsForRead(false);
1784 } 1793 }
1785 1794
1786 if (assetID == UUID.Zero) 1795 if (assetID == UUID.Zero)
@@ -1827,6 +1836,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1827 1836
1828 if (!UUID.TryParse(name, out assetID)) 1837 if (!UUID.TryParse(name, out assetID))
1829 { 1838 {
1839 m_host.TaskInventory.LockItemsForRead(true);
1830 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1840 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1831 { 1841 {
1832 if (item.Type == 7 && item.Name == name) 1842 if (item.Type == 7 && item.Name == name)
@@ -1834,6 +1844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1834 assetID = item.AssetID; 1844 assetID = item.AssetID;
1835 } 1845 }
1836 } 1846 }
1847 m_host.TaskInventory.LockItemsForRead(false);
1837 } 1848 }
1838 1849
1839 if (assetID == UUID.Zero) 1850 if (assetID == UUID.Zero)
@@ -1884,6 +1895,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1884 1895
1885 if (!UUID.TryParse(name, out assetID)) 1896 if (!UUID.TryParse(name, out assetID))
1886 { 1897 {
1898 m_host.TaskInventory.LockItemsForRead(true);
1887 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1899 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1888 { 1900 {
1889 if (item.Type == 7 && item.Name == name) 1901 if (item.Type == 7 && item.Name == name)
@@ -1891,6 +1903,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1891 assetID = item.AssetID; 1903 assetID = item.AssetID;
1892 } 1904 }
1893 } 1905 }
1906 m_host.TaskInventory.LockItemsForRead(false);
1894 } 1907 }
1895 1908
1896 if (assetID == UUID.Zero) 1909 if (assetID == UUID.Zero)
@@ -2370,9 +2383,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2370 { 2383 {
2371 if (avatar.IsChildAgent == false) 2384 if (avatar.IsChildAgent == false)
2372 { 2385 {
2373 result.Add(avatar.UUID); 2386 result.Add(new LSL_Key(avatar.UUID.ToString()));
2374 result.Add(avatar.AbsolutePosition); 2387 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2375 result.Add(avatar.Name); 2388 result.Add(new LSL_String(avatar.Name));
2376 } 2389 }
2377 } 2390 }
2378 }); 2391 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index fefbb35..c4f90d2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
204 // Is the sensor type is AGENT and not SCRIPTED then include agents 204 // Is the sensor type is AGENT and not SCRIPTED then include agents
205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0)
206 { 206 {
207 sensedEntities.AddRange(doAgentSensor(ts)); 207 sensedEntities.AddRange(doAgentSensor(ts));
208 } 208 }
209 209
210 // If SCRIPTED or PASSIVE or ACTIVE check objects 210 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -301,7 +301,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
301 float dy; 301 float dy;
302 float dz; 302 float dz;
303 303
304 Quaternion q = SensePoint.RotationOffset; 304// Quaternion q = SensePoint.RotationOffset;
305 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
305 if (SensePoint.ParentGroup.RootPart.IsAttachment) 306 if (SensePoint.ParentGroup.RootPart.IsAttachment)
306 { 307 {
307 // In attachments, the sensor cone always orients with the 308 // In attachments, the sensor cone always orients with the
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // in mouselook. 310 // in mouselook.
310 311
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -422,6 +424,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
422 SceneObjectPart SensePoint = ts.host; 424 SceneObjectPart SensePoint = ts.host;
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 425 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 Quaternion q = SensePoint.RotationOffset; 426 Quaternion q = SensePoint.RotationOffset;
427 if (SensePoint.ParentGroup.RootPart.IsAttachment)
428 {
429 // In attachments, the sensor cone always orients with the
430 // avatar rotation. This may include a nonzero elevation if
431 // in mouselook.
432
433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
434 fromRegionPos = avatar.AbsolutePosition;
435 q = avatar.Rotation;
436 }
425 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 437 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
426 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 438 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
427 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 439 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 561e3b3..bae7d4b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -398,6 +398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
398 LSL_Vector llWind(LSL_Vector offset); 398 LSL_Vector llWind(LSL_Vector offset);
399 LSL_String llXorBase64Strings(string str1, string str2); 399 LSL_String llXorBase64Strings(string str1, string str2);
400 LSL_String llXorBase64StringsCorrect(string str1, string str2); 400 LSL_String llXorBase64StringsCorrect(string str1, string str2);
401 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
401 402
402 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 403 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
403 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 404 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 63007c6..c08ad3b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index b3c4d95..c31e5d3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -279,6 +279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 279 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
280 public const int CHANGED_MEDIA = 2048; 280 public const int CHANGED_MEDIA = 2048;
281 public const int CHANGED_ANIMATION = 16384; 281 public const int CHANGED_ANIMATION = 16384;
282 public const int CHANGED_POSITION = 32768;
282 public const int TYPE_INVALID = 0; 283 public const int TYPE_INVALID = 0;
283 public const int TYPE_INTEGER = 1; 284 public const int TYPE_INTEGER = 1;
284 public const int TYPE_FLOAT = 2; 285 public const int TYPE_FLOAT = 2;
@@ -372,6 +373,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
372 public const int PRIM_SCULPT_TYPE_TORUS = 2; 373 public const int PRIM_SCULPT_TYPE_TORUS = 2;
373 public const int PRIM_SCULPT_TYPE_PLANE = 3; 374 public const int PRIM_SCULPT_TYPE_PLANE = 3;
374 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 375 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
376 public const int PRIM_SCULPT_FLAG_INVERT = 64;
377 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
375 378
376 public const int MASK_BASE = 0; 379 public const int MASK_BASE = 0;
377 public const int MASK_OWNER = 1; 380 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 451163f..7c26824 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -309,6 +310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
309 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 310 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
310 } 311 }
311 312
313 [DebuggerNonUserCode]
312 public void llDie() 314 public void llDie()
313 { 315 {
314 m_LSL_Functions.llDie(); 316 m_LSL_Functions.llDie();
@@ -1847,5 +1849,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1847 { 1849 {
1848 return m_LSL_Functions.llClearPrimMedia(face); 1850 return m_LSL_Functions.llClearPrimMedia(face);
1849 } 1851 }
1852
1853 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1854 {
1855 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1856 }
1850 } 1857 }
1851} 1858}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);