aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs118
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs2995
-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.cs1
-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, 2517 insertions, 1067 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 14edde4..57794f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -250,6 +250,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 250
251 } 251 }
252 252
253 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
254 {
255 // Remove a specific script
256
257 // Remove dataserver events
258 m_Dataserver[engine].RemoveEvents(localID, itemID);
259
260 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
261 if (comms != null)
262 comms.DeleteListener(itemID);
263
264 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
265 xmlrpc.DeleteChannels(itemID);
266 xmlrpc.CancelSRDRequests(itemID);
267
268 // Remove Sensors
269 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
270
271 }
272
253 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 273 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
254 { 274 {
255 List<Object> data = new List<Object>(); 275 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 0003515..8708b99 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,
@@ -6537,13 +6995,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6537 UUID av = new UUID(); 6995 UUID av = new UUID();
6538 if (!UUID.TryParse(avatar,out av)) 6996 if (!UUID.TryParse(avatar,out av))
6539 { 6997 {
6540 LSLError("First parameter to llDialog needs to be a key"); 6998 //LSLError("First parameter to llDialog needs to be a key");
6541 return; 6999 return;
6542 } 7000 }
6543 if (buttons.Length < 1) 7001 if (buttons.Length < 1)
6544 { 7002 {
6545 LSLError("No less than 1 button can be shown"); 7003 buttons.Add("OK");
6546 return;
6547 } 7004 }
6548 if (buttons.Length > 12) 7005 if (buttons.Length > 12)
6549 { 7006 {
@@ -6560,7 +7017,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6560 } 7017 }
6561 if (buttons.Data[i].ToString().Length > 24) 7018 if (buttons.Data[i].ToString().Length > 24)
6562 { 7019 {
6563 LSLError("button label cannot be longer than 24 characters"); 7020 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6564 return; 7021 return;
6565 } 7022 }
6566 buts[i] = buttons.Data[i].ToString(); 7023 buts[i] = buttons.Data[i].ToString();
@@ -6619,22 +7076,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6619 } 7076 }
6620 7077
6621 // copy the first script found with this inventory name 7078 // copy the first script found with this inventory name
6622 lock (m_host.TaskInventory) 7079 TaskInventoryItem scriptItem = null;
7080 m_host.TaskInventory.LockItemsForRead(true);
7081 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6623 { 7082 {
6624 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7083 if (inv.Value.Name == name)
6625 { 7084 {
6626 if (inv.Value.Name == name) 7085 // make sure the object is a script
7086 if (10 == inv.Value.Type)
6627 { 7087 {
6628 // make sure the object is a script 7088 found = true;
6629 if (10 == inv.Value.Type) 7089 srcId = inv.Key;
6630 { 7090 scriptItem = inv.Value;
6631 found = true; 7091 break;
6632 srcId = inv.Key;
6633 break;
6634 }
6635 } 7092 }
6636 } 7093 }
6637 } 7094 }
7095 m_host.TaskInventory.LockItemsForRead(false);
6638 7096
6639 if (!found) 7097 if (!found)
6640 { 7098 {
@@ -6642,9 +7100,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6642 return; 7100 return;
6643 } 7101 }
6644 7102
6645 // the rest of the permission checks are done in RezScript, so check the pin there as well 7103 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6646 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7104 if (dest != null)
7105 {
7106 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7107 {
7108 // the rest of the permission checks are done in RezScript, so check the pin there as well
7109 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6647 7110
7111 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7112 m_host.Inventory.RemoveInventoryItem(srcId);
7113 }
7114 }
6648 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7115 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6649 ScriptSleep(3000); 7116 ScriptSleep(3000);
6650 } 7117 }
@@ -6707,19 +7174,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6707 public LSL_String llMD5String(string src, int nonce) 7174 public LSL_String llMD5String(string src, int nonce)
6708 { 7175 {
6709 m_host.AddScriptLPS(1); 7176 m_host.AddScriptLPS(1);
6710 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7177 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6711 } 7178 }
6712 7179
6713 public LSL_String llSHA1String(string src) 7180 public LSL_String llSHA1String(string src)
6714 { 7181 {
6715 m_host.AddScriptLPS(1); 7182 m_host.AddScriptLPS(1);
6716 return Util.SHA1Hash(src).ToLower(); 7183 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6717 } 7184 }
6718 7185
6719 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7186 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6720 { 7187 {
6721 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7188 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6722 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7189 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7190 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7191 return shapeBlock;
6723 7192
6724 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7193 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6725 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7194 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6824,6 +7293,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6824 // Prim type box, cylinder and prism. 7293 // Prim type box, cylinder and prism.
6825 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) 7294 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)
6826 { 7295 {
7296 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7297 return;
7298
6827 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7299 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6828 ObjectShapePacket.ObjectDataBlock shapeBlock; 7300 ObjectShapePacket.ObjectDataBlock shapeBlock;
6829 7301
@@ -6877,6 +7349,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 // Prim type sphere. 7349 // Prim type sphere.
6878 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7350 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6879 { 7351 {
7352 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7353 return;
7354
6880 ObjectShapePacket.ObjectDataBlock shapeBlock; 7355 ObjectShapePacket.ObjectDataBlock shapeBlock;
6881 7356
6882 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7357 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6918,6 +7393,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6918 // Prim type torus, tube and ring. 7393 // Prim type torus, tube and ring.
6919 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) 7394 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)
6920 { 7395 {
7396 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7397 return;
7398
6921 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7399 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6922 ObjectShapePacket.ObjectDataBlock shapeBlock; 7400 ObjectShapePacket.ObjectDataBlock shapeBlock;
6923 7401
@@ -7053,6 +7531,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7053 // Prim type sculpt. 7531 // Prim type sculpt.
7054 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7532 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7055 { 7533 {
7534 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7535 return;
7536
7056 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7537 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7057 UUID sculptId; 7538 UUID sculptId;
7058 7539
@@ -7077,7 +7558,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7077 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7558 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7078 { 7559 {
7079 // default 7560 // default
7080 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7561 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7081 } 7562 }
7082 7563
7083 part.Shape.SetSculptProperties((byte)type, sculptId); 7564 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7093,32 +7574,119 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7093 ScriptSleep(200); 7574 ScriptSleep(200);
7094 } 7575 }
7095 7576
7096 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7577 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7097 { 7578 {
7098 m_host.AddScriptLPS(1); 7579 m_host.AddScriptLPS(1);
7099 7580
7100 setLinkPrimParams(linknumber, rules); 7581 setLinkPrimParams(linknumber, rules);
7101
7102 ScriptSleep(200);
7103 } 7582 }
7104 7583
7105 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7584 private void setLinkPrimParams(int linknumber, LSL_List rules)
7106 { 7585 {
7107 m_host.AddScriptLPS(1); 7586 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7587 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7588 if (parts.Count>0)
7589 {
7590 try
7591 {
7592 parts[0].ParentGroup.areUpdatesSuspended = true;
7593 foreach (SceneObjectPart part in parts)
7594 SetPrimParams(part, rules);
7595 }
7596 finally
7597 {
7598 parts[0].ParentGroup.areUpdatesSuspended = false;
7599 }
7600 }
7601 if (avatars.Count > 0)
7602 {
7603 foreach (ScenePresence avatar in avatars)
7604 SetPrimParams(avatar, rules);
7605 }
7606 }
7108 7607
7109 setLinkPrimParams(linknumber, rules); 7608 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7609 {
7610 llSetLinkPrimitiveParamsFast(linknumber, rules);
7611 ScriptSleep(200);
7110 } 7612 }
7111 7613
7112 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7614 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7113 { 7615 {
7114 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7616 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7617 //We only support PRIM_POSITION and PRIM_ROTATION
7115 7618
7116 foreach (SceneObjectPart part in parts) 7619 int idx = 0;
7117 SetPrimParams(part, rules); 7620
7621 while (idx < rules.Length)
7622 {
7623 int code = rules.GetLSLIntegerItem(idx++);
7624
7625 int remain = rules.Length - idx;
7626
7627 switch (code)
7628 {
7629 case (int)ScriptBaseClass.PRIM_POSITION:
7630 {
7631 if (remain < 1)
7632 return;
7633 LSL_Vector v;
7634 v = rules.GetVector3Item(idx++);
7635
7636 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7637 if (part == null)
7638 break;
7639
7640 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7641 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7642 if (llGetLinkNumber() > 1)
7643 {
7644 localRot = llGetLocalRot();
7645 localPos = llGetLocalPos();
7646 }
7647
7648 v -= localPos;
7649 v /= localRot;
7650
7651 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7652
7653 v = v + 2 * sitOffset;
7654
7655 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7656 av.SendAvatarDataToAllAgents();
7657
7658 }
7659 break;
7660
7661 case (int)ScriptBaseClass.PRIM_ROTATION:
7662 {
7663 if (remain < 1)
7664 return;
7665
7666 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7667 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7668 if (llGetLinkNumber() > 1)
7669 {
7670 localRot = llGetLocalRot();
7671 localPos = llGetLocalPos();
7672 }
7673
7674 LSL_Rotation r;
7675 r = rules.GetQuaternionItem(idx++);
7676 r = r * llGetRootRotation() / localRot;
7677 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7678 av.SendAvatarDataToAllAgents();
7679 }
7680 break;
7681 }
7682 }
7118 } 7683 }
7119 7684
7120 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7685 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7121 { 7686 {
7687 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7688 return;
7689
7122 int idx = 0; 7690 int idx = 0;
7123 7691
7124 bool positionChanged = false; 7692 bool positionChanged = false;
@@ -7146,6 +7714,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7146 currentPosition = GetSetPosTarget(part, v, currentPosition); 7714 currentPosition = GetSetPosTarget(part, v, currentPosition);
7147 7715
7148 break; 7716 break;
7717 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7718 if (remain < 1)
7719 return;
7720
7721 v=rules.GetVector3Item(idx++);
7722 positionChanged = true;
7723 currentPosition = GetSetPosTarget(part, v, currentPosition);
7724
7725 break;
7149 case (int)ScriptBaseClass.PRIM_SIZE: 7726 case (int)ScriptBaseClass.PRIM_SIZE:
7150 if (remain < 1) 7727 if (remain < 1)
7151 return; 7728 return;
@@ -7512,7 +8089,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7512 if (part.ParentGroup.RootPart == part) 8089 if (part.ParentGroup.RootPart == part)
7513 { 8090 {
7514 SceneObjectGroup parent = part.ParentGroup; 8091 SceneObjectGroup parent = part.ParentGroup;
7515 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8092 Util.FireAndForget(delegate(object x) {
8093 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8094 });
7516 } 8095 }
7517 else 8096 else
7518 { 8097 {
@@ -7523,6 +8102,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7523 } 8102 }
7524 } 8103 }
7525 } 8104 }
8105
8106 if (positionChanged)
8107 {
8108 if (part.ParentGroup.RootPart == part)
8109 {
8110 SceneObjectGroup parent = part.ParentGroup;
8111 Util.FireAndForget(delegate(object x) {
8112 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8113 });
8114 }
8115 else
8116 {
8117 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8118 SceneObjectGroup parent = part.ParentGroup;
8119 parent.HasGroupChanged = true;
8120 parent.ScheduleGroupForTerseUpdate();
8121 }
8122 }
7526 } 8123 }
7527 8124
7528 public LSL_String llStringToBase64(string str) 8125 public LSL_String llStringToBase64(string str)
@@ -7683,13 +8280,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7683 public LSL_Integer llGetNumberOfPrims() 8280 public LSL_Integer llGetNumberOfPrims()
7684 { 8281 {
7685 m_host.AddScriptLPS(1); 8282 m_host.AddScriptLPS(1);
7686 int avatarCount = 0; 8283 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7687 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8284
7688 {
7689 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7690 avatarCount++;
7691 });
7692
7693 return m_host.ParentGroup.PrimCount + avatarCount; 8285 return m_host.ParentGroup.PrimCount + avatarCount;
7694 } 8286 }
7695 8287
@@ -7705,55 +8297,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7705 m_host.AddScriptLPS(1); 8297 m_host.AddScriptLPS(1);
7706 UUID objID = UUID.Zero; 8298 UUID objID = UUID.Zero;
7707 LSL_List result = new LSL_List(); 8299 LSL_List result = new LSL_List();
8300
8301 // If the ID is not valid, return null result
7708 if (!UUID.TryParse(obj, out objID)) 8302 if (!UUID.TryParse(obj, out objID))
7709 { 8303 {
7710 result.Add(new LSL_Vector()); 8304 result.Add(new LSL_Vector());
7711 result.Add(new LSL_Vector()); 8305 result.Add(new LSL_Vector());
7712 return result; 8306 return result;
7713 } 8307 }
8308
8309 // Check if this is an attached prim. If so, replace
8310 // the UUID with the avatar UUID and report it's bounding box
8311 SceneObjectPart part = World.GetSceneObjectPart(objID);
8312 if (part != null && part.ParentGroup.IsAttachment)
8313 objID = part.ParentGroup.AttachedAvatar;
8314
8315 // Find out if this is an avatar ID. If so, return it's box
7714 ScenePresence presence = World.GetScenePresence(objID); 8316 ScenePresence presence = World.GetScenePresence(objID);
7715 if (presence != null) 8317 if (presence != null)
7716 { 8318 {
7717 if (presence.ParentID == 0) // not sat on an object 8319 // As per LSL Wiki, there is no difference between sitting
8320 // and standing avatar since server 1.36
8321 LSL_Vector lower;
8322 LSL_Vector upper;
8323 if (presence.Animator.Animations.DefaultAnimation.AnimID
8324 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7718 { 8325 {
7719 LSL_Vector lower; 8326 // This is for ground sitting avatars
7720 LSL_Vector upper; 8327 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7721 if (presence.Animator.Animations.DefaultAnimation.AnimID 8328 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7722 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8329 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7723 {
7724 // This is for ground sitting avatars
7725 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7726 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7727 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7728 }
7729 else
7730 {
7731 // This is for standing/flying avatars
7732 float height = presence.Appearance.AvatarHeight / 2.0f;
7733 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7734 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7735 }
7736 result.Add(lower);
7737 result.Add(upper);
7738 return result;
7739 } 8330 }
7740 else 8331 else
7741 { 8332 {
7742 // sitting on an object so we need the bounding box of that 8333 // This is for standing/flying avatars
7743 // which should include the avatar so set the UUID to the 8334 float height = presence.Appearance.AvatarHeight / 2.0f;
7744 // UUID of the object the avatar is sat on and allow it to fall through 8335 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7745 // to processing an object 8336 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7746 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7747 objID = p.UUID;
7748 } 8337 }
8338
8339 // Adjust to the documented error offsets (see LSL Wiki)
8340 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8341 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8342
8343 if (lower.x > upper.x)
8344 lower.x = upper.x;
8345 if (lower.y > upper.y)
8346 lower.y = upper.y;
8347 if (lower.z > upper.z)
8348 lower.z = upper.z;
8349
8350 result.Add(lower);
8351 result.Add(upper);
8352 return result;
7749 } 8353 }
7750 SceneObjectPart part = World.GetSceneObjectPart(objID); 8354
8355 part = World.GetSceneObjectPart(objID);
7751 // Currently only works for single prims without a sitting avatar 8356 // Currently only works for single prims without a sitting avatar
7752 if (part != null) 8357 if (part != null)
7753 { 8358 {
7754 Vector3 halfSize = part.Scale / 2.0f; 8359 float minX;
7755 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8360 float maxX;
7756 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8361 float minY;
8362 float maxY;
8363 float minZ;
8364 float maxZ;
8365
8366 // This BBox is in sim coordinates, with the offset being
8367 // a contained point.
8368 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8369 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8370
8371 minX -= offsets[0].X;
8372 maxX -= offsets[0].X;
8373 minY -= offsets[0].Y;
8374 maxY -= offsets[0].Y;
8375 minZ -= offsets[0].Z;
8376 maxZ -= offsets[0].Z;
8377
8378 LSL_Vector lower;
8379 LSL_Vector upper;
8380
8381 // Adjust to the documented error offsets (see LSL Wiki)
8382 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8383 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8384
8385 if (lower.x > upper.x)
8386 lower.x = upper.x;
8387 if (lower.y > upper.y)
8388 lower.y = upper.y;
8389 if (lower.z > upper.z)
8390 lower.z = upper.z;
8391
7757 result.Add(lower); 8392 result.Add(lower);
7758 result.Add(upper); 8393 result.Add(upper);
7759 return result; 8394 return result;
@@ -7833,13 +8468,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7833 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8468 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7834 part.AbsolutePosition.Y, 8469 part.AbsolutePosition.Y,
7835 part.AbsolutePosition.Z); 8470 part.AbsolutePosition.Z);
7836 // For some reason, the part.AbsolutePosition.* values do not change if the
7837 // linkset is rotated; they always reflect the child prim's world position
7838 // as though the linkset is unrotated. This is incompatible behavior with SL's
7839 // implementation, so will break scripts imported from there (not to mention it
7840 // makes it more difficult to determine a child prim's actual inworld position).
7841 if (part.ParentID != 0)
7842 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7843 res.Add(v); 8471 res.Add(v);
7844 break; 8472 break;
7845 8473
@@ -8010,56 +8638,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8010 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8638 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8011 if (remain < 1) 8639 if (remain < 1)
8012 return res; 8640 return res;
8013 8641 face = (int)rules.GetLSLIntegerItem(idx++);
8014 face=(int)rules.GetLSLIntegerItem(idx++);
8015 8642
8016 tex = part.Shape.Textures; 8643 tex = part.Shape.Textures;
8644 int shiny;
8017 if (face == ScriptBaseClass.ALL_SIDES) 8645 if (face == ScriptBaseClass.ALL_SIDES)
8018 { 8646 {
8019 for (face = 0; face < GetNumberOfSides(part); face++) 8647 for (face = 0; face < GetNumberOfSides(part); face++)
8020 { 8648 {
8021 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8649 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8022 // Convert Shininess to PRIM_SHINY_* 8650 if (shinyness == Shininess.High)
8023 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8651 {
8024 // PRIM_BUMP_* 8652 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8025 res.Add(new LSL_Integer((int)texface.Bump)); 8653 }
8654 else if (shinyness == Shininess.Medium)
8655 {
8656 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8657 }
8658 else if (shinyness == Shininess.Low)
8659 {
8660 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8661 }
8662 else
8663 {
8664 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8665 }
8666 res.Add(new LSL_Integer(shiny));
8667 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8026 } 8668 }
8027 } 8669 }
8028 else 8670 else
8029 { 8671 {
8030 if (face >= 0 && face < GetNumberOfSides(part)) 8672 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8673 if (shinyness == Shininess.High)
8031 { 8674 {
8032 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8675 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8033 // Convert Shininess to PRIM_SHINY_*
8034 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8035 // PRIM_BUMP_*
8036 res.Add(new LSL_Integer((int)texface.Bump));
8037 } 8676 }
8677 else if (shinyness == Shininess.Medium)
8678 {
8679 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8680 }
8681 else if (shinyness == Shininess.Low)
8682 {
8683 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8684 }
8685 else
8686 {
8687 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8688 }
8689 res.Add(new LSL_Integer(shiny));
8690 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8038 } 8691 }
8039 break; 8692 break;
8040 8693
8041 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8694 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8042 if (remain < 1) 8695 if (remain < 1)
8043 return res; 8696 return res;
8044 8697 face = (int)rules.GetLSLIntegerItem(idx++);
8045 face=(int)rules.GetLSLIntegerItem(idx++);
8046 8698
8047 tex = part.Shape.Textures; 8699 tex = part.Shape.Textures;
8700 int fullbright;
8048 if (face == ScriptBaseClass.ALL_SIDES) 8701 if (face == ScriptBaseClass.ALL_SIDES)
8049 { 8702 {
8050 for (face = 0; face < GetNumberOfSides(part); face++) 8703 for (face = 0; face < GetNumberOfSides(part); face++)
8051 { 8704 {
8052 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8705 if (tex.GetFace((uint)face).Fullbright == true)
8053 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8706 {
8707 fullbright = ScriptBaseClass.TRUE;
8708 }
8709 else
8710 {
8711 fullbright = ScriptBaseClass.FALSE;
8712 }
8713 res.Add(new LSL_Integer(fullbright));
8054 } 8714 }
8055 } 8715 }
8056 else 8716 else
8057 { 8717 {
8058 if (face >= 0 && face < GetNumberOfSides(part)) 8718 if (tex.GetFace((uint)face).Fullbright == true)
8059 { 8719 {
8060 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8720 fullbright = ScriptBaseClass.TRUE;
8061 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8721 }
8722 else
8723 {
8724 fullbright = ScriptBaseClass.FALSE;
8062 } 8725 }
8726 res.Add(new LSL_Integer(fullbright));
8063 } 8727 }
8064 break; 8728 break;
8065 8729
@@ -8081,27 +8745,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8081 break; 8745 break;
8082 8746
8083 case (int)ScriptBaseClass.PRIM_TEXGEN: 8747 case (int)ScriptBaseClass.PRIM_TEXGEN:
8748 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8084 if (remain < 1) 8749 if (remain < 1)
8085 return res; 8750 return res;
8086 8751 face = (int)rules.GetLSLIntegerItem(idx++);
8087 face=(int)rules.GetLSLIntegerItem(idx++);
8088 8752
8089 tex = part.Shape.Textures; 8753 tex = part.Shape.Textures;
8090 if (face == ScriptBaseClass.ALL_SIDES) 8754 if (face == ScriptBaseClass.ALL_SIDES)
8091 { 8755 {
8092 for (face = 0; face < GetNumberOfSides(part); face++) 8756 for (face = 0; face < GetNumberOfSides(part); face++)
8093 { 8757 {
8094 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8758 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8095 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8759 {
8096 res.Add(new LSL_Integer((uint)texgen >> 1)); 8760 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8761 }
8762 else
8763 {
8764 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8765 }
8097 } 8766 }
8098 } 8767 }
8099 else 8768 else
8100 { 8769 {
8101 if (face >= 0 && face < GetNumberOfSides(part)) 8770 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8102 { 8771 {
8103 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8772 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8104 res.Add(new LSL_Integer((uint)texgen >> 1)); 8773 }
8774 else
8775 {
8776 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8105 } 8777 }
8106 } 8778 }
8107 break; 8779 break;
@@ -8124,28 +8796,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8124 case (int)ScriptBaseClass.PRIM_GLOW: 8796 case (int)ScriptBaseClass.PRIM_GLOW:
8125 if (remain < 1) 8797 if (remain < 1)
8126 return res; 8798 return res;
8127 8799 face = (int)rules.GetLSLIntegerItem(idx++);
8128 face=(int)rules.GetLSLIntegerItem(idx++);
8129 8800
8130 tex = part.Shape.Textures; 8801 tex = part.Shape.Textures;
8802 float primglow;
8131 if (face == ScriptBaseClass.ALL_SIDES) 8803 if (face == ScriptBaseClass.ALL_SIDES)
8132 { 8804 {
8133 for (face = 0; face < GetNumberOfSides(part); face++) 8805 for (face = 0; face < GetNumberOfSides(part); face++)
8134 { 8806 {
8135 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8807 primglow = tex.GetFace((uint)face).Glow;
8136 res.Add(new LSL_Float(texface.Glow)); 8808 res.Add(new LSL_Float(primglow));
8137 } 8809 }
8138 } 8810 }
8139 else 8811 else
8140 { 8812 {
8141 if (face >= 0 && face < GetNumberOfSides(part)) 8813 primglow = tex.GetFace((uint)face).Glow;
8142 { 8814 res.Add(new LSL_Float(primglow));
8143 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8144 res.Add(new LSL_Float(texface.Glow));
8145 }
8146 } 8815 }
8147 break; 8816 break;
8148
8149 case (int)ScriptBaseClass.PRIM_TEXT: 8817 case (int)ScriptBaseClass.PRIM_TEXT:
8150 Color4 textColor = part.GetTextColor(); 8818 Color4 textColor = part.GetTextColor();
8151 res.Add(new LSL_String(part.Text)); 8819 res.Add(new LSL_String(part.Text));
@@ -8757,8 +9425,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8757 // The function returns an ordered list 9425 // The function returns an ordered list
8758 // representing the tokens found in the supplied 9426 // representing the tokens found in the supplied
8759 // sources string. If two successive tokenizers 9427 // sources string. If two successive tokenizers
8760 // are encountered, then a NULL entry is added 9428 // are encountered, then a null-string entry is
8761 // to the list. 9429 // added to the list.
8762 // 9430 //
8763 // It is a precondition that the source and 9431 // It is a precondition that the source and
8764 // toekizer lisst are non-null. If they are null, 9432 // toekizer lisst are non-null. If they are null,
@@ -8766,7 +9434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8766 // while their lengths are being determined. 9434 // while their lengths are being determined.
8767 // 9435 //
8768 // A small amount of working memoryis required 9436 // A small amount of working memoryis required
8769 // of approximately 8*#tokenizers. 9437 // of approximately 8*#tokenizers + 8*srcstrlen.
8770 // 9438 //
8771 // There are many ways in which this function 9439 // There are many ways in which this function
8772 // can be implemented, this implementation is 9440 // can be implemented, this implementation is
@@ -8782,155 +9450,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8782 // and eliminates redundant tokenizers as soon 9450 // and eliminates redundant tokenizers as soon
8783 // as is possible. 9451 // as is possible.
8784 // 9452 //
8785 // The implementation tries to avoid any copying 9453 // The implementation tries to minimize temporary
8786 // of arrays or other objects. 9454 // garbage generation.
8787 // </remarks> 9455 // </remarks>
8788 9456
8789 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9457 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8790 { 9458 {
8791 int beginning = 0; 9459 return ParseString2List(src, separators, spacers, true);
8792 int srclen = src.Length; 9460 }
8793 int seplen = separators.Length;
8794 object[] separray = separators.Data;
8795 int spclen = spacers.Length;
8796 object[] spcarray = spacers.Data;
8797 int mlen = seplen+spclen;
8798
8799 int[] offset = new int[mlen+1];
8800 bool[] active = new bool[mlen];
8801
8802 int best;
8803 int j;
8804
8805 // Initial capacity reduces resize cost
8806 9461
8807 LSL_List tokens = new LSL_List(); 9462 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9463 {
9464 int srclen = src.Length;
9465 int seplen = separators.Length;
9466 object[] separray = separators.Data;
9467 int spclen = spacers.Length;
9468 object[] spcarray = spacers.Data;
9469 int dellen = 0;
9470 string[] delarray = new string[seplen+spclen];
8808 9471
8809 // All entries are initially valid 9472 int outlen = 0;
9473 string[] outarray = new string[srclen*2+1];
8810 9474
8811 for (int i = 0; i < mlen; i++) 9475 int i, j;
8812 active[i] = true; 9476 string d;
8813 9477
8814 offset[mlen] = srclen; 9478 m_host.AddScriptLPS(1);
8815 9479
8816 while (beginning < srclen) 9480 /*
9481 * Convert separator and spacer lists to C# strings.
9482 * Also filter out null strings so we don't hang.
9483 */
9484 for (i = 0; i < seplen; i ++)
8817 { 9485 {
9486 d = separray[i].ToString();
9487 if (d.Length > 0)
9488 {
9489 delarray[dellen++] = d;
9490 }
9491 }
9492 seplen = dellen;
8818 9493
8819 best = mlen; // as bad as it gets 9494 for (i = 0; i < spclen; i ++)
9495 {
9496 d = spcarray[i].ToString();
9497 if (d.Length > 0)
9498 {
9499 delarray[dellen++] = d;
9500 }
9501 }
8820 9502
8821 // Scan for separators 9503 /*
9504 * Scan through source string from beginning to end.
9505 */
9506 for (i = 0;;)
9507 {
8822 9508
8823 for (j = 0; j < seplen; j++) 9509 /*
9510 * Find earliest delimeter in src starting at i (if any).
9511 */
9512 int earliestDel = -1;
9513 int earliestSrc = srclen;
9514 string earliestStr = null;
9515 for (j = 0; j < dellen; j ++)
8824 { 9516 {
8825 if (separray[j].ToString() == String.Empty) 9517 d = delarray[j];
8826 active[j] = false; 9518 if (d != null)
8827
8828 if (active[j])
8829 { 9519 {
8830 // scan all of the markers 9520 int index = src.IndexOf(d, i);
8831 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9521 if (index < 0)
8832 { 9522 {
8833 // not present at all 9523 delarray[j] = null; // delim nowhere in src, don't check it anymore
8834 active[j] = false;
8835 } 9524 }
8836 else 9525 else if (index < earliestSrc)
8837 { 9526 {
8838 // present and correct 9527 earliestSrc = index; // where delimeter starts in source string
8839 if (offset[j] < offset[best]) 9528 earliestDel = j; // where delimeter is in delarray[]
8840 { 9529 earliestStr = d; // the delimeter string from delarray[]
8841 // closest so far 9530 if (index == i) break; // can't do any better than found at beg of string
8842 best = j;
8843 if (offset[best] == beginning)
8844 break;
8845 }
8846 } 9531 }
8847 } 9532 }
8848 } 9533 }
8849 9534
8850 // Scan for spacers 9535 /*
8851 9536 * Output source string starting at i through start of earliest delimeter.
8852 if (offset[best] != beginning) 9537 */
9538 if (keepNulls || (earliestSrc > i))
8853 { 9539 {
8854 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9540 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8855 {
8856 if (spcarray[j-seplen].ToString() == String.Empty)
8857 active[j] = false;
8858
8859 if (active[j])
8860 {
8861 // scan all of the markers
8862 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8863 {
8864 // not present at all
8865 active[j] = false;
8866 }
8867 else
8868 {
8869 // present and correct
8870 if (offset[j] < offset[best])
8871 {
8872 // closest so far
8873 best = j;
8874 }
8875 }
8876 }
8877 }
8878 } 9541 }
8879 9542
8880 // This is the normal exit from the scanning loop 9543 /*
9544 * If no delimeter found at or after i, we're done scanning.
9545 */
9546 if (earliestDel < 0) break;
8881 9547
8882 if (best == mlen) 9548 /*
9549 * If delimeter was a spacer, output the spacer.
9550 */
9551 if (earliestDel >= seplen)
8883 { 9552 {
8884 // no markers were found on this pass 9553 outarray[outlen++] = earliestStr;
8885 // so we're pretty much done
8886 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8887 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8888 break;
8889 } 9554 }
8890 9555
8891 // Otherwise we just add the newly delimited token 9556 /*
8892 // and recalculate where the search should continue. 9557 * Look at rest of src string following delimeter.
8893 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9558 */
8894 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9559 i = earliestSrc + earliestStr.Length;
8895
8896 if (best < seplen)
8897 {
8898 beginning = offset[best] + (separray[best].ToString()).Length;
8899 }
8900 else
8901 {
8902 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8903 string str = spcarray[best - seplen].ToString();
8904 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8905 tokens.Add(new LSL_String(str));
8906 }
8907 } 9560 }
8908 9561
8909 // This an awkward an not very intuitive boundary case. If the 9562 /*
8910 // last substring is a tokenizer, then there is an implied trailing 9563 * Make up an exact-sized output array suitable for an LSL_List object.
8911 // null list entry. Hopefully the single comparison will not be too 9564 */
8912 // arduous. Alternatively the 'break' could be replced with a return 9565 object[] outlist = new object[outlen];
8913 // but that's shabby programming. 9566 for (i = 0; i < outlen; i ++)
8914
8915 if ((beginning == srclen) && (keepNulls))
8916 { 9567 {
8917 if (srclen != 0) 9568 outlist[i] = new LSL_String(outarray[i]);
8918 tokens.Add(new LSL_String(""));
8919 } 9569 }
8920 9570 return new LSL_List(outlist);
8921 return tokens;
8922 }
8923
8924 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8925 {
8926 m_host.AddScriptLPS(1);
8927 return this.ParseString(src, separators, spacers, false);
8928 }
8929
8930 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8931 {
8932 m_host.AddScriptLPS(1);
8933 return this.ParseString(src, separators, spacers, true);
8934 } 9571 }
8935 9572
8936 public LSL_Integer llGetObjectPermMask(int mask) 9573 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9007,28 +9644,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9007 { 9644 {
9008 m_host.AddScriptLPS(1); 9645 m_host.AddScriptLPS(1);
9009 9646
9010 lock (m_host.TaskInventory) 9647 m_host.TaskInventory.LockItemsForRead(true);
9648 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9011 { 9649 {
9012 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9650 if (inv.Value.Name == item)
9013 { 9651 {
9014 if (inv.Value.Name == item) 9652 m_host.TaskInventory.LockItemsForRead(false);
9653 switch (mask)
9015 { 9654 {
9016 switch (mask) 9655 case 0:
9017 { 9656 return (int)inv.Value.BasePermissions;
9018 case 0: 9657 case 1:
9019 return (int)inv.Value.BasePermissions; 9658 return (int)inv.Value.CurrentPermissions;
9020 case 1: 9659 case 2:
9021 return (int)inv.Value.CurrentPermissions; 9660 return (int)inv.Value.GroupPermissions;
9022 case 2: 9661 case 3:
9023 return (int)inv.Value.GroupPermissions; 9662 return (int)inv.Value.EveryonePermissions;
9024 case 3: 9663 case 4:
9025 return (int)inv.Value.EveryonePermissions; 9664 return (int)inv.Value.NextPermissions;
9026 case 4:
9027 return (int)inv.Value.NextPermissions;
9028 }
9029 } 9665 }
9030 } 9666 }
9031 } 9667 }
9668 m_host.TaskInventory.LockItemsForRead(false);
9032 9669
9033 return -1; 9670 return -1;
9034 } 9671 }
@@ -9075,16 +9712,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9075 { 9712 {
9076 m_host.AddScriptLPS(1); 9713 m_host.AddScriptLPS(1);
9077 9714
9078 lock (m_host.TaskInventory) 9715 m_host.TaskInventory.LockItemsForRead(true);
9716 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9079 { 9717 {
9080 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9718 if (inv.Value.Name == item)
9081 { 9719 {
9082 if (inv.Value.Name == item) 9720 m_host.TaskInventory.LockItemsForRead(false);
9083 { 9721 return inv.Value.CreatorID.ToString();
9084 return inv.Value.CreatorID.ToString();
9085 }
9086 } 9722 }
9087 } 9723 }
9724 m_host.TaskInventory.LockItemsForRead(false);
9088 9725
9089 llSay(0, "No item name '" + item + "'"); 9726 llSay(0, "No item name '" + item + "'");
9090 9727
@@ -9232,7 +9869,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9232 } 9869 }
9233 9870
9234 /// <summary> 9871 /// <summary>
9235 /// illListReplaceList removes the sub-list defined by the inclusive indices 9872 /// llListReplaceList removes the sub-list defined by the inclusive indices
9236 /// start and end and inserts the src list in its place. The inclusive 9873 /// start and end and inserts the src list in its place. The inclusive
9237 /// nature of the indices means that at least one element must be deleted 9874 /// nature of the indices means that at least one element must be deleted
9238 /// if the indices are within the bounds of the existing list. I.e. 2,2 9875 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9289,16 +9926,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9289 // based upon end. Note that if end exceeds the upper 9926 // based upon end. Note that if end exceeds the upper
9290 // bound in this case, the entire destination list 9927 // bound in this case, the entire destination list
9291 // is removed. 9928 // is removed.
9292 else 9929 else if (start == 0)
9293 { 9930 {
9294 if (end + 1 < dest.Length) 9931 if (end + 1 < dest.Length)
9295 {
9296 return src + dest.GetSublist(end + 1, -1); 9932 return src + dest.GetSublist(end + 1, -1);
9297 }
9298 else 9933 else
9299 {
9300 return src; 9934 return src;
9301 } 9935 }
9936 else // Start < 0
9937 {
9938 if (end + 1 < dest.Length)
9939 return dest.GetSublist(end + 1, -1);
9940 else
9941 return new LSL_List();
9302 } 9942 }
9303 } 9943 }
9304 // Finally, if start > end, we strip away a prefix and 9944 // Finally, if start > end, we strip away a prefix and
@@ -9349,17 +9989,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9349 int width = 0; 9989 int width = 0;
9350 int height = 0; 9990 int height = 0;
9351 9991
9352 ParcelMediaCommandEnum? commandToSend = null; 9992 uint commandToSend = 0;
9353 float time = 0.0f; // default is from start 9993 float time = 0.0f; // default is from start
9354 9994
9355 ScenePresence presence = null; 9995 ScenePresence presence = null;
9356 9996
9357 for (int i = 0; i < commandList.Data.Length; i++) 9997 for (int i = 0; i < commandList.Data.Length; i++)
9358 { 9998 {
9359 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9999 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9360 switch (command) 10000 switch (command)
9361 { 10001 {
9362 case ParcelMediaCommandEnum.Agent: 10002 case (uint)ParcelMediaCommandEnum.Agent:
9363 // we send only to one agent 10003 // we send only to one agent
9364 if ((i + 1) < commandList.Length) 10004 if ((i + 1) < commandList.Length)
9365 { 10005 {
@@ -9376,25 +10016,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9376 } 10016 }
9377 break; 10017 break;
9378 10018
9379 case ParcelMediaCommandEnum.Loop: 10019 case (uint)ParcelMediaCommandEnum.Loop:
9380 loop = 1; 10020 loop = 1;
9381 commandToSend = command; 10021 commandToSend = command;
9382 update = true; //need to send the media update packet to set looping 10022 update = true; //need to send the media update packet to set looping
9383 break; 10023 break;
9384 10024
9385 case ParcelMediaCommandEnum.Play: 10025 case (uint)ParcelMediaCommandEnum.Play:
9386 loop = 0; 10026 loop = 0;
9387 commandToSend = command; 10027 commandToSend = command;
9388 update = true; //need to send the media update packet to make sure it doesn't loop 10028 update = true; //need to send the media update packet to make sure it doesn't loop
9389 break; 10029 break;
9390 10030
9391 case ParcelMediaCommandEnum.Pause: 10031 case (uint)ParcelMediaCommandEnum.Pause:
9392 case ParcelMediaCommandEnum.Stop: 10032 case (uint)ParcelMediaCommandEnum.Stop:
9393 case ParcelMediaCommandEnum.Unload: 10033 case (uint)ParcelMediaCommandEnum.Unload:
9394 commandToSend = command; 10034 commandToSend = command;
9395 break; 10035 break;
9396 10036
9397 case ParcelMediaCommandEnum.Url: 10037 case (uint)ParcelMediaCommandEnum.Url:
9398 if ((i + 1) < commandList.Length) 10038 if ((i + 1) < commandList.Length)
9399 { 10039 {
9400 if (commandList.Data[i + 1] is LSL_String) 10040 if (commandList.Data[i + 1] is LSL_String)
@@ -9407,7 +10047,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9407 } 10047 }
9408 break; 10048 break;
9409 10049
9410 case ParcelMediaCommandEnum.Texture: 10050 case (uint)ParcelMediaCommandEnum.Texture:
9411 if ((i + 1) < commandList.Length) 10051 if ((i + 1) < commandList.Length)
9412 { 10052 {
9413 if (commandList.Data[i + 1] is LSL_String) 10053 if (commandList.Data[i + 1] is LSL_String)
@@ -9420,7 +10060,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9420 } 10060 }
9421 break; 10061 break;
9422 10062
9423 case ParcelMediaCommandEnum.Time: 10063 case (uint)ParcelMediaCommandEnum.Time:
9424 if ((i + 1) < commandList.Length) 10064 if ((i + 1) < commandList.Length)
9425 { 10065 {
9426 if (commandList.Data[i + 1] is LSL_Float) 10066 if (commandList.Data[i + 1] is LSL_Float)
@@ -9432,7 +10072,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9432 } 10072 }
9433 break; 10073 break;
9434 10074
9435 case ParcelMediaCommandEnum.AutoAlign: 10075 case (uint)ParcelMediaCommandEnum.AutoAlign:
9436 if ((i + 1) < commandList.Length) 10076 if ((i + 1) < commandList.Length)
9437 { 10077 {
9438 if (commandList.Data[i + 1] is LSL_Integer) 10078 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9446,7 +10086,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9446 } 10086 }
9447 break; 10087 break;
9448 10088
9449 case ParcelMediaCommandEnum.Type: 10089 case (uint)ParcelMediaCommandEnum.Type:
9450 if ((i + 1) < commandList.Length) 10090 if ((i + 1) < commandList.Length)
9451 { 10091 {
9452 if (commandList.Data[i + 1] is LSL_String) 10092 if (commandList.Data[i + 1] is LSL_String)
@@ -9459,7 +10099,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9459 } 10099 }
9460 break; 10100 break;
9461 10101
9462 case ParcelMediaCommandEnum.Desc: 10102 case (uint)ParcelMediaCommandEnum.Desc:
9463 if ((i + 1) < commandList.Length) 10103 if ((i + 1) < commandList.Length)
9464 { 10104 {
9465 if (commandList.Data[i + 1] is LSL_String) 10105 if (commandList.Data[i + 1] is LSL_String)
@@ -9472,7 +10112,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9472 } 10112 }
9473 break; 10113 break;
9474 10114
9475 case ParcelMediaCommandEnum.Size: 10115 case (uint)ParcelMediaCommandEnum.Size:
9476 if ((i + 2) < commandList.Length) 10116 if ((i + 2) < commandList.Length)
9477 { 10117 {
9478 if (commandList.Data[i + 1] is LSL_Integer) 10118 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9542,7 +10182,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9542 } 10182 }
9543 } 10183 }
9544 10184
9545 if (commandToSend != null) 10185 if (commandToSend != 0)
9546 { 10186 {
9547 // the commandList contained a start/stop/... command, too 10187 // the commandList contained a start/stop/... command, too
9548 if (presence == null) 10188 if (presence == null)
@@ -9579,7 +10219,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9579 10219
9580 if (aList.Data[i] != null) 10220 if (aList.Data[i] != null)
9581 { 10221 {
9582 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10222 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9583 { 10223 {
9584 case ParcelMediaCommandEnum.Url: 10224 case ParcelMediaCommandEnum.Url:
9585 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10225 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9622,16 +10262,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9622 { 10262 {
9623 m_host.AddScriptLPS(1); 10263 m_host.AddScriptLPS(1);
9624 10264
9625 lock (m_host.TaskInventory) 10265 m_host.TaskInventory.LockItemsForRead(true);
10266 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9626 { 10267 {
9627 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10268 if (inv.Value.Name == name)
9628 { 10269 {
9629 if (inv.Value.Name == name) 10270 m_host.TaskInventory.LockItemsForRead(false);
9630 { 10271 return inv.Value.Type;
9631 return inv.Value.Type;
9632 }
9633 } 10272 }
9634 } 10273 }
10274 m_host.TaskInventory.LockItemsForRead(false);
9635 10275
9636 return -1; 10276 return -1;
9637 } 10277 }
@@ -9642,15 +10282,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9642 10282
9643 if (quick_pay_buttons.Data.Length < 4) 10283 if (quick_pay_buttons.Data.Length < 4)
9644 { 10284 {
9645 LSLError("List must have at least 4 elements"); 10285 int x;
9646 return; 10286 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10287 {
10288 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10289 }
9647 } 10290 }
9648 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10291 int[] nPrice = new int[5];
9649 10292 nPrice[0] = price;
9650 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10293 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9651 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10294 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9652 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10295 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9653 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10296 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10297 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9654 m_host.ParentGroup.HasGroupChanged = true; 10298 m_host.ParentGroup.HasGroupChanged = true;
9655 } 10299 }
9656 10300
@@ -9662,17 +10306,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9662 if (invItemID == UUID.Zero) 10306 if (invItemID == UUID.Zero)
9663 return new LSL_Vector(); 10307 return new LSL_Vector();
9664 10308
9665 lock (m_host.TaskInventory) 10309 m_host.TaskInventory.LockItemsForRead(true);
10310 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9666 { 10311 {
9667 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10312 m_host.TaskInventory.LockItemsForRead(false);
9668 return new LSL_Vector(); 10313 return new LSL_Vector();
10314 }
9669 10315
9670 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10316 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9671 { 10317 {
9672 ShoutError("No permissions to track the camera"); 10318 ShoutError("No permissions to track the camera");
9673 return new LSL_Vector(); 10319 m_host.TaskInventory.LockItemsForRead(false);
9674 } 10320 return new LSL_Vector();
9675 } 10321 }
10322 m_host.TaskInventory.LockItemsForRead(false);
9676 10323
9677 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10324 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9678 if (presence != null) 10325 if (presence != null)
@@ -9690,17 +10337,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9690 if (invItemID == UUID.Zero) 10337 if (invItemID == UUID.Zero)
9691 return new LSL_Rotation(); 10338 return new LSL_Rotation();
9692 10339
9693 lock (m_host.TaskInventory) 10340 m_host.TaskInventory.LockItemsForRead(true);
10341 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9694 { 10342 {
9695 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10343 m_host.TaskInventory.LockItemsForRead(false);
9696 return new LSL_Rotation(); 10344 return new LSL_Rotation();
9697 10345 }
9698 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10346 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9699 { 10347 {
9700 ShoutError("No permissions to track the camera"); 10348 ShoutError("No permissions to track the camera");
9701 return new LSL_Rotation(); 10349 m_host.TaskInventory.LockItemsForRead(false);
9702 } 10350 return new LSL_Rotation();
9703 } 10351 }
10352 m_host.TaskInventory.LockItemsForRead(false);
9704 10353
9705 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10354 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9706 if (presence != null) 10355 if (presence != null)
@@ -9762,8 +10411,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9762 { 10411 {
9763 m_host.AddScriptLPS(1); 10412 m_host.AddScriptLPS(1);
9764 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10413 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9765 if (detectedParams == null) return; // only works on the first detected avatar 10414 if (detectedParams == null)
9766 10415 {
10416 if (m_host.ParentGroup.IsAttachment == true)
10417 {
10418 detectedParams = new DetectParams();
10419 detectedParams.Key = m_host.OwnerID;
10420 }
10421 else
10422 {
10423 return;
10424 }
10425 }
10426
9767 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10427 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9768 if (avatar != null) 10428 if (avatar != null)
9769 { 10429 {
@@ -9771,6 +10431,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9771 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10431 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9772 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10432 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9773 } 10433 }
10434
9774 ScriptSleep(1000); 10435 ScriptSleep(1000);
9775 } 10436 }
9776 10437
@@ -9882,14 +10543,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9882 if (objectID == UUID.Zero) return; 10543 if (objectID == UUID.Zero) return;
9883 10544
9884 UUID agentID; 10545 UUID agentID;
9885 lock (m_host.TaskInventory) 10546 m_host.TaskInventory.LockItemsForRead(true);
9886 { 10547 // we need the permission first, to know which avatar we want to set the camera for
9887 // we need the permission first, to know which avatar we want to set the camera for 10548 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9888 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9889 10549
9890 if (agentID == UUID.Zero) return; 10550 if (agentID == UUID.Zero)
9891 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10551 {
10552 m_host.TaskInventory.LockItemsForRead(false);
10553 return;
9892 } 10554 }
10555 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10556 {
10557 m_host.TaskInventory.LockItemsForRead(false);
10558 return;
10559 }
10560 m_host.TaskInventory.LockItemsForRead(false);
9893 10561
9894 ScenePresence presence = World.GetScenePresence(agentID); 10562 ScenePresence presence = World.GetScenePresence(agentID);
9895 10563
@@ -9898,12 +10566,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9898 10566
9899 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10567 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9900 object[] data = rules.Data; 10568 object[] data = rules.Data;
9901 for (int i = 0; i < data.Length; ++i) { 10569 for (int i = 0; i < data.Length; ++i)
10570 {
9902 int type = Convert.ToInt32(data[i++].ToString()); 10571 int type = Convert.ToInt32(data[i++].ToString());
9903 if (i >= data.Length) break; // odd number of entries => ignore the last 10572 if (i >= data.Length) break; // odd number of entries => ignore the last
9904 10573
9905 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10574 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9906 switch (type) { 10575 switch (type)
10576 {
9907 case ScriptBaseClass.CAMERA_FOCUS: 10577 case ScriptBaseClass.CAMERA_FOCUS:
9908 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10578 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9909 case ScriptBaseClass.CAMERA_POSITION: 10579 case ScriptBaseClass.CAMERA_POSITION:
@@ -9939,12 +10609,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9939 10609
9940 // we need the permission first, to know which avatar we want to clear the camera for 10610 // we need the permission first, to know which avatar we want to clear the camera for
9941 UUID agentID; 10611 UUID agentID;
9942 lock (m_host.TaskInventory) 10612 m_host.TaskInventory.LockItemsForRead(true);
10613 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10614 if (agentID == UUID.Zero)
9943 { 10615 {
9944 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10616 m_host.TaskInventory.LockItemsForRead(false);
9945 if (agentID == UUID.Zero) return; 10617 return;
9946 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10618 }
10619 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10620 {
10621 m_host.TaskInventory.LockItemsForRead(false);
10622 return;
9947 } 10623 }
10624 m_host.TaskInventory.LockItemsForRead(false);
9948 10625
9949 ScenePresence presence = World.GetScenePresence(agentID); 10626 ScenePresence presence = World.GetScenePresence(agentID);
9950 10627
@@ -10011,19 +10688,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10011 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10688 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10012 { 10689 {
10013 m_host.AddScriptLPS(1); 10690 m_host.AddScriptLPS(1);
10014 string ret = String.Empty; 10691
10015 string src1 = llBase64ToString(str1); 10692 if (str1 == String.Empty)
10016 string src2 = llBase64ToString(str2); 10693 return String.Empty;
10017 int c = 0; 10694 if (str2 == String.Empty)
10018 for (int i = 0; i < src1.Length; i++) 10695 return str1;
10696
10697 int len = str2.Length;
10698 if ((len % 4) != 0) // LL is EVIL!!!!
10699 {
10700 while (str2.EndsWith("="))
10701 str2 = str2.Substring(0, str2.Length - 1);
10702
10703 len = str2.Length;
10704 int mod = len % 4;
10705
10706 if (mod == 1)
10707 str2 = str2.Substring(0, str2.Length - 1);
10708 else if (mod == 2)
10709 str2 += "==";
10710 else if (mod == 3)
10711 str2 += "=";
10712 }
10713
10714 byte[] data1;
10715 byte[] data2;
10716 try
10717 {
10718 data1 = Convert.FromBase64String(str1);
10719 data2 = Convert.FromBase64String(str2);
10720 }
10721 catch (Exception)
10019 { 10722 {
10020 ret += (char) (src1[i] ^ src2[c]); 10723 return new LSL_String(String.Empty);
10724 }
10021 10725
10022 c++; 10726 byte[] d2 = new Byte[data1.Length];
10023 if (c >= src2.Length) 10727 int pos = 0;
10024 c = 0; 10728
10729 if (data1.Length <= data2.Length)
10730 {
10731 Array.Copy(data2, 0, d2, 0, data1.Length);
10025 } 10732 }
10026 return llStringToBase64(ret); 10733 else
10734 {
10735 while (pos < data1.Length)
10736 {
10737 len = data1.Length - pos;
10738 if (len > data2.Length)
10739 len = data2.Length;
10740
10741 Array.Copy(data2, 0, d2, pos, len);
10742 pos += len;
10743 }
10744 }
10745
10746 for (pos = 0 ; pos < data1.Length ; pos++ )
10747 data1[pos] ^= d2[pos];
10748
10749 return Convert.ToBase64String(data1);
10027 } 10750 }
10028 10751
10029 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10752 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10080,12 +10803,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10080 Regex r = new Regex(authregex); 10803 Regex r = new Regex(authregex);
10081 int[] gnums = r.GetGroupNumbers(); 10804 int[] gnums = r.GetGroupNumbers();
10082 Match m = r.Match(url); 10805 Match m = r.Match(url);
10083 if (m.Success) { 10806 if (m.Success)
10084 for (int i = 1; i < gnums.Length; i++) { 10807 {
10808 for (int i = 1; i < gnums.Length; i++)
10809 {
10085 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10810 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10086 //CaptureCollection cc = g.Captures; 10811 //CaptureCollection cc = g.Captures;
10087 } 10812 }
10088 if (m.Groups.Count == 5) { 10813 if (m.Groups.Count == 5)
10814 {
10089 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10815 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10090 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10816 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10091 } 10817 }
@@ -10371,15 +11097,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10371 11097
10372 internal UUID ScriptByName(string name) 11098 internal UUID ScriptByName(string name)
10373 { 11099 {
10374 lock (m_host.TaskInventory) 11100 m_host.TaskInventory.LockItemsForRead(true);
11101
11102 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10375 { 11103 {
10376 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11104 if (item.Type == 10 && item.Name == name)
10377 { 11105 {
10378 if (item.Type == 10 && item.Name == name) 11106 m_host.TaskInventory.LockItemsForRead(false);
10379 return item.ItemID; 11107 return item.ItemID;
10380 } 11108 }
10381 } 11109 }
10382 11110
11111 m_host.TaskInventory.LockItemsForRead(false);
11112
10383 return UUID.Zero; 11113 return UUID.Zero;
10384 } 11114 }
10385 11115
@@ -10420,6 +11150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10420 { 11150 {
10421 m_host.AddScriptLPS(1); 11151 m_host.AddScriptLPS(1);
10422 11152
11153 //Clone is thread safe
10423 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11154 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10424 11155
10425 UUID assetID = UUID.Zero; 11156 UUID assetID = UUID.Zero;
@@ -10482,6 +11213,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10482 { 11213 {
10483 m_host.AddScriptLPS(1); 11214 m_host.AddScriptLPS(1);
10484 11215
11216 //Clone is thread safe
10485 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11217 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10486 11218
10487 UUID assetID = UUID.Zero; 11219 UUID assetID = UUID.Zero;
@@ -10562,15 +11294,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10562 return GetLinkPrimitiveParams(obj, rules); 11294 return GetLinkPrimitiveParams(obj, rules);
10563 } 11295 }
10564 11296
10565 public void print(string str) 11297 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10566 { 11298 {
10567 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11299 List<SceneObjectPart> parts = GetLinkParts(link);
10568 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11300 if (parts.Count < 1)
10569 if (ossl != null) 11301 return 0;
10570 { 11302
10571 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11303 return GetNumberOfSides(parts[0]);
10572 m_log.Info("LSL print():" + str);
10573 }
10574 } 11304 }
10575 11305
10576 private string Name2Username(string name) 11306 private string Name2Username(string name)
@@ -10616,153 +11346,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10616 return rq.ToString(); 11346 return rq.ToString();
10617 } 11347 }
10618 11348
11349 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11350 {
11351 m_SayShoutCount = 0;
11352 }
11353
11354 private struct Tri
11355 {
11356 public Vector3 p1;
11357 public Vector3 p2;
11358 public Vector3 p3;
11359 }
11360
11361 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11362 {
11363 float height = avatar.Appearance.AvatarHeight;
11364 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11365 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11366
11367 if (point.X > b1.X && point.X < b2.X &&
11368 point.Y > b1.Y && point.Y < b2.Y &&
11369 point.Z > b1.Z && point.Z < b2.Z)
11370 return true;
11371 return false;
11372 }
11373
11374 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11375 {
11376 List<ContactResult> contacts = new List<ContactResult>();
11377
11378 Vector3 ab = rayEnd - rayStart;
11379
11380 World.ForEachScenePresence(delegate(ScenePresence sp)
11381 {
11382 Vector3 ac = sp.AbsolutePosition - rayStart;
11383 Vector3 bc = sp.AbsolutePosition - rayEnd;
11384
11385 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11386
11387 if (d > 1.5)
11388 return;
11389
11390 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11391
11392 if (d2 > 0)
11393 return;
11394
11395 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11396 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11397
11398 if (!InBoundingBox(sp, p))
11399 return;
11400
11401 ContactResult result = new ContactResult ();
11402 result.ConsumerID = sp.LocalId;
11403 result.Depth = Vector3.Distance(rayStart, p);
11404 result.Normal = Vector3.Zero;
11405 result.Pos = p;
11406
11407 contacts.Add(result);
11408 });
11409
11410 return contacts.ToArray();
11411 }
11412
11413 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11414 {
11415 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11416 List<ContactResult> contacts = new List<ContactResult>();
11417
11418 Vector3 ab = rayEnd - rayStart;
11419
11420 World.ForEachSOG(delegate(SceneObjectGroup group)
11421 {
11422 if (m_host.ParentGroup == group)
11423 return;
11424
11425 if (group.IsAttachment)
11426 return;
11427
11428 if (group.RootPart.PhysActor == null)
11429 {
11430 if (!includePhantom)
11431 return;
11432 }
11433 else
11434 {
11435 if (group.RootPart.PhysActor.IsPhysical)
11436 {
11437 if (!includePhysical)
11438 return;
11439 }
11440 else
11441 {
11442 if (!includeNonPhysical)
11443 return;
11444 }
11445 }
11446
11447 // Find the radius ouside of which we don't even need to hit test
11448 float minX;
11449 float maxX;
11450 float minY;
11451 float maxY;
11452 float minZ;
11453 float maxZ;
11454
11455 float radius = 0.0f;
11456
11457 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11458
11459 if (Math.Abs(minX) > radius)
11460 radius = Math.Abs(minX);
11461 if (Math.Abs(minY) > radius)
11462 radius = Math.Abs(minY);
11463 if (Math.Abs(minZ) > radius)
11464 radius = Math.Abs(minZ);
11465 if (Math.Abs(maxX) > radius)
11466 radius = Math.Abs(maxX);
11467 if (Math.Abs(maxY) > radius)
11468 radius = Math.Abs(maxY);
11469 if (Math.Abs(maxZ) > radius)
11470 radius = Math.Abs(maxZ);
11471
11472 Vector3 ac = group.AbsolutePosition - rayStart;
11473 Vector3 bc = group.AbsolutePosition - rayEnd;
11474
11475 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11476
11477 // Too far off ray, don't bother
11478 if (d > radius)
11479 return;
11480
11481 // Behind ray, drop
11482 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11483 if (d2 > 0)
11484 return;
11485
11486 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11487 // Miss.
11488 if (!intersection.HitTF)
11489 return;
11490
11491 ContactResult result = new ContactResult ();
11492 result.ConsumerID = group.LocalId;
11493 result.Depth = intersection.distance;
11494 result.Normal = intersection.normal;
11495 result.Pos = intersection.ipoint;
11496
11497 contacts.Add(result);
11498 });
11499
11500 return contacts.ToArray();
11501 }
11502
11503 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11504 {
11505 double[,] heightfield = World.Heightmap.GetDoubles();
11506 List<ContactResult> contacts = new List<ContactResult>();
11507
11508 double min = 2048.0;
11509 double max = 0.0;
11510
11511 // Find the min and max of the heightfield
11512 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11513 {
11514 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11515 {
11516 if (heightfield[x, y] > max)
11517 max = heightfield[x, y];
11518 if (heightfield[x, y] < min)
11519 min = heightfield[x, y];
11520 }
11521 }
11522
11523
11524 // A ray extends past rayEnd, but doesn't go back before
11525 // rayStart. If the start is above the highest point of the ground
11526 // and the ray goes up, we can't hit the ground. Ever.
11527 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11528 return null;
11529
11530 // Same for going down
11531 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11532 return null;
11533
11534 List<Tri> trilist = new List<Tri>();
11535
11536 // Create our triangle list
11537 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11538 {
11539 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11540 {
11541 Tri t1 = new Tri();
11542 Tri t2 = new Tri();
11543
11544 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11545 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11546 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11547 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11548
11549 t1.p1 = p1;
11550 t1.p2 = p2;
11551 t1.p3 = p3;
11552
11553 t2.p1 = p3;
11554 t2.p2 = p4;
11555 t2.p3 = p1;
11556
11557 trilist.Add(t1);
11558 trilist.Add(t2);
11559 }
11560 }
11561
11562 // Ray direction
11563 Vector3 rayDirection = rayEnd - rayStart;
11564
11565 foreach (Tri t in trilist)
11566 {
11567 // Compute triangle plane normal and edges
11568 Vector3 u = t.p2 - t.p1;
11569 Vector3 v = t.p3 - t.p1;
11570 Vector3 n = Vector3.Cross(u, v);
11571
11572 if (n == Vector3.Zero)
11573 continue;
11574
11575 Vector3 w0 = rayStart - t.p1;
11576 double a = -Vector3.Dot(n, w0);
11577 double b = Vector3.Dot(n, rayDirection);
11578
11579 // Not intersecting the plane, or in plane (same thing)
11580 // Ignoring this MAY cause the ground to not be detected
11581 // sometimes
11582 if (Math.Abs(b) < 0.000001)
11583 continue;
11584
11585 double r = a / b;
11586
11587 // ray points away from plane
11588 if (r < 0.0)
11589 continue;
11590
11591 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11592
11593 float uu = Vector3.Dot(u, u);
11594 float uv = Vector3.Dot(u, v);
11595 float vv = Vector3.Dot(v, v);
11596 Vector3 w = ip - t.p1;
11597 float wu = Vector3.Dot(w, u);
11598 float wv = Vector3.Dot(w, v);
11599 float d = uv * uv - uu * vv;
11600
11601 float cs = (uv * wv - vv * wu) / d;
11602 if (cs < 0 || cs > 1.0)
11603 continue;
11604 float ct = (uv * wu - uu * wv) / d;
11605 if (ct < 0 || (cs + ct) > 1.0)
11606 continue;
11607
11608 // Add contact point
11609 ContactResult result = new ContactResult ();
11610 result.ConsumerID = 0;
11611 result.Depth = Vector3.Distance(rayStart, ip);
11612 result.Normal = n;
11613 result.Pos = ip;
11614
11615 contacts.Add(result);
11616 }
11617
11618 if (contacts.Count == 0)
11619 return null;
11620
11621 contacts.Sort(delegate(ContactResult a, ContactResult b)
11622 {
11623 return (int)(a.Depth - b.Depth);
11624 });
11625
11626 return contacts[0];
11627 }
11628
10619 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11629 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10620 { 11630 {
11631 LSL_List list = new LSL_List();
11632
10621 m_host.AddScriptLPS(1); 11633 m_host.AddScriptLPS(1);
10622 11634
10623 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11635 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10624 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11636 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10625 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11637 Vector3 dir = rayEnd - rayStart;
10626 11638
10627 int count = 0; 11639 int count = 1;
10628// int detectPhantom = 0; 11640 bool detectPhantom = false;
10629 int dataFlags = 0; 11641 int dataFlags = 0;
10630 int rejectTypes = 0; 11642 int rejectTypes = 0;
10631 11643
10632 for (int i = 0; i < options.Length; i += 2) 11644 for (int i = 0; i < options.Length; i += 2)
10633 { 11645 {
10634 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11646 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10635 {
10636 count = options.GetLSLIntegerItem(i + 1); 11647 count = options.GetLSLIntegerItem(i + 1);
10637 } 11648 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10638// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11649 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10639// {
10640// detectPhantom = options.GetLSLIntegerItem(i + 1);
10641// }
10642 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11650 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10643 {
10644 dataFlags = options.GetLSLIntegerItem(i + 1); 11651 dataFlags = options.GetLSLIntegerItem(i + 1);
10645 }
10646 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11652 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10647 {
10648 rejectTypes = options.GetLSLIntegerItem(i + 1); 11653 rejectTypes = options.GetLSLIntegerItem(i + 1);
10649 }
10650 } 11654 }
10651 11655
10652 LSL_List list = new LSL_List(); 11656 if (count > 16)
10653 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11657 count = 16;
10654
10655 double distance = Util.GetDistanceTo(startvector, endvector);
10656 11658
10657 if (distance == 0) 11659 List<ContactResult> results = new List<ContactResult>();
10658 distance = 0.001;
10659
10660 Vector3 posToCheck = startvector;
10661 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10662 11660
10663 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11661 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10664 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11662 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10665 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11663 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10666 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11664 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10667 11665
10668 for (float i = 0; i <= distance; i += 0.1f) 11666 if (checkTerrain)
10669 { 11667 {
10670 posToCheck = startvector + (dir * (i / (float)distance)); 11668 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11669 if (groundContact != null)
11670 results.Add((ContactResult)groundContact);
11671 }
10671 11672
10672 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11673 if (checkAgents)
10673 { 11674 {
10674 ContactResult result = new ContactResult(); 11675 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10675 result.ConsumerID = 0; 11676 foreach (ContactResult r in agentHits)
10676 result.Depth = 0; 11677 results.Add(r);
10677 result.Normal = Vector3.Zero; 11678 }
10678 result.Pos = posToCheck;
10679 results.Add(result);
10680 checkTerrain = false;
10681 }
10682 11679
10683 if (checkAgents) 11680 if (checkPhysical || checkNonPhysical)
10684 { 11681 {
10685 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11682 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10686 { 11683 foreach (ContactResult r in objectHits)
10687 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11684 results.Add(r);
10688 {
10689 ContactResult result = new ContactResult ();
10690 result.ConsumerID = sp.LocalId;
10691 result.Depth = 0;
10692 result.Normal = Vector3.Zero;
10693 result.Pos = posToCheck;
10694 results.Add(result);
10695 }
10696 });
10697 }
10698 } 11685 }
10699 11686
10700 int refcount = 0; 11687 results.Sort(delegate(ContactResult a, ContactResult b)
11688 {
11689 return (int)(a.Depth - b.Depth);
11690 });
11691
11692 int values = 0;
10701 foreach (ContactResult result in results) 11693 foreach (ContactResult result in results)
10702 { 11694 {
10703 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11695 UUID itemID = UUID.Zero;
10704 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11696 int linkNum = 0;
10705 continue;
10706
10707 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
10708
10709 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
10710 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
10711 11697
10712 if (entity == null) 11698 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11699 // It's a prim!
11700 if (part != null)
10713 { 11701 {
10714 list.Add(UUID.Zero); 11702 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10715 11703 itemID = part.ParentGroup.UUID;
10716 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11704 else
10717 list.Add(0); 11705 itemID = part.UUID;
10718
10719 list.Add(result.Pos);
10720
10721 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10722 list.Add(result.Normal);
10723 11706
10724 continue; //Can't find it, so add UUID.Zero 11707 linkNum = part.LinkNum;
10725 } 11708 }
10726 11709 else
10727 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10728 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10729 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10730
10731 if (entity is SceneObjectPart)
10732 { 11710 {
10733 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11711 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10734 { 11712 /// It it a boy? a girl?
10735 if (!checkPhysical) 11713 if (sp != null)
10736 continue; 11714 itemID = sp.UUID;
10737 }
10738 else
10739 {
10740 if (!checkNonPhysical)
10741 continue;
10742 }
10743 } 11715 }
10744 11716
10745 refcount++; 11717 list.Add(new LSL_String(itemID.ToString()));
10746 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11718 list.Add(new LSL_String(result.Pos.ToString()));
10747 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10748 else
10749 list.Add(entity.UUID);
10750 11719
10751 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11720 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10752 { 11721 list.Add(new LSL_Integer(linkNum));
10753 if (entity is SceneObjectPart)
10754 list.Add(((SceneObjectPart)entity).LinkNum);
10755 else
10756 list.Add(0);
10757 }
10758 11722
10759 list.Add(result.Pos);
10760 11723
10761 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11724 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10762 list.Add(result.Normal); 11725 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11726
11727 values++;
11728 count--;
11729
11730 if (count == 0)
11731 break;
10763 } 11732 }
10764 11733
10765 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11734 list.Add(new LSL_Integer(values));
10766 11735
10767 return list; 11736 return list;
10768 } 11737 }
@@ -10802,7 +11771,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10802 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11771 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10803 if (!isAccount) return 0; 11772 if (!isAccount) return 0;
10804 if (estate.HasAccess(id)) return 1; 11773 if (estate.HasAccess(id)) return 1;
10805 if (estate.IsBanned(id)) 11774 if (estate.IsBanned(id, World.GetUserFlags(id)))
10806 estate.RemoveBan(id); 11775 estate.RemoveBan(id);
10807 estate.AddEstateUser(id); 11776 estate.AddEstateUser(id);
10808 break; 11777 break;
@@ -10821,14 +11790,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10821 break; 11790 break;
10822 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11791 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10823 if (!isAccount) return 0; 11792 if (!isAccount) return 0;
10824 if (estate.IsBanned(id)) return 1; 11793 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10825 EstateBan ban = new EstateBan(); 11794 EstateBan ban = new EstateBan();
10826 ban.EstateID = estate.EstateID; 11795 ban.EstateID = estate.EstateID;
10827 ban.BannedUserID = id; 11796 ban.BannedUserID = id;
10828 estate.AddBan(ban); 11797 estate.AddBan(ban);
10829 break; 11798 break;
10830 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11799 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10831 if (!isAccount || !estate.IsBanned(id)) return 0; 11800 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10832 estate.RemoveBan(id); 11801 estate.RemoveBan(id);
10833 break; 11802 break;
10834 default: return 0; 11803 default: return 0;
@@ -10854,22 +11823,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10854 NotImplemented("llGetSPMaxMemory"); 11823 NotImplemented("llGetSPMaxMemory");
10855 } 11824 }
10856 11825
10857 public void llGetUsedMemory() 11826 public virtual LSL_Integer llGetUsedMemory()
10858 { 11827 {
10859 m_host.AddScriptLPS(1); 11828 m_host.AddScriptLPS(1);
10860 NotImplemented("llGetUsedMemory"); 11829 NotImplemented("llGetUsedMemory");
11830 return 0;
10861 } 11831 }
10862 11832
10863 public void llScriptProfiler(LSL_Integer flags) 11833 public void llScriptProfiler(LSL_Integer flags)
10864 { 11834 {
10865 m_host.AddScriptLPS(1); 11835 m_host.AddScriptLPS(1);
10866 NotImplemented("llScriptProfiler"); 11836 //NotImplemented("llScriptProfiler");
10867 } 11837 }
10868 11838
10869 public void llSetSoundQueueing(int queue) 11839 public void llSetSoundQueueing(int queue)
10870 { 11840 {
10871 m_host.AddScriptLPS(1); 11841 m_host.AddScriptLPS(1);
10872 NotImplemented("llSetSoundQueueing");
10873 } 11842 }
10874 11843
10875 public void llCollisionSprite(string impact_sprite) 11844 public void llCollisionSprite(string impact_sprite)
@@ -10881,7 +11850,133 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10881 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11850 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10882 { 11851 {
10883 m_host.AddScriptLPS(1); 11852 m_host.AddScriptLPS(1);
10884 NotImplemented("llGodLikeRezObject"); 11853
11854 if (!World.Permissions.IsGod(m_host.OwnerID))
11855 NotImplemented("llGodLikeRezObject");
11856
11857 AssetBase rezAsset = World.AssetService.Get(inventory);
11858 if (rezAsset == null)
11859 {
11860 llSay(0, "Asset not found");
11861 return;
11862 }
11863
11864 SceneObjectGroup group = null;
11865
11866 try
11867 {
11868 string xmlData = Utils.BytesToString(rezAsset.Data);
11869 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11870 }
11871 catch
11872 {
11873 llSay(0, "Asset not found");
11874 return;
11875 }
11876
11877 if (group == null)
11878 {
11879 llSay(0, "Asset not found");
11880 return;
11881 }
11882
11883 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11884 group.RootPart.AttachOffset = group.AbsolutePosition;
11885
11886 group.ResetIDs();
11887
11888 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11889 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11890 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11891 group.ScheduleGroupForFullUpdate();
11892
11893 // objects rezzed with this method are die_at_edge by default.
11894 group.RootPart.SetDieAtEdge(true);
11895
11896 group.ResumeScripts();
11897
11898 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11899 "object_rez", new Object[] {
11900 new LSL_String(
11901 group.RootPart.UUID.ToString()) },
11902 new DetectParams[0]));
11903 }
11904
11905 public LSL_String llTransferLindenDollars(string destination, int amount)
11906 {
11907 UUID txn = UUID.Random();
11908
11909 Util.FireAndForget(delegate(object x)
11910 {
11911 int replycode = 0;
11912 string replydata = destination + "," + amount.ToString();
11913
11914 try
11915 {
11916 UUID invItemID=InventorySelf();
11917 if (invItemID == UUID.Zero)
11918 {
11919 replydata = "SERVICE_ERROR";
11920 return;
11921 }
11922
11923 m_host.AddScriptLPS(1);
11924
11925 m_host.TaskInventory.LockItemsForRead(true);
11926 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11927 m_host.TaskInventory.LockItemsForRead(false);
11928
11929 if (item.PermsGranter == UUID.Zero)
11930 {
11931 replydata = "MISSING_PERMISSION_DEBIT";
11932 return;
11933 }
11934
11935 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11936 {
11937 replydata = "MISSING_PERMISSION_DEBIT";
11938 return;
11939 }
11940
11941 UUID toID = new UUID();
11942
11943 if (!UUID.TryParse(destination, out toID))
11944 {
11945 replydata = "INVALID_AGENT";
11946 return;
11947 }
11948
11949 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11950
11951 if (money == null)
11952 {
11953 replydata = "TRANSFERS_DISABLED";
11954 return;
11955 }
11956
11957 bool result = money.ObjectGiveMoney(
11958 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11959
11960 if (result)
11961 {
11962 replycode = 1;
11963 return;
11964 }
11965
11966 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11967 }
11968 finally
11969 {
11970 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11971 "transaction_result", new Object[] {
11972 new LSL_String(txn.ToString()),
11973 new LSL_Integer(replycode),
11974 new LSL_String(replydata) },
11975 new DetectParams[0]));
11976 }
11977 });
11978
11979 return txn.ToString();
10885 } 11980 }
10886 11981
10887 #endregion 11982 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 8edd146..44fd980 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)
@@ -2258,7 +2267,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2258 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2267 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2259 m_host.AddScriptLPS(1); 2268 m_host.AddScriptLPS(1);
2260 2269
2261 return NpcCreate(firstname, lastname, position, notecard, false, false); 2270 return NpcCreate(firstname, lastname, position, notecard, true, false);
2262 } 2271 }
2263 2272
2264 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2273 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2269,24 +2278,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2269 return NpcCreate( 2278 return NpcCreate(
2270 firstname, lastname, position, notecard, 2279 firstname, lastname, position, notecard,
2271 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2280 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2272 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2281 false);
2282// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2273 } 2283 }
2274 2284
2275 private LSL_Key NpcCreate( 2285 private LSL_Key NpcCreate(
2276 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2286 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2277 { 2287 {
2288 if (!owned)
2289 OSSLError("Unowned NPCs are unsupported");
2290
2291 string groupTitle = String.Empty;
2292
2293 if (firstname != String.Empty || lastname != String.Empty)
2294 {
2295 if (firstname != "Shown outfit:")
2296 groupTitle = "- NPC -";
2297 }
2298
2278 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2299 INPCModule module = World.RequestModuleInterface<INPCModule>();
2279 if (module != null) 2300 if (module != null)
2280 { 2301 {
2281 AvatarAppearance appearance = null; 2302 AvatarAppearance appearance = null;
2282 2303
2283 UUID id; 2304// UUID id;
2284 if (UUID.TryParse(notecard, out id)) 2305// if (UUID.TryParse(notecard, out id))
2285 { 2306// {
2286 ScenePresence clonePresence = World.GetScenePresence(id); 2307// ScenePresence clonePresence = World.GetScenePresence(id);
2287 if (clonePresence != null) 2308// if (clonePresence != null)
2288 appearance = clonePresence.Appearance; 2309// appearance = clonePresence.Appearance;
2289 } 2310// }
2290 2311
2291 if (appearance == null) 2312 if (appearance == null)
2292 { 2313 {
@@ -2314,6 +2335,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2314 World, 2335 World,
2315 appearance); 2336 appearance);
2316 2337
2338 ScenePresence sp;
2339 if (World.TryGetScenePresence(x, out sp))
2340 {
2341 sp.Grouptitle = groupTitle;
2342 sp.SendAvatarDataToAllAgents();
2343 }
2317 return new LSL_Key(x.ToString()); 2344 return new LSL_Key(x.ToString());
2318 } 2345 }
2319 2346
@@ -2582,16 +2609,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2582 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2609 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2583 m_host.AddScriptLPS(1); 2610 m_host.AddScriptLPS(1);
2584 2611
2585 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2612 ManualResetEvent ev = new ManualResetEvent(false);
2586 if (module != null)
2587 {
2588 UUID npcId = new UUID(npc.m_string);
2589 2613
2590 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2614 Util.FireAndForget(delegate(object x) {
2591 return; 2615 try
2616 {
2617 INPCModule module = World.RequestModuleInterface<INPCModule>();
2618 if (module != null)
2619 {
2620 UUID npcId = new UUID(npc.m_string);
2592 2621
2593 module.DeleteNPC(npcId, World); 2622 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2594 } 2623 return;
2624
2625 module.DeleteNPC(npcId, World);
2626 }
2627 }
2628 finally
2629 {
2630 ev.Set();
2631 }
2632 });
2633 ev.WaitOne();
2595 } 2634 }
2596 2635
2597 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2636 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -2944,4 +2983,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2944 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ"); 2983 return date.ToString("yyyy-MM-ddTHH:mm:ss.fffffffZ");
2945 } 2984 }
2946 } 2985 }
2947} \ No newline at end of file 2986}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index fbb7c39..e25255c 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 0f53bc3..55444dc 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -124,6 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
124 LSL_Float llGetEnergy(); 124 LSL_Float llGetEnergy();
125 LSL_Vector llGetForce(); 125 LSL_Vector llGetForce();
126 LSL_Integer llGetFreeMemory(); 126 LSL_Integer llGetFreeMemory();
127 LSL_Integer llGetUsedMemory();
127 LSL_Integer llGetFreeURLs(); 128 LSL_Integer llGetFreeURLs();
128 LSL_Vector llGetGeometricCenter(); 129 LSL_Vector llGetGeometricCenter();
129 LSL_Float llGetGMTclock(); 130 LSL_Float llGetGMTclock();
@@ -203,6 +204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
203 void llGiveInventory(string destination, string inventory); 204 void llGiveInventory(string destination, string inventory);
204 void llGiveInventoryList(string destination, string category, LSL_List inventory); 205 void llGiveInventoryList(string destination, string category, LSL_List inventory);
205 LSL_Integer llGiveMoney(string destination, int amount); 206 LSL_Integer llGiveMoney(string destination, int amount);
207 LSL_String llTransferLindenDollars(string destination, int amount);
206 void llGodLikeRezObject(string inventory, LSL_Vector pos); 208 void llGodLikeRezObject(string inventory, LSL_Vector pos);
207 LSL_Float llGround(LSL_Vector offset); 209 LSL_Float llGround(LSL_Vector offset);
208 LSL_Vector llGroundContour(LSL_Vector offset); 210 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -348,6 +350,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
348 void llSetParcelMusicURL(string url); 350 void llSetParcelMusicURL(string url);
349 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 351 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
350 void llSetPos(LSL_Vector pos); 352 void llSetPos(LSL_Vector pos);
353 LSL_Integer llSetRegionPos(LSL_Vector pos);
351 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 354 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
352 void llSetPrimitiveParams(LSL_List rules); 355 void llSetPrimitiveParams(LSL_List rules);
353 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 356 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -412,7 +415,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
412 LSL_Vector llWind(LSL_Vector offset); 415 LSL_Vector llWind(LSL_Vector offset);
413 LSL_String llXorBase64Strings(string str1, string str2); 416 LSL_String llXorBase64Strings(string str1, string str2);
414 LSL_String llXorBase64StringsCorrect(string str1, string str2); 417 LSL_String llXorBase64StringsCorrect(string str1, string str2);
415 void print(string str); 418 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
416 419
417 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 420 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
418 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 421 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 82a6caf..fb52600 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 5a53e15..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;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index f8e3c36..5f9f0b9 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);
@@ -1913,9 +1935,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1913 return m_LSL_Functions.llClearLinkMedia(link, face); 1935 return m_LSL_Functions.llClearLinkMedia(link, face);
1914 } 1936 }
1915 1937
1916 public void print(string str) 1938 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1917 { 1939 {
1918 m_LSL_Functions.print(str); 1940 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1919 } 1941 }
1920 } 1942 }
1921} 1943}
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 {