aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs1876
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs1011
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs53
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
6 files changed, 1801 insertions, 1204 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 dc43e45..1e2e0c8 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)
@@ -282,40 +340,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 protected UUID InventorySelf() 340 protected UUID InventorySelf()
283 { 341 {
284 UUID invItemID = new UUID(); 342 UUID invItemID = new UUID();
285 343 bool unlock = false;
286 lock (m_host.TaskInventory) 344 if (!m_host.TaskInventory.IsReadLockedByMe())
287 { 345 {
288 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 346 m_host.TaskInventory.LockItemsForRead(true);
347 unlock = true;
348 }
349 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
350 {
351 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
289 { 352 {
290 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 353 invItemID = inv.Key;
291 { 354 break;
292 invItemID = inv.Key;
293 break;
294 }
295 } 355 }
296 } 356 }
297 357 if (unlock)
358 {
359 m_host.TaskInventory.LockItemsForRead(false);
360 }
298 return invItemID; 361 return invItemID;
299 } 362 }
300 363
301 protected UUID InventoryKey(string name, int type) 364 protected UUID InventoryKey(string name, int type)
302 { 365 {
303 m_host.AddScriptLPS(1); 366 m_host.AddScriptLPS(1);
304 367 m_host.TaskInventory.LockItemsForRead(true);
305 lock (m_host.TaskInventory) 368
369 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
306 { 370 {
307 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 371 if (inv.Value.Name == name)
308 { 372 {
309 if (inv.Value.Name == name) 373 m_host.TaskInventory.LockItemsForRead(false);
374
375 if (inv.Value.Type != type)
310 { 376 {
311 if (inv.Value.Type != type) 377 return UUID.Zero;
312 return UUID.Zero;
313
314 return inv.Value.AssetID;
315 } 378 }
379
380 return inv.Value.AssetID;
316 } 381 }
317 } 382 }
318 383
384 m_host.TaskInventory.LockItemsForRead(false);
319 return UUID.Zero; 385 return UUID.Zero;
320 } 386 }
321 387
@@ -323,17 +389,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
323 { 389 {
324 m_host.AddScriptLPS(1); 390 m_host.AddScriptLPS(1);
325 391
326 lock (m_host.TaskInventory) 392
393 m_host.TaskInventory.LockItemsForRead(true);
394
395 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
327 { 396 {
328 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 397 if (inv.Value.Name == name)
329 { 398 {
330 if (inv.Value.Name == name) 399 m_host.TaskInventory.LockItemsForRead(false);
331 { 400 return inv.Value.AssetID;
332 return inv.Value.AssetID;
333 }
334 } 401 }
335 } 402 }
336 403
404 m_host.TaskInventory.LockItemsForRead(false);
405
406
337 return UUID.Zero; 407 return UUID.Zero;
338 } 408 }
339 409
@@ -475,26 +545,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
475 545
476 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 546 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
477 547
478 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 548 // Utility function for llRot2Euler
479 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
480 549
481 public LSL_Vector llRot2Euler(LSL_Rotation r) 550 // normalize an angle between -PI and PI (-180 to +180 degrees)
551 protected double NormalizeAngle(double angle)
552 {
553 if (angle > -Math.PI && angle < Math.PI)
554 return angle;
555
556 int numPis = (int)(Math.PI / angle);
557 double remainder = angle - Math.PI * numPis;
558 if (numPis % 2 == 1)
559 return Math.PI - angle;
560 return remainder;
561 }
562
563 public LSL_Vector llRot2Euler(LSL_Rotation q1)
482 { 564 {
483 m_host.AddScriptLPS(1); 565 m_host.AddScriptLPS(1);
484 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 566 LSL_Vector eul = new LSL_Vector();
485 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 567
486 double m = (t.x + t.y + t.z + t.s); 568 double sqw = q1.s*q1.s;
487 if (m == 0) return new LSL_Vector(); 569 double sqx = q1.x*q1.x;
488 double n = 2 * (r.y * r.s + r.x * r.z); 570 double sqy = q1.z*q1.z;
489 double p = m * m - n * n; 571 double sqz = q1.y*q1.y;
490 if (p > 0) 572 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
491 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 573 double test = q1.x*q1.z + q1.y*q1.s;
492 Math.Atan2(n, Math.Sqrt(p)), 574 if (test > 0.4999*unit) { // singularity at north pole
493 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 575 eul.z = 2 * Math.Atan2(q1.x,q1.s);
494 else if (n > 0) 576 eul.y = Math.PI/2;
495 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)); 577 eul.x = 0;
496 else 578 return eul;
497 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)); 579 }
580 if (test < -0.4999*unit) { // singularity at south pole
581 eul.z = -2 * Math.Atan2(q1.x,q1.s);
582 eul.y = -Math.PI/2;
583 eul.x = 0;
584 return eul;
585 }
586 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
587 eul.y = Math.Asin(2*test/unit);
588 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
589 return eul;
498 } 590 }
499 591
500 /* From wiki: 592 /* From wiki:
@@ -696,77 +788,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
696 { 788 {
697 //A and B should both be normalized 789 //A and B should both be normalized
698 m_host.AddScriptLPS(1); 790 m_host.AddScriptLPS(1);
699 LSL_Rotation rotBetween; 791 /* This method is more accurate than the SL one, and thus causes problems
700 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 792 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
701 // continue calculation. 793
702 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 794 double dotProduct = LSL_Vector.Dot(a, b);
795 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
796 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
797 double angle = Math.Acos(dotProduct / magProduct);
798 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
799 double s = Math.Sin(angle / 2);
800
801 double x = axis.x * s;
802 double y = axis.y * s;
803 double z = axis.z * s;
804 double w = Math.Cos(angle / 2);
805
806 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
807 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
808
809 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
810 */
811
812 // This method mimics the 180 errors found in SL
813 // See www.euclideanspace.com... angleBetween
814 LSL_Vector vec_a = a;
815 LSL_Vector vec_b = b;
816
817 // Eliminate zero length
818 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
819 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
820 if (vec_a_mag < 0.00001 ||
821 vec_b_mag < 0.00001)
703 { 822 {
704 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 823 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
705 } 824 }
706 else 825
826 // Normalize
827 vec_a = llVecNorm(vec_a);
828 vec_b = llVecNorm(vec_b);
829
830 // Calculate axis and rotation angle
831 LSL_Vector axis = vec_a % vec_b;
832 LSL_Float cos_theta = vec_a * vec_b;
833
834 // Check if parallel
835 if (cos_theta > 0.99999)
707 { 836 {
708 a = LSL_Vector.Norm(a); 837 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
709 b = LSL_Vector.Norm(b); 838 }
710 double dotProduct = LSL_Vector.Dot(a, b); 839
711 // There are two degenerate cases possible. These are for vectors 180 or 840 // Check if anti-parallel
712 // 0 degrees apart. These have to be detected and handled individually. 841 else if (cos_theta < -0.99999)
713 // 842 {
714 // Check for vectors 180 degrees apart. 843 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
715 // A dot product of -1 would mean the angle between vectors is 180 degrees. 844 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
716 if (dotProduct < -0.9999999f) 845 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
717 { 846 }
718 // First assume X axis is orthogonal to the vectors. 847 else // other rotation
719 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 848 {
720 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 849 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
721 // Check for near zero vector. A very small non-zero number here will create 850 axis = llVecNorm(axis);
722 // a rotation in an undesired direction. 851 double x, y, z, s, t;
723 if (LSL_Vector.Mag(orthoVector) > 0.0001) 852 s = Math.Cos(theta);
724 { 853 t = Math.Sin(theta);
725 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 854 x = axis.x * t;
726 } 855 y = axis.y * t;
727 // If the magnitude of the vector was near zero, then assume the X axis is not 856 z = axis.z * t;
728 // orthogonal and use the Z axis instead. 857 return new LSL_Rotation(x,y,z,s);
729 else
730 {
731 // Set 180 z rotation.
732 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
733 }
734 }
735 // Check for parallel vectors.
736 // A dot product of 1 would mean the angle between vectors is 0 degrees.
737 else if (dotProduct > 0.9999999f)
738 {
739 // Set zero rotation.
740 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
741 }
742 else
743 {
744 // All special checks have been performed so get the axis of rotation.
745 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
746 // Quarternion s value is the length of the unit vector + dot product.
747 double qs = 1.0 + dotProduct;
748 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
749 // Normalize the rotation.
750 double mag = LSL_Rotation.Mag(rotBetween);
751 // We shouldn't have to worry about a divide by zero here. The qs value will be
752 // non-zero because we already know if we're here, then the dotProduct is not -1 so
753 // qs will not be zero. Also, we've already handled the input vectors being zero so the
754 // crossProduct vector should also not be zero.
755 rotBetween.x = rotBetween.x / mag;
756 rotBetween.y = rotBetween.y / mag;
757 rotBetween.z = rotBetween.z / mag;
758 rotBetween.s = rotBetween.s / mag;
759 // Check for undefined values and set zero rotation if any found. This code might not actually be required
760 // any longer since zero vectors are checked for at the top.
761 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
762 {
763 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
764 }
765 }
766 } 858 }
767 return rotBetween;
768 } 859 }
769 860
770 public void llWhisper(int channelID, string text) 861 public void llWhisper(int channelID, string text)
771 { 862 {
772 m_host.AddScriptLPS(1); 863 m_host.AddScriptLPS(1);
@@ -1090,10 +1181,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1090 return detectedParams.TouchUV; 1181 return detectedParams.TouchUV;
1091 } 1182 }
1092 1183
1184 [DebuggerNonUserCode]
1093 public virtual void llDie() 1185 public virtual void llDie()
1094 { 1186 {
1095 m_host.AddScriptLPS(1); 1187 m_host.AddScriptLPS(1);
1096 throw new SelfDeleteException(); 1188 if (!m_host.IsAttachment) throw new SelfDeleteException();
1097 } 1189 }
1098 1190
1099 public LSL_Float llGround(LSL_Vector offset) 1191 public LSL_Float llGround(LSL_Vector offset)
@@ -1166,6 +1258,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1166 1258
1167 public void llSetStatus(int status, int value) 1259 public void llSetStatus(int status, int value)
1168 { 1260 {
1261 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1262 return;
1169 m_host.AddScriptLPS(1); 1263 m_host.AddScriptLPS(1);
1170 1264
1171 int statusrotationaxis = 0; 1265 int statusrotationaxis = 0;
@@ -1395,6 +1489,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1395 { 1489 {
1396 m_host.AddScriptLPS(1); 1490 m_host.AddScriptLPS(1);
1397 1491
1492 SetColor(m_host, color, face);
1493 }
1494
1495 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1496 {
1497 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1498 return;
1499
1500 Primitive.TextureEntry tex = part.Shape.Textures;
1501 Color4 texcolor;
1502 if (face >= 0 && face < GetNumberOfSides(part))
1503 {
1504 texcolor = tex.CreateFace((uint)face).RGBA;
1505 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1506 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1507 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1508 tex.FaceTextures[face].RGBA = texcolor;
1509 part.UpdateTexture(tex);
1510 return;
1511 }
1512 else if (face == ScriptBaseClass.ALL_SIDES)
1513 {
1514 for (uint i = 0; i < GetNumberOfSides(part); i++)
1515 {
1516 if (tex.FaceTextures[i] != null)
1517 {
1518 texcolor = tex.FaceTextures[i].RGBA;
1519 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1520 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1521 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1522 tex.FaceTextures[i].RGBA = texcolor;
1523 }
1524 texcolor = tex.DefaultTexture.RGBA;
1525 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1526 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1527 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1528 tex.DefaultTexture.RGBA = texcolor;
1529 }
1530 part.UpdateTexture(tex);
1531 return;
1532 }
1533
1398 if (face == ScriptBaseClass.ALL_SIDES) 1534 if (face == ScriptBaseClass.ALL_SIDES)
1399 face = SceneObjectPart.ALL_SIDES; 1535 face = SceneObjectPart.ALL_SIDES;
1400 1536
@@ -1403,6 +1539,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1403 1539
1404 public void SetTexGen(SceneObjectPart part, int face,int style) 1540 public void SetTexGen(SceneObjectPart part, int face,int style)
1405 { 1541 {
1542 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1543 return;
1544
1406 Primitive.TextureEntry tex = part.Shape.Textures; 1545 Primitive.TextureEntry tex = part.Shape.Textures;
1407 MappingType textype; 1546 MappingType textype;
1408 textype = MappingType.Default; 1547 textype = MappingType.Default;
@@ -1433,6 +1572,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1433 1572
1434 public void SetGlow(SceneObjectPart part, int face, float glow) 1573 public void SetGlow(SceneObjectPart part, int face, float glow)
1435 { 1574 {
1575 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1576 return;
1577
1436 Primitive.TextureEntry tex = part.Shape.Textures; 1578 Primitive.TextureEntry tex = part.Shape.Textures;
1437 if (face >= 0 && face < GetNumberOfSides(part)) 1579 if (face >= 0 && face < GetNumberOfSides(part))
1438 { 1580 {
@@ -1458,6 +1600,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1458 1600
1459 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1601 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1460 { 1602 {
1603 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1604 return;
1461 1605
1462 Shininess sval = new Shininess(); 1606 Shininess sval = new Shininess();
1463 1607
@@ -1508,6 +1652,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1508 1652
1509 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1653 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1510 { 1654 {
1655 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1656 return;
1657
1511 Primitive.TextureEntry tex = part.Shape.Textures; 1658 Primitive.TextureEntry tex = part.Shape.Textures;
1512 if (face >= 0 && face < GetNumberOfSides(part)) 1659 if (face >= 0 && face < GetNumberOfSides(part))
1513 { 1660 {
@@ -1568,13 +1715,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1568 m_host.AddScriptLPS(1); 1715 m_host.AddScriptLPS(1);
1569 1716
1570 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1717 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1571 1718 if (parts.Count > 0)
1572 foreach (SceneObjectPart part in parts) 1719 {
1573 SetAlpha(part, alpha, face); 1720 try
1721 {
1722 parts[0].ParentGroup.areUpdatesSuspended = true;
1723 foreach (SceneObjectPart part in parts)
1724 SetAlpha(part, alpha, face);
1725 }
1726 finally
1727 {
1728 parts[0].ParentGroup.areUpdatesSuspended = false;
1729 }
1730 }
1574 } 1731 }
1575 1732
1576 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1733 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1577 { 1734 {
1735 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1736 return;
1737
1578 Primitive.TextureEntry tex = part.Shape.Textures; 1738 Primitive.TextureEntry tex = part.Shape.Textures;
1579 Color4 texcolor; 1739 Color4 texcolor;
1580 if (face >= 0 && face < GetNumberOfSides(part)) 1740 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1620,7 +1780,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1620 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1780 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1621 float wind, float tension, LSL_Vector Force) 1781 float wind, float tension, LSL_Vector Force)
1622 { 1782 {
1623 if (part == null) 1783 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1624 return; 1784 return;
1625 1785
1626 if (flexi) 1786 if (flexi)
@@ -1655,7 +1815,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1655 /// <param name="falloff"></param> 1815 /// <param name="falloff"></param>
1656 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1816 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1657 { 1817 {
1658 if (part == null) 1818 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1659 return; 1819 return;
1660 1820
1661 if (light) 1821 if (light)
@@ -1732,15 +1892,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1732 m_host.AddScriptLPS(1); 1892 m_host.AddScriptLPS(1);
1733 1893
1734 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1894 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1735 1895 if (parts.Count > 0)
1736 foreach (SceneObjectPart part in parts) 1896 {
1737 SetTexture(part, texture, face); 1897 try
1738 1898 {
1899 parts[0].ParentGroup.areUpdatesSuspended = true;
1900 foreach (SceneObjectPart part in parts)
1901 SetTexture(part, texture, face);
1902 }
1903 finally
1904 {
1905 parts[0].ParentGroup.areUpdatesSuspended = false;
1906 }
1907 }
1739 ScriptSleep(200); 1908 ScriptSleep(200);
1740 } 1909 }
1741 1910
1742 protected void SetTexture(SceneObjectPart part, string texture, int face) 1911 protected void SetTexture(SceneObjectPart part, string texture, int face)
1743 { 1912 {
1913 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1914 return;
1915
1744 UUID textureID=new UUID(); 1916 UUID textureID=new UUID();
1745 1917
1746 if (!UUID.TryParse(texture, out textureID)) 1918 if (!UUID.TryParse(texture, out textureID))
@@ -1786,6 +1958,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1786 1958
1787 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1959 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1788 { 1960 {
1961 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1962 return;
1963
1789 Primitive.TextureEntry tex = part.Shape.Textures; 1964 Primitive.TextureEntry tex = part.Shape.Textures;
1790 if (face >= 0 && face < GetNumberOfSides(part)) 1965 if (face >= 0 && face < GetNumberOfSides(part))
1791 { 1966 {
@@ -1822,6 +1997,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1822 1997
1823 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 1998 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1824 { 1999 {
2000 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2001 return;
2002
1825 Primitive.TextureEntry tex = part.Shape.Textures; 2003 Primitive.TextureEntry tex = part.Shape.Textures;
1826 if (face >= 0 && face < GetNumberOfSides(part)) 2004 if (face >= 0 && face < GetNumberOfSides(part))
1827 { 2005 {
@@ -1858,6 +2036,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1858 2036
1859 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2037 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1860 { 2038 {
2039 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2040 return;
2041
1861 Primitive.TextureEntry tex = part.Shape.Textures; 2042 Primitive.TextureEntry tex = part.Shape.Textures;
1862 if (face >= 0 && face < GetNumberOfSides(part)) 2043 if (face >= 0 && face < GetNumberOfSides(part))
1863 { 2044 {
@@ -1928,6 +2109,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1928 2109
1929 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2110 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1930 { 2111 {
2112 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2113 return;
2114
1931 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2115 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1932 LSL_Vector currentPos = GetPartLocalPos(part); 2116 LSL_Vector currentPos = GetPartLocalPos(part);
1933 2117
@@ -1944,7 +2128,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1944 } 2128 }
1945 else 2129 else
1946 { 2130 {
1947 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2131 LSL_Vector rel_vec = SetPosAdjust(new LSL_Vector(part.OffsetPosition.X, part.OffsetPosition.Y, part.OffsetPosition.Z), targetPos);
1948 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z); 2132 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1949 SceneObjectGroup parent = part.ParentGroup; 2133 SceneObjectGroup parent = part.ParentGroup;
1950 parent.HasGroupChanged = true; 2134 parent.HasGroupChanged = true;
@@ -2018,6 +2202,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2018 2202
2019 protected void SetRot(SceneObjectPart part, Quaternion rot) 2203 protected void SetRot(SceneObjectPart part, Quaternion rot)
2020 { 2204 {
2205 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2206 return;
2207
2021 part.UpdateRotation(rot); 2208 part.UpdateRotation(rot);
2022 // Update rotation does not move the object in the physics scene if it's a linkset. 2209 // Update rotation does not move the object in the physics scene if it's a linkset.
2023 2210
@@ -2637,12 +2824,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2637 2824
2638 m_host.AddScriptLPS(1); 2825 m_host.AddScriptLPS(1);
2639 2826
2827 m_host.TaskInventory.LockItemsForRead(true);
2640 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2828 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2641 2829 m_host.TaskInventory.LockItemsForRead(false);
2642 lock (m_host.TaskInventory)
2643 {
2644 item = m_host.TaskInventory[invItemID];
2645 }
2646 2830
2647 if (item.PermsGranter == UUID.Zero) 2831 if (item.PermsGranter == UUID.Zero)
2648 return 0; 2832 return 0;
@@ -2717,6 +2901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2717 if (dist > m_ScriptDistanceFactor * 10.0f) 2901 if (dist > m_ScriptDistanceFactor * 10.0f)
2718 return; 2902 return;
2719 2903
2904 //Clone is thread-safe
2720 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2905 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2721 2906
2722 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2779,6 +2964,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2779 2964
2780 public void llLookAt(LSL_Vector target, double strength, double damping) 2965 public void llLookAt(LSL_Vector target, double strength, double damping)
2781 { 2966 {
2967 /*
2782 m_host.AddScriptLPS(1); 2968 m_host.AddScriptLPS(1);
2783 // Determine where we are looking from 2969 // Determine where we are looking from
2784 LSL_Vector from = llGetPos(); 2970 LSL_Vector from = llGetPos();
@@ -2798,10 +2984,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2798 // the angles of rotation in radians into rotation value 2984 // the angles of rotation in radians into rotation value
2799 2985
2800 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2986 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2801 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2987
2802 m_host.startLookAt(rotation, (float)damping, (float)strength); 2988 // This would only work if your physics system contains an APID controller:
2989 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
2990 // m_host.startLookAt(rotation, (float)damping, (float)strength);
2991
2803 // Orient the object to the angle calculated 2992 // Orient the object to the angle calculated
2804 //llSetRot(rot); 2993 llSetRot(rot);
2994 */
2995
2996 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
2997 //There's probably a smarter way of doing this, my rotation math-fu is weak.
2998 // http://bugs.meta7.com/view.php?id=28
2999 // - Tom
3000
3001 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3002 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3003
3004 }
3005
3006 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3007 {
3008 m_host.AddScriptLPS(1);
3009// NotImplemented("llRotLookAt");
3010 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3011
2805 } 3012 }
2806 3013
2807 public void llStopLookAt() 3014 public void llStopLookAt()
@@ -2850,13 +3057,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2850 { 3057 {
2851 TaskInventoryItem item; 3058 TaskInventoryItem item;
2852 3059
2853 lock (m_host.TaskInventory) 3060 m_host.TaskInventory.LockItemsForRead(true);
3061 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2854 { 3062 {
2855 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3063 m_host.TaskInventory.LockItemsForRead(false);
2856 return; 3064 return;
2857 else 3065 }
2858 item = m_host.TaskInventory[InventorySelf()]; 3066 else
3067 {
3068 item = m_host.TaskInventory[InventorySelf()];
2859 } 3069 }
3070 m_host.TaskInventory.LockItemsForRead(false);
2860 3071
2861 if (item.PermsGranter != UUID.Zero) 3072 if (item.PermsGranter != UUID.Zero)
2862 { 3073 {
@@ -2878,13 +3089,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2878 { 3089 {
2879 TaskInventoryItem item; 3090 TaskInventoryItem item;
2880 3091
3092 m_host.TaskInventory.LockItemsForRead(true);
2881 lock (m_host.TaskInventory) 3093 lock (m_host.TaskInventory)
2882 { 3094 {
3095
2883 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3096 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3097 {
3098 m_host.TaskInventory.LockItemsForRead(false);
2884 return; 3099 return;
3100 }
2885 else 3101 else
3102 {
2886 item = m_host.TaskInventory[InventorySelf()]; 3103 item = m_host.TaskInventory[InventorySelf()];
3104 }
2887 } 3105 }
3106 m_host.TaskInventory.LockItemsForRead(false);
2888 3107
2889 m_host.AddScriptLPS(1); 3108 m_host.AddScriptLPS(1);
2890 3109
@@ -2916,19 +3135,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3135 {
2917 m_host.AddScriptLPS(1); 3136 m_host.AddScriptLPS(1);
2918 3137
2919 if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2920 return;
2921
2922 TaskInventoryItem item; 3138 TaskInventoryItem item;
2923 3139
2924 lock (m_host.TaskInventory) 3140 m_host.TaskInventory.LockItemsForRead(true);
3141
3142 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2925 { 3143 {
2926 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3144 m_host.TaskInventory.LockItemsForRead(false);
2927 return; 3145 return;
2928 else 3146 }
2929 item = m_host.TaskInventory[InventorySelf()]; 3147 else
3148 {
3149 item = m_host.TaskInventory[InventorySelf()];
2930 } 3150 }
2931 3151
3152 m_host.TaskInventory.LockItemsForRead(false);
3153
2932 if (item.PermsGranter != m_host.OwnerID) 3154 if (item.PermsGranter != m_host.OwnerID)
2933 return; 3155 return;
2934 3156
@@ -2938,10 +3160,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2938 3160
2939 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3161 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2940 3162
2941 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3163 grp.AttachToAgent(m_host.OwnerID, (uint)attachment, Vector3.Zero, false);
2942 if (attachmentsModule != null)
2943 attachmentsModule.AttachObject(presence.ControllingClient,
2944 grp, (uint)attachment, false);
2945 } 3164 }
2946 } 3165 }
2947 3166
@@ -2954,13 +3173,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2954 3173
2955 TaskInventoryItem item; 3174 TaskInventoryItem item;
2956 3175
2957 lock (m_host.TaskInventory) 3176 m_host.TaskInventory.LockItemsForRead(true);
3177
3178 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2958 { 3179 {
2959 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3180 m_host.TaskInventory.LockItemsForRead(false);
2960 return; 3181 return;
2961 else 3182 }
2962 item = m_host.TaskInventory[InventorySelf()]; 3183 else
3184 {
3185 item = m_host.TaskInventory[InventorySelf()];
2963 } 3186 }
3187 m_host.TaskInventory.LockItemsForRead(false);
3188
2964 3189
2965 if (item.PermsGranter != m_host.OwnerID) 3190 if (item.PermsGranter != m_host.OwnerID)
2966 return; 3191 return;
@@ -2999,6 +3224,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2999 3224
3000 public void llInstantMessage(string user, string message) 3225 public void llInstantMessage(string user, string message)
3001 { 3226 {
3227 UUID result;
3228 if (!UUID.TryParse(user, out result))
3229 {
3230 if (!m_debuggerSafe)
3231 {
3232 throw new Exception(String.Format("An invalid key of '{0} was passed to llInstantMessage", user));
3233 }
3234 return;
3235 }
3236
3237
3002 m_host.AddScriptLPS(1); 3238 m_host.AddScriptLPS(1);
3003 3239
3004 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3240 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3013,14 +3249,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3013 UUID friendTransactionID = UUID.Random(); 3249 UUID friendTransactionID = UUID.Random();
3014 3250
3015 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3251 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3016 3252
3017 GridInstantMessage msg = new GridInstantMessage(); 3253 GridInstantMessage msg = new GridInstantMessage();
3018 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3254 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3019 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3255 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3020 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3256 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3021// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3257// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3022// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3258// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3023 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3259 DateTime dt = DateTime.UtcNow;
3260
3261 // Ticks from UtcNow, but make it look like local. Evil, huh?
3262 dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3263
3264 try
3265 {
3266 // Convert that to the PST timezone
3267 TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3268 dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3269 }
3270 catch
3271 {
3272 // No logging here, as it could be VERY spammy
3273 }
3274
3275 // And make it look local again to fool the unix time util
3276 dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3277
3278 msg.timestamp = (uint)Util.ToUnixTime(dt);
3279
3024 //if (client != null) 3280 //if (client != null)
3025 //{ 3281 //{
3026 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3282 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3034,13 +3290,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3034 msg.message = message.Substring(0, 1024); 3290 msg.message = message.Substring(0, 1024);
3035 else 3291 else
3036 msg.message = message; 3292 msg.message = message;
3037 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3293 msg.dialog = (byte)19; // MessageFromObject
3038 msg.fromGroup = false;// fromGroup; 3294 msg.fromGroup = false;// fromGroup;
3039 msg.offline = (byte)0; //offline; 3295 msg.offline = (byte)0; //offline;
3040 msg.ParentEstateID = 0; //ParentEstateID; 3296 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3041 msg.Position = Vector3.Zero;// new Vector3(m_host.AbsolutePosition); 3297 msg.Position = new Vector3(m_host.AbsolutePosition);
3042 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3298 msg.RegionID = World.RegionInfo.RegionID.Guid;
3043 msg.binaryBucket = new byte[0];// binaryBucket; 3299 msg.binaryBucket = Util.StringToBytes256(m_host.OwnerID.ToString());
3044 3300
3045 if (m_TransferModule != null) 3301 if (m_TransferModule != null)
3046 { 3302 {
@@ -3060,7 +3316,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3060 } 3316 }
3061 3317
3062 emailModule.SendEmail(m_host.UUID, address, subject, message); 3318 emailModule.SendEmail(m_host.UUID, address, subject, message);
3063 ScriptSleep(20000); 3319 ScriptSleep(15000);
3064 } 3320 }
3065 3321
3066 public void llGetNextEmail(string address, string subject) 3322 public void llGetNextEmail(string address, string subject)
@@ -3162,13 +3418,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3162 m_host.AddScriptLPS(1); 3418 m_host.AddScriptLPS(1);
3163 } 3419 }
3164 3420
3165 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3166 {
3167 m_host.AddScriptLPS(1);
3168 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3169 m_host.RotLookAt(rot, (float)strength, (float)damping);
3170 }
3171
3172 public LSL_Integer llStringLength(string str) 3421 public LSL_Integer llStringLength(string str)
3173 { 3422 {
3174 m_host.AddScriptLPS(1); 3423 m_host.AddScriptLPS(1);
@@ -3192,14 +3441,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3192 3441
3193 TaskInventoryItem item; 3442 TaskInventoryItem item;
3194 3443
3195 lock (m_host.TaskInventory) 3444 m_host.TaskInventory.LockItemsForRead(true);
3445 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3196 { 3446 {
3197 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3447 m_host.TaskInventory.LockItemsForRead(false);
3198 return; 3448 return;
3199 else
3200 item = m_host.TaskInventory[InventorySelf()];
3201 } 3449 }
3202 3450 else
3451 {
3452 item = m_host.TaskInventory[InventorySelf()];
3453 }
3454 m_host.TaskInventory.LockItemsForRead(false);
3203 if (item.PermsGranter == UUID.Zero) 3455 if (item.PermsGranter == UUID.Zero)
3204 return; 3456 return;
3205 3457
@@ -3229,13 +3481,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3229 3481
3230 TaskInventoryItem item; 3482 TaskInventoryItem item;
3231 3483
3232 lock (m_host.TaskInventory) 3484 m_host.TaskInventory.LockItemsForRead(true);
3485 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3233 { 3486 {
3234 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3487 m_host.TaskInventory.LockItemsForRead(false);
3235 return; 3488 return;
3236 else 3489 }
3237 item = m_host.TaskInventory[InventorySelf()]; 3490 else
3491 {
3492 item = m_host.TaskInventory[InventorySelf()];
3238 } 3493 }
3494 m_host.TaskInventory.LockItemsForRead(false);
3495
3239 3496
3240 if (item.PermsGranter == UUID.Zero) 3497 if (item.PermsGranter == UUID.Zero)
3241 return; 3498 return;
@@ -3306,10 +3563,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3306 3563
3307 TaskInventoryItem item; 3564 TaskInventoryItem item;
3308 3565
3309 lock (m_host.TaskInventory) 3566
3567 m_host.TaskInventory.LockItemsForRead(true);
3568 if (!m_host.TaskInventory.ContainsKey(invItemID))
3569 {
3570 m_host.TaskInventory.LockItemsForRead(false);
3571 return;
3572 }
3573 else
3310 { 3574 {
3311 item = m_host.TaskInventory[invItemID]; 3575 item = m_host.TaskInventory[invItemID];
3312 } 3576 }
3577 m_host.TaskInventory.LockItemsForRead(false);
3313 3578
3314 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3579 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3315 { 3580 {
@@ -3341,11 +3606,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3341 3606
3342 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3607 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3343 { 3608 {
3344 lock (m_host.TaskInventory) 3609 m_host.TaskInventory.LockItemsForWrite(true);
3345 { 3610 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3346 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3611 m_host.TaskInventory[invItemID].PermsMask = perm;
3347 m_host.TaskInventory[invItemID].PermsMask = perm; 3612 m_host.TaskInventory.LockItemsForWrite(false);
3348 }
3349 3613
3350 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3614 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3351 "run_time_permissions", new Object[] { 3615 "run_time_permissions", new Object[] {
@@ -3365,11 +3629,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3365 3629
3366 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3630 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3367 { 3631 {
3368 lock (m_host.TaskInventory) 3632 m_host.TaskInventory.LockItemsForWrite(true);
3369 { 3633 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3370 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3634 m_host.TaskInventory[invItemID].PermsMask = perm;
3371 m_host.TaskInventory[invItemID].PermsMask = perm; 3635 m_host.TaskInventory.LockItemsForWrite(false);
3372 }
3373 3636
3374 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3637 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3375 "run_time_permissions", new Object[] { 3638 "run_time_permissions", new Object[] {
@@ -3390,11 +3653,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3390 3653
3391 if (!m_waitingForScriptAnswer) 3654 if (!m_waitingForScriptAnswer)
3392 { 3655 {
3393 lock (m_host.TaskInventory) 3656 m_host.TaskInventory.LockItemsForWrite(true);
3394 { 3657 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3395 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3658 m_host.TaskInventory[invItemID].PermsMask = 0;
3396 m_host.TaskInventory[invItemID].PermsMask = 0; 3659 m_host.TaskInventory.LockItemsForWrite(false);
3397 }
3398 3660
3399 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3661 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3400 m_waitingForScriptAnswer=true; 3662 m_waitingForScriptAnswer=true;
@@ -3429,10 +3691,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3691 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3430 llReleaseControls(); 3692 llReleaseControls();
3431 3693
3432 lock (m_host.TaskInventory) 3694
3433 { 3695 m_host.TaskInventory.LockItemsForWrite(true);
3434 m_host.TaskInventory[invItemID].PermsMask = answer; 3696 m_host.TaskInventory[invItemID].PermsMask = answer;
3435 } 3697 m_host.TaskInventory.LockItemsForWrite(false);
3698
3436 3699
3437 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3700 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3438 "run_time_permissions", new Object[] { 3701 "run_time_permissions", new Object[] {
@@ -3444,16 +3707,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3444 { 3707 {
3445 m_host.AddScriptLPS(1); 3708 m_host.AddScriptLPS(1);
3446 3709
3447 lock (m_host.TaskInventory) 3710 m_host.TaskInventory.LockItemsForRead(true);
3711
3712 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3448 { 3713 {
3449 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3714 if (item.Type == 10 && item.ItemID == m_itemID)
3450 { 3715 {
3451 if (item.Type == 10 && item.ItemID == m_itemID) 3716 m_host.TaskInventory.LockItemsForRead(false);
3452 { 3717 return item.PermsGranter.ToString();
3453 return item.PermsGranter.ToString();
3454 }
3455 } 3718 }
3456 } 3719 }
3720 m_host.TaskInventory.LockItemsForRead(false);
3457 3721
3458 return UUID.Zero.ToString(); 3722 return UUID.Zero.ToString();
3459 } 3723 }
@@ -3462,19 +3726,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3462 { 3726 {
3463 m_host.AddScriptLPS(1); 3727 m_host.AddScriptLPS(1);
3464 3728
3465 lock (m_host.TaskInventory) 3729 m_host.TaskInventory.LockItemsForRead(true);
3730
3731 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3466 { 3732 {
3467 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3733 if (item.Type == 10 && item.ItemID == m_itemID)
3468 { 3734 {
3469 if (item.Type == 10 && item.ItemID == m_itemID) 3735 int perms = item.PermsMask;
3470 { 3736 if (m_automaticLinkPermission)
3471 int perms = item.PermsMask; 3737 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3472 if (m_automaticLinkPermission) 3738 m_host.TaskInventory.LockItemsForRead(false);
3473 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3739 return perms;
3474 return perms;
3475 }
3476 } 3740 }
3477 } 3741 }
3742 m_host.TaskInventory.LockItemsForRead(false);
3478 3743
3479 return 0; 3744 return 0;
3480 } 3745 }
@@ -3496,9 +3761,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3496 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3761 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3497 { 3762 {
3498 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3763 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3499 3764 if (parts.Count > 0)
3500 foreach (SceneObjectPart part in parts) 3765 {
3501 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3766 try
3767 {
3768 parts[0].ParentGroup.areUpdatesSuspended = true;
3769 foreach (SceneObjectPart part in parts)
3770 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3771 }
3772 finally
3773 {
3774 parts[0].ParentGroup.areUpdatesSuspended = false;
3775 }
3776 }
3502 } 3777 }
3503 3778
3504 public void llCreateLink(string target, int parent) 3779 public void llCreateLink(string target, int parent)
@@ -3511,11 +3786,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3511 return; 3786 return;
3512 3787
3513 TaskInventoryItem item; 3788 TaskInventoryItem item;
3514 lock (m_host.TaskInventory) 3789 m_host.TaskInventory.LockItemsForRead(true);
3515 { 3790 item = m_host.TaskInventory[invItemID];
3516 item = m_host.TaskInventory[invItemID]; 3791 m_host.TaskInventory.LockItemsForRead(false);
3517 } 3792
3518
3519 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3793 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3520 && !m_automaticLinkPermission) 3794 && !m_automaticLinkPermission)
3521 { 3795 {
@@ -3568,16 +3842,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3568 m_host.AddScriptLPS(1); 3842 m_host.AddScriptLPS(1);
3569 UUID invItemID = InventorySelf(); 3843 UUID invItemID = InventorySelf();
3570 3844
3571 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForRead(true);
3572 {
3573 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3846 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3574 && !m_automaticLinkPermission) 3847 && !m_automaticLinkPermission)
3575 { 3848 {
3576 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3849 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3850 m_host.TaskInventory.LockItemsForRead(false);
3577 return; 3851 return;
3578 } 3852 }
3579 } 3853 m_host.TaskInventory.LockItemsForRead(false);
3580 3854
3581 if (linknum < ScriptBaseClass.LINK_THIS) 3855 if (linknum < ScriptBaseClass.LINK_THIS)
3582 return; 3856 return;
3583 3857
@@ -3616,10 +3890,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3616 // Restructuring Multiple Prims. 3890 // Restructuring Multiple Prims.
3617 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3891 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3618 parts.Remove(parentPrim.RootPart); 3892 parts.Remove(parentPrim.RootPart);
3619 foreach (SceneObjectPart part in parts) 3893 if (parts.Count > 0)
3620 { 3894 {
3621 parentPrim.DelinkFromGroup(part.LocalId, true); 3895 try
3896 {
3897 parts[0].ParentGroup.areUpdatesSuspended = true;
3898 foreach (SceneObjectPart part in parts)
3899 {
3900 parentPrim.DelinkFromGroup(part.LocalId, true);
3901 }
3902 }
3903 finally
3904 {
3905 parts[0].ParentGroup.areUpdatesSuspended = false;
3906 }
3622 } 3907 }
3908
3623 parentPrim.HasGroupChanged = true; 3909 parentPrim.HasGroupChanged = true;
3624 parentPrim.ScheduleGroupForFullUpdate(); 3910 parentPrim.ScheduleGroupForFullUpdate();
3625 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3911 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3628,11 +3914,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3628 { 3914 {
3629 SceneObjectPart newRoot = parts[0]; 3915 SceneObjectPart newRoot = parts[0];
3630 parts.Remove(newRoot); 3916 parts.Remove(newRoot);
3631 foreach (SceneObjectPart part in parts) 3917
3918 try
3632 { 3919 {
3633 part.UpdateFlag = 0; 3920 parts[0].ParentGroup.areUpdatesSuspended = true;
3634 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3921 foreach (SceneObjectPart part in parts)
3922 {
3923 part.UpdateFlag = 0;
3924 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3925 }
3635 } 3926 }
3927 finally
3928 {
3929 parts[0].ParentGroup.areUpdatesSuspended = false;
3930 }
3931
3932
3636 newRoot.ParentGroup.HasGroupChanged = true; 3933 newRoot.ParentGroup.HasGroupChanged = true;
3637 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 3934 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3638 } 3935 }
@@ -3658,11 +3955,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3658 3955
3659 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values); 3956 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Children.Values);
3660 parts.Remove(parentPrim.RootPart); 3957 parts.Remove(parentPrim.RootPart);
3661 3958 if (parts.Count > 0)
3662 foreach (SceneObjectPart part in parts)
3663 { 3959 {
3664 parentPrim.DelinkFromGroup(part.LocalId, true); 3960 try
3665 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3961 {
3962 parts[0].ParentGroup.areUpdatesSuspended = true;
3963 foreach (SceneObjectPart part in parts)
3964 {
3965 parentPrim.DelinkFromGroup(part.LocalId, true);
3966 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
3967 }
3968 }
3969 finally
3970 {
3971 parts[0].ParentGroup.areUpdatesSuspended = false;
3972 }
3666 } 3973 }
3667 parentPrim.HasGroupChanged = true; 3974 parentPrim.HasGroupChanged = true;
3668 parentPrim.ScheduleGroupForFullUpdate(); 3975 parentPrim.ScheduleGroupForFullUpdate();
@@ -3678,6 +3985,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3678 } 3985 }
3679 else 3986 else
3680 { 3987 {
3988 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
3989 {
3990 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3991
3992 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3993 if (avatars.Count > linknum)
3994 {
3995 return avatars[linknum].UUID.ToString();
3996 }
3997 }
3681 return UUID.Zero.ToString(); 3998 return UUID.Zero.ToString();
3682 } 3999 }
3683 } 4000 }
@@ -3754,17 +4071,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 m_host.AddScriptLPS(1); 4071 m_host.AddScriptLPS(1);
3755 int count = 0; 4072 int count = 0;
3756 4073
3757 lock (m_host.TaskInventory) 4074 m_host.TaskInventory.LockItemsForRead(true);
4075 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3758 { 4076 {
3759 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4077 if (inv.Value.Type == type || type == -1)
3760 { 4078 {
3761 if (inv.Value.Type == type || type == -1) 4079 count = count + 1;
3762 {
3763 count = count + 1;
3764 }
3765 } 4080 }
3766 } 4081 }
3767 4082
4083 m_host.TaskInventory.LockItemsForRead(false);
3768 return count; 4084 return count;
3769 } 4085 }
3770 4086
@@ -3773,16 +4089,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3773 m_host.AddScriptLPS(1); 4089 m_host.AddScriptLPS(1);
3774 ArrayList keys = new ArrayList(); 4090 ArrayList keys = new ArrayList();
3775 4091
3776 lock (m_host.TaskInventory) 4092 m_host.TaskInventory.LockItemsForRead(true);
4093 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3777 { 4094 {
3778 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4095 if (inv.Value.Type == type || type == -1)
3779 { 4096 {
3780 if (inv.Value.Type == type || type == -1) 4097 keys.Add(inv.Value.Name);
3781 {
3782 keys.Add(inv.Value.Name);
3783 }
3784 } 4098 }
3785 } 4099 }
4100 m_host.TaskInventory.LockItemsForRead(false);
3786 4101
3787 if (keys.Count == 0) 4102 if (keys.Count == 0)
3788 { 4103 {
@@ -3819,20 +4134,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3819 } 4134 }
3820 4135
3821 // move the first object found with this inventory name 4136 // move the first object found with this inventory name
3822 lock (m_host.TaskInventory) 4137 m_host.TaskInventory.LockItemsForRead(true);
4138 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3823 { 4139 {
3824 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4140 if (inv.Value.Name == inventory)
3825 { 4141 {
3826 if (inv.Value.Name == inventory) 4142 found = true;
3827 { 4143 objId = inv.Key;
3828 found = true; 4144 assetType = inv.Value.Type;
3829 objId = inv.Key; 4145 objName = inv.Value.Name;
3830 assetType = inv.Value.Type; 4146 break;
3831 objName = inv.Value.Name;
3832 break;
3833 }
3834 } 4147 }
3835 } 4148 }
4149 m_host.TaskInventory.LockItemsForRead(false);
3836 4150
3837 if (!found) 4151 if (!found)
3838 { 4152 {
@@ -3840,9 +4154,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3840 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4154 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3841 } 4155 }
3842 4156
3843 // check if destination is an avatar 4157 // check if destination is an object
3844 if (World.GetScenePresence(destId) != null) 4158 if (World.GetSceneObjectPart(destId) != null)
4159 {
4160 // destination is an object
4161 World.MoveTaskInventoryItem(destId, m_host, objId);
4162 }
4163 else
3845 { 4164 {
4165 ScenePresence presence = World.GetScenePresence(destId);
4166
4167 if (presence == null)
4168 {
4169 UserAccount account =
4170 World.UserAccountService.GetUserAccount(
4171 World.RegionInfo.ScopeID,
4172 destId);
4173
4174 if (account == null)
4175 {
4176 llSay(0, "Can't find destination "+destId.ToString());
4177 return;
4178 }
4179 }
4180
3846 // destination is an avatar 4181 // destination is an avatar
3847 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4182 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3848 4183
@@ -3866,31 +4201,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3866 4201
3867 if (m_TransferModule != null) 4202 if (m_TransferModule != null)
3868 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4203 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4204
4205 //This delay should only occur when giving inventory to avatars.
4206 ScriptSleep(3000);
3869 } 4207 }
3870 else
3871 {
3872 // destination is an object
3873 World.MoveTaskInventoryItem(destId, m_host, objId);
3874 }
3875 ScriptSleep(3000);
3876 } 4208 }
3877 4209
4210 [DebuggerNonUserCode]
3878 public void llRemoveInventory(string name) 4211 public void llRemoveInventory(string name)
3879 { 4212 {
3880 m_host.AddScriptLPS(1); 4213 m_host.AddScriptLPS(1);
3881 4214
3882 lock (m_host.TaskInventory) 4215 List<TaskInventoryItem> inv;
4216 try
3883 { 4217 {
3884 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4218 m_host.TaskInventory.LockItemsForRead(true);
4219 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4220 }
4221 finally
4222 {
4223 m_host.TaskInventory.LockItemsForRead(false);
4224 }
4225 foreach (TaskInventoryItem item in inv)
4226 {
4227 if (item.Name == name)
3885 { 4228 {
3886 if (item.Name == name) 4229 if (item.ItemID == m_itemID)
3887 { 4230 throw new ScriptDeleteException();
3888 if (item.ItemID == m_itemID) 4231 else
3889 throw new ScriptDeleteException(); 4232 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3890 else 4233 return;
3891 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3892 return;
3893 }
3894 } 4234 }
3895 } 4235 }
3896 } 4236 }
@@ -3948,6 +4288,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3948 ce.time = Util.EnvironmentTickCount(); 4288 ce.time = Util.EnvironmentTickCount();
3949 ce.account = account; 4289 ce.account = account;
3950 ce.pinfo = pinfo; 4290 ce.pinfo = pinfo;
4291 m_userInfoCache[uuid] = ce;
3951 } 4292 }
3952 else 4293 else
3953 { 4294 {
@@ -4015,6 +4356,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4015 { 4356 {
4016 m_host.AddScriptLPS(1); 4357 m_host.AddScriptLPS(1);
4017 4358
4359 //Clone is thread safe
4018 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4360 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4019 4361
4020 foreach (TaskInventoryItem item in itemDictionary.Values) 4362 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4068,6 +4410,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4068 ScenePresence presence = World.GetScenePresence(agentId); 4410 ScenePresence presence = World.GetScenePresence(agentId);
4069 if (presence != null) 4411 if (presence != null)
4070 { 4412 {
4413 // agent must not be a god
4414 if (presence.GodLevel >= 200) return;
4415
4071 // agent must be over the owners land 4416 // agent must be over the owners land
4072 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4417 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4073 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4418 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4127,17 +4472,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4127 UUID soundId = UUID.Zero; 4472 UUID soundId = UUID.Zero;
4128 if (!UUID.TryParse(impact_sound, out soundId)) 4473 if (!UUID.TryParse(impact_sound, out soundId))
4129 { 4474 {
4130 lock (m_host.TaskInventory) 4475 m_host.TaskInventory.LockItemsForRead(true);
4476 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4131 { 4477 {
4132 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4478 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4133 { 4479 {
4134 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4480 soundId = item.AssetID;
4135 { 4481 break;
4136 soundId = item.AssetID;
4137 break;
4138 }
4139 } 4482 }
4140 } 4483 }
4484 m_host.TaskInventory.LockItemsForRead(false);
4141 } 4485 }
4142 m_host.CollisionSound = soundId; 4486 m_host.CollisionSound = soundId;
4143 m_host.CollisionSoundVolume = (float)impact_volume; 4487 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4183,6 +4527,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4183 UUID partItemID; 4527 UUID partItemID;
4184 foreach (SceneObjectPart part in parts) 4528 foreach (SceneObjectPart part in parts)
4185 { 4529 {
4530 //Clone is thread safe
4186 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4531 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4187 4532
4188 foreach (TaskInventoryItem item in itemsDictionary.Values) 4533 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4397,17 +4742,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4397 4742
4398 m_host.AddScriptLPS(1); 4743 m_host.AddScriptLPS(1);
4399 4744
4400 lock (m_host.TaskInventory) 4745 m_host.TaskInventory.LockItemsForRead(true);
4746 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4401 { 4747 {
4402 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4748 if (item.Type == 10 && item.ItemID == m_itemID)
4403 { 4749 {
4404 if (item.Type == 10 && item.ItemID == m_itemID) 4750 result = item.Name!=null?item.Name:String.Empty;
4405 { 4751 break;
4406 result = item.Name != null ? item.Name : String.Empty;
4407 break;
4408 }
4409 } 4752 }
4410 } 4753 }
4754 m_host.TaskInventory.LockItemsForRead(false);
4411 4755
4412 return result; 4756 return result;
4413 } 4757 }
@@ -4560,23 +4904,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4560 { 4904 {
4561 m_host.AddScriptLPS(1); 4905 m_host.AddScriptLPS(1);
4562 4906
4563 lock (m_host.TaskInventory) 4907 m_host.TaskInventory.LockItemsForRead(true);
4908 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4564 { 4909 {
4565 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4910 if (inv.Value.Name == name)
4566 { 4911 {
4567 if (inv.Value.Name == name) 4912 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4568 { 4913 {
4569 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 4914 m_host.TaskInventory.LockItemsForRead(false);
4570 { 4915 return inv.Value.AssetID.ToString();
4571 return inv.Value.AssetID.ToString(); 4916 }
4572 } 4917 else
4573 else 4918 {
4574 { 4919 m_host.TaskInventory.LockItemsForRead(false);
4575 return UUID.Zero.ToString(); 4920 return UUID.Zero.ToString();
4576 }
4577 } 4921 }
4578 } 4922 }
4579 } 4923 }
4924 m_host.TaskInventory.LockItemsForRead(false);
4580 4925
4581 return UUID.Zero.ToString(); 4926 return UUID.Zero.ToString();
4582 } 4927 }
@@ -4729,14 +5074,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4729 { 5074 {
4730 m_host.AddScriptLPS(1); 5075 m_host.AddScriptLPS(1);
4731 5076
4732 if (src == null) 5077 return src.Length;
4733 {
4734 return 0;
4735 }
4736 else
4737 {
4738 return src.Length;
4739 }
4740 } 5078 }
4741 5079
4742 public LSL_Integer llList2Integer(LSL_List src, int index) 5080 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4782,7 +5120,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4782 else if (src.Data[index] is LSL_Float) 5120 else if (src.Data[index] is LSL_Float)
4783 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5121 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4784 else if (src.Data[index] is LSL_String) 5122 else if (src.Data[index] is LSL_String)
4785 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5123 {
5124 string str = ((LSL_String) src.Data[index]).m_string;
5125 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5126 if (m != Match.Empty)
5127 {
5128 str = m.Value;
5129 double d = 0.0;
5130 if (!Double.TryParse(str, out d))
5131 return 0.0;
5132
5133 return d;
5134 }
5135 return 0.0;
5136 }
4786 return Convert.ToDouble(src.Data[index]); 5137 return Convert.ToDouble(src.Data[index]);
4787 } 5138 }
4788 catch (FormatException) 5139 catch (FormatException)
@@ -5467,7 +5818,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5467 public void llSetSoundQueueing(int queue) 5818 public void llSetSoundQueueing(int queue)
5468 { 5819 {
5469 m_host.AddScriptLPS(1); 5820 m_host.AddScriptLPS(1);
5470 NotImplemented("llSetSoundQueueing");
5471 } 5821 }
5472 5822
5473 public void llSetSoundRadius(double radius) 5823 public void llSetSoundRadius(double radius)
@@ -5512,10 +5862,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5512 m_host.AddScriptLPS(1); 5862 m_host.AddScriptLPS(1);
5513 5863
5514 List<SceneObjectPart> parts = GetLinkParts(linknumber); 5864 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5515 5865 if (parts.Count > 0)
5516 foreach (var part in parts)
5517 { 5866 {
5518 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 5867 try
5868 {
5869 parts[0].ParentGroup.areUpdatesSuspended = true;
5870 foreach (var part in parts)
5871 {
5872 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5873 }
5874 }
5875 finally
5876 {
5877 parts[0].ParentGroup.areUpdatesSuspended = false;
5878 }
5519 } 5879 }
5520 } 5880 }
5521 5881
@@ -5571,74 +5931,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5571 5931
5572 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers) 5932 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
5573 { 5933 {
5574 m_host.AddScriptLPS(1); 5934 return ParseString2List(str, separators, in_spacers, false);
5575 LSL_List ret = new LSL_List();
5576 LSL_List spacers = new LSL_List();
5577 if (in_spacers.Length > 0 && separators.Length > 0)
5578 {
5579 for (int i = 0; i < in_spacers.Length; i++)
5580 {
5581 object s = in_spacers.Data[i];
5582 for (int j = 0; j < separators.Length; j++)
5583 {
5584 if (separators.Data[j].ToString() == s.ToString())
5585 {
5586 s = null;
5587 break;
5588 }
5589 }
5590 if (s != null)
5591 {
5592 spacers.Add(s);
5593 }
5594 }
5595 }
5596 object[] delimiters = new object[separators.Length + spacers.Length];
5597 separators.Data.CopyTo(delimiters, 0);
5598 spacers.Data.CopyTo(delimiters, separators.Length);
5599 bool dfound = false;
5600 do
5601 {
5602 dfound = false;
5603 int cindex = -1;
5604 string cdeli = "";
5605 for (int i = 0; i < delimiters.Length; i++)
5606 {
5607 int index = str.IndexOf(delimiters[i].ToString());
5608 bool found = index != -1;
5609 if (found && String.Empty != delimiters[i].ToString())
5610 {
5611 if ((cindex > index) || (cindex == -1))
5612 {
5613 cindex = index;
5614 cdeli = delimiters[i].ToString();
5615 }
5616 dfound = dfound || found;
5617 }
5618 }
5619 if (cindex != -1)
5620 {
5621 if (cindex > 0)
5622 {
5623 ret.Add(new LSL_String(str.Substring(0, cindex)));
5624 }
5625 // Cannot use spacers.Contains() because spacers may be either type String or LSLString
5626 for (int j = 0; j < spacers.Length; j++)
5627 {
5628 if (spacers.Data[j].ToString() == cdeli)
5629 {
5630 ret.Add(new LSL_String(cdeli));
5631 break;
5632 }
5633 }
5634 str = str.Substring(cindex + cdeli.Length);
5635 }
5636 } while (dfound);
5637 if (str != "")
5638 {
5639 ret.Add(new LSL_String(str));
5640 }
5641 return ret;
5642 } 5935 }
5643 5936
5644 public LSL_Integer llOverMyLand(string id) 5937 public LSL_Integer llOverMyLand(string id)
@@ -5841,7 +6134,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5841 return m_host.ParentGroup.RootPart.AttachmentPoint; 6134 return m_host.ParentGroup.RootPart.AttachmentPoint;
5842 } 6135 }
5843 6136
5844 public LSL_Integer llGetFreeMemory() 6137 public virtual LSL_Integer llGetFreeMemory()
5845 { 6138 {
5846 m_host.AddScriptLPS(1); 6139 m_host.AddScriptLPS(1);
5847 // Make scripts designed for LSO happy 6140 // Make scripts designed for LSO happy
@@ -6152,14 +6445,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6152 6445
6153 protected UUID GetTaskInventoryItem(string name) 6446 protected UUID GetTaskInventoryItem(string name)
6154 { 6447 {
6155 lock (m_host.TaskInventory) 6448 m_host.TaskInventory.LockItemsForRead(true);
6449 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6156 { 6450 {
6157 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6451 if (inv.Value.Name == name)
6158 { 6452 {
6159 if (inv.Value.Name == name) 6453 m_host.TaskInventory.LockItemsForRead(false);
6160 return inv.Key; 6454 return inv.Key;
6161 } 6455 }
6162 } 6456 }
6457 m_host.TaskInventory.LockItemsForRead(false);
6163 6458
6164 return UUID.Zero; 6459 return UUID.Zero;
6165 } 6460 }
@@ -6487,22 +6782,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6487 } 6782 }
6488 6783
6489 // copy the first script found with this inventory name 6784 // copy the first script found with this inventory name
6490 lock (m_host.TaskInventory) 6785 m_host.TaskInventory.LockItemsForRead(true);
6786 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6491 { 6787 {
6492 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6788 if (inv.Value.Name == name)
6493 { 6789 {
6494 if (inv.Value.Name == name) 6790 // make sure the object is a script
6791 if (10 == inv.Value.Type)
6495 { 6792 {
6496 // make sure the object is a script 6793 found = true;
6497 if (10 == inv.Value.Type) 6794 srcId = inv.Key;
6498 { 6795 break;
6499 found = true;
6500 srcId = inv.Key;
6501 break;
6502 }
6503 } 6796 }
6504 } 6797 }
6505 } 6798 }
6799 m_host.TaskInventory.LockItemsForRead(false);
6506 6800
6507 if (!found) 6801 if (!found)
6508 { 6802 {
@@ -6586,6 +6880,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6586 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist) 6880 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist)
6587 { 6881 {
6588 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 6882 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6883 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6884 return shapeBlock;
6589 6885
6590 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 6886 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6591 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 6887 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6661,6 +6957,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6661 6957
6662 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge) 6958 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte fudge)
6663 { 6959 {
6960 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
6961 return;
6962
6664 ObjectShapePacket.ObjectDataBlock shapeBlock; 6963 ObjectShapePacket.ObjectDataBlock shapeBlock;
6665 6964
6666 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 6965 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6710,6 +7009,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6710 7009
6711 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge) 7010 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte fudge)
6712 { 7011 {
7012 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7013 return;
7014
6713 ObjectShapePacket.ObjectDataBlock shapeBlock; 7015 ObjectShapePacket.ObjectDataBlock shapeBlock;
6714 7016
6715 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7017 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6752,6 +7054,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6752 7054
6753 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) 7055 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)
6754 { 7056 {
7057 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7058 return;
7059
6755 ObjectShapePacket.ObjectDataBlock shapeBlock; 7060 ObjectShapePacket.ObjectDataBlock shapeBlock;
6756 7061
6757 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist); 7062 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist);
@@ -6878,6 +7183,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6878 7183
6879 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type) 7184 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type)
6880 { 7185 {
7186 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7187 return;
7188
6881 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7189 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6882 UUID sculptId; 7190 UUID sculptId;
6883 7191
@@ -6893,13 +7201,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6893 shapeBlock.PathScaleX = 100; 7201 shapeBlock.PathScaleX = 100;
6894 shapeBlock.PathScaleY = 150; 7202 shapeBlock.PathScaleY = 150;
6895 7203
6896 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7204 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6897 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7205 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6898 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7206 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6899 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7207 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6900 { 7208 {
6901 // default 7209 // default
6902 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7210 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
6903 } 7211 }
6904 7212
6905 // retain pathcurve 7213 // retain pathcurve
@@ -6916,23 +7224,83 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6916 SetPrimParams(m_host, rules); 7224 SetPrimParams(m_host, rules);
6917 } 7225 }
6918 7226
6919 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7227 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
6920 { 7228 {
6921 m_host.AddScriptLPS(1); 7229 m_host.AddScriptLPS(1);
6922 7230
6923 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7231 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7232 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7233 if (parts.Count>0)
7234 {
7235 try
7236 {
7237 parts[0].ParentGroup.areUpdatesSuspended = true;
7238 foreach (SceneObjectPart part in parts)
7239 SetPrimParams(part, rules);
7240 }
7241 finally
7242 {
7243 parts[0].ParentGroup.areUpdatesSuspended = false;
7244 }
7245 }
7246 if (avatars.Count > 0)
7247 {
7248 foreach (ScenePresence avatar in avatars)
7249 SetPrimParams(avatar, rules);
7250 }
7251 }
6924 7252
6925 foreach (SceneObjectPart part in parts) 7253 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
6926 SetPrimParams(part, rules); 7254 {
7255 llSetLinkPrimitiveParamsFast(linknumber, rules);
7256 ScriptSleep(200);
6927 } 7257 }
6928 7258
6929 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7259 protected void SetPrimParams(ScenePresence av, LSL_List rules)
6930 { 7260 {
6931 llSetLinkPrimitiveParams(linknumber, rules); 7261 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7262 //We only support PRIM_POSITION and PRIM_ROTATION
7263
7264 int idx = 0;
7265
7266 while (idx < rules.Length)
7267 {
7268 int code = rules.GetLSLIntegerItem(idx++);
7269
7270 int remain = rules.Length - idx;
7271
7272
7273
7274 switch (code)
7275 {
7276 case (int)ScriptBaseClass.PRIM_POSITION:
7277 if (remain < 1)
7278 return;
7279 LSL_Vector v;
7280 v = rules.GetVector3Item(idx++);
7281 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7282 av.SendFullUpdateToAllClients();
7283
7284 break;
7285
7286 case (int)ScriptBaseClass.PRIM_ROTATION:
7287 if (remain < 1)
7288 return;
7289 LSL_Rotation r;
7290 r = rules.GetQuaternionItem(idx++);
7291 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7292 av.SendFullUpdateToAllClients();
7293 break;
7294 }
7295 }
7296
6932 } 7297 }
6933 7298
6934 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7299 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
6935 { 7300 {
7301 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7302 return;
7303
6936 int idx = 0; 7304 int idx = 0;
6937 7305
6938 while (idx < rules.Length) 7306 while (idx < rules.Length)
@@ -7449,13 +7817,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7449 public LSL_Integer llGetNumberOfPrims() 7817 public LSL_Integer llGetNumberOfPrims()
7450 { 7818 {
7451 m_host.AddScriptLPS(1); 7819 m_host.AddScriptLPS(1);
7452 int avatarCount = 0; 7820 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7453 World.ForEachScenePresence(delegate(ScenePresence presence) 7821
7454 {
7455 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7456 avatarCount++;
7457 });
7458
7459 return m_host.ParentGroup.PrimCount + avatarCount; 7822 return m_host.ParentGroup.PrimCount + avatarCount;
7460 } 7823 }
7461 7824
@@ -7471,55 +7834,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7471 m_host.AddScriptLPS(1); 7834 m_host.AddScriptLPS(1);
7472 UUID objID = UUID.Zero; 7835 UUID objID = UUID.Zero;
7473 LSL_List result = new LSL_List(); 7836 LSL_List result = new LSL_List();
7837
7838 // If the ID is not valid, return null result
7474 if (!UUID.TryParse(obj, out objID)) 7839 if (!UUID.TryParse(obj, out objID))
7475 { 7840 {
7476 result.Add(new LSL_Vector()); 7841 result.Add(new LSL_Vector());
7477 result.Add(new LSL_Vector()); 7842 result.Add(new LSL_Vector());
7478 return result; 7843 return result;
7479 } 7844 }
7845
7846 // Check if this is an attached prim. If so, replace
7847 // the UUID with the avatar UUID and report it's bounding box
7848 SceneObjectPart part = World.GetSceneObjectPart(objID);
7849 if (part != null && part.ParentGroup.IsAttachment)
7850 objID = part.ParentGroup.RootPart.AttachedAvatar;
7851
7852 // Find out if this is an avatar ID. If so, return it's box
7480 ScenePresence presence = World.GetScenePresence(objID); 7853 ScenePresence presence = World.GetScenePresence(objID);
7481 if (presence != null) 7854 if (presence != null)
7482 { 7855 {
7483 if (presence.ParentID == 0) // not sat on an object 7856 // As per LSL Wiki, there is no difference between sitting
7857 // and standing avatar since server 1.36
7858 LSL_Vector lower;
7859 LSL_Vector upper;
7860 if (presence.Animator.Animations.DefaultAnimation.AnimID
7861 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7484 { 7862 {
7485 LSL_Vector lower; 7863 // This is for ground sitting avatars
7486 LSL_Vector upper; 7864 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7487 if (presence.Animator.Animations.DefaultAnimation.AnimID 7865 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7488 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 7866 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7489 {
7490 // This is for ground sitting avatars
7491 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7492 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7493 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7494 }
7495 else
7496 {
7497 // This is for standing/flying avatars
7498 float height = presence.Appearance.AvatarHeight / 2.0f;
7499 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7500 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7501 }
7502 result.Add(lower);
7503 result.Add(upper);
7504 return result;
7505 } 7867 }
7506 else 7868 else
7507 { 7869 {
7508 // sitting on an object so we need the bounding box of that 7870 // This is for standing/flying avatars
7509 // which should include the avatar so set the UUID to the 7871 float height = presence.Appearance.AvatarHeight / 2.0f;
7510 // UUID of the object the avatar is sat on and allow it to fall through 7872 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7511 // to processing an object 7873 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7512 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7513 objID = p.UUID;
7514 } 7874 }
7875
7876 // Adjust to the documented error offsets (see LSL Wiki)
7877 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7878 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7879
7880 if (lower.x > upper.x)
7881 lower.x = upper.x;
7882 if (lower.y > upper.y)
7883 lower.y = upper.y;
7884 if (lower.z > upper.z)
7885 lower.z = upper.z;
7886
7887 result.Add(lower);
7888 result.Add(upper);
7889 return result;
7515 } 7890 }
7516 SceneObjectPart part = World.GetSceneObjectPart(objID); 7891
7892 part = World.GetSceneObjectPart(objID);
7517 // Currently only works for single prims without a sitting avatar 7893 // Currently only works for single prims without a sitting avatar
7518 if (part != null) 7894 if (part != null)
7519 { 7895 {
7520 Vector3 halfSize = part.Scale / 2.0f; 7896 float minX;
7521 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 7897 float maxX;
7522 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 7898 float minY;
7899 float maxY;
7900 float minZ;
7901 float maxZ;
7902
7903 // This BBox is in sim coordinates, with the offset being
7904 // a contained point.
7905 Vector3[] offsets = World.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
7906 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
7907
7908 minX -= offsets[0].X;
7909 maxX -= offsets[0].X;
7910 minY -= offsets[0].Y;
7911 maxY -= offsets[0].Y;
7912 minZ -= offsets[0].Z;
7913 maxZ -= offsets[0].Z;
7914
7915 LSL_Vector lower;
7916 LSL_Vector upper;
7917
7918 // Adjust to the documented error offsets (see LSL Wiki)
7919 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
7920 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
7921
7922 if (lower.x > upper.x)
7923 lower.x = upper.x;
7924 if (lower.y > upper.y)
7925 lower.y = upper.y;
7926 if (lower.z > upper.z)
7927 lower.z = upper.z;
7928
7523 result.Add(lower); 7929 result.Add(lower);
7524 result.Add(upper); 7930 result.Add(upper);
7525 return result; 7931 return result;
@@ -7764,24 +8170,95 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7764 break; 8170 break;
7765 8171
7766 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8172 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7767 // TODO--------------
7768 if (remain < 1) 8173 if (remain < 1)
7769 return res; 8174 return res;
8175 face = (int)rules.GetLSLIntegerItem(idx++);
7770 8176
7771 face=(int)rules.GetLSLIntegerItem(idx++); 8177 tex = part.Shape.Textures;
7772 8178 int shiny;
7773 res.Add(new LSL_Integer(0)); 8179 if (face == ScriptBaseClass.ALL_SIDES)
7774 res.Add(new LSL_Integer(0)); 8180 {
8181 for (face = 0; face < GetNumberOfSides(part); face++)
8182 {
8183 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8184 if (shinyness == Shininess.High)
8185 {
8186 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8187 }
8188 else if (shinyness == Shininess.Medium)
8189 {
8190 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8191 }
8192 else if (shinyness == Shininess.Low)
8193 {
8194 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8195 }
8196 else
8197 {
8198 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8199 }
8200 res.Add(new LSL_Integer(shiny));
8201 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8202 }
8203 }
8204 else
8205 {
8206 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8207 if (shinyness == Shininess.High)
8208 {
8209 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8210 }
8211 else if (shinyness == Shininess.Medium)
8212 {
8213 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8214 }
8215 else if (shinyness == Shininess.Low)
8216 {
8217 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8218 }
8219 else
8220 {
8221 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8222 }
8223 res.Add(new LSL_Integer(shiny));
8224 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8225 }
7775 break; 8226 break;
7776 8227
7777 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8228 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7778 // TODO--------------
7779 if (remain < 1) 8229 if (remain < 1)
7780 return res; 8230 return res;
8231 face = (int)rules.GetLSLIntegerItem(idx++);
7781 8232
7782 face=(int)rules.GetLSLIntegerItem(idx++); 8233 tex = part.Shape.Textures;
7783 8234 int fullbright;
7784 res.Add(new LSL_Integer(0)); 8235 if (face == ScriptBaseClass.ALL_SIDES)
8236 {
8237 for (face = 0; face < GetNumberOfSides(part); face++)
8238 {
8239 if (tex.GetFace((uint)face).Fullbright == true)
8240 {
8241 fullbright = ScriptBaseClass.TRUE;
8242 }
8243 else
8244 {
8245 fullbright = ScriptBaseClass.FALSE;
8246 }
8247 res.Add(new LSL_Integer(fullbright));
8248 }
8249 }
8250 else
8251 {
8252 if (tex.GetFace((uint)face).Fullbright == true)
8253 {
8254 fullbright = ScriptBaseClass.TRUE;
8255 }
8256 else
8257 {
8258 fullbright = ScriptBaseClass.FALSE;
8259 }
8260 res.Add(new LSL_Integer(fullbright));
8261 }
7785 break; 8262 break;
7786 8263
7787 case (int)ScriptBaseClass.PRIM_FLEXIBLE: 8264 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
@@ -7802,14 +8279,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7802 break; 8279 break;
7803 8280
7804 case (int)ScriptBaseClass.PRIM_TEXGEN: 8281 case (int)ScriptBaseClass.PRIM_TEXGEN:
7805 // TODO--------------
7806 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) 8282 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7807 if (remain < 1) 8283 if (remain < 1)
7808 return res; 8284 return res;
8285 face = (int)rules.GetLSLIntegerItem(idx++);
7809 8286
7810 face=(int)rules.GetLSLIntegerItem(idx++); 8287 tex = part.Shape.Textures;
7811 8288 if (face == ScriptBaseClass.ALL_SIDES)
7812 res.Add(new LSL_Integer(0)); 8289 {
8290 for (face = 0; face < GetNumberOfSides(part); face++)
8291 {
8292 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8293 {
8294 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8295 }
8296 else
8297 {
8298 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8299 }
8300 }
8301 }
8302 else
8303 {
8304 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8305 {
8306 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8307 }
8308 else
8309 {
8310 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8311 }
8312 }
7813 break; 8313 break;
7814 8314
7815 case (int)ScriptBaseClass.PRIM_POINT_LIGHT: 8315 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
@@ -7828,13 +8328,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7828 break; 8328 break;
7829 8329
7830 case (int)ScriptBaseClass.PRIM_GLOW: 8330 case (int)ScriptBaseClass.PRIM_GLOW:
7831 // TODO--------------
7832 if (remain < 1) 8331 if (remain < 1)
7833 return res; 8332 return res;
8333 face = (int)rules.GetLSLIntegerItem(idx++);
7834 8334
7835 face=(int)rules.GetLSLIntegerItem(idx++); 8335 tex = part.Shape.Textures;
7836 8336 float primglow;
7837 res.Add(new LSL_Float(0)); 8337 if (face == ScriptBaseClass.ALL_SIDES)
8338 {
8339 for (face = 0; face < GetNumberOfSides(part); face++)
8340 {
8341 primglow = tex.GetFace((uint)face).Glow;
8342 res.Add(new LSL_Float(primglow));
8343 }
8344 }
8345 else
8346 {
8347 primglow = tex.GetFace((uint)face).Glow;
8348 res.Add(new LSL_Float(primglow));
8349 }
7838 break; 8350 break;
7839 case (int)ScriptBaseClass.PRIM_TEXT: 8351 case (int)ScriptBaseClass.PRIM_TEXT:
7840 Color4 textColor = part.GetTextColor(); 8352 Color4 textColor = part.GetTextColor();
@@ -8375,8 +8887,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8375 // The function returns an ordered list 8887 // The function returns an ordered list
8376 // representing the tokens found in the supplied 8888 // representing the tokens found in the supplied
8377 // sources string. If two successive tokenizers 8889 // sources string. If two successive tokenizers
8378 // are encountered, then a NULL entry is added 8890 // are encountered, then a null-string entry is
8379 // to the list. 8891 // added to the list.
8380 // 8892 //
8381 // It is a precondition that the source and 8893 // It is a precondition that the source and
8382 // toekizer lisst are non-null. If they are null, 8894 // toekizer lisst are non-null. If they are null,
@@ -8384,7 +8896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8384 // while their lengths are being determined. 8896 // while their lengths are being determined.
8385 // 8897 //
8386 // A small amount of working memoryis required 8898 // A small amount of working memoryis required
8387 // of approximately 8*#tokenizers. 8899 // of approximately 8*#tokenizers + 8*srcstrlen.
8388 // 8900 //
8389 // There are many ways in which this function 8901 // There are many ways in which this function
8390 // can be implemented, this implementation is 8902 // can be implemented, this implementation is
@@ -8400,136 +8912,111 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8400 // and eliminates redundant tokenizers as soon 8912 // and eliminates redundant tokenizers as soon
8401 // as is possible. 8913 // as is possible.
8402 // 8914 //
8403 // The implementation tries to avoid any copying 8915 // The implementation tries to minimize temporary
8404 // of arrays or other objects. 8916 // garbage generation.
8405 // </remarks> 8917 // </remarks>
8406 8918
8407 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers) 8919 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8408 { 8920 {
8409 int beginning = 0; 8921 return ParseString2List(src, separators, spacers, true);
8410 int srclen = src.Length; 8922 }
8411 int seplen = separators.Length;
8412 object[] separray = separators.Data;
8413 int spclen = spacers.Length;
8414 object[] spcarray = spacers.Data;
8415 int mlen = seplen+spclen;
8416
8417 int[] offset = new int[mlen+1];
8418 bool[] active = new bool[mlen];
8419 8923
8420 int best; 8924 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
8421 int j; 8925 {
8926 int srclen = src.Length;
8927 int seplen = separators.Length;
8928 object[] separray = separators.Data;
8929 int spclen = spacers.Length;
8930 object[] spcarray = spacers.Data;
8931 int dellen = 0;
8932 string[] delarray = new string[seplen+spclen];
8422 8933
8423 // Initial capacity reduces resize cost 8934 int outlen = 0;
8935 string[] outarray = new string[srclen*2+1];
8424 8936
8425 LSL_List tokens = new LSL_List(); 8937 int i, j;
8938 string d;
8426 8939
8427 m_host.AddScriptLPS(1); 8940 m_host.AddScriptLPS(1);
8428 8941
8429 // All entries are initially valid 8942 /*
8430 8943 * Convert separator and spacer lists to C# strings.
8431 for (int i = 0; i < mlen; i++) 8944 * Also filter out null strings so we don't hang.
8432 active[i] = true; 8945 */
8433 8946 for (i = 0; i < seplen; i ++) {
8434 offset[mlen] = srclen; 8947 d = separray[i].ToString();
8435 8948 if (d.Length > 0) {
8436 while (beginning < srclen) 8949 delarray[dellen++] = d;
8437 { 8950 }
8438 8951 }
8439 best = mlen; // as bad as it gets 8952 seplen = dellen;
8440
8441 // Scan for separators
8442 8953
8443 for (j = 0; j < seplen; j++) 8954 for (i = 0; i < spclen; i ++) {
8444 { 8955 d = spcarray[i].ToString();
8445 if (active[j]) 8956 if (d.Length > 0) {
8446 { 8957 delarray[dellen++] = d;
8447 // scan all of the markers
8448 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1)
8449 {
8450 // not present at all
8451 active[j] = false;
8452 }
8453 else
8454 {
8455 // present and correct
8456 if (offset[j] < offset[best])
8457 {
8458 // closest so far
8459 best = j;
8460 if (offset[best] == beginning)
8461 break;
8462 }
8463 }
8464 }
8465 } 8958 }
8959 }
8466 8960
8467 // Scan for spacers 8961 /*
8962 * Scan through source string from beginning to end.
8963 */
8964 for (i = 0;;) {
8468 8965
8469 if (offset[best] != beginning) 8966 /*
8470 { 8967 * Find earliest delimeter in src starting at i (if any).
8471 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 8968 */
8472 { 8969 int earliestDel = -1;
8473 if (active[j]) 8970 int earliestSrc = srclen;
8474 { 8971 string earliestStr = null;
8475 // scan all of the markers 8972 for (j = 0; j < dellen; j ++) {
8476 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1) 8973 d = delarray[j];
8477 { 8974 if (d != null) {
8478 // not present at all 8975 int index = src.IndexOf(d, i);
8479 active[j] = false; 8976 if (index < 0) {
8480 } 8977 delarray[j] = null; // delim nowhere in src, don't check it anymore
8481 else 8978 } else if (index < earliestSrc) {
8482 { 8979 earliestSrc = index; // where delimeter starts in source string
8483 // present and correct 8980 earliestDel = j; // where delimeter is in delarray[]
8484 if (offset[j] < offset[best]) 8981 earliestStr = d; // the delimeter string from delarray[]
8485 { 8982 if (index == i) break; // can't do any better than found at beg of string
8486 // closest so far
8487 best = j;
8488 }
8489 }
8490 } 8983 }
8491 } 8984 }
8492 } 8985 }
8493 8986
8494 // This is the normal exit from the scanning loop 8987 /*
8495 8988 * Output source string starting at i through start of earliest delimeter.
8496 if (best == mlen) 8989 */
8497 { 8990 if (keepNulls || (earliestSrc > i)) {
8498 // no markers were found on this pass 8991 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8499 // so we're pretty much done
8500 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8501 break;
8502 } 8992 }
8503 8993
8504 // Otherwise we just add the newly delimited token 8994 /*
8505 // and recalculate where the search should continue. 8995 * If no delimeter found at or after i, we're done scanning.
8506 8996 */
8507 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 8997 if (earliestDel < 0) break;
8508 8998
8509 if (best < seplen) 8999 /*
8510 { 9000 * If delimeter was a spacer, output the spacer.
8511 beginning = offset[best] + (separray[best].ToString()).Length; 9001 */
8512 } 9002 if (earliestDel >= seplen) {
8513 else 9003 outarray[outlen++] = earliestStr;
8514 {
8515 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8516 tokens.Add(new LSL_String(spcarray[best - seplen].ToString()));
8517 } 9004 }
8518 }
8519
8520 // This an awkward an not very intuitive boundary case. If the
8521 // last substring is a tokenizer, then there is an implied trailing
8522 // null list entry. Hopefully the single comparison will not be too
8523 // arduous. Alternatively the 'break' could be replced with a return
8524 // but that's shabby programming.
8525 9005
8526 if (beginning == srclen) 9006 /*
8527 { 9007 * Look at rest of src string following delimeter.
8528 if (srclen != 0) 9008 */
8529 tokens.Add(new LSL_String("")); 9009 i = earliestSrc + earliestStr.Length;
8530 } 9010 }
8531 9011
8532 return tokens; 9012 /*
9013 * Make up an exact-sized output array suitable for an LSL_List object.
9014 */
9015 object[] outlist = new object[outlen];
9016 for (i = 0; i < outlen; i ++) {
9017 outlist[i] = new LSL_String(outarray[i]);
9018 }
9019 return new LSL_List(outlist);
8533 } 9020 }
8534 9021
8535 public LSL_Integer llGetObjectPermMask(int mask) 9022 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8606,28 +9093,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8606 { 9093 {
8607 m_host.AddScriptLPS(1); 9094 m_host.AddScriptLPS(1);
8608 9095
8609 lock (m_host.TaskInventory) 9096 m_host.TaskInventory.LockItemsForRead(true);
9097 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8610 { 9098 {
8611 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9099 if (inv.Value.Name == item)
8612 { 9100 {
8613 if (inv.Value.Name == item) 9101 m_host.TaskInventory.LockItemsForRead(false);
9102 switch (mask)
8614 { 9103 {
8615 switch (mask) 9104 case 0:
8616 { 9105 return (int)inv.Value.BasePermissions;
8617 case 0: 9106 case 1:
8618 return (int)inv.Value.BasePermissions; 9107 return (int)inv.Value.CurrentPermissions;
8619 case 1: 9108 case 2:
8620 return (int)inv.Value.CurrentPermissions; 9109 return (int)inv.Value.GroupPermissions;
8621 case 2: 9110 case 3:
8622 return (int)inv.Value.GroupPermissions; 9111 return (int)inv.Value.EveryonePermissions;
8623 case 3: 9112 case 4:
8624 return (int)inv.Value.EveryonePermissions; 9113 return (int)inv.Value.NextPermissions;
8625 case 4:
8626 return (int)inv.Value.NextPermissions;
8627 }
8628 } 9114 }
8629 } 9115 }
8630 } 9116 }
9117 m_host.TaskInventory.LockItemsForRead(false);
8631 9118
8632 return -1; 9119 return -1;
8633 } 9120 }
@@ -8674,16 +9161,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8674 { 9161 {
8675 m_host.AddScriptLPS(1); 9162 m_host.AddScriptLPS(1);
8676 9163
8677 lock (m_host.TaskInventory) 9164 m_host.TaskInventory.LockItemsForRead(true);
9165 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8678 { 9166 {
8679 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9167 if (inv.Value.Name == item)
8680 { 9168 {
8681 if (inv.Value.Name == item) 9169 m_host.TaskInventory.LockItemsForRead(false);
8682 { 9170 return inv.Value.CreatorID.ToString();
8683 return inv.Value.CreatorID.ToString();
8684 }
8685 } 9171 }
8686 } 9172 }
9173 m_host.TaskInventory.LockItemsForRead(false);
8687 9174
8688 llSay(0, "No item name '" + item + "'"); 9175 llSay(0, "No item name '" + item + "'");
8689 9176
@@ -8734,8 +9221,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8734 return UUID.Zero.ToString(); 9221 return UUID.Zero.ToString();
8735 } 9222 }
8736 reply = new LSL_Vector( 9223 reply = new LSL_Vector(
8737 info.RegionLocX * Constants.RegionSize, 9224 info.RegionLocX,
8738 info.RegionLocY * Constants.RegionSize, 9225 info.RegionLocY,
8739 0).ToString(); 9226 0).ToString();
8740 break; 9227 break;
8741 case 6: // DATA_SIM_STATUS 9228 case 6: // DATA_SIM_STATUS
@@ -8948,17 +9435,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8948 int width = 0; 9435 int width = 0;
8949 int height = 0; 9436 int height = 0;
8950 9437
8951 ParcelMediaCommandEnum? commandToSend = null; 9438 uint commandToSend = 0;
8952 float time = 0.0f; // default is from start 9439 float time = 0.0f; // default is from start
8953 9440
8954 ScenePresence presence = null; 9441 ScenePresence presence = null;
8955 9442
8956 for (int i = 0; i < commandList.Data.Length; i++) 9443 for (int i = 0; i < commandList.Data.Length; i++)
8957 { 9444 {
8958 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9445 uint command = (uint)(commandList.GetLSLIntegerItem(i));
8959 switch (command) 9446 switch (command)
8960 { 9447 {
8961 case ParcelMediaCommandEnum.Agent: 9448 case (uint)ParcelMediaCommandEnum.Agent:
8962 // we send only to one agent 9449 // we send only to one agent
8963 if ((i + 1) < commandList.Length) 9450 if ((i + 1) < commandList.Length)
8964 { 9451 {
@@ -8975,25 +9462,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8975 } 9462 }
8976 break; 9463 break;
8977 9464
8978 case ParcelMediaCommandEnum.Loop: 9465 case (uint)ParcelMediaCommandEnum.Loop:
8979 loop = 1; 9466 loop = 1;
8980 commandToSend = command; 9467 commandToSend = command;
8981 update = true; //need to send the media update packet to set looping 9468 update = true; //need to send the media update packet to set looping
8982 break; 9469 break;
8983 9470
8984 case ParcelMediaCommandEnum.Play: 9471 case (uint)ParcelMediaCommandEnum.Play:
8985 loop = 0; 9472 loop = 0;
8986 commandToSend = command; 9473 commandToSend = command;
8987 update = true; //need to send the media update packet to make sure it doesn't loop 9474 update = true; //need to send the media update packet to make sure it doesn't loop
8988 break; 9475 break;
8989 9476
8990 case ParcelMediaCommandEnum.Pause: 9477 case (uint)ParcelMediaCommandEnum.Pause:
8991 case ParcelMediaCommandEnum.Stop: 9478 case (uint)ParcelMediaCommandEnum.Stop:
8992 case ParcelMediaCommandEnum.Unload: 9479 case (uint)ParcelMediaCommandEnum.Unload:
8993 commandToSend = command; 9480 commandToSend = command;
8994 break; 9481 break;
8995 9482
8996 case ParcelMediaCommandEnum.Url: 9483 case (uint)ParcelMediaCommandEnum.Url:
8997 if ((i + 1) < commandList.Length) 9484 if ((i + 1) < commandList.Length)
8998 { 9485 {
8999 if (commandList.Data[i + 1] is LSL_String) 9486 if (commandList.Data[i + 1] is LSL_String)
@@ -9006,7 +9493,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9006 } 9493 }
9007 break; 9494 break;
9008 9495
9009 case ParcelMediaCommandEnum.Texture: 9496 case (uint)ParcelMediaCommandEnum.Texture:
9010 if ((i + 1) < commandList.Length) 9497 if ((i + 1) < commandList.Length)
9011 { 9498 {
9012 if (commandList.Data[i + 1] is LSL_String) 9499 if (commandList.Data[i + 1] is LSL_String)
@@ -9019,7 +9506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9019 } 9506 }
9020 break; 9507 break;
9021 9508
9022 case ParcelMediaCommandEnum.Time: 9509 case (uint)ParcelMediaCommandEnum.Time:
9023 if ((i + 1) < commandList.Length) 9510 if ((i + 1) < commandList.Length)
9024 { 9511 {
9025 if (commandList.Data[i + 1] is LSL_Float) 9512 if (commandList.Data[i + 1] is LSL_Float)
@@ -9031,7 +9518,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9031 } 9518 }
9032 break; 9519 break;
9033 9520
9034 case ParcelMediaCommandEnum.AutoAlign: 9521 case (uint)ParcelMediaCommandEnum.AutoAlign:
9035 if ((i + 1) < commandList.Length) 9522 if ((i + 1) < commandList.Length)
9036 { 9523 {
9037 if (commandList.Data[i + 1] is LSL_Integer) 9524 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9045,7 +9532,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9045 } 9532 }
9046 break; 9533 break;
9047 9534
9048 case ParcelMediaCommandEnum.Type: 9535 case (uint)ParcelMediaCommandEnum.Type:
9049 if ((i + 1) < commandList.Length) 9536 if ((i + 1) < commandList.Length)
9050 { 9537 {
9051 if (commandList.Data[i + 1] is LSL_String) 9538 if (commandList.Data[i + 1] is LSL_String)
@@ -9058,7 +9545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9058 } 9545 }
9059 break; 9546 break;
9060 9547
9061 case ParcelMediaCommandEnum.Desc: 9548 case (uint)ParcelMediaCommandEnum.Desc:
9062 if ((i + 1) < commandList.Length) 9549 if ((i + 1) < commandList.Length)
9063 { 9550 {
9064 if (commandList.Data[i + 1] is LSL_String) 9551 if (commandList.Data[i + 1] is LSL_String)
@@ -9071,7 +9558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9071 } 9558 }
9072 break; 9559 break;
9073 9560
9074 case ParcelMediaCommandEnum.Size: 9561 case (uint)ParcelMediaCommandEnum.Size:
9075 if ((i + 2) < commandList.Length) 9562 if ((i + 2) < commandList.Length)
9076 { 9563 {
9077 if (commandList.Data[i + 1] is LSL_Integer) 9564 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9141,7 +9628,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9141 } 9628 }
9142 } 9629 }
9143 9630
9144 if (commandToSend != null) 9631 if (commandToSend != 0)
9145 { 9632 {
9146 // the commandList contained a start/stop/... command, too 9633 // the commandList contained a start/stop/... command, too
9147 if (presence == null) 9634 if (presence == null)
@@ -9178,7 +9665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9178 9665
9179 if (aList.Data[i] != null) 9666 if (aList.Data[i] != null)
9180 { 9667 {
9181 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9668 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9182 { 9669 {
9183 case ParcelMediaCommandEnum.Url: 9670 case ParcelMediaCommandEnum.Url:
9184 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9671 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9221,16 +9708,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9221 { 9708 {
9222 m_host.AddScriptLPS(1); 9709 m_host.AddScriptLPS(1);
9223 9710
9224 lock (m_host.TaskInventory) 9711 m_host.TaskInventory.LockItemsForRead(true);
9712 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9225 { 9713 {
9226 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9714 if (inv.Value.Name == name)
9227 { 9715 {
9228 if (inv.Value.Name == name) 9716 m_host.TaskInventory.LockItemsForRead(false);
9229 { 9717 return inv.Value.Type;
9230 return inv.Value.Type;
9231 }
9232 } 9718 }
9233 } 9719 }
9720 m_host.TaskInventory.LockItemsForRead(false);
9234 9721
9235 return -1; 9722 return -1;
9236 } 9723 }
@@ -9241,15 +9728,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9241 9728
9242 if (quick_pay_buttons.Data.Length < 4) 9729 if (quick_pay_buttons.Data.Length < 4)
9243 { 9730 {
9244 LSLError("List must have at least 4 elements"); 9731 int x;
9245 return; 9732 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
9733 {
9734 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
9735 }
9246 } 9736 }
9247 m_host.ParentGroup.RootPart.PayPrice[0]=price; 9737 int[] nPrice = new int[5];
9248 9738 nPrice[0]=price;
9249 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 9739 nPrice[1] = (LSL_Integer)quick_pay_buttons.Data[0];
9250 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 9740 nPrice[2] = (LSL_Integer)quick_pay_buttons.Data[1];
9251 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 9741 nPrice[3] = (LSL_Integer)quick_pay_buttons.Data[2];
9252 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 9742 nPrice[4] = (LSL_Integer)quick_pay_buttons.Data[3];
9743 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9253 m_host.ParentGroup.HasGroupChanged = true; 9744 m_host.ParentGroup.HasGroupChanged = true;
9254 } 9745 }
9255 9746
@@ -9261,17 +9752,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9261 if (invItemID == UUID.Zero) 9752 if (invItemID == UUID.Zero)
9262 return new LSL_Vector(); 9753 return new LSL_Vector();
9263 9754
9264 lock (m_host.TaskInventory) 9755 m_host.TaskInventory.LockItemsForRead(true);
9756 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9265 { 9757 {
9266 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9758 m_host.TaskInventory.LockItemsForRead(false);
9267 return new LSL_Vector(); 9759 return new LSL_Vector();
9760 }
9268 9761
9269 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9762 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9270 { 9763 {
9271 ShoutError("No permissions to track the camera"); 9764 ShoutError("No permissions to track the camera");
9272 return new LSL_Vector(); 9765 m_host.TaskInventory.LockItemsForRead(false);
9273 } 9766 return new LSL_Vector();
9274 } 9767 }
9768 m_host.TaskInventory.LockItemsForRead(false);
9275 9769
9276 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9770 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9277 if (presence != null) 9771 if (presence != null)
@@ -9289,17 +9783,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9289 if (invItemID == UUID.Zero) 9783 if (invItemID == UUID.Zero)
9290 return new LSL_Rotation(); 9784 return new LSL_Rotation();
9291 9785
9292 lock (m_host.TaskInventory) 9786 m_host.TaskInventory.LockItemsForRead(true);
9787 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9293 { 9788 {
9294 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 9789 m_host.TaskInventory.LockItemsForRead(false);
9295 return new LSL_Rotation(); 9790 return new LSL_Rotation();
9296 9791 }
9297 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 9792 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9298 { 9793 {
9299 ShoutError("No permissions to track the camera"); 9794 ShoutError("No permissions to track the camera");
9300 return new LSL_Rotation(); 9795 m_host.TaskInventory.LockItemsForRead(false);
9301 } 9796 return new LSL_Rotation();
9302 } 9797 }
9798 m_host.TaskInventory.LockItemsForRead(false);
9303 9799
9304 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 9800 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9305 if (presence != null) 9801 if (presence != null)
@@ -9361,8 +9857,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9361 { 9857 {
9362 m_host.AddScriptLPS(1); 9858 m_host.AddScriptLPS(1);
9363 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 9859 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9364 if (detectedParams == null) return; // only works on the first detected avatar 9860 if (detectedParams == null)
9365 9861 {
9862 if (m_host.IsAttachment == true)
9863 {
9864 detectedParams = new DetectParams();
9865 detectedParams.Key = m_host.OwnerID;
9866 }
9867 else
9868 {
9869 return;
9870 }
9871 }
9872
9366 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 9873 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9367 if (avatar != null) 9874 if (avatar != null)
9368 { 9875 {
@@ -9370,6 +9877,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9370 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 9877 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9371 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 9878 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9372 } 9879 }
9880
9373 ScriptSleep(1000); 9881 ScriptSleep(1000);
9374 } 9882 }
9375 9883
@@ -9449,14 +9957,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9449 if (objectID == UUID.Zero) return; 9957 if (objectID == UUID.Zero) return;
9450 9958
9451 UUID agentID; 9959 UUID agentID;
9452 lock (m_host.TaskInventory) 9960 m_host.TaskInventory.LockItemsForRead(true);
9453 { 9961 // we need the permission first, to know which avatar we want to set the camera for
9454 // we need the permission first, to know which avatar we want to set the camera for 9962 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9455 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9456 9963
9457 if (agentID == UUID.Zero) return; 9964 if (agentID == UUID.Zero)
9458 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 9965 {
9966 m_host.TaskInventory.LockItemsForRead(false);
9967 return;
9968 }
9969 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9970 {
9971 m_host.TaskInventory.LockItemsForRead(false);
9972 return;
9459 } 9973 }
9974 m_host.TaskInventory.LockItemsForRead(false);
9460 9975
9461 ScenePresence presence = World.GetScenePresence(agentID); 9976 ScenePresence presence = World.GetScenePresence(agentID);
9462 9977
@@ -9506,12 +10021,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9506 10021
9507 // we need the permission first, to know which avatar we want to clear the camera for 10022 // we need the permission first, to know which avatar we want to clear the camera for
9508 UUID agentID; 10023 UUID agentID;
9509 lock (m_host.TaskInventory) 10024 m_host.TaskInventory.LockItemsForRead(true);
10025 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10026 if (agentID == UUID.Zero)
10027 {
10028 m_host.TaskInventory.LockItemsForRead(false);
10029 return;
10030 }
10031 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9510 { 10032 {
9511 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10033 m_host.TaskInventory.LockItemsForRead(false);
9512 if (agentID == UUID.Zero) return; 10034 return;
9513 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9514 } 10035 }
10036 m_host.TaskInventory.LockItemsForRead(false);
9515 10037
9516 ScenePresence presence = World.GetScenePresence(agentID); 10038 ScenePresence presence = World.GetScenePresence(agentID);
9517 10039
@@ -9578,19 +10100,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9578 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10100 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9579 { 10101 {
9580 m_host.AddScriptLPS(1); 10102 m_host.AddScriptLPS(1);
9581 string ret = String.Empty; 10103
9582 string src1 = llBase64ToString(str1); 10104 if (str1 == String.Empty)
9583 string src2 = llBase64ToString(str2); 10105 return String.Empty;
9584 int c = 0; 10106 if (str2 == String.Empty)
9585 for (int i = 0; i < src1.Length; i++) 10107 return str1;
10108
10109 byte[] data1 = Convert.FromBase64String(str1);
10110 byte[] data2 = Convert.FromBase64String(str2);
10111
10112 byte[] d2 = new Byte[data1.Length];
10113 int pos = 0;
10114
10115 if (data1.Length <= data2.Length)
10116 {
10117 Array.Copy(data2, 0, d2, 0, data1.Length);
10118 }
10119 else
9586 { 10120 {
9587 ret += (char) (src1[i] ^ src2[c]); 10121 while (pos < data1.Length)
10122 {
10123 int len = data1.Length - pos;
10124 if (len > data2.Length)
10125 len = data2.Length;
9588 10126
9589 c++; 10127 Array.Copy(data2, 0, d2, pos, len);
9590 if (c >= src2.Length) 10128 pos += len;
9591 c = 0; 10129 }
9592 } 10130 }
9593 return llStringToBase64(ret); 10131
10132 for (pos = 0 ; pos < data1.Length ; pos++ )
10133 data1[pos] ^= d2[pos];
10134
10135 return Convert.ToBase64String(data1);
9594 } 10136 }
9595 10137
9596 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10138 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9968,15 +10510,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9968 10510
9969 internal UUID ScriptByName(string name) 10511 internal UUID ScriptByName(string name)
9970 { 10512 {
9971 lock (m_host.TaskInventory) 10513 m_host.TaskInventory.LockItemsForRead(true);
10514
10515 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
9972 { 10516 {
9973 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10517 if (item.Type == 10 && item.Name == name)
9974 { 10518 {
9975 if (item.Type == 10 && item.Name == name) 10519 m_host.TaskInventory.LockItemsForRead(false);
9976 return item.ItemID; 10520 return item.ItemID;
9977 } 10521 }
9978 } 10522 }
9979 10523
10524 m_host.TaskInventory.LockItemsForRead(false);
10525
9980 return UUID.Zero; 10526 return UUID.Zero;
9981 } 10527 }
9982 10528
@@ -10017,6 +10563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10017 { 10563 {
10018 m_host.AddScriptLPS(1); 10564 m_host.AddScriptLPS(1);
10019 10565
10566 //Clone is thread safe
10020 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10567 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10021 10568
10022 UUID assetID = UUID.Zero; 10569 UUID assetID = UUID.Zero;
@@ -10079,6 +10626,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10079 { 10626 {
10080 m_host.AddScriptLPS(1); 10627 m_host.AddScriptLPS(1);
10081 10628
10629 //Clone is thread safe
10082 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10630 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10083 10631
10084 UUID assetID = UUID.Zero; 10632 UUID assetID = UUID.Zero;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
index 5ae6439..f0384f8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LS_Api.cs
@@ -1,504 +1,507 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright 7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright 9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution. 11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the 12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products 13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission. 14 * derived from this software without specific prior written permission.
15 * 15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY 16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY 19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection; 29using System.Reflection;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse; 33using OpenMetaverse;
34using Nini.Config; 34using Nini.Config;
35using OpenSim; 35using OpenSim;
36using OpenSim.Framework; 36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare; 37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes; 39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared; 40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase; 42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces; 43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces; 44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45 45
46using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; 46using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
47using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; 47using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
48using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 48using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
49using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; 49using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
50using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; 50using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
51using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 51using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
52using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 52using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
53 53
54namespace OpenSim.Region.ScriptEngine.Shared.Api 54namespace OpenSim.Region.ScriptEngine.Shared.Api
55{ 55{
56 [Serializable] 56 [Serializable]
57 public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi 57 public class LS_Api : MarshalByRefObject, ILS_Api, IScriptApi
58 { 58 {
59 internal IScriptEngine m_ScriptEngine; 59 internal IScriptEngine m_ScriptEngine;
60 internal SceneObjectPart m_host; 60 internal SceneObjectPart m_host;
61 internal uint m_localID; 61 internal uint m_localID;
62 internal UUID m_itemID; 62 internal UUID m_itemID;
63 internal bool m_LSFunctionsEnabled = false; 63 internal bool m_LSFunctionsEnabled = false;
64 internal IScriptModuleComms m_comms = null; 64 internal IScriptModuleComms m_comms = null;
65 65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 { 67 {
68 m_ScriptEngine = ScriptEngine; 68 m_ScriptEngine = ScriptEngine;
69 m_host = host; 69 m_host = host;
70 m_localID = localID; 70 m_localID = localID;
71 m_itemID = itemID; 71 m_itemID = itemID;
72 72
73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false)) 73 if (m_ScriptEngine.Config.GetBoolean("AllowLightShareFunctions", false))
74 m_LSFunctionsEnabled = true; 74 m_LSFunctionsEnabled = true;
75 75
76 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>(); 76 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
77 if (m_comms == null) 77 m_LSFunctionsEnabled = true;
78 m_LSFunctionsEnabled = false; 78
79 } 79 m_comms = m_ScriptEngine.World.RequestModuleInterface<IScriptModuleComms>();
80 80 if (m_comms == null)
81 public override Object InitializeLifetimeService() 81 m_LSFunctionsEnabled = false;
82 { 82 }
83 ILease lease = (ILease)base.InitializeLifetimeService(); 83
84 84 public override Object InitializeLifetimeService()
85 if (lease.CurrentState == LeaseState.Initial) 85 {
86 { 86 ILease lease = (ILease)base.InitializeLifetimeService();
87 lease.InitialLeaseTime = TimeSpan.FromMinutes(0); 87
88 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0); 88 if (lease.CurrentState == LeaseState.Initial)
89 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0); 89 {
90 } 90 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
91 return lease; 91 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
92 } 92 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
93 93 }
94 public Scene World 94 return lease;
95 { 95 }
96 get { return m_ScriptEngine.World; } 96
97 } 97 public Scene World
98 98 {
99 // 99 get { return m_ScriptEngine.World; }
100 //Dumps an error message on the debug console. 100 }
101 // 101
102 102 //
103 internal void LSShoutError(string message) 103 //Dumps an error message on the debug console.
104 { 104 //
105 if (message.Length > 1023) 105
106 message = message.Substring(0, 1023); 106 internal void LSShoutError(string message)
107 107 {
108 World.SimChat(Utils.StringToBytes(message), 108 if (message.Length > 1023)
109 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true); 109 message = message.Substring(0, 1023);
110 110
111 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 111 World.SimChat(Utils.StringToBytes(message),
112 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message); 112 ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.ParentGroup.RootPart.AbsolutePosition, m_host.Name, m_host.UUID, true);
113 } 113
114 114 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
115 /// <summary> 115 wComm.DeliverMessage(ChatTypeEnum.Shout, ScriptBaseClass.DEBUG_CHANNEL, m_host.Name, m_host.UUID, message);
116 /// Get the current Windlight scene 116 }
117 /// </summary> 117
118 /// <returns>List of windlight parameters</returns> 118 /// <summary>
119 public LSL_List lsGetWindlightScene(LSL_List rules) 119 /// Get the current Windlight scene
120 { 120 /// </summary>
121 if (!m_LSFunctionsEnabled) 121 /// <returns>List of windlight parameters</returns>
122 { 122 public LSL_List lsGetWindlightScene(LSL_List rules)
123 LSShoutError("LightShare functions are not enabled."); 123 {
124 return new LSL_List(); 124 if (!m_LSFunctionsEnabled)
125 } 125 {
126 m_host.AddScriptLPS(1); 126 LSShoutError("LightShare functions are not enabled.");
127 RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings; 127 return new LSL_List();
128 128 }
129 LSL_List values = new LSL_List(); 129 m_host.AddScriptLPS(1);
130 int idx = 0; 130 RegionLightShareData wl = m_host.ParentGroup.Scene.RegionInfo.WindlightSettings;
131 while (idx < rules.Length) 131
132 { 132 LSL_List values = new LSL_List();
133 uint rule = (uint)rules.GetLSLIntegerItem(idx); 133 int idx = 0;
134 LSL_List toadd = new LSL_List(); 134 while (idx < rules.Length)
135 135 {
136 switch (rule) 136 uint rule = (uint)rules.GetLSLIntegerItem(idx);
137 { 137 LSL_List toadd = new LSL_List();
138 case (int)ScriptBaseClass.WL_AMBIENT: 138
139 toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W)); 139 switch (rule)
140 break; 140 {
141 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: 141 case (int)ScriptBaseClass.WL_AMBIENT:
142 toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f)); 142 toadd.Add(new LSL_Rotation(wl.ambient.X, wl.ambient.Y, wl.ambient.Z, wl.ambient.W));
143 break; 143 break;
144 case (int)ScriptBaseClass.WL_BLUE_DENSITY: 144 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
145 toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W)); 145 toadd.Add(new LSL_Vector(wl.bigWaveDirection.X, wl.bigWaveDirection.Y, 0.0f));
146 break; 146 break;
147 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: 147 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
148 toadd.Add(new LSL_Float(wl.blurMultiplier)); 148 toadd.Add(new LSL_Rotation(wl.blueDensity.X, wl.blueDensity.Y, wl.blueDensity.Z, wl.blueDensity.W));
149 break; 149 break;
150 case (int)ScriptBaseClass.WL_CLOUD_COLOR: 150 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
151 toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W)); 151 toadd.Add(new LSL_Float(wl.blurMultiplier));
152 break; 152 break;
153 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: 153 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
154 toadd.Add(new LSL_Float(wl.cloudCoverage)); 154 toadd.Add(new LSL_Rotation(wl.cloudColor.X, wl.cloudColor.Y, wl.cloudColor.Z, wl.cloudColor.W));
155 break; 155 break;
156 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: 156 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
157 toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z)); 157 toadd.Add(new LSL_Float(wl.cloudCoverage));
158 break; 158 break;
159 case (int)ScriptBaseClass.WL_CLOUD_SCALE: 159 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
160 toadd.Add(new LSL_Float(wl.cloudScale)); 160 toadd.Add(new LSL_Vector(wl.cloudDetailXYDensity.X, wl.cloudDetailXYDensity.Y, wl.cloudDetailXYDensity.Z));
161 break; 161 break;
162 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: 162 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
163 toadd.Add(new LSL_Float(wl.cloudScrollX)); 163 toadd.Add(new LSL_Float(wl.cloudScale));
164 break; 164 break;
165 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: 165 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
166 toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0)); 166 toadd.Add(new LSL_Float(wl.cloudScrollX));
167 break; 167 break;
168 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: 168 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
169 toadd.Add(new LSL_Float(wl.cloudScrollY)); 169 toadd.Add(new LSL_Integer(wl.cloudScrollXLock ? 1 : 0));
170 break; 170 break;
171 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: 171 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
172 toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0)); 172 toadd.Add(new LSL_Float(wl.cloudScrollY));
173 break; 173 break;
174 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: 174 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
175 toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z)); 175 toadd.Add(new LSL_Integer(wl.cloudScrollYLock ? 1 : 0));
176 break; 176 break;
177 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: 177 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
178 toadd.Add(new LSL_Float(wl.densityMultiplier)); 178 toadd.Add(new LSL_Vector(wl.cloudXYDensity.X, wl.cloudXYDensity.Y, wl.cloudXYDensity.Z));
179 break; 179 break;
180 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: 180 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
181 toadd.Add(new LSL_Float(wl.distanceMultiplier)); 181 toadd.Add(new LSL_Float(wl.densityMultiplier));
182 break; 182 break;
183 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: 183 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
184 toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0)); 184 toadd.Add(new LSL_Float(wl.distanceMultiplier));
185 break; 185 break;
186 case (int)ScriptBaseClass.WL_EAST_ANGLE: 186 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
187 toadd.Add(new LSL_Float(wl.eastAngle)); 187 toadd.Add(new LSL_Integer(wl.drawClassicClouds ? 1 : 0));
188 break; 188 break;
189 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: 189 case (int)ScriptBaseClass.WL_EAST_ANGLE:
190 toadd.Add(new LSL_Float(wl.fresnelOffset)); 190 toadd.Add(new LSL_Float(wl.eastAngle));
191 break; 191 break;
192 case (int)ScriptBaseClass.WL_FRESNEL_SCALE: 192 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
193 toadd.Add(new LSL_Float(wl.fresnelScale)); 193 toadd.Add(new LSL_Float(wl.fresnelOffset));
194 break; 194 break;
195 case (int)ScriptBaseClass.WL_HAZE_DENSITY: 195 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
196 toadd.Add(new LSL_Float(wl.hazeDensity)); 196 toadd.Add(new LSL_Float(wl.fresnelScale));
197 break; 197 break;
198 case (int)ScriptBaseClass.WL_HAZE_HORIZON: 198 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
199 toadd.Add(new LSL_Float(wl.hazeHorizon)); 199 toadd.Add(new LSL_Float(wl.hazeDensity));
200 break; 200 break;
201 case (int)ScriptBaseClass.WL_HORIZON: 201 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
202 toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W)); 202 toadd.Add(new LSL_Float(wl.hazeHorizon));
203 break; 203 break;
204 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: 204 case (int)ScriptBaseClass.WL_HORIZON:
205 toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f)); 205 toadd.Add(new LSL_Rotation(wl.horizon.X, wl.horizon.Y, wl.horizon.Z, wl.horizon.W));
206 break; 206 break;
207 case (int)ScriptBaseClass.WL_MAX_ALTITUDE: 207 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
208 toadd.Add(new LSL_Integer(wl.maxAltitude)); 208 toadd.Add(new LSL_Vector(wl.littleWaveDirection.X, wl.littleWaveDirection.Y, 0.0f));
209 break; 209 break;
210 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: 210 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
211 toadd.Add(new LSL_Key(wl.normalMapTexture.ToString())); 211 toadd.Add(new LSL_Integer(wl.maxAltitude));
212 break; 212 break;
213 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: 213 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
214 toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z)); 214 toadd.Add(new LSL_Key(wl.normalMapTexture.ToString()));
215 break; 215 break;
216 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: 216 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
217 toadd.Add(new LSL_Float(wl.refractScaleAbove)); 217 toadd.Add(new LSL_Vector(wl.reflectionWaveletScale.X, wl.reflectionWaveletScale.Y, wl.reflectionWaveletScale.Z));
218 break; 218 break;
219 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: 219 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
220 toadd.Add(new LSL_Float(wl.refractScaleBelow)); 220 toadd.Add(new LSL_Float(wl.refractScaleAbove));
221 break; 221 break;
222 case (int)ScriptBaseClass.WL_SCENE_GAMMA: 222 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
223 toadd.Add(new LSL_Float(wl.sceneGamma)); 223 toadd.Add(new LSL_Float(wl.refractScaleBelow));
224 break; 224 break;
225 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: 225 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
226 toadd.Add(new LSL_Float(wl.starBrightness)); 226 toadd.Add(new LSL_Float(wl.sceneGamma));
227 break; 227 break;
228 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: 228 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
229 toadd.Add(new LSL_Float(wl.sunGlowFocus)); 229 toadd.Add(new LSL_Float(wl.starBrightness));
230 break; 230 break;
231 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: 231 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
232 toadd.Add(new LSL_Float(wl.sunGlowSize)); 232 toadd.Add(new LSL_Float(wl.sunGlowFocus));
233 break; 233 break;
234 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: 234 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
235 toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W)); 235 toadd.Add(new LSL_Float(wl.sunGlowSize));
236 break; 236 break;
237 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: 237 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
238 toadd.Add(new LSL_Float(wl.underwaterFogModifier)); 238 toadd.Add(new LSL_Rotation(wl.sunMoonColor.X, wl.sunMoonColor.Y, wl.sunMoonColor.Z, wl.sunMoonColor.W));
239 break; 239 break;
240 case (int)ScriptBaseClass.WL_WATER_COLOR: 240 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
241 toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z)); 241 toadd.Add(new LSL_Float(wl.underwaterFogModifier));
242 break; 242 break;
243 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: 243 case (int)ScriptBaseClass.WL_WATER_COLOR:
244 toadd.Add(new LSL_Float(wl.waterFogDensityExponent)); 244 toadd.Add(new LSL_Vector(wl.waterColor.X, wl.waterColor.Y, wl.waterColor.Z));
245 break; 245 break;
246 } 246 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
247 247 toadd.Add(new LSL_Float(wl.waterFogDensityExponent));
248 if (toadd.Length > 0) 248 break;
249 { 249 }
250 values.Add(rule); 250
251 values.Add(toadd.Data[0]); 251 if (toadd.Length > 0)
252 } 252 {
253 idx++; 253 values.Add(new LSL_Integer(rule));
254 } 254 values.Add(toadd.Data[0]);
255 255 }
256 256 idx++;
257 return values; 257 }
258 258
259 } 259
260 260 return values;
261 private RegionLightShareData getWindlightProfileFromRules(LSL_List rules) 261
262 { 262 }
263 RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone(); 263
264 264 private RegionLightShareData getWindlightProfileFromRules(LSL_List rules)
265 LSL_List values = new LSL_List(); 265 {
266 int idx = 0; 266 RegionLightShareData wl = (RegionLightShareData)m_host.ParentGroup.Scene.RegionInfo.WindlightSettings.Clone();
267 while (idx < rules.Length) 267
268 { 268 LSL_List values = new LSL_List();
269 uint rule = (uint)rules.GetLSLIntegerItem(idx); 269 int idx = 0;
270 LSL_Types.Quaternion iQ; 270 while (idx < rules.Length)
271 LSL_Types.Vector3 iV; 271 {
272 switch (rule) 272 uint rule = (uint)rules.GetLSLIntegerItem(idx);
273 { 273 LSL_Types.Quaternion iQ;
274 case (int)ScriptBaseClass.WL_SUN_MOON_POSITION: 274 LSL_Types.Vector3 iV;
275 idx++; 275 switch (rule)
276 wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx); 276 {
277 break; 277 case (int)ScriptBaseClass.WL_SUN_MOON_POSITION:
278 case (int)ScriptBaseClass.WL_AMBIENT: 278 idx++;
279 idx++; 279 wl.sunMoonPosition = (float)rules.GetLSLFloatItem(idx);
280 iQ = rules.GetQuaternionItem(idx); 280 break;
281 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 281 case (int)ScriptBaseClass.WL_AMBIENT:
282 break; 282 idx++;
283 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION: 283 iQ = rules.GetQuaternionItem(idx);
284 idx++; 284 wl.ambient = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
285 iV = rules.GetVector3Item(idx); 285 break;
286 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y); 286 case (int)ScriptBaseClass.WL_BIG_WAVE_DIRECTION:
287 break; 287 idx++;
288 case (int)ScriptBaseClass.WL_BLUE_DENSITY: 288 iV = rules.GetVector3Item(idx);
289 idx++; 289 wl.bigWaveDirection = new Vector2((float)iV.x, (float)iV.y);
290 iQ = rules.GetQuaternionItem(idx); 290 break;
291 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 291 case (int)ScriptBaseClass.WL_BLUE_DENSITY:
292 break; 292 idx++;
293 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER: 293 iQ = rules.GetQuaternionItem(idx);
294 idx++; 294 wl.blueDensity = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
295 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx); 295 break;
296 break; 296 case (int)ScriptBaseClass.WL_BLUR_MULTIPLIER:
297 case (int)ScriptBaseClass.WL_CLOUD_COLOR: 297 idx++;
298 idx++; 298 wl.blurMultiplier = (float)rules.GetLSLFloatItem(idx);
299 iQ = rules.GetQuaternionItem(idx); 299 break;
300 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 300 case (int)ScriptBaseClass.WL_CLOUD_COLOR:
301 break; 301 idx++;
302 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE: 302 iQ = rules.GetQuaternionItem(idx);
303 idx++; 303 wl.cloudColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
304 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx); 304 break;
305 break; 305 case (int)ScriptBaseClass.WL_CLOUD_COVERAGE:
306 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY: 306 idx++;
307 idx++; 307 wl.cloudCoverage = (float)rules.GetLSLFloatItem(idx);
308 iV = rules.GetVector3Item(idx); 308 break;
309 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 309 case (int)ScriptBaseClass.WL_CLOUD_DETAIL_XY_DENSITY:
310 break; 310 idx++;
311 case (int)ScriptBaseClass.WL_CLOUD_SCALE: 311 iV = rules.GetVector3Item(idx);
312 idx++; 312 wl.cloudDetailXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
313 wl.cloudScale = (float)rules.GetLSLFloatItem(idx); 313 break;
314 break; 314 case (int)ScriptBaseClass.WL_CLOUD_SCALE:
315 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X: 315 idx++;
316 idx++; 316 wl.cloudScale = (float)rules.GetLSLFloatItem(idx);
317 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx); 317 break;
318 break; 318 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X:
319 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK: 319 idx++;
320 idx++; 320 wl.cloudScrollX = (float)rules.GetLSLFloatItem(idx);
321 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; 321 break;
322 break; 322 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_X_LOCK:
323 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y: 323 idx++;
324 idx++; 324 wl.cloudScrollXLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
325 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx); 325 break;
326 break; 326 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y:
327 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK: 327 idx++;
328 idx++; 328 wl.cloudScrollY = (float)rules.GetLSLFloatItem(idx);
329 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; 329 break;
330 break; 330 case (int)ScriptBaseClass.WL_CLOUD_SCROLL_Y_LOCK:
331 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY: 331 idx++;
332 idx++; 332 wl.cloudScrollYLock = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
333 iV = rules.GetVector3Item(idx); 333 break;
334 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 334 case (int)ScriptBaseClass.WL_CLOUD_XY_DENSITY:
335 break; 335 idx++;
336 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER: 336 iV = rules.GetVector3Item(idx);
337 idx++; 337 wl.cloudXYDensity = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
338 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx); 338 break;
339 break; 339 case (int)ScriptBaseClass.WL_DENSITY_MULTIPLIER:
340 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER: 340 idx++;
341 idx++; 341 wl.densityMultiplier = (float)rules.GetLSLFloatItem(idx);
342 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx); 342 break;
343 break; 343 case (int)ScriptBaseClass.WL_DISTANCE_MULTIPLIER:
344 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS: 344 idx++;
345 idx++; 345 wl.distanceMultiplier = (float)rules.GetLSLFloatItem(idx);
346 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false; 346 break;
347 break; 347 case (int)ScriptBaseClass.WL_DRAW_CLASSIC_CLOUDS:
348 case (int)ScriptBaseClass.WL_EAST_ANGLE: 348 idx++;
349 idx++; 349 wl.drawClassicClouds = rules.GetLSLIntegerItem(idx).value == 1 ? true : false;
350 wl.eastAngle = (float)rules.GetLSLFloatItem(idx); 350 break;
351 break; 351 case (int)ScriptBaseClass.WL_EAST_ANGLE:
352 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET: 352 idx++;
353 idx++; 353 wl.eastAngle = (float)rules.GetLSLFloatItem(idx);
354 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx); 354 break;
355 break; 355 case (int)ScriptBaseClass.WL_FRESNEL_OFFSET:
356 case (int)ScriptBaseClass.WL_FRESNEL_SCALE: 356 idx++;
357 idx++; 357 wl.fresnelOffset = (float)rules.GetLSLFloatItem(idx);
358 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx); 358 break;
359 break; 359 case (int)ScriptBaseClass.WL_FRESNEL_SCALE:
360 case (int)ScriptBaseClass.WL_HAZE_DENSITY: 360 idx++;
361 idx++; 361 wl.fresnelScale = (float)rules.GetLSLFloatItem(idx);
362 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx); 362 break;
363 break; 363 case (int)ScriptBaseClass.WL_HAZE_DENSITY:
364 case (int)ScriptBaseClass.WL_HAZE_HORIZON: 364 idx++;
365 idx++; 365 wl.hazeDensity = (float)rules.GetLSLFloatItem(idx);
366 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx); 366 break;
367 break; 367 case (int)ScriptBaseClass.WL_HAZE_HORIZON:
368 case (int)ScriptBaseClass.WL_HORIZON: 368 idx++;
369 idx++; 369 wl.hazeHorizon = (float)rules.GetLSLFloatItem(idx);
370 iQ = rules.GetQuaternionItem(idx); 370 break;
371 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 371 case (int)ScriptBaseClass.WL_HORIZON:
372 break; 372 idx++;
373 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION: 373 iQ = rules.GetQuaternionItem(idx);
374 idx++; 374 wl.horizon = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
375 iV = rules.GetVector3Item(idx); 375 break;
376 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y); 376 case (int)ScriptBaseClass.WL_LITTLE_WAVE_DIRECTION:
377 break; 377 idx++;
378 case (int)ScriptBaseClass.WL_MAX_ALTITUDE: 378 iV = rules.GetVector3Item(idx);
379 idx++; 379 wl.littleWaveDirection = new Vector2((float)iV.x, (float)iV.y);
380 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value; 380 break;
381 break; 381 case (int)ScriptBaseClass.WL_MAX_ALTITUDE:
382 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE: 382 idx++;
383 idx++; 383 wl.maxAltitude = (ushort)rules.GetLSLIntegerItem(idx).value;
384 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string); 384 break;
385 break; 385 case (int)ScriptBaseClass.WL_NORMAL_MAP_TEXTURE:
386 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE: 386 idx++;
387 idx++; 387 wl.normalMapTexture = new UUID(rules.GetLSLStringItem(idx).m_string);
388 iV = rules.GetVector3Item(idx); 388 break;
389 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 389 case (int)ScriptBaseClass.WL_REFLECTION_WAVELET_SCALE:
390 break; 390 idx++;
391 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE: 391 iV = rules.GetVector3Item(idx);
392 idx++; 392 wl.reflectionWaveletScale = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
393 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx); 393 break;
394 break; 394 case (int)ScriptBaseClass.WL_REFRACT_SCALE_ABOVE:
395 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW: 395 idx++;
396 idx++; 396 wl.refractScaleAbove = (float)rules.GetLSLFloatItem(idx);
397 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx); 397 break;
398 break; 398 case (int)ScriptBaseClass.WL_REFRACT_SCALE_BELOW:
399 case (int)ScriptBaseClass.WL_SCENE_GAMMA: 399 idx++;
400 idx++; 400 wl.refractScaleBelow = (float)rules.GetLSLFloatItem(idx);
401 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx); 401 break;
402 break; 402 case (int)ScriptBaseClass.WL_SCENE_GAMMA:
403 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS: 403 idx++;
404 idx++; 404 wl.sceneGamma = (float)rules.GetLSLFloatItem(idx);
405 wl.starBrightness = (float)rules.GetLSLFloatItem(idx); 405 break;
406 break; 406 case (int)ScriptBaseClass.WL_STAR_BRIGHTNESS:
407 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS: 407 idx++;
408 idx++; 408 wl.starBrightness = (float)rules.GetLSLFloatItem(idx);
409 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx); 409 break;
410 break; 410 case (int)ScriptBaseClass.WL_SUN_GLOW_FOCUS:
411 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE: 411 idx++;
412 idx++; 412 wl.sunGlowFocus = (float)rules.GetLSLFloatItem(idx);
413 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx); 413 break;
414 break; 414 case (int)ScriptBaseClass.WL_SUN_GLOW_SIZE:
415 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR: 415 idx++;
416 idx++; 416 wl.sunGlowSize = (float)rules.GetLSLFloatItem(idx);
417 iQ = rules.GetQuaternionItem(idx); 417 break;
418 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s); 418 case (int)ScriptBaseClass.WL_SUN_MOON_COLOR:
419 break; 419 idx++;
420 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER: 420 iQ = rules.GetQuaternionItem(idx);
421 idx++; 421 wl.sunMoonColor = new Vector4((float)iQ.x, (float)iQ.y, (float)iQ.z, (float)iQ.s);
422 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx); 422 break;
423 break; 423 case (int)ScriptBaseClass.WL_UNDERWATER_FOG_MODIFIER:
424 case (int)ScriptBaseClass.WL_WATER_COLOR: 424 idx++;
425 idx++; 425 wl.underwaterFogModifier = (float)rules.GetLSLFloatItem(idx);
426 iV = rules.GetVector3Item(idx); 426 break;
427 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z); 427 case (int)ScriptBaseClass.WL_WATER_COLOR:
428 break; 428 idx++;
429 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT: 429 iV = rules.GetVector3Item(idx);
430 idx++; 430 wl.waterColor = new Vector3((float)iV.x, (float)iV.y, (float)iV.z);
431 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx); 431 break;
432 break; 432 case (int)ScriptBaseClass.WL_WATER_FOG_DENSITY_EXPONENT:
433 } 433 idx++;
434 idx++; 434 wl.waterFogDensityExponent = (float)rules.GetLSLFloatItem(idx);
435 } 435 break;
436 return wl; 436 }
437 } 437 idx++;
438 /// <summary> 438 }
439 /// Set the current Windlight scene 439 return wl;
440 /// </summary> 440 }
441 /// <param name="rules"></param> 441 /// <summary>
442 /// <returns>success: true or false</returns> 442 /// Set the current Windlight scene
443 public int lsSetWindlightScene(LSL_List rules) 443 /// </summary>
444 { 444 /// <param name="rules"></param>
445 if (!m_LSFunctionsEnabled) 445 /// <returns>success: true or false</returns>
446 { 446 public int lsSetWindlightScene(LSL_List rules)
447 LSShoutError("LightShare functions are not enabled."); 447 {
448 return 0; 448 if (!m_LSFunctionsEnabled)
449 } 449 {
450 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 450 LSShoutError("LightShare functions are not enabled.");
451 { 451 return 0;
452 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners."); 452 }
453 return 0; 453 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
454 } 454 {
455 int success = 0; 455 LSShoutError("lsSetWindlightScene can only be used by estate managers or owners.");
456 m_host.AddScriptLPS(1); 456 return 0;
457 if (LightShareModule.EnableWindlight) 457 }
458 { 458 int success = 0;
459 RegionLightShareData wl = getWindlightProfileFromRules(rules); 459 m_host.AddScriptLPS(1);
460 m_host.ParentGroup.Scene.StoreWindlightProfile(wl); 460 if (LightShareModule.EnableWindlight)
461 success = 1; 461 {
462 } 462 RegionLightShareData wl = getWindlightProfileFromRules(rules);
463 else 463 m_host.ParentGroup.Scene.StoreWindlightProfile(wl);
464 { 464 success = 1;
465 LSShoutError("Windlight module is disabled"); 465 }
466 return 0; 466 else
467 } 467 {
468 return success; 468 LSShoutError("Windlight module is disabled");
469 } 469 return 0;
470 /// <summary> 470 }
471 /// Set the current Windlight scene to a target avatar 471 return success;
472 /// </summary> 472 }
473 /// <param name="rules"></param> 473 /// <summary>
474 /// <returns>success: true or false</returns> 474 /// Set the current Windlight scene to a target avatar
475 public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target) 475 /// </summary>
476 { 476 /// <param name="rules"></param>
477 if (!m_LSFunctionsEnabled) 477 /// <returns>success: true or false</returns>
478 { 478 public int lsSetWindlightSceneTargeted(LSL_List rules, LSL_Key target)
479 LSShoutError("LightShare functions are not enabled."); 479 {
480 return 0; 480 if (!m_LSFunctionsEnabled)
481 } 481 {
482 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200) 482 LSShoutError("LightShare functions are not enabled.");
483 { 483 return 0;
484 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners."); 484 }
485 return 0; 485 if (!World.RegionInfo.EstateSettings.IsEstateManager(m_host.OwnerID) && World.GetScenePresence(m_host.OwnerID).GodLevel < 200)
486 } 486 {
487 int success = 0; 487 LSShoutError("lsSetWindlightSceneTargeted can only be used by estate managers or owners.");
488 m_host.AddScriptLPS(1); 488 return 0;
489 if (LightShareModule.EnableWindlight) 489 }
490 { 490 int success = 0;
491 RegionLightShareData wl = getWindlightProfileFromRules(rules); 491 m_host.AddScriptLPS(1);
492 World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string)); 492 if (LightShareModule.EnableWindlight)
493 success = 1; 493 {
494 } 494 RegionLightShareData wl = getWindlightProfileFromRules(rules);
495 else 495 World.EventManager.TriggerOnSendNewWindlightProfileTargeted(wl, new UUID(target.m_string));
496 { 496 success = 1;
497 LSShoutError("Windlight module is disabled"); 497 }
498 return 0; 498 else
499 } 499 {
500 return success; 500 LSShoutError("Windlight module is disabled");
501 } 501 return 0;
502 502 }
503 } 503 return success;
504} 504 }
505
506 }
507}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index a529a94..a08b135 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -129,6 +129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 129 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
130 internal float m_ScriptDelayFactor = 1.0f; 130 internal float m_ScriptDelayFactor = 1.0f;
131 internal float m_ScriptDistanceFactor = 1.0f; 131 internal float m_ScriptDistanceFactor = 1.0f;
132 internal bool m_debuggerSafe = false;
132 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 133 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
133 134
134 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 135 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -137,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 m_host = host; 138 m_host = host;
138 m_localID = localID; 139 m_localID = localID;
139 m_itemID = itemID; 140 m_itemID = itemID;
141 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
140 142
141 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 143 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
142 m_OSFunctionsEnabled = true; 144 m_OSFunctionsEnabled = true;
@@ -195,7 +197,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
195 197
196 internal void OSSLError(string msg) 198 internal void OSSLError(string msg)
197 { 199 {
198 throw new Exception("OSSL Runtime Error: " + msg); 200 if (m_debuggerSafe)
201 {
202 OSSLShoutError(msg);
203 }
204 else
205 {
206 throw new Exception("OSSL Runtime Error: " + msg);
207 }
199 } 208 }
200 209
201 private void InitLSL() 210 private void InitLSL()
@@ -767,18 +776,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
767 if (target != null) 776 if (target != null)
768 { 777 {
769 UUID animID=UUID.Zero; 778 UUID animID=UUID.Zero;
770 lock (m_host.TaskInventory) 779 m_host.TaskInventory.LockItemsForRead(true);
780 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
771 { 781 {
772 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 782 if (inv.Value.Name == animation)
773 { 783 {
774 if (inv.Value.Name == animation) 784 if (inv.Value.Type == (int)AssetType.Animation)
775 { 785 animID = inv.Value.AssetID;
776 if (inv.Value.Type == (int)AssetType.Animation) 786 continue;
777 animID = inv.Value.AssetID;
778 continue;
779 }
780 } 787 }
781 } 788 }
789 m_host.TaskInventory.LockItemsForRead(false);
782 if (animID == UUID.Zero) 790 if (animID == UUID.Zero)
783 target.Animator.AddAnimation(animation, m_host.UUID); 791 target.Animator.AddAnimation(animation, m_host.UUID);
784 else 792 else
@@ -800,18 +808,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
800 if (target != null) 808 if (target != null)
801 { 809 {
802 UUID animID=UUID.Zero; 810 UUID animID=UUID.Zero;
803 lock (m_host.TaskInventory) 811 m_host.TaskInventory.LockItemsForRead(true);
812 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
804 { 813 {
805 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 814 if (inv.Value.Name == animation)
806 { 815 {
807 if (inv.Value.Name == animation) 816 if (inv.Value.Type == (int)AssetType.Animation)
808 { 817 animID = inv.Value.AssetID;
809 if (inv.Value.Type == (int)AssetType.Animation) 818 continue;
810 animID = inv.Value.AssetID;
811 continue;
812 }
813 } 819 }
814 } 820 }
821 m_host.TaskInventory.LockItemsForRead(false);
815 822
816 if (animID == UUID.Zero) 823 if (animID == UUID.Zero)
817 target.Animator.RemoveAnimation(animation); 824 target.Animator.RemoveAnimation(animation);
@@ -1662,6 +1669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1662 1669
1663 if (!UUID.TryParse(name, out assetID)) 1670 if (!UUID.TryParse(name, out assetID))
1664 { 1671 {
1672 m_host.TaskInventory.LockItemsForRead(true);
1665 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1673 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1666 { 1674 {
1667 if (item.Type == 7 && item.Name == name) 1675 if (item.Type == 7 && item.Name == name)
@@ -1669,6 +1677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1669 assetID = item.AssetID; 1677 assetID = item.AssetID;
1670 } 1678 }
1671 } 1679 }
1680 m_host.TaskInventory.LockItemsForRead(false);
1672 } 1681 }
1673 1682
1674 if (assetID == UUID.Zero) 1683 if (assetID == UUID.Zero)
@@ -1715,6 +1724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1715 1724
1716 if (!UUID.TryParse(name, out assetID)) 1725 if (!UUID.TryParse(name, out assetID))
1717 { 1726 {
1727 m_host.TaskInventory.LockItemsForRead(true);
1718 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1728 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1719 { 1729 {
1720 if (item.Type == 7 && item.Name == name) 1730 if (item.Type == 7 && item.Name == name)
@@ -1722,6 +1732,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1722 assetID = item.AssetID; 1732 assetID = item.AssetID;
1723 } 1733 }
1724 } 1734 }
1735 m_host.TaskInventory.LockItemsForRead(false);
1725 } 1736 }
1726 1737
1727 if (assetID == UUID.Zero) 1738 if (assetID == UUID.Zero)
@@ -1772,6 +1783,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1783
1773 if (!UUID.TryParse(name, out assetID)) 1784 if (!UUID.TryParse(name, out assetID))
1774 { 1785 {
1786 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1788 {
1777 if (item.Type == 7 && item.Name == name) 1789 if (item.Type == 7 && item.Name == name)
@@ -1779,6 +1791,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1791 assetID = item.AssetID;
1780 } 1792 }
1781 } 1793 }
1794 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1795 }
1783 1796
1784 if (assetID == UUID.Zero) 1797 if (assetID == UUID.Zero)
@@ -2216,9 +2229,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 { 2229 {
2217 if (avatar.IsChildAgent == false) 2230 if (avatar.IsChildAgent == false)
2218 { 2231 {
2219 result.Add(avatar.UUID); 2232 result.Add(new LSL_Key(avatar.UUID.ToString()));
2220 result.Add(avatar.AbsolutePosition); 2233 result.Add(new LSL_Vector(avatar.AbsolutePosition.X, avatar.AbsolutePosition.Y, avatar.AbsolutePosition.Z));
2221 result.Add(avatar.Name); 2234 result.Add(new LSL_String(avatar.Name));
2222 } 2235 }
2223 } 2236 }
2224 }); 2237 });
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 5c2abd5..a5b1124 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -204,7 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
204 // Is the sensor type is AGENT and not SCRIPTED then include agents 204 // Is the sensor type is AGENT and not SCRIPTED then include agents
205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0) 205 if ((ts.type & AGENT) != 0 && (ts.type & SCRIPTED) == 0)
206 { 206 {
207 sensedEntities.AddRange(doAgentSensor(ts)); 207 sensedEntities.AddRange(doAgentSensor(ts));
208 } 208 }
209 209
210 // If SCRIPTED or PASSIVE or ACTIVE check objects 210 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -309,6 +309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
309 // in mouselook. 309 // in mouselook.
310 310
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar); 311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
312 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 313 q = avatar.Rotation;
313 } 314 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 315 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -422,6 +423,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
422 SceneObjectPart SensePoint = ts.host; 423 SceneObjectPart SensePoint = ts.host;
423 Vector3 fromRegionPos = SensePoint.AbsolutePosition; 424 Vector3 fromRegionPos = SensePoint.AbsolutePosition;
424 Quaternion q = SensePoint.RotationOffset; 425 Quaternion q = SensePoint.RotationOffset;
426 if (SensePoint.ParentGroup.RootPart.IsAttachment)
427 {
428 // In attachments, the sensor cone always orients with the
429 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook.
431
432 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.RootPart.AttachedAvatar);
433 fromRegionPos = avatar.AbsolutePosition;
434 q = avatar.Rotation;
435 }
425 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 436 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
426 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r); 437 LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
427 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir); 438 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }