aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2913
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs109
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs85
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
18 files changed, 2427 insertions, 1071 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/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..489c1c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal uint m_localID;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true;
75 }
76
77 public override Object InitializeLifetimeService()
78 {
79 ILease lease = (ILease)base.InitializeLifetimeService();
80
81 if (lease.CurrentState == LeaseState.Initial)
82 {
83 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
84 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
85 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
86 }
87 return lease;
88 }
89
90 public Scene World
91 {
92 get { return m_ScriptEngine.World; }
93 }
94
95 public string cmDetectedCountry(int number)
96 {
97 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
99 if (detectedParams == null)
100 return String.Empty;
101 return detectedParams.Country;
102 }
103
104 public string cmGetAgentCountry(LSL_Key key)
105 {
106 if (!World.Permissions.IsGod(m_host.OwnerID))
107 return String.Empty;
108
109 UUID uuid;
110
111 if (!UUID.TryParse(key, out uuid))
112 return String.Empty;
113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
116 }
117 }
118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 0bdd84a..1529140 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
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;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -156,6 +170,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
156 get { return m_ScriptEngine.World; } 170 get { return m_ScriptEngine.World; }
157 } 171 }
158 172
173 [DebuggerNonUserCode]
159 public void state(string newState) 174 public void state(string newState)
160 { 175 {
161 m_ScriptEngine.SetState(m_itemID, newState); 176 m_ScriptEngine.SetState(m_itemID, newState);
@@ -165,6 +180,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
165 /// Reset the named script. The script must be present 180 /// Reset the named script. The script must be present
166 /// in the same prim. 181 /// in the same prim.
167 /// </summary> 182 /// </summary>
183 [DebuggerNonUserCode]
168 public void llResetScript() 184 public void llResetScript()
169 { 185 {
170 m_host.AddScriptLPS(1); 186 m_host.AddScriptLPS(1);
@@ -221,9 +237,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
221 } 237 }
222 } 238 }
223 239
240 public List<ScenePresence> GetLinkAvatars(int linkType)
241 {
242 List<ScenePresence> ret = new List<ScenePresence>();
243 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
244 return ret;
245
246 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
247
248 switch (linkType)
249 {
250 case ScriptBaseClass.LINK_SET:
251 return avs;
252
253 case ScriptBaseClass.LINK_ROOT:
254 return ret;
255
256 case ScriptBaseClass.LINK_ALL_OTHERS:
257 return avs;
258
259 case ScriptBaseClass.LINK_ALL_CHILDREN:
260 return avs;
261
262 case ScriptBaseClass.LINK_THIS:
263 return ret;
264
265 default:
266 if (linkType < 0)
267 return ret;
268
269 int partCount = m_host.ParentGroup.GetPartCount();
270
271 if (linkType <= partCount)
272 {
273 return ret;
274 }
275 else
276 {
277 linkType = linkType - partCount;
278 if (linkType > avs.Count)
279 {
280 return ret;
281 }
282 else
283 {
284 ret.Add(avs[linkType-1]);
285 return ret;
286 }
287 }
288 }
289 }
290
224 public List<SceneObjectPart> GetLinkParts(int linkType) 291 public List<SceneObjectPart> GetLinkParts(int linkType)
225 { 292 {
226 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 293 List<SceneObjectPart> ret = new List<SceneObjectPart>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
227 ret.Add(m_host); 296 ret.Add(m_host);
228 297
229 switch (linkType) 298 switch (linkType)
@@ -270,40 +339,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
270 protected UUID InventorySelf() 339 protected UUID InventorySelf()
271 { 340 {
272 UUID invItemID = new UUID(); 341 UUID invItemID = new UUID();
273 342 bool unlock = false;
274 lock (m_host.TaskInventory) 343 if (!m_host.TaskInventory.IsReadLockedByMe())
344 {
345 m_host.TaskInventory.LockItemsForRead(true);
346 unlock = true;
347 }
348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
275 { 349 {
276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 350 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
277 { 351 {
278 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 352 invItemID = inv.Key;
279 { 353 break;
280 invItemID = inv.Key;
281 break;
282 }
283 } 354 }
284 } 355 }
285 356 if (unlock)
357 {
358 m_host.TaskInventory.LockItemsForRead(false);
359 }
286 return invItemID; 360 return invItemID;
287 } 361 }
288 362
289 protected UUID InventoryKey(string name, int type) 363 protected UUID InventoryKey(string name, int type)
290 { 364 {
291 m_host.AddScriptLPS(1); 365 m_host.AddScriptLPS(1);
292 366 m_host.TaskInventory.LockItemsForRead(true);
293 lock (m_host.TaskInventory) 367
368 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
294 { 369 {
295 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 370 if (inv.Value.Name == name)
296 { 371 {
297 if (inv.Value.Name == name) 372 m_host.TaskInventory.LockItemsForRead(false);
373
374 if (inv.Value.Type != type)
298 { 375 {
299 if (inv.Value.Type != type) 376 return UUID.Zero;
300 return UUID.Zero;
301
302 return inv.Value.AssetID;
303 } 377 }
378
379 return inv.Value.AssetID;
304 } 380 }
305 } 381 }
306 382
383 m_host.TaskInventory.LockItemsForRead(false);
307 return UUID.Zero; 384 return UUID.Zero;
308 } 385 }
309 386
@@ -311,17 +388,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
311 { 388 {
312 m_host.AddScriptLPS(1); 389 m_host.AddScriptLPS(1);
313 390
314 lock (m_host.TaskInventory) 391
392 m_host.TaskInventory.LockItemsForRead(true);
393
394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 395 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 396 if (inv.Value.Name == name)
317 { 397 {
318 if (inv.Value.Name == name) 398 m_host.TaskInventory.LockItemsForRead(false);
319 { 399 return inv.Value.AssetID;
320 return inv.Value.AssetID;
321 }
322 } 400 }
323 } 401 }
324 402
403 m_host.TaskInventory.LockItemsForRead(false);
404
405
325 return UUID.Zero; 406 return UUID.Zero;
326 } 407 }
327 408
@@ -463,31 +544,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
463 544
464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 545 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
465 546
466 /// <summary> 547 // Utility function for llRot2Euler
467 /// Convert an LSL rotation to a Euler vector. 548
468 /// </summary> 549 // normalize an angle between -PI and PI (-180 to +180 degrees)
469 /// <remarks> 550 protected double NormalizeAngle(double angle)
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
475 public LSL_Vector llRot2Euler(LSL_Rotation r)
476 { 551 {
477 m_host.AddScriptLPS(1); 552 if (angle > -Math.PI && angle < Math.PI)
553 return angle;
554
555 int numPis = (int)(Math.PI / angle);
556 double remainder = angle - Math.PI * numPis;
557 if (numPis % 2 == 1)
558 return Math.PI - angle;
559 return remainder;
560 }
478 561
479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 563 {
481 if (m == 0.0) return new LSL_Vector(); 564 m_host.AddScriptLPS(1);
482 double x = Math.Atan2(-v.y, v.z); 565 LSL_Vector eul = new LSL_Vector();
483 double sin = v.x / m;
484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
485 double y = Math.Asin(sin);
486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
487 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
488 double z = Math.Atan2(v.y, v.x);
489 566
490 return new LSL_Vector(x, y, z); 567 double sqw = q1.s*q1.s;
568 double sqx = q1.x*q1.x;
569 double sqy = q1.z*q1.z;
570 double sqz = q1.y*q1.y;
571 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
572 double test = q1.x*q1.z + q1.y*q1.s;
573 if (test > 0.4999*unit) { // singularity at north pole
574 eul.z = 2 * Math.Atan2(q1.x,q1.s);
575 eul.y = Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 if (test < -0.4999*unit) { // singularity at south pole
580 eul.z = -2 * Math.Atan2(q1.x,q1.s);
581 eul.y = -Math.PI/2;
582 eul.x = 0;
583 return eul;
584 }
585 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
586 eul.y = Math.Asin(2*test/unit);
587 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
588 return eul;
491 } 589 }
492 590
493 /* From wiki: 591 /* From wiki:
@@ -689,77 +787,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 787 {
690 //A and B should both be normalized 788 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 789 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 790 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 791 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 792
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 793 double dotProduct = LSL_Vector.Dot(a, b);
794 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
795 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
796 double angle = Math.Acos(dotProduct / magProduct);
797 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
798 double s = Math.Sin(angle / 2);
799
800 double x = axis.x * s;
801 double y = axis.y * s;
802 double z = axis.z * s;
803 double w = Math.Cos(angle / 2);
804
805 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
806 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
807
808 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
809 */
810
811 // This method mimics the 180 errors found in SL
812 // See www.euclideanspace.com... angleBetween
813 LSL_Vector vec_a = a;
814 LSL_Vector vec_b = b;
815
816 // Eliminate zero length
817 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
818 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
819 if (vec_a_mag < 0.00001 ||
820 vec_b_mag < 0.00001)
696 { 821 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 822 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 823 }
699 else 824
825 // Normalize
826 vec_a = llVecNorm(vec_a);
827 vec_b = llVecNorm(vec_b);
828
829 // Calculate axis and rotation angle
830 LSL_Vector axis = vec_a % vec_b;
831 LSL_Float cos_theta = vec_a * vec_b;
832
833 // Check if parallel
834 if (cos_theta > 0.99999)
700 { 835 {
701 a = LSL_Vector.Norm(a); 836 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 837 }
703 double dotProduct = LSL_Vector.Dot(a, b); 838
704 // There are two degenerate cases possible. These are for vectors 180 or 839 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 840 else if (cos_theta < -0.99999)
706 // 841 {
707 // Check for vectors 180 degrees apart. 842 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 843 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 844 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 845 }
711 // First assume X axis is orthogonal to the vectors. 846 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 847 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 848 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 849 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 850 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 851 s = Math.Cos(theta);
717 { 852 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 853 x = axis.x * t;
719 } 854 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 855 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 856 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 857 }
760 return rotBetween;
761 } 858 }
762 859
763 public void llWhisper(int channelID, string text) 860 public void llWhisper(int channelID, string text)
764 { 861 {
765 m_host.AddScriptLPS(1); 862 m_host.AddScriptLPS(1);
@@ -779,6 +876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 876 {
780 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
781 878
879 if (channelID == 0)
880 m_SayShoutCount++;
881
882 if (m_SayShoutCount >= 11)
883 ScriptSleep(2000);
884
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 885 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 886 {
784 Console.WriteLine(text); 887 Console.WriteLine(text);
@@ -801,6 +904,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 904 {
802 m_host.AddScriptLPS(1); 905 m_host.AddScriptLPS(1);
803 906
907 if (channelID == 0)
908 m_SayShoutCount++;
909
910 if (m_SayShoutCount >= 11)
911 ScriptSleep(2000);
912
804 if (text.Length > 1023) 913 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 914 text = text.Substring(0, 1023);
806 915
@@ -1101,10 +1210,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1210 return detectedParams.TouchUV;
1102 } 1211 }
1103 1212
1213 [DebuggerNonUserCode]
1104 public virtual void llDie() 1214 public virtual void llDie()
1105 { 1215 {
1106 m_host.AddScriptLPS(1); 1216 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1217 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1218 }
1109 1219
1110 public LSL_Float llGround(LSL_Vector offset) 1220 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1287
1178 public void llSetStatus(int status, int value) 1288 public void llSetStatus(int status, int value)
1179 { 1289 {
1290 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1291 return;
1180 m_host.AddScriptLPS(1); 1292 m_host.AddScriptLPS(1);
1181 1293
1182 int statusrotationaxis = 0; 1294 int statusrotationaxis = 0;
@@ -1406,6 +1518,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1518 {
1407 m_host.AddScriptLPS(1); 1519 m_host.AddScriptLPS(1);
1408 1520
1521 SetColor(m_host, color, face);
1522 }
1523
1524 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1525 {
1526 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1527 return;
1528
1529 Primitive.TextureEntry tex = part.Shape.Textures;
1530 Color4 texcolor;
1531 if (face >= 0 && face < GetNumberOfSides(part))
1532 {
1533 texcolor = tex.CreateFace((uint)face).RGBA;
1534 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1535 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1536 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1537 tex.FaceTextures[face].RGBA = texcolor;
1538 part.UpdateTextureEntry(tex.GetBytes());
1539 return;
1540 }
1541 else if (face == ScriptBaseClass.ALL_SIDES)
1542 {
1543 for (uint i = 0; i < GetNumberOfSides(part); i++)
1544 {
1545 if (tex.FaceTextures[i] != null)
1546 {
1547 texcolor = tex.FaceTextures[i].RGBA;
1548 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1549 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1550 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1551 tex.FaceTextures[i].RGBA = texcolor;
1552 }
1553 texcolor = tex.DefaultTexture.RGBA;
1554 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1555 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1556 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1557 tex.DefaultTexture.RGBA = texcolor;
1558 }
1559 part.UpdateTextureEntry(tex.GetBytes());
1560 return;
1561 }
1562
1409 if (face == ScriptBaseClass.ALL_SIDES) 1563 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1564 face = SceneObjectPart.ALL_SIDES;
1411 1565
@@ -1414,6 +1568,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1568
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1569 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1570 {
1571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1572 return;
1573
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1574 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1575 MappingType textype;
1419 textype = MappingType.Default; 1576 textype = MappingType.Default;
@@ -1444,6 +1601,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1601
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1602 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1603 {
1604 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1605 return;
1606
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1607 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1608 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1609 {
@@ -1469,6 +1629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1629
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1630 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1631 {
1632 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1633 return;
1472 1634
1473 Shininess sval = new Shininess(); 1635 Shininess sval = new Shininess();
1474 1636
@@ -1519,6 +1681,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1681
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1682 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1686
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1687 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1688 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1689 {
@@ -1579,13 +1744,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1744 m_host.AddScriptLPS(1);
1580 1745
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1746 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1747 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1748 {
1584 SetAlpha(part, alpha, face); 1749 try
1750 {
1751 parts[0].ParentGroup.areUpdatesSuspended = true;
1752 foreach (SceneObjectPart part in parts)
1753 SetAlpha(part, alpha, face);
1754 }
1755 finally
1756 {
1757 parts[0].ParentGroup.areUpdatesSuspended = false;
1758 }
1759 }
1585 } 1760 }
1586 1761
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1762 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1763 {
1764 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1765 return;
1766
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1767 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1768 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1769 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1816 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1817 float wind, float tension, LSL_Vector Force)
1640 { 1818 {
1641 if (part == null) 1819 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1820 return;
1643 1821
1644 if (flexi) 1822 if (flexi)
@@ -1672,7 +1850,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1672 /// <param name="falloff"></param> 1850 /// <param name="falloff"></param>
1673 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1851 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1674 { 1852 {
1675 if (part == null) 1853 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1676 return; 1854 return;
1677 1855
1678 if (light) 1856 if (light)
@@ -1749,15 +1927,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1749 m_host.AddScriptLPS(1); 1927 m_host.AddScriptLPS(1);
1750 1928
1751 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1929 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1752 1930 if (parts.Count > 0)
1753 foreach (SceneObjectPart part in parts) 1931 {
1754 SetTexture(part, texture, face); 1932 try
1755 1933 {
1934 parts[0].ParentGroup.areUpdatesSuspended = true;
1935 foreach (SceneObjectPart part in parts)
1936 SetTexture(part, texture, face);
1937 }
1938 finally
1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = false;
1941 }
1942 }
1756 ScriptSleep(200); 1943 ScriptSleep(200);
1757 } 1944 }
1758 1945
1759 protected void SetTexture(SceneObjectPart part, string texture, int face) 1946 protected void SetTexture(SceneObjectPart part, string texture, int face)
1760 { 1947 {
1948 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1949 return;
1950
1761 UUID textureID = new UUID(); 1951 UUID textureID = new UUID();
1762 1952
1763 textureID = InventoryKey(texture, (int)AssetType.Texture); 1953 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1802,6 +1992,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1802 1992
1803 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1993 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1804 { 1994 {
1995 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1996 return;
1997
1805 Primitive.TextureEntry tex = part.Shape.Textures; 1998 Primitive.TextureEntry tex = part.Shape.Textures;
1806 if (face >= 0 && face < GetNumberOfSides(part)) 1999 if (face >= 0 && face < GetNumberOfSides(part))
1807 { 2000 {
@@ -1838,6 +2031,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1838 2031
1839 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2032 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1840 { 2033 {
2034 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2035 return;
2036
1841 Primitive.TextureEntry tex = part.Shape.Textures; 2037 Primitive.TextureEntry tex = part.Shape.Textures;
1842 if (face >= 0 && face < GetNumberOfSides(part)) 2038 if (face >= 0 && face < GetNumberOfSides(part))
1843 { 2039 {
@@ -1874,6 +2070,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 2070
1875 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2071 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1876 { 2072 {
2073 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2074 return;
2075
1877 Primitive.TextureEntry tex = part.Shape.Textures; 2076 Primitive.TextureEntry tex = part.Shape.Textures;
1878 if (face >= 0 && face < GetNumberOfSides(part)) 2077 if (face >= 0 && face < GetNumberOfSides(part))
1879 { 2078 {
@@ -1980,24 +2179,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 2179
1981 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2180 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1982 { 2181 {
1983 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2182 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1984 LSL_Vector currentPos = GetPartLocalPos(part); 2183 return;
1985 2184
1986 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2185 LSL_Vector currentPos = GetPartLocalPos(part);
1987 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2186 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1988 2187
1989 if (part.ParentGroup.RootPart == part) 2188 if (part.ParentGroup.RootPart == part)
1990 { 2189 {
1991 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1992 targetPos.z = ground;
1993 SceneObjectGroup parent = part.ParentGroup; 2190 SceneObjectGroup parent = part.ParentGroup;
1994 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2191 Util.FireAndForget(delegate(object x) {
1995 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2192 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
2193 });
1996 } 2194 }
1997 else 2195 else
1998 { 2196 {
1999 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2197 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2000 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2001 SceneObjectGroup parent = part.ParentGroup; 2198 SceneObjectGroup parent = part.ParentGroup;
2002 parent.HasGroupChanged = true; 2199 parent.HasGroupChanged = true;
2003 parent.ScheduleGroupForTerseUpdate(); 2200 parent.ScheduleGroupForTerseUpdate();
@@ -2028,11 +2225,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2028 } 2225 }
2029 else 2226 else
2030 { 2227 {
2031 if (m_host.IsRoot) 2228 if (part.IsRoot)
2032 { 2229 {
2033 return new LSL_Vector(m_host.AttachedPos.X, 2230 return new LSL_Vector(part.AttachedPos.X,
2034 m_host.AttachedPos.Y, 2231 part.AttachedPos.Y,
2035 m_host.AttachedPos.Z); 2232 part.AttachedPos.Z);
2036 } 2233 }
2037 else 2234 else
2038 { 2235 {
@@ -2048,9 +2245,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2048 m_host.AddScriptLPS(1); 2245 m_host.AddScriptLPS(1);
2049 2246
2050 // try to let this work as in SL... 2247 // try to let this work as in SL...
2051 if (m_host.ParentID == 0) 2248 if (m_host.LinkNum < 2)
2052 { 2249 {
2053 // special case: If we are root, rotate complete SOG to new rotation 2250 // Special case: If we are root, rotate complete SOG to new
2251 // rotation.
2252 // We are root if the link number is 0 (single prim) or 1
2253 // (root prim). ParentID may be nonzero in attachments and
2254 // using it would cause attachments and HUDs to rotate
2255 // to the wrong positions.
2054 SetRot(m_host, Rot2Quaternion(rot)); 2256 SetRot(m_host, Rot2Quaternion(rot));
2055 } 2257 }
2056 else 2258 else
@@ -2075,6 +2277,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 2277
2076 protected void SetRot(SceneObjectPart part, Quaternion rot) 2278 protected void SetRot(SceneObjectPart part, Quaternion rot)
2077 { 2279 {
2280 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2281 return;
2282
2078 part.UpdateRotation(rot); 2283 part.UpdateRotation(rot);
2079 // Update rotation does not move the object in the physics scene if it's a linkset. 2284 // Update rotation does not move the object in the physics scene if it's a linkset.
2080 2285
@@ -2698,12 +2903,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2698 2903
2699 m_host.AddScriptLPS(1); 2904 m_host.AddScriptLPS(1);
2700 2905
2906 m_host.TaskInventory.LockItemsForRead(true);
2701 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2907 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2702 2908 m_host.TaskInventory.LockItemsForRead(false);
2703 lock (m_host.TaskInventory)
2704 {
2705 item = m_host.TaskInventory[invItemID];
2706 }
2707 2909
2708 if (item.PermsGranter == UUID.Zero) 2910 if (item.PermsGranter == UUID.Zero)
2709 return 0; 2911 return 0;
@@ -2771,64 +2973,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2771 { 2973 {
2772 m_host.AddScriptLPS(1); 2974 m_host.AddScriptLPS(1);
2773 2975
2774 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) 2976 Util.FireAndForget(delegate (object x)
2775 return; 2977 {
2776 float dist = (float)llVecDist(llGetPos(), pos); 2978 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
2979 return;
2980 float dist = (float)llVecDist(llGetPos(), pos);
2777 2981
2778 if (dist > m_ScriptDistanceFactor * 10.0f) 2982 if (dist > m_ScriptDistanceFactor * 10.0f)
2779 return; 2983 return;
2780 2984
2781 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2985 //Clone is thread-safe
2986 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2782 2987
2783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2988 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
2784 {
2785 if (inv.Value.Name == inventory)
2786 { 2989 {
2787 // make sure we're an object. 2990 if (inv.Value.Name == inventory)
2788 if (inv.Value.InvType != (int)InventoryType.Object)
2789 { 2991 {
2790 llSay(0, "Unable to create requested object. Object is missing from database."); 2992 // make sure we're an object.
2791 return; 2993 if (inv.Value.InvType != (int)InventoryType.Object)
2792 } 2994 {
2995 llSay(0, "Unable to create requested object. Object is missing from database.");
2996 return;
2997 }
2793 2998
2794 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); 2999 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
2795 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z); 3000 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
2796 3001
2797 // need the magnitude later 3002 // need the magnitude later
2798 float velmag = (float)Util.GetMagnitude(llvel); 3003 // float velmag = (float)Util.GetMagnitude(llvel);
2799 3004
2800 SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param); 3005 SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
2801 3006
2802 // If either of these are null, then there was an unknown error. 3007 // If either of these are null, then there was an unknown error.
2803 if (new_group == null) 3008 if (new_group == null)
2804 continue; 3009 continue;
2805 3010
2806 // objects rezzed with this method are die_at_edge by default. 3011 // objects rezzed with this method are die_at_edge by default.
2807 new_group.RootPart.SetDieAtEdge(true); 3012 new_group.RootPart.SetDieAtEdge(true);
2808 3013
2809 new_group.ResumeScripts(); 3014 new_group.ResumeScripts();
2810 3015
2811 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( 3016 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
2812 "object_rez", new Object[] { 3017 "object_rez", new Object[] {
2813 new LSL_String( 3018 new LSL_String(
2814 new_group.RootPart.UUID.ToString()) }, 3019 new_group.RootPart.UUID.ToString()) },
2815 new DetectParams[0])); 3020 new DetectParams[0]));
2816 3021
2817 float groupmass = new_group.GetMass(); 3022 float groupmass = new_group.GetMass();
2818 3023
2819 if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero) 3024 if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero)
2820 { 3025 {
2821 //Recoil. 3026 //Recoil.
2822 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3027 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
3028 }
3029 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3030 return;
2823 } 3031 }
2824 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
2825 ScriptSleep((int)((groupmass * velmag) / 10));
2826 ScriptSleep(100);
2827 return;
2828 } 3032 }
2829 }
2830 3033
2831 llSay(0, "Could not find object " + inventory); 3034 llSay(0, "Could not find object " + inventory);
3035 });
3036
3037 //ScriptSleep((int)((groupmass * velmag) / 10));
3038 ScriptSleep(100);
2832 } 3039 }
2833 3040
2834 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3041 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
@@ -2839,34 +3046,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 public void llLookAt(LSL_Vector target, double strength, double damping) 3046 public void llLookAt(LSL_Vector target, double strength, double damping)
2840 { 3047 {
2841 m_host.AddScriptLPS(1); 3048 m_host.AddScriptLPS(1);
2842 // Determine where we are looking from
2843 LSL_Vector from = llGetPos();
2844 3049
2845 // Work out the normalised vector from the source to the target 3050 // Get the normalized vector to the target
2846 LSL_Vector delta = llVecNorm(target - from); 3051 LSL_Vector d1 = llVecNorm(target - llGetPos());
2847 LSL_Vector angle = new LSL_Vector(0,0,0);
2848 3052
2849 // Calculate the yaw 3053 // Get the bearing (yaw)
2850 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3054 LSL_Vector a1 = new LSL_Vector(0,0,0);
2851 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3055 a1.z = llAtan2(d1.y, d1.x);
2852 3056
2853 // Calculate pitch 3057 // Get the elevation (pitch)
2854 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3058 LSL_Vector a2 = new LSL_Vector(0,0,0);
3059 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2855 3060
2856 // we need to convert from a vector describing 3061 LSL_Rotation r1 = llEuler2Rot(a1);
2857 // the angles of rotation in radians into rotation value 3062 LSL_Rotation r2 = llEuler2Rot(a2);
3063 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2858 3064
2859 LSL_Rotation rot = llEuler2Rot(angle); 3065 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2860
2861 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2862 // set the rotation of the object, copy that behavior
2863 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2864 { 3066 {
2865 llSetRot(rot); 3067 // Do nothing if either value is 0 (this has been checked in SL)
3068 if (strength <= 0.0 || damping <= 0.0)
3069 return;
3070
3071 llSetRot(r3 * r2 * r1);
2866 } 3072 }
2867 else 3073 else
2868 { 3074 {
2869 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3075 if (strength == 0)
3076 {
3077 llSetRot(r3 * r2 * r1);
3078 return;
3079 }
3080
3081 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2870 } 3082 }
2871 } 3083 }
2872 3084
@@ -2916,13 +3128,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3128 {
2917 TaskInventoryItem item; 3129 TaskInventoryItem item;
2918 3130
2919 lock (m_host.TaskInventory) 3131 m_host.TaskInventory.LockItemsForRead(true);
3132 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2920 { 3133 {
2921 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3134 m_host.TaskInventory.LockItemsForRead(false);
2922 return; 3135 return;
2923 else 3136 }
2924 item = m_host.TaskInventory[InventorySelf()]; 3137 else
3138 {
3139 item = m_host.TaskInventory[InventorySelf()];
2925 } 3140 }
3141 m_host.TaskInventory.LockItemsForRead(false);
2926 3142
2927 if (item.PermsGranter != UUID.Zero) 3143 if (item.PermsGranter != UUID.Zero)
2928 { 3144 {
@@ -2944,13 +3160,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2944 { 3160 {
2945 TaskInventoryItem item; 3161 TaskInventoryItem item;
2946 3162
3163 m_host.TaskInventory.LockItemsForRead(true);
2947 lock (m_host.TaskInventory) 3164 lock (m_host.TaskInventory)
2948 { 3165 {
3166
2949 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3167 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3168 {
3169 m_host.TaskInventory.LockItemsForRead(false);
2950 return; 3170 return;
3171 }
2951 else 3172 else
3173 {
2952 item = m_host.TaskInventory[InventorySelf()]; 3174 item = m_host.TaskInventory[InventorySelf()];
3175 }
2953 } 3176 }
3177 m_host.TaskInventory.LockItemsForRead(false);
2954 3178
2955 m_host.AddScriptLPS(1); 3179 m_host.AddScriptLPS(1);
2956 3180
@@ -2982,19 +3206,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2982 { 3206 {
2983 m_host.AddScriptLPS(1); 3207 m_host.AddScriptLPS(1);
2984 3208
2985// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2986// return;
2987
2988 TaskInventoryItem item; 3209 TaskInventoryItem item;
2989 3210
2990 lock (m_host.TaskInventory) 3211 m_host.TaskInventory.LockItemsForRead(true);
3212
3213 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2991 { 3214 {
2992 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3215 m_host.TaskInventory.LockItemsForRead(false);
2993 return; 3216 return;
2994 else 3217 }
2995 item = m_host.TaskInventory[InventorySelf()]; 3218 else
3219 {
3220 item = m_host.TaskInventory[InventorySelf()];
2996 } 3221 }
2997 3222
3223 m_host.TaskInventory.LockItemsForRead(false);
3224
2998 if (item.PermsGranter != m_host.OwnerID) 3225 if (item.PermsGranter != m_host.OwnerID)
2999 return; 3226 return;
3000 3227
@@ -3019,13 +3246,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 3246
3020 TaskInventoryItem item; 3247 TaskInventoryItem item;
3021 3248
3022 lock (m_host.TaskInventory) 3249 m_host.TaskInventory.LockItemsForRead(true);
3250
3251 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3023 { 3252 {
3024 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3253 m_host.TaskInventory.LockItemsForRead(false);
3025 return; 3254 return;
3026 else
3027 item = m_host.TaskInventory[InventorySelf()];
3028 } 3255 }
3256 else
3257 {
3258 item = m_host.TaskInventory[InventorySelf()];
3259 }
3260 m_host.TaskInventory.LockItemsForRead(false);
3261
3029 3262
3030 if (item.PermsGranter != m_host.OwnerID) 3263 if (item.PermsGranter != m_host.OwnerID)
3031 return; 3264 return;
@@ -3072,6 +3305,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3072 3305
3073 public void llInstantMessage(string user, string message) 3306 public void llInstantMessage(string user, string message)
3074 { 3307 {
3308 UUID result;
3309 if (!UUID.TryParse(user, out result))
3310 {
3311 ShoutError("An invalid key was passed to llInstantMessage");
3312 ScriptSleep(2000);
3313 return;
3314 }
3315
3316
3075 m_host.AddScriptLPS(1); 3317 m_host.AddScriptLPS(1);
3076 3318
3077 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3319 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3086,14 +3328,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3086 UUID friendTransactionID = UUID.Random(); 3328 UUID friendTransactionID = UUID.Random();
3087 3329
3088 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3330 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3089 3331
3090 GridInstantMessage msg = new GridInstantMessage(); 3332 GridInstantMessage msg = new GridInstantMessage();
3091 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3333 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3092 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3334 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3093 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3335 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3094// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3336// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3095// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3337// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3096 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3338// DateTime dt = DateTime.UtcNow;
3339//
3340// // Ticks from UtcNow, but make it look like local. Evil, huh?
3341// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3342//
3343// try
3344// {
3345// // Convert that to the PST timezone
3346// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3347// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3348// }
3349// catch
3350// {
3351// // No logging here, as it could be VERY spammy
3352// }
3353//
3354// // And make it look local again to fool the unix time util
3355// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3356
3357 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3358
3097 //if (client != null) 3359 //if (client != null)
3098 //{ 3360 //{
3099 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3361 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3107,12 +3369,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3107 msg.message = message.Substring(0, 1024); 3369 msg.message = message.Substring(0, 1024);
3108 else 3370 else
3109 msg.message = message; 3371 msg.message = message;
3110 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3372 msg.dialog = (byte)19; // MessageFromObject
3111 msg.fromGroup = false;// fromGroup; 3373 msg.fromGroup = false;// fromGroup;
3112 msg.offline = (byte)0; //offline; 3374 msg.offline = (byte)0; //offline;
3113 msg.ParentEstateID = 0; //ParentEstateID; 3375 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3114 msg.Position = new Vector3(m_host.AbsolutePosition); 3376 msg.Position = new Vector3(m_host.AbsolutePosition);
3115 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3377 msg.RegionID = World.RegionInfo.RegionID.Guid;
3116 msg.binaryBucket 3378 msg.binaryBucket
3117 = Util.StringToBytes256( 3379 = Util.StringToBytes256(
3118 "{0}/{1}/{2}/{3}", 3380 "{0}/{1}/{2}/{3}",
@@ -3140,7 +3402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3140 } 3402 }
3141 3403
3142 emailModule.SendEmail(m_host.UUID, address, subject, message); 3404 emailModule.SendEmail(m_host.UUID, address, subject, message);
3143 ScriptSleep(20000); 3405 ScriptSleep(15000);
3144 } 3406 }
3145 3407
3146 public void llGetNextEmail(string address, string subject) 3408 public void llGetNextEmail(string address, string subject)
@@ -3279,14 +3541,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3279 3541
3280 TaskInventoryItem item; 3542 TaskInventoryItem item;
3281 3543
3282 lock (m_host.TaskInventory) 3544 m_host.TaskInventory.LockItemsForRead(true);
3545 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3283 { 3546 {
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3547 m_host.TaskInventory.LockItemsForRead(false);
3285 return; 3548 return;
3286 else
3287 item = m_host.TaskInventory[InventorySelf()];
3288 } 3549 }
3289 3550 else
3551 {
3552 item = m_host.TaskInventory[InventorySelf()];
3553 }
3554 m_host.TaskInventory.LockItemsForRead(false);
3290 if (item.PermsGranter == UUID.Zero) 3555 if (item.PermsGranter == UUID.Zero)
3291 return; 3556 return;
3292 3557
@@ -3316,13 +3581,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3316 3581
3317 TaskInventoryItem item; 3582 TaskInventoryItem item;
3318 3583
3319 lock (m_host.TaskInventory) 3584 m_host.TaskInventory.LockItemsForRead(true);
3585 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3320 { 3586 {
3321 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3587 m_host.TaskInventory.LockItemsForRead(false);
3322 return; 3588 return;
3323 else 3589 }
3324 item = m_host.TaskInventory[InventorySelf()]; 3590 else
3591 {
3592 item = m_host.TaskInventory[InventorySelf()];
3325 } 3593 }
3594 m_host.TaskInventory.LockItemsForRead(false);
3595
3326 3596
3327 if (item.PermsGranter == UUID.Zero) 3597 if (item.PermsGranter == UUID.Zero)
3328 return; 3598 return;
@@ -3389,10 +3659,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3659
3390 TaskInventoryItem item; 3660 TaskInventoryItem item;
3391 3661
3392 lock (m_host.TaskInventory) 3662
3663 m_host.TaskInventory.LockItemsForRead(true);
3664 if (!m_host.TaskInventory.ContainsKey(invItemID))
3665 {
3666 m_host.TaskInventory.LockItemsForRead(false);
3667 return;
3668 }
3669 else
3393 { 3670 {
3394 item = m_host.TaskInventory[invItemID]; 3671 item = m_host.TaskInventory[invItemID];
3395 } 3672 }
3673 m_host.TaskInventory.LockItemsForRead(false);
3396 3674
3397 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3675 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3398 { 3676 {
@@ -3420,15 +3698,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3698 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3421 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3699 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3422 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3700 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3701 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3423 ScriptBaseClass.PERMISSION_ATTACH; 3702 ScriptBaseClass.PERMISSION_ATTACH;
3424 3703
3425 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3704 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3426 { 3705 {
3427 lock (m_host.TaskInventory) 3706 m_host.TaskInventory.LockItemsForWrite(true);
3428 { 3707 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3429 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3708 m_host.TaskInventory[invItemID].PermsMask = perm;
3430 m_host.TaskInventory[invItemID].PermsMask = perm; 3709 m_host.TaskInventory.LockItemsForWrite(false);
3431 }
3432 3710
3433 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3711 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3434 "run_time_permissions", new Object[] { 3712 "run_time_permissions", new Object[] {
@@ -3438,28 +3716,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 return; 3716 return;
3439 } 3717 }
3440 } 3718 }
3441 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3719 else
3442 { 3720 {
3443 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3721 bool sitting = false;
3444 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3722 if (m_host.SitTargetAvatar == agentID)
3445 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3723 {
3446 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3724 sitting = true;
3447 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3725 }
3726 else
3727 {
3728 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3729 {
3730 if (p.SitTargetAvatar == agentID)
3731 sitting = true;
3732 }
3733 }
3448 3734
3449 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3735 if (sitting)
3450 { 3736 {
3451 lock (m_host.TaskInventory) 3737 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3738 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3739 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3740 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3741 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3742
3743 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3452 { 3744 {
3745 m_host.TaskInventory.LockItemsForWrite(true);
3453 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3746 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3454 m_host.TaskInventory[invItemID].PermsMask = perm; 3747 m_host.TaskInventory[invItemID].PermsMask = perm;
3455 } 3748 m_host.TaskInventory.LockItemsForWrite(false);
3456 3749
3457 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3750 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3458 "run_time_permissions", new Object[] { 3751 "run_time_permissions", new Object[] {
3459 new LSL_Integer(perm) }, 3752 new LSL_Integer(perm) },
3460 new DetectParams[0])); 3753 new DetectParams[0]));
3461 3754
3462 return; 3755 return;
3756 }
3463 } 3757 }
3464 } 3758 }
3465 3759
@@ -3473,11 +3767,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 3767
3474 if (!m_waitingForScriptAnswer) 3768 if (!m_waitingForScriptAnswer)
3475 { 3769 {
3476 lock (m_host.TaskInventory) 3770 m_host.TaskInventory.LockItemsForWrite(true);
3477 { 3771 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3478 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3772 m_host.TaskInventory[invItemID].PermsMask = 0;
3479 m_host.TaskInventory[invItemID].PermsMask = 0; 3773 m_host.TaskInventory.LockItemsForWrite(false);
3480 }
3481 3774
3482 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3775 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3483 m_waitingForScriptAnswer=true; 3776 m_waitingForScriptAnswer=true;
@@ -3512,10 +3805,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3805 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3513 llReleaseControls(); 3806 llReleaseControls();
3514 3807
3515 lock (m_host.TaskInventory) 3808
3516 { 3809 m_host.TaskInventory.LockItemsForWrite(true);
3517 m_host.TaskInventory[invItemID].PermsMask = answer; 3810 m_host.TaskInventory[invItemID].PermsMask = answer;
3518 } 3811 m_host.TaskInventory.LockItemsForWrite(false);
3812
3519 3813
3520 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3814 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3521 "run_time_permissions", new Object[] { 3815 "run_time_permissions", new Object[] {
@@ -3527,16 +3821,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 { 3821 {
3528 m_host.AddScriptLPS(1); 3822 m_host.AddScriptLPS(1);
3529 3823
3530 lock (m_host.TaskInventory) 3824 m_host.TaskInventory.LockItemsForRead(true);
3825
3826 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3531 { 3827 {
3532 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3828 if (item.Type == 10 && item.ItemID == m_itemID)
3533 { 3829 {
3534 if (item.Type == 10 && item.ItemID == m_itemID) 3830 m_host.TaskInventory.LockItemsForRead(false);
3535 { 3831 return item.PermsGranter.ToString();
3536 return item.PermsGranter.ToString();
3537 }
3538 } 3832 }
3539 } 3833 }
3834 m_host.TaskInventory.LockItemsForRead(false);
3540 3835
3541 return UUID.Zero.ToString(); 3836 return UUID.Zero.ToString();
3542 } 3837 }
@@ -3545,19 +3840,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3545 { 3840 {
3546 m_host.AddScriptLPS(1); 3841 m_host.AddScriptLPS(1);
3547 3842
3548 lock (m_host.TaskInventory) 3843 m_host.TaskInventory.LockItemsForRead(true);
3844
3845 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3549 { 3846 {
3550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3847 if (item.Type == 10 && item.ItemID == m_itemID)
3551 { 3848 {
3552 if (item.Type == 10 && item.ItemID == m_itemID) 3849 int perms = item.PermsMask;
3553 { 3850 if (m_automaticLinkPermission)
3554 int perms = item.PermsMask; 3851 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3555 if (m_automaticLinkPermission) 3852 m_host.TaskInventory.LockItemsForRead(false);
3556 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3853 return perms;
3557 return perms;
3558 }
3559 } 3854 }
3560 } 3855 }
3856 m_host.TaskInventory.LockItemsForRead(false);
3561 3857
3562 return 0; 3858 return 0;
3563 } 3859 }
@@ -3579,9 +3875,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3875 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3876 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3877 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3878 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3879 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3880 try
3881 {
3882 parts[0].ParentGroup.areUpdatesSuspended = true;
3883 foreach (SceneObjectPart part in parts)
3884 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3885 }
3886 finally
3887 {
3888 parts[0].ParentGroup.areUpdatesSuspended = false;
3889 }
3890 }
3585 } 3891 }
3586 3892
3587 public void llCreateLink(string target, int parent) 3893 public void llCreateLink(string target, int parent)
@@ -3594,11 +3900,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3594 return; 3900 return;
3595 3901
3596 TaskInventoryItem item; 3902 TaskInventoryItem item;
3597 lock (m_host.TaskInventory) 3903 m_host.TaskInventory.LockItemsForRead(true);
3598 { 3904 item = m_host.TaskInventory[invItemID];
3599 item = m_host.TaskInventory[invItemID]; 3905 m_host.TaskInventory.LockItemsForRead(false);
3600 } 3906
3601
3602 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3907 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3603 && !m_automaticLinkPermission) 3908 && !m_automaticLinkPermission)
3604 { 3909 {
@@ -3615,11 +3920,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3615 3920
3616 if (targetPart.ParentGroup.AttachmentPoint != 0) 3921 if (targetPart.ParentGroup.AttachmentPoint != 0)
3617 return; // Fail silently if attached 3922 return; // Fail silently if attached
3923
3924 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3925 return;
3926
3618 SceneObjectGroup parentPrim = null, childPrim = null; 3927 SceneObjectGroup parentPrim = null, childPrim = null;
3619 3928
3620 if (targetPart != null) 3929 if (targetPart != null)
3621 { 3930 {
3622 if (parent != 0) { 3931 if (parent != 0)
3932 {
3623 parentPrim = m_host.ParentGroup; 3933 parentPrim = m_host.ParentGroup;
3624 childPrim = targetPart.ParentGroup; 3934 childPrim = targetPart.ParentGroup;
3625 } 3935 }
@@ -3631,7 +3941,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3631 3941
3632 // Required for linking 3942 // Required for linking
3633 childPrim.RootPart.ClearUpdateSchedule(); 3943 childPrim.RootPart.ClearUpdateSchedule();
3634 parentPrim.LinkToGroup(childPrim); 3944 parentPrim.LinkToGroup(childPrim, true);
3635 } 3945 }
3636 3946
3637 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3947 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3650,16 +3960,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3650 m_host.AddScriptLPS(1); 3960 m_host.AddScriptLPS(1);
3651 UUID invItemID = InventorySelf(); 3961 UUID invItemID = InventorySelf();
3652 3962
3653 lock (m_host.TaskInventory) 3963 m_host.TaskInventory.LockItemsForRead(true);
3654 {
3655 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3964 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3656 && !m_automaticLinkPermission) 3965 && !m_automaticLinkPermission)
3657 { 3966 {
3658 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3967 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3968 m_host.TaskInventory.LockItemsForRead(false);
3659 return; 3969 return;
3660 } 3970 }
3661 } 3971 m_host.TaskInventory.LockItemsForRead(false);
3662 3972
3663 if (linknum < ScriptBaseClass.LINK_THIS) 3973 if (linknum < ScriptBaseClass.LINK_THIS)
3664 return; 3974 return;
3665 3975
@@ -3698,10 +4008,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 // Restructuring Multiple Prims. 4008 // Restructuring Multiple Prims.
3699 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4009 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3700 parts.Remove(parentPrim.RootPart); 4010 parts.Remove(parentPrim.RootPart);
3701 foreach (SceneObjectPart part in parts) 4011 if (parts.Count > 0)
3702 { 4012 {
3703 parentPrim.DelinkFromGroup(part.LocalId, true); 4013 try
4014 {
4015 parts[0].ParentGroup.areUpdatesSuspended = true;
4016 foreach (SceneObjectPart part in parts)
4017 {
4018 parentPrim.DelinkFromGroup(part.LocalId, true);
4019 }
4020 }
4021 finally
4022 {
4023 parts[0].ParentGroup.areUpdatesSuspended = false;
4024 }
3704 } 4025 }
4026
3705 parentPrim.HasGroupChanged = true; 4027 parentPrim.HasGroupChanged = true;
3706 parentPrim.ScheduleGroupForFullUpdate(); 4028 parentPrim.ScheduleGroupForFullUpdate();
3707 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4029 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3710,12 +4032,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3710 { 4032 {
3711 SceneObjectPart newRoot = parts[0]; 4033 SceneObjectPart newRoot = parts[0];
3712 parts.Remove(newRoot); 4034 parts.Remove(newRoot);
3713 foreach (SceneObjectPart part in parts) 4035
4036 try
3714 { 4037 {
3715 // Required for linking 4038 parts[0].ParentGroup.areUpdatesSuspended = true;
3716 part.ClearUpdateSchedule(); 4039 foreach (SceneObjectPart part in parts)
3717 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4040 {
4041 part.ClearUpdateSchedule();
4042 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4043 }
3718 } 4044 }
4045 finally
4046 {
4047 parts[0].ParentGroup.areUpdatesSuspended = false;
4048 }
4049
4050
3719 newRoot.ParentGroup.HasGroupChanged = true; 4051 newRoot.ParentGroup.HasGroupChanged = true;
3720 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4052 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3721 } 4053 }
@@ -3735,6 +4067,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 public void llBreakAllLinks() 4067 public void llBreakAllLinks()
3736 { 4068 {
3737 m_host.AddScriptLPS(1); 4069 m_host.AddScriptLPS(1);
4070
4071 UUID invItemID = InventorySelf();
4072
4073 TaskInventoryItem item;
4074 m_host.TaskInventory.LockItemsForRead(true);
4075 item = m_host.TaskInventory[invItemID];
4076 m_host.TaskInventory.LockItemsForRead(false);
4077
4078 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4079 && !m_automaticLinkPermission)
4080 {
4081 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4082 return;
4083 }
4084
3738 SceneObjectGroup parentPrim = m_host.ParentGroup; 4085 SceneObjectGroup parentPrim = m_host.ParentGroup;
3739 if (parentPrim.AttachmentPoint != 0) 4086 if (parentPrim.AttachmentPoint != 0)
3740 return; // Fail silently if attached 4087 return; // Fail silently if attached
@@ -3754,25 +4101,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 public LSL_String llGetLinkKey(int linknum) 4101 public LSL_String llGetLinkKey(int linknum)
3755 { 4102 {
3756 m_host.AddScriptLPS(1); 4103 m_host.AddScriptLPS(1);
3757 List<UUID> keytable = new List<UUID>();
3758 // parse for sitting avatare-uuids
3759 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3760 {
3761 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
3762 keytable.Add(presence.UUID);
3763 });
3764
3765 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3766 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3767 {
3768 return keytable[totalprims - linknum].ToString();
3769 }
3770
3771 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3772 {
3773 return m_host.UUID.ToString();
3774 }
3775
3776 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4104 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3777 if (part != null) 4105 if (part != null)
3778 { 4106 {
@@ -3780,6 +4108,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3780 } 4108 }
3781 else 4109 else
3782 { 4110 {
4111 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4112 {
4113 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4114
4115 if (linknum < 0)
4116 return UUID.Zero.ToString();
4117
4118 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4119 if (avatars.Count > linknum)
4120 {
4121 return avatars[linknum].UUID.ToString();
4122 }
4123 }
3783 return UUID.Zero.ToString(); 4124 return UUID.Zero.ToString();
3784 } 4125 }
3785 } 4126 }
@@ -3878,17 +4219,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3878 m_host.AddScriptLPS(1); 4219 m_host.AddScriptLPS(1);
3879 int count = 0; 4220 int count = 0;
3880 4221
3881 lock (m_host.TaskInventory) 4222 m_host.TaskInventory.LockItemsForRead(true);
4223 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3882 { 4224 {
3883 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4225 if (inv.Value.Type == type || type == -1)
3884 { 4226 {
3885 if (inv.Value.Type == type || type == -1) 4227 count = count + 1;
3886 {
3887 count = count + 1;
3888 }
3889 } 4228 }
3890 } 4229 }
3891 4230
4231 m_host.TaskInventory.LockItemsForRead(false);
3892 return count; 4232 return count;
3893 } 4233 }
3894 4234
@@ -3897,16 +4237,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 m_host.AddScriptLPS(1); 4237 m_host.AddScriptLPS(1);
3898 ArrayList keys = new ArrayList(); 4238 ArrayList keys = new ArrayList();
3899 4239
3900 lock (m_host.TaskInventory) 4240 m_host.TaskInventory.LockItemsForRead(true);
4241 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3901 { 4242 {
3902 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4243 if (inv.Value.Type == type || type == -1)
3903 { 4244 {
3904 if (inv.Value.Type == type || type == -1) 4245 keys.Add(inv.Value.Name);
3905 {
3906 keys.Add(inv.Value.Name);
3907 }
3908 } 4246 }
3909 } 4247 }
4248 m_host.TaskInventory.LockItemsForRead(false);
3910 4249
3911 if (keys.Count == 0) 4250 if (keys.Count == 0)
3912 { 4251 {
@@ -3943,25 +4282,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3943 } 4282 }
3944 4283
3945 // move the first object found with this inventory name 4284 // move the first object found with this inventory name
3946 lock (m_host.TaskInventory) 4285 m_host.TaskInventory.LockItemsForRead(true);
4286 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3947 { 4287 {
3948 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4288 if (inv.Value.Name == inventory)
3949 { 4289 {
3950 if (inv.Value.Name == inventory) 4290 found = true;
3951 { 4291 objId = inv.Key;
3952 found = true; 4292 assetType = inv.Value.Type;
3953 objId = inv.Key; 4293 objName = inv.Value.Name;
3954 assetType = inv.Value.Type; 4294 break;
3955 objName = inv.Value.Name;
3956 break;
3957 }
3958 } 4295 }
3959 } 4296 }
4297 m_host.TaskInventory.LockItemsForRead(false);
3960 4298
3961 if (!found) 4299 if (!found)
3962 { 4300 {
3963 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4301 llSay(0, String.Format("Could not find object '{0}'", inventory));
3964 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4302 return;
4303// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3965 } 4304 }
3966 4305
3967 // check if destination is an object 4306 // check if destination is an object
@@ -3987,48 +4326,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3987 return; 4326 return;
3988 } 4327 }
3989 } 4328 }
4329
3990 // destination is an avatar 4330 // destination is an avatar
3991 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4331 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3992 4332
3993 if (agentItem == null) 4333 if (agentItem == null)
3994 return; 4334 return;
3995 4335
3996 byte[] bucket = new byte[17]; 4336 byte[] bucket = new byte[1];
3997 bucket[0] = (byte)assetType; 4337 bucket[0] = (byte)assetType;
3998 byte[] objBytes = agentItem.ID.GetBytes(); 4338 //byte[] objBytes = agentItem.ID.GetBytes();
3999 Array.Copy(objBytes, 0, bucket, 1, 16); 4339 //Array.Copy(objBytes, 0, bucket, 1, 16);
4000 4340
4001 GridInstantMessage msg = new GridInstantMessage(World, 4341 GridInstantMessage msg = new GridInstantMessage(World,
4002 m_host.UUID, m_host.Name+", an object owned by "+ 4342 m_host.OwnerID, m_host.Name, destId,
4003 resolveName(m_host.OwnerID)+",", destId,
4004 (byte)InstantMessageDialog.TaskInventoryOffered, 4343 (byte)InstantMessageDialog.TaskInventoryOffered,
4005 false, objName+"\n"+m_host.Name+" is located at "+ 4344 false, objName+". "+m_host.Name+" is located at "+
4006 World.RegionInfo.RegionName+" "+ 4345 World.RegionInfo.RegionName+" "+
4007 m_host.AbsolutePosition.ToString(), 4346 m_host.AbsolutePosition.ToString(),
4008 agentItem.ID, true, m_host.AbsolutePosition, 4347 agentItem.ID, true, m_host.AbsolutePosition,
4009 bucket); 4348 bucket);
4010 if (m_TransferModule != null) 4349
4011 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4350 ScenePresence sp;
4351
4352 if (World.TryGetScenePresence(destId, out sp))
4353 {
4354 sp.ControllingClient.SendInstantMessage(msg);
4355 }
4356 else
4357 {
4358 if (m_TransferModule != null)
4359 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4360 }
4361
4362 //This delay should only occur when giving inventory to avatars.
4012 ScriptSleep(3000); 4363 ScriptSleep(3000);
4013 } 4364 }
4014 } 4365 }
4015 4366
4367 [DebuggerNonUserCode]
4016 public void llRemoveInventory(string name) 4368 public void llRemoveInventory(string name)
4017 { 4369 {
4018 m_host.AddScriptLPS(1); 4370 m_host.AddScriptLPS(1);
4019 4371
4020 lock (m_host.TaskInventory) 4372 List<TaskInventoryItem> inv;
4373 try
4021 { 4374 {
4022 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4375 m_host.TaskInventory.LockItemsForRead(true);
4376 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4377 }
4378 finally
4379 {
4380 m_host.TaskInventory.LockItemsForRead(false);
4381 }
4382 foreach (TaskInventoryItem item in inv)
4383 {
4384 if (item.Name == name)
4023 { 4385 {
4024 if (item.Name == name) 4386 if (item.ItemID == m_itemID)
4025 { 4387 throw new ScriptDeleteException();
4026 if (item.ItemID == m_itemID) 4388 else
4027 throw new ScriptDeleteException(); 4389 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4028 else 4390 return;
4029 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4030 return;
4031 }
4032 } 4391 }
4033 } 4392 }
4034 } 4393 }
@@ -4063,112 +4422,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4063 { 4422 {
4064 m_host.AddScriptLPS(1); 4423 m_host.AddScriptLPS(1);
4065 4424
4066 UUID uuid = (UUID)id; 4425 UUID uuid;
4067 PresenceInfo pinfo = null; 4426 if (UUID.TryParse(id, out uuid))
4068 UserAccount account;
4069
4070 UserInfoCacheEntry ce;
4071 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4072 { 4427 {
4073 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4428 PresenceInfo pinfo = null;
4074 if (account == null) 4429 UserAccount account;
4430
4431 UserInfoCacheEntry ce;
4432 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4075 { 4433 {
4076 m_userInfoCache[uuid] = null; // Cache negative 4434 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4077 return UUID.Zero.ToString(); 4435 if (account == null)
4078 } 4436 {
4437 m_userInfoCache[uuid] = null; // Cache negative
4438 return UUID.Zero.ToString();
4439 }
4079 4440
4080 4441
4081 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4442 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4082 if (pinfos != null && pinfos.Length > 0) 4443 if (pinfos != null && pinfos.Length > 0)
4083 {
4084 foreach (PresenceInfo p in pinfos)
4085 { 4444 {
4086 if (p.RegionID != UUID.Zero) 4445 foreach (PresenceInfo p in pinfos)
4087 { 4446 {
4088 pinfo = p; 4447 if (p.RegionID != UUID.Zero)
4448 {
4449 pinfo = p;
4450 }
4089 } 4451 }
4090 } 4452 }
4091 }
4092 4453
4093 ce = new UserInfoCacheEntry(); 4454 ce = new UserInfoCacheEntry();
4094 ce.time = Util.EnvironmentTickCount(); 4455 ce.time = Util.EnvironmentTickCount();
4095 ce.account = account; 4456 ce.account = account;
4096 ce.pinfo = pinfo; 4457 ce.pinfo = pinfo;
4097 } 4458 m_userInfoCache[uuid] = ce;
4098 else 4459 }
4099 { 4460 else
4100 if (ce == null) 4461 {
4101 return UUID.Zero.ToString(); 4462 if (ce == null)
4463 return UUID.Zero.ToString();
4102 4464
4103 account = ce.account; 4465 account = ce.account;
4104 pinfo = ce.pinfo; 4466 pinfo = ce.pinfo;
4105 } 4467 }
4106 4468
4107 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4469 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4108 {
4109 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4110 if (pinfos != null && pinfos.Length > 0)
4111 { 4470 {
4112 foreach (PresenceInfo p in pinfos) 4471 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4472 if (pinfos != null && pinfos.Length > 0)
4113 { 4473 {
4114 if (p.RegionID != UUID.Zero) 4474 foreach (PresenceInfo p in pinfos)
4115 { 4475 {
4116 pinfo = p; 4476 if (p.RegionID != UUID.Zero)
4477 {
4478 pinfo = p;
4479 }
4117 } 4480 }
4118 } 4481 }
4119 } 4482 else
4120 else 4483 pinfo = null;
4121 pinfo = null;
4122 4484
4123 ce.time = Util.EnvironmentTickCount(); 4485 ce.time = Util.EnvironmentTickCount();
4124 ce.pinfo = pinfo; 4486 ce.pinfo = pinfo;
4125 } 4487 }
4126 4488
4127 string reply = String.Empty; 4489 string reply = String.Empty;
4128 4490
4129 switch (data) 4491 switch (data)
4130 { 4492 {
4131 case 1: // DATA_ONLINE (0|1) 4493 case 1: // DATA_ONLINE (0|1)
4132 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4494 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4133 reply = "1"; 4495 reply = "1";
4134 else 4496 else
4135 reply = "0"; 4497 reply = "0";
4136 break; 4498 break;
4137 case 2: // DATA_NAME (First Last) 4499 case 2: // DATA_NAME (First Last)
4138 reply = account.FirstName + " " + account.LastName; 4500 reply = account.FirstName + " " + account.LastName;
4139 break; 4501 break;
4140 case 3: // DATA_BORN (YYYY-MM-DD) 4502 case 3: // DATA_BORN (YYYY-MM-DD)
4141 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4503 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4142 born = born.AddSeconds(account.Created); 4504 born = born.AddSeconds(account.Created);
4143 reply = born.ToString("yyyy-MM-dd"); 4505 reply = born.ToString("yyyy-MM-dd");
4144 break; 4506 break;
4145 case 4: // DATA_RATING (0,0,0,0,0,0) 4507 case 4: // DATA_RATING (0,0,0,0,0,0)
4146 reply = "0,0,0,0,0,0"; 4508 reply = "0,0,0,0,0,0";
4147 break; 4509 break;
4148 case 8: // DATA_PAYINFO (0|1|2|3) 4510 case 8: // DATA_PAYINFO (0|1|2|3)
4149 reply = "0"; 4511 reply = "0";
4150 break; 4512 break;
4151 default: 4513 default:
4152 return UUID.Zero.ToString(); // Raise no event 4514 return UUID.Zero.ToString(); // Raise no event
4153 } 4515 }
4154 4516
4155 UUID rq = UUID.Random(); 4517 UUID rq = UUID.Random();
4156 4518
4157 UUID tid = AsyncCommands. 4519 UUID tid = AsyncCommands.
4158 DataserverPlugin.RegisterRequest(m_localID, 4520 DataserverPlugin.RegisterRequest(m_localID,
4159 m_itemID, rq.ToString()); 4521 m_itemID, rq.ToString());
4160 4522
4161 AsyncCommands. 4523 AsyncCommands.
4162 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4524 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4163 4525
4164 ScriptSleep(100); 4526 ScriptSleep(100);
4165 return tid.ToString(); 4527 return tid.ToString();
4528 }
4529 else
4530 {
4531 ShoutError("Invalid UUID passed to llRequestAgentData.");
4532 }
4533 return "";
4166 } 4534 }
4167 4535
4168 public LSL_String llRequestInventoryData(string name) 4536 public LSL_String llRequestInventoryData(string name)
4169 { 4537 {
4170 m_host.AddScriptLPS(1); 4538 m_host.AddScriptLPS(1);
4171 4539
4540 //Clone is thread safe
4172 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4541 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4173 4542
4174 foreach (TaskInventoryItem item in itemDictionary.Values) 4543 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4222,6 +4591,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4222 ScenePresence presence = World.GetScenePresence(agentId); 4591 ScenePresence presence = World.GetScenePresence(agentId);
4223 if (presence != null) 4592 if (presence != null)
4224 { 4593 {
4594 // agent must not be a god
4595 if (presence.UserLevel >= 200) return;
4596
4225 // agent must be over the owners land 4597 // agent must be over the owners land
4226 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4598 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4227 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4599 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4244,7 +4616,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4244 UUID av = new UUID(); 4616 UUID av = new UUID();
4245 if (!UUID.TryParse(agent,out av)) 4617 if (!UUID.TryParse(agent,out av))
4246 { 4618 {
4247 LSLError("First parameter to llDialog needs to be a key"); 4619 //LSLError("First parameter to llDialog needs to be a key");
4248 return; 4620 return;
4249 } 4621 }
4250 4622
@@ -4281,17 +4653,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4281 UUID soundId = UUID.Zero; 4653 UUID soundId = UUID.Zero;
4282 if (!UUID.TryParse(impact_sound, out soundId)) 4654 if (!UUID.TryParse(impact_sound, out soundId))
4283 { 4655 {
4284 lock (m_host.TaskInventory) 4656 m_host.TaskInventory.LockItemsForRead(true);
4657 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4285 { 4658 {
4286 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4659 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4287 { 4660 {
4288 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4661 soundId = item.AssetID;
4289 { 4662 break;
4290 soundId = item.AssetID;
4291 break;
4292 }
4293 } 4663 }
4294 } 4664 }
4665 m_host.TaskInventory.LockItemsForRead(false);
4295 } 4666 }
4296 m_host.CollisionSound = soundId; 4667 m_host.CollisionSound = soundId;
4297 m_host.CollisionSoundVolume = (float)impact_volume; 4668 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4331,6 +4702,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4331 UUID partItemID; 4702 UUID partItemID;
4332 foreach (SceneObjectPart part in parts) 4703 foreach (SceneObjectPart part in parts)
4333 { 4704 {
4705 //Clone is thread safe
4334 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4706 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4335 4707
4336 foreach (TaskInventoryItem item in itemsDictionary.Values) 4708 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4545,17 +4917,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4545 4917
4546 m_host.AddScriptLPS(1); 4918 m_host.AddScriptLPS(1);
4547 4919
4548 lock (m_host.TaskInventory) 4920 m_host.TaskInventory.LockItemsForRead(true);
4921 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4549 { 4922 {
4550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4923 if (item.Type == 10 && item.ItemID == m_itemID)
4551 { 4924 {
4552 if (item.Type == 10 && item.ItemID == m_itemID) 4925 result = item.Name!=null?item.Name:String.Empty;
4553 { 4926 break;
4554 result = item.Name != null ? item.Name : String.Empty;
4555 break;
4556 }
4557 } 4927 }
4558 } 4928 }
4929 m_host.TaskInventory.LockItemsForRead(false);
4559 4930
4560 return result; 4931 return result;
4561 } 4932 }
@@ -4728,23 +5099,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4728 { 5099 {
4729 m_host.AddScriptLPS(1); 5100 m_host.AddScriptLPS(1);
4730 5101
4731 lock (m_host.TaskInventory) 5102 m_host.TaskInventory.LockItemsForRead(true);
5103 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4732 { 5104 {
4733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5105 if (inv.Value.Name == name)
4734 { 5106 {
4735 if (inv.Value.Name == name) 5107 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4736 { 5108 {
4737 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5109 m_host.TaskInventory.LockItemsForRead(false);
4738 { 5110 return inv.Value.AssetID.ToString();
4739 return inv.Value.AssetID.ToString(); 5111 }
4740 } 5112 else
4741 else 5113 {
4742 { 5114 m_host.TaskInventory.LockItemsForRead(false);
4743 return UUID.Zero.ToString(); 5115 return UUID.Zero.ToString();
4744 }
4745 } 5116 }
4746 } 5117 }
4747 } 5118 }
5119 m_host.TaskInventory.LockItemsForRead(false);
4748 5120
4749 return UUID.Zero.ToString(); 5121 return UUID.Zero.ToString();
4750 } 5122 }
@@ -4897,14 +5269,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 { 5269 {
4898 m_host.AddScriptLPS(1); 5270 m_host.AddScriptLPS(1);
4899 5271
4900 if (src == null) 5272 return src.Length;
4901 {
4902 return 0;
4903 }
4904 else
4905 {
4906 return src.Length;
4907 }
4908 } 5273 }
4909 5274
4910 public LSL_Integer llList2Integer(LSL_List src, int index) 5275 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4950,7 +5315,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4950 else if (src.Data[index] is LSL_Float) 5315 else if (src.Data[index] is LSL_Float)
4951 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5316 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4952 else if (src.Data[index] is LSL_String) 5317 else if (src.Data[index] is LSL_String)
4953 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5318 {
5319 string str = ((LSL_String) src.Data[index]).m_string;
5320 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5321 if (m != Match.Empty)
5322 {
5323 str = m.Value;
5324 double d = 0.0;
5325 if (!Double.TryParse(str, out d))
5326 return 0.0;
5327
5328 return d;
5329 }
5330 return 0.0;
5331 }
4954 return Convert.ToDouble(src.Data[index]); 5332 return Convert.ToDouble(src.Data[index]);
4955 } 5333 }
4956 catch (FormatException) 5334 catch (FormatException)
@@ -5223,7 +5601,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5223 } 5601 }
5224 } 5602 }
5225 } 5603 }
5226 else { 5604 else
5605 {
5227 object[] array = new object[src.Length]; 5606 object[] array = new object[src.Length];
5228 Array.Copy(src.Data, 0, array, 0, src.Length); 5607 Array.Copy(src.Data, 0, array, 0, src.Length);
5229 result = new LSL_List(array); 5608 result = new LSL_List(array);
@@ -5672,10 +6051,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5672 m_host.AddScriptLPS(1); 6051 m_host.AddScriptLPS(1);
5673 6052
5674 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6053 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5675 6054 if (parts.Count > 0)
5676 foreach (var part in parts)
5677 { 6055 {
5678 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6056 try
6057 {
6058 parts[0].ParentGroup.areUpdatesSuspended = true;
6059 foreach (var part in parts)
6060 {
6061 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6062 }
6063 }
6064 finally
6065 {
6066 parts[0].ParentGroup.areUpdatesSuspended = false;
6067 }
5679 } 6068 }
5680 } 6069 }
5681 6070
@@ -5727,13 +6116,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5727 6116
5728 if (m_host.OwnerID == land.LandData.OwnerID) 6117 if (m_host.OwnerID == land.LandData.OwnerID)
5729 { 6118 {
5730 World.TeleportClientHome(agentID, presence.ControllingClient); 6119 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6120 presence.TeleportWithMomentum(pos);
6121 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5731 } 6122 }
5732 } 6123 }
5733 } 6124 }
5734 ScriptSleep(5000); 6125 ScriptSleep(5000);
5735 } 6126 }
5736 6127
6128 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6129 {
6130 return ParseString2List(str, separators, in_spacers, false);
6131 }
6132
5737 public LSL_Integer llOverMyLand(string id) 6133 public LSL_Integer llOverMyLand(string id)
5738 { 6134 {
5739 m_host.AddScriptLPS(1); 6135 m_host.AddScriptLPS(1);
@@ -5798,8 +6194,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5798 UUID agentId = new UUID(); 6194 UUID agentId = new UUID();
5799 if (!UUID.TryParse(agent, out agentId)) 6195 if (!UUID.TryParse(agent, out agentId))
5800 return new LSL_Integer(0); 6196 return new LSL_Integer(0);
6197 if (agentId == m_host.GroupID)
6198 return new LSL_Integer(1);
5801 ScenePresence presence = World.GetScenePresence(agentId); 6199 ScenePresence presence = World.GetScenePresence(agentId);
5802 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6200 if (presence == null || presence.IsChildAgent) // Return false for child agents
5803 return new LSL_Integer(0); 6201 return new LSL_Integer(0);
5804 IClientAPI client = presence.ControllingClient; 6202 IClientAPI client = presence.ControllingClient;
5805 if (m_host.GroupID == client.ActiveGroupId) 6203 if (m_host.GroupID == client.ActiveGroupId)
@@ -5934,7 +6332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5934 return m_host.ParentGroup.AttachmentPoint; 6332 return m_host.ParentGroup.AttachmentPoint;
5935 } 6333 }
5936 6334
5937 public LSL_Integer llGetFreeMemory() 6335 public virtual LSL_Integer llGetFreeMemory()
5938 { 6336 {
5939 m_host.AddScriptLPS(1); 6337 m_host.AddScriptLPS(1);
5940 // Make scripts designed for LSO happy 6338 // Make scripts designed for LSO happy
@@ -6051,7 +6449,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6051 SetParticleSystem(m_host, rules); 6449 SetParticleSystem(m_host, rules);
6052 } 6450 }
6053 6451
6054 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6452 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6453 {
6055 6454
6056 6455
6057 if (rules.Length == 0) 6456 if (rules.Length == 0)
@@ -6245,14 +6644,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6245 6644
6246 protected UUID GetTaskInventoryItem(string name) 6645 protected UUID GetTaskInventoryItem(string name)
6247 { 6646 {
6248 lock (m_host.TaskInventory) 6647 m_host.TaskInventory.LockItemsForRead(true);
6648 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6249 { 6649 {
6250 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6650 if (inv.Value.Name == name)
6251 { 6651 {
6252 if (inv.Value.Name == name) 6652 m_host.TaskInventory.LockItemsForRead(false);
6253 return inv.Key; 6653 return inv.Key;
6254 } 6654 }
6255 } 6655 }
6656 m_host.TaskInventory.LockItemsForRead(false);
6256 6657
6257 return UUID.Zero; 6658 return UUID.Zero;
6258 } 6659 }
@@ -6290,16 +6691,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6290 if (folderID == UUID.Zero) 6691 if (folderID == UUID.Zero)
6291 return; 6692 return;
6292 6693
6293 byte[] bucket = new byte[17]; 6694 byte[] bucket = new byte[1];
6294 bucket[0] = (byte)AssetType.Folder; 6695 bucket[0] = (byte)AssetType.Folder;
6295 byte[] objBytes = folderID.GetBytes(); 6696 //byte[] objBytes = folderID.GetBytes();
6296 Array.Copy(objBytes, 0, bucket, 1, 16); 6697 //Array.Copy(objBytes, 0, bucket, 1, 16);
6297 6698
6298 GridInstantMessage msg = new GridInstantMessage(World, 6699 GridInstantMessage msg = new GridInstantMessage(World,
6299 m_host.UUID, m_host.Name+", an object owned by "+ 6700 m_host.OwnerID, m_host.Name, destID,
6300 resolveName(m_host.OwnerID)+",", destID, 6701 (byte)InstantMessageDialog.TaskInventoryOffered,
6301 (byte)InstantMessageDialog.InventoryOffered, 6702 false, category+". "+m_host.Name+" is located at "+
6302 false, category+"\n"+m_host.Name+" is located at "+
6303 World.RegionInfo.RegionName+" "+ 6703 World.RegionInfo.RegionName+" "+
6304 m_host.AbsolutePosition.ToString(), 6704 m_host.AbsolutePosition.ToString(),
6305 folderID, true, m_host.AbsolutePosition, 6705 folderID, true, m_host.AbsolutePosition,
@@ -6515,13 +6915,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6515 UUID av = new UUID(); 6915 UUID av = new UUID();
6516 if (!UUID.TryParse(avatar,out av)) 6916 if (!UUID.TryParse(avatar,out av))
6517 { 6917 {
6518 LSLError("First parameter to llDialog needs to be a key"); 6918 //LSLError("First parameter to llDialog needs to be a key");
6519 return; 6919 return;
6520 } 6920 }
6521 if (buttons.Length < 1) 6921 if (buttons.Length < 1)
6522 { 6922 {
6523 LSLError("No less than 1 button can be shown"); 6923 buttons.Add("OK");
6524 return;
6525 } 6924 }
6526 if (buttons.Length > 12) 6925 if (buttons.Length > 12)
6527 { 6926 {
@@ -6538,7 +6937,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6538 } 6937 }
6539 if (buttons.Data[i].ToString().Length > 24) 6938 if (buttons.Data[i].ToString().Length > 24)
6540 { 6939 {
6541 LSLError("button label cannot be longer than 24 characters"); 6940 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6542 return; 6941 return;
6543 } 6942 }
6544 buts[i] = buttons.Data[i].ToString(); 6943 buts[i] = buttons.Data[i].ToString();
@@ -6597,22 +6996,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6597 } 6996 }
6598 6997
6599 // copy the first script found with this inventory name 6998 // copy the first script found with this inventory name
6600 lock (m_host.TaskInventory) 6999 TaskInventoryItem scriptItem = null;
7000 m_host.TaskInventory.LockItemsForRead(true);
7001 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6601 { 7002 {
6602 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7003 if (inv.Value.Name == name)
6603 { 7004 {
6604 if (inv.Value.Name == name) 7005 // make sure the object is a script
7006 if (10 == inv.Value.Type)
6605 { 7007 {
6606 // make sure the object is a script 7008 found = true;
6607 if (10 == inv.Value.Type) 7009 srcId = inv.Key;
6608 { 7010 scriptItem = inv.Value;
6609 found = true; 7011 break;
6610 srcId = inv.Key;
6611 break;
6612 }
6613 } 7012 }
6614 } 7013 }
6615 } 7014 }
7015 m_host.TaskInventory.LockItemsForRead(false);
6616 7016
6617 if (!found) 7017 if (!found)
6618 { 7018 {
@@ -6620,9 +7020,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6620 return; 7020 return;
6621 } 7021 }
6622 7022
6623 // the rest of the permission checks are done in RezScript, so check the pin there as well 7023 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6624 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7024 if (dest != null)
7025 {
7026 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7027 {
7028 // the rest of the permission checks are done in RezScript, so check the pin there as well
7029 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6625 7030
7031 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7032 m_host.Inventory.RemoveInventoryItem(srcId);
7033 }
7034 }
6626 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7035 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6627 ScriptSleep(3000); 7036 ScriptSleep(3000);
6628 } 7037 }
@@ -6685,19 +7094,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6685 public LSL_String llMD5String(string src, int nonce) 7094 public LSL_String llMD5String(string src, int nonce)
6686 { 7095 {
6687 m_host.AddScriptLPS(1); 7096 m_host.AddScriptLPS(1);
6688 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7097 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6689 } 7098 }
6690 7099
6691 public LSL_String llSHA1String(string src) 7100 public LSL_String llSHA1String(string src)
6692 { 7101 {
6693 m_host.AddScriptLPS(1); 7102 m_host.AddScriptLPS(1);
6694 return Util.SHA1Hash(src).ToLower(); 7103 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6695 } 7104 }
6696 7105
6697 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7106 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6698 { 7107 {
6699 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7108 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6700 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7109 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7110 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7111 return shapeBlock;
6701 7112
6702 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7113 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6703 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7114 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6802,6 +7213,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6802 // Prim type box, cylinder and prism. 7213 // Prim type box, cylinder and prism.
6803 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7214 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
6804 { 7215 {
7216 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7217 return;
7218
6805 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7219 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6806 ObjectShapePacket.ObjectDataBlock shapeBlock; 7220 ObjectShapePacket.ObjectDataBlock shapeBlock;
6807 7221
@@ -6855,6 +7269,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6855 // Prim type sphere. 7269 // Prim type sphere.
6856 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7270 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6857 { 7271 {
7272 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7273 return;
7274
6858 ObjectShapePacket.ObjectDataBlock shapeBlock; 7275 ObjectShapePacket.ObjectDataBlock shapeBlock;
6859 7276
6860 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7277 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6896,6 +7313,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6896 // Prim type torus, tube and ring. 7313 // Prim type torus, tube and ring.
6897 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 profileshape, byte pathcurve) 7314 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 profileshape, byte pathcurve)
6898 { 7315 {
7316 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7317 return;
7318
6899 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7319 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6900 ObjectShapePacket.ObjectDataBlock shapeBlock; 7320 ObjectShapePacket.ObjectDataBlock shapeBlock;
6901 7321
@@ -7031,6 +7451,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7031 // Prim type sculpt. 7451 // Prim type sculpt.
7032 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7452 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7033 { 7453 {
7454 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7455 return;
7456
7034 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7457 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7035 UUID sculptId; 7458 UUID sculptId;
7036 7459
@@ -7047,13 +7470,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7047 shapeBlock.PathScaleX = 100; 7470 shapeBlock.PathScaleX = 100;
7048 shapeBlock.PathScaleY = 150; 7471 shapeBlock.PathScaleY = 150;
7049 7472
7050 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7473 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7051 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7474 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7052 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7475 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7053 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7476 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7054 { 7477 {
7055 // default 7478 // default
7056 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7479 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7057 } 7480 }
7058 7481
7059 part.Shape.SetSculptProperties((byte)type, sculptId); 7482 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7069,32 +7492,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7069 ScriptSleep(200); 7492 ScriptSleep(200);
7070 } 7493 }
7071 7494
7072 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7495 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7073 { 7496 {
7074 m_host.AddScriptLPS(1); 7497 m_host.AddScriptLPS(1);
7075 7498
7076 setLinkPrimParams(linknumber, rules); 7499 setLinkPrimParams(linknumber, rules);
7077
7078 ScriptSleep(200);
7079 } 7500 }
7080 7501
7081 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7502 private void setLinkPrimParams(int linknumber, LSL_List rules)
7082 { 7503 {
7083 m_host.AddScriptLPS(1); 7504 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7505 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7506 if (parts.Count>0)
7507 {
7508 try
7509 {
7510 parts[0].ParentGroup.areUpdatesSuspended = true;
7511 foreach (SceneObjectPart part in parts)
7512 SetPrimParams(part, rules);
7513 }
7514 finally
7515 {
7516 parts[0].ParentGroup.areUpdatesSuspended = false;
7517 }
7518 }
7519 if (avatars.Count > 0)
7520 {
7521 foreach (ScenePresence avatar in avatars)
7522 SetPrimParams(avatar, rules);
7523 }
7524 }
7084 7525
7085 setLinkPrimParams(linknumber, rules); 7526 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7527 {
7528 llSetLinkPrimitiveParamsFast(linknumber, rules);
7529 ScriptSleep(200);
7086 } 7530 }
7087 7531
7088 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7532 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7089 { 7533 {
7090 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7534 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7535 //We only support PRIM_POSITION and PRIM_ROTATION
7091 7536
7092 foreach (SceneObjectPart part in parts) 7537 int idx = 0;
7093 SetPrimParams(part, rules); 7538
7539 while (idx < rules.Length)
7540 {
7541 int code = rules.GetLSLIntegerItem(idx++);
7542
7543 int remain = rules.Length - idx;
7544
7545
7546
7547 switch (code)
7548 {
7549 case (int)ScriptBaseClass.PRIM_POSITION:
7550 if (remain < 1)
7551 return;
7552 LSL_Vector v;
7553 v = rules.GetVector3Item(idx++);
7554 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7555 av.SendAvatarDataToAllAgents();
7556
7557 break;
7558
7559 case (int)ScriptBaseClass.PRIM_ROTATION:
7560 if (remain < 1)
7561 return;
7562 LSL_Rotation r;
7563 r = rules.GetQuaternionItem(idx++);
7564 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7565 av.SendAvatarDataToAllAgents();
7566 break;
7567 }
7568 }
7094 } 7569 }
7095 7570
7096 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7571 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7097 { 7572 {
7573 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7574 return;
7575
7098 int idx = 0; 7576 int idx = 0;
7099 7577
7100 bool positionChanged = false; 7578 bool positionChanged = false;
@@ -7122,6 +7600,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7122 currentPosition = GetSetPosTarget(part, v, currentPosition); 7600 currentPosition = GetSetPosTarget(part, v, currentPosition);
7123 7601
7124 break; 7602 break;
7603 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7604 if (remain < 1)
7605 return;
7606
7607 v=rules.GetVector3Item(idx++);
7608 positionChanged = true;
7609 currentPosition = GetSetPosTarget(part, v, currentPosition);
7610
7611 break;
7125 case (int)ScriptBaseClass.PRIM_SIZE: 7612 case (int)ScriptBaseClass.PRIM_SIZE:
7126 if (remain < 1) 7613 if (remain < 1)
7127 return; 7614 return;
@@ -7488,7 +7975,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7488 if (part.ParentGroup.RootPart == part) 7975 if (part.ParentGroup.RootPart == part)
7489 { 7976 {
7490 SceneObjectGroup parent = part.ParentGroup; 7977 SceneObjectGroup parent = part.ParentGroup;
7491 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 7978 Util.FireAndForget(delegate(object x) {
7979 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7980 });
7492 } 7981 }
7493 else 7982 else
7494 { 7983 {
@@ -7499,6 +7988,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7499 } 7988 }
7500 } 7989 }
7501 } 7990 }
7991
7992 if (positionChanged)
7993 {
7994 if (part.ParentGroup.RootPart == part)
7995 {
7996 SceneObjectGroup parent = part.ParentGroup;
7997 Util.FireAndForget(delegate(object x) {
7998 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7999 });
8000 }
8001 else
8002 {
8003 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8004 SceneObjectGroup parent = part.ParentGroup;
8005 parent.HasGroupChanged = true;
8006 parent.ScheduleGroupForTerseUpdate();
8007 }
8008 }
7502 } 8009 }
7503 8010
7504 public LSL_String llStringToBase64(string str) 8011 public LSL_String llStringToBase64(string str)
@@ -7659,13 +8166,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7659 public LSL_Integer llGetNumberOfPrims() 8166 public LSL_Integer llGetNumberOfPrims()
7660 { 8167 {
7661 m_host.AddScriptLPS(1); 8168 m_host.AddScriptLPS(1);
7662 int avatarCount = 0; 8169 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7663 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8170
7664 {
7665 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7666 avatarCount++;
7667 });
7668
7669 return m_host.ParentGroup.PrimCount + avatarCount; 8171 return m_host.ParentGroup.PrimCount + avatarCount;
7670 } 8172 }
7671 8173
@@ -7681,55 +8183,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7681 m_host.AddScriptLPS(1); 8183 m_host.AddScriptLPS(1);
7682 UUID objID = UUID.Zero; 8184 UUID objID = UUID.Zero;
7683 LSL_List result = new LSL_List(); 8185 LSL_List result = new LSL_List();
8186
8187 // If the ID is not valid, return null result
7684 if (!UUID.TryParse(obj, out objID)) 8188 if (!UUID.TryParse(obj, out objID))
7685 { 8189 {
7686 result.Add(new LSL_Vector()); 8190 result.Add(new LSL_Vector());
7687 result.Add(new LSL_Vector()); 8191 result.Add(new LSL_Vector());
7688 return result; 8192 return result;
7689 } 8193 }
8194
8195 // Check if this is an attached prim. If so, replace
8196 // the UUID with the avatar UUID and report it's bounding box
8197 SceneObjectPart part = World.GetSceneObjectPart(objID);
8198 if (part != null && part.ParentGroup.IsAttachment)
8199 objID = part.ParentGroup.AttachedAvatar;
8200
8201 // Find out if this is an avatar ID. If so, return it's box
7690 ScenePresence presence = World.GetScenePresence(objID); 8202 ScenePresence presence = World.GetScenePresence(objID);
7691 if (presence != null) 8203 if (presence != null)
7692 { 8204 {
7693 if (presence.ParentID == 0) // not sat on an object 8205 // As per LSL Wiki, there is no difference between sitting
8206 // and standing avatar since server 1.36
8207 LSL_Vector lower;
8208 LSL_Vector upper;
8209 if (presence.Animator.Animations.DefaultAnimation.AnimID
8210 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7694 { 8211 {
7695 LSL_Vector lower; 8212 // This is for ground sitting avatars
7696 LSL_Vector upper; 8213 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7697 if (presence.Animator.Animations.DefaultAnimation.AnimID 8214 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7698 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8215 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7699 {
7700 // This is for ground sitting avatars
7701 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7702 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7703 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7704 }
7705 else
7706 {
7707 // This is for standing/flying avatars
7708 float height = presence.Appearance.AvatarHeight / 2.0f;
7709 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7710 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7711 }
7712 result.Add(lower);
7713 result.Add(upper);
7714 return result;
7715 } 8216 }
7716 else 8217 else
7717 { 8218 {
7718 // sitting on an object so we need the bounding box of that 8219 // This is for standing/flying avatars
7719 // which should include the avatar so set the UUID to the 8220 float height = presence.Appearance.AvatarHeight / 2.0f;
7720 // UUID of the object the avatar is sat on and allow it to fall through 8221 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7721 // to processing an object 8222 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7722 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7723 objID = p.UUID;
7724 } 8223 }
8224
8225 // Adjust to the documented error offsets (see LSL Wiki)
8226 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8227 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8228
8229 if (lower.x > upper.x)
8230 lower.x = upper.x;
8231 if (lower.y > upper.y)
8232 lower.y = upper.y;
8233 if (lower.z > upper.z)
8234 lower.z = upper.z;
8235
8236 result.Add(lower);
8237 result.Add(upper);
8238 return result;
7725 } 8239 }
7726 SceneObjectPart part = World.GetSceneObjectPart(objID); 8240
8241 part = World.GetSceneObjectPart(objID);
7727 // Currently only works for single prims without a sitting avatar 8242 // Currently only works for single prims without a sitting avatar
7728 if (part != null) 8243 if (part != null)
7729 { 8244 {
7730 Vector3 halfSize = part.Scale / 2.0f; 8245 float minX;
7731 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8246 float maxX;
7732 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8247 float minY;
8248 float maxY;
8249 float minZ;
8250 float maxZ;
8251
8252 // This BBox is in sim coordinates, with the offset being
8253 // a contained point.
8254 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8255 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8256
8257 minX -= offsets[0].X;
8258 maxX -= offsets[0].X;
8259 minY -= offsets[0].Y;
8260 maxY -= offsets[0].Y;
8261 minZ -= offsets[0].Z;
8262 maxZ -= offsets[0].Z;
8263
8264 LSL_Vector lower;
8265 LSL_Vector upper;
8266
8267 // Adjust to the documented error offsets (see LSL Wiki)
8268 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8269 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8270
8271 if (lower.x > upper.x)
8272 lower.x = upper.x;
8273 if (lower.y > upper.y)
8274 lower.y = upper.y;
8275 if (lower.z > upper.z)
8276 lower.z = upper.z;
8277
7733 result.Add(lower); 8278 result.Add(lower);
7734 result.Add(upper); 8279 result.Add(upper);
7735 return result; 8280 return result;
@@ -7809,13 +8354,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7809 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8354 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7810 part.AbsolutePosition.Y, 8355 part.AbsolutePosition.Y,
7811 part.AbsolutePosition.Z); 8356 part.AbsolutePosition.Z);
7812 // For some reason, the part.AbsolutePosition.* values do not change if the
7813 // linkset is rotated; they always reflect the child prim's world position
7814 // as though the linkset is unrotated. This is incompatible behavior with SL's
7815 // implementation, so will break scripts imported from there (not to mention it
7816 // makes it more difficult to determine a child prim's actual inworld position).
7817 if (part.ParentID != 0)
7818 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7819 res.Add(v); 8357 res.Add(v);
7820 break; 8358 break;
7821 8359
@@ -7986,56 +8524,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7986 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8524 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7987 if (remain < 1) 8525 if (remain < 1)
7988 return res; 8526 return res;
7989 8527 face = (int)rules.GetLSLIntegerItem(idx++);
7990 face=(int)rules.GetLSLIntegerItem(idx++);
7991 8528
7992 tex = part.Shape.Textures; 8529 tex = part.Shape.Textures;
8530 int shiny;
7993 if (face == ScriptBaseClass.ALL_SIDES) 8531 if (face == ScriptBaseClass.ALL_SIDES)
7994 { 8532 {
7995 for (face = 0; face < GetNumberOfSides(part); face++) 8533 for (face = 0; face < GetNumberOfSides(part); face++)
7996 { 8534 {
7997 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8535 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7998 // Convert Shininess to PRIM_SHINY_* 8536 if (shinyness == Shininess.High)
7999 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8537 {
8000 // PRIM_BUMP_* 8538 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8001 res.Add(new LSL_Integer((int)texface.Bump)); 8539 }
8540 else if (shinyness == Shininess.Medium)
8541 {
8542 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8543 }
8544 else if (shinyness == Shininess.Low)
8545 {
8546 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8547 }
8548 else
8549 {
8550 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8551 }
8552 res.Add(new LSL_Integer(shiny));
8553 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8002 } 8554 }
8003 } 8555 }
8004 else 8556 else
8005 { 8557 {
8006 if (face >= 0 && face < GetNumberOfSides(part)) 8558 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8559 if (shinyness == Shininess.High)
8007 { 8560 {
8008 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8561 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8009 // Convert Shininess to PRIM_SHINY_* 8562 }
8010 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8563 else if (shinyness == Shininess.Medium)
8011 // PRIM_BUMP_* 8564 {
8012 res.Add(new LSL_Integer((int)texface.Bump)); 8565 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8013 } 8566 }
8567 else if (shinyness == Shininess.Low)
8568 {
8569 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8570 }
8571 else
8572 {
8573 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8574 }
8575 res.Add(new LSL_Integer(shiny));
8576 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8014 } 8577 }
8015 break; 8578 break;
8016 8579
8017 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8580 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8018 if (remain < 1) 8581 if (remain < 1)
8019 return res; 8582 return res;
8020 8583 face = (int)rules.GetLSLIntegerItem(idx++);
8021 face=(int)rules.GetLSLIntegerItem(idx++);
8022 8584
8023 tex = part.Shape.Textures; 8585 tex = part.Shape.Textures;
8586 int fullbright;
8024 if (face == ScriptBaseClass.ALL_SIDES) 8587 if (face == ScriptBaseClass.ALL_SIDES)
8025 { 8588 {
8026 for (face = 0; face < GetNumberOfSides(part); face++) 8589 for (face = 0; face < GetNumberOfSides(part); face++)
8027 { 8590 {
8028 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8591 if (tex.GetFace((uint)face).Fullbright == true)
8029 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8592 {
8593 fullbright = ScriptBaseClass.TRUE;
8594 }
8595 else
8596 {
8597 fullbright = ScriptBaseClass.FALSE;
8598 }
8599 res.Add(new LSL_Integer(fullbright));
8030 } 8600 }
8031 } 8601 }
8032 else 8602 else
8033 { 8603 {
8034 if (face >= 0 && face < GetNumberOfSides(part)) 8604 if (tex.GetFace((uint)face).Fullbright == true)
8035 { 8605 {
8036 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8606 fullbright = ScriptBaseClass.TRUE;
8037 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8038 } 8607 }
8608 else
8609 {
8610 fullbright = ScriptBaseClass.FALSE;
8611 }
8612 res.Add(new LSL_Integer(fullbright));
8039 } 8613 }
8040 break; 8614 break;
8041 8615
@@ -8057,27 +8631,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8057 break; 8631 break;
8058 8632
8059 case (int)ScriptBaseClass.PRIM_TEXGEN: 8633 case (int)ScriptBaseClass.PRIM_TEXGEN:
8634 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8060 if (remain < 1) 8635 if (remain < 1)
8061 return res; 8636 return res;
8062 8637 face = (int)rules.GetLSLIntegerItem(idx++);
8063 face=(int)rules.GetLSLIntegerItem(idx++);
8064 8638
8065 tex = part.Shape.Textures; 8639 tex = part.Shape.Textures;
8066 if (face == ScriptBaseClass.ALL_SIDES) 8640 if (face == ScriptBaseClass.ALL_SIDES)
8067 { 8641 {
8068 for (face = 0; face < GetNumberOfSides(part); face++) 8642 for (face = 0; face < GetNumberOfSides(part); face++)
8069 { 8643 {
8070 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8644 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8071 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8645 {
8072 res.Add(new LSL_Integer((uint)texgen >> 1)); 8646 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8647 }
8648 else
8649 {
8650 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8651 }
8073 } 8652 }
8074 } 8653 }
8075 else 8654 else
8076 { 8655 {
8077 if (face >= 0 && face < GetNumberOfSides(part)) 8656 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8657 {
8658 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8659 }
8660 else
8078 { 8661 {
8079 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8662 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8080 res.Add(new LSL_Integer((uint)texgen >> 1));
8081 } 8663 }
8082 } 8664 }
8083 break; 8665 break;
@@ -8100,28 +8682,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8100 case (int)ScriptBaseClass.PRIM_GLOW: 8682 case (int)ScriptBaseClass.PRIM_GLOW:
8101 if (remain < 1) 8683 if (remain < 1)
8102 return res; 8684 return res;
8103 8685 face = (int)rules.GetLSLIntegerItem(idx++);
8104 face=(int)rules.GetLSLIntegerItem(idx++);
8105 8686
8106 tex = part.Shape.Textures; 8687 tex = part.Shape.Textures;
8688 float primglow;
8107 if (face == ScriptBaseClass.ALL_SIDES) 8689 if (face == ScriptBaseClass.ALL_SIDES)
8108 { 8690 {
8109 for (face = 0; face < GetNumberOfSides(part); face++) 8691 for (face = 0; face < GetNumberOfSides(part); face++)
8110 { 8692 {
8111 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8693 primglow = tex.GetFace((uint)face).Glow;
8112 res.Add(new LSL_Float(texface.Glow)); 8694 res.Add(new LSL_Float(primglow));
8113 } 8695 }
8114 } 8696 }
8115 else 8697 else
8116 { 8698 {
8117 if (face >= 0 && face < GetNumberOfSides(part)) 8699 primglow = tex.GetFace((uint)face).Glow;
8118 { 8700 res.Add(new LSL_Float(primglow));
8119 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8120 res.Add(new LSL_Float(texface.Glow));
8121 }
8122 } 8701 }
8123 break; 8702 break;
8124
8125 case (int)ScriptBaseClass.PRIM_TEXT: 8703 case (int)ScriptBaseClass.PRIM_TEXT:
8126 Color4 textColor = part.GetTextColor(); 8704 Color4 textColor = part.GetTextColor();
8127 res.Add(new LSL_String(part.Text)); 8705 res.Add(new LSL_String(part.Text));
@@ -8673,8 +9251,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8673 // The function returns an ordered list 9251 // The function returns an ordered list
8674 // representing the tokens found in the supplied 9252 // representing the tokens found in the supplied
8675 // sources string. If two successive tokenizers 9253 // sources string. If two successive tokenizers
8676 // are encountered, then a NULL entry is added 9254 // are encountered, then a null-string entry is
8677 // to the list. 9255 // added to the list.
8678 // 9256 //
8679 // It is a precondition that the source and 9257 // It is a precondition that the source and
8680 // toekizer lisst are non-null. If they are null, 9258 // toekizer lisst are non-null. If they are null,
@@ -8682,7 +9260,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8682 // while their lengths are being determined. 9260 // while their lengths are being determined.
8683 // 9261 //
8684 // A small amount of working memoryis required 9262 // A small amount of working memoryis required
8685 // of approximately 8*#tokenizers. 9263 // of approximately 8*#tokenizers + 8*srcstrlen.
8686 // 9264 //
8687 // There are many ways in which this function 9265 // There are many ways in which this function
8688 // can be implemented, this implementation is 9266 // can be implemented, this implementation is
@@ -8698,155 +9276,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8698 // and eliminates redundant tokenizers as soon 9276 // and eliminates redundant tokenizers as soon
8699 // as is possible. 9277 // as is possible.
8700 // 9278 //
8701 // The implementation tries to avoid any copying 9279 // The implementation tries to minimize temporary
8702 // of arrays or other objects. 9280 // garbage generation.
8703 // </remarks> 9281 // </remarks>
8704 9282
8705 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9283 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8706 { 9284 {
8707 int beginning = 0; 9285 return ParseString2List(src, separators, spacers, true);
8708 int srclen = src.Length; 9286 }
8709 int seplen = separators.Length;
8710 object[] separray = separators.Data;
8711 int spclen = spacers.Length;
8712 object[] spcarray = spacers.Data;
8713 int mlen = seplen+spclen;
8714
8715 int[] offset = new int[mlen+1];
8716 bool[] active = new bool[mlen];
8717
8718 int best;
8719 int j;
8720
8721 // Initial capacity reduces resize cost
8722 9287
8723 LSL_List tokens = new LSL_List(); 9288 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9289 {
9290 int srclen = src.Length;
9291 int seplen = separators.Length;
9292 object[] separray = separators.Data;
9293 int spclen = spacers.Length;
9294 object[] spcarray = spacers.Data;
9295 int dellen = 0;
9296 string[] delarray = new string[seplen+spclen];
8724 9297
8725 // All entries are initially valid 9298 int outlen = 0;
9299 string[] outarray = new string[srclen*2+1];
8726 9300
8727 for (int i = 0; i < mlen; i++) 9301 int i, j;
8728 active[i] = true; 9302 string d;
8729 9303
8730 offset[mlen] = srclen; 9304 m_host.AddScriptLPS(1);
8731 9305
8732 while (beginning < srclen) 9306 /*
9307 * Convert separator and spacer lists to C# strings.
9308 * Also filter out null strings so we don't hang.
9309 */
9310 for (i = 0; i < seplen; i ++)
8733 { 9311 {
9312 d = separray[i].ToString();
9313 if (d.Length > 0)
9314 {
9315 delarray[dellen++] = d;
9316 }
9317 }
9318 seplen = dellen;
8734 9319
8735 best = mlen; // as bad as it gets 9320 for (i = 0; i < spclen; i ++)
9321 {
9322 d = spcarray[i].ToString();
9323 if (d.Length > 0)
9324 {
9325 delarray[dellen++] = d;
9326 }
9327 }
8736 9328
8737 // Scan for separators 9329 /*
9330 * Scan through source string from beginning to end.
9331 */
9332 for (i = 0;;)
9333 {
8738 9334
8739 for (j = 0; j < seplen; j++) 9335 /*
9336 * Find earliest delimeter in src starting at i (if any).
9337 */
9338 int earliestDel = -1;
9339 int earliestSrc = srclen;
9340 string earliestStr = null;
9341 for (j = 0; j < dellen; j ++)
8740 { 9342 {
8741 if (separray[j].ToString() == String.Empty) 9343 d = delarray[j];
8742 active[j] = false; 9344 if (d != null)
8743
8744 if (active[j])
8745 { 9345 {
8746 // scan all of the markers 9346 int index = src.IndexOf(d, i);
8747 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9347 if (index < 0)
8748 { 9348 {
8749 // not present at all 9349 delarray[j] = null; // delim nowhere in src, don't check it anymore
8750 active[j] = false;
8751 } 9350 }
8752 else 9351 else if (index < earliestSrc)
8753 { 9352 {
8754 // present and correct 9353 earliestSrc = index; // where delimeter starts in source string
8755 if (offset[j] < offset[best]) 9354 earliestDel = j; // where delimeter is in delarray[]
8756 { 9355 earliestStr = d; // the delimeter string from delarray[]
8757 // closest so far 9356 if (index == i) break; // can't do any better than found at beg of string
8758 best = j;
8759 if (offset[best] == beginning)
8760 break;
8761 }
8762 } 9357 }
8763 } 9358 }
8764 } 9359 }
8765 9360
8766 // Scan for spacers 9361 /*
8767 9362 * Output source string starting at i through start of earliest delimeter.
8768 if (offset[best] != beginning) 9363 */
9364 if (keepNulls || (earliestSrc > i))
8769 { 9365 {
8770 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9366 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8771 {
8772 if (spcarray[j-seplen].ToString() == String.Empty)
8773 active[j] = false;
8774
8775 if (active[j])
8776 {
8777 // scan all of the markers
8778 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8779 {
8780 // not present at all
8781 active[j] = false;
8782 }
8783 else
8784 {
8785 // present and correct
8786 if (offset[j] < offset[best])
8787 {
8788 // closest so far
8789 best = j;
8790 }
8791 }
8792 }
8793 }
8794 } 9367 }
8795 9368
8796 // This is the normal exit from the scanning loop 9369 /*
9370 * If no delimeter found at or after i, we're done scanning.
9371 */
9372 if (earliestDel < 0) break;
8797 9373
8798 if (best == mlen) 9374 /*
9375 * If delimeter was a spacer, output the spacer.
9376 */
9377 if (earliestDel >= seplen)
8799 { 9378 {
8800 // no markers were found on this pass 9379 outarray[outlen++] = earliestStr;
8801 // so we're pretty much done
8802 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8803 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8804 break;
8805 } 9380 }
8806 9381
8807 // Otherwise we just add the newly delimited token 9382 /*
8808 // and recalculate where the search should continue. 9383 * Look at rest of src string following delimeter.
8809 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9384 */
8810 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9385 i = earliestSrc + earliestStr.Length;
8811
8812 if (best < seplen)
8813 {
8814 beginning = offset[best] + (separray[best].ToString()).Length;
8815 }
8816 else
8817 {
8818 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8819 string str = spcarray[best - seplen].ToString();
8820 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8821 tokens.Add(new LSL_String(str));
8822 }
8823 } 9386 }
8824 9387
8825 // This an awkward an not very intuitive boundary case. If the 9388 /*
8826 // last substring is a tokenizer, then there is an implied trailing 9389 * Make up an exact-sized output array suitable for an LSL_List object.
8827 // null list entry. Hopefully the single comparison will not be too 9390 */
8828 // arduous. Alternatively the 'break' could be replced with a return 9391 object[] outlist = new object[outlen];
8829 // but that's shabby programming. 9392 for (i = 0; i < outlen; i ++)
8830
8831 if ((beginning == srclen) && (keepNulls))
8832 { 9393 {
8833 if (srclen != 0) 9394 outlist[i] = new LSL_String(outarray[i]);
8834 tokens.Add(new LSL_String(""));
8835 } 9395 }
8836 9396 return new LSL_List(outlist);
8837 return tokens;
8838 }
8839
8840 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8841 {
8842 m_host.AddScriptLPS(1);
8843 return this.ParseString(src, separators, spacers, false);
8844 }
8845
8846 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8847 {
8848 m_host.AddScriptLPS(1);
8849 return this.ParseString(src, separators, spacers, true);
8850 } 9397 }
8851 9398
8852 public LSL_Integer llGetObjectPermMask(int mask) 9399 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8923,28 +9470,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8923 { 9470 {
8924 m_host.AddScriptLPS(1); 9471 m_host.AddScriptLPS(1);
8925 9472
8926 lock (m_host.TaskInventory) 9473 m_host.TaskInventory.LockItemsForRead(true);
9474 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8927 { 9475 {
8928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9476 if (inv.Value.Name == item)
8929 { 9477 {
8930 if (inv.Value.Name == item) 9478 m_host.TaskInventory.LockItemsForRead(false);
9479 switch (mask)
8931 { 9480 {
8932 switch (mask) 9481 case 0:
8933 { 9482 return (int)inv.Value.BasePermissions;
8934 case 0: 9483 case 1:
8935 return (int)inv.Value.BasePermissions; 9484 return (int)inv.Value.CurrentPermissions;
8936 case 1: 9485 case 2:
8937 return (int)inv.Value.CurrentPermissions; 9486 return (int)inv.Value.GroupPermissions;
8938 case 2: 9487 case 3:
8939 return (int)inv.Value.GroupPermissions; 9488 return (int)inv.Value.EveryonePermissions;
8940 case 3: 9489 case 4:
8941 return (int)inv.Value.EveryonePermissions; 9490 return (int)inv.Value.NextPermissions;
8942 case 4:
8943 return (int)inv.Value.NextPermissions;
8944 }
8945 } 9491 }
8946 } 9492 }
8947 } 9493 }
9494 m_host.TaskInventory.LockItemsForRead(false);
8948 9495
8949 return -1; 9496 return -1;
8950 } 9497 }
@@ -8991,16 +9538,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8991 { 9538 {
8992 m_host.AddScriptLPS(1); 9539 m_host.AddScriptLPS(1);
8993 9540
8994 lock (m_host.TaskInventory) 9541 m_host.TaskInventory.LockItemsForRead(true);
9542 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8995 { 9543 {
8996 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9544 if (inv.Value.Name == item)
8997 { 9545 {
8998 if (inv.Value.Name == item) 9546 m_host.TaskInventory.LockItemsForRead(false);
8999 { 9547 return inv.Value.CreatorID.ToString();
9000 return inv.Value.CreatorID.ToString();
9001 }
9002 } 9548 }
9003 } 9549 }
9550 m_host.TaskInventory.LockItemsForRead(false);
9004 9551
9005 llSay(0, "No item name '" + item + "'"); 9552 llSay(0, "No item name '" + item + "'");
9006 9553
@@ -9148,7 +9695,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9148 } 9695 }
9149 9696
9150 /// <summary> 9697 /// <summary>
9151 /// illListReplaceList removes the sub-list defined by the inclusive indices 9698 /// llListReplaceList removes the sub-list defined by the inclusive indices
9152 /// start and end and inserts the src list in its place. The inclusive 9699 /// start and end and inserts the src list in its place. The inclusive
9153 /// nature of the indices means that at least one element must be deleted 9700 /// nature of the indices means that at least one element must be deleted
9154 /// if the indices are within the bounds of the existing list. I.e. 2,2 9701 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9205,16 +9752,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9205 // based upon end. Note that if end exceeds the upper 9752 // based upon end. Note that if end exceeds the upper
9206 // bound in this case, the entire destination list 9753 // bound in this case, the entire destination list
9207 // is removed. 9754 // is removed.
9208 else 9755 else if (start == 0)
9209 { 9756 {
9210 if (end + 1 < dest.Length) 9757 if (end + 1 < dest.Length)
9211 {
9212 return src + dest.GetSublist(end + 1, -1); 9758 return src + dest.GetSublist(end + 1, -1);
9213 }
9214 else 9759 else
9215 {
9216 return src; 9760 return src;
9217 } 9761 }
9762 else // Start < 0
9763 {
9764 if (end + 1 < dest.Length)
9765 return dest.GetSublist(end + 1, -1);
9766 else
9767 return new LSL_List();
9218 } 9768 }
9219 } 9769 }
9220 // Finally, if start > end, we strip away a prefix and 9770 // Finally, if start > end, we strip away a prefix and
@@ -9265,17 +9815,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9265 int width = 0; 9815 int width = 0;
9266 int height = 0; 9816 int height = 0;
9267 9817
9268 ParcelMediaCommandEnum? commandToSend = null; 9818 uint commandToSend = 0;
9269 float time = 0.0f; // default is from start 9819 float time = 0.0f; // default is from start
9270 9820
9271 ScenePresence presence = null; 9821 ScenePresence presence = null;
9272 9822
9273 for (int i = 0; i < commandList.Data.Length; i++) 9823 for (int i = 0; i < commandList.Data.Length; i++)
9274 { 9824 {
9275 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9825 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9276 switch (command) 9826 switch (command)
9277 { 9827 {
9278 case ParcelMediaCommandEnum.Agent: 9828 case (uint)ParcelMediaCommandEnum.Agent:
9279 // we send only to one agent 9829 // we send only to one agent
9280 if ((i + 1) < commandList.Length) 9830 if ((i + 1) < commandList.Length)
9281 { 9831 {
@@ -9292,25 +9842,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 } 9842 }
9293 break; 9843 break;
9294 9844
9295 case ParcelMediaCommandEnum.Loop: 9845 case (uint)ParcelMediaCommandEnum.Loop:
9296 loop = 1; 9846 loop = 1;
9297 commandToSend = command; 9847 commandToSend = command;
9298 update = true; //need to send the media update packet to set looping 9848 update = true; //need to send the media update packet to set looping
9299 break; 9849 break;
9300 9850
9301 case ParcelMediaCommandEnum.Play: 9851 case (uint)ParcelMediaCommandEnum.Play:
9302 loop = 0; 9852 loop = 0;
9303 commandToSend = command; 9853 commandToSend = command;
9304 update = true; //need to send the media update packet to make sure it doesn't loop 9854 update = true; //need to send the media update packet to make sure it doesn't loop
9305 break; 9855 break;
9306 9856
9307 case ParcelMediaCommandEnum.Pause: 9857 case (uint)ParcelMediaCommandEnum.Pause:
9308 case ParcelMediaCommandEnum.Stop: 9858 case (uint)ParcelMediaCommandEnum.Stop:
9309 case ParcelMediaCommandEnum.Unload: 9859 case (uint)ParcelMediaCommandEnum.Unload:
9310 commandToSend = command; 9860 commandToSend = command;
9311 break; 9861 break;
9312 9862
9313 case ParcelMediaCommandEnum.Url: 9863 case (uint)ParcelMediaCommandEnum.Url:
9314 if ((i + 1) < commandList.Length) 9864 if ((i + 1) < commandList.Length)
9315 { 9865 {
9316 if (commandList.Data[i + 1] is LSL_String) 9866 if (commandList.Data[i + 1] is LSL_String)
@@ -9323,7 +9873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9323 } 9873 }
9324 break; 9874 break;
9325 9875
9326 case ParcelMediaCommandEnum.Texture: 9876 case (uint)ParcelMediaCommandEnum.Texture:
9327 if ((i + 1) < commandList.Length) 9877 if ((i + 1) < commandList.Length)
9328 { 9878 {
9329 if (commandList.Data[i + 1] is LSL_String) 9879 if (commandList.Data[i + 1] is LSL_String)
@@ -9336,7 +9886,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9336 } 9886 }
9337 break; 9887 break;
9338 9888
9339 case ParcelMediaCommandEnum.Time: 9889 case (uint)ParcelMediaCommandEnum.Time:
9340 if ((i + 1) < commandList.Length) 9890 if ((i + 1) < commandList.Length)
9341 { 9891 {
9342 if (commandList.Data[i + 1] is LSL_Float) 9892 if (commandList.Data[i + 1] is LSL_Float)
@@ -9348,7 +9898,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9348 } 9898 }
9349 break; 9899 break;
9350 9900
9351 case ParcelMediaCommandEnum.AutoAlign: 9901 case (uint)ParcelMediaCommandEnum.AutoAlign:
9352 if ((i + 1) < commandList.Length) 9902 if ((i + 1) < commandList.Length)
9353 { 9903 {
9354 if (commandList.Data[i + 1] is LSL_Integer) 9904 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9362,7 +9912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9362 } 9912 }
9363 break; 9913 break;
9364 9914
9365 case ParcelMediaCommandEnum.Type: 9915 case (uint)ParcelMediaCommandEnum.Type:
9366 if ((i + 1) < commandList.Length) 9916 if ((i + 1) < commandList.Length)
9367 { 9917 {
9368 if (commandList.Data[i + 1] is LSL_String) 9918 if (commandList.Data[i + 1] is LSL_String)
@@ -9375,7 +9925,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9375 } 9925 }
9376 break; 9926 break;
9377 9927
9378 case ParcelMediaCommandEnum.Desc: 9928 case (uint)ParcelMediaCommandEnum.Desc:
9379 if ((i + 1) < commandList.Length) 9929 if ((i + 1) < commandList.Length)
9380 { 9930 {
9381 if (commandList.Data[i + 1] is LSL_String) 9931 if (commandList.Data[i + 1] is LSL_String)
@@ -9388,7 +9938,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9388 } 9938 }
9389 break; 9939 break;
9390 9940
9391 case ParcelMediaCommandEnum.Size: 9941 case (uint)ParcelMediaCommandEnum.Size:
9392 if ((i + 2) < commandList.Length) 9942 if ((i + 2) < commandList.Length)
9393 { 9943 {
9394 if (commandList.Data[i + 1] is LSL_Integer) 9944 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9458,7 +10008,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9458 } 10008 }
9459 } 10009 }
9460 10010
9461 if (commandToSend != null) 10011 if (commandToSend != 0)
9462 { 10012 {
9463 // the commandList contained a start/stop/... command, too 10013 // the commandList contained a start/stop/... command, too
9464 if (presence == null) 10014 if (presence == null)
@@ -9495,7 +10045,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9495 10045
9496 if (aList.Data[i] != null) 10046 if (aList.Data[i] != null)
9497 { 10047 {
9498 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10048 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9499 { 10049 {
9500 case ParcelMediaCommandEnum.Url: 10050 case ParcelMediaCommandEnum.Url:
9501 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10051 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9538,16 +10088,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9538 { 10088 {
9539 m_host.AddScriptLPS(1); 10089 m_host.AddScriptLPS(1);
9540 10090
9541 lock (m_host.TaskInventory) 10091 m_host.TaskInventory.LockItemsForRead(true);
10092 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9542 { 10093 {
9543 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10094 if (inv.Value.Name == name)
9544 { 10095 {
9545 if (inv.Value.Name == name) 10096 m_host.TaskInventory.LockItemsForRead(false);
9546 { 10097 return inv.Value.Type;
9547 return inv.Value.Type;
9548 }
9549 } 10098 }
9550 } 10099 }
10100 m_host.TaskInventory.LockItemsForRead(false);
9551 10101
9552 return -1; 10102 return -1;
9553 } 10103 }
@@ -9558,15 +10108,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9558 10108
9559 if (quick_pay_buttons.Data.Length < 4) 10109 if (quick_pay_buttons.Data.Length < 4)
9560 { 10110 {
9561 LSLError("List must have at least 4 elements"); 10111 int x;
9562 return; 10112 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10113 {
10114 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10115 }
9563 } 10116 }
9564 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10117 int[] nPrice = new int[5];
9565 10118 nPrice[0] = price;
9566 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10119 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9567 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10120 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9568 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10121 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9569 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10122 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10123 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9570 m_host.ParentGroup.HasGroupChanged = true; 10124 m_host.ParentGroup.HasGroupChanged = true;
9571 } 10125 }
9572 10126
@@ -9578,17 +10132,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9578 if (invItemID == UUID.Zero) 10132 if (invItemID == UUID.Zero)
9579 return new LSL_Vector(); 10133 return new LSL_Vector();
9580 10134
9581 lock (m_host.TaskInventory) 10135 m_host.TaskInventory.LockItemsForRead(true);
10136 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9582 { 10137 {
9583 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10138 m_host.TaskInventory.LockItemsForRead(false);
9584 return new LSL_Vector(); 10139 return new LSL_Vector();
10140 }
9585 10141
9586 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10142 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9587 { 10143 {
9588 ShoutError("No permissions to track the camera"); 10144 ShoutError("No permissions to track the camera");
9589 return new LSL_Vector(); 10145 m_host.TaskInventory.LockItemsForRead(false);
9590 } 10146 return new LSL_Vector();
9591 } 10147 }
10148 m_host.TaskInventory.LockItemsForRead(false);
9592 10149
9593 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10150 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9594 if (presence != null) 10151 if (presence != null)
@@ -9606,17 +10163,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9606 if (invItemID == UUID.Zero) 10163 if (invItemID == UUID.Zero)
9607 return new LSL_Rotation(); 10164 return new LSL_Rotation();
9608 10165
9609 lock (m_host.TaskInventory) 10166 m_host.TaskInventory.LockItemsForRead(true);
10167 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9610 { 10168 {
9611 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10169 m_host.TaskInventory.LockItemsForRead(false);
9612 return new LSL_Rotation(); 10170 return new LSL_Rotation();
9613 10171 }
9614 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10172 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9615 { 10173 {
9616 ShoutError("No permissions to track the camera"); 10174 ShoutError("No permissions to track the camera");
9617 return new LSL_Rotation(); 10175 m_host.TaskInventory.LockItemsForRead(false);
9618 } 10176 return new LSL_Rotation();
9619 } 10177 }
10178 m_host.TaskInventory.LockItemsForRead(false);
9620 10179
9621 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10180 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9622 if (presence != null) 10181 if (presence != null)
@@ -9678,8 +10237,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9678 { 10237 {
9679 m_host.AddScriptLPS(1); 10238 m_host.AddScriptLPS(1);
9680 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10239 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9681 if (detectedParams == null) return; // only works on the first detected avatar 10240 if (detectedParams == null)
9682 10241 {
10242 if (m_host.ParentGroup.IsAttachment == true)
10243 {
10244 detectedParams = new DetectParams();
10245 detectedParams.Key = m_host.OwnerID;
10246 }
10247 else
10248 {
10249 return;
10250 }
10251 }
10252
9683 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10253 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9684 if (avatar != null) 10254 if (avatar != null)
9685 { 10255 {
@@ -9687,6 +10257,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9687 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10257 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9688 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10258 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9689 } 10259 }
10260
9690 ScriptSleep(1000); 10261 ScriptSleep(1000);
9691 } 10262 }
9692 10263
@@ -9798,14 +10369,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9798 if (objectID == UUID.Zero) return; 10369 if (objectID == UUID.Zero) return;
9799 10370
9800 UUID agentID; 10371 UUID agentID;
9801 lock (m_host.TaskInventory) 10372 m_host.TaskInventory.LockItemsForRead(true);
9802 { 10373 // we need the permission first, to know which avatar we want to set the camera for
9803 // we need the permission first, to know which avatar we want to set the camera for 10374 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9804 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9805 10375
9806 if (agentID == UUID.Zero) return; 10376 if (agentID == UUID.Zero)
9807 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10377 {
10378 m_host.TaskInventory.LockItemsForRead(false);
10379 return;
10380 }
10381 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10382 {
10383 m_host.TaskInventory.LockItemsForRead(false);
10384 return;
9808 } 10385 }
10386 m_host.TaskInventory.LockItemsForRead(false);
9809 10387
9810 ScenePresence presence = World.GetScenePresence(agentID); 10388 ScenePresence presence = World.GetScenePresence(agentID);
9811 10389
@@ -9814,12 +10392,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9814 10392
9815 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10393 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9816 object[] data = rules.Data; 10394 object[] data = rules.Data;
9817 for (int i = 0; i < data.Length; ++i) { 10395 for (int i = 0; i < data.Length; ++i)
10396 {
9818 int type = Convert.ToInt32(data[i++].ToString()); 10397 int type = Convert.ToInt32(data[i++].ToString());
9819 if (i >= data.Length) break; // odd number of entries => ignore the last 10398 if (i >= data.Length) break; // odd number of entries => ignore the last
9820 10399
9821 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10400 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9822 switch (type) { 10401 switch (type)
10402 {
9823 case ScriptBaseClass.CAMERA_FOCUS: 10403 case ScriptBaseClass.CAMERA_FOCUS:
9824 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10404 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9825 case ScriptBaseClass.CAMERA_POSITION: 10405 case ScriptBaseClass.CAMERA_POSITION:
@@ -9855,12 +10435,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9855 10435
9856 // we need the permission first, to know which avatar we want to clear the camera for 10436 // we need the permission first, to know which avatar we want to clear the camera for
9857 UUID agentID; 10437 UUID agentID;
9858 lock (m_host.TaskInventory) 10438 m_host.TaskInventory.LockItemsForRead(true);
10439 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10440 if (agentID == UUID.Zero)
9859 { 10441 {
9860 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10442 m_host.TaskInventory.LockItemsForRead(false);
9861 if (agentID == UUID.Zero) return; 10443 return;
9862 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10444 }
10445 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10446 {
10447 m_host.TaskInventory.LockItemsForRead(false);
10448 return;
9863 } 10449 }
10450 m_host.TaskInventory.LockItemsForRead(false);
9864 10451
9865 ScenePresence presence = World.GetScenePresence(agentID); 10452 ScenePresence presence = World.GetScenePresence(agentID);
9866 10453
@@ -9927,19 +10514,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9927 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10514 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9928 { 10515 {
9929 m_host.AddScriptLPS(1); 10516 m_host.AddScriptLPS(1);
9930 string ret = String.Empty; 10517
9931 string src1 = llBase64ToString(str1); 10518 if (str1 == String.Empty)
9932 string src2 = llBase64ToString(str2); 10519 return String.Empty;
9933 int c = 0; 10520 if (str2 == String.Empty)
9934 for (int i = 0; i < src1.Length; i++) 10521 return str1;
10522
10523 int len = str2.Length;
10524 if ((len % 4) != 0) // LL is EVIL!!!!
10525 {
10526 while (str2.EndsWith("="))
10527 str2 = str2.Substring(0, str2.Length - 1);
10528
10529 len = str2.Length;
10530 int mod = len % 4;
10531
10532 if (mod == 1)
10533 str2 = str2.Substring(0, str2.Length - 1);
10534 else if (mod == 2)
10535 str2 += "==";
10536 else if (mod == 3)
10537 str2 += "=";
10538 }
10539
10540 byte[] data1;
10541 byte[] data2;
10542 try
10543 {
10544 data1 = Convert.FromBase64String(str1);
10545 data2 = Convert.FromBase64String(str2);
10546 }
10547 catch (Exception)
10548 {
10549 return new LSL_String(String.Empty);
10550 }
10551
10552 byte[] d2 = new Byte[data1.Length];
10553 int pos = 0;
10554
10555 if (data1.Length <= data2.Length)
10556 {
10557 Array.Copy(data2, 0, d2, 0, data1.Length);
10558 }
10559 else
9935 { 10560 {
9936 ret += (char) (src1[i] ^ src2[c]); 10561 while (pos < data1.Length)
10562 {
10563 len = data1.Length - pos;
10564 if (len > data2.Length)
10565 len = data2.Length;
9937 10566
9938 c++; 10567 Array.Copy(data2, 0, d2, pos, len);
9939 if (c >= src2.Length) 10568 pos += len;
9940 c = 0; 10569 }
9941 } 10570 }
9942 return llStringToBase64(ret); 10571
10572 for (pos = 0 ; pos < data1.Length ; pos++ )
10573 data1[pos] ^= d2[pos];
10574
10575 return Convert.ToBase64String(data1);
9943 } 10576 }
9944 10577
9945 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10578 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9996,12 +10629,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9996 Regex r = new Regex(authregex); 10629 Regex r = new Regex(authregex);
9997 int[] gnums = r.GetGroupNumbers(); 10630 int[] gnums = r.GetGroupNumbers();
9998 Match m = r.Match(url); 10631 Match m = r.Match(url);
9999 if (m.Success) { 10632 if (m.Success)
10000 for (int i = 1; i < gnums.Length; i++) { 10633 {
10634 for (int i = 1; i < gnums.Length; i++)
10635 {
10001 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10636 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10002 //CaptureCollection cc = g.Captures; 10637 //CaptureCollection cc = g.Captures;
10003 } 10638 }
10004 if (m.Groups.Count == 5) { 10639 if (m.Groups.Count == 5)
10640 {
10005 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10641 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10006 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10642 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10007 } 10643 }
@@ -10287,15 +10923,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10287 10923
10288 internal UUID ScriptByName(string name) 10924 internal UUID ScriptByName(string name)
10289 { 10925 {
10290 lock (m_host.TaskInventory) 10926 m_host.TaskInventory.LockItemsForRead(true);
10927
10928 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10291 { 10929 {
10292 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10930 if (item.Type == 10 && item.Name == name)
10293 { 10931 {
10294 if (item.Type == 10 && item.Name == name) 10932 m_host.TaskInventory.LockItemsForRead(false);
10295 return item.ItemID; 10933 return item.ItemID;
10296 } 10934 }
10297 } 10935 }
10298 10936
10937 m_host.TaskInventory.LockItemsForRead(false);
10938
10299 return UUID.Zero; 10939 return UUID.Zero;
10300 } 10940 }
10301 10941
@@ -10336,6 +10976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10336 { 10976 {
10337 m_host.AddScriptLPS(1); 10977 m_host.AddScriptLPS(1);
10338 10978
10979 //Clone is thread safe
10339 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10980 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10340 10981
10341 UUID assetID = UUID.Zero; 10982 UUID assetID = UUID.Zero;
@@ -10398,6 +11039,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10398 { 11039 {
10399 m_host.AddScriptLPS(1); 11040 m_host.AddScriptLPS(1);
10400 11041
11042 //Clone is thread safe
10401 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11043 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10402 11044
10403 UUID assetID = UUID.Zero; 11045 UUID assetID = UUID.Zero;
@@ -10478,15 +11120,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10478 return GetLinkPrimitiveParams(obj, rules); 11120 return GetLinkPrimitiveParams(obj, rules);
10479 } 11121 }
10480 11122
10481 public void print(string str) 11123 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10482 { 11124 {
10483 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11125 List<SceneObjectPart> parts = GetLinkParts(link);
10484 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11126 if (parts.Count < 1)
10485 if (ossl != null) 11127 return 0;
10486 { 11128
10487 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11129 return GetNumberOfSides(parts[0]);
10488 m_log.Info("LSL print():" + str);
10489 }
10490 } 11130 }
10491 11131
10492 private string Name2Username(string name) 11132 private string Name2Username(string name)
@@ -10532,153 +11172,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10532 return rq.ToString(); 11172 return rq.ToString();
10533 } 11173 }
10534 11174
11175 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11176 {
11177 m_SayShoutCount = 0;
11178 }
11179
11180 private struct Tri
11181 {
11182 public Vector3 p1;
11183 public Vector3 p2;
11184 public Vector3 p3;
11185 }
11186
11187 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11188 {
11189 float height = avatar.Appearance.AvatarHeight;
11190 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11191 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11192
11193 if (point.X > b1.X && point.X < b2.X &&
11194 point.Y > b1.Y && point.Y < b2.Y &&
11195 point.Z > b1.Z && point.Z < b2.Z)
11196 return true;
11197 return false;
11198 }
11199
11200 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11201 {
11202 List<ContactResult> contacts = new List<ContactResult>();
11203
11204 Vector3 ab = rayEnd - rayStart;
11205
11206 World.ForEachScenePresence(delegate(ScenePresence sp)
11207 {
11208 Vector3 ac = sp.AbsolutePosition - rayStart;
11209 Vector3 bc = sp.AbsolutePosition - rayEnd;
11210
11211 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11212
11213 if (d > 1.5)
11214 return;
11215
11216 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11217
11218 if (d2 > 0)
11219 return;
11220
11221 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11222 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11223
11224 if (!InBoundingBox(sp, p))
11225 return;
11226
11227 ContactResult result = new ContactResult ();
11228 result.ConsumerID = sp.LocalId;
11229 result.Depth = Vector3.Distance(rayStart, p);
11230 result.Normal = Vector3.Zero;
11231 result.Pos = p;
11232
11233 contacts.Add(result);
11234 });
11235
11236 return contacts.ToArray();
11237 }
11238
11239 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11240 {
11241 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11242 List<ContactResult> contacts = new List<ContactResult>();
11243
11244 Vector3 ab = rayEnd - rayStart;
11245
11246 World.ForEachSOG(delegate(SceneObjectGroup group)
11247 {
11248 if (m_host.ParentGroup == group)
11249 return;
11250
11251 if (group.IsAttachment)
11252 return;
11253
11254 if (group.RootPart.PhysActor == null)
11255 {
11256 if (!includePhantom)
11257 return;
11258 }
11259 else
11260 {
11261 if (group.RootPart.PhysActor.IsPhysical)
11262 {
11263 if (!includePhysical)
11264 return;
11265 }
11266 else
11267 {
11268 if (!includeNonPhysical)
11269 return;
11270 }
11271 }
11272
11273 // Find the radius ouside of which we don't even need to hit test
11274 float minX;
11275 float maxX;
11276 float minY;
11277 float maxY;
11278 float minZ;
11279 float maxZ;
11280
11281 float radius = 0.0f;
11282
11283 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11284
11285 if (Math.Abs(minX) > radius)
11286 radius = Math.Abs(minX);
11287 if (Math.Abs(minY) > radius)
11288 radius = Math.Abs(minY);
11289 if (Math.Abs(minZ) > radius)
11290 radius = Math.Abs(minZ);
11291 if (Math.Abs(maxX) > radius)
11292 radius = Math.Abs(maxX);
11293 if (Math.Abs(maxY) > radius)
11294 radius = Math.Abs(maxY);
11295 if (Math.Abs(maxZ) > radius)
11296 radius = Math.Abs(maxZ);
11297
11298 Vector3 ac = group.AbsolutePosition - rayStart;
11299 Vector3 bc = group.AbsolutePosition - rayEnd;
11300
11301 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11302
11303 // Too far off ray, don't bother
11304 if (d > radius)
11305 return;
11306
11307 // Behind ray, drop
11308 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11309 if (d2 > 0)
11310 return;
11311
11312 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11313 // Miss.
11314 if (!intersection.HitTF)
11315 return;
11316
11317 ContactResult result = new ContactResult ();
11318 result.ConsumerID = group.LocalId;
11319 result.Depth = intersection.distance;
11320 result.Normal = intersection.normal;
11321 result.Pos = intersection.ipoint;
11322
11323 contacts.Add(result);
11324 });
11325
11326 return contacts.ToArray();
11327 }
11328
11329 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11330 {
11331 double[,] heightfield = World.Heightmap.GetDoubles();
11332 List<ContactResult> contacts = new List<ContactResult>();
11333
11334 double min = 2048.0;
11335 double max = 0.0;
11336
11337 // Find the min and max of the heightfield
11338 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11339 {
11340 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11341 {
11342 if (heightfield[x, y] > max)
11343 max = heightfield[x, y];
11344 if (heightfield[x, y] < min)
11345 min = heightfield[x, y];
11346 }
11347 }
11348
11349
11350 // A ray extends past rayEnd, but doesn't go back before
11351 // rayStart. If the start is above the highest point of the ground
11352 // and the ray goes up, we can't hit the ground. Ever.
11353 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11354 return null;
11355
11356 // Same for going down
11357 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11358 return null;
11359
11360 List<Tri> trilist = new List<Tri>();
11361
11362 // Create our triangle list
11363 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11364 {
11365 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11366 {
11367 Tri t1 = new Tri();
11368 Tri t2 = new Tri();
11369
11370 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11371 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11372 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11373 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11374
11375 t1.p1 = p1;
11376 t1.p2 = p2;
11377 t1.p3 = p3;
11378
11379 t2.p1 = p3;
11380 t2.p2 = p4;
11381 t2.p3 = p1;
11382
11383 trilist.Add(t1);
11384 trilist.Add(t2);
11385 }
11386 }
11387
11388 // Ray direction
11389 Vector3 rayDirection = rayEnd - rayStart;
11390
11391 foreach (Tri t in trilist)
11392 {
11393 // Compute triangle plane normal and edges
11394 Vector3 u = t.p2 - t.p1;
11395 Vector3 v = t.p3 - t.p1;
11396 Vector3 n = Vector3.Cross(u, v);
11397
11398 if (n == Vector3.Zero)
11399 continue;
11400
11401 Vector3 w0 = rayStart - t.p1;
11402 double a = -Vector3.Dot(n, w0);
11403 double b = Vector3.Dot(n, rayDirection);
11404
11405 // Not intersecting the plane, or in plane (same thing)
11406 // Ignoring this MAY cause the ground to not be detected
11407 // sometimes
11408 if (Math.Abs(b) < 0.000001)
11409 continue;
11410
11411 double r = a / b;
11412
11413 // ray points away from plane
11414 if (r < 0.0)
11415 continue;
11416
11417 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11418
11419 float uu = Vector3.Dot(u, u);
11420 float uv = Vector3.Dot(u, v);
11421 float vv = Vector3.Dot(v, v);
11422 Vector3 w = ip - t.p1;
11423 float wu = Vector3.Dot(w, u);
11424 float wv = Vector3.Dot(w, v);
11425 float d = uv * uv - uu * vv;
11426
11427 float cs = (uv * wv - vv * wu) / d;
11428 if (cs < 0 || cs > 1.0)
11429 continue;
11430 float ct = (uv * wu - uu * wv) / d;
11431 if (ct < 0 || (cs + ct) > 1.0)
11432 continue;
11433
11434 // Add contact point
11435 ContactResult result = new ContactResult ();
11436 result.ConsumerID = 0;
11437 result.Depth = Vector3.Distance(rayStart, ip);
11438 result.Normal = n;
11439 result.Pos = ip;
11440
11441 contacts.Add(result);
11442 }
11443
11444 if (contacts.Count == 0)
11445 return null;
11446
11447 contacts.Sort(delegate(ContactResult a, ContactResult b)
11448 {
11449 return (int)(a.Depth - b.Depth);
11450 });
11451
11452 return contacts[0];
11453 }
11454
10535 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11455 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10536 { 11456 {
11457 LSL_List list = new LSL_List();
11458
10537 m_host.AddScriptLPS(1); 11459 m_host.AddScriptLPS(1);
10538 11460
10539 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11461 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10540 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11462 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10541 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11463 Vector3 dir = rayEnd - rayStart;
10542 11464
10543 int count = 0; 11465 int count = 1;
10544// int detectPhantom = 0; 11466 bool detectPhantom = false;
10545 int dataFlags = 0; 11467 int dataFlags = 0;
10546 int rejectTypes = 0; 11468 int rejectTypes = 0;
10547 11469
10548 for (int i = 0; i < options.Length; i += 2) 11470 for (int i = 0; i < options.Length; i += 2)
10549 { 11471 {
10550 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11472 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10551 {
10552 count = options.GetLSLIntegerItem(i + 1); 11473 count = options.GetLSLIntegerItem(i + 1);
10553 } 11474 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10554// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11475 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10555// {
10556// detectPhantom = options.GetLSLIntegerItem(i + 1);
10557// }
10558 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11476 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10559 {
10560 dataFlags = options.GetLSLIntegerItem(i + 1); 11477 dataFlags = options.GetLSLIntegerItem(i + 1);
10561 }
10562 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11478 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10563 {
10564 rejectTypes = options.GetLSLIntegerItem(i + 1); 11479 rejectTypes = options.GetLSLIntegerItem(i + 1);
10565 }
10566 } 11480 }
10567 11481
10568 LSL_List list = new LSL_List(); 11482 if (count > 16)
10569 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11483 count = 16;
10570
10571 double distance = Util.GetDistanceTo(startvector, endvector);
10572
10573 if (distance == 0)
10574 distance = 0.001;
10575 11484
10576 Vector3 posToCheck = startvector; 11485 List<ContactResult> results = new List<ContactResult>();
10577 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10578 11486
10579 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11487 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10580 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11488 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10581 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11489 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10582 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11490 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10583 11491
10584 for (float i = 0; i <= distance; i += 0.1f) 11492 if (checkTerrain)
10585 { 11493 {
10586 posToCheck = startvector + (dir * (i / (float)distance)); 11494 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11495 if (groundContact != null)
11496 results.Add((ContactResult)groundContact);
11497 }
10587 11498
10588 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11499 if (checkAgents)
10589 { 11500 {
10590 ContactResult result = new ContactResult(); 11501 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10591 result.ConsumerID = 0; 11502 foreach (ContactResult r in agentHits)
10592 result.Depth = 0; 11503 results.Add(r);
10593 result.Normal = Vector3.Zero; 11504 }
10594 result.Pos = posToCheck;
10595 results.Add(result);
10596 checkTerrain = false;
10597 }
10598 11505
10599 if (checkAgents) 11506 if (checkPhysical || checkNonPhysical)
10600 { 11507 {
10601 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11508 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10602 { 11509 foreach (ContactResult r in objectHits)
10603 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11510 results.Add(r);
10604 {
10605 ContactResult result = new ContactResult ();
10606 result.ConsumerID = sp.LocalId;
10607 result.Depth = 0;
10608 result.Normal = Vector3.Zero;
10609 result.Pos = posToCheck;
10610 results.Add(result);
10611 }
10612 });
10613 }
10614 } 11511 }
10615 11512
10616 int refcount = 0; 11513 results.Sort(delegate(ContactResult a, ContactResult b)
11514 {
11515 return (int)(a.Depth - b.Depth);
11516 });
11517
11518 int values = 0;
10617 foreach (ContactResult result in results) 11519 foreach (ContactResult result in results)
10618 { 11520 {
10619 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11521 UUID itemID = UUID.Zero;
10620 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11522 int linkNum = 0;
10621 continue;
10622
10623 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
10624 11523
10625 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11524 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
10626 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11525 // It's a prim!
10627 11526 if (part != null)
10628 if (entity == null)
10629 { 11527 {
10630 list.Add(UUID.Zero); 11528 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10631 11529 itemID = part.ParentGroup.UUID;
10632 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11530 else
10633 list.Add(0); 11531 itemID = part.UUID;
10634
10635 list.Add(result.Pos);
10636
10637 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10638 list.Add(result.Normal);
10639 11532
10640 continue; //Can't find it, so add UUID.Zero 11533 linkNum = part.LinkNum;
10641 } 11534 }
10642 11535 else
10643 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10644 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10645 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10646
10647 if (entity is SceneObjectPart)
10648 { 11536 {
10649 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11537 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10650 { 11538 /// It it a boy? a girl?
10651 if (!checkPhysical) 11539 if (sp != null)
10652 continue; 11540 itemID = sp.UUID;
10653 }
10654 else
10655 {
10656 if (!checkNonPhysical)
10657 continue;
10658 }
10659 } 11541 }
10660 11542
10661 refcount++; 11543 list.Add(new LSL_String(itemID.ToString()));
10662 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11544 list.Add(new LSL_String(result.Pos.ToString()));
10663 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10664 else
10665 list.Add(entity.UUID);
10666 11545
10667 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11546 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10668 { 11547 list.Add(new LSL_Integer(linkNum));
10669 if (entity is SceneObjectPart)
10670 list.Add(((SceneObjectPart)entity).LinkNum);
10671 else
10672 list.Add(0);
10673 }
10674 11548
10675 list.Add(result.Pos);
10676 11549
10677 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11550 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10678 list.Add(result.Normal); 11551 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11552
11553 values++;
11554 count--;
11555
11556 if (count == 0)
11557 break;
10679 } 11558 }
10680 11559
10681 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11560 list.Add(new LSL_Integer(values));
10682 11561
10683 return list; 11562 return list;
10684 } 11563 }
@@ -10718,7 +11597,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10718 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11597 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10719 if (!isAccount) return 0; 11598 if (!isAccount) return 0;
10720 if (estate.HasAccess(id)) return 1; 11599 if (estate.HasAccess(id)) return 1;
10721 if (estate.IsBanned(id)) 11600 if (estate.IsBanned(id, World.GetUserFlags(id)))
10722 estate.RemoveBan(id); 11601 estate.RemoveBan(id);
10723 estate.AddEstateUser(id); 11602 estate.AddEstateUser(id);
10724 break; 11603 break;
@@ -10737,14 +11616,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10737 break; 11616 break;
10738 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11617 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10739 if (!isAccount) return 0; 11618 if (!isAccount) return 0;
10740 if (estate.IsBanned(id)) return 1; 11619 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10741 EstateBan ban = new EstateBan(); 11620 EstateBan ban = new EstateBan();
10742 ban.EstateID = estate.EstateID; 11621 ban.EstateID = estate.EstateID;
10743 ban.BannedUserID = id; 11622 ban.BannedUserID = id;
10744 estate.AddBan(ban); 11623 estate.AddBan(ban);
10745 break; 11624 break;
10746 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11625 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10747 if (!isAccount || !estate.IsBanned(id)) return 0; 11626 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10748 estate.RemoveBan(id); 11627 estate.RemoveBan(id);
10749 break; 11628 break;
10750 default: return 0; 11629 default: return 0;
@@ -10770,22 +11649,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10770 NotImplemented("llGetSPMaxMemory"); 11649 NotImplemented("llGetSPMaxMemory");
10771 } 11650 }
10772 11651
10773 public void llGetUsedMemory() 11652 public virtual LSL_Integer llGetUsedMemory()
10774 { 11653 {
10775 m_host.AddScriptLPS(1); 11654 m_host.AddScriptLPS(1);
10776 NotImplemented("llGetUsedMemory"); 11655 NotImplemented("llGetUsedMemory");
11656 return 0;
10777 } 11657 }
10778 11658
10779 public void llScriptProfiler(LSL_Integer flags) 11659 public void llScriptProfiler(LSL_Integer flags)
10780 { 11660 {
10781 m_host.AddScriptLPS(1); 11661 m_host.AddScriptLPS(1);
10782 NotImplemented("llScriptProfiler"); 11662 //NotImplemented("llScriptProfiler");
10783 } 11663 }
10784 11664
10785 public void llSetSoundQueueing(int queue) 11665 public void llSetSoundQueueing(int queue)
10786 { 11666 {
10787 m_host.AddScriptLPS(1); 11667 m_host.AddScriptLPS(1);
10788 NotImplemented("llSetSoundQueueing");
10789 } 11668 }
10790 11669
10791 public void llCollisionSprite(string impact_sprite) 11670 public void llCollisionSprite(string impact_sprite)
@@ -10797,7 +11676,133 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10797 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11676 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10798 { 11677 {
10799 m_host.AddScriptLPS(1); 11678 m_host.AddScriptLPS(1);
10800 NotImplemented("llGodLikeRezObject"); 11679
11680 if (!World.Permissions.IsGod(m_host.OwnerID))
11681 NotImplemented("llGodLikeRezObject");
11682
11683 AssetBase rezAsset = World.AssetService.Get(inventory);
11684 if (rezAsset == null)
11685 {
11686 llSay(0, "Asset not found");
11687 return;
11688 }
11689
11690 SceneObjectGroup group = null;
11691
11692 try
11693 {
11694 string xmlData = Utils.BytesToString(rezAsset.Data);
11695 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11696 }
11697 catch
11698 {
11699 llSay(0, "Asset not found");
11700 return;
11701 }
11702
11703 if (group == null)
11704 {
11705 llSay(0, "Asset not found");
11706 return;
11707 }
11708
11709 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11710 group.RootPart.AttachOffset = group.AbsolutePosition;
11711
11712 group.ResetIDs();
11713
11714 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11715 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11716 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11717 group.ScheduleGroupForFullUpdate();
11718
11719 // objects rezzed with this method are die_at_edge by default.
11720 group.RootPart.SetDieAtEdge(true);
11721
11722 group.ResumeScripts();
11723
11724 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11725 "object_rez", new Object[] {
11726 new LSL_String(
11727 group.RootPart.UUID.ToString()) },
11728 new DetectParams[0]));
11729 }
11730
11731 public LSL_String llTransferLindenDollars(string destination, int amount)
11732 {
11733 UUID txn = UUID.Random();
11734
11735 Util.FireAndForget(delegate(object x)
11736 {
11737 int replycode = 0;
11738 string replydata = destination + "," + amount.ToString();
11739
11740 try
11741 {
11742 UUID invItemID=InventorySelf();
11743 if (invItemID == UUID.Zero)
11744 {
11745 replydata = "SERVICE_ERROR";
11746 return;
11747 }
11748
11749 m_host.AddScriptLPS(1);
11750
11751 m_host.TaskInventory.LockItemsForRead(true);
11752 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11753 m_host.TaskInventory.LockItemsForRead(false);
11754
11755 if (item.PermsGranter == UUID.Zero)
11756 {
11757 replydata = "MISSING_PERMISSION_DEBIT";
11758 return;
11759 }
11760
11761 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11762 {
11763 replydata = "MISSING_PERMISSION_DEBIT";
11764 return;
11765 }
11766
11767 UUID toID = new UUID();
11768
11769 if (!UUID.TryParse(destination, out toID))
11770 {
11771 replydata = "INVALID_AGENT";
11772 return;
11773 }
11774
11775 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11776
11777 if (money == null)
11778 {
11779 replydata = "TRANSFERS_DISABLED";
11780 return;
11781 }
11782
11783 bool result = money.ObjectGiveMoney(
11784 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11785
11786 if (result)
11787 {
11788 replycode = 1;
11789 return;
11790 }
11791
11792 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11793 }
11794 finally
11795 {
11796 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11797 "transaction_result", new Object[] {
11798 new LSL_String(txn.ToString()),
11799 new LSL_Integer(replycode),
11800 new LSL_String(replydata) },
11801 new DetectParams[0]));
11802 }
11803 });
11804
11805 return txn.ToString();
10801 } 11806 }
10802 11807
10803 #endregion 11808 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index c55e2ae..2424130 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 private void InitLSL() 221 private void InitLSL()
@@ -917,18 +926,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
917 if (target != null) 926 if (target != null)
918 { 927 {
919 UUID animID=UUID.Zero; 928 UUID animID=UUID.Zero;
920 lock (m_host.TaskInventory) 929 m_host.TaskInventory.LockItemsForRead(true);
930 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
921 { 931 {
922 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 932 if (inv.Value.Name == animation)
923 { 933 {
924 if (inv.Value.Name == animation) 934 if (inv.Value.Type == (int)AssetType.Animation)
925 { 935 animID = inv.Value.AssetID;
926 if (inv.Value.Type == (int)AssetType.Animation) 936 continue;
927 animID = inv.Value.AssetID;
928 continue;
929 }
930 } 937 }
931 } 938 }
939 m_host.TaskInventory.LockItemsForRead(false);
932 if (animID == UUID.Zero) 940 if (animID == UUID.Zero)
933 target.Animator.AddAnimation(animation, m_host.UUID); 941 target.Animator.AddAnimation(animation, m_host.UUID);
934 else 942 else
@@ -955,18 +963,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
955 if (target != null) 963 if (target != null)
956 { 964 {
957 UUID animID = UUID.Zero; 965 UUID animID = UUID.Zero;
958 lock (m_host.TaskInventory) 966 m_host.TaskInventory.LockItemsForRead(true);
967 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
959 { 968 {
960 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 969 if (inv.Value.Name == animation)
961 { 970 {
962 if (inv.Value.Name == animation) 971 if (inv.Value.Type == (int)AssetType.Animation)
963 { 972 animID = inv.Value.AssetID;
964 if (inv.Value.Type == (int)AssetType.Animation) 973 continue;
965 animID = inv.Value.AssetID;
966 continue;
967 }
968 } 974 }
969 } 975 }
976 m_host.TaskInventory.LockItemsForRead(false);
970 977
971 if (animID == UUID.Zero) 978 if (animID == UUID.Zero)
972 target.Animator.RemoveAnimation(animation); 979 target.Animator.RemoveAnimation(animation);
@@ -1798,6 +1805,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1798 1805
1799 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1806 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1800 { 1807 {
1808 m_host.TaskInventory.LockItemsForRead(true);
1801 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1809 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1802 { 1810 {
1803 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1811 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1805,6 +1813,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1805 assetID = item.AssetID; 1813 assetID = item.AssetID;
1806 } 1814 }
1807 } 1815 }
1816 m_host.TaskInventory.LockItemsForRead(false);
1808 } 1817 }
1809 1818
1810 if (assetID == UUID.Zero) 1819 if (assetID == UUID.Zero)
@@ -2233,7 +2242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2233 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2242 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2234 m_host.AddScriptLPS(1); 2243 m_host.AddScriptLPS(1);
2235 2244
2236 return NpcCreate(firstname, lastname, position, notecard, false, false); 2245 return NpcCreate(firstname, lastname, position, notecard, true, false);
2237 } 2246 }
2238 2247
2239 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2248 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2244,24 +2253,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2244 return NpcCreate( 2253 return NpcCreate(
2245 firstname, lastname, position, notecard, 2254 firstname, lastname, position, notecard,
2246 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2255 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2247 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2256 false);
2257// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2248 } 2258 }
2249 2259
2250 private LSL_Key NpcCreate( 2260 private LSL_Key NpcCreate(
2251 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2261 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2252 { 2262 {
2263 if (!owned)
2264 OSSLError("Unowned NPCs are unsupported");
2265
2266 string groupTitle = String.Empty;
2267
2268 if (firstname != String.Empty || lastname != String.Empty)
2269 {
2270 if (firstname != "Shown outfit:")
2271 groupTitle = "- NPC -";
2272 }
2273
2253 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2274 INPCModule module = World.RequestModuleInterface<INPCModule>();
2254 if (module != null) 2275 if (module != null)
2255 { 2276 {
2256 AvatarAppearance appearance = null; 2277 AvatarAppearance appearance = null;
2257 2278
2258 UUID id; 2279// UUID id;
2259 if (UUID.TryParse(notecard, out id)) 2280// if (UUID.TryParse(notecard, out id))
2260 { 2281// {
2261 ScenePresence clonePresence = World.GetScenePresence(id); 2282// ScenePresence clonePresence = World.GetScenePresence(id);
2262 if (clonePresence != null) 2283// if (clonePresence != null)
2263 appearance = clonePresence.Appearance; 2284// appearance = clonePresence.Appearance;
2264 } 2285// }
2265 2286
2266 if (appearance == null) 2287 if (appearance == null)
2267 { 2288 {
@@ -2289,6 +2310,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2289 World, 2310 World,
2290 appearance); 2311 appearance);
2291 2312
2313 ScenePresence sp;
2314 if (World.TryGetScenePresence(x, out sp))
2315 {
2316 sp.Grouptitle = groupTitle;
2317 sp.SendAvatarDataToAllAgents();
2318 }
2292 return new LSL_Key(x.ToString()); 2319 return new LSL_Key(x.ToString());
2293 } 2320 }
2294 2321
@@ -2557,16 +2584,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2557 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2584 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2558 m_host.AddScriptLPS(1); 2585 m_host.AddScriptLPS(1);
2559 2586
2560 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2587 ManualResetEvent ev = new ManualResetEvent(false);
2561 if (module != null)
2562 {
2563 UUID npcId = new UUID(npc.m_string);
2564 2588
2565 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2589 Util.FireAndForget(delegate(object x) {
2566 return; 2590 try
2591 {
2592 INPCModule module = World.RequestModuleInterface<INPCModule>();
2593 if (module != null)
2594 {
2595 UUID npcId = new UUID(npc.m_string);
2567 2596
2568 module.DeleteNPC(npcId, World); 2597 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2569 } 2598 return;
2599
2600 module.DeleteNPC(npcId, World);
2601 }
2602 }
2603 finally
2604 {
2605 ev.Set();
2606 }
2607 });
2608 ev.WaitOne();
2570 } 2609 }
2571 2610
2572 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2611 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -2917,4 +2956,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2917 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 2956 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2918 } 2957 }
2919 } 2958 }
2920} \ No newline at end of file 2959}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 5c1bdff..83da204 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -210,7 +210,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
210 // Is the sensor type is AGENT and not SCRIPTED then include agents 210 // Is the sensor type is AGENT and not SCRIPTED then include agents
211 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) 211 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
212 { 212 {
213 sensedEntities.AddRange(doAgentSensor(ts)); 213 sensedEntities.AddRange(doAgentSensor(ts));
214 } 214 }
215 215
216 // If SCRIPTED or PASSIVE or ACTIVE check objects 216 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -307,13 +307,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
307 float dy; 307 float dy;
308 float dz; 308 float dz;
309 309
310 Quaternion q = SensePoint.RotationOffset; 310// Quaternion q = SensePoint.RotationOffset;
311 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
311 if (SensePoint.ParentGroup.IsAttachment) 312 if (SensePoint.ParentGroup.IsAttachment)
312 { 313 {
313 // In attachments, the sensor cone always orients with the 314 // In attachments, the sensor cone always orients with the
314 // avatar rotation. This may include a nonzero elevation if 315 // avatar rotation. This may include a nonzero elevation if
315 // in mouselook. 316 // in mouselook.
316 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 317 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
318 fromRegionPos = avatar.AbsolutePosition;
317 q = avatar.Rotation; 319 q = avatar.Rotation;
318 } 320 }
319 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 321 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -436,6 +438,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
436 // avatar rotation. This may include a nonzero elevation if 438 // avatar rotation. This may include a nonzero elevation if
437 // in mouselook. 439 // in mouselook.
438 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 440 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
441 if (avatar == null)
442 return sensedEntities;
443 fromRegionPos = avatar.AbsolutePosition;
439 q = avatar.Rotation; 444 q = avatar.Rotation;
440 } 445 }
441 446
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 6106a65..f2d4399 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
124 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
125 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
126 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
127 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
128 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -201,6 +202,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
201 void llGiveInventory(string destination, string inventory); 202 void llGiveInventory(string destination, string inventory);
202 void llGiveInventoryList(string destination, string category, LSL_List inventory); 203 void llGiveInventoryList(string destination, string category, LSL_List inventory);
203 LSL_Integer llGiveMoney(string destination, int amount); 204 LSL_Integer llGiveMoney(string destination, int amount);
205 LSL_String llTransferLindenDollars(string destination, int amount);
204 void llGodLikeRezObject(string inventory, LSL_Vector pos); 206 void llGodLikeRezObject(string inventory, LSL_Vector pos);
205 LSL_Float llGround(LSL_Vector offset); 207 LSL_Float llGround(LSL_Vector offset);
206 LSL_Vector llGroundContour(LSL_Vector offset); 208 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -408,7 +410,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
408 LSL_Vector llWind(LSL_Vector offset); 410 LSL_Vector llWind(LSL_Vector offset);
409 LSL_String llXorBase64Strings(string str1, string str2); 411 LSL_String llXorBase64Strings(string str1, string str2);
410 LSL_String llXorBase64StringsCorrect(string str1, string str2); 412 LSL_String llXorBase64StringsCorrect(string str1, string str2);
411 void print(string str); 413 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
412 414
413 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 415 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
414 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 416 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index dbc1dfc..ca24051 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
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
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index bb498b5..3d0e5cb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -282,6 +282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 283 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 284 public const int CHANGED_ANIMATION = 16384;
285 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 286 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 287 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 288 public const int TYPE_FLOAT = 2;
@@ -378,6 +379,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
378 public const int PRIM_SCULPT_TYPE_TORUS = 2; 379 public const int PRIM_SCULPT_TYPE_TORUS = 2;
379 public const int PRIM_SCULPT_TYPE_PLANE = 3; 380 public const int PRIM_SCULPT_TYPE_PLANE = 3;
380 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 381 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
382 public const int PRIM_SCULPT_FLAG_INVERT = 64;
383 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
381 384
382 public const int MASK_BASE = 0; 385 public const int MASK_BASE = 0;
383 public const int MASK_OWNER = 1; 386 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 83550a5..fad6c35 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -164,6 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
164 m_LSL_Functions.llBreakLink(linknum); 165 m_LSL_Functions.llBreakLink(linknum);
165 } 166 }
166 167
168 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
169 {
170 return m_LSL_Functions.llCastRay(start, end, options);
171 }
172
167 public LSL_Integer llCeil(double f) 173 public LSL_Integer llCeil(double f)
168 { 174 {
169 return m_LSL_Functions.llCeil(f); 175 return m_LSL_Functions.llCeil(f);
@@ -314,6 +320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 320 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 321 }
316 322
323 [DebuggerNonUserCode]
317 public void llDie() 324 public void llDie()
318 { 325 {
319 m_LSL_Functions.llDie(); 326 m_LSL_Functions.llDie();
@@ -464,6 +471,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 471 return m_LSL_Functions.llGetFreeMemory();
465 } 472 }
466 473
474 public LSL_Integer llGetUsedMemory()
475 {
476 return m_LSL_Functions.llGetUsedMemory();
477 }
478
467 public LSL_Integer llGetFreeURLs() 479 public LSL_Integer llGetFreeURLs()
468 { 480 {
469 return m_LSL_Functions.llGetFreeURLs(); 481 return m_LSL_Functions.llGetFreeURLs();
@@ -849,6 +861,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
849 return m_LSL_Functions.llGiveMoney(destination, amount); 861 return m_LSL_Functions.llGiveMoney(destination, amount);
850 } 862 }
851 863
864 public LSL_String llTransferLindenDollars(string destination, int amount)
865 {
866 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
867 }
868
852 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 869 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
853 { 870 {
854 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 871 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1893,9 +1910,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1893 return m_LSL_Functions.llClearPrimMedia(face); 1910 return m_LSL_Functions.llClearPrimMedia(face);
1894 } 1911 }
1895 1912
1896 public void print(string str) 1913 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1897 { 1914 {
1898 m_LSL_Functions.print(str); 1915 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1899 } 1916 }
1900 } 1917 }
1901} 1918}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index bc1902b..da2ef7b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -264,13 +265,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
264 265
265 if (part != null) 266 if (part != null)
266 { 267 {
267 lock (part.TaskInventory) 268 part.TaskInventory.LockItemsForRead(true);
269 if (part.TaskInventory.ContainsKey(m_ItemID))
268 { 270 {
269 if (part.TaskInventory.ContainsKey(m_ItemID)) 271 m_thisScriptTask = part.TaskInventory[m_ItemID];
270 {
271 m_thisScriptTask = part.TaskInventory[m_ItemID];
272 }
273 } 272 }
273 part.TaskInventory.LockItemsForRead(false);
274 } 274 }
275 275
276 ApiManager am = new ApiManager(); 276 ApiManager am = new ApiManager();
@@ -469,14 +469,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
469 { 469 {
470 int permsMask; 470 int permsMask;
471 UUID permsGranter; 471 UUID permsGranter;
472 lock (part.TaskInventory) 472 part.TaskInventory.LockItemsForRead(true);
473 if (!part.TaskInventory.ContainsKey(m_ItemID))
473 { 474 {
474 if (!part.TaskInventory.ContainsKey(m_ItemID)) 475 part.TaskInventory.LockItemsForRead(false);
475 return; 476 return;
476
477 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
478 permsMask = part.TaskInventory[m_ItemID].PermsMask;
479 } 477 }
478 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
479 permsMask = part.TaskInventory[m_ItemID].PermsMask;
480 part.TaskInventory.LockItemsForRead(false);
480 481
481 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 482 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
482 { 483 {
@@ -588,6 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
588 return true; 589 return true;
589 } 590 }
590 591
592 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
591 public void SetState(string state) 593 public void SetState(string state)
592 { 594 {
593 if (state == State) 595 if (state == State)
@@ -599,7 +601,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
599 new DetectParams[0])); 601 new DetectParams[0]));
600 PostEvent(new EventParams("state_entry", new Object[0], 602 PostEvent(new EventParams("state_entry", new Object[0],
601 new DetectParams[0])); 603 new DetectParams[0]));
602 604
603 throw new EventAbortException(); 605 throw new EventAbortException();
604 } 606 }
605 607
@@ -682,41 +684,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
682 /// <returns></returns> 684 /// <returns></returns>
683 public object EventProcessor() 685 public object EventProcessor()
684 { 686 {
685 lock (m_Script) 687 EventParams data = null;
686 {
687// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
688 688
689 if (Suspended) 689// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
690 return 0;
691 690
692 EventParams data = null; 691 if (Suspended)
692 return 0;
693 693
694 lock (m_EventQueue) 694 lock (m_EventQueue)
695 {
696 data = (EventParams) m_EventQueue.Dequeue();
697 if (data == null) // Shouldn't happen
695 { 698 {
696 data = (EventParams) m_EventQueue.Dequeue(); 699 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
697 if (data == null) // Shouldn't happen
698 { 700 {
699 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 701 m_CurrentResult = m_Engine.QueueEventHandler(this);
700 {
701 m_CurrentResult = m_Engine.QueueEventHandler(this);
702 }
703 else
704 {
705 m_CurrentResult = null;
706 }
707 return 0;
708 } 702 }
709 703 else
710 if (data.EventName == "timer")
711 m_TimerQueued = false;
712 if (data.EventName == "control")
713 { 704 {
714 if (m_ControlEventsInQueue > 0) 705 m_CurrentResult = null;
715 m_ControlEventsInQueue--;
716 } 706 }
717 if (data.EventName == "collision") 707 return 0;
718 m_CollisionInQueue = false; 708 }
709
710 if (data.EventName == "timer")
711 m_TimerQueued = false;
712 if (data.EventName == "control")
713 {
714 if (m_ControlEventsInQueue > 0)
715 m_ControlEventsInQueue--;
719 } 716 }
717 if (data.EventName == "collision")
718 m_CollisionInQueue = false;
719 }
720
721 lock(m_Script)
722 {
720 723
721// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 724// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
722 725
@@ -876,6 +879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
876 new Object[0], new DetectParams[0])); 879 new Object[0], new DetectParams[0]));
877 } 880 }
878 881
882 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
879 public void ApiResetScript() 883 public void ApiResetScript()
880 { 884 {
881 // bool running = Running; 885 // bool running = Running;
@@ -907,10 +911,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
907 911
908 public Dictionary<string, object> GetVars() 912 public Dictionary<string, object> GetVars()
909 { 913 {
910 if (m_Script != null) 914 return m_Script.GetVars();
911 return m_Script.GetVars();
912 else
913 return new Dictionary<string, object>();
914 } 915 }
915 916
916 public void SetVars(Dictionary<string, object> vars) 917 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {