aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to '')
-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.cs3003
-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.cs5
-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.cs26
-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, 2523 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 61a6907..d0430f4 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())
275 { 344 {
276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 345 m_host.TaskInventory.LockItemsForRead(true);
346 unlock = true;
347 }
348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
349 {
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 {
@@ -1978,26 +2177,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1978 return real_vec; 2177 return real_vec;
1979 } 2178 }
1980 2179
2180 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2181 {
2182 return new LSL_Integer(SetRegionPos(m_host, pos));
2183 }
2184
2185 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2186 {
2187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2188 return 0;
2189
2190 SceneObjectGroup grp = part.ParentGroup;
2191
2192 if (grp.IsAttachment)
2193 return 0;
2194
2195 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2196 return 0;
2197
2198 if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
2199 return 0;
2200
2201 float constrainedX = (float)targetPos.x;
2202 float constrainedY = (float)targetPos.y;
2203
2204 if (constrainedX < 0.0f)
2205 constrainedX = 0.0f;
2206 if (constrainedY < 0.0f)
2207 constrainedY = 0.0f;
2208 if (constrainedX >= (float)Constants.RegionSize)
2209 constrainedX = (float)Constants.RegionSize - 0.1f;
2210 if (constrainedY >= (float)Constants.RegionSize)
2211 constrainedY = (float)Constants.RegionSize -0.1f;
2212
2213 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2214
2215 if (targetPos.z < ground)
2216 targetPos.z = ground;
2217
2218 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2219
2220 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2221 return 0;
2222
2223 grp.UpdateGroupPosition(dest);
2224
2225 return 1;
2226 }
2227
1981 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2228 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1982 { 2229 {
1983 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2230 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2231 return;
2232
1984 LSL_Vector currentPos = GetPartLocalPos(part); 2233 LSL_Vector currentPos = GetPartLocalPos(part);
2234 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1985 2235
1986 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1987 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1988 2236
1989 if (part.ParentGroup.RootPart == part) 2237 if (part.ParentGroup.RootPart == part)
1990 { 2238 {
1991 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1992 targetPos.z = ground;
1993 SceneObjectGroup parent = part.ParentGroup; 2239 SceneObjectGroup parent = part.ParentGroup;
1994 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2240 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1995 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2241 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2242 return;
2243 Util.FireAndForget(delegate(object x) {
2244 parent.UpdateGroupPosition(dest);
2245 });
1996 } 2246 }
1997 else 2247 else
1998 { 2248 {
1999 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2249 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; 2250 SceneObjectGroup parent = part.ParentGroup;
2002 parent.HasGroupChanged = true; 2251 parent.HasGroupChanged = true;
2003 parent.ScheduleGroupForTerseUpdate(); 2252 parent.ScheduleGroupForTerseUpdate();
@@ -2028,11 +2277,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2028 } 2277 }
2029 else 2278 else
2030 { 2279 {
2031 if (m_host.IsRoot) 2280 if (part.IsRoot)
2032 { 2281 {
2033 return new LSL_Vector(m_host.AttachedPos.X, 2282 return new LSL_Vector(part.AttachedPos.X,
2034 m_host.AttachedPos.Y, 2283 part.AttachedPos.Y,
2035 m_host.AttachedPos.Z); 2284 part.AttachedPos.Z);
2036 } 2285 }
2037 else 2286 else
2038 { 2287 {
@@ -2048,9 +2297,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2048 m_host.AddScriptLPS(1); 2297 m_host.AddScriptLPS(1);
2049 2298
2050 // try to let this work as in SL... 2299 // try to let this work as in SL...
2051 if (m_host.ParentID == 0) 2300 if (m_host.LinkNum < 2)
2052 { 2301 {
2053 // special case: If we are root, rotate complete SOG to new rotation 2302 // Special case: If we are root, rotate complete SOG to new
2303 // rotation.
2304 // We are root if the link number is 0 (single prim) or 1
2305 // (root prim). ParentID may be nonzero in attachments and
2306 // using it would cause attachments and HUDs to rotate
2307 // to the wrong positions.
2054 SetRot(m_host, Rot2Quaternion(rot)); 2308 SetRot(m_host, Rot2Quaternion(rot));
2055 } 2309 }
2056 else 2310 else
@@ -2075,6 +2329,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 2329
2076 protected void SetRot(SceneObjectPart part, Quaternion rot) 2330 protected void SetRot(SceneObjectPart part, Quaternion rot)
2077 { 2331 {
2332 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2333 return;
2334
2078 part.UpdateRotation(rot); 2335 part.UpdateRotation(rot);
2079 // Update rotation does not move the object in the physics scene if it's a linkset. 2336 // Update rotation does not move the object in the physics scene if it's a linkset.
2080 2337
@@ -2698,12 +2955,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2698 2955
2699 m_host.AddScriptLPS(1); 2956 m_host.AddScriptLPS(1);
2700 2957
2958 m_host.TaskInventory.LockItemsForRead(true);
2701 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2959 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2702 2960 m_host.TaskInventory.LockItemsForRead(false);
2703 lock (m_host.TaskInventory)
2704 {
2705 item = m_host.TaskInventory[invItemID];
2706 }
2707 2961
2708 if (item.PermsGranter == UUID.Zero) 2962 if (item.PermsGranter == UUID.Zero)
2709 return 0; 2963 return 0;
@@ -2771,64 +3025,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2771 { 3025 {
2772 m_host.AddScriptLPS(1); 3026 m_host.AddScriptLPS(1);
2773 3027
2774 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s)) 3028 Util.FireAndForget(delegate (object x)
2775 return; 3029 {
2776 float dist = (float)llVecDist(llGetPos(), pos); 3030 if (Double.IsNaN(rot.x) || Double.IsNaN(rot.y) || Double.IsNaN(rot.z) || Double.IsNaN(rot.s))
3031 return;
3032 float dist = (float)llVecDist(llGetPos(), pos);
2777 3033
2778 if (dist > m_ScriptDistanceFactor * 10.0f) 3034 if (dist > m_ScriptDistanceFactor * 10.0f)
2779 return; 3035 return;
2780 3036
2781 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 3037 //Clone is thread-safe
3038 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2782 3039
2783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 3040 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
2784 {
2785 if (inv.Value.Name == inventory)
2786 { 3041 {
2787 // make sure we're an object. 3042 if (inv.Value.Name == inventory)
2788 if (inv.Value.InvType != (int)InventoryType.Object)
2789 { 3043 {
2790 llSay(0, "Unable to create requested object. Object is missing from database."); 3044 // make sure we're an object.
2791 return; 3045 if (inv.Value.InvType != (int)InventoryType.Object)
2792 } 3046 {
3047 llSay(0, "Unable to create requested object. Object is missing from database.");
3048 return;
3049 }
2793 3050
2794 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z); 3051 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); 3052 Vector3 llvel = new Vector3((float)vel.x, (float)vel.y, (float)vel.z);
2796 3053
2797 // need the magnitude later 3054 // need the magnitude later
2798 float velmag = (float)Util.GetMagnitude(llvel); 3055 // float velmag = (float)Util.GetMagnitude(llvel);
2799 3056
2800 SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param); 3057 SceneObjectGroup new_group = World.RezObject(m_host, inv.Value, llpos, Rot2Quaternion(rot), llvel, param);
2801 3058
2802 // If either of these are null, then there was an unknown error. 3059 // If either of these are null, then there was an unknown error.
2803 if (new_group == null) 3060 if (new_group == null)
2804 continue; 3061 continue;
2805 3062
2806 // objects rezzed with this method are die_at_edge by default. 3063 // objects rezzed with this method are die_at_edge by default.
2807 new_group.RootPart.SetDieAtEdge(true); 3064 new_group.RootPart.SetDieAtEdge(true);
2808 3065
2809 new_group.ResumeScripts(); 3066 new_group.ResumeScripts();
2810 3067
2811 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( 3068 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
2812 "object_rez", new Object[] { 3069 "object_rez", new Object[] {
2813 new LSL_String( 3070 new LSL_String(
2814 new_group.RootPart.UUID.ToString()) }, 3071 new_group.RootPart.UUID.ToString()) },
2815 new DetectParams[0])); 3072 new DetectParams[0]));
2816 3073
2817 float groupmass = new_group.GetMass(); 3074 float groupmass = new_group.GetMass();
2818 3075
2819 if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero) 3076 if (new_group.RootPart.PhysActor != null && new_group.RootPart.PhysActor.IsPhysical && llvel != Vector3.Zero)
2820 { 3077 {
2821 //Recoil. 3078 //Recoil.
2822 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3079 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0);
3080 }
3081 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3082 return;
2823 } 3083 }
2824 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
2825 ScriptSleep((int)((groupmass * velmag) / 10));
2826 ScriptSleep(100);
2827 return;
2828 } 3084 }
2829 }
2830 3085
2831 llSay(0, "Could not find object " + inventory); 3086 llSay(0, "Could not find object " + inventory);
3087 });
3088
3089 //ScriptSleep((int)((groupmass * velmag) / 10));
3090 ScriptSleep(100);
2832 } 3091 }
2833 3092
2834 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param) 3093 public void llRezObject(string inventory, LSL_Vector pos, LSL_Vector vel, LSL_Rotation rot, int param)
@@ -2839,34 +3098,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 public void llLookAt(LSL_Vector target, double strength, double damping) 3098 public void llLookAt(LSL_Vector target, double strength, double damping)
2840 { 3099 {
2841 m_host.AddScriptLPS(1); 3100 m_host.AddScriptLPS(1);
2842 // Determine where we are looking from
2843 LSL_Vector from = llGetPos();
2844 3101
2845 // Work out the normalised vector from the source to the target 3102 // Get the normalized vector to the target
2846 LSL_Vector delta = llVecNorm(target - from); 3103 LSL_Vector d1 = llVecNorm(target - llGetPos());
2847 LSL_Vector angle = new LSL_Vector(0,0,0);
2848 3104
2849 // Calculate the yaw 3105 // Get the bearing (yaw)
2850 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3106 LSL_Vector a1 = new LSL_Vector(0,0,0);
2851 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3107 a1.z = llAtan2(d1.y, d1.x);
2852 3108
2853 // Calculate pitch 3109 // Get the elevation (pitch)
2854 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3110 LSL_Vector a2 = new LSL_Vector(0,0,0);
3111 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2855 3112
2856 // we need to convert from a vector describing 3113 LSL_Rotation r1 = llEuler2Rot(a1);
2857 // the angles of rotation in radians into rotation value 3114 LSL_Rotation r2 = llEuler2Rot(a2);
3115 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2858 3116
2859 LSL_Rotation rot = llEuler2Rot(angle); 3117 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 { 3118 {
2865 llSetRot(rot); 3119 // Do nothing if either value is 0 (this has been checked in SL)
3120 if (strength <= 0.0 || damping <= 0.0)
3121 return;
3122
3123 llSetRot(r3 * r2 * r1);
2866 } 3124 }
2867 else 3125 else
2868 { 3126 {
2869 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3127 if (strength == 0)
3128 {
3129 llSetRot(r3 * r2 * r1);
3130 return;
3131 }
3132
3133 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2870 } 3134 }
2871 } 3135 }
2872 3136
@@ -2916,13 +3180,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3180 {
2917 TaskInventoryItem item; 3181 TaskInventoryItem item;
2918 3182
2919 lock (m_host.TaskInventory) 3183 m_host.TaskInventory.LockItemsForRead(true);
3184 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2920 { 3185 {
2921 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3186 m_host.TaskInventory.LockItemsForRead(false);
2922 return; 3187 return;
2923 else
2924 item = m_host.TaskInventory[InventorySelf()];
2925 } 3188 }
3189 else
3190 {
3191 item = m_host.TaskInventory[InventorySelf()];
3192 }
3193 m_host.TaskInventory.LockItemsForRead(false);
2926 3194
2927 if (item.PermsGranter != UUID.Zero) 3195 if (item.PermsGranter != UUID.Zero)
2928 { 3196 {
@@ -2944,13 +3212,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2944 { 3212 {
2945 TaskInventoryItem item; 3213 TaskInventoryItem item;
2946 3214
3215 m_host.TaskInventory.LockItemsForRead(true);
2947 lock (m_host.TaskInventory) 3216 lock (m_host.TaskInventory)
2948 { 3217 {
3218
2949 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3219 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3220 {
3221 m_host.TaskInventory.LockItemsForRead(false);
2950 return; 3222 return;
3223 }
2951 else 3224 else
3225 {
2952 item = m_host.TaskInventory[InventorySelf()]; 3226 item = m_host.TaskInventory[InventorySelf()];
3227 }
2953 } 3228 }
3229 m_host.TaskInventory.LockItemsForRead(false);
2954 3230
2955 m_host.AddScriptLPS(1); 3231 m_host.AddScriptLPS(1);
2956 3232
@@ -2982,18 +3258,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2982 { 3258 {
2983 m_host.AddScriptLPS(1); 3259 m_host.AddScriptLPS(1);
2984 3260
2985// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2986// return;
2987
2988 TaskInventoryItem item; 3261 TaskInventoryItem item;
2989 3262
2990 lock (m_host.TaskInventory) 3263 m_host.TaskInventory.LockItemsForRead(true);
3264
3265 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2991 { 3266 {
2992 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3267 m_host.TaskInventory.LockItemsForRead(false);
2993 return; 3268 return;
2994 else
2995 item = m_host.TaskInventory[InventorySelf()];
2996 } 3269 }
3270 else
3271 {
3272 item = m_host.TaskInventory[InventorySelf()];
3273 }
3274
3275 m_host.TaskInventory.LockItemsForRead(false);
2997 3276
2998 if (item.PermsGranter != m_host.OwnerID) 3277 if (item.PermsGranter != m_host.OwnerID)
2999 return; 3278 return;
@@ -3019,13 +3298,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 3298
3020 TaskInventoryItem item; 3299 TaskInventoryItem item;
3021 3300
3022 lock (m_host.TaskInventory) 3301 m_host.TaskInventory.LockItemsForRead(true);
3302
3303 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3023 { 3304 {
3024 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3305 m_host.TaskInventory.LockItemsForRead(false);
3025 return; 3306 return;
3026 else
3027 item = m_host.TaskInventory[InventorySelf()];
3028 } 3307 }
3308 else
3309 {
3310 item = m_host.TaskInventory[InventorySelf()];
3311 }
3312 m_host.TaskInventory.LockItemsForRead(false);
3313
3029 3314
3030 if (item.PermsGranter != m_host.OwnerID) 3315 if (item.PermsGranter != m_host.OwnerID)
3031 return; 3316 return;
@@ -3072,6 +3357,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3072 3357
3073 public void llInstantMessage(string user, string message) 3358 public void llInstantMessage(string user, string message)
3074 { 3359 {
3360 UUID result;
3361 if (!UUID.TryParse(user, out result))
3362 {
3363 ShoutError("An invalid key was passed to llInstantMessage");
3364 ScriptSleep(2000);
3365 return;
3366 }
3367
3368
3075 m_host.AddScriptLPS(1); 3369 m_host.AddScriptLPS(1);
3076 3370
3077 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3371 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3086,14 +3380,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3086 UUID friendTransactionID = UUID.Random(); 3380 UUID friendTransactionID = UUID.Random();
3087 3381
3088 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3382 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3089 3383
3090 GridInstantMessage msg = new GridInstantMessage(); 3384 GridInstantMessage msg = new GridInstantMessage();
3091 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3385 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3092 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3386 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3093 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3387 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); 3388// 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()); 3389// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3096 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3390// DateTime dt = DateTime.UtcNow;
3391//
3392// // Ticks from UtcNow, but make it look like local. Evil, huh?
3393// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3394//
3395// try
3396// {
3397// // Convert that to the PST timezone
3398// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3399// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3400// }
3401// catch
3402// {
3403// // No logging here, as it could be VERY spammy
3404// }
3405//
3406// // And make it look local again to fool the unix time util
3407// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3408
3409 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3410
3097 //if (client != null) 3411 //if (client != null)
3098 //{ 3412 //{
3099 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3413 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3107,12 +3421,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3107 msg.message = message.Substring(0, 1024); 3421 msg.message = message.Substring(0, 1024);
3108 else 3422 else
3109 msg.message = message; 3423 msg.message = message;
3110 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3424 msg.dialog = (byte)19; // MessageFromObject
3111 msg.fromGroup = false;// fromGroup; 3425 msg.fromGroup = false;// fromGroup;
3112 msg.offline = (byte)0; //offline; 3426 msg.offline = (byte)0; //offline;
3113 msg.ParentEstateID = 0; //ParentEstateID; 3427 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3114 msg.Position = new Vector3(m_host.AbsolutePosition); 3428 msg.Position = new Vector3(m_host.AbsolutePosition);
3115 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3429 msg.RegionID = World.RegionInfo.RegionID.Guid;
3116 msg.binaryBucket 3430 msg.binaryBucket
3117 = Util.StringToBytes256( 3431 = Util.StringToBytes256(
3118 "{0}/{1}/{2}/{3}", 3432 "{0}/{1}/{2}/{3}",
@@ -3140,7 +3454,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3140 } 3454 }
3141 3455
3142 emailModule.SendEmail(m_host.UUID, address, subject, message); 3456 emailModule.SendEmail(m_host.UUID, address, subject, message);
3143 ScriptSleep(20000); 3457 ScriptSleep(15000);
3144 } 3458 }
3145 3459
3146 public void llGetNextEmail(string address, string subject) 3460 public void llGetNextEmail(string address, string subject)
@@ -3279,14 +3593,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3279 3593
3280 TaskInventoryItem item; 3594 TaskInventoryItem item;
3281 3595
3282 lock (m_host.TaskInventory) 3596 m_host.TaskInventory.LockItemsForRead(true);
3597 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3283 { 3598 {
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3599 m_host.TaskInventory.LockItemsForRead(false);
3285 return; 3600 return;
3286 else
3287 item = m_host.TaskInventory[InventorySelf()];
3288 } 3601 }
3289 3602 else
3603 {
3604 item = m_host.TaskInventory[InventorySelf()];
3605 }
3606 m_host.TaskInventory.LockItemsForRead(false);
3290 if (item.PermsGranter == UUID.Zero) 3607 if (item.PermsGranter == UUID.Zero)
3291 return; 3608 return;
3292 3609
@@ -3316,13 +3633,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3316 3633
3317 TaskInventoryItem item; 3634 TaskInventoryItem item;
3318 3635
3319 lock (m_host.TaskInventory) 3636 m_host.TaskInventory.LockItemsForRead(true);
3637 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3320 { 3638 {
3321 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3639 m_host.TaskInventory.LockItemsForRead(false);
3322 return; 3640 return;
3323 else 3641 }
3324 item = m_host.TaskInventory[InventorySelf()]; 3642 else
3643 {
3644 item = m_host.TaskInventory[InventorySelf()];
3325 } 3645 }
3646 m_host.TaskInventory.LockItemsForRead(false);
3647
3326 3648
3327 if (item.PermsGranter == UUID.Zero) 3649 if (item.PermsGranter == UUID.Zero)
3328 return; 3650 return;
@@ -3389,10 +3711,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3711
3390 TaskInventoryItem item; 3712 TaskInventoryItem item;
3391 3713
3392 lock (m_host.TaskInventory) 3714
3715 m_host.TaskInventory.LockItemsForRead(true);
3716 if (!m_host.TaskInventory.ContainsKey(invItemID))
3717 {
3718 m_host.TaskInventory.LockItemsForRead(false);
3719 return;
3720 }
3721 else
3393 { 3722 {
3394 item = m_host.TaskInventory[invItemID]; 3723 item = m_host.TaskInventory[invItemID];
3395 } 3724 }
3725 m_host.TaskInventory.LockItemsForRead(false);
3396 3726
3397 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3727 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3398 { 3728 {
@@ -3420,15 +3750,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3750 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3421 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3751 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3422 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3752 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3753 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3423 ScriptBaseClass.PERMISSION_ATTACH; 3754 ScriptBaseClass.PERMISSION_ATTACH;
3424 3755
3425 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3756 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3426 { 3757 {
3427 lock (m_host.TaskInventory) 3758 m_host.TaskInventory.LockItemsForWrite(true);
3428 { 3759 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3429 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3760 m_host.TaskInventory[invItemID].PermsMask = perm;
3430 m_host.TaskInventory[invItemID].PermsMask = perm; 3761 m_host.TaskInventory.LockItemsForWrite(false);
3431 }
3432 3762
3433 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3763 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3434 "run_time_permissions", new Object[] { 3764 "run_time_permissions", new Object[] {
@@ -3438,28 +3768,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 return; 3768 return;
3439 } 3769 }
3440 } 3770 }
3441 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3771 else
3442 { 3772 {
3443 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3773 bool sitting = false;
3444 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3774 if (m_host.SitTargetAvatar == agentID)
3445 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3775 {
3446 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3776 sitting = true;
3447 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3777 }
3778 else
3779 {
3780 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3781 {
3782 if (p.SitTargetAvatar == agentID)
3783 sitting = true;
3784 }
3785 }
3448 3786
3449 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3787 if (sitting)
3450 { 3788 {
3451 lock (m_host.TaskInventory) 3789 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3790 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3791 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3792 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3793 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3794
3795 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3452 { 3796 {
3797 m_host.TaskInventory.LockItemsForWrite(true);
3453 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3798 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3454 m_host.TaskInventory[invItemID].PermsMask = perm; 3799 m_host.TaskInventory[invItemID].PermsMask = perm;
3455 } 3800 m_host.TaskInventory.LockItemsForWrite(false);
3456 3801
3457 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3802 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3458 "run_time_permissions", new Object[] { 3803 "run_time_permissions", new Object[] {
3459 new LSL_Integer(perm) }, 3804 new LSL_Integer(perm) },
3460 new DetectParams[0])); 3805 new DetectParams[0]));
3461 3806
3462 return; 3807 return;
3808 }
3463 } 3809 }
3464 } 3810 }
3465 3811
@@ -3473,11 +3819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 3819
3474 if (!m_waitingForScriptAnswer) 3820 if (!m_waitingForScriptAnswer)
3475 { 3821 {
3476 lock (m_host.TaskInventory) 3822 m_host.TaskInventory.LockItemsForWrite(true);
3477 { 3823 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3478 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3824 m_host.TaskInventory[invItemID].PermsMask = 0;
3479 m_host.TaskInventory[invItemID].PermsMask = 0; 3825 m_host.TaskInventory.LockItemsForWrite(false);
3480 }
3481 3826
3482 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3827 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3483 m_waitingForScriptAnswer=true; 3828 m_waitingForScriptAnswer=true;
@@ -3512,10 +3857,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3857 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3513 llReleaseControls(); 3858 llReleaseControls();
3514 3859
3515 lock (m_host.TaskInventory) 3860
3516 { 3861 m_host.TaskInventory.LockItemsForWrite(true);
3517 m_host.TaskInventory[invItemID].PermsMask = answer; 3862 m_host.TaskInventory[invItemID].PermsMask = answer;
3518 } 3863 m_host.TaskInventory.LockItemsForWrite(false);
3864
3519 3865
3520 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3866 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3521 "run_time_permissions", new Object[] { 3867 "run_time_permissions", new Object[] {
@@ -3527,16 +3873,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 { 3873 {
3528 m_host.AddScriptLPS(1); 3874 m_host.AddScriptLPS(1);
3529 3875
3530 lock (m_host.TaskInventory) 3876 m_host.TaskInventory.LockItemsForRead(true);
3877
3878 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3531 { 3879 {
3532 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3880 if (item.Type == 10 && item.ItemID == m_itemID)
3533 { 3881 {
3534 if (item.Type == 10 && item.ItemID == m_itemID) 3882 m_host.TaskInventory.LockItemsForRead(false);
3535 { 3883 return item.PermsGranter.ToString();
3536 return item.PermsGranter.ToString();
3537 }
3538 } 3884 }
3539 } 3885 }
3886 m_host.TaskInventory.LockItemsForRead(false);
3540 3887
3541 return UUID.Zero.ToString(); 3888 return UUID.Zero.ToString();
3542 } 3889 }
@@ -3545,19 +3892,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3545 { 3892 {
3546 m_host.AddScriptLPS(1); 3893 m_host.AddScriptLPS(1);
3547 3894
3548 lock (m_host.TaskInventory) 3895 m_host.TaskInventory.LockItemsForRead(true);
3896
3897 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3549 { 3898 {
3550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3899 if (item.Type == 10 && item.ItemID == m_itemID)
3551 { 3900 {
3552 if (item.Type == 10 && item.ItemID == m_itemID) 3901 int perms = item.PermsMask;
3553 { 3902 if (m_automaticLinkPermission)
3554 int perms = item.PermsMask; 3903 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3555 if (m_automaticLinkPermission) 3904 m_host.TaskInventory.LockItemsForRead(false);
3556 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3905 return perms;
3557 return perms;
3558 }
3559 } 3906 }
3560 } 3907 }
3908 m_host.TaskInventory.LockItemsForRead(false);
3561 3909
3562 return 0; 3910 return 0;
3563 } 3911 }
@@ -3579,9 +3927,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3927 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3928 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3929 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3930 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3931 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3932 try
3933 {
3934 parts[0].ParentGroup.areUpdatesSuspended = true;
3935 foreach (SceneObjectPart part in parts)
3936 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3937 }
3938 finally
3939 {
3940 parts[0].ParentGroup.areUpdatesSuspended = false;
3941 }
3942 }
3585 } 3943 }
3586 3944
3587 public void llCreateLink(string target, int parent) 3945 public void llCreateLink(string target, int parent)
@@ -3594,11 +3952,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3594 return; 3952 return;
3595 3953
3596 TaskInventoryItem item; 3954 TaskInventoryItem item;
3597 lock (m_host.TaskInventory) 3955 m_host.TaskInventory.LockItemsForRead(true);
3598 { 3956 item = m_host.TaskInventory[invItemID];
3599 item = m_host.TaskInventory[invItemID]; 3957 m_host.TaskInventory.LockItemsForRead(false);
3600 } 3958
3601
3602 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3959 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3603 && !m_automaticLinkPermission) 3960 && !m_automaticLinkPermission)
3604 { 3961 {
@@ -3615,11 +3972,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3615 3972
3616 if (targetPart.ParentGroup.AttachmentPoint != 0) 3973 if (targetPart.ParentGroup.AttachmentPoint != 0)
3617 return; // Fail silently if attached 3974 return; // Fail silently if attached
3975
3976 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3977 return;
3978
3618 SceneObjectGroup parentPrim = null, childPrim = null; 3979 SceneObjectGroup parentPrim = null, childPrim = null;
3619 3980
3620 if (targetPart != null) 3981 if (targetPart != null)
3621 { 3982 {
3622 if (parent != 0) { 3983 if (parent != 0)
3984 {
3623 parentPrim = m_host.ParentGroup; 3985 parentPrim = m_host.ParentGroup;
3624 childPrim = targetPart.ParentGroup; 3986 childPrim = targetPart.ParentGroup;
3625 } 3987 }
@@ -3631,7 +3993,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3631 3993
3632 // Required for linking 3994 // Required for linking
3633 childPrim.RootPart.ClearUpdateSchedule(); 3995 childPrim.RootPart.ClearUpdateSchedule();
3634 parentPrim.LinkToGroup(childPrim); 3996 parentPrim.LinkToGroup(childPrim, true);
3635 } 3997 }
3636 3998
3637 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3999 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3650,16 +4012,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3650 m_host.AddScriptLPS(1); 4012 m_host.AddScriptLPS(1);
3651 UUID invItemID = InventorySelf(); 4013 UUID invItemID = InventorySelf();
3652 4014
3653 lock (m_host.TaskInventory) 4015 m_host.TaskInventory.LockItemsForRead(true);
3654 {
3655 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4016 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3656 && !m_automaticLinkPermission) 4017 && !m_automaticLinkPermission)
3657 { 4018 {
3658 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4019 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4020 m_host.TaskInventory.LockItemsForRead(false);
3659 return; 4021 return;
3660 } 4022 }
3661 } 4023 m_host.TaskInventory.LockItemsForRead(false);
3662 4024
3663 if (linknum < ScriptBaseClass.LINK_THIS) 4025 if (linknum < ScriptBaseClass.LINK_THIS)
3664 return; 4026 return;
3665 4027
@@ -3698,10 +4060,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 // Restructuring Multiple Prims. 4060 // Restructuring Multiple Prims.
3699 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4061 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3700 parts.Remove(parentPrim.RootPart); 4062 parts.Remove(parentPrim.RootPart);
3701 foreach (SceneObjectPart part in parts) 4063 if (parts.Count > 0)
3702 { 4064 {
3703 parentPrim.DelinkFromGroup(part.LocalId, true); 4065 try
4066 {
4067 parts[0].ParentGroup.areUpdatesSuspended = true;
4068 foreach (SceneObjectPart part in parts)
4069 {
4070 parentPrim.DelinkFromGroup(part.LocalId, true);
4071 }
4072 }
4073 finally
4074 {
4075 parts[0].ParentGroup.areUpdatesSuspended = false;
4076 }
3704 } 4077 }
4078
3705 parentPrim.HasGroupChanged = true; 4079 parentPrim.HasGroupChanged = true;
3706 parentPrim.ScheduleGroupForFullUpdate(); 4080 parentPrim.ScheduleGroupForFullUpdate();
3707 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4081 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3710,12 +4084,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3710 { 4084 {
3711 SceneObjectPart newRoot = parts[0]; 4085 SceneObjectPart newRoot = parts[0];
3712 parts.Remove(newRoot); 4086 parts.Remove(newRoot);
3713 foreach (SceneObjectPart part in parts) 4087
4088 try
3714 { 4089 {
3715 // Required for linking 4090 parts[0].ParentGroup.areUpdatesSuspended = true;
3716 part.ClearUpdateSchedule(); 4091 foreach (SceneObjectPart part in parts)
3717 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4092 {
4093 part.ClearUpdateSchedule();
4094 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4095 }
3718 } 4096 }
4097 finally
4098 {
4099 parts[0].ParentGroup.areUpdatesSuspended = false;
4100 }
4101
4102
3719 newRoot.ParentGroup.HasGroupChanged = true; 4103 newRoot.ParentGroup.HasGroupChanged = true;
3720 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4104 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3721 } 4105 }
@@ -3735,6 +4119,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 public void llBreakAllLinks() 4119 public void llBreakAllLinks()
3736 { 4120 {
3737 m_host.AddScriptLPS(1); 4121 m_host.AddScriptLPS(1);
4122
4123 UUID invItemID = InventorySelf();
4124
4125 TaskInventoryItem item;
4126 m_host.TaskInventory.LockItemsForRead(true);
4127 item = m_host.TaskInventory[invItemID];
4128 m_host.TaskInventory.LockItemsForRead(false);
4129
4130 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4131 && !m_automaticLinkPermission)
4132 {
4133 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4134 return;
4135 }
4136
3738 SceneObjectGroup parentPrim = m_host.ParentGroup; 4137 SceneObjectGroup parentPrim = m_host.ParentGroup;
3739 if (parentPrim.AttachmentPoint != 0) 4138 if (parentPrim.AttachmentPoint != 0)
3740 return; // Fail silently if attached 4139 return; // Fail silently if attached
@@ -3754,25 +4153,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 public LSL_String llGetLinkKey(int linknum) 4153 public LSL_String llGetLinkKey(int linknum)
3755 { 4154 {
3756 m_host.AddScriptLPS(1); 4155 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); 4156 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3777 if (part != null) 4157 if (part != null)
3778 { 4158 {
@@ -3780,6 +4160,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3780 } 4160 }
3781 else 4161 else
3782 { 4162 {
4163 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4164 {
4165 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4166
4167 if (linknum < 0)
4168 return UUID.Zero.ToString();
4169
4170 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4171 if (avatars.Count > linknum)
4172 {
4173 return avatars[linknum].UUID.ToString();
4174 }
4175 }
3783 return UUID.Zero.ToString(); 4176 return UUID.Zero.ToString();
3784 } 4177 }
3785 } 4178 }
@@ -3878,17 +4271,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3878 m_host.AddScriptLPS(1); 4271 m_host.AddScriptLPS(1);
3879 int count = 0; 4272 int count = 0;
3880 4273
3881 lock (m_host.TaskInventory) 4274 m_host.TaskInventory.LockItemsForRead(true);
4275 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3882 { 4276 {
3883 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4277 if (inv.Value.Type == type || type == -1)
3884 { 4278 {
3885 if (inv.Value.Type == type || type == -1) 4279 count = count + 1;
3886 {
3887 count = count + 1;
3888 }
3889 } 4280 }
3890 } 4281 }
3891 4282
4283 m_host.TaskInventory.LockItemsForRead(false);
3892 return count; 4284 return count;
3893 } 4285 }
3894 4286
@@ -3897,16 +4289,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 m_host.AddScriptLPS(1); 4289 m_host.AddScriptLPS(1);
3898 ArrayList keys = new ArrayList(); 4290 ArrayList keys = new ArrayList();
3899 4291
3900 lock (m_host.TaskInventory) 4292 m_host.TaskInventory.LockItemsForRead(true);
4293 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3901 { 4294 {
3902 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4295 if (inv.Value.Type == type || type == -1)
3903 { 4296 {
3904 if (inv.Value.Type == type || type == -1) 4297 keys.Add(inv.Value.Name);
3905 {
3906 keys.Add(inv.Value.Name);
3907 }
3908 } 4298 }
3909 } 4299 }
4300 m_host.TaskInventory.LockItemsForRead(false);
3910 4301
3911 if (keys.Count == 0) 4302 if (keys.Count == 0)
3912 { 4303 {
@@ -3943,25 +4334,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3943 } 4334 }
3944 4335
3945 // move the first object found with this inventory name 4336 // move the first object found with this inventory name
3946 lock (m_host.TaskInventory) 4337 m_host.TaskInventory.LockItemsForRead(true);
4338 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3947 { 4339 {
3948 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4340 if (inv.Value.Name == inventory)
3949 { 4341 {
3950 if (inv.Value.Name == inventory) 4342 found = true;
3951 { 4343 objId = inv.Key;
3952 found = true; 4344 assetType = inv.Value.Type;
3953 objId = inv.Key; 4345 objName = inv.Value.Name;
3954 assetType = inv.Value.Type; 4346 break;
3955 objName = inv.Value.Name;
3956 break;
3957 }
3958 } 4347 }
3959 } 4348 }
4349 m_host.TaskInventory.LockItemsForRead(false);
3960 4350
3961 if (!found) 4351 if (!found)
3962 { 4352 {
3963 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4353 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)); 4354 return;
4355// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3965 } 4356 }
3966 4357
3967 // check if destination is an object 4358 // check if destination is an object
@@ -3987,48 +4378,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3987 return; 4378 return;
3988 } 4379 }
3989 } 4380 }
4381
3990 // destination is an avatar 4382 // destination is an avatar
3991 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4383 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3992 4384
3993 if (agentItem == null) 4385 if (agentItem == null)
3994 return; 4386 return;
3995 4387
3996 byte[] bucket = new byte[17]; 4388 byte[] bucket = new byte[1];
3997 bucket[0] = (byte)assetType; 4389 bucket[0] = (byte)assetType;
3998 byte[] objBytes = agentItem.ID.GetBytes(); 4390 //byte[] objBytes = agentItem.ID.GetBytes();
3999 Array.Copy(objBytes, 0, bucket, 1, 16); 4391 //Array.Copy(objBytes, 0, bucket, 1, 16);
4000 4392
4001 GridInstantMessage msg = new GridInstantMessage(World, 4393 GridInstantMessage msg = new GridInstantMessage(World,
4002 m_host.UUID, m_host.Name+", an object owned by "+ 4394 m_host.OwnerID, m_host.Name, destId,
4003 resolveName(m_host.OwnerID)+",", destId,
4004 (byte)InstantMessageDialog.TaskInventoryOffered, 4395 (byte)InstantMessageDialog.TaskInventoryOffered,
4005 false, objName+"\n"+m_host.Name+" is located at "+ 4396 false, objName+". "+m_host.Name+" is located at "+
4006 World.RegionInfo.RegionName+" "+ 4397 World.RegionInfo.RegionName+" "+
4007 m_host.AbsolutePosition.ToString(), 4398 m_host.AbsolutePosition.ToString(),
4008 agentItem.ID, true, m_host.AbsolutePosition, 4399 agentItem.ID, true, m_host.AbsolutePosition,
4009 bucket); 4400 bucket);
4010 if (m_TransferModule != null) 4401
4011 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4402 ScenePresence sp;
4403
4404 if (World.TryGetScenePresence(destId, out sp))
4405 {
4406 sp.ControllingClient.SendInstantMessage(msg);
4407 }
4408 else
4409 {
4410 if (m_TransferModule != null)
4411 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4412 }
4413
4414 //This delay should only occur when giving inventory to avatars.
4012 ScriptSleep(3000); 4415 ScriptSleep(3000);
4013 } 4416 }
4014 } 4417 }
4015 4418
4419 [DebuggerNonUserCode]
4016 public void llRemoveInventory(string name) 4420 public void llRemoveInventory(string name)
4017 { 4421 {
4018 m_host.AddScriptLPS(1); 4422 m_host.AddScriptLPS(1);
4019 4423
4020 lock (m_host.TaskInventory) 4424 List<TaskInventoryItem> inv;
4425 try
4021 { 4426 {
4022 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4427 m_host.TaskInventory.LockItemsForRead(true);
4428 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4429 }
4430 finally
4431 {
4432 m_host.TaskInventory.LockItemsForRead(false);
4433 }
4434 foreach (TaskInventoryItem item in inv)
4435 {
4436 if (item.Name == name)
4023 { 4437 {
4024 if (item.Name == name) 4438 if (item.ItemID == m_itemID)
4025 { 4439 throw new ScriptDeleteException();
4026 if (item.ItemID == m_itemID) 4440 else
4027 throw new ScriptDeleteException(); 4441 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4028 else 4442 return;
4029 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4030 return;
4031 }
4032 } 4443 }
4033 } 4444 }
4034 } 4445 }
@@ -4063,112 +4474,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4063 { 4474 {
4064 m_host.AddScriptLPS(1); 4475 m_host.AddScriptLPS(1);
4065 4476
4066 UUID uuid = (UUID)id; 4477 UUID uuid;
4067 PresenceInfo pinfo = null; 4478 if (UUID.TryParse(id, out uuid))
4068 UserAccount account;
4069
4070 UserInfoCacheEntry ce;
4071 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4072 { 4479 {
4073 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4480 PresenceInfo pinfo = null;
4074 if (account == null) 4481 UserAccount account;
4482
4483 UserInfoCacheEntry ce;
4484 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4075 { 4485 {
4076 m_userInfoCache[uuid] = null; // Cache negative 4486 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4077 return UUID.Zero.ToString(); 4487 if (account == null)
4078 } 4488 {
4489 m_userInfoCache[uuid] = null; // Cache negative
4490 return UUID.Zero.ToString();
4491 }
4079 4492
4080 4493
4081 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4494 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4082 if (pinfos != null && pinfos.Length > 0) 4495 if (pinfos != null && pinfos.Length > 0)
4083 {
4084 foreach (PresenceInfo p in pinfos)
4085 { 4496 {
4086 if (p.RegionID != UUID.Zero) 4497 foreach (PresenceInfo p in pinfos)
4087 { 4498 {
4088 pinfo = p; 4499 if (p.RegionID != UUID.Zero)
4500 {
4501 pinfo = p;
4502 }
4089 } 4503 }
4090 } 4504 }
4091 }
4092 4505
4093 ce = new UserInfoCacheEntry(); 4506 ce = new UserInfoCacheEntry();
4094 ce.time = Util.EnvironmentTickCount(); 4507 ce.time = Util.EnvironmentTickCount();
4095 ce.account = account; 4508 ce.account = account;
4096 ce.pinfo = pinfo; 4509 ce.pinfo = pinfo;
4097 } 4510 m_userInfoCache[uuid] = ce;
4098 else 4511 }
4099 { 4512 else
4100 if (ce == null) 4513 {
4101 return UUID.Zero.ToString(); 4514 if (ce == null)
4515 return UUID.Zero.ToString();
4102 4516
4103 account = ce.account; 4517 account = ce.account;
4104 pinfo = ce.pinfo; 4518 pinfo = ce.pinfo;
4105 } 4519 }
4106 4520
4107 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4521 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 { 4522 {
4112 foreach (PresenceInfo p in pinfos) 4523 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4524 if (pinfos != null && pinfos.Length > 0)
4113 { 4525 {
4114 if (p.RegionID != UUID.Zero) 4526 foreach (PresenceInfo p in pinfos)
4115 { 4527 {
4116 pinfo = p; 4528 if (p.RegionID != UUID.Zero)
4529 {
4530 pinfo = p;
4531 }
4117 } 4532 }
4118 } 4533 }
4119 } 4534 else
4120 else 4535 pinfo = null;
4121 pinfo = null;
4122 4536
4123 ce.time = Util.EnvironmentTickCount(); 4537 ce.time = Util.EnvironmentTickCount();
4124 ce.pinfo = pinfo; 4538 ce.pinfo = pinfo;
4125 } 4539 }
4126 4540
4127 string reply = String.Empty; 4541 string reply = String.Empty;
4128 4542
4129 switch (data) 4543 switch (data)
4130 { 4544 {
4131 case 1: // DATA_ONLINE (0|1) 4545 case 1: // DATA_ONLINE (0|1)
4132 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4546 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4133 reply = "1"; 4547 reply = "1";
4134 else 4548 else
4135 reply = "0"; 4549 reply = "0";
4136 break; 4550 break;
4137 case 2: // DATA_NAME (First Last) 4551 case 2: // DATA_NAME (First Last)
4138 reply = account.FirstName + " " + account.LastName; 4552 reply = account.FirstName + " " + account.LastName;
4139 break; 4553 break;
4140 case 3: // DATA_BORN (YYYY-MM-DD) 4554 case 3: // DATA_BORN (YYYY-MM-DD)
4141 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4555 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4142 born = born.AddSeconds(account.Created); 4556 born = born.AddSeconds(account.Created);
4143 reply = born.ToString("yyyy-MM-dd"); 4557 reply = born.ToString("yyyy-MM-dd");
4144 break; 4558 break;
4145 case 4: // DATA_RATING (0,0,0,0,0,0) 4559 case 4: // DATA_RATING (0,0,0,0,0,0)
4146 reply = "0,0,0,0,0,0"; 4560 reply = "0,0,0,0,0,0";
4147 break; 4561 break;
4148 case 8: // DATA_PAYINFO (0|1|2|3) 4562 case 8: // DATA_PAYINFO (0|1|2|3)
4149 reply = "0"; 4563 reply = "0";
4150 break; 4564 break;
4151 default: 4565 default:
4152 return UUID.Zero.ToString(); // Raise no event 4566 return UUID.Zero.ToString(); // Raise no event
4153 } 4567 }
4154 4568
4155 UUID rq = UUID.Random(); 4569 UUID rq = UUID.Random();
4156 4570
4157 UUID tid = AsyncCommands. 4571 UUID tid = AsyncCommands.
4158 DataserverPlugin.RegisterRequest(m_localID, 4572 DataserverPlugin.RegisterRequest(m_localID,
4159 m_itemID, rq.ToString()); 4573 m_itemID, rq.ToString());
4160 4574
4161 AsyncCommands. 4575 AsyncCommands.
4162 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4576 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4163 4577
4164 ScriptSleep(100); 4578 ScriptSleep(100);
4165 return tid.ToString(); 4579 return tid.ToString();
4580 }
4581 else
4582 {
4583 ShoutError("Invalid UUID passed to llRequestAgentData.");
4584 }
4585 return "";
4166 } 4586 }
4167 4587
4168 public LSL_String llRequestInventoryData(string name) 4588 public LSL_String llRequestInventoryData(string name)
4169 { 4589 {
4170 m_host.AddScriptLPS(1); 4590 m_host.AddScriptLPS(1);
4171 4591
4592 //Clone is thread safe
4172 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4593 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4173 4594
4174 foreach (TaskInventoryItem item in itemDictionary.Values) 4595 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4222,6 +4643,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4222 ScenePresence presence = World.GetScenePresence(agentId); 4643 ScenePresence presence = World.GetScenePresence(agentId);
4223 if (presence != null) 4644 if (presence != null)
4224 { 4645 {
4646 // agent must not be a god
4647 if (presence.UserLevel >= 200) return;
4648
4225 // agent must be over the owners land 4649 // agent must be over the owners land
4226 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4650 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4227 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4651 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4244,7 +4668,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4244 UUID av = new UUID(); 4668 UUID av = new UUID();
4245 if (!UUID.TryParse(agent,out av)) 4669 if (!UUID.TryParse(agent,out av))
4246 { 4670 {
4247 LSLError("First parameter to llDialog needs to be a key"); 4671 //LSLError("First parameter to llDialog needs to be a key");
4248 return; 4672 return;
4249 } 4673 }
4250 4674
@@ -4281,17 +4705,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4281 UUID soundId = UUID.Zero; 4705 UUID soundId = UUID.Zero;
4282 if (!UUID.TryParse(impact_sound, out soundId)) 4706 if (!UUID.TryParse(impact_sound, out soundId))
4283 { 4707 {
4284 lock (m_host.TaskInventory) 4708 m_host.TaskInventory.LockItemsForRead(true);
4709 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4285 { 4710 {
4286 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4711 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4287 { 4712 {
4288 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4713 soundId = item.AssetID;
4289 { 4714 break;
4290 soundId = item.AssetID;
4291 break;
4292 }
4293 } 4715 }
4294 } 4716 }
4717 m_host.TaskInventory.LockItemsForRead(false);
4295 } 4718 }
4296 m_host.CollisionSound = soundId; 4719 m_host.CollisionSound = soundId;
4297 m_host.CollisionSoundVolume = (float)impact_volume; 4720 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4331,6 +4754,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4331 UUID partItemID; 4754 UUID partItemID;
4332 foreach (SceneObjectPart part in parts) 4755 foreach (SceneObjectPart part in parts)
4333 { 4756 {
4757 //Clone is thread safe
4334 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4758 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4335 4759
4336 foreach (TaskInventoryItem item in itemsDictionary.Values) 4760 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4545,17 +4969,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4545 4969
4546 m_host.AddScriptLPS(1); 4970 m_host.AddScriptLPS(1);
4547 4971
4548 lock (m_host.TaskInventory) 4972 m_host.TaskInventory.LockItemsForRead(true);
4973 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4549 { 4974 {
4550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4975 if (item.Type == 10 && item.ItemID == m_itemID)
4551 { 4976 {
4552 if (item.Type == 10 && item.ItemID == m_itemID) 4977 result = item.Name!=null?item.Name:String.Empty;
4553 { 4978 break;
4554 result = item.Name != null ? item.Name : String.Empty;
4555 break;
4556 }
4557 } 4979 }
4558 } 4980 }
4981 m_host.TaskInventory.LockItemsForRead(false);
4559 4982
4560 return result; 4983 return result;
4561 } 4984 }
@@ -4728,23 +5151,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4728 { 5151 {
4729 m_host.AddScriptLPS(1); 5152 m_host.AddScriptLPS(1);
4730 5153
4731 lock (m_host.TaskInventory) 5154 m_host.TaskInventory.LockItemsForRead(true);
5155 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4732 { 5156 {
4733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5157 if (inv.Value.Name == name)
4734 { 5158 {
4735 if (inv.Value.Name == name) 5159 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4736 { 5160 {
4737 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5161 m_host.TaskInventory.LockItemsForRead(false);
4738 { 5162 return inv.Value.AssetID.ToString();
4739 return inv.Value.AssetID.ToString(); 5163 }
4740 } 5164 else
4741 else 5165 {
4742 { 5166 m_host.TaskInventory.LockItemsForRead(false);
4743 return UUID.Zero.ToString(); 5167 return UUID.Zero.ToString();
4744 }
4745 } 5168 }
4746 } 5169 }
4747 } 5170 }
5171 m_host.TaskInventory.LockItemsForRead(false);
4748 5172
4749 return UUID.Zero.ToString(); 5173 return UUID.Zero.ToString();
4750 } 5174 }
@@ -4897,14 +5321,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 { 5321 {
4898 m_host.AddScriptLPS(1); 5322 m_host.AddScriptLPS(1);
4899 5323
4900 if (src == null) 5324 return src.Length;
4901 {
4902 return 0;
4903 }
4904 else
4905 {
4906 return src.Length;
4907 }
4908 } 5325 }
4909 5326
4910 public LSL_Integer llList2Integer(LSL_List src, int index) 5327 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4950,7 +5367,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4950 else if (src.Data[index] is LSL_Float) 5367 else if (src.Data[index] is LSL_Float)
4951 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5368 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4952 else if (src.Data[index] is LSL_String) 5369 else if (src.Data[index] is LSL_String)
4953 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5370 {
5371 string str = ((LSL_String) src.Data[index]).m_string;
5372 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5373 if (m != Match.Empty)
5374 {
5375 str = m.Value;
5376 double d = 0.0;
5377 if (!Double.TryParse(str, out d))
5378 return 0.0;
5379
5380 return d;
5381 }
5382 return 0.0;
5383 }
4954 return Convert.ToDouble(src.Data[index]); 5384 return Convert.ToDouble(src.Data[index]);
4955 } 5385 }
4956 catch (FormatException) 5386 catch (FormatException)
@@ -5223,7 +5653,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5223 } 5653 }
5224 } 5654 }
5225 } 5655 }
5226 else { 5656 else
5657 {
5227 object[] array = new object[src.Length]; 5658 object[] array = new object[src.Length];
5228 Array.Copy(src.Data, 0, array, 0, src.Length); 5659 Array.Copy(src.Data, 0, array, 0, src.Length);
5229 result = new LSL_List(array); 5660 result = new LSL_List(array);
@@ -5330,7 +5761,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5330 public LSL_Integer llGetRegionAgentCount() 5761 public LSL_Integer llGetRegionAgentCount()
5331 { 5762 {
5332 m_host.AddScriptLPS(1); 5763 m_host.AddScriptLPS(1);
5333 return new LSL_Integer(World.GetRootAgentCount()); 5764
5765 int count = 0;
5766 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5767 count++;
5768 });
5769
5770 return new LSL_Integer(count);
5334 } 5771 }
5335 5772
5336 public LSL_Vector llGetRegionCorner() 5773 public LSL_Vector llGetRegionCorner()
@@ -5672,10 +6109,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5672 m_host.AddScriptLPS(1); 6109 m_host.AddScriptLPS(1);
5673 6110
5674 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6111 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5675 6112 if (parts.Count > 0)
5676 foreach (var part in parts)
5677 { 6113 {
5678 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6114 try
6115 {
6116 parts[0].ParentGroup.areUpdatesSuspended = true;
6117 foreach (var part in parts)
6118 {
6119 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6120 }
6121 }
6122 finally
6123 {
6124 parts[0].ParentGroup.areUpdatesSuspended = false;
6125 }
5679 } 6126 }
5680 } 6127 }
5681 6128
@@ -5727,13 +6174,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5727 6174
5728 if (m_host.OwnerID == land.LandData.OwnerID) 6175 if (m_host.OwnerID == land.LandData.OwnerID)
5729 { 6176 {
5730 World.TeleportClientHome(agentID, presence.ControllingClient); 6177 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6178 presence.TeleportWithMomentum(pos);
6179 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5731 } 6180 }
5732 } 6181 }
5733 } 6182 }
5734 ScriptSleep(5000); 6183 ScriptSleep(5000);
5735 } 6184 }
5736 6185
6186 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6187 {
6188 return ParseString2List(str, separators, in_spacers, false);
6189 }
6190
5737 public LSL_Integer llOverMyLand(string id) 6191 public LSL_Integer llOverMyLand(string id)
5738 { 6192 {
5739 m_host.AddScriptLPS(1); 6193 m_host.AddScriptLPS(1);
@@ -5798,8 +6252,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5798 UUID agentId = new UUID(); 6252 UUID agentId = new UUID();
5799 if (!UUID.TryParse(agent, out agentId)) 6253 if (!UUID.TryParse(agent, out agentId))
5800 return new LSL_Integer(0); 6254 return new LSL_Integer(0);
6255 if (agentId == m_host.GroupID)
6256 return new LSL_Integer(1);
5801 ScenePresence presence = World.GetScenePresence(agentId); 6257 ScenePresence presence = World.GetScenePresence(agentId);
5802 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6258 if (presence == null || presence.IsChildAgent) // Return false for child agents
5803 return new LSL_Integer(0); 6259 return new LSL_Integer(0);
5804 IClientAPI client = presence.ControllingClient; 6260 IClientAPI client = presence.ControllingClient;
5805 if (m_host.GroupID == client.ActiveGroupId) 6261 if (m_host.GroupID == client.ActiveGroupId)
@@ -5934,7 +6390,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5934 return m_host.ParentGroup.AttachmentPoint; 6390 return m_host.ParentGroup.AttachmentPoint;
5935 } 6391 }
5936 6392
5937 public LSL_Integer llGetFreeMemory() 6393 public virtual LSL_Integer llGetFreeMemory()
5938 { 6394 {
5939 m_host.AddScriptLPS(1); 6395 m_host.AddScriptLPS(1);
5940 // Make scripts designed for LSO happy 6396 // Make scripts designed for LSO happy
@@ -6051,7 +6507,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6051 SetParticleSystem(m_host, rules); 6507 SetParticleSystem(m_host, rules);
6052 } 6508 }
6053 6509
6054 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6510 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6511 {
6055 6512
6056 6513
6057 if (rules.Length == 0) 6514 if (rules.Length == 0)
@@ -6245,14 +6702,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6245 6702
6246 protected UUID GetTaskInventoryItem(string name) 6703 protected UUID GetTaskInventoryItem(string name)
6247 { 6704 {
6248 lock (m_host.TaskInventory) 6705 m_host.TaskInventory.LockItemsForRead(true);
6706 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6249 { 6707 {
6250 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6708 if (inv.Value.Name == name)
6251 { 6709 {
6252 if (inv.Value.Name == name) 6710 m_host.TaskInventory.LockItemsForRead(false);
6253 return inv.Key; 6711 return inv.Key;
6254 } 6712 }
6255 } 6713 }
6714 m_host.TaskInventory.LockItemsForRead(false);
6256 6715
6257 return UUID.Zero; 6716 return UUID.Zero;
6258 } 6717 }
@@ -6290,16 +6749,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6290 if (folderID == UUID.Zero) 6749 if (folderID == UUID.Zero)
6291 return; 6750 return;
6292 6751
6293 byte[] bucket = new byte[17]; 6752 byte[] bucket = new byte[1];
6294 bucket[0] = (byte)AssetType.Folder; 6753 bucket[0] = (byte)AssetType.Folder;
6295 byte[] objBytes = folderID.GetBytes(); 6754 //byte[] objBytes = folderID.GetBytes();
6296 Array.Copy(objBytes, 0, bucket, 1, 16); 6755 //Array.Copy(objBytes, 0, bucket, 1, 16);
6297 6756
6298 GridInstantMessage msg = new GridInstantMessage(World, 6757 GridInstantMessage msg = new GridInstantMessage(World,
6299 m_host.UUID, m_host.Name+", an object owned by "+ 6758 m_host.OwnerID, m_host.Name, destID,
6300 resolveName(m_host.OwnerID)+",", destID, 6759 (byte)InstantMessageDialog.TaskInventoryOffered,
6301 (byte)InstantMessageDialog.InventoryOffered, 6760 false, category+". "+m_host.Name+" is located at "+
6302 false, category+"\n"+m_host.Name+" is located at "+
6303 World.RegionInfo.RegionName+" "+ 6761 World.RegionInfo.RegionName+" "+
6304 m_host.AbsolutePosition.ToString(), 6762 m_host.AbsolutePosition.ToString(),
6305 folderID, true, m_host.AbsolutePosition, 6763 folderID, true, m_host.AbsolutePosition,
@@ -6515,13 +6973,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6515 UUID av = new UUID(); 6973 UUID av = new UUID();
6516 if (!UUID.TryParse(avatar,out av)) 6974 if (!UUID.TryParse(avatar,out av))
6517 { 6975 {
6518 LSLError("First parameter to llDialog needs to be a key"); 6976 //LSLError("First parameter to llDialog needs to be a key");
6519 return; 6977 return;
6520 } 6978 }
6521 if (buttons.Length < 1) 6979 if (buttons.Length < 1)
6522 { 6980 {
6523 LSLError("No less than 1 button can be shown"); 6981 buttons.Add("OK");
6524 return;
6525 } 6982 }
6526 if (buttons.Length > 12) 6983 if (buttons.Length > 12)
6527 { 6984 {
@@ -6538,7 +6995,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6538 } 6995 }
6539 if (buttons.Data[i].ToString().Length > 24) 6996 if (buttons.Data[i].ToString().Length > 24)
6540 { 6997 {
6541 LSLError("button label cannot be longer than 24 characters"); 6998 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6542 return; 6999 return;
6543 } 7000 }
6544 buts[i] = buttons.Data[i].ToString(); 7001 buts[i] = buttons.Data[i].ToString();
@@ -6597,22 +7054,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6597 } 7054 }
6598 7055
6599 // copy the first script found with this inventory name 7056 // copy the first script found with this inventory name
6600 lock (m_host.TaskInventory) 7057 TaskInventoryItem scriptItem = null;
7058 m_host.TaskInventory.LockItemsForRead(true);
7059 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6601 { 7060 {
6602 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7061 if (inv.Value.Name == name)
6603 { 7062 {
6604 if (inv.Value.Name == name) 7063 // make sure the object is a script
7064 if (10 == inv.Value.Type)
6605 { 7065 {
6606 // make sure the object is a script 7066 found = true;
6607 if (10 == inv.Value.Type) 7067 srcId = inv.Key;
6608 { 7068 scriptItem = inv.Value;
6609 found = true; 7069 break;
6610 srcId = inv.Key;
6611 break;
6612 }
6613 } 7070 }
6614 } 7071 }
6615 } 7072 }
7073 m_host.TaskInventory.LockItemsForRead(false);
6616 7074
6617 if (!found) 7075 if (!found)
6618 { 7076 {
@@ -6620,9 +7078,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6620 return; 7078 return;
6621 } 7079 }
6622 7080
6623 // the rest of the permission checks are done in RezScript, so check the pin there as well 7081 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6624 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7082 if (dest != null)
7083 {
7084 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7085 {
7086 // the rest of the permission checks are done in RezScript, so check the pin there as well
7087 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6625 7088
7089 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7090 m_host.Inventory.RemoveInventoryItem(srcId);
7091 }
7092 }
6626 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7093 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6627 ScriptSleep(3000); 7094 ScriptSleep(3000);
6628 } 7095 }
@@ -6685,19 +7152,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6685 public LSL_String llMD5String(string src, int nonce) 7152 public LSL_String llMD5String(string src, int nonce)
6686 { 7153 {
6687 m_host.AddScriptLPS(1); 7154 m_host.AddScriptLPS(1);
6688 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7155 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6689 } 7156 }
6690 7157
6691 public LSL_String llSHA1String(string src) 7158 public LSL_String llSHA1String(string src)
6692 { 7159 {
6693 m_host.AddScriptLPS(1); 7160 m_host.AddScriptLPS(1);
6694 return Util.SHA1Hash(src).ToLower(); 7161 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6695 } 7162 }
6696 7163
6697 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7164 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6698 { 7165 {
6699 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7166 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6700 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7167 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7168 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7169 return shapeBlock;
6701 7170
6702 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7171 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6703 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7172 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6802,6 +7271,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6802 // Prim type box, cylinder and prism. 7271 // 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) 7272 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 { 7273 {
7274 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7275 return;
7276
6805 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7277 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6806 ObjectShapePacket.ObjectDataBlock shapeBlock; 7278 ObjectShapePacket.ObjectDataBlock shapeBlock;
6807 7279
@@ -6855,6 +7327,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6855 // Prim type sphere. 7327 // 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) 7328 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6857 { 7329 {
7330 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7331 return;
7332
6858 ObjectShapePacket.ObjectDataBlock shapeBlock; 7333 ObjectShapePacket.ObjectDataBlock shapeBlock;
6859 7334
6860 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7335 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6896,6 +7371,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6896 // Prim type torus, tube and ring. 7371 // 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) 7372 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 { 7373 {
7374 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7375 return;
7376
6899 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7377 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6900 ObjectShapePacket.ObjectDataBlock shapeBlock; 7378 ObjectShapePacket.ObjectDataBlock shapeBlock;
6901 7379
@@ -7031,6 +7509,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7031 // Prim type sculpt. 7509 // Prim type sculpt.
7032 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7510 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7033 { 7511 {
7512 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7513 return;
7514
7034 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7515 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7035 UUID sculptId; 7516 UUID sculptId;
7036 7517
@@ -7047,13 +7528,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7047 shapeBlock.PathScaleX = 100; 7528 shapeBlock.PathScaleX = 100;
7048 shapeBlock.PathScaleY = 150; 7529 shapeBlock.PathScaleY = 150;
7049 7530
7050 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7531 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7051 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7532 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7052 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7533 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7053 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7534 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7054 { 7535 {
7055 // default 7536 // default
7056 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7537 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7057 } 7538 }
7058 7539
7059 part.Shape.SetSculptProperties((byte)type, sculptId); 7540 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7069,32 +7550,119 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7069 ScriptSleep(200); 7550 ScriptSleep(200);
7070 } 7551 }
7071 7552
7072 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7553 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7073 { 7554 {
7074 m_host.AddScriptLPS(1); 7555 m_host.AddScriptLPS(1);
7075 7556
7076 setLinkPrimParams(linknumber, rules); 7557 setLinkPrimParams(linknumber, rules);
7077
7078 ScriptSleep(200);
7079 } 7558 }
7080 7559
7081 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7560 private void setLinkPrimParams(int linknumber, LSL_List rules)
7082 { 7561 {
7083 m_host.AddScriptLPS(1); 7562 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7563 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7564 if (parts.Count>0)
7565 {
7566 try
7567 {
7568 parts[0].ParentGroup.areUpdatesSuspended = true;
7569 foreach (SceneObjectPart part in parts)
7570 SetPrimParams(part, rules);
7571 }
7572 finally
7573 {
7574 parts[0].ParentGroup.areUpdatesSuspended = false;
7575 }
7576 }
7577 if (avatars.Count > 0)
7578 {
7579 foreach (ScenePresence avatar in avatars)
7580 SetPrimParams(avatar, rules);
7581 }
7582 }
7084 7583
7085 setLinkPrimParams(linknumber, rules); 7584 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7585 {
7586 llSetLinkPrimitiveParamsFast(linknumber, rules);
7587 ScriptSleep(200);
7086 } 7588 }
7087 7589
7088 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7590 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7089 { 7591 {
7090 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7592 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7593 //We only support PRIM_POSITION and PRIM_ROTATION
7091 7594
7092 foreach (SceneObjectPart part in parts) 7595 int idx = 0;
7093 SetPrimParams(part, rules); 7596
7597 while (idx < rules.Length)
7598 {
7599 int code = rules.GetLSLIntegerItem(idx++);
7600
7601 int remain = rules.Length - idx;
7602
7603 switch (code)
7604 {
7605 case (int)ScriptBaseClass.PRIM_POSITION:
7606 {
7607 if (remain < 1)
7608 return;
7609 LSL_Vector v;
7610 v = rules.GetVector3Item(idx++);
7611
7612 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7613 if (part == null)
7614 break;
7615
7616 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7617 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7618 if (llGetLinkNumber() > 1)
7619 {
7620 localRot = llGetLocalRot();
7621 localPos = llGetLocalPos();
7622 }
7623
7624 v -= localPos;
7625 v /= localRot;
7626
7627 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7628
7629 v = v + 2 * sitOffset;
7630
7631 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7632 av.SendAvatarDataToAllAgents();
7633
7634 }
7635 break;
7636
7637 case (int)ScriptBaseClass.PRIM_ROTATION:
7638 {
7639 if (remain < 1)
7640 return;
7641
7642 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7643 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7644 if (llGetLinkNumber() > 1)
7645 {
7646 localRot = llGetLocalRot();
7647 localPos = llGetLocalPos();
7648 }
7649
7650 LSL_Rotation r;
7651 r = rules.GetQuaternionItem(idx++);
7652 r = r * llGetRootRotation() / localRot;
7653 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7654 av.SendAvatarDataToAllAgents();
7655 }
7656 break;
7657 }
7658 }
7094 } 7659 }
7095 7660
7096 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7661 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7097 { 7662 {
7663 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7664 return;
7665
7098 int idx = 0; 7666 int idx = 0;
7099 7667
7100 bool positionChanged = false; 7668 bool positionChanged = false;
@@ -7122,6 +7690,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7122 currentPosition = GetSetPosTarget(part, v, currentPosition); 7690 currentPosition = GetSetPosTarget(part, v, currentPosition);
7123 7691
7124 break; 7692 break;
7693 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7694 if (remain < 1)
7695 return;
7696
7697 v=rules.GetVector3Item(idx++);
7698 positionChanged = true;
7699 currentPosition = GetSetPosTarget(part, v, currentPosition);
7700
7701 break;
7125 case (int)ScriptBaseClass.PRIM_SIZE: 7702 case (int)ScriptBaseClass.PRIM_SIZE:
7126 if (remain < 1) 7703 if (remain < 1)
7127 return; 7704 return;
@@ -7488,7 +8065,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7488 if (part.ParentGroup.RootPart == part) 8065 if (part.ParentGroup.RootPart == part)
7489 { 8066 {
7490 SceneObjectGroup parent = part.ParentGroup; 8067 SceneObjectGroup parent = part.ParentGroup;
7491 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8068 Util.FireAndForget(delegate(object x) {
8069 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8070 });
7492 } 8071 }
7493 else 8072 else
7494 { 8073 {
@@ -7499,6 +8078,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7499 } 8078 }
7500 } 8079 }
7501 } 8080 }
8081
8082 if (positionChanged)
8083 {
8084 if (part.ParentGroup.RootPart == part)
8085 {
8086 SceneObjectGroup parent = part.ParentGroup;
8087 Util.FireAndForget(delegate(object x) {
8088 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8089 });
8090 }
8091 else
8092 {
8093 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8094 SceneObjectGroup parent = part.ParentGroup;
8095 parent.HasGroupChanged = true;
8096 parent.ScheduleGroupForTerseUpdate();
8097 }
8098 }
7502 } 8099 }
7503 8100
7504 public LSL_String llStringToBase64(string str) 8101 public LSL_String llStringToBase64(string str)
@@ -7659,13 +8256,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7659 public LSL_Integer llGetNumberOfPrims() 8256 public LSL_Integer llGetNumberOfPrims()
7660 { 8257 {
7661 m_host.AddScriptLPS(1); 8258 m_host.AddScriptLPS(1);
7662 int avatarCount = 0; 8259 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7663 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8260
7664 {
7665 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7666 avatarCount++;
7667 });
7668
7669 return m_host.ParentGroup.PrimCount + avatarCount; 8261 return m_host.ParentGroup.PrimCount + avatarCount;
7670 } 8262 }
7671 8263
@@ -7681,55 +8273,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7681 m_host.AddScriptLPS(1); 8273 m_host.AddScriptLPS(1);
7682 UUID objID = UUID.Zero; 8274 UUID objID = UUID.Zero;
7683 LSL_List result = new LSL_List(); 8275 LSL_List result = new LSL_List();
8276
8277 // If the ID is not valid, return null result
7684 if (!UUID.TryParse(obj, out objID)) 8278 if (!UUID.TryParse(obj, out objID))
7685 { 8279 {
7686 result.Add(new LSL_Vector()); 8280 result.Add(new LSL_Vector());
7687 result.Add(new LSL_Vector()); 8281 result.Add(new LSL_Vector());
7688 return result; 8282 return result;
7689 } 8283 }
8284
8285 // Check if this is an attached prim. If so, replace
8286 // the UUID with the avatar UUID and report it's bounding box
8287 SceneObjectPart part = World.GetSceneObjectPart(objID);
8288 if (part != null && part.ParentGroup.IsAttachment)
8289 objID = part.ParentGroup.AttachedAvatar;
8290
8291 // Find out if this is an avatar ID. If so, return it's box
7690 ScenePresence presence = World.GetScenePresence(objID); 8292 ScenePresence presence = World.GetScenePresence(objID);
7691 if (presence != null) 8293 if (presence != null)
7692 { 8294 {
7693 if (presence.ParentID == 0) // not sat on an object 8295 // As per LSL Wiki, there is no difference between sitting
8296 // and standing avatar since server 1.36
8297 LSL_Vector lower;
8298 LSL_Vector upper;
8299 if (presence.Animator.Animations.DefaultAnimation.AnimID
8300 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7694 { 8301 {
7695 LSL_Vector lower; 8302 // This is for ground sitting avatars
7696 LSL_Vector upper; 8303 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7697 if (presence.Animator.Animations.DefaultAnimation.AnimID 8304 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7698 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8305 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 } 8306 }
7716 else 8307 else
7717 { 8308 {
7718 // sitting on an object so we need the bounding box of that 8309 // This is for standing/flying avatars
7719 // which should include the avatar so set the UUID to the 8310 float height = presence.Appearance.AvatarHeight / 2.0f;
7720 // UUID of the object the avatar is sat on and allow it to fall through 8311 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7721 // to processing an object 8312 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7722 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7723 objID = p.UUID;
7724 } 8313 }
8314
8315 // Adjust to the documented error offsets (see LSL Wiki)
8316 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8317 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8318
8319 if (lower.x > upper.x)
8320 lower.x = upper.x;
8321 if (lower.y > upper.y)
8322 lower.y = upper.y;
8323 if (lower.z > upper.z)
8324 lower.z = upper.z;
8325
8326 result.Add(lower);
8327 result.Add(upper);
8328 return result;
7725 } 8329 }
7726 SceneObjectPart part = World.GetSceneObjectPart(objID); 8330
8331 part = World.GetSceneObjectPart(objID);
7727 // Currently only works for single prims without a sitting avatar 8332 // Currently only works for single prims without a sitting avatar
7728 if (part != null) 8333 if (part != null)
7729 { 8334 {
7730 Vector3 halfSize = part.Scale / 2.0f; 8335 float minX;
7731 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8336 float maxX;
7732 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8337 float minY;
8338 float maxY;
8339 float minZ;
8340 float maxZ;
8341
8342 // This BBox is in sim coordinates, with the offset being
8343 // a contained point.
8344 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8345 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8346
8347 minX -= offsets[0].X;
8348 maxX -= offsets[0].X;
8349 minY -= offsets[0].Y;
8350 maxY -= offsets[0].Y;
8351 minZ -= offsets[0].Z;
8352 maxZ -= offsets[0].Z;
8353
8354 LSL_Vector lower;
8355 LSL_Vector upper;
8356
8357 // Adjust to the documented error offsets (see LSL Wiki)
8358 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8359 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8360
8361 if (lower.x > upper.x)
8362 lower.x = upper.x;
8363 if (lower.y > upper.y)
8364 lower.y = upper.y;
8365 if (lower.z > upper.z)
8366 lower.z = upper.z;
8367
7733 result.Add(lower); 8368 result.Add(lower);
7734 result.Add(upper); 8369 result.Add(upper);
7735 return result; 8370 return result;
@@ -7809,13 +8444,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7809 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8444 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7810 part.AbsolutePosition.Y, 8445 part.AbsolutePosition.Y,
7811 part.AbsolutePosition.Z); 8446 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); 8447 res.Add(v);
7820 break; 8448 break;
7821 8449
@@ -7986,56 +8614,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7986 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8614 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7987 if (remain < 1) 8615 if (remain < 1)
7988 return res; 8616 return res;
7989 8617 face = (int)rules.GetLSLIntegerItem(idx++);
7990 face=(int)rules.GetLSLIntegerItem(idx++);
7991 8618
7992 tex = part.Shape.Textures; 8619 tex = part.Shape.Textures;
8620 int shiny;
7993 if (face == ScriptBaseClass.ALL_SIDES) 8621 if (face == ScriptBaseClass.ALL_SIDES)
7994 { 8622 {
7995 for (face = 0; face < GetNumberOfSides(part); face++) 8623 for (face = 0; face < GetNumberOfSides(part); face++)
7996 { 8624 {
7997 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8625 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7998 // Convert Shininess to PRIM_SHINY_* 8626 if (shinyness == Shininess.High)
7999 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8627 {
8000 // PRIM_BUMP_* 8628 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8001 res.Add(new LSL_Integer((int)texface.Bump)); 8629 }
8630 else if (shinyness == Shininess.Medium)
8631 {
8632 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8633 }
8634 else if (shinyness == Shininess.Low)
8635 {
8636 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8637 }
8638 else
8639 {
8640 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8641 }
8642 res.Add(new LSL_Integer(shiny));
8643 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8002 } 8644 }
8003 } 8645 }
8004 else 8646 else
8005 { 8647 {
8006 if (face >= 0 && face < GetNumberOfSides(part)) 8648 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8649 if (shinyness == Shininess.High)
8007 { 8650 {
8008 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8651 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8009 // Convert Shininess to PRIM_SHINY_*
8010 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8011 // PRIM_BUMP_*
8012 res.Add(new LSL_Integer((int)texface.Bump));
8013 } 8652 }
8653 else if (shinyness == Shininess.Medium)
8654 {
8655 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8656 }
8657 else if (shinyness == Shininess.Low)
8658 {
8659 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8660 }
8661 else
8662 {
8663 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8664 }
8665 res.Add(new LSL_Integer(shiny));
8666 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8014 } 8667 }
8015 break; 8668 break;
8016 8669
8017 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8670 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8018 if (remain < 1) 8671 if (remain < 1)
8019 return res; 8672 return res;
8020 8673 face = (int)rules.GetLSLIntegerItem(idx++);
8021 face=(int)rules.GetLSLIntegerItem(idx++);
8022 8674
8023 tex = part.Shape.Textures; 8675 tex = part.Shape.Textures;
8676 int fullbright;
8024 if (face == ScriptBaseClass.ALL_SIDES) 8677 if (face == ScriptBaseClass.ALL_SIDES)
8025 { 8678 {
8026 for (face = 0; face < GetNumberOfSides(part); face++) 8679 for (face = 0; face < GetNumberOfSides(part); face++)
8027 { 8680 {
8028 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8681 if (tex.GetFace((uint)face).Fullbright == true)
8029 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8682 {
8683 fullbright = ScriptBaseClass.TRUE;
8684 }
8685 else
8686 {
8687 fullbright = ScriptBaseClass.FALSE;
8688 }
8689 res.Add(new LSL_Integer(fullbright));
8030 } 8690 }
8031 } 8691 }
8032 else 8692 else
8033 { 8693 {
8034 if (face >= 0 && face < GetNumberOfSides(part)) 8694 if (tex.GetFace((uint)face).Fullbright == true)
8035 { 8695 {
8036 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8696 fullbright = ScriptBaseClass.TRUE;
8037 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8697 }
8698 else
8699 {
8700 fullbright = ScriptBaseClass.FALSE;
8038 } 8701 }
8702 res.Add(new LSL_Integer(fullbright));
8039 } 8703 }
8040 break; 8704 break;
8041 8705
@@ -8057,27 +8721,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8057 break; 8721 break;
8058 8722
8059 case (int)ScriptBaseClass.PRIM_TEXGEN: 8723 case (int)ScriptBaseClass.PRIM_TEXGEN:
8724 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8060 if (remain < 1) 8725 if (remain < 1)
8061 return res; 8726 return res;
8062 8727 face = (int)rules.GetLSLIntegerItem(idx++);
8063 face=(int)rules.GetLSLIntegerItem(idx++);
8064 8728
8065 tex = part.Shape.Textures; 8729 tex = part.Shape.Textures;
8066 if (face == ScriptBaseClass.ALL_SIDES) 8730 if (face == ScriptBaseClass.ALL_SIDES)
8067 { 8731 {
8068 for (face = 0; face < GetNumberOfSides(part); face++) 8732 for (face = 0; face < GetNumberOfSides(part); face++)
8069 { 8733 {
8070 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8734 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8071 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8735 {
8072 res.Add(new LSL_Integer((uint)texgen >> 1)); 8736 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8737 }
8738 else
8739 {
8740 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8741 }
8073 } 8742 }
8074 } 8743 }
8075 else 8744 else
8076 { 8745 {
8077 if (face >= 0 && face < GetNumberOfSides(part)) 8746 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8078 { 8747 {
8079 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8748 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8080 res.Add(new LSL_Integer((uint)texgen >> 1)); 8749 }
8750 else
8751 {
8752 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8081 } 8753 }
8082 } 8754 }
8083 break; 8755 break;
@@ -8100,28 +8772,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8100 case (int)ScriptBaseClass.PRIM_GLOW: 8772 case (int)ScriptBaseClass.PRIM_GLOW:
8101 if (remain < 1) 8773 if (remain < 1)
8102 return res; 8774 return res;
8103 8775 face = (int)rules.GetLSLIntegerItem(idx++);
8104 face=(int)rules.GetLSLIntegerItem(idx++);
8105 8776
8106 tex = part.Shape.Textures; 8777 tex = part.Shape.Textures;
8778 float primglow;
8107 if (face == ScriptBaseClass.ALL_SIDES) 8779 if (face == ScriptBaseClass.ALL_SIDES)
8108 { 8780 {
8109 for (face = 0; face < GetNumberOfSides(part); face++) 8781 for (face = 0; face < GetNumberOfSides(part); face++)
8110 { 8782 {
8111 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8783 primglow = tex.GetFace((uint)face).Glow;
8112 res.Add(new LSL_Float(texface.Glow)); 8784 res.Add(new LSL_Float(primglow));
8113 } 8785 }
8114 } 8786 }
8115 else 8787 else
8116 { 8788 {
8117 if (face >= 0 && face < GetNumberOfSides(part)) 8789 primglow = tex.GetFace((uint)face).Glow;
8118 { 8790 res.Add(new LSL_Float(primglow));
8119 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8120 res.Add(new LSL_Float(texface.Glow));
8121 }
8122 } 8791 }
8123 break; 8792 break;
8124
8125 case (int)ScriptBaseClass.PRIM_TEXT: 8793 case (int)ScriptBaseClass.PRIM_TEXT:
8126 Color4 textColor = part.GetTextColor(); 8794 Color4 textColor = part.GetTextColor();
8127 res.Add(new LSL_String(part.Text)); 8795 res.Add(new LSL_String(part.Text));
@@ -8673,8 +9341,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8673 // The function returns an ordered list 9341 // The function returns an ordered list
8674 // representing the tokens found in the supplied 9342 // representing the tokens found in the supplied
8675 // sources string. If two successive tokenizers 9343 // sources string. If two successive tokenizers
8676 // are encountered, then a NULL entry is added 9344 // are encountered, then a null-string entry is
8677 // to the list. 9345 // added to the list.
8678 // 9346 //
8679 // It is a precondition that the source and 9347 // It is a precondition that the source and
8680 // toekizer lisst are non-null. If they are null, 9348 // toekizer lisst are non-null. If they are null,
@@ -8682,7 +9350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8682 // while their lengths are being determined. 9350 // while their lengths are being determined.
8683 // 9351 //
8684 // A small amount of working memoryis required 9352 // A small amount of working memoryis required
8685 // of approximately 8*#tokenizers. 9353 // of approximately 8*#tokenizers + 8*srcstrlen.
8686 // 9354 //
8687 // There are many ways in which this function 9355 // There are many ways in which this function
8688 // can be implemented, this implementation is 9356 // can be implemented, this implementation is
@@ -8698,155 +9366,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8698 // and eliminates redundant tokenizers as soon 9366 // and eliminates redundant tokenizers as soon
8699 // as is possible. 9367 // as is possible.
8700 // 9368 //
8701 // The implementation tries to avoid any copying 9369 // The implementation tries to minimize temporary
8702 // of arrays or other objects. 9370 // garbage generation.
8703 // </remarks> 9371 // </remarks>
8704 9372
8705 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9373 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8706 { 9374 {
8707 int beginning = 0; 9375 return ParseString2List(src, separators, spacers, true);
8708 int srclen = src.Length; 9376 }
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 9377
8723 LSL_List tokens = new LSL_List(); 9378 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9379 {
9380 int srclen = src.Length;
9381 int seplen = separators.Length;
9382 object[] separray = separators.Data;
9383 int spclen = spacers.Length;
9384 object[] spcarray = spacers.Data;
9385 int dellen = 0;
9386 string[] delarray = new string[seplen+spclen];
8724 9387
8725 // All entries are initially valid 9388 int outlen = 0;
9389 string[] outarray = new string[srclen*2+1];
8726 9390
8727 for (int i = 0; i < mlen; i++) 9391 int i, j;
8728 active[i] = true; 9392 string d;
8729 9393
8730 offset[mlen] = srclen; 9394 m_host.AddScriptLPS(1);
8731 9395
8732 while (beginning < srclen) 9396 /*
9397 * Convert separator and spacer lists to C# strings.
9398 * Also filter out null strings so we don't hang.
9399 */
9400 for (i = 0; i < seplen; i ++)
8733 { 9401 {
9402 d = separray[i].ToString();
9403 if (d.Length > 0)
9404 {
9405 delarray[dellen++] = d;
9406 }
9407 }
9408 seplen = dellen;
8734 9409
8735 best = mlen; // as bad as it gets 9410 for (i = 0; i < spclen; i ++)
9411 {
9412 d = spcarray[i].ToString();
9413 if (d.Length > 0)
9414 {
9415 delarray[dellen++] = d;
9416 }
9417 }
8736 9418
8737 // Scan for separators 9419 /*
9420 * Scan through source string from beginning to end.
9421 */
9422 for (i = 0;;)
9423 {
8738 9424
8739 for (j = 0; j < seplen; j++) 9425 /*
9426 * Find earliest delimeter in src starting at i (if any).
9427 */
9428 int earliestDel = -1;
9429 int earliestSrc = srclen;
9430 string earliestStr = null;
9431 for (j = 0; j < dellen; j ++)
8740 { 9432 {
8741 if (separray[j].ToString() == String.Empty) 9433 d = delarray[j];
8742 active[j] = false; 9434 if (d != null)
8743
8744 if (active[j])
8745 { 9435 {
8746 // scan all of the markers 9436 int index = src.IndexOf(d, i);
8747 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9437 if (index < 0)
8748 { 9438 {
8749 // not present at all 9439 delarray[j] = null; // delim nowhere in src, don't check it anymore
8750 active[j] = false;
8751 } 9440 }
8752 else 9441 else if (index < earliestSrc)
8753 { 9442 {
8754 // present and correct 9443 earliestSrc = index; // where delimeter starts in source string
8755 if (offset[j] < offset[best]) 9444 earliestDel = j; // where delimeter is in delarray[]
8756 { 9445 earliestStr = d; // the delimeter string from delarray[]
8757 // closest so far 9446 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 } 9447 }
8763 } 9448 }
8764 } 9449 }
8765 9450
8766 // Scan for spacers 9451 /*
8767 9452 * Output source string starting at i through start of earliest delimeter.
8768 if (offset[best] != beginning) 9453 */
9454 if (keepNulls || (earliestSrc > i))
8769 { 9455 {
8770 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9456 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 } 9457 }
8795 9458
8796 // This is the normal exit from the scanning loop 9459 /*
9460 * If no delimeter found at or after i, we're done scanning.
9461 */
9462 if (earliestDel < 0) break;
8797 9463
8798 if (best == mlen) 9464 /*
9465 * If delimeter was a spacer, output the spacer.
9466 */
9467 if (earliestDel >= seplen)
8799 { 9468 {
8800 // no markers were found on this pass 9469 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 } 9470 }
8806 9471
8807 // Otherwise we just add the newly delimited token 9472 /*
8808 // and recalculate where the search should continue. 9473 * Look at rest of src string following delimeter.
8809 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9474 */
8810 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9475 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 } 9476 }
8824 9477
8825 // This an awkward an not very intuitive boundary case. If the 9478 /*
8826 // last substring is a tokenizer, then there is an implied trailing 9479 * 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 9480 */
8828 // arduous. Alternatively the 'break' could be replced with a return 9481 object[] outlist = new object[outlen];
8829 // but that's shabby programming. 9482 for (i = 0; i < outlen; i ++)
8830
8831 if ((beginning == srclen) && (keepNulls))
8832 { 9483 {
8833 if (srclen != 0) 9484 outlist[i] = new LSL_String(outarray[i]);
8834 tokens.Add(new LSL_String(""));
8835 } 9485 }
8836 9486 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 } 9487 }
8851 9488
8852 public LSL_Integer llGetObjectPermMask(int mask) 9489 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8923,28 +9560,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8923 { 9560 {
8924 m_host.AddScriptLPS(1); 9561 m_host.AddScriptLPS(1);
8925 9562
8926 lock (m_host.TaskInventory) 9563 m_host.TaskInventory.LockItemsForRead(true);
9564 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8927 { 9565 {
8928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9566 if (inv.Value.Name == item)
8929 { 9567 {
8930 if (inv.Value.Name == item) 9568 m_host.TaskInventory.LockItemsForRead(false);
9569 switch (mask)
8931 { 9570 {
8932 switch (mask) 9571 case 0:
8933 { 9572 return (int)inv.Value.BasePermissions;
8934 case 0: 9573 case 1:
8935 return (int)inv.Value.BasePermissions; 9574 return (int)inv.Value.CurrentPermissions;
8936 case 1: 9575 case 2:
8937 return (int)inv.Value.CurrentPermissions; 9576 return (int)inv.Value.GroupPermissions;
8938 case 2: 9577 case 3:
8939 return (int)inv.Value.GroupPermissions; 9578 return (int)inv.Value.EveryonePermissions;
8940 case 3: 9579 case 4:
8941 return (int)inv.Value.EveryonePermissions; 9580 return (int)inv.Value.NextPermissions;
8942 case 4:
8943 return (int)inv.Value.NextPermissions;
8944 }
8945 } 9581 }
8946 } 9582 }
8947 } 9583 }
9584 m_host.TaskInventory.LockItemsForRead(false);
8948 9585
8949 return -1; 9586 return -1;
8950 } 9587 }
@@ -8991,16 +9628,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8991 { 9628 {
8992 m_host.AddScriptLPS(1); 9629 m_host.AddScriptLPS(1);
8993 9630
8994 lock (m_host.TaskInventory) 9631 m_host.TaskInventory.LockItemsForRead(true);
9632 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8995 { 9633 {
8996 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9634 if (inv.Value.Name == item)
8997 { 9635 {
8998 if (inv.Value.Name == item) 9636 m_host.TaskInventory.LockItemsForRead(false);
8999 { 9637 return inv.Value.CreatorID.ToString();
9000 return inv.Value.CreatorID.ToString();
9001 }
9002 } 9638 }
9003 } 9639 }
9640 m_host.TaskInventory.LockItemsForRead(false);
9004 9641
9005 llSay(0, "No item name '" + item + "'"); 9642 llSay(0, "No item name '" + item + "'");
9006 9643
@@ -9148,7 +9785,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9148 } 9785 }
9149 9786
9150 /// <summary> 9787 /// <summary>
9151 /// illListReplaceList removes the sub-list defined by the inclusive indices 9788 /// llListReplaceList removes the sub-list defined by the inclusive indices
9152 /// start and end and inserts the src list in its place. The inclusive 9789 /// 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 9790 /// 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 9791 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9205,16 +9842,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9205 // based upon end. Note that if end exceeds the upper 9842 // based upon end. Note that if end exceeds the upper
9206 // bound in this case, the entire destination list 9843 // bound in this case, the entire destination list
9207 // is removed. 9844 // is removed.
9208 else 9845 else if (start == 0)
9209 { 9846 {
9210 if (end + 1 < dest.Length) 9847 if (end + 1 < dest.Length)
9211 {
9212 return src + dest.GetSublist(end + 1, -1); 9848 return src + dest.GetSublist(end + 1, -1);
9213 }
9214 else 9849 else
9215 {
9216 return src; 9850 return src;
9217 } 9851 }
9852 else // Start < 0
9853 {
9854 if (end + 1 < dest.Length)
9855 return dest.GetSublist(end + 1, -1);
9856 else
9857 return new LSL_List();
9218 } 9858 }
9219 } 9859 }
9220 // Finally, if start > end, we strip away a prefix and 9860 // Finally, if start > end, we strip away a prefix and
@@ -9265,17 +9905,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9265 int width = 0; 9905 int width = 0;
9266 int height = 0; 9906 int height = 0;
9267 9907
9268 ParcelMediaCommandEnum? commandToSend = null; 9908 uint commandToSend = 0;
9269 float time = 0.0f; // default is from start 9909 float time = 0.0f; // default is from start
9270 9910
9271 ScenePresence presence = null; 9911 ScenePresence presence = null;
9272 9912
9273 for (int i = 0; i < commandList.Data.Length; i++) 9913 for (int i = 0; i < commandList.Data.Length; i++)
9274 { 9914 {
9275 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9915 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9276 switch (command) 9916 switch (command)
9277 { 9917 {
9278 case ParcelMediaCommandEnum.Agent: 9918 case (uint)ParcelMediaCommandEnum.Agent:
9279 // we send only to one agent 9919 // we send only to one agent
9280 if ((i + 1) < commandList.Length) 9920 if ((i + 1) < commandList.Length)
9281 { 9921 {
@@ -9292,25 +9932,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 } 9932 }
9293 break; 9933 break;
9294 9934
9295 case ParcelMediaCommandEnum.Loop: 9935 case (uint)ParcelMediaCommandEnum.Loop:
9296 loop = 1; 9936 loop = 1;
9297 commandToSend = command; 9937 commandToSend = command;
9298 update = true; //need to send the media update packet to set looping 9938 update = true; //need to send the media update packet to set looping
9299 break; 9939 break;
9300 9940
9301 case ParcelMediaCommandEnum.Play: 9941 case (uint)ParcelMediaCommandEnum.Play:
9302 loop = 0; 9942 loop = 0;
9303 commandToSend = command; 9943 commandToSend = command;
9304 update = true; //need to send the media update packet to make sure it doesn't loop 9944 update = true; //need to send the media update packet to make sure it doesn't loop
9305 break; 9945 break;
9306 9946
9307 case ParcelMediaCommandEnum.Pause: 9947 case (uint)ParcelMediaCommandEnum.Pause:
9308 case ParcelMediaCommandEnum.Stop: 9948 case (uint)ParcelMediaCommandEnum.Stop:
9309 case ParcelMediaCommandEnum.Unload: 9949 case (uint)ParcelMediaCommandEnum.Unload:
9310 commandToSend = command; 9950 commandToSend = command;
9311 break; 9951 break;
9312 9952
9313 case ParcelMediaCommandEnum.Url: 9953 case (uint)ParcelMediaCommandEnum.Url:
9314 if ((i + 1) < commandList.Length) 9954 if ((i + 1) < commandList.Length)
9315 { 9955 {
9316 if (commandList.Data[i + 1] is LSL_String) 9956 if (commandList.Data[i + 1] is LSL_String)
@@ -9323,7 +9963,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9323 } 9963 }
9324 break; 9964 break;
9325 9965
9326 case ParcelMediaCommandEnum.Texture: 9966 case (uint)ParcelMediaCommandEnum.Texture:
9327 if ((i + 1) < commandList.Length) 9967 if ((i + 1) < commandList.Length)
9328 { 9968 {
9329 if (commandList.Data[i + 1] is LSL_String) 9969 if (commandList.Data[i + 1] is LSL_String)
@@ -9336,7 +9976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9336 } 9976 }
9337 break; 9977 break;
9338 9978
9339 case ParcelMediaCommandEnum.Time: 9979 case (uint)ParcelMediaCommandEnum.Time:
9340 if ((i + 1) < commandList.Length) 9980 if ((i + 1) < commandList.Length)
9341 { 9981 {
9342 if (commandList.Data[i + 1] is LSL_Float) 9982 if (commandList.Data[i + 1] is LSL_Float)
@@ -9348,7 +9988,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9348 } 9988 }
9349 break; 9989 break;
9350 9990
9351 case ParcelMediaCommandEnum.AutoAlign: 9991 case (uint)ParcelMediaCommandEnum.AutoAlign:
9352 if ((i + 1) < commandList.Length) 9992 if ((i + 1) < commandList.Length)
9353 { 9993 {
9354 if (commandList.Data[i + 1] is LSL_Integer) 9994 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9362,7 +10002,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9362 } 10002 }
9363 break; 10003 break;
9364 10004
9365 case ParcelMediaCommandEnum.Type: 10005 case (uint)ParcelMediaCommandEnum.Type:
9366 if ((i + 1) < commandList.Length) 10006 if ((i + 1) < commandList.Length)
9367 { 10007 {
9368 if (commandList.Data[i + 1] is LSL_String) 10008 if (commandList.Data[i + 1] is LSL_String)
@@ -9375,7 +10015,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9375 } 10015 }
9376 break; 10016 break;
9377 10017
9378 case ParcelMediaCommandEnum.Desc: 10018 case (uint)ParcelMediaCommandEnum.Desc:
9379 if ((i + 1) < commandList.Length) 10019 if ((i + 1) < commandList.Length)
9380 { 10020 {
9381 if (commandList.Data[i + 1] is LSL_String) 10021 if (commandList.Data[i + 1] is LSL_String)
@@ -9388,7 +10028,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9388 } 10028 }
9389 break; 10029 break;
9390 10030
9391 case ParcelMediaCommandEnum.Size: 10031 case (uint)ParcelMediaCommandEnum.Size:
9392 if ((i + 2) < commandList.Length) 10032 if ((i + 2) < commandList.Length)
9393 { 10033 {
9394 if (commandList.Data[i + 1] is LSL_Integer) 10034 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9458,7 +10098,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9458 } 10098 }
9459 } 10099 }
9460 10100
9461 if (commandToSend != null) 10101 if (commandToSend != 0)
9462 { 10102 {
9463 // the commandList contained a start/stop/... command, too 10103 // the commandList contained a start/stop/... command, too
9464 if (presence == null) 10104 if (presence == null)
@@ -9495,7 +10135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9495 10135
9496 if (aList.Data[i] != null) 10136 if (aList.Data[i] != null)
9497 { 10137 {
9498 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10138 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9499 { 10139 {
9500 case ParcelMediaCommandEnum.Url: 10140 case ParcelMediaCommandEnum.Url:
9501 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10141 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9538,16 +10178,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9538 { 10178 {
9539 m_host.AddScriptLPS(1); 10179 m_host.AddScriptLPS(1);
9540 10180
9541 lock (m_host.TaskInventory) 10181 m_host.TaskInventory.LockItemsForRead(true);
10182 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9542 { 10183 {
9543 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10184 if (inv.Value.Name == name)
9544 { 10185 {
9545 if (inv.Value.Name == name) 10186 m_host.TaskInventory.LockItemsForRead(false);
9546 { 10187 return inv.Value.Type;
9547 return inv.Value.Type;
9548 }
9549 } 10188 }
9550 } 10189 }
10190 m_host.TaskInventory.LockItemsForRead(false);
9551 10191
9552 return -1; 10192 return -1;
9553 } 10193 }
@@ -9558,15 +10198,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9558 10198
9559 if (quick_pay_buttons.Data.Length < 4) 10199 if (quick_pay_buttons.Data.Length < 4)
9560 { 10200 {
9561 LSLError("List must have at least 4 elements"); 10201 int x;
9562 return; 10202 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10203 {
10204 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10205 }
9563 } 10206 }
9564 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10207 int[] nPrice = new int[5];
9565 10208 nPrice[0] = price;
9566 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10209 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9567 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10210 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9568 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10211 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9569 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10212 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10213 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9570 m_host.ParentGroup.HasGroupChanged = true; 10214 m_host.ParentGroup.HasGroupChanged = true;
9571 } 10215 }
9572 10216
@@ -9578,17 +10222,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9578 if (invItemID == UUID.Zero) 10222 if (invItemID == UUID.Zero)
9579 return new LSL_Vector(); 10223 return new LSL_Vector();
9580 10224
9581 lock (m_host.TaskInventory) 10225 m_host.TaskInventory.LockItemsForRead(true);
10226 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9582 { 10227 {
9583 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10228 m_host.TaskInventory.LockItemsForRead(false);
9584 return new LSL_Vector(); 10229 return new LSL_Vector();
10230 }
9585 10231
9586 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10232 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9587 { 10233 {
9588 ShoutError("No permissions to track the camera"); 10234 ShoutError("No permissions to track the camera");
9589 return new LSL_Vector(); 10235 m_host.TaskInventory.LockItemsForRead(false);
9590 } 10236 return new LSL_Vector();
9591 } 10237 }
10238 m_host.TaskInventory.LockItemsForRead(false);
9592 10239
9593 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10240 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9594 if (presence != null) 10241 if (presence != null)
@@ -9606,17 +10253,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9606 if (invItemID == UUID.Zero) 10253 if (invItemID == UUID.Zero)
9607 return new LSL_Rotation(); 10254 return new LSL_Rotation();
9608 10255
9609 lock (m_host.TaskInventory) 10256 m_host.TaskInventory.LockItemsForRead(true);
10257 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9610 { 10258 {
9611 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10259 m_host.TaskInventory.LockItemsForRead(false);
9612 return new LSL_Rotation(); 10260 return new LSL_Rotation();
9613 10261 }
9614 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10262 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9615 { 10263 {
9616 ShoutError("No permissions to track the camera"); 10264 ShoutError("No permissions to track the camera");
9617 return new LSL_Rotation(); 10265 m_host.TaskInventory.LockItemsForRead(false);
9618 } 10266 return new LSL_Rotation();
9619 } 10267 }
10268 m_host.TaskInventory.LockItemsForRead(false);
9620 10269
9621 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10270 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9622 if (presence != null) 10271 if (presence != null)
@@ -9678,8 +10327,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9678 { 10327 {
9679 m_host.AddScriptLPS(1); 10328 m_host.AddScriptLPS(1);
9680 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10329 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9681 if (detectedParams == null) return; // only works on the first detected avatar 10330 if (detectedParams == null)
9682 10331 {
10332 if (m_host.ParentGroup.IsAttachment == true)
10333 {
10334 detectedParams = new DetectParams();
10335 detectedParams.Key = m_host.OwnerID;
10336 }
10337 else
10338 {
10339 return;
10340 }
10341 }
10342
9683 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10343 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9684 if (avatar != null) 10344 if (avatar != null)
9685 { 10345 {
@@ -9687,6 +10347,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9687 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10347 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9688 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10348 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9689 } 10349 }
10350
9690 ScriptSleep(1000); 10351 ScriptSleep(1000);
9691 } 10352 }
9692 10353
@@ -9798,14 +10459,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9798 if (objectID == UUID.Zero) return; 10459 if (objectID == UUID.Zero) return;
9799 10460
9800 UUID agentID; 10461 UUID agentID;
9801 lock (m_host.TaskInventory) 10462 m_host.TaskInventory.LockItemsForRead(true);
9802 { 10463 // 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 10464 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9804 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9805 10465
9806 if (agentID == UUID.Zero) return; 10466 if (agentID == UUID.Zero)
9807 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10467 {
10468 m_host.TaskInventory.LockItemsForRead(false);
10469 return;
9808 } 10470 }
10471 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10472 {
10473 m_host.TaskInventory.LockItemsForRead(false);
10474 return;
10475 }
10476 m_host.TaskInventory.LockItemsForRead(false);
9809 10477
9810 ScenePresence presence = World.GetScenePresence(agentID); 10478 ScenePresence presence = World.GetScenePresence(agentID);
9811 10479
@@ -9814,12 +10482,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9814 10482
9815 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10483 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9816 object[] data = rules.Data; 10484 object[] data = rules.Data;
9817 for (int i = 0; i < data.Length; ++i) { 10485 for (int i = 0; i < data.Length; ++i)
10486 {
9818 int type = Convert.ToInt32(data[i++].ToString()); 10487 int type = Convert.ToInt32(data[i++].ToString());
9819 if (i >= data.Length) break; // odd number of entries => ignore the last 10488 if (i >= data.Length) break; // odd number of entries => ignore the last
9820 10489
9821 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10490 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9822 switch (type) { 10491 switch (type)
10492 {
9823 case ScriptBaseClass.CAMERA_FOCUS: 10493 case ScriptBaseClass.CAMERA_FOCUS:
9824 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10494 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9825 case ScriptBaseClass.CAMERA_POSITION: 10495 case ScriptBaseClass.CAMERA_POSITION:
@@ -9855,12 +10525,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9855 10525
9856 // we need the permission first, to know which avatar we want to clear the camera for 10526 // we need the permission first, to know which avatar we want to clear the camera for
9857 UUID agentID; 10527 UUID agentID;
9858 lock (m_host.TaskInventory) 10528 m_host.TaskInventory.LockItemsForRead(true);
10529 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10530 if (agentID == UUID.Zero)
9859 { 10531 {
9860 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10532 m_host.TaskInventory.LockItemsForRead(false);
9861 if (agentID == UUID.Zero) return; 10533 return;
9862 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10534 }
10535 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10536 {
10537 m_host.TaskInventory.LockItemsForRead(false);
10538 return;
9863 } 10539 }
10540 m_host.TaskInventory.LockItemsForRead(false);
9864 10541
9865 ScenePresence presence = World.GetScenePresence(agentID); 10542 ScenePresence presence = World.GetScenePresence(agentID);
9866 10543
@@ -9927,19 +10604,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9927 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10604 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9928 { 10605 {
9929 m_host.AddScriptLPS(1); 10606 m_host.AddScriptLPS(1);
9930 string ret = String.Empty; 10607
9931 string src1 = llBase64ToString(str1); 10608 if (str1 == String.Empty)
9932 string src2 = llBase64ToString(str2); 10609 return String.Empty;
9933 int c = 0; 10610 if (str2 == String.Empty)
9934 for (int i = 0; i < src1.Length; i++) 10611 return str1;
10612
10613 int len = str2.Length;
10614 if ((len % 4) != 0) // LL is EVIL!!!!
10615 {
10616 while (str2.EndsWith("="))
10617 str2 = str2.Substring(0, str2.Length - 1);
10618
10619 len = str2.Length;
10620 int mod = len % 4;
10621
10622 if (mod == 1)
10623 str2 = str2.Substring(0, str2.Length - 1);
10624 else if (mod == 2)
10625 str2 += "==";
10626 else if (mod == 3)
10627 str2 += "=";
10628 }
10629
10630 byte[] data1;
10631 byte[] data2;
10632 try
10633 {
10634 data1 = Convert.FromBase64String(str1);
10635 data2 = Convert.FromBase64String(str2);
10636 }
10637 catch (Exception)
9935 { 10638 {
9936 ret += (char) (src1[i] ^ src2[c]); 10639 return new LSL_String(String.Empty);
10640 }
9937 10641
9938 c++; 10642 byte[] d2 = new Byte[data1.Length];
9939 if (c >= src2.Length) 10643 int pos = 0;
9940 c = 0; 10644
10645 if (data1.Length <= data2.Length)
10646 {
10647 Array.Copy(data2, 0, d2, 0, data1.Length);
9941 } 10648 }
9942 return llStringToBase64(ret); 10649 else
10650 {
10651 while (pos < data1.Length)
10652 {
10653 len = data1.Length - pos;
10654 if (len > data2.Length)
10655 len = data2.Length;
10656
10657 Array.Copy(data2, 0, d2, pos, len);
10658 pos += len;
10659 }
10660 }
10661
10662 for (pos = 0 ; pos < data1.Length ; pos++ )
10663 data1[pos] ^= d2[pos];
10664
10665 return Convert.ToBase64String(data1);
9943 } 10666 }
9944 10667
9945 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10668 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9996,12 +10719,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9996 Regex r = new Regex(authregex); 10719 Regex r = new Regex(authregex);
9997 int[] gnums = r.GetGroupNumbers(); 10720 int[] gnums = r.GetGroupNumbers();
9998 Match m = r.Match(url); 10721 Match m = r.Match(url);
9999 if (m.Success) { 10722 if (m.Success)
10000 for (int i = 1; i < gnums.Length; i++) { 10723 {
10724 for (int i = 1; i < gnums.Length; i++)
10725 {
10001 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10726 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10002 //CaptureCollection cc = g.Captures; 10727 //CaptureCollection cc = g.Captures;
10003 } 10728 }
10004 if (m.Groups.Count == 5) { 10729 if (m.Groups.Count == 5)
10730 {
10005 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10731 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(); 10732 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10007 } 10733 }
@@ -10287,15 +11013,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10287 11013
10288 internal UUID ScriptByName(string name) 11014 internal UUID ScriptByName(string name)
10289 { 11015 {
10290 lock (m_host.TaskInventory) 11016 m_host.TaskInventory.LockItemsForRead(true);
11017
11018 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10291 { 11019 {
10292 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11020 if (item.Type == 10 && item.Name == name)
10293 { 11021 {
10294 if (item.Type == 10 && item.Name == name) 11022 m_host.TaskInventory.LockItemsForRead(false);
10295 return item.ItemID; 11023 return item.ItemID;
10296 } 11024 }
10297 } 11025 }
10298 11026
11027 m_host.TaskInventory.LockItemsForRead(false);
11028
10299 return UUID.Zero; 11029 return UUID.Zero;
10300 } 11030 }
10301 11031
@@ -10336,6 +11066,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10336 { 11066 {
10337 m_host.AddScriptLPS(1); 11067 m_host.AddScriptLPS(1);
10338 11068
11069 //Clone is thread safe
10339 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11070 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10340 11071
10341 UUID assetID = UUID.Zero; 11072 UUID assetID = UUID.Zero;
@@ -10398,6 +11129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10398 { 11129 {
10399 m_host.AddScriptLPS(1); 11130 m_host.AddScriptLPS(1);
10400 11131
11132 //Clone is thread safe
10401 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11133 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10402 11134
10403 UUID assetID = UUID.Zero; 11135 UUID assetID = UUID.Zero;
@@ -10478,15 +11210,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10478 return GetLinkPrimitiveParams(obj, rules); 11210 return GetLinkPrimitiveParams(obj, rules);
10479 } 11211 }
10480 11212
10481 public void print(string str) 11213 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10482 { 11214 {
10483 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11215 List<SceneObjectPart> parts = GetLinkParts(link);
10484 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11216 if (parts.Count < 1)
10485 if (ossl != null) 11217 return 0;
10486 { 11218
10487 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11219 return GetNumberOfSides(parts[0]);
10488 m_log.Info("LSL print():" + str);
10489 }
10490 } 11220 }
10491 11221
10492 private string Name2Username(string name) 11222 private string Name2Username(string name)
@@ -10532,153 +11262,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10532 return rq.ToString(); 11262 return rq.ToString();
10533 } 11263 }
10534 11264
11265 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11266 {
11267 m_SayShoutCount = 0;
11268 }
11269
11270 private struct Tri
11271 {
11272 public Vector3 p1;
11273 public Vector3 p2;
11274 public Vector3 p3;
11275 }
11276
11277 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11278 {
11279 float height = avatar.Appearance.AvatarHeight;
11280 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11281 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11282
11283 if (point.X > b1.X && point.X < b2.X &&
11284 point.Y > b1.Y && point.Y < b2.Y &&
11285 point.Z > b1.Z && point.Z < b2.Z)
11286 return true;
11287 return false;
11288 }
11289
11290 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11291 {
11292 List<ContactResult> contacts = new List<ContactResult>();
11293
11294 Vector3 ab = rayEnd - rayStart;
11295
11296 World.ForEachScenePresence(delegate(ScenePresence sp)
11297 {
11298 Vector3 ac = sp.AbsolutePosition - rayStart;
11299 Vector3 bc = sp.AbsolutePosition - rayEnd;
11300
11301 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11302
11303 if (d > 1.5)
11304 return;
11305
11306 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11307
11308 if (d2 > 0)
11309 return;
11310
11311 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11312 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11313
11314 if (!InBoundingBox(sp, p))
11315 return;
11316
11317 ContactResult result = new ContactResult ();
11318 result.ConsumerID = sp.LocalId;
11319 result.Depth = Vector3.Distance(rayStart, p);
11320 result.Normal = Vector3.Zero;
11321 result.Pos = p;
11322
11323 contacts.Add(result);
11324 });
11325
11326 return contacts.ToArray();
11327 }
11328
11329 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11330 {
11331 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11332 List<ContactResult> contacts = new List<ContactResult>();
11333
11334 Vector3 ab = rayEnd - rayStart;
11335
11336 World.ForEachSOG(delegate(SceneObjectGroup group)
11337 {
11338 if (m_host.ParentGroup == group)
11339 return;
11340
11341 if (group.IsAttachment)
11342 return;
11343
11344 if (group.RootPart.PhysActor == null)
11345 {
11346 if (!includePhantom)
11347 return;
11348 }
11349 else
11350 {
11351 if (group.RootPart.PhysActor.IsPhysical)
11352 {
11353 if (!includePhysical)
11354 return;
11355 }
11356 else
11357 {
11358 if (!includeNonPhysical)
11359 return;
11360 }
11361 }
11362
11363 // Find the radius ouside of which we don't even need to hit test
11364 float minX;
11365 float maxX;
11366 float minY;
11367 float maxY;
11368 float minZ;
11369 float maxZ;
11370
11371 float radius = 0.0f;
11372
11373 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11374
11375 if (Math.Abs(minX) > radius)
11376 radius = Math.Abs(minX);
11377 if (Math.Abs(minY) > radius)
11378 radius = Math.Abs(minY);
11379 if (Math.Abs(minZ) > radius)
11380 radius = Math.Abs(minZ);
11381 if (Math.Abs(maxX) > radius)
11382 radius = Math.Abs(maxX);
11383 if (Math.Abs(maxY) > radius)
11384 radius = Math.Abs(maxY);
11385 if (Math.Abs(maxZ) > radius)
11386 radius = Math.Abs(maxZ);
11387
11388 Vector3 ac = group.AbsolutePosition - rayStart;
11389 Vector3 bc = group.AbsolutePosition - rayEnd;
11390
11391 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11392
11393 // Too far off ray, don't bother
11394 if (d > radius)
11395 return;
11396
11397 // Behind ray, drop
11398 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11399 if (d2 > 0)
11400 return;
11401
11402 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11403 // Miss.
11404 if (!intersection.HitTF)
11405 return;
11406
11407 ContactResult result = new ContactResult ();
11408 result.ConsumerID = group.LocalId;
11409 result.Depth = intersection.distance;
11410 result.Normal = intersection.normal;
11411 result.Pos = intersection.ipoint;
11412
11413 contacts.Add(result);
11414 });
11415
11416 return contacts.ToArray();
11417 }
11418
11419 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11420 {
11421 double[,] heightfield = World.Heightmap.GetDoubles();
11422 List<ContactResult> contacts = new List<ContactResult>();
11423
11424 double min = 2048.0;
11425 double max = 0.0;
11426
11427 // Find the min and max of the heightfield
11428 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11429 {
11430 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11431 {
11432 if (heightfield[x, y] > max)
11433 max = heightfield[x, y];
11434 if (heightfield[x, y] < min)
11435 min = heightfield[x, y];
11436 }
11437 }
11438
11439
11440 // A ray extends past rayEnd, but doesn't go back before
11441 // rayStart. If the start is above the highest point of the ground
11442 // and the ray goes up, we can't hit the ground. Ever.
11443 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11444 return null;
11445
11446 // Same for going down
11447 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11448 return null;
11449
11450 List<Tri> trilist = new List<Tri>();
11451
11452 // Create our triangle list
11453 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11454 {
11455 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11456 {
11457 Tri t1 = new Tri();
11458 Tri t2 = new Tri();
11459
11460 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11461 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11462 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11463 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11464
11465 t1.p1 = p1;
11466 t1.p2 = p2;
11467 t1.p3 = p3;
11468
11469 t2.p1 = p3;
11470 t2.p2 = p4;
11471 t2.p3 = p1;
11472
11473 trilist.Add(t1);
11474 trilist.Add(t2);
11475 }
11476 }
11477
11478 // Ray direction
11479 Vector3 rayDirection = rayEnd - rayStart;
11480
11481 foreach (Tri t in trilist)
11482 {
11483 // Compute triangle plane normal and edges
11484 Vector3 u = t.p2 - t.p1;
11485 Vector3 v = t.p3 - t.p1;
11486 Vector3 n = Vector3.Cross(u, v);
11487
11488 if (n == Vector3.Zero)
11489 continue;
11490
11491 Vector3 w0 = rayStart - t.p1;
11492 double a = -Vector3.Dot(n, w0);
11493 double b = Vector3.Dot(n, rayDirection);
11494
11495 // Not intersecting the plane, or in plane (same thing)
11496 // Ignoring this MAY cause the ground to not be detected
11497 // sometimes
11498 if (Math.Abs(b) < 0.000001)
11499 continue;
11500
11501 double r = a / b;
11502
11503 // ray points away from plane
11504 if (r < 0.0)
11505 continue;
11506
11507 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11508
11509 float uu = Vector3.Dot(u, u);
11510 float uv = Vector3.Dot(u, v);
11511 float vv = Vector3.Dot(v, v);
11512 Vector3 w = ip - t.p1;
11513 float wu = Vector3.Dot(w, u);
11514 float wv = Vector3.Dot(w, v);
11515 float d = uv * uv - uu * vv;
11516
11517 float cs = (uv * wv - vv * wu) / d;
11518 if (cs < 0 || cs > 1.0)
11519 continue;
11520 float ct = (uv * wu - uu * wv) / d;
11521 if (ct < 0 || (cs + ct) > 1.0)
11522 continue;
11523
11524 // Add contact point
11525 ContactResult result = new ContactResult ();
11526 result.ConsumerID = 0;
11527 result.Depth = Vector3.Distance(rayStart, ip);
11528 result.Normal = n;
11529 result.Pos = ip;
11530
11531 contacts.Add(result);
11532 }
11533
11534 if (contacts.Count == 0)
11535 return null;
11536
11537 contacts.Sort(delegate(ContactResult a, ContactResult b)
11538 {
11539 return (int)(a.Depth - b.Depth);
11540 });
11541
11542 return contacts[0];
11543 }
11544
10535 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11545 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10536 { 11546 {
11547 LSL_List list = new LSL_List();
11548
10537 m_host.AddScriptLPS(1); 11549 m_host.AddScriptLPS(1);
10538 11550
10539 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11551 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); 11552 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); 11553 Vector3 dir = rayEnd - rayStart;
10542 11554
10543 int count = 0; 11555 int count = 1;
10544// int detectPhantom = 0; 11556 bool detectPhantom = false;
10545 int dataFlags = 0; 11557 int dataFlags = 0;
10546 int rejectTypes = 0; 11558 int rejectTypes = 0;
10547 11559
10548 for (int i = 0; i < options.Length; i += 2) 11560 for (int i = 0; i < options.Length; i += 2)
10549 { 11561 {
10550 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11562 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10551 {
10552 count = options.GetLSLIntegerItem(i + 1); 11563 count = options.GetLSLIntegerItem(i + 1);
10553 } 11564 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10554// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11565 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10555// {
10556// detectPhantom = options.GetLSLIntegerItem(i + 1);
10557// }
10558 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11566 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10559 {
10560 dataFlags = options.GetLSLIntegerItem(i + 1); 11567 dataFlags = options.GetLSLIntegerItem(i + 1);
10561 }
10562 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11568 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10563 {
10564 rejectTypes = options.GetLSLIntegerItem(i + 1); 11569 rejectTypes = options.GetLSLIntegerItem(i + 1);
10565 }
10566 } 11570 }
10567 11571
10568 LSL_List list = new LSL_List(); 11572 if (count > 16)
10569 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11573 count = 16;
10570
10571 double distance = Util.GetDistanceTo(startvector, endvector);
10572 11574
10573 if (distance == 0) 11575 List<ContactResult> results = new List<ContactResult>();
10574 distance = 0.001;
10575
10576 Vector3 posToCheck = startvector;
10577 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10578 11576
10579 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11577 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10580 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11578 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10581 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11579 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10582 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11580 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10583 11581
10584 for (float i = 0; i <= distance; i += 0.1f) 11582 if (checkTerrain)
10585 { 11583 {
10586 posToCheck = startvector + (dir * (i / (float)distance)); 11584 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11585 if (groundContact != null)
11586 results.Add((ContactResult)groundContact);
11587 }
10587 11588
10588 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11589 if (checkAgents)
10589 { 11590 {
10590 ContactResult result = new ContactResult(); 11591 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10591 result.ConsumerID = 0; 11592 foreach (ContactResult r in agentHits)
10592 result.Depth = 0; 11593 results.Add(r);
10593 result.Normal = Vector3.Zero; 11594 }
10594 result.Pos = posToCheck;
10595 results.Add(result);
10596 checkTerrain = false;
10597 }
10598 11595
10599 if (checkAgents) 11596 if (checkPhysical || checkNonPhysical)
10600 { 11597 {
10601 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11598 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10602 { 11599 foreach (ContactResult r in objectHits)
10603 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11600 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 } 11601 }
10615 11602
10616 int refcount = 0; 11603 results.Sort(delegate(ContactResult a, ContactResult b)
11604 {
11605 return (int)(a.Depth - b.Depth);
11606 });
11607
11608 int values = 0;
10617 foreach (ContactResult result in results) 11609 foreach (ContactResult result in results)
10618 { 11610 {
10619 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11611 UUID itemID = UUID.Zero;
10620 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11612 int linkNum = 0;
10621 continue;
10622
10623 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
10624
10625 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
10626 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
10627 11613
10628 if (entity == null) 11614 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11615 // It's a prim!
11616 if (part != null)
10629 { 11617 {
10630 list.Add(UUID.Zero); 11618 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10631 11619 itemID = part.ParentGroup.UUID;
10632 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11620 else
10633 list.Add(0); 11621 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 11622
10640 continue; //Can't find it, so add UUID.Zero 11623 linkNum = part.LinkNum;
10641 } 11624 }
10642 11625 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 { 11626 {
10649 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11627 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10650 { 11628 /// It it a boy? a girl?
10651 if (!checkPhysical) 11629 if (sp != null)
10652 continue; 11630 itemID = sp.UUID;
10653 }
10654 else
10655 {
10656 if (!checkNonPhysical)
10657 continue;
10658 }
10659 } 11631 }
10660 11632
10661 refcount++; 11633 list.Add(new LSL_String(itemID.ToString()));
10662 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11634 list.Add(new LSL_String(result.Pos.ToString()));
10663 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10664 else
10665 list.Add(entity.UUID);
10666 11635
10667 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11636 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10668 { 11637 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 11638
10675 list.Add(result.Pos);
10676 11639
10677 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11640 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10678 list.Add(result.Normal); 11641 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11642
11643 values++;
11644 count--;
11645
11646 if (count == 0)
11647 break;
10679 } 11648 }
10680 11649
10681 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11650 list.Add(new LSL_Integer(values));
10682 11651
10683 return list; 11652 return list;
10684 } 11653 }
@@ -10718,7 +11687,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10718 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11687 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10719 if (!isAccount) return 0; 11688 if (!isAccount) return 0;
10720 if (estate.HasAccess(id)) return 1; 11689 if (estate.HasAccess(id)) return 1;
10721 if (estate.IsBanned(id)) 11690 if (estate.IsBanned(id, World.GetUserFlags(id)))
10722 estate.RemoveBan(id); 11691 estate.RemoveBan(id);
10723 estate.AddEstateUser(id); 11692 estate.AddEstateUser(id);
10724 break; 11693 break;
@@ -10737,14 +11706,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10737 break; 11706 break;
10738 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11707 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10739 if (!isAccount) return 0; 11708 if (!isAccount) return 0;
10740 if (estate.IsBanned(id)) return 1; 11709 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10741 EstateBan ban = new EstateBan(); 11710 EstateBan ban = new EstateBan();
10742 ban.EstateID = estate.EstateID; 11711 ban.EstateID = estate.EstateID;
10743 ban.BannedUserID = id; 11712 ban.BannedUserID = id;
10744 estate.AddBan(ban); 11713 estate.AddBan(ban);
10745 break; 11714 break;
10746 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11715 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10747 if (!isAccount || !estate.IsBanned(id)) return 0; 11716 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10748 estate.RemoveBan(id); 11717 estate.RemoveBan(id);
10749 break; 11718 break;
10750 default: return 0; 11719 default: return 0;
@@ -10770,22 +11739,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10770 NotImplemented("llGetSPMaxMemory"); 11739 NotImplemented("llGetSPMaxMemory");
10771 } 11740 }
10772 11741
10773 public void llGetUsedMemory() 11742 public virtual LSL_Integer llGetUsedMemory()
10774 { 11743 {
10775 m_host.AddScriptLPS(1); 11744 m_host.AddScriptLPS(1);
10776 NotImplemented("llGetUsedMemory"); 11745 NotImplemented("llGetUsedMemory");
11746 return 0;
10777 } 11747 }
10778 11748
10779 public void llScriptProfiler(LSL_Integer flags) 11749 public void llScriptProfiler(LSL_Integer flags)
10780 { 11750 {
10781 m_host.AddScriptLPS(1); 11751 m_host.AddScriptLPS(1);
10782 NotImplemented("llScriptProfiler"); 11752 //NotImplemented("llScriptProfiler");
10783 } 11753 }
10784 11754
10785 public void llSetSoundQueueing(int queue) 11755 public void llSetSoundQueueing(int queue)
10786 { 11756 {
10787 m_host.AddScriptLPS(1); 11757 m_host.AddScriptLPS(1);
10788 NotImplemented("llSetSoundQueueing");
10789 } 11758 }
10790 11759
10791 public void llCollisionSprite(string impact_sprite) 11760 public void llCollisionSprite(string impact_sprite)
@@ -10797,7 +11766,133 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10797 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11766 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10798 { 11767 {
10799 m_host.AddScriptLPS(1); 11768 m_host.AddScriptLPS(1);
10800 NotImplemented("llGodLikeRezObject"); 11769
11770 if (!World.Permissions.IsGod(m_host.OwnerID))
11771 NotImplemented("llGodLikeRezObject");
11772
11773 AssetBase rezAsset = World.AssetService.Get(inventory);
11774 if (rezAsset == null)
11775 {
11776 llSay(0, "Asset not found");
11777 return;
11778 }
11779
11780 SceneObjectGroup group = null;
11781
11782 try
11783 {
11784 string xmlData = Utils.BytesToString(rezAsset.Data);
11785 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11786 }
11787 catch
11788 {
11789 llSay(0, "Asset not found");
11790 return;
11791 }
11792
11793 if (group == null)
11794 {
11795 llSay(0, "Asset not found");
11796 return;
11797 }
11798
11799 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11800 group.RootPart.AttachOffset = group.AbsolutePosition;
11801
11802 group.ResetIDs();
11803
11804 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11805 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11806 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11807 group.ScheduleGroupForFullUpdate();
11808
11809 // objects rezzed with this method are die_at_edge by default.
11810 group.RootPart.SetDieAtEdge(true);
11811
11812 group.ResumeScripts();
11813
11814 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11815 "object_rez", new Object[] {
11816 new LSL_String(
11817 group.RootPart.UUID.ToString()) },
11818 new DetectParams[0]));
11819 }
11820
11821 public LSL_String llTransferLindenDollars(string destination, int amount)
11822 {
11823 UUID txn = UUID.Random();
11824
11825 Util.FireAndForget(delegate(object x)
11826 {
11827 int replycode = 0;
11828 string replydata = destination + "," + amount.ToString();
11829
11830 try
11831 {
11832 UUID invItemID=InventorySelf();
11833 if (invItemID == UUID.Zero)
11834 {
11835 replydata = "SERVICE_ERROR";
11836 return;
11837 }
11838
11839 m_host.AddScriptLPS(1);
11840
11841 m_host.TaskInventory.LockItemsForRead(true);
11842 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11843 m_host.TaskInventory.LockItemsForRead(false);
11844
11845 if (item.PermsGranter == UUID.Zero)
11846 {
11847 replydata = "MISSING_PERMISSION_DEBIT";
11848 return;
11849 }
11850
11851 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11852 {
11853 replydata = "MISSING_PERMISSION_DEBIT";
11854 return;
11855 }
11856
11857 UUID toID = new UUID();
11858
11859 if (!UUID.TryParse(destination, out toID))
11860 {
11861 replydata = "INVALID_AGENT";
11862 return;
11863 }
11864
11865 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11866
11867 if (money == null)
11868 {
11869 replydata = "TRANSFERS_DISABLED";
11870 return;
11871 }
11872
11873 bool result = money.ObjectGiveMoney(
11874 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11875
11876 if (result)
11877 {
11878 replycode = 1;
11879 return;
11880 }
11881
11882 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11883 }
11884 finally
11885 {
11886 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11887 "transaction_result", new Object[] {
11888 new LSL_String(txn.ToString()),
11889 new LSL_Integer(replycode),
11890 new LSL_String(replydata) },
11891 new DetectParams[0]));
11892 }
11893 });
11894
11895 return txn.ToString();
10801 } 11896 }
10802 11897
10803 #endregion 11898 #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..9679798 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);
@@ -344,6 +346,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
344 void llSetParcelMusicURL(string url); 346 void llSetParcelMusicURL(string url);
345 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 347 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
346 void llSetPos(LSL_Vector pos); 348 void llSetPos(LSL_Vector pos);
349 LSL_Integer llSetRegionPos(LSL_Vector pos);
347 LSL_Integer llSetPrimMediaParams(int face, LSL_List rules); 350 LSL_Integer llSetPrimMediaParams(int face, LSL_List rules);
348 void llSetPrimitiveParams(LSL_List rules); 351 void llSetPrimitiveParams(LSL_List rules);
349 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 352 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -408,7 +411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
408 LSL_Vector llWind(LSL_Vector offset); 411 LSL_Vector llWind(LSL_Vector offset);
409 LSL_String llXorBase64Strings(string str1, string str2); 412 LSL_String llXorBase64Strings(string str1, string str2);
410 LSL_String llXorBase64StringsCorrect(string str1, string str2); 413 LSL_String llXorBase64StringsCorrect(string str1, string str2);
411 void print(string str); 414 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
412 415
413 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 416 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
414 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 417 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..dcaa3b4 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);
@@ -1563,6 +1580,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1563 m_LSL_Functions.llSetPos(pos); 1580 m_LSL_Functions.llSetPos(pos);
1564 } 1581 }
1565 1582
1583 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1584 {
1585 return m_LSL_Functions.llSetRegionPos(pos);
1586 }
1587
1566 public void llSetPrimitiveParams(LSL_List rules) 1588 public void llSetPrimitiveParams(LSL_List rules)
1567 { 1589 {
1568 m_LSL_Functions.llSetPrimitiveParams(rules); 1590 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1893,9 +1915,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1893 return m_LSL_Functions.llClearPrimMedia(face); 1915 return m_LSL_Functions.llClearPrimMedia(face);
1894 } 1916 }
1895 1917
1896 public void print(string str) 1918 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1897 { 1919 {
1898 m_LSL_Functions.print(str); 1920 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1899 } 1921 }
1900 } 1922 }
1901} 1923}
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 {