aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-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.cs3163
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs116
-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.cs8
-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.cs26
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs41
-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.cs84
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs364
19 files changed, 3009 insertions, 1163 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 993d10f..3cbdde5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -301,6 +301,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
301 return null; 301 return null;
302 } 302 }
303 303
304 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
305 {
306 // Remove a specific script
307
308 // Remove dataserver events
309 m_Dataserver[engine].RemoveEvents(localID, itemID);
310
311 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
312 if (comms != null)
313 comms.DeleteListener(itemID);
314
315 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
316 xmlrpc.DeleteChannels(itemID);
317 xmlrpc.CancelSRDRequests(itemID);
318
319 // Remove Sensors
320 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
321
322 }
323
304 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 324 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
305 { 325 {
306 List<Object> data = new List<Object>(); 326 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 b502ab8..ce05b8c 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;
478 554
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. 555 int numPis = (int)(Math.PI / angle);
480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 556 double remainder = angle - Math.PI * numPis;
481 if (m == 0.0) return new LSL_Vector(); 557 if (numPis % 2 == 1)
482 double x = Math.Atan2(-v.y, v.z); 558 return Math.PI - angle;
483 double sin = v.x / m; 559 return remainder;
484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 560 }
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 561
490 return new LSL_Vector(x, y, z); 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
563 {
564 m_host.AddScriptLPS(1);
565 LSL_Vector eul = new LSL_Vector();
566
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
@@ -2227,13 +2484,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2227 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2484 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2228 { 2485 {
2229 m_host.AddScriptLPS(1); 2486 m_host.AddScriptLPS(1);
2230 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2487 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2231 } 2488 }
2232 2489
2233 public void llSetTorque(LSL_Vector torque, int local) 2490 public void llSetTorque(LSL_Vector torque, int local)
2234 { 2491 {
2235 m_host.AddScriptLPS(1); 2492 m_host.AddScriptLPS(1);
2236 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2493 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2237 } 2494 }
2238 2495
2239 public LSL_Vector llGetTorque() 2496 public LSL_Vector llGetTorque()
@@ -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;
@@ -2844,34 +3098,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2844 public void llLookAt(LSL_Vector target, double strength, double damping) 3098 public void llLookAt(LSL_Vector target, double strength, double damping)
2845 { 3099 {
2846 m_host.AddScriptLPS(1); 3100 m_host.AddScriptLPS(1);
2847 // Determine where we are looking from
2848 LSL_Vector from = llGetPos();
2849 3101
2850 // Work out the normalised vector from the source to the target 3102 // Get the normalized vector to the target
2851 LSL_Vector delta = llVecNorm(target - from); 3103 LSL_Vector d1 = llVecNorm(target - llGetPos());
2852 LSL_Vector angle = new LSL_Vector(0,0,0);
2853 3104
2854 // Calculate the yaw 3105 // Get the bearing (yaw)
2855 // 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);
2856 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3107 a1.z = llAtan2(d1.y, d1.x);
2857 3108
2858 // Calculate pitch 3109 // Get the elevation (pitch)
2859 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)));
2860 3112
2861 // we need to convert from a vector describing 3113 LSL_Rotation r1 = llEuler2Rot(a1);
2862 // 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);
2863 3116
2864 LSL_Rotation rot = llEuler2Rot(angle); 3117 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2865
2866 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2867 // set the rotation of the object, copy that behavior
2868 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2869 { 3118 {
2870 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);
2871 } 3124 }
2872 else 3125 else
2873 { 3126 {
2874 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);
2875 } 3134 }
2876 } 3135 }
2877 3136
@@ -2921,13 +3180,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2921 { 3180 {
2922 TaskInventoryItem item; 3181 TaskInventoryItem item;
2923 3182
2924 lock (m_host.TaskInventory) 3183 m_host.TaskInventory.LockItemsForRead(true);
3184 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2925 { 3185 {
2926 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3186 m_host.TaskInventory.LockItemsForRead(false);
2927 return; 3187 return;
2928 else 3188 }
2929 item = m_host.TaskInventory[InventorySelf()]; 3189 else
3190 {
3191 item = m_host.TaskInventory[InventorySelf()];
2930 } 3192 }
3193 m_host.TaskInventory.LockItemsForRead(false);
2931 3194
2932 if (item.PermsGranter != UUID.Zero) 3195 if (item.PermsGranter != UUID.Zero)
2933 { 3196 {
@@ -2949,13 +3212,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2949 { 3212 {
2950 TaskInventoryItem item; 3213 TaskInventoryItem item;
2951 3214
3215 m_host.TaskInventory.LockItemsForRead(true);
2952 lock (m_host.TaskInventory) 3216 lock (m_host.TaskInventory)
2953 { 3217 {
3218
2954 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3219 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3220 {
3221 m_host.TaskInventory.LockItemsForRead(false);
2955 return; 3222 return;
3223 }
2956 else 3224 else
3225 {
2957 item = m_host.TaskInventory[InventorySelf()]; 3226 item = m_host.TaskInventory[InventorySelf()];
3227 }
2958 } 3228 }
3229 m_host.TaskInventory.LockItemsForRead(false);
2959 3230
2960 m_host.AddScriptLPS(1); 3231 m_host.AddScriptLPS(1);
2961 3232
@@ -2987,19 +3258,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2987 { 3258 {
2988 m_host.AddScriptLPS(1); 3259 m_host.AddScriptLPS(1);
2989 3260
2990// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2991// return;
2992
2993 TaskInventoryItem item; 3261 TaskInventoryItem item;
2994 3262
2995 lock (m_host.TaskInventory) 3263 m_host.TaskInventory.LockItemsForRead(true);
3264
3265 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2996 { 3266 {
2997 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3267 m_host.TaskInventory.LockItemsForRead(false);
2998 return; 3268 return;
2999 else 3269 }
3000 item = m_host.TaskInventory[InventorySelf()]; 3270 else
3271 {
3272 item = m_host.TaskInventory[InventorySelf()];
3001 } 3273 }
3002 3274
3275 m_host.TaskInventory.LockItemsForRead(false);
3276
3003 if (item.PermsGranter != m_host.OwnerID) 3277 if (item.PermsGranter != m_host.OwnerID)
3004 return; 3278 return;
3005 3279
@@ -3024,13 +3298,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3024 3298
3025 TaskInventoryItem item; 3299 TaskInventoryItem item;
3026 3300
3027 lock (m_host.TaskInventory) 3301 m_host.TaskInventory.LockItemsForRead(true);
3302
3303 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3028 { 3304 {
3029 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3305 m_host.TaskInventory.LockItemsForRead(false);
3030 return; 3306 return;
3031 else 3307 }
3032 item = m_host.TaskInventory[InventorySelf()]; 3308 else
3309 {
3310 item = m_host.TaskInventory[InventorySelf()];
3033 } 3311 }
3312 m_host.TaskInventory.LockItemsForRead(false);
3313
3034 3314
3035 if (item.PermsGranter != m_host.OwnerID) 3315 if (item.PermsGranter != m_host.OwnerID)
3036 return; 3316 return;
@@ -3077,6 +3357,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3077 3357
3078 public void llInstantMessage(string user, string message) 3358 public void llInstantMessage(string user, string message)
3079 { 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
3080 m_host.AddScriptLPS(1); 3369 m_host.AddScriptLPS(1);
3081 3370
3082 // 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.
@@ -3091,14 +3380,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3091 UUID friendTransactionID = UUID.Random(); 3380 UUID friendTransactionID = UUID.Random();
3092 3381
3093 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3382 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3094 3383
3095 GridInstantMessage msg = new GridInstantMessage(); 3384 GridInstantMessage msg = new GridInstantMessage();
3096 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3385 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3097 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3386 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3098 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
3099// 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);
3100// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3389// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3101 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
3102 //if (client != null) 3411 //if (client != null)
3103 //{ 3412 //{
3104 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3413 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3112,12 +3421,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3112 msg.message = message.Substring(0, 1024); 3421 msg.message = message.Substring(0, 1024);
3113 else 3422 else
3114 msg.message = message; 3423 msg.message = message;
3115 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3424 msg.dialog = (byte)19; // MessageFromObject
3116 msg.fromGroup = false;// fromGroup; 3425 msg.fromGroup = false;// fromGroup;
3117 msg.offline = (byte)0; //offline; 3426 msg.offline = (byte)0; //offline;
3118 msg.ParentEstateID = 0; //ParentEstateID; 3427 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3119 msg.Position = new Vector3(m_host.AbsolutePosition); 3428 msg.Position = new Vector3(m_host.AbsolutePosition);
3120 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3429 msg.RegionID = World.RegionInfo.RegionID.Guid;
3121 msg.binaryBucket 3430 msg.binaryBucket
3122 = Util.StringToBytes256( 3431 = Util.StringToBytes256(
3123 "{0}/{1}/{2}/{3}", 3432 "{0}/{1}/{2}/{3}",
@@ -3145,7 +3454,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3145 } 3454 }
3146 3455
3147 emailModule.SendEmail(m_host.UUID, address, subject, message); 3456 emailModule.SendEmail(m_host.UUID, address, subject, message);
3148 ScriptSleep(20000); 3457 ScriptSleep(15000);
3149 } 3458 }
3150 3459
3151 public void llGetNextEmail(string address, string subject) 3460 public void llGetNextEmail(string address, string subject)
@@ -3284,14 +3593,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3284 3593
3285 TaskInventoryItem item; 3594 TaskInventoryItem item;
3286 3595
3287 lock (m_host.TaskInventory) 3596 m_host.TaskInventory.LockItemsForRead(true);
3597 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3288 { 3598 {
3289 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3599 m_host.TaskInventory.LockItemsForRead(false);
3290 return; 3600 return;
3291 else
3292 item = m_host.TaskInventory[InventorySelf()];
3293 } 3601 }
3294 3602 else
3603 {
3604 item = m_host.TaskInventory[InventorySelf()];
3605 }
3606 m_host.TaskInventory.LockItemsForRead(false);
3295 if (item.PermsGranter == UUID.Zero) 3607 if (item.PermsGranter == UUID.Zero)
3296 return; 3608 return;
3297 3609
@@ -3321,13 +3633,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3321 3633
3322 TaskInventoryItem item; 3634 TaskInventoryItem item;
3323 3635
3324 lock (m_host.TaskInventory) 3636 m_host.TaskInventory.LockItemsForRead(true);
3637 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3325 { 3638 {
3326 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3639 m_host.TaskInventory.LockItemsForRead(false);
3327 return; 3640 return;
3328 else
3329 item = m_host.TaskInventory[InventorySelf()];
3330 } 3641 }
3642 else
3643 {
3644 item = m_host.TaskInventory[InventorySelf()];
3645 }
3646 m_host.TaskInventory.LockItemsForRead(false);
3647
3331 3648
3332 if (item.PermsGranter == UUID.Zero) 3649 if (item.PermsGranter == UUID.Zero)
3333 return; 3650 return;
@@ -3394,10 +3711,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3394 3711
3395 TaskInventoryItem item; 3712 TaskInventoryItem item;
3396 3713
3397 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
3398 { 3722 {
3399 item = m_host.TaskInventory[invItemID]; 3723 item = m_host.TaskInventory[invItemID];
3400 } 3724 }
3725 m_host.TaskInventory.LockItemsForRead(false);
3401 3726
3402 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3727 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3403 { 3728 {
@@ -3425,15 +3750,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3425 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3750 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3426 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3751 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3427 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3752 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3753 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3428 ScriptBaseClass.PERMISSION_ATTACH; 3754 ScriptBaseClass.PERMISSION_ATTACH;
3429 3755
3430 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3756 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3431 { 3757 {
3432 lock (m_host.TaskInventory) 3758 m_host.TaskInventory.LockItemsForWrite(true);
3433 { 3759 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3434 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3760 m_host.TaskInventory[invItemID].PermsMask = perm;
3435 m_host.TaskInventory[invItemID].PermsMask = perm; 3761 m_host.TaskInventory.LockItemsForWrite(false);
3436 }
3437 3762
3438 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3763 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3439 "run_time_permissions", new Object[] { 3764 "run_time_permissions", new Object[] {
@@ -3443,28 +3768,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3443 return; 3768 return;
3444 } 3769 }
3445 } 3770 }
3446 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3771 else
3447 { 3772 {
3448 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3773 bool sitting = false;
3449 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3774 if (m_host.SitTargetAvatar == agentID)
3450 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3775 {
3451 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3776 sitting = true;
3452 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 }
3453 3786
3454 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3787 if (sitting)
3455 { 3788 {
3456 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
3457 { 3796 {
3797 m_host.TaskInventory.LockItemsForWrite(true);
3458 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3798 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3459 m_host.TaskInventory[invItemID].PermsMask = perm; 3799 m_host.TaskInventory[invItemID].PermsMask = perm;
3460 } 3800 m_host.TaskInventory.LockItemsForWrite(false);
3461 3801
3462 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3802 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3463 "run_time_permissions", new Object[] { 3803 "run_time_permissions", new Object[] {
3464 new LSL_Integer(perm) }, 3804 new LSL_Integer(perm) },
3465 new DetectParams[0])); 3805 new DetectParams[0]));
3466 3806
3467 return; 3807 return;
3808 }
3468 } 3809 }
3469 } 3810 }
3470 3811
@@ -3478,11 +3819,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 3819
3479 if (!m_waitingForScriptAnswer) 3820 if (!m_waitingForScriptAnswer)
3480 { 3821 {
3481 lock (m_host.TaskInventory) 3822 m_host.TaskInventory.LockItemsForWrite(true);
3482 { 3823 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3483 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3824 m_host.TaskInventory[invItemID].PermsMask = 0;
3484 m_host.TaskInventory[invItemID].PermsMask = 0; 3825 m_host.TaskInventory.LockItemsForWrite(false);
3485 }
3486 3826
3487 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3827 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3488 m_waitingForScriptAnswer=true; 3828 m_waitingForScriptAnswer=true;
@@ -3517,10 +3857,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3517 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3857 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3518 llReleaseControls(); 3858 llReleaseControls();
3519 3859
3520 lock (m_host.TaskInventory) 3860
3521 { 3861 m_host.TaskInventory.LockItemsForWrite(true);
3522 m_host.TaskInventory[invItemID].PermsMask = answer; 3862 m_host.TaskInventory[invItemID].PermsMask = answer;
3523 } 3863 m_host.TaskInventory.LockItemsForWrite(false);
3864
3524 3865
3525 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3866 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3526 "run_time_permissions", new Object[] { 3867 "run_time_permissions", new Object[] {
@@ -3532,16 +3873,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3532 { 3873 {
3533 m_host.AddScriptLPS(1); 3874 m_host.AddScriptLPS(1);
3534 3875
3535 lock (m_host.TaskInventory) 3876 m_host.TaskInventory.LockItemsForRead(true);
3877
3878 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3536 { 3879 {
3537 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3880 if (item.Type == 10 && item.ItemID == m_itemID)
3538 { 3881 {
3539 if (item.Type == 10 && item.ItemID == m_itemID) 3882 m_host.TaskInventory.LockItemsForRead(false);
3540 { 3883 return item.PermsGranter.ToString();
3541 return item.PermsGranter.ToString();
3542 }
3543 } 3884 }
3544 } 3885 }
3886 m_host.TaskInventory.LockItemsForRead(false);
3545 3887
3546 return UUID.Zero.ToString(); 3888 return UUID.Zero.ToString();
3547 } 3889 }
@@ -3550,19 +3892,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3550 { 3892 {
3551 m_host.AddScriptLPS(1); 3893 m_host.AddScriptLPS(1);
3552 3894
3553 lock (m_host.TaskInventory) 3895 m_host.TaskInventory.LockItemsForRead(true);
3896
3897 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3554 { 3898 {
3555 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3899 if (item.Type == 10 && item.ItemID == m_itemID)
3556 { 3900 {
3557 if (item.Type == 10 && item.ItemID == m_itemID) 3901 int perms = item.PermsMask;
3558 { 3902 if (m_automaticLinkPermission)
3559 int perms = item.PermsMask; 3903 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3560 if (m_automaticLinkPermission) 3904 m_host.TaskInventory.LockItemsForRead(false);
3561 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3905 return perms;
3562 return perms;
3563 }
3564 } 3906 }
3565 } 3907 }
3908 m_host.TaskInventory.LockItemsForRead(false);
3566 3909
3567 return 0; 3910 return 0;
3568 } 3911 }
@@ -3584,9 +3927,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3584 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3927 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3585 { 3928 {
3586 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3929 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3587 3930 if (parts.Count > 0)
3588 foreach (SceneObjectPart part in parts) 3931 {
3589 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 }
3590 } 3943 }
3591 3944
3592 public void llCreateLink(string target, int parent) 3945 public void llCreateLink(string target, int parent)
@@ -3599,11 +3952,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3599 return; 3952 return;
3600 3953
3601 TaskInventoryItem item; 3954 TaskInventoryItem item;
3602 lock (m_host.TaskInventory) 3955 m_host.TaskInventory.LockItemsForRead(true);
3603 { 3956 item = m_host.TaskInventory[invItemID];
3604 item = m_host.TaskInventory[invItemID]; 3957 m_host.TaskInventory.LockItemsForRead(false);
3605 } 3958
3606
3607 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3959 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3608 && !m_automaticLinkPermission) 3960 && !m_automaticLinkPermission)
3609 { 3961 {
@@ -3620,11 +3972,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3620 3972
3621 if (targetPart.ParentGroup.AttachmentPoint != 0) 3973 if (targetPart.ParentGroup.AttachmentPoint != 0)
3622 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
3623 SceneObjectGroup parentPrim = null, childPrim = null; 3979 SceneObjectGroup parentPrim = null, childPrim = null;
3624 3980
3625 if (targetPart != null) 3981 if (targetPart != null)
3626 { 3982 {
3627 if (parent != 0) { 3983 if (parent != 0)
3984 {
3628 parentPrim = m_host.ParentGroup; 3985 parentPrim = m_host.ParentGroup;
3629 childPrim = targetPart.ParentGroup; 3986 childPrim = targetPart.ParentGroup;
3630 } 3987 }
@@ -3636,7 +3993,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3636 3993
3637 // Required for linking 3994 // Required for linking
3638 childPrim.RootPart.ClearUpdateSchedule(); 3995 childPrim.RootPart.ClearUpdateSchedule();
3639 parentPrim.LinkToGroup(childPrim); 3996 parentPrim.LinkToGroup(childPrim, true);
3640 } 3997 }
3641 3998
3642 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3999 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3655,16 +4012,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3655 m_host.AddScriptLPS(1); 4012 m_host.AddScriptLPS(1);
3656 UUID invItemID = InventorySelf(); 4013 UUID invItemID = InventorySelf();
3657 4014
3658 lock (m_host.TaskInventory) 4015 m_host.TaskInventory.LockItemsForRead(true);
3659 {
3660 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4016 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3661 && !m_automaticLinkPermission) 4017 && !m_automaticLinkPermission)
3662 { 4018 {
3663 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);
3664 return; 4021 return;
3665 } 4022 }
3666 } 4023 m_host.TaskInventory.LockItemsForRead(false);
3667 4024
3668 if (linknum < ScriptBaseClass.LINK_THIS) 4025 if (linknum < ScriptBaseClass.LINK_THIS)
3669 return; 4026 return;
3670 4027
@@ -3703,10 +4060,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3703 // Restructuring Multiple Prims. 4060 // Restructuring Multiple Prims.
3704 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4061 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3705 parts.Remove(parentPrim.RootPart); 4062 parts.Remove(parentPrim.RootPart);
3706 foreach (SceneObjectPart part in parts) 4063 if (parts.Count > 0)
3707 { 4064 {
3708 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 }
3709 } 4077 }
4078
3710 parentPrim.HasGroupChanged = true; 4079 parentPrim.HasGroupChanged = true;
3711 parentPrim.ScheduleGroupForFullUpdate(); 4080 parentPrim.ScheduleGroupForFullUpdate();
3712 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4081 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3715,12 +4084,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3715 { 4084 {
3716 SceneObjectPart newRoot = parts[0]; 4085 SceneObjectPart newRoot = parts[0];
3717 parts.Remove(newRoot); 4086 parts.Remove(newRoot);
3718 foreach (SceneObjectPart part in parts) 4087
4088 try
3719 { 4089 {
3720 // Required for linking 4090 parts[0].ParentGroup.areUpdatesSuspended = true;
3721 part.ClearUpdateSchedule(); 4091 foreach (SceneObjectPart part in parts)
3722 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4092 {
4093 part.ClearUpdateSchedule();
4094 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4095 }
3723 } 4096 }
4097 finally
4098 {
4099 parts[0].ParentGroup.areUpdatesSuspended = false;
4100 }
4101
4102
3724 newRoot.ParentGroup.HasGroupChanged = true; 4103 newRoot.ParentGroup.HasGroupChanged = true;
3725 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4104 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3726 } 4105 }
@@ -3740,6 +4119,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3740 public void llBreakAllLinks() 4119 public void llBreakAllLinks()
3741 { 4120 {
3742 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
3743 SceneObjectGroup parentPrim = m_host.ParentGroup; 4137 SceneObjectGroup parentPrim = m_host.ParentGroup;
3744 if (parentPrim.AttachmentPoint != 0) 4138 if (parentPrim.AttachmentPoint != 0)
3745 return; // Fail silently if attached 4139 return; // Fail silently if attached
@@ -3759,25 +4153,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3759 public LSL_String llGetLinkKey(int linknum) 4153 public LSL_String llGetLinkKey(int linknum)
3760 { 4154 {
3761 m_host.AddScriptLPS(1); 4155 m_host.AddScriptLPS(1);
3762 List<UUID> keytable = new List<UUID>();
3763 // parse for sitting avatare-uuids
3764 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3765 {
3766 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3767 keytable.Add(presence.UUID);
3768 });
3769
3770 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3771 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3772 {
3773 return keytable[totalprims - linknum].ToString();
3774 }
3775
3776 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3777 {
3778 return m_host.UUID.ToString();
3779 }
3780
3781 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4156 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3782 if (part != null) 4157 if (part != null)
3783 { 4158 {
@@ -3785,6 +4160,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3785 } 4160 }
3786 else 4161 else
3787 { 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 }
3788 return UUID.Zero.ToString(); 4176 return UUID.Zero.ToString();
3789 } 4177 }
3790 } 4178 }
@@ -3884,17 +4272,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3884 m_host.AddScriptLPS(1); 4272 m_host.AddScriptLPS(1);
3885 int count = 0; 4273 int count = 0;
3886 4274
3887 lock (m_host.TaskInventory) 4275 m_host.TaskInventory.LockItemsForRead(true);
4276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3888 { 4277 {
3889 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4278 if (inv.Value.Type == type || type == -1)
3890 { 4279 {
3891 if (inv.Value.Type == type || type == -1) 4280 count = count + 1;
3892 {
3893 count = count + 1;
3894 }
3895 } 4281 }
3896 } 4282 }
3897 4283
4284 m_host.TaskInventory.LockItemsForRead(false);
3898 return count; 4285 return count;
3899 } 4286 }
3900 4287
@@ -3903,16 +4290,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3903 m_host.AddScriptLPS(1); 4290 m_host.AddScriptLPS(1);
3904 ArrayList keys = new ArrayList(); 4291 ArrayList keys = new ArrayList();
3905 4292
3906 lock (m_host.TaskInventory) 4293 m_host.TaskInventory.LockItemsForRead(true);
4294 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3907 { 4295 {
3908 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4296 if (inv.Value.Type == type || type == -1)
3909 { 4297 {
3910 if (inv.Value.Type == type || type == -1) 4298 keys.Add(inv.Value.Name);
3911 {
3912 keys.Add(inv.Value.Name);
3913 }
3914 } 4299 }
3915 } 4300 }
4301 m_host.TaskInventory.LockItemsForRead(false);
3916 4302
3917 if (keys.Count == 0) 4303 if (keys.Count == 0)
3918 { 4304 {
@@ -3949,25 +4335,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3949 } 4335 }
3950 4336
3951 // move the first object found with this inventory name 4337 // move the first object found with this inventory name
3952 lock (m_host.TaskInventory) 4338 m_host.TaskInventory.LockItemsForRead(true);
4339 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3953 { 4340 {
3954 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4341 if (inv.Value.Name == inventory)
3955 { 4342 {
3956 if (inv.Value.Name == inventory) 4343 found = true;
3957 { 4344 objId = inv.Key;
3958 found = true; 4345 assetType = inv.Value.Type;
3959 objId = inv.Key; 4346 objName = inv.Value.Name;
3960 assetType = inv.Value.Type; 4347 break;
3961 objName = inv.Value.Name;
3962 break;
3963 }
3964 } 4348 }
3965 } 4349 }
4350 m_host.TaskInventory.LockItemsForRead(false);
3966 4351
3967 if (!found) 4352 if (!found)
3968 { 4353 {
3969 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4354 llSay(0, String.Format("Could not find object '{0}'", inventory));
3970 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4355 return;
4356// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3971 } 4357 }
3972 4358
3973 // check if destination is an object 4359 // check if destination is an object
@@ -3993,48 +4379,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3993 return; 4379 return;
3994 } 4380 }
3995 } 4381 }
4382
3996 // destination is an avatar 4383 // destination is an avatar
3997 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4384 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3998 4385
3999 if (agentItem == null) 4386 if (agentItem == null)
4000 return; 4387 return;
4001 4388
4002 byte[] bucket = new byte[17]; 4389 byte[] bucket = new byte[1];
4003 bucket[0] = (byte)assetType; 4390 bucket[0] = (byte)assetType;
4004 byte[] objBytes = agentItem.ID.GetBytes(); 4391 //byte[] objBytes = agentItem.ID.GetBytes();
4005 Array.Copy(objBytes, 0, bucket, 1, 16); 4392 //Array.Copy(objBytes, 0, bucket, 1, 16);
4006 4393
4007 GridInstantMessage msg = new GridInstantMessage(World, 4394 GridInstantMessage msg = new GridInstantMessage(World,
4008 m_host.UUID, m_host.Name+", an object owned by "+ 4395 m_host.OwnerID, m_host.Name, destId,
4009 resolveName(m_host.OwnerID)+",", destId,
4010 (byte)InstantMessageDialog.TaskInventoryOffered, 4396 (byte)InstantMessageDialog.TaskInventoryOffered,
4011 false, objName+"\n"+m_host.Name+" is located at "+ 4397 false, objName+". "+m_host.Name+" is located at "+
4012 World.RegionInfo.RegionName+" "+ 4398 World.RegionInfo.RegionName+" "+
4013 m_host.AbsolutePosition.ToString(), 4399 m_host.AbsolutePosition.ToString(),
4014 agentItem.ID, true, m_host.AbsolutePosition, 4400 agentItem.ID, true, m_host.AbsolutePosition,
4015 bucket); 4401 bucket);
4016 if (m_TransferModule != null) 4402
4017 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4403 ScenePresence sp;
4404
4405 if (World.TryGetScenePresence(destId, out sp))
4406 {
4407 sp.ControllingClient.SendInstantMessage(msg);
4408 }
4409 else
4410 {
4411 if (m_TransferModule != null)
4412 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4413 }
4414
4415 //This delay should only occur when giving inventory to avatars.
4018 ScriptSleep(3000); 4416 ScriptSleep(3000);
4019 } 4417 }
4020 } 4418 }
4021 4419
4420 [DebuggerNonUserCode]
4022 public void llRemoveInventory(string name) 4421 public void llRemoveInventory(string name)
4023 { 4422 {
4024 m_host.AddScriptLPS(1); 4423 m_host.AddScriptLPS(1);
4025 4424
4026 lock (m_host.TaskInventory) 4425 List<TaskInventoryItem> inv;
4426 try
4027 { 4427 {
4028 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4428 m_host.TaskInventory.LockItemsForRead(true);
4429 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4430 }
4431 finally
4432 {
4433 m_host.TaskInventory.LockItemsForRead(false);
4434 }
4435 foreach (TaskInventoryItem item in inv)
4436 {
4437 if (item.Name == name)
4029 { 4438 {
4030 if (item.Name == name) 4439 if (item.ItemID == m_itemID)
4031 { 4440 throw new ScriptDeleteException();
4032 if (item.ItemID == m_itemID) 4441 else
4033 throw new ScriptDeleteException(); 4442 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4034 else 4443 return;
4035 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4036 return;
4037 }
4038 } 4444 }
4039 } 4445 }
4040 } 4446 }
@@ -4069,115 +4475,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4069 { 4475 {
4070 m_host.AddScriptLPS(1); 4476 m_host.AddScriptLPS(1);
4071 4477
4072 UUID uuid = (UUID)id; 4478 UUID uuid;
4073 PresenceInfo pinfo = null; 4479 if (UUID.TryParse(id, out uuid))
4074 UserAccount account;
4075
4076 UserInfoCacheEntry ce;
4077 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4078 { 4480 {
4079 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4481 PresenceInfo pinfo = null;
4080 if (account == null) 4482 UserAccount account;
4483
4484 UserInfoCacheEntry ce;
4485 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4081 { 4486 {
4082 m_userInfoCache[uuid] = null; // Cache negative 4487 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4083 return UUID.Zero.ToString(); 4488 if (account == null)
4084 } 4489 {
4490 m_userInfoCache[uuid] = null; // Cache negative
4491 return UUID.Zero.ToString();
4492 }
4085 4493
4086 4494
4087 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4495 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4088 if (pinfos != null && pinfos.Length > 0) 4496 if (pinfos != null && pinfos.Length > 0)
4089 {
4090 foreach (PresenceInfo p in pinfos)
4091 { 4497 {
4092 if (p.RegionID != UUID.Zero) 4498 foreach (PresenceInfo p in pinfos)
4093 { 4499 {
4094 pinfo = p; 4500 if (p.RegionID != UUID.Zero)
4501 {
4502 pinfo = p;
4503 }
4095 } 4504 }
4096 } 4505 }
4097 }
4098 4506
4099 ce = new UserInfoCacheEntry(); 4507 ce = new UserInfoCacheEntry();
4100 ce.time = Util.EnvironmentTickCount(); 4508 ce.time = Util.EnvironmentTickCount();
4101 ce.account = account; 4509 ce.account = account;
4102 ce.pinfo = pinfo; 4510 ce.pinfo = pinfo;
4103 } 4511 m_userInfoCache[uuid] = ce;
4104 else 4512 }
4105 { 4513 else
4106 if (ce == null) 4514 {
4107 return UUID.Zero.ToString(); 4515 if (ce == null)
4516 return UUID.Zero.ToString();
4108 4517
4109 account = ce.account; 4518 account = ce.account;
4110 pinfo = ce.pinfo; 4519 pinfo = ce.pinfo;
4111 } 4520 }
4112 4521
4113 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4522 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4114 {
4115 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4116 if (pinfos != null && pinfos.Length > 0)
4117 { 4523 {
4118 foreach (PresenceInfo p in pinfos) 4524 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4525 if (pinfos != null && pinfos.Length > 0)
4119 { 4526 {
4120 if (p.RegionID != UUID.Zero) 4527 foreach (PresenceInfo p in pinfos)
4121 { 4528 {
4122 pinfo = p; 4529 if (p.RegionID != UUID.Zero)
4530 {
4531 pinfo = p;
4532 }
4123 } 4533 }
4124 } 4534 }
4125 } 4535 else
4126 else 4536 pinfo = null;
4127 pinfo = null;
4128 4537
4129 ce.time = Util.EnvironmentTickCount(); 4538 ce.time = Util.EnvironmentTickCount();
4130 ce.pinfo = pinfo; 4539 ce.pinfo = pinfo;
4131 } 4540 }
4132 4541
4133 string reply = String.Empty; 4542 string reply = String.Empty;
4134 4543
4135 switch (data) 4544 switch (data)
4136 { 4545 {
4137 case 1: // DATA_ONLINE (0|1) 4546 case 1: // DATA_ONLINE (0|1)
4138 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4547 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4139 reply = "1"; 4548 reply = "1";
4140 else 4549 else
4141 reply = "0"; 4550 reply = "0";
4142 break; 4551 break;
4143 case 2: // DATA_NAME (First Last) 4552 case 2: // DATA_NAME (First Last)
4144 reply = account.FirstName + " " + account.LastName; 4553 reply = account.FirstName + " " + account.LastName;
4145 break; 4554 break;
4146 case 3: // DATA_BORN (YYYY-MM-DD) 4555 case 3: // DATA_BORN (YYYY-MM-DD)
4147 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4556 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4148 born = born.AddSeconds(account.Created); 4557 born = born.AddSeconds(account.Created);
4149 reply = born.ToString("yyyy-MM-dd"); 4558 reply = born.ToString("yyyy-MM-dd");
4150 break; 4559 break;
4151 case 4: // DATA_RATING (0,0,0,0,0,0) 4560 case 4: // DATA_RATING (0,0,0,0,0,0)
4152 reply = "0,0,0,0,0,0"; 4561 reply = "0,0,0,0,0,0";
4153 break; 4562 break;
4154 case 7: // DATA_USERLEVEL (integer) 4563 case 8: // DATA_PAYINFO (0|1|2|3)
4155 reply = account.UserLevel.ToString(); 4564 reply = "0";
4156 break; 4565 break;
4157 case 8: // DATA_PAYINFO (0|1|2|3) 4566 default:
4158 reply = "0"; 4567 return UUID.Zero.ToString(); // Raise no event
4159 break; 4568 }
4160 default:
4161 return UUID.Zero.ToString(); // Raise no event
4162 }
4163 4569
4164 UUID rq = UUID.Random(); 4570 UUID rq = UUID.Random();
4165 4571
4166 UUID tid = AsyncCommands. 4572 UUID tid = AsyncCommands.
4167 DataserverPlugin.RegisterRequest(m_localID, 4573 DataserverPlugin.RegisterRequest(m_localID,
4168 m_itemID, rq.ToString()); 4574 m_itemID, rq.ToString());
4169 4575
4170 AsyncCommands. 4576 AsyncCommands.
4171 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4577 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4172 4578
4173 ScriptSleep(100); 4579 ScriptSleep(100);
4174 return tid.ToString(); 4580 return tid.ToString();
4581 }
4582 else
4583 {
4584 ShoutError("Invalid UUID passed to llRequestAgentData.");
4585 }
4586 return "";
4175 } 4587 }
4176 4588
4177 public LSL_String llRequestInventoryData(string name) 4589 public LSL_String llRequestInventoryData(string name)
4178 { 4590 {
4179 m_host.AddScriptLPS(1); 4591 m_host.AddScriptLPS(1);
4180 4592
4593 //Clone is thread safe
4181 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4594 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4182 4595
4183 foreach (TaskInventoryItem item in itemDictionary.Values) 4596 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4229,19 +4642,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4229 if (UUID.TryParse(agent, out agentId)) 4642 if (UUID.TryParse(agent, out agentId))
4230 { 4643 {
4231 ScenePresence presence = World.GetScenePresence(agentId); 4644 ScenePresence presence = World.GetScenePresence(agentId);
4232 if (presence != null) 4645 if (presence != null && presence.PresenceType != PresenceType.Npc)
4233 { 4646 {
4647 // agent must not be a god
4648 if (presence.UserLevel >= 200) return;
4649
4234 // agent must be over the owners land 4650 // agent must be over the owners land
4235 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4651 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4236 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4652 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4237 { 4653 {
4238 World.TeleportClientHome(agentId, presence.ControllingClient); 4654 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4655 {
4656 // They can't be teleported home for some reason
4657 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4658 if (regionInfo != null)
4659 {
4660 World.RequestTeleportLocation(
4661 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4662 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4663 }
4664 }
4239 } 4665 }
4240 } 4666 }
4241 } 4667 }
4242 ScriptSleep(5000); 4668 ScriptSleep(5000);
4243 } 4669 }
4244 4670
4671 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4672 {
4673 m_host.AddScriptLPS(1);
4674 UUID agentId = new UUID();
4675 if (UUID.TryParse(agent, out agentId))
4676 {
4677 ScenePresence presence = World.GetScenePresence(agentId);
4678 if (presence != null && presence.PresenceType != PresenceType.Npc)
4679 {
4680 // agent must not be a god
4681 if (presence.GodLevel >= 200) return;
4682
4683 if (simname == String.Empty)
4684 simname = World.RegionInfo.RegionName;
4685
4686 // agent must be over the owners land
4687 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4688 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4689 {
4690 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4691 }
4692 else // or must be wearing the prim
4693 {
4694 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4695 {
4696 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4697 }
4698 }
4699 }
4700 }
4701 }
4702
4245 public void llTextBox(string agent, string message, int chatChannel) 4703 public void llTextBox(string agent, string message, int chatChannel)
4246 { 4704 {
4247 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4705 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4253,7 +4711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4253 UUID av = new UUID(); 4711 UUID av = new UUID();
4254 if (!UUID.TryParse(agent,out av)) 4712 if (!UUID.TryParse(agent,out av))
4255 { 4713 {
4256 LSLError("First parameter to llDialog needs to be a key"); 4714 //LSLError("First parameter to llDialog needs to be a key");
4257 return; 4715 return;
4258 } 4716 }
4259 4717
@@ -4290,17 +4748,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4290 UUID soundId = UUID.Zero; 4748 UUID soundId = UUID.Zero;
4291 if (!UUID.TryParse(impact_sound, out soundId)) 4749 if (!UUID.TryParse(impact_sound, out soundId))
4292 { 4750 {
4293 lock (m_host.TaskInventory) 4751 m_host.TaskInventory.LockItemsForRead(true);
4752 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4294 { 4753 {
4295 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4754 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4296 { 4755 {
4297 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4756 soundId = item.AssetID;
4298 { 4757 break;
4299 soundId = item.AssetID;
4300 break;
4301 }
4302 } 4758 }
4303 } 4759 }
4760 m_host.TaskInventory.LockItemsForRead(false);
4304 } 4761 }
4305 m_host.CollisionSound = soundId; 4762 m_host.CollisionSound = soundId;
4306 m_host.CollisionSoundVolume = (float)impact_volume; 4763 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4340,6 +4797,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4340 UUID partItemID; 4797 UUID partItemID;
4341 foreach (SceneObjectPart part in parts) 4798 foreach (SceneObjectPart part in parts)
4342 { 4799 {
4800 //Clone is thread safe
4343 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4801 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4344 4802
4345 foreach (TaskInventoryItem item in itemsDictionary.Values) 4803 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4543,17 +5001,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4543 5001
4544 m_host.AddScriptLPS(1); 5002 m_host.AddScriptLPS(1);
4545 5003
4546 lock (m_host.TaskInventory) 5004 m_host.TaskInventory.LockItemsForRead(true);
5005 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4547 { 5006 {
4548 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 5007 if (item.Type == 10 && item.ItemID == m_itemID)
4549 { 5008 {
4550 if (item.Type == 10 && item.ItemID == m_itemID) 5009 result = item.Name!=null?item.Name:String.Empty;
4551 { 5010 break;
4552 result = item.Name != null ? item.Name : String.Empty;
4553 break;
4554 }
4555 } 5011 }
4556 } 5012 }
5013 m_host.TaskInventory.LockItemsForRead(false);
4557 5014
4558 return result; 5015 return result;
4559 } 5016 }
@@ -4726,23 +5183,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4726 { 5183 {
4727 m_host.AddScriptLPS(1); 5184 m_host.AddScriptLPS(1);
4728 5185
4729 lock (m_host.TaskInventory) 5186 m_host.TaskInventory.LockItemsForRead(true);
5187 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4730 { 5188 {
4731 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5189 if (inv.Value.Name == name)
4732 { 5190 {
4733 if (inv.Value.Name == name) 5191 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4734 { 5192 {
4735 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5193 m_host.TaskInventory.LockItemsForRead(false);
4736 { 5194 return inv.Value.AssetID.ToString();
4737 return inv.Value.AssetID.ToString(); 5195 }
4738 } 5196 else
4739 else 5197 {
4740 { 5198 m_host.TaskInventory.LockItemsForRead(false);
4741 return UUID.Zero.ToString(); 5199 return UUID.Zero.ToString();
4742 }
4743 } 5200 }
4744 } 5201 }
4745 } 5202 }
5203 m_host.TaskInventory.LockItemsForRead(false);
4746 5204
4747 return UUID.Zero.ToString(); 5205 return UUID.Zero.ToString();
4748 } 5206 }
@@ -4895,14 +5353,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4895 { 5353 {
4896 m_host.AddScriptLPS(1); 5354 m_host.AddScriptLPS(1);
4897 5355
4898 if (src == null) 5356 return src.Length;
4899 {
4900 return 0;
4901 }
4902 else
4903 {
4904 return src.Length;
4905 }
4906 } 5357 }
4907 5358
4908 public LSL_Integer llList2Integer(LSL_List src, int index) 5359 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4948,7 +5399,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4948 else if (src.Data[index] is LSL_Float) 5399 else if (src.Data[index] is LSL_Float)
4949 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5400 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4950 else if (src.Data[index] is LSL_String) 5401 else if (src.Data[index] is LSL_String)
4951 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5402 {
5403 string str = ((LSL_String) src.Data[index]).m_string;
5404 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5405 if (m != Match.Empty)
5406 {
5407 str = m.Value;
5408 double d = 0.0;
5409 if (!Double.TryParse(str, out d))
5410 return 0.0;
5411
5412 return d;
5413 }
5414 return 0.0;
5415 }
4952 return Convert.ToDouble(src.Data[index]); 5416 return Convert.ToDouble(src.Data[index]);
4953 } 5417 }
4954 catch (FormatException) 5418 catch (FormatException)
@@ -5221,7 +5685,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5221 } 5685 }
5222 } 5686 }
5223 } 5687 }
5224 else { 5688 else
5689 {
5225 object[] array = new object[src.Length]; 5690 object[] array = new object[src.Length];
5226 Array.Copy(src.Data, 0, array, 0, src.Length); 5691 Array.Copy(src.Data, 0, array, 0, src.Length);
5227 result = new LSL_List(array); 5692 result = new LSL_List(array);
@@ -5328,7 +5793,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5328 public LSL_Integer llGetRegionAgentCount() 5793 public LSL_Integer llGetRegionAgentCount()
5329 { 5794 {
5330 m_host.AddScriptLPS(1); 5795 m_host.AddScriptLPS(1);
5331 return new LSL_Integer(World.GetRootAgentCount()); 5796
5797 int count = 0;
5798 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5799 count++;
5800 });
5801
5802 return new LSL_Integer(count);
5332 } 5803 }
5333 5804
5334 public LSL_Vector llGetRegionCorner() 5805 public LSL_Vector llGetRegionCorner()
@@ -5608,6 +6079,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5608 flags |= ScriptBaseClass.AGENT_SITTING; 6079 flags |= ScriptBaseClass.AGENT_SITTING;
5609 } 6080 }
5610 6081
6082 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6083 {
6084 flags |= ScriptBaseClass.AGENT_MALE;
6085 }
6086
5611 return flags; 6087 return flags;
5612 } 6088 }
5613 6089
@@ -5670,10 +6146,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5670 m_host.AddScriptLPS(1); 6146 m_host.AddScriptLPS(1);
5671 6147
5672 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6148 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5673 6149 if (parts.Count > 0)
5674 foreach (var part in parts)
5675 { 6150 {
5676 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6151 try
6152 {
6153 parts[0].ParentGroup.areUpdatesSuspended = true;
6154 foreach (var part in parts)
6155 {
6156 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6157 }
6158 }
6159 finally
6160 {
6161 parts[0].ParentGroup.areUpdatesSuspended = false;
6162 }
5677 } 6163 }
5678 } 6164 }
5679 6165
@@ -5725,13 +6211,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5725 6211
5726 if (m_host.OwnerID == land.LandData.OwnerID) 6212 if (m_host.OwnerID == land.LandData.OwnerID)
5727 { 6213 {
5728 World.TeleportClientHome(agentID, presence.ControllingClient); 6214 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6215 presence.TeleportWithMomentum(pos);
6216 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5729 } 6217 }
5730 } 6218 }
5731 } 6219 }
5732 ScriptSleep(5000); 6220 ScriptSleep(5000);
5733 } 6221 }
5734 6222
6223 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6224 {
6225 return ParseString2List(str, separators, in_spacers, false);
6226 }
6227
5735 public LSL_Integer llOverMyLand(string id) 6228 public LSL_Integer llOverMyLand(string id)
5736 { 6229 {
5737 m_host.AddScriptLPS(1); 6230 m_host.AddScriptLPS(1);
@@ -5796,8 +6289,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5796 UUID agentId = new UUID(); 6289 UUID agentId = new UUID();
5797 if (!UUID.TryParse(agent, out agentId)) 6290 if (!UUID.TryParse(agent, out agentId))
5798 return new LSL_Integer(0); 6291 return new LSL_Integer(0);
6292 if (agentId == m_host.GroupID)
6293 return new LSL_Integer(1);
5799 ScenePresence presence = World.GetScenePresence(agentId); 6294 ScenePresence presence = World.GetScenePresence(agentId);
5800 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6295 if (presence == null || presence.IsChildAgent) // Return false for child agents
5801 return new LSL_Integer(0); 6296 return new LSL_Integer(0);
5802 IClientAPI client = presence.ControllingClient; 6297 IClientAPI client = presence.ControllingClient;
5803 if (m_host.GroupID == client.ActiveGroupId) 6298 if (m_host.GroupID == client.ActiveGroupId)
@@ -5932,7 +6427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5932 return m_host.ParentGroup.AttachmentPoint; 6427 return m_host.ParentGroup.AttachmentPoint;
5933 } 6428 }
5934 6429
5935 public LSL_Integer llGetFreeMemory() 6430 public virtual LSL_Integer llGetFreeMemory()
5936 { 6431 {
5937 m_host.AddScriptLPS(1); 6432 m_host.AddScriptLPS(1);
5938 // Make scripts designed for LSO happy 6433 // Make scripts designed for LSO happy
@@ -6049,7 +6544,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6049 SetParticleSystem(m_host, rules); 6544 SetParticleSystem(m_host, rules);
6050 } 6545 }
6051 6546
6052 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6547 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6548 {
6053 6549
6054 6550
6055 if (rules.Length == 0) 6551 if (rules.Length == 0)
@@ -6243,14 +6739,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6243 6739
6244 protected UUID GetTaskInventoryItem(string name) 6740 protected UUID GetTaskInventoryItem(string name)
6245 { 6741 {
6246 lock (m_host.TaskInventory) 6742 m_host.TaskInventory.LockItemsForRead(true);
6743 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6247 { 6744 {
6248 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6745 if (inv.Value.Name == name)
6249 { 6746 {
6250 if (inv.Value.Name == name) 6747 m_host.TaskInventory.LockItemsForRead(false);
6251 return inv.Key; 6748 return inv.Key;
6252 } 6749 }
6253 } 6750 }
6751 m_host.TaskInventory.LockItemsForRead(false);
6254 6752
6255 return UUID.Zero; 6753 return UUID.Zero;
6256 } 6754 }
@@ -6288,16 +6786,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6288 if (folderID == UUID.Zero) 6786 if (folderID == UUID.Zero)
6289 return; 6787 return;
6290 6788
6291 byte[] bucket = new byte[17]; 6789 byte[] bucket = new byte[1];
6292 bucket[0] = (byte)AssetType.Folder; 6790 bucket[0] = (byte)AssetType.Folder;
6293 byte[] objBytes = folderID.GetBytes(); 6791 //byte[] objBytes = folderID.GetBytes();
6294 Array.Copy(objBytes, 0, bucket, 1, 16); 6792 //Array.Copy(objBytes, 0, bucket, 1, 16);
6295 6793
6296 GridInstantMessage msg = new GridInstantMessage(World, 6794 GridInstantMessage msg = new GridInstantMessage(World,
6297 m_host.UUID, m_host.Name+", an object owned by "+ 6795 m_host.OwnerID, m_host.Name, destID,
6298 resolveName(m_host.OwnerID)+",", destID, 6796 (byte)InstantMessageDialog.TaskInventoryOffered,
6299 (byte)InstantMessageDialog.InventoryOffered, 6797 false, category+". "+m_host.Name+" is located at "+
6300 false, category+"\n"+m_host.Name+" is located at "+
6301 World.RegionInfo.RegionName+" "+ 6798 World.RegionInfo.RegionName+" "+
6302 m_host.AbsolutePosition.ToString(), 6799 m_host.AbsolutePosition.ToString(),
6303 folderID, true, m_host.AbsolutePosition, 6800 folderID, true, m_host.AbsolutePosition,
@@ -6535,13 +7032,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6535 UUID av = new UUID(); 7032 UUID av = new UUID();
6536 if (!UUID.TryParse(avatar,out av)) 7033 if (!UUID.TryParse(avatar,out av))
6537 { 7034 {
6538 LSLError("First parameter to llDialog needs to be a key"); 7035 //LSLError("First parameter to llDialog needs to be a key");
6539 return; 7036 return;
6540 } 7037 }
6541 if (buttons.Length < 1) 7038 if (buttons.Length < 1)
6542 { 7039 {
6543 LSLError("No less than 1 button can be shown"); 7040 buttons.Add("OK");
6544 return;
6545 } 7041 }
6546 if (buttons.Length > 12) 7042 if (buttons.Length > 12)
6547 { 7043 {
@@ -6558,7 +7054,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6558 } 7054 }
6559 if (buttons.Data[i].ToString().Length > 24) 7055 if (buttons.Data[i].ToString().Length > 24)
6560 { 7056 {
6561 LSLError("button label cannot be longer than 24 characters"); 7057 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6562 return; 7058 return;
6563 } 7059 }
6564 buts[i] = buttons.Data[i].ToString(); 7060 buts[i] = buttons.Data[i].ToString();
@@ -6617,22 +7113,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6617 } 7113 }
6618 7114
6619 // copy the first script found with this inventory name 7115 // copy the first script found with this inventory name
6620 lock (m_host.TaskInventory) 7116 TaskInventoryItem scriptItem = null;
7117 m_host.TaskInventory.LockItemsForRead(true);
7118 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6621 { 7119 {
6622 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7120 if (inv.Value.Name == name)
6623 { 7121 {
6624 if (inv.Value.Name == name) 7122 // make sure the object is a script
7123 if (10 == inv.Value.Type)
6625 { 7124 {
6626 // make sure the object is a script 7125 found = true;
6627 if (10 == inv.Value.Type) 7126 srcId = inv.Key;
6628 { 7127 scriptItem = inv.Value;
6629 found = true; 7128 break;
6630 srcId = inv.Key;
6631 break;
6632 }
6633 } 7129 }
6634 } 7130 }
6635 } 7131 }
7132 m_host.TaskInventory.LockItemsForRead(false);
6636 7133
6637 if (!found) 7134 if (!found)
6638 { 7135 {
@@ -6640,9 +7137,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6640 return; 7137 return;
6641 } 7138 }
6642 7139
6643 // the rest of the permission checks are done in RezScript, so check the pin there as well 7140 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6644 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7141 if (dest != null)
7142 {
7143 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7144 {
7145 // the rest of the permission checks are done in RezScript, so check the pin there as well
7146 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6645 7147
7148 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7149 m_host.Inventory.RemoveInventoryItem(srcId);
7150 }
7151 }
6646 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7152 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6647 ScriptSleep(3000); 7153 ScriptSleep(3000);
6648 } 7154 }
@@ -6705,19 +7211,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6705 public LSL_String llMD5String(string src, int nonce) 7211 public LSL_String llMD5String(string src, int nonce)
6706 { 7212 {
6707 m_host.AddScriptLPS(1); 7213 m_host.AddScriptLPS(1);
6708 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7214 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6709 } 7215 }
6710 7216
6711 public LSL_String llSHA1String(string src) 7217 public LSL_String llSHA1String(string src)
6712 { 7218 {
6713 m_host.AddScriptLPS(1); 7219 m_host.AddScriptLPS(1);
6714 return Util.SHA1Hash(src).ToLower(); 7220 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6715 } 7221 }
6716 7222
6717 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7223 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6718 { 7224 {
6719 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7225 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6720 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7226 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7227 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7228 return shapeBlock;
6721 7229
6722 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7230 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6723 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7231 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6822,6 +7330,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6822 // Prim type box, cylinder and prism. 7330 // Prim type box, cylinder and prism.
6823 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) 7331 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)
6824 { 7332 {
7333 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7334 return;
7335
6825 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7336 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6826 ObjectShapePacket.ObjectDataBlock shapeBlock; 7337 ObjectShapePacket.ObjectDataBlock shapeBlock;
6827 7338
@@ -6875,6 +7386,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6875 // Prim type sphere. 7386 // Prim type sphere.
6876 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7387 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6877 { 7388 {
7389 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7390 return;
7391
6878 ObjectShapePacket.ObjectDataBlock shapeBlock; 7392 ObjectShapePacket.ObjectDataBlock shapeBlock;
6879 7393
6880 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7394 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6916,6 +7430,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6916 // Prim type torus, tube and ring. 7430 // Prim type torus, tube and ring.
6917 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) 7431 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)
6918 { 7432 {
7433 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7434 return;
7435
6919 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7436 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6920 ObjectShapePacket.ObjectDataBlock shapeBlock; 7437 ObjectShapePacket.ObjectDataBlock shapeBlock;
6921 7438
@@ -7051,6 +7568,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7051 // Prim type sculpt. 7568 // Prim type sculpt.
7052 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7569 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7053 { 7570 {
7571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7572 return;
7573
7054 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7574 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7055 UUID sculptId; 7575 UUID sculptId;
7056 7576
@@ -7075,7 +7595,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7075 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7595 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7076 { 7596 {
7077 // default 7597 // default
7078 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7598 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7079 } 7599 }
7080 7600
7081 part.Shape.SetSculptProperties((byte)type, sculptId); 7601 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7091,32 +7611,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7091 ScriptSleep(200); 7611 ScriptSleep(200);
7092 } 7612 }
7093 7613
7094 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7614 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7095 { 7615 {
7096 m_host.AddScriptLPS(1); 7616 m_host.AddScriptLPS(1);
7097 7617
7098 setLinkPrimParams(linknumber, rules); 7618 setLinkPrimParams(linknumber, rules);
7619 }
7099 7620
7100 ScriptSleep(200); 7621 private void setLinkPrimParams(int linknumber, LSL_List rules)
7622 {
7623 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7624 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7625 if (parts.Count>0)
7626 {
7627 try
7628 {
7629 parts[0].ParentGroup.areUpdatesSuspended = true;
7630 foreach (SceneObjectPart part in parts)
7631 SetPrimParams(part, rules);
7632 }
7633 finally
7634 {
7635 parts[0].ParentGroup.areUpdatesSuspended = false;
7636 }
7637 }
7638 if (avatars.Count > 0)
7639 {
7640 foreach (ScenePresence avatar in avatars)
7641 SetPrimParams(avatar, rules);
7642 }
7101 } 7643 }
7102 7644
7103 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7645 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7646 float material_density, float material_friction,
7647 float material_restitution, float material_gravity_modifier)
7104 { 7648 {
7105 m_host.AddScriptLPS(1); 7649 ExtraPhysicsData physdata = new ExtraPhysicsData();
7650 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7651 physdata.Density = part.Density;
7652 physdata.Friction = part.Friction;
7653 physdata.Bounce = part.Bounciness;
7654 physdata.GravitationModifier = part.GravityModifier;
7106 7655
7107 setLinkPrimParams(linknumber, rules); 7656 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7657 physdata.Density = material_density;
7658 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7659 physdata.Friction = material_friction;
7660 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7661 physdata.Bounce = material_restitution;
7662 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7663 physdata.GravitationModifier = material_gravity_modifier;
7664
7665 part.UpdateExtraPhysics(physdata);
7108 } 7666 }
7109 7667
7110 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7668 public void llSetPhysicsMaterial(int material_bits,
7669 float material_gravity_modifier, float material_restitution,
7670 float material_friction, float material_density)
7111 { 7671 {
7112 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7672 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7673 }
7113 7674
7114 foreach (SceneObjectPart part in parts) 7675 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7115 SetPrimParams(part, rules); 7676 {
7677 llSetLinkPrimitiveParamsFast(linknumber, rules);
7678 ScriptSleep(200);
7679 }
7680
7681 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7682 {
7683 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7684 //We only support PRIM_POSITION and PRIM_ROTATION
7685
7686 int idx = 0;
7687
7688 while (idx < rules.Length)
7689 {
7690 int code = rules.GetLSLIntegerItem(idx++);
7691
7692 int remain = rules.Length - idx;
7693
7694 switch (code)
7695 {
7696 case (int)ScriptBaseClass.PRIM_POSITION:
7697 {
7698 if (remain < 1)
7699 return;
7700 LSL_Vector v;
7701 v = rules.GetVector3Item(idx++);
7702
7703 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7704 if (part == null)
7705 break;
7706
7707 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7708 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7709 if (llGetLinkNumber() > 1)
7710 {
7711 localRot = llGetLocalRot();
7712 localPos = llGetLocalPos();
7713 }
7714
7715 v -= localPos;
7716 v /= localRot;
7717
7718 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7719
7720 v = v + 2 * sitOffset;
7721
7722 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7723 av.SendAvatarDataToAllAgents();
7724
7725 }
7726 break;
7727
7728 case (int)ScriptBaseClass.PRIM_ROTATION:
7729 {
7730 if (remain < 1)
7731 return;
7732
7733 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7734 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7735 if (llGetLinkNumber() > 1)
7736 {
7737 localRot = llGetLocalRot();
7738 localPos = llGetLocalPos();
7739 }
7740
7741 LSL_Rotation r;
7742 r = rules.GetQuaternionItem(idx++);
7743 r = r * llGetRootRotation() / localRot;
7744 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7745 av.SendAvatarDataToAllAgents();
7746 }
7747 break;
7748 }
7749 }
7116 } 7750 }
7117 7751
7118 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7752 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7119 { 7753 {
7754 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7755 return;
7756
7120 int idx = 0; 7757 int idx = 0;
7121 7758
7122 bool positionChanged = false; 7759 bool positionChanged = false;
@@ -7144,6 +7781,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7144 currentPosition = GetSetPosTarget(part, v, currentPosition); 7781 currentPosition = GetSetPosTarget(part, v, currentPosition);
7145 7782
7146 break; 7783 break;
7784 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7785 if (remain < 1)
7786 return;
7787
7788 v=rules.GetVector3Item(idx++);
7789 positionChanged = true;
7790 currentPosition = GetSetPosTarget(part, v, currentPosition);
7791
7792 break;
7147 case (int)ScriptBaseClass.PRIM_SIZE: 7793 case (int)ScriptBaseClass.PRIM_SIZE:
7148 if (remain < 1) 7794 if (remain < 1)
7149 return; 7795 return;
@@ -7437,6 +8083,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7437 part.ScriptSetPhysicsStatus(physics); 8083 part.ScriptSetPhysicsStatus(physics);
7438 break; 8084 break;
7439 8085
8086 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8087 if (remain < 1)
8088 return;
8089
8090 int shape_type = rules.GetLSLIntegerItem(idx++);
8091
8092 ExtraPhysicsData physdata = new ExtraPhysicsData();
8093 physdata.Density = part.Density;
8094 physdata.Bounce = part.Bounciness;
8095 physdata.GravitationModifier = part.GravityModifier;
8096 physdata.PhysShapeType = (PhysShapeType)shape_type;
8097
8098 part.UpdateExtraPhysics(physdata);
8099
8100 break;
8101
8102 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8103 if (remain < 5)
8104 return;
8105
8106 int material_bits = rules.GetLSLIntegerItem(idx++);
8107 float material_density = (float)rules.GetLSLFloatItem(idx++);
8108 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8109 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8110 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8111
8112 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8113
8114 break;
8115
7440 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8116 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7441 if (remain < 1) 8117 if (remain < 1)
7442 return; 8118 return;
@@ -7510,7 +8186,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7510 if (part.ParentGroup.RootPart == part) 8186 if (part.ParentGroup.RootPart == part)
7511 { 8187 {
7512 SceneObjectGroup parent = part.ParentGroup; 8188 SceneObjectGroup parent = part.ParentGroup;
7513 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8189 Util.FireAndForget(delegate(object x) {
8190 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8191 });
7514 } 8192 }
7515 else 8193 else
7516 { 8194 {
@@ -7521,6 +8199,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7521 } 8199 }
7522 } 8200 }
7523 } 8201 }
8202
8203 if (positionChanged)
8204 {
8205 if (part.ParentGroup.RootPart == part)
8206 {
8207 SceneObjectGroup parent = part.ParentGroup;
8208 Util.FireAndForget(delegate(object x) {
8209 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8210 });
8211 }
8212 else
8213 {
8214 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8215 SceneObjectGroup parent = part.ParentGroup;
8216 parent.HasGroupChanged = true;
8217 parent.ScheduleGroupForTerseUpdate();
8218 }
8219 }
7524 } 8220 }
7525 8221
7526 public LSL_String llStringToBase64(string str) 8222 public LSL_String llStringToBase64(string str)
@@ -7681,13 +8377,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7681 public LSL_Integer llGetNumberOfPrims() 8377 public LSL_Integer llGetNumberOfPrims()
7682 { 8378 {
7683 m_host.AddScriptLPS(1); 8379 m_host.AddScriptLPS(1);
7684 int avatarCount = 0; 8380 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7685 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8381
7686 {
7687 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7688 avatarCount++;
7689 });
7690
7691 return m_host.ParentGroup.PrimCount + avatarCount; 8382 return m_host.ParentGroup.PrimCount + avatarCount;
7692 } 8383 }
7693 8384
@@ -7703,55 +8394,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7703 m_host.AddScriptLPS(1); 8394 m_host.AddScriptLPS(1);
7704 UUID objID = UUID.Zero; 8395 UUID objID = UUID.Zero;
7705 LSL_List result = new LSL_List(); 8396 LSL_List result = new LSL_List();
8397
8398 // If the ID is not valid, return null result
7706 if (!UUID.TryParse(obj, out objID)) 8399 if (!UUID.TryParse(obj, out objID))
7707 { 8400 {
7708 result.Add(new LSL_Vector()); 8401 result.Add(new LSL_Vector());
7709 result.Add(new LSL_Vector()); 8402 result.Add(new LSL_Vector());
7710 return result; 8403 return result;
7711 } 8404 }
8405
8406 // Check if this is an attached prim. If so, replace
8407 // the UUID with the avatar UUID and report it's bounding box
8408 SceneObjectPart part = World.GetSceneObjectPart(objID);
8409 if (part != null && part.ParentGroup.IsAttachment)
8410 objID = part.ParentGroup.AttachedAvatar;
8411
8412 // Find out if this is an avatar ID. If so, return it's box
7712 ScenePresence presence = World.GetScenePresence(objID); 8413 ScenePresence presence = World.GetScenePresence(objID);
7713 if (presence != null) 8414 if (presence != null)
7714 { 8415 {
7715 if (presence.ParentID == 0) // not sat on an object 8416 // As per LSL Wiki, there is no difference between sitting
8417 // and standing avatar since server 1.36
8418 LSL_Vector lower;
8419 LSL_Vector upper;
8420 if (presence.Animator.Animations.DefaultAnimation.AnimID
8421 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7716 { 8422 {
7717 LSL_Vector lower; 8423 // This is for ground sitting avatars
7718 LSL_Vector upper; 8424 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7719 if (presence.Animator.Animations.DefaultAnimation.AnimID 8425 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7720 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8426 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7721 {
7722 // This is for ground sitting avatars
7723 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7724 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7725 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7726 }
7727 else
7728 {
7729 // This is for standing/flying avatars
7730 float height = presence.Appearance.AvatarHeight / 2.0f;
7731 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7732 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7733 }
7734 result.Add(lower);
7735 result.Add(upper);
7736 return result;
7737 } 8427 }
7738 else 8428 else
7739 { 8429 {
7740 // sitting on an object so we need the bounding box of that 8430 // This is for standing/flying avatars
7741 // which should include the avatar so set the UUID to the 8431 float height = presence.Appearance.AvatarHeight / 2.0f;
7742 // UUID of the object the avatar is sat on and allow it to fall through 8432 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7743 // to processing an object 8433 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7744 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7745 objID = p.UUID;
7746 } 8434 }
8435
8436 // Adjust to the documented error offsets (see LSL Wiki)
8437 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8438 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8439
8440 if (lower.x > upper.x)
8441 lower.x = upper.x;
8442 if (lower.y > upper.y)
8443 lower.y = upper.y;
8444 if (lower.z > upper.z)
8445 lower.z = upper.z;
8446
8447 result.Add(lower);
8448 result.Add(upper);
8449 return result;
7747 } 8450 }
7748 SceneObjectPart part = World.GetSceneObjectPart(objID); 8451
8452 part = World.GetSceneObjectPart(objID);
7749 // Currently only works for single prims without a sitting avatar 8453 // Currently only works for single prims without a sitting avatar
7750 if (part != null) 8454 if (part != null)
7751 { 8455 {
7752 Vector3 halfSize = part.Scale / 2.0f; 8456 float minX;
7753 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8457 float maxX;
7754 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8458 float minY;
8459 float maxY;
8460 float minZ;
8461 float maxZ;
8462
8463 // This BBox is in sim coordinates, with the offset being
8464 // a contained point.
8465 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8466 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8467
8468 minX -= offsets[0].X;
8469 maxX -= offsets[0].X;
8470 minY -= offsets[0].Y;
8471 maxY -= offsets[0].Y;
8472 minZ -= offsets[0].Z;
8473 maxZ -= offsets[0].Z;
8474
8475 LSL_Vector lower;
8476 LSL_Vector upper;
8477
8478 // Adjust to the documented error offsets (see LSL Wiki)
8479 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8480 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8481
8482 if (lower.x > upper.x)
8483 lower.x = upper.x;
8484 if (lower.y > upper.y)
8485 lower.y = upper.y;
8486 if (lower.z > upper.z)
8487 lower.z = upper.z;
8488
7755 result.Add(lower); 8489 result.Add(lower);
7756 result.Add(upper); 8490 result.Add(upper);
7757 return result; 8491 return result;
@@ -7831,13 +8565,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7831 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8565 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7832 part.AbsolutePosition.Y, 8566 part.AbsolutePosition.Y,
7833 part.AbsolutePosition.Z); 8567 part.AbsolutePosition.Z);
7834 // For some reason, the part.AbsolutePosition.* values do not change if the
7835 // linkset is rotated; they always reflect the child prim's world position
7836 // as though the linkset is unrotated. This is incompatible behavior with SL's
7837 // implementation, so will break scripts imported from there (not to mention it
7838 // makes it more difficult to determine a child prim's actual inworld position).
7839 if (part.ParentID != 0)
7840 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7841 res.Add(v); 8568 res.Add(v);
7842 break; 8569 break;
7843 8570
@@ -8008,56 +8735,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8008 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8735 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8009 if (remain < 1) 8736 if (remain < 1)
8010 return res; 8737 return res;
8011 8738 face = (int)rules.GetLSLIntegerItem(idx++);
8012 face=(int)rules.GetLSLIntegerItem(idx++);
8013 8739
8014 tex = part.Shape.Textures; 8740 tex = part.Shape.Textures;
8741 int shiny;
8015 if (face == ScriptBaseClass.ALL_SIDES) 8742 if (face == ScriptBaseClass.ALL_SIDES)
8016 { 8743 {
8017 for (face = 0; face < GetNumberOfSides(part); face++) 8744 for (face = 0; face < GetNumberOfSides(part); face++)
8018 { 8745 {
8019 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8746 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8020 // Convert Shininess to PRIM_SHINY_* 8747 if (shinyness == Shininess.High)
8021 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8748 {
8022 // PRIM_BUMP_* 8749 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8023 res.Add(new LSL_Integer((int)texface.Bump)); 8750 }
8751 else if (shinyness == Shininess.Medium)
8752 {
8753 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8754 }
8755 else if (shinyness == Shininess.Low)
8756 {
8757 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8758 }
8759 else
8760 {
8761 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8762 }
8763 res.Add(new LSL_Integer(shiny));
8764 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8024 } 8765 }
8025 } 8766 }
8026 else 8767 else
8027 { 8768 {
8028 if (face >= 0 && face < GetNumberOfSides(part)) 8769 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8770 if (shinyness == Shininess.High)
8029 { 8771 {
8030 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8772 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8031 // Convert Shininess to PRIM_SHINY_* 8773 }
8032 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8774 else if (shinyness == Shininess.Medium)
8033 // PRIM_BUMP_* 8775 {
8034 res.Add(new LSL_Integer((int)texface.Bump)); 8776 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8777 }
8778 else if (shinyness == Shininess.Low)
8779 {
8780 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8035 } 8781 }
8782 else
8783 {
8784 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8785 }
8786 res.Add(new LSL_Integer(shiny));
8787 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8036 } 8788 }
8037 break; 8789 break;
8038 8790
8039 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8791 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8040 if (remain < 1) 8792 if (remain < 1)
8041 return res; 8793 return res;
8042 8794 face = (int)rules.GetLSLIntegerItem(idx++);
8043 face=(int)rules.GetLSLIntegerItem(idx++);
8044 8795
8045 tex = part.Shape.Textures; 8796 tex = part.Shape.Textures;
8797 int fullbright;
8046 if (face == ScriptBaseClass.ALL_SIDES) 8798 if (face == ScriptBaseClass.ALL_SIDES)
8047 { 8799 {
8048 for (face = 0; face < GetNumberOfSides(part); face++) 8800 for (face = 0; face < GetNumberOfSides(part); face++)
8049 { 8801 {
8050 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8802 if (tex.GetFace((uint)face).Fullbright == true)
8051 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8803 {
8804 fullbright = ScriptBaseClass.TRUE;
8805 }
8806 else
8807 {
8808 fullbright = ScriptBaseClass.FALSE;
8809 }
8810 res.Add(new LSL_Integer(fullbright));
8052 } 8811 }
8053 } 8812 }
8054 else 8813 else
8055 { 8814 {
8056 if (face >= 0 && face < GetNumberOfSides(part)) 8815 if (tex.GetFace((uint)face).Fullbright == true)
8057 { 8816 {
8058 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8817 fullbright = ScriptBaseClass.TRUE;
8059 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8060 } 8818 }
8819 else
8820 {
8821 fullbright = ScriptBaseClass.FALSE;
8822 }
8823 res.Add(new LSL_Integer(fullbright));
8061 } 8824 }
8062 break; 8825 break;
8063 8826
@@ -8079,27 +8842,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8079 break; 8842 break;
8080 8843
8081 case (int)ScriptBaseClass.PRIM_TEXGEN: 8844 case (int)ScriptBaseClass.PRIM_TEXGEN:
8845 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8082 if (remain < 1) 8846 if (remain < 1)
8083 return res; 8847 return res;
8084 8848 face = (int)rules.GetLSLIntegerItem(idx++);
8085 face=(int)rules.GetLSLIntegerItem(idx++);
8086 8849
8087 tex = part.Shape.Textures; 8850 tex = part.Shape.Textures;
8088 if (face == ScriptBaseClass.ALL_SIDES) 8851 if (face == ScriptBaseClass.ALL_SIDES)
8089 { 8852 {
8090 for (face = 0; face < GetNumberOfSides(part); face++) 8853 for (face = 0; face < GetNumberOfSides(part); face++)
8091 { 8854 {
8092 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8855 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8093 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8856 {
8094 res.Add(new LSL_Integer((uint)texgen >> 1)); 8857 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8858 }
8859 else
8860 {
8861 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8862 }
8095 } 8863 }
8096 } 8864 }
8097 else 8865 else
8098 { 8866 {
8099 if (face >= 0 && face < GetNumberOfSides(part)) 8867 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8868 {
8869 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8870 }
8871 else
8100 { 8872 {
8101 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8873 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8102 res.Add(new LSL_Integer((uint)texgen >> 1));
8103 } 8874 }
8104 } 8875 }
8105 break; 8876 break;
@@ -8122,28 +8893,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8122 case (int)ScriptBaseClass.PRIM_GLOW: 8893 case (int)ScriptBaseClass.PRIM_GLOW:
8123 if (remain < 1) 8894 if (remain < 1)
8124 return res; 8895 return res;
8125 8896 face = (int)rules.GetLSLIntegerItem(idx++);
8126 face=(int)rules.GetLSLIntegerItem(idx++);
8127 8897
8128 tex = part.Shape.Textures; 8898 tex = part.Shape.Textures;
8899 float primglow;
8129 if (face == ScriptBaseClass.ALL_SIDES) 8900 if (face == ScriptBaseClass.ALL_SIDES)
8130 { 8901 {
8131 for (face = 0; face < GetNumberOfSides(part); face++) 8902 for (face = 0; face < GetNumberOfSides(part); face++)
8132 { 8903 {
8133 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8904 primglow = tex.GetFace((uint)face).Glow;
8134 res.Add(new LSL_Float(texface.Glow)); 8905 res.Add(new LSL_Float(primglow));
8135 } 8906 }
8136 } 8907 }
8137 else 8908 else
8138 { 8909 {
8139 if (face >= 0 && face < GetNumberOfSides(part)) 8910 primglow = tex.GetFace((uint)face).Glow;
8140 { 8911 res.Add(new LSL_Float(primglow));
8141 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8142 res.Add(new LSL_Float(texface.Glow));
8143 }
8144 } 8912 }
8145 break; 8913 break;
8146
8147 case (int)ScriptBaseClass.PRIM_TEXT: 8914 case (int)ScriptBaseClass.PRIM_TEXT:
8148 Color4 textColor = part.GetTextColor(); 8915 Color4 textColor = part.GetTextColor();
8149 res.Add(new LSL_String(part.Text)); 8916 res.Add(new LSL_String(part.Text));
@@ -8755,8 +9522,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8755 // The function returns an ordered list 9522 // The function returns an ordered list
8756 // representing the tokens found in the supplied 9523 // representing the tokens found in the supplied
8757 // sources string. If two successive tokenizers 9524 // sources string. If two successive tokenizers
8758 // are encountered, then a NULL entry is added 9525 // are encountered, then a null-string entry is
8759 // to the list. 9526 // added to the list.
8760 // 9527 //
8761 // It is a precondition that the source and 9528 // It is a precondition that the source and
8762 // toekizer lisst are non-null. If they are null, 9529 // toekizer lisst are non-null. If they are null,
@@ -8764,7 +9531,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8764 // while their lengths are being determined. 9531 // while their lengths are being determined.
8765 // 9532 //
8766 // A small amount of working memoryis required 9533 // A small amount of working memoryis required
8767 // of approximately 8*#tokenizers. 9534 // of approximately 8*#tokenizers + 8*srcstrlen.
8768 // 9535 //
8769 // There are many ways in which this function 9536 // There are many ways in which this function
8770 // can be implemented, this implementation is 9537 // can be implemented, this implementation is
@@ -8780,155 +9547,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8780 // and eliminates redundant tokenizers as soon 9547 // and eliminates redundant tokenizers as soon
8781 // as is possible. 9548 // as is possible.
8782 // 9549 //
8783 // The implementation tries to avoid any copying 9550 // The implementation tries to minimize temporary
8784 // of arrays or other objects. 9551 // garbage generation.
8785 // </remarks> 9552 // </remarks>
8786 9553
8787 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9554 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8788 { 9555 {
8789 int beginning = 0; 9556 return ParseString2List(src, separators, spacers, true);
8790 int srclen = src.Length; 9557 }
8791 int seplen = separators.Length;
8792 object[] separray = separators.Data;
8793 int spclen = spacers.Length;
8794 object[] spcarray = spacers.Data;
8795 int mlen = seplen+spclen;
8796
8797 int[] offset = new int[mlen+1];
8798 bool[] active = new bool[mlen];
8799
8800 int best;
8801 int j;
8802
8803 // Initial capacity reduces resize cost
8804 9558
8805 LSL_List tokens = new LSL_List(); 9559 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9560 {
9561 int srclen = src.Length;
9562 int seplen = separators.Length;
9563 object[] separray = separators.Data;
9564 int spclen = spacers.Length;
9565 object[] spcarray = spacers.Data;
9566 int dellen = 0;
9567 string[] delarray = new string[seplen+spclen];
8806 9568
8807 // All entries are initially valid 9569 int outlen = 0;
9570 string[] outarray = new string[srclen*2+1];
8808 9571
8809 for (int i = 0; i < mlen; i++) 9572 int i, j;
8810 active[i] = true; 9573 string d;
8811 9574
8812 offset[mlen] = srclen; 9575 m_host.AddScriptLPS(1);
8813 9576
8814 while (beginning < srclen) 9577 /*
9578 * Convert separator and spacer lists to C# strings.
9579 * Also filter out null strings so we don't hang.
9580 */
9581 for (i = 0; i < seplen; i ++)
8815 { 9582 {
9583 d = separray[i].ToString();
9584 if (d.Length > 0)
9585 {
9586 delarray[dellen++] = d;
9587 }
9588 }
9589 seplen = dellen;
8816 9590
8817 best = mlen; // as bad as it gets 9591 for (i = 0; i < spclen; i ++)
9592 {
9593 d = spcarray[i].ToString();
9594 if (d.Length > 0)
9595 {
9596 delarray[dellen++] = d;
9597 }
9598 }
8818 9599
8819 // Scan for separators 9600 /*
9601 * Scan through source string from beginning to end.
9602 */
9603 for (i = 0;;)
9604 {
8820 9605
8821 for (j = 0; j < seplen; j++) 9606 /*
9607 * Find earliest delimeter in src starting at i (if any).
9608 */
9609 int earliestDel = -1;
9610 int earliestSrc = srclen;
9611 string earliestStr = null;
9612 for (j = 0; j < dellen; j ++)
8822 { 9613 {
8823 if (separray[j].ToString() == String.Empty) 9614 d = delarray[j];
8824 active[j] = false; 9615 if (d != null)
8825
8826 if (active[j])
8827 { 9616 {
8828 // scan all of the markers 9617 int index = src.IndexOf(d, i);
8829 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9618 if (index < 0)
8830 { 9619 {
8831 // not present at all 9620 delarray[j] = null; // delim nowhere in src, don't check it anymore
8832 active[j] = false;
8833 } 9621 }
8834 else 9622 else if (index < earliestSrc)
8835 { 9623 {
8836 // present and correct 9624 earliestSrc = index; // where delimeter starts in source string
8837 if (offset[j] < offset[best]) 9625 earliestDel = j; // where delimeter is in delarray[]
8838 { 9626 earliestStr = d; // the delimeter string from delarray[]
8839 // closest so far 9627 if (index == i) break; // can't do any better than found at beg of string
8840 best = j;
8841 if (offset[best] == beginning)
8842 break;
8843 }
8844 } 9628 }
8845 } 9629 }
8846 } 9630 }
8847 9631
8848 // Scan for spacers 9632 /*
8849 9633 * Output source string starting at i through start of earliest delimeter.
8850 if (offset[best] != beginning) 9634 */
9635 if (keepNulls || (earliestSrc > i))
8851 { 9636 {
8852 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9637 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8853 {
8854 if (spcarray[j-seplen].ToString() == String.Empty)
8855 active[j] = false;
8856
8857 if (active[j])
8858 {
8859 // scan all of the markers
8860 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8861 {
8862 // not present at all
8863 active[j] = false;
8864 }
8865 else
8866 {
8867 // present and correct
8868 if (offset[j] < offset[best])
8869 {
8870 // closest so far
8871 best = j;
8872 }
8873 }
8874 }
8875 }
8876 } 9638 }
8877 9639
8878 // This is the normal exit from the scanning loop 9640 /*
9641 * If no delimeter found at or after i, we're done scanning.
9642 */
9643 if (earliestDel < 0) break;
8879 9644
8880 if (best == mlen) 9645 /*
9646 * If delimeter was a spacer, output the spacer.
9647 */
9648 if (earliestDel >= seplen)
8881 { 9649 {
8882 // no markers were found on this pass 9650 outarray[outlen++] = earliestStr;
8883 // so we're pretty much done
8884 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8885 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8886 break;
8887 } 9651 }
8888 9652
8889 // Otherwise we just add the newly delimited token 9653 /*
8890 // and recalculate where the search should continue. 9654 * Look at rest of src string following delimeter.
8891 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9655 */
8892 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9656 i = earliestSrc + earliestStr.Length;
8893
8894 if (best < seplen)
8895 {
8896 beginning = offset[best] + (separray[best].ToString()).Length;
8897 }
8898 else
8899 {
8900 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8901 string str = spcarray[best - seplen].ToString();
8902 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8903 tokens.Add(new LSL_String(str));
8904 }
8905 } 9657 }
8906 9658
8907 // This an awkward an not very intuitive boundary case. If the 9659 /*
8908 // last substring is a tokenizer, then there is an implied trailing 9660 * Make up an exact-sized output array suitable for an LSL_List object.
8909 // null list entry. Hopefully the single comparison will not be too 9661 */
8910 // arduous. Alternatively the 'break' could be replced with a return 9662 object[] outlist = new object[outlen];
8911 // but that's shabby programming. 9663 for (i = 0; i < outlen; i ++)
8912
8913 if ((beginning == srclen) && (keepNulls))
8914 { 9664 {
8915 if (srclen != 0) 9665 outlist[i] = new LSL_String(outarray[i]);
8916 tokens.Add(new LSL_String(""));
8917 } 9666 }
8918 9667 return new LSL_List(outlist);
8919 return tokens;
8920 }
8921
8922 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8923 {
8924 m_host.AddScriptLPS(1);
8925 return this.ParseString(src, separators, spacers, false);
8926 }
8927
8928 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8929 {
8930 m_host.AddScriptLPS(1);
8931 return this.ParseString(src, separators, spacers, true);
8932 } 9668 }
8933 9669
8934 public LSL_Integer llGetObjectPermMask(int mask) 9670 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9005,28 +9741,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9005 { 9741 {
9006 m_host.AddScriptLPS(1); 9742 m_host.AddScriptLPS(1);
9007 9743
9008 lock (m_host.TaskInventory) 9744 m_host.TaskInventory.LockItemsForRead(true);
9745 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9009 { 9746 {
9010 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9747 if (inv.Value.Name == item)
9011 { 9748 {
9012 if (inv.Value.Name == item) 9749 m_host.TaskInventory.LockItemsForRead(false);
9750 switch (mask)
9013 { 9751 {
9014 switch (mask) 9752 case 0:
9015 { 9753 return (int)inv.Value.BasePermissions;
9016 case 0: 9754 case 1:
9017 return (int)inv.Value.BasePermissions; 9755 return (int)inv.Value.CurrentPermissions;
9018 case 1: 9756 case 2:
9019 return (int)inv.Value.CurrentPermissions; 9757 return (int)inv.Value.GroupPermissions;
9020 case 2: 9758 case 3:
9021 return (int)inv.Value.GroupPermissions; 9759 return (int)inv.Value.EveryonePermissions;
9022 case 3: 9760 case 4:
9023 return (int)inv.Value.EveryonePermissions; 9761 return (int)inv.Value.NextPermissions;
9024 case 4:
9025 return (int)inv.Value.NextPermissions;
9026 }
9027 } 9762 }
9028 } 9763 }
9029 } 9764 }
9765 m_host.TaskInventory.LockItemsForRead(false);
9030 9766
9031 return -1; 9767 return -1;
9032 } 9768 }
@@ -9073,16 +9809,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9073 { 9809 {
9074 m_host.AddScriptLPS(1); 9810 m_host.AddScriptLPS(1);
9075 9811
9076 lock (m_host.TaskInventory) 9812 m_host.TaskInventory.LockItemsForRead(true);
9813 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9077 { 9814 {
9078 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9815 if (inv.Value.Name == item)
9079 { 9816 {
9080 if (inv.Value.Name == item) 9817 m_host.TaskInventory.LockItemsForRead(false);
9081 { 9818 return inv.Value.CreatorID.ToString();
9082 return inv.Value.CreatorID.ToString();
9083 }
9084 } 9819 }
9085 } 9820 }
9821 m_host.TaskInventory.LockItemsForRead(false);
9086 9822
9087 llSay(0, "No item name '" + item + "'"); 9823 llSay(0, "No item name '" + item + "'");
9088 9824
@@ -9230,7 +9966,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9230 } 9966 }
9231 9967
9232 /// <summary> 9968 /// <summary>
9233 /// illListReplaceList removes the sub-list defined by the inclusive indices 9969 /// llListReplaceList removes the sub-list defined by the inclusive indices
9234 /// start and end and inserts the src list in its place. The inclusive 9970 /// start and end and inserts the src list in its place. The inclusive
9235 /// nature of the indices means that at least one element must be deleted 9971 /// nature of the indices means that at least one element must be deleted
9236 /// if the indices are within the bounds of the existing list. I.e. 2,2 9972 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9287,16 +10023,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9287 // based upon end. Note that if end exceeds the upper 10023 // based upon end. Note that if end exceeds the upper
9288 // bound in this case, the entire destination list 10024 // bound in this case, the entire destination list
9289 // is removed. 10025 // is removed.
9290 else 10026 else if (start == 0)
9291 { 10027 {
9292 if (end + 1 < dest.Length) 10028 if (end + 1 < dest.Length)
9293 {
9294 return src + dest.GetSublist(end + 1, -1); 10029 return src + dest.GetSublist(end + 1, -1);
9295 }
9296 else 10030 else
9297 {
9298 return src; 10031 return src;
9299 } 10032 }
10033 else // Start < 0
10034 {
10035 if (end + 1 < dest.Length)
10036 return dest.GetSublist(end + 1, -1);
10037 else
10038 return new LSL_List();
9300 } 10039 }
9301 } 10040 }
9302 // Finally, if start > end, we strip away a prefix and 10041 // Finally, if start > end, we strip away a prefix and
@@ -9347,17 +10086,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9347 int width = 0; 10086 int width = 0;
9348 int height = 0; 10087 int height = 0;
9349 10088
9350 ParcelMediaCommandEnum? commandToSend = null; 10089 uint commandToSend = 0;
9351 float time = 0.0f; // default is from start 10090 float time = 0.0f; // default is from start
9352 10091
9353 ScenePresence presence = null; 10092 ScenePresence presence = null;
9354 10093
9355 for (int i = 0; i < commandList.Data.Length; i++) 10094 for (int i = 0; i < commandList.Data.Length; i++)
9356 { 10095 {
9357 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10096 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9358 switch (command) 10097 switch (command)
9359 { 10098 {
9360 case ParcelMediaCommandEnum.Agent: 10099 case (uint)ParcelMediaCommandEnum.Agent:
9361 // we send only to one agent 10100 // we send only to one agent
9362 if ((i + 1) < commandList.Length) 10101 if ((i + 1) < commandList.Length)
9363 { 10102 {
@@ -9374,25 +10113,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9374 } 10113 }
9375 break; 10114 break;
9376 10115
9377 case ParcelMediaCommandEnum.Loop: 10116 case (uint)ParcelMediaCommandEnum.Loop:
9378 loop = 1; 10117 loop = 1;
9379 commandToSend = command; 10118 commandToSend = command;
9380 update = true; //need to send the media update packet to set looping 10119 update = true; //need to send the media update packet to set looping
9381 break; 10120 break;
9382 10121
9383 case ParcelMediaCommandEnum.Play: 10122 case (uint)ParcelMediaCommandEnum.Play:
9384 loop = 0; 10123 loop = 0;
9385 commandToSend = command; 10124 commandToSend = command;
9386 update = true; //need to send the media update packet to make sure it doesn't loop 10125 update = true; //need to send the media update packet to make sure it doesn't loop
9387 break; 10126 break;
9388 10127
9389 case ParcelMediaCommandEnum.Pause: 10128 case (uint)ParcelMediaCommandEnum.Pause:
9390 case ParcelMediaCommandEnum.Stop: 10129 case (uint)ParcelMediaCommandEnum.Stop:
9391 case ParcelMediaCommandEnum.Unload: 10130 case (uint)ParcelMediaCommandEnum.Unload:
9392 commandToSend = command; 10131 commandToSend = command;
9393 break; 10132 break;
9394 10133
9395 case ParcelMediaCommandEnum.Url: 10134 case (uint)ParcelMediaCommandEnum.Url:
9396 if ((i + 1) < commandList.Length) 10135 if ((i + 1) < commandList.Length)
9397 { 10136 {
9398 if (commandList.Data[i + 1] is LSL_String) 10137 if (commandList.Data[i + 1] is LSL_String)
@@ -9405,7 +10144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9405 } 10144 }
9406 break; 10145 break;
9407 10146
9408 case ParcelMediaCommandEnum.Texture: 10147 case (uint)ParcelMediaCommandEnum.Texture:
9409 if ((i + 1) < commandList.Length) 10148 if ((i + 1) < commandList.Length)
9410 { 10149 {
9411 if (commandList.Data[i + 1] is LSL_String) 10150 if (commandList.Data[i + 1] is LSL_String)
@@ -9418,7 +10157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9418 } 10157 }
9419 break; 10158 break;
9420 10159
9421 case ParcelMediaCommandEnum.Time: 10160 case (uint)ParcelMediaCommandEnum.Time:
9422 if ((i + 1) < commandList.Length) 10161 if ((i + 1) < commandList.Length)
9423 { 10162 {
9424 if (commandList.Data[i + 1] is LSL_Float) 10163 if (commandList.Data[i + 1] is LSL_Float)
@@ -9430,7 +10169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9430 } 10169 }
9431 break; 10170 break;
9432 10171
9433 case ParcelMediaCommandEnum.AutoAlign: 10172 case (uint)ParcelMediaCommandEnum.AutoAlign:
9434 if ((i + 1) < commandList.Length) 10173 if ((i + 1) < commandList.Length)
9435 { 10174 {
9436 if (commandList.Data[i + 1] is LSL_Integer) 10175 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9444,7 +10183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9444 } 10183 }
9445 break; 10184 break;
9446 10185
9447 case ParcelMediaCommandEnum.Type: 10186 case (uint)ParcelMediaCommandEnum.Type:
9448 if ((i + 1) < commandList.Length) 10187 if ((i + 1) < commandList.Length)
9449 { 10188 {
9450 if (commandList.Data[i + 1] is LSL_String) 10189 if (commandList.Data[i + 1] is LSL_String)
@@ -9457,7 +10196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9457 } 10196 }
9458 break; 10197 break;
9459 10198
9460 case ParcelMediaCommandEnum.Desc: 10199 case (uint)ParcelMediaCommandEnum.Desc:
9461 if ((i + 1) < commandList.Length) 10200 if ((i + 1) < commandList.Length)
9462 { 10201 {
9463 if (commandList.Data[i + 1] is LSL_String) 10202 if (commandList.Data[i + 1] is LSL_String)
@@ -9470,7 +10209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9470 } 10209 }
9471 break; 10210 break;
9472 10211
9473 case ParcelMediaCommandEnum.Size: 10212 case (uint)ParcelMediaCommandEnum.Size:
9474 if ((i + 2) < commandList.Length) 10213 if ((i + 2) < commandList.Length)
9475 { 10214 {
9476 if (commandList.Data[i + 1] is LSL_Integer) 10215 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9540,7 +10279,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9540 } 10279 }
9541 } 10280 }
9542 10281
9543 if (commandToSend != null) 10282 if (commandToSend != 0)
9544 { 10283 {
9545 // the commandList contained a start/stop/... command, too 10284 // the commandList contained a start/stop/... command, too
9546 if (presence == null) 10285 if (presence == null)
@@ -9577,7 +10316,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9577 10316
9578 if (aList.Data[i] != null) 10317 if (aList.Data[i] != null)
9579 { 10318 {
9580 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10319 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9581 { 10320 {
9582 case ParcelMediaCommandEnum.Url: 10321 case ParcelMediaCommandEnum.Url:
9583 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10322 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9620,16 +10359,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9620 { 10359 {
9621 m_host.AddScriptLPS(1); 10360 m_host.AddScriptLPS(1);
9622 10361
9623 lock (m_host.TaskInventory) 10362 m_host.TaskInventory.LockItemsForRead(true);
10363 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9624 { 10364 {
9625 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10365 if (inv.Value.Name == name)
9626 { 10366 {
9627 if (inv.Value.Name == name) 10367 m_host.TaskInventory.LockItemsForRead(false);
9628 { 10368 return inv.Value.Type;
9629 return inv.Value.Type;
9630 }
9631 } 10369 }
9632 } 10370 }
10371 m_host.TaskInventory.LockItemsForRead(false);
9633 10372
9634 return -1; 10373 return -1;
9635 } 10374 }
@@ -9640,15 +10379,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9640 10379
9641 if (quick_pay_buttons.Data.Length < 4) 10380 if (quick_pay_buttons.Data.Length < 4)
9642 { 10381 {
9643 LSLError("List must have at least 4 elements"); 10382 int x;
9644 return; 10383 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10384 {
10385 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10386 }
9645 } 10387 }
9646 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10388 int[] nPrice = new int[5];
9647 10389 nPrice[0] = price;
9648 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10390 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9649 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10391 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9650 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10392 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9651 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10393 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10394 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9652 m_host.ParentGroup.HasGroupChanged = true; 10395 m_host.ParentGroup.HasGroupChanged = true;
9653 } 10396 }
9654 10397
@@ -9660,17 +10403,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9660 if (invItemID == UUID.Zero) 10403 if (invItemID == UUID.Zero)
9661 return new LSL_Vector(); 10404 return new LSL_Vector();
9662 10405
9663 lock (m_host.TaskInventory) 10406 m_host.TaskInventory.LockItemsForRead(true);
10407 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9664 { 10408 {
9665 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10409 m_host.TaskInventory.LockItemsForRead(false);
9666 return new LSL_Vector(); 10410 return new LSL_Vector();
10411 }
9667 10412
9668 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10413 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9669 { 10414 {
9670 ShoutError("No permissions to track the camera"); 10415 ShoutError("No permissions to track the camera");
9671 return new LSL_Vector(); 10416 m_host.TaskInventory.LockItemsForRead(false);
9672 } 10417 return new LSL_Vector();
9673 } 10418 }
10419 m_host.TaskInventory.LockItemsForRead(false);
9674 10420
9675 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10421 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9676 if (presence != null) 10422 if (presence != null)
@@ -9688,17 +10434,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9688 if (invItemID == UUID.Zero) 10434 if (invItemID == UUID.Zero)
9689 return new LSL_Rotation(); 10435 return new LSL_Rotation();
9690 10436
9691 lock (m_host.TaskInventory) 10437 m_host.TaskInventory.LockItemsForRead(true);
10438 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9692 { 10439 {
9693 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10440 m_host.TaskInventory.LockItemsForRead(false);
9694 return new LSL_Rotation(); 10441 return new LSL_Rotation();
9695
9696 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9697 {
9698 ShoutError("No permissions to track the camera");
9699 return new LSL_Rotation();
9700 }
9701 } 10442 }
10443 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10444 {
10445 ShoutError("No permissions to track the camera");
10446 m_host.TaskInventory.LockItemsForRead(false);
10447 return new LSL_Rotation();
10448 }
10449 m_host.TaskInventory.LockItemsForRead(false);
9702 10450
9703 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10451 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9704 if (presence != null) 10452 if (presence != null)
@@ -9760,8 +10508,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9760 { 10508 {
9761 m_host.AddScriptLPS(1); 10509 m_host.AddScriptLPS(1);
9762 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10510 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9763 if (detectedParams == null) return; // only works on the first detected avatar 10511 if (detectedParams == null)
9764 10512 {
10513 if (m_host.ParentGroup.IsAttachment == true)
10514 {
10515 detectedParams = new DetectParams();
10516 detectedParams.Key = m_host.OwnerID;
10517 }
10518 else
10519 {
10520 return;
10521 }
10522 }
10523
9765 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10524 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9766 if (avatar != null) 10525 if (avatar != null)
9767 { 10526 {
@@ -9769,6 +10528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9769 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10528 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9770 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10529 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9771 } 10530 }
10531
9772 ScriptSleep(1000); 10532 ScriptSleep(1000);
9773 } 10533 }
9774 10534
@@ -9880,14 +10640,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9880 if (objectID == UUID.Zero) return; 10640 if (objectID == UUID.Zero) return;
9881 10641
9882 UUID agentID; 10642 UUID agentID;
9883 lock (m_host.TaskInventory) 10643 m_host.TaskInventory.LockItemsForRead(true);
9884 { 10644 // we need the permission first, to know which avatar we want to set the camera for
9885 // we need the permission first, to know which avatar we want to set the camera for 10645 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9886 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9887 10646
9888 if (agentID == UUID.Zero) return; 10647 if (agentID == UUID.Zero)
9889 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10648 {
10649 m_host.TaskInventory.LockItemsForRead(false);
10650 return;
9890 } 10651 }
10652 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10653 {
10654 m_host.TaskInventory.LockItemsForRead(false);
10655 return;
10656 }
10657 m_host.TaskInventory.LockItemsForRead(false);
9891 10658
9892 ScenePresence presence = World.GetScenePresence(agentID); 10659 ScenePresence presence = World.GetScenePresence(agentID);
9893 10660
@@ -9896,12 +10663,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9896 10663
9897 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10664 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9898 object[] data = rules.Data; 10665 object[] data = rules.Data;
9899 for (int i = 0; i < data.Length; ++i) { 10666 for (int i = 0; i < data.Length; ++i)
10667 {
9900 int type = Convert.ToInt32(data[i++].ToString()); 10668 int type = Convert.ToInt32(data[i++].ToString());
9901 if (i >= data.Length) break; // odd number of entries => ignore the last 10669 if (i >= data.Length) break; // odd number of entries => ignore the last
9902 10670
9903 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10671 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9904 switch (type) { 10672 switch (type)
10673 {
9905 case ScriptBaseClass.CAMERA_FOCUS: 10674 case ScriptBaseClass.CAMERA_FOCUS:
9906 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10675 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9907 case ScriptBaseClass.CAMERA_POSITION: 10676 case ScriptBaseClass.CAMERA_POSITION:
@@ -9937,12 +10706,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9937 10706
9938 // we need the permission first, to know which avatar we want to clear the camera for 10707 // we need the permission first, to know which avatar we want to clear the camera for
9939 UUID agentID; 10708 UUID agentID;
9940 lock (m_host.TaskInventory) 10709 m_host.TaskInventory.LockItemsForRead(true);
10710 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10711 if (agentID == UUID.Zero)
9941 { 10712 {
9942 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10713 m_host.TaskInventory.LockItemsForRead(false);
9943 if (agentID == UUID.Zero) return; 10714 return;
9944 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10715 }
10716 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10717 {
10718 m_host.TaskInventory.LockItemsForRead(false);
10719 return;
9945 } 10720 }
10721 m_host.TaskInventory.LockItemsForRead(false);
9946 10722
9947 ScenePresence presence = World.GetScenePresence(agentID); 10723 ScenePresence presence = World.GetScenePresence(agentID);
9948 10724
@@ -10009,19 +10785,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10009 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10785 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10010 { 10786 {
10011 m_host.AddScriptLPS(1); 10787 m_host.AddScriptLPS(1);
10012 string ret = String.Empty; 10788
10013 string src1 = llBase64ToString(str1); 10789 if (str1 == String.Empty)
10014 string src2 = llBase64ToString(str2); 10790 return String.Empty;
10015 int c = 0; 10791 if (str2 == String.Empty)
10016 for (int i = 0; i < src1.Length; i++) 10792 return str1;
10793
10794 int len = str2.Length;
10795 if ((len % 4) != 0) // LL is EVIL!!!!
10017 { 10796 {
10018 ret += (char) (src1[i] ^ src2[c]); 10797 while (str2.EndsWith("="))
10798 str2 = str2.Substring(0, str2.Length - 1);
10799
10800 len = str2.Length;
10801 int mod = len % 4;
10019 10802
10020 c++; 10803 if (mod == 1)
10021 if (c >= src2.Length) 10804 str2 = str2.Substring(0, str2.Length - 1);
10022 c = 0; 10805 else if (mod == 2)
10806 str2 += "==";
10807 else if (mod == 3)
10808 str2 += "=";
10023 } 10809 }
10024 return llStringToBase64(ret); 10810
10811 byte[] data1;
10812 byte[] data2;
10813 try
10814 {
10815 data1 = Convert.FromBase64String(str1);
10816 data2 = Convert.FromBase64String(str2);
10817 }
10818 catch (Exception)
10819 {
10820 return new LSL_String(String.Empty);
10821 }
10822
10823 byte[] d2 = new Byte[data1.Length];
10824 int pos = 0;
10825
10826 if (data1.Length <= data2.Length)
10827 {
10828 Array.Copy(data2, 0, d2, 0, data1.Length);
10829 }
10830 else
10831 {
10832 while (pos < data1.Length)
10833 {
10834 len = data1.Length - pos;
10835 if (len > data2.Length)
10836 len = data2.Length;
10837
10838 Array.Copy(data2, 0, d2, pos, len);
10839 pos += len;
10840 }
10841 }
10842
10843 for (pos = 0 ; pos < data1.Length ; pos++ )
10844 data1[pos] ^= d2[pos];
10845
10846 return Convert.ToBase64String(data1);
10025 } 10847 }
10026 10848
10027 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10849 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10078,12 +10900,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10078 Regex r = new Regex(authregex); 10900 Regex r = new Regex(authregex);
10079 int[] gnums = r.GetGroupNumbers(); 10901 int[] gnums = r.GetGroupNumbers();
10080 Match m = r.Match(url); 10902 Match m = r.Match(url);
10081 if (m.Success) { 10903 if (m.Success)
10082 for (int i = 1; i < gnums.Length; i++) { 10904 {
10905 for (int i = 1; i < gnums.Length; i++)
10906 {
10083 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10907 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10084 //CaptureCollection cc = g.Captures; 10908 //CaptureCollection cc = g.Captures;
10085 } 10909 }
10086 if (m.Groups.Count == 5) { 10910 if (m.Groups.Count == 5)
10911 {
10087 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10912 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10088 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10913 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10089 } 10914 }
@@ -10369,15 +11194,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10369 11194
10370 internal UUID ScriptByName(string name) 11195 internal UUID ScriptByName(string name)
10371 { 11196 {
10372 lock (m_host.TaskInventory) 11197 m_host.TaskInventory.LockItemsForRead(true);
11198
11199 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10373 { 11200 {
10374 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11201 if (item.Type == 10 && item.Name == name)
10375 { 11202 {
10376 if (item.Type == 10 && item.Name == name) 11203 m_host.TaskInventory.LockItemsForRead(false);
10377 return item.ItemID; 11204 return item.ItemID;
10378 } 11205 }
10379 } 11206 }
10380 11207
11208 m_host.TaskInventory.LockItemsForRead(false);
11209
10381 return UUID.Zero; 11210 return UUID.Zero;
10382 } 11211 }
10383 11212
@@ -10418,6 +11247,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10418 { 11247 {
10419 m_host.AddScriptLPS(1); 11248 m_host.AddScriptLPS(1);
10420 11249
11250 //Clone is thread safe
10421 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11251 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10422 11252
10423 UUID assetID = UUID.Zero; 11253 UUID assetID = UUID.Zero;
@@ -10480,6 +11310,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10480 { 11310 {
10481 m_host.AddScriptLPS(1); 11311 m_host.AddScriptLPS(1);
10482 11312
11313 //Clone is thread safe
10483 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11314 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10484 11315
10485 UUID assetID = UUID.Zero; 11316 UUID assetID = UUID.Zero;
@@ -10560,15 +11391,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10560 return GetLinkPrimitiveParams(obj, rules); 11391 return GetLinkPrimitiveParams(obj, rules);
10561 } 11392 }
10562 11393
10563 public void print(string str) 11394 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10564 { 11395 {
10565 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11396 List<SceneObjectPart> parts = GetLinkParts(link);
10566 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11397 if (parts.Count < 1)
10567 if (ossl != null) 11398 return 0;
10568 { 11399
10569 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11400 return GetNumberOfSides(parts[0]);
10570 m_log.Info("LSL print():" + str);
10571 }
10572 } 11401 }
10573 11402
10574 private string Name2Username(string name) 11403 private string Name2Username(string name)
@@ -10614,153 +11443,397 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10614 return rq.ToString(); 11443 return rq.ToString();
10615 } 11444 }
10616 11445
11446 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11447 {
11448 m_SayShoutCount = 0;
11449 }
11450
11451 private struct Tri
11452 {
11453 public Vector3 p1;
11454 public Vector3 p2;
11455 public Vector3 p3;
11456 }
11457
11458 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11459 {
11460 float height = avatar.Appearance.AvatarHeight;
11461 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11462 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11463
11464 if (point.X > b1.X && point.X < b2.X &&
11465 point.Y > b1.Y && point.Y < b2.Y &&
11466 point.Z > b1.Z && point.Z < b2.Z)
11467 return true;
11468 return false;
11469 }
11470
11471 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11472 {
11473 List<ContactResult> contacts = new List<ContactResult>();
11474
11475 Vector3 ab = rayEnd - rayStart;
11476
11477 World.ForEachScenePresence(delegate(ScenePresence sp)
11478 {
11479 Vector3 ac = sp.AbsolutePosition - rayStart;
11480 Vector3 bc = sp.AbsolutePosition - rayEnd;
11481
11482 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11483
11484 if (d > 1.5)
11485 return;
11486
11487 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11488
11489 if (d2 > 0)
11490 return;
11491
11492 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11493 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11494
11495 if (!InBoundingBox(sp, p))
11496 return;
11497
11498 ContactResult result = new ContactResult ();
11499 result.ConsumerID = sp.LocalId;
11500 result.Depth = Vector3.Distance(rayStart, p);
11501 result.Normal = Vector3.Zero;
11502 result.Pos = p;
11503
11504 contacts.Add(result);
11505 });
11506
11507 return contacts.ToArray();
11508 }
11509
11510 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11511 {
11512 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11513 List<ContactResult> contacts = new List<ContactResult>();
11514
11515 Vector3 ab = rayEnd - rayStart;
11516
11517 World.ForEachSOG(delegate(SceneObjectGroup group)
11518 {
11519 if (m_host.ParentGroup == group)
11520 return;
11521
11522 if (group.IsAttachment)
11523 return;
11524
11525 if (group.RootPart.PhysActor == null)
11526 {
11527 if (!includePhantom)
11528 return;
11529 }
11530 else
11531 {
11532 if (group.RootPart.PhysActor.IsPhysical)
11533 {
11534 if (!includePhysical)
11535 return;
11536 }
11537 else
11538 {
11539 if (!includeNonPhysical)
11540 return;
11541 }
11542 }
11543
11544 // Find the radius ouside of which we don't even need to hit test
11545 float minX;
11546 float maxX;
11547 float minY;
11548 float maxY;
11549 float minZ;
11550 float maxZ;
11551
11552 float radius = 0.0f;
11553
11554 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11555
11556 if (Math.Abs(minX) > radius)
11557 radius = Math.Abs(minX);
11558 if (Math.Abs(minY) > radius)
11559 radius = Math.Abs(minY);
11560 if (Math.Abs(minZ) > radius)
11561 radius = Math.Abs(minZ);
11562 if (Math.Abs(maxX) > radius)
11563 radius = Math.Abs(maxX);
11564 if (Math.Abs(maxY) > radius)
11565 radius = Math.Abs(maxY);
11566 if (Math.Abs(maxZ) > radius)
11567 radius = Math.Abs(maxZ);
11568
11569 Vector3 ac = group.AbsolutePosition - rayStart;
11570 Vector3 bc = group.AbsolutePosition - rayEnd;
11571
11572 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11573
11574 // Too far off ray, don't bother
11575 if (d > radius)
11576 return;
11577
11578 // Behind ray, drop
11579 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11580 if (d2 > 0)
11581 return;
11582
11583 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11584 // Miss.
11585 if (!intersection.HitTF)
11586 return;
11587
11588 ContactResult result = new ContactResult ();
11589 result.ConsumerID = group.LocalId;
11590 result.Depth = intersection.distance;
11591 result.Normal = intersection.normal;
11592 result.Pos = intersection.ipoint;
11593
11594 contacts.Add(result);
11595 });
11596
11597 return contacts.ToArray();
11598 }
11599
11600 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11601 {
11602 double[,] heightfield = World.Heightmap.GetDoubles();
11603 List<ContactResult> contacts = new List<ContactResult>();
11604
11605 double min = 2048.0;
11606 double max = 0.0;
11607
11608 // Find the min and max of the heightfield
11609 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11610 {
11611 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11612 {
11613 if (heightfield[x, y] > max)
11614 max = heightfield[x, y];
11615 if (heightfield[x, y] < min)
11616 min = heightfield[x, y];
11617 }
11618 }
11619
11620
11621 // A ray extends past rayEnd, but doesn't go back before
11622 // rayStart. If the start is above the highest point of the ground
11623 // and the ray goes up, we can't hit the ground. Ever.
11624 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11625 return null;
11626
11627 // Same for going down
11628 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11629 return null;
11630
11631 List<Tri> trilist = new List<Tri>();
11632
11633 // Create our triangle list
11634 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11635 {
11636 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11637 {
11638 Tri t1 = new Tri();
11639 Tri t2 = new Tri();
11640
11641 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11642 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11643 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11644 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11645
11646 t1.p1 = p1;
11647 t1.p2 = p2;
11648 t1.p3 = p3;
11649
11650 t2.p1 = p3;
11651 t2.p2 = p4;
11652 t2.p3 = p1;
11653
11654 trilist.Add(t1);
11655 trilist.Add(t2);
11656 }
11657 }
11658
11659 // Ray direction
11660 Vector3 rayDirection = rayEnd - rayStart;
11661
11662 foreach (Tri t in trilist)
11663 {
11664 // Compute triangle plane normal and edges
11665 Vector3 u = t.p2 - t.p1;
11666 Vector3 v = t.p3 - t.p1;
11667 Vector3 n = Vector3.Cross(u, v);
11668
11669 if (n == Vector3.Zero)
11670 continue;
11671
11672 Vector3 w0 = rayStart - t.p1;
11673 double a = -Vector3.Dot(n, w0);
11674 double b = Vector3.Dot(n, rayDirection);
11675
11676 // Not intersecting the plane, or in plane (same thing)
11677 // Ignoring this MAY cause the ground to not be detected
11678 // sometimes
11679 if (Math.Abs(b) < 0.000001)
11680 continue;
11681
11682 double r = a / b;
11683
11684 // ray points away from plane
11685 if (r < 0.0)
11686 continue;
11687
11688 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11689
11690 float uu = Vector3.Dot(u, u);
11691 float uv = Vector3.Dot(u, v);
11692 float vv = Vector3.Dot(v, v);
11693 Vector3 w = ip - t.p1;
11694 float wu = Vector3.Dot(w, u);
11695 float wv = Vector3.Dot(w, v);
11696 float d = uv * uv - uu * vv;
11697
11698 float cs = (uv * wv - vv * wu) / d;
11699 if (cs < 0 || cs > 1.0)
11700 continue;
11701 float ct = (uv * wu - uu * wv) / d;
11702 if (ct < 0 || (cs + ct) > 1.0)
11703 continue;
11704
11705 // Add contact point
11706 ContactResult result = new ContactResult ();
11707 result.ConsumerID = 0;
11708 result.Depth = Vector3.Distance(rayStart, ip);
11709 result.Normal = n;
11710 result.Pos = ip;
11711
11712 contacts.Add(result);
11713 }
11714
11715 if (contacts.Count == 0)
11716 return null;
11717
11718 contacts.Sort(delegate(ContactResult a, ContactResult b)
11719 {
11720 return (int)(a.Depth - b.Depth);
11721 });
11722
11723 return contacts[0];
11724 }
11725
10617 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11726 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10618 { 11727 {
11728 LSL_List list = new LSL_List();
11729
10619 m_host.AddScriptLPS(1); 11730 m_host.AddScriptLPS(1);
10620 11731
10621 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11732 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10622 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11733 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10623 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11734 Vector3 dir = rayEnd - rayStart;
10624 11735
10625 int count = 0; 11736 float dist = Vector3.Mag(dir);
10626// int detectPhantom = 0; 11737
11738 int count = 1;
11739 bool detectPhantom = false;
10627 int dataFlags = 0; 11740 int dataFlags = 0;
10628 int rejectTypes = 0; 11741 int rejectTypes = 0;
10629 11742
10630 for (int i = 0; i < options.Length; i += 2) 11743 for (int i = 0; i < options.Length; i += 2)
10631 { 11744 {
10632 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11745 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10633 {
10634 count = options.GetLSLIntegerItem(i + 1); 11746 count = options.GetLSLIntegerItem(i + 1);
10635 } 11747 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10636// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11748 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10637// {
10638// detectPhantom = options.GetLSLIntegerItem(i + 1);
10639// }
10640 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11749 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10641 {
10642 dataFlags = options.GetLSLIntegerItem(i + 1); 11750 dataFlags = options.GetLSLIntegerItem(i + 1);
10643 }
10644 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11751 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10645 {
10646 rejectTypes = options.GetLSLIntegerItem(i + 1); 11752 rejectTypes = options.GetLSLIntegerItem(i + 1);
10647 }
10648 } 11753 }
10649 11754
10650 LSL_List list = new LSL_List(); 11755 if (count > 16)
10651 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11756 count = 16;
10652 11757
10653 double distance = Util.GetDistanceTo(startvector, endvector); 11758 List<ContactResult> results = new List<ContactResult>();
10654
10655 if (distance == 0)
10656 distance = 0.001;
10657
10658 Vector3 posToCheck = startvector;
10659 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10660 11759
10661 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11760 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10662 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11761 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10663 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11762 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10664 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11763 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10665 11764
10666 for (float i = 0; i <= distance; i += 0.1f) 11765 if (checkTerrain)
10667 { 11766 {
10668 posToCheck = startvector + (dir * (i / (float)distance)); 11767 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11768 if (groundContact != null)
11769 results.Add((ContactResult)groundContact);
11770 }
10669 11771
10670 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11772 if (checkAgents)
10671 { 11773 {
10672 ContactResult result = new ContactResult(); 11774 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10673 result.ConsumerID = 0; 11775 foreach (ContactResult r in agentHits)
10674 result.Depth = 0; 11776 results.Add(r);
10675 result.Normal = Vector3.Zero; 11777 }
10676 result.Pos = posToCheck;
10677 results.Add(result);
10678 checkTerrain = false;
10679 }
10680 11778
10681 if (checkAgents) 11779 if (checkPhysical || checkNonPhysical)
10682 { 11780 {
10683 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11781 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10684 { 11782 foreach (ContactResult r in objectHits)
10685 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11783 results.Add(r);
10686 {
10687 ContactResult result = new ContactResult ();
10688 result.ConsumerID = sp.LocalId;
10689 result.Depth = 0;
10690 result.Normal = Vector3.Zero;
10691 result.Pos = posToCheck;
10692 results.Add(result);
10693 }
10694 });
10695 }
10696 } 11784 }
10697 11785
10698 int refcount = 0; 11786 results.Sort(delegate(ContactResult a, ContactResult b)
11787 {
11788 return (int)(a.Depth - b.Depth);
11789 });
11790
11791 int values = 0;
10699 foreach (ContactResult result in results) 11792 foreach (ContactResult result in results)
10700 { 11793 {
10701 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11794 if (result.Depth > dist)
10702 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10703 continue; 11795 continue;
10704 11796
10705 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11797 UUID itemID = UUID.Zero;
10706 11798 int linkNum = 0;
10707 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS)
10708 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents
10709 11799
10710 if (entity == null) 11800 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11801 // It's a prim!
11802 if (part != null)
10711 { 11803 {
10712 list.Add(UUID.Zero); 11804 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10713 11805 itemID = part.ParentGroup.UUID;
10714 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11806 else
10715 list.Add(0); 11807 itemID = part.UUID;
10716
10717 list.Add(result.Pos);
10718
10719 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10720 list.Add(result.Normal);
10721 11808
10722 continue; //Can't find it, so add UUID.Zero 11809 linkNum = part.LinkNum;
10723 } 11810 }
10724 11811 else
10725 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10726 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10727 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10728
10729 if (entity is SceneObjectPart)
10730 { 11812 {
10731 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11813 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10732 { 11814 /// It it a boy? a girl?
10733 if (!checkPhysical) 11815 if (sp != null)
10734 continue; 11816 itemID = sp.UUID;
10735 }
10736 else
10737 {
10738 if (!checkNonPhysical)
10739 continue;
10740 }
10741 } 11817 }
10742 11818
10743 refcount++; 11819 list.Add(new LSL_String(itemID.ToString()));
10744 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11820 list.Add(new LSL_String(result.Pos.ToString()));
10745 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10746 else
10747 list.Add(entity.UUID);
10748 11821
10749 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11822 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10750 { 11823 list.Add(new LSL_Integer(linkNum));
10751 if (entity is SceneObjectPart)
10752 list.Add(((SceneObjectPart)entity).LinkNum);
10753 else
10754 list.Add(0);
10755 }
10756 11824
10757 list.Add(result.Pos);
10758 11825
10759 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11826 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10760 list.Add(result.Normal); 11827 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11828
11829 values++;
11830 count--;
11831
11832 if (count == 0)
11833 break;
10761 } 11834 }
10762 11835
10763 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11836 list.Add(new LSL_Integer(values));
10764 11837
10765 return list; 11838 return list;
10766 } 11839 }
@@ -10800,7 +11873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10800 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11873 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10801 if (!isAccount) return 0; 11874 if (!isAccount) return 0;
10802 if (estate.HasAccess(id)) return 1; 11875 if (estate.HasAccess(id)) return 1;
10803 if (estate.IsBanned(id)) 11876 if (estate.IsBanned(id, World.GetUserFlags(id)))
10804 estate.RemoveBan(id); 11877 estate.RemoveBan(id);
10805 estate.AddEstateUser(id); 11878 estate.AddEstateUser(id);
10806 break; 11879 break;
@@ -10819,14 +11892,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10819 break; 11892 break;
10820 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11893 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10821 if (!isAccount) return 0; 11894 if (!isAccount) return 0;
10822 if (estate.IsBanned(id)) return 1; 11895 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10823 EstateBan ban = new EstateBan(); 11896 EstateBan ban = new EstateBan();
10824 ban.EstateID = estate.EstateID; 11897 ban.EstateID = estate.EstateID;
10825 ban.BannedUserID = id; 11898 ban.BannedUserID = id;
10826 estate.AddBan(ban); 11899 estate.AddBan(ban);
10827 break; 11900 break;
10828 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11901 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10829 if (!isAccount || !estate.IsBanned(id)) return 0; 11902 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10830 estate.RemoveBan(id); 11903 estate.RemoveBan(id);
10831 break; 11904 break;
10832 default: return 0; 11905 default: return 0;
@@ -10852,22 +11925,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10852 NotImplemented("llGetSPMaxMemory"); 11925 NotImplemented("llGetSPMaxMemory");
10853 } 11926 }
10854 11927
10855 public void llGetUsedMemory() 11928 public virtual LSL_Integer llGetUsedMemory()
10856 { 11929 {
10857 m_host.AddScriptLPS(1); 11930 m_host.AddScriptLPS(1);
10858 NotImplemented("llGetUsedMemory"); 11931 NotImplemented("llGetUsedMemory");
11932 return 0;
10859 } 11933 }
10860 11934
10861 public void llScriptProfiler(LSL_Integer flags) 11935 public void llScriptProfiler(LSL_Integer flags)
10862 { 11936 {
10863 m_host.AddScriptLPS(1); 11937 m_host.AddScriptLPS(1);
10864 NotImplemented("llScriptProfiler"); 11938 //NotImplemented("llScriptProfiler");
10865 } 11939 }
10866 11940
10867 public void llSetSoundQueueing(int queue) 11941 public void llSetSoundQueueing(int queue)
10868 { 11942 {
10869 m_host.AddScriptLPS(1); 11943 m_host.AddScriptLPS(1);
10870 NotImplemented("llSetSoundQueueing");
10871 } 11944 }
10872 11945
10873 public void llCollisionSprite(string impact_sprite) 11946 public void llCollisionSprite(string impact_sprite)
@@ -10879,10 +11952,274 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10879 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11952 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10880 { 11953 {
10881 m_host.AddScriptLPS(1); 11954 m_host.AddScriptLPS(1);
10882 NotImplemented("llGodLikeRezObject"); 11955
11956 if (!World.Permissions.IsGod(m_host.OwnerID))
11957 NotImplemented("llGodLikeRezObject");
11958
11959 AssetBase rezAsset = World.AssetService.Get(inventory);
11960 if (rezAsset == null)
11961 {
11962 llSay(0, "Asset not found");
11963 return;
11964 }
11965
11966 SceneObjectGroup group = null;
11967
11968 try
11969 {
11970 string xmlData = Utils.BytesToString(rezAsset.Data);
11971 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11972 }
11973 catch
11974 {
11975 llSay(0, "Asset not found");
11976 return;
11977 }
11978
11979 if (group == null)
11980 {
11981 llSay(0, "Asset not found");
11982 return;
11983 }
11984
11985 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11986 group.RootPart.AttachOffset = group.AbsolutePosition;
11987
11988 group.ResetIDs();
11989
11990 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11991 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11992 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11993 group.ScheduleGroupForFullUpdate();
11994
11995 // objects rezzed with this method are die_at_edge by default.
11996 group.RootPart.SetDieAtEdge(true);
11997
11998 group.ResumeScripts();
11999
12000 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12001 "object_rez", new Object[] {
12002 new LSL_String(
12003 group.RootPart.UUID.ToString()) },
12004 new DetectParams[0]));
12005 }
12006
12007 public LSL_String llTransferLindenDollars(string destination, int amount)
12008 {
12009 UUID txn = UUID.Random();
12010
12011 Util.FireAndForget(delegate(object x)
12012 {
12013 int replycode = 0;
12014 string replydata = destination + "," + amount.ToString();
12015
12016 try
12017 {
12018 UUID invItemID=InventorySelf();
12019 if (invItemID == UUID.Zero)
12020 {
12021 replydata = "SERVICE_ERROR";
12022 return;
12023 }
12024
12025 m_host.AddScriptLPS(1);
12026
12027 m_host.TaskInventory.LockItemsForRead(true);
12028 TaskInventoryItem item = m_host.TaskInventory[invItemID];
12029 m_host.TaskInventory.LockItemsForRead(false);
12030
12031 if (item.PermsGranter == UUID.Zero)
12032 {
12033 replydata = "MISSING_PERMISSION_DEBIT";
12034 return;
12035 }
12036
12037 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12038 {
12039 replydata = "MISSING_PERMISSION_DEBIT";
12040 return;
12041 }
12042
12043 UUID toID = new UUID();
12044
12045 if (!UUID.TryParse(destination, out toID))
12046 {
12047 replydata = "INVALID_AGENT";
12048 return;
12049 }
12050
12051 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12052
12053 if (money == null)
12054 {
12055 replydata = "TRANSFERS_DISABLED";
12056 return;
12057 }
12058
12059 bool result = money.ObjectGiveMoney(
12060 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12061
12062 if (result)
12063 {
12064 replycode = 1;
12065 return;
12066 }
12067
12068 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12069 }
12070 finally
12071 {
12072 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12073 "transaction_result", new Object[] {
12074 new LSL_String(txn.ToString()),
12075 new LSL_Integer(replycode),
12076 new LSL_String(replydata) },
12077 new DetectParams[0]));
12078 }
12079 });
12080
12081 return txn.ToString();
10883 } 12082 }
10884 12083
10885 #endregion 12084 #endregion
12085
12086 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12087 {
12088 SceneObjectGroup group = m_host.ParentGroup;
12089
12090 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12091 return;
12092 if (group.IsAttachment)
12093 return;
12094
12095 if (frames.Data.Length > 0) // We are getting a new motion
12096 {
12097 if (group.RootPart.KeyframeMotion != null)
12098 group.RootPart.KeyframeMotion.Stop();
12099 group.RootPart.KeyframeMotion = null;
12100
12101 int idx = 0;
12102
12103 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12104 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12105
12106 while (idx < options.Data.Length)
12107 {
12108 int option = (int)options.GetLSLIntegerItem(idx++);
12109 int remain = options.Data.Length - idx;
12110
12111 switch (option)
12112 {
12113 case ScriptBaseClass.KFM_MODE:
12114 if (remain < 1)
12115 break;
12116 int modeval = (int)options.GetLSLIntegerItem(idx++);
12117 switch(modeval)
12118 {
12119 case ScriptBaseClass.KFM_FORWARD:
12120 mode = KeyframeMotion.PlayMode.Forward;
12121 break;
12122 case ScriptBaseClass.KFM_REVERSE:
12123 mode = KeyframeMotion.PlayMode.Reverse;
12124 break;
12125 case ScriptBaseClass.KFM_LOOP:
12126 mode = KeyframeMotion.PlayMode.Loop;
12127 break;
12128 case ScriptBaseClass.KFM_PING_PONG:
12129 mode = KeyframeMotion.PlayMode.PingPong;
12130 break;
12131 }
12132 break;
12133 case ScriptBaseClass.KFM_DATA:
12134 if (remain < 1)
12135 break;
12136 int dataval = (int)options.GetLSLIntegerItem(idx++);
12137 data = (KeyframeMotion.DataFormat)dataval;
12138 break;
12139 }
12140 }
12141
12142 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12143
12144 idx = 0;
12145
12146 int elemLength = 2;
12147 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12148 elemLength = 3;
12149
12150 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12151 while (idx < frames.Data.Length)
12152 {
12153 int remain = frames.Data.Length - idx;
12154
12155 if (remain < elemLength)
12156 break;
12157
12158 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12159 frame.Position = null;
12160 frame.Rotation = null;
12161
12162 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12163 {
12164 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12165 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12166 }
12167 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12168 {
12169 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12170 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12171 }
12172
12173 float tempf = (float)frames.GetLSLFloatItem(idx++);
12174 frame.TimeMS = (int)(tempf * 1000.0f);
12175
12176 keyframes.Add(frame);
12177 }
12178
12179 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12180 group.RootPart.KeyframeMotion.Start();
12181 }
12182 else
12183 {
12184 if (group.RootPart.KeyframeMotion == null)
12185 return;
12186
12187 if (options.Data.Length == 0)
12188 {
12189 group.RootPart.KeyframeMotion.Stop();
12190 return;
12191 }
12192
12193 int code = (int)options.GetLSLIntegerItem(0);
12194
12195 int idx = 0;
12196
12197 while (idx < options.Data.Length)
12198 {
12199 int option = (int)options.GetLSLIntegerItem(idx++);
12200 int remain = options.Data.Length - idx;
12201
12202 switch (option)
12203 {
12204 case ScriptBaseClass.KFM_COMMAND:
12205 int cmd = (int)options.GetLSLIntegerItem(idx++);
12206 switch (cmd)
12207 {
12208 case ScriptBaseClass.KFM_CMD_PLAY:
12209 group.RootPart.KeyframeMotion.Start();
12210 break;
12211 case ScriptBaseClass.KFM_CMD_STOP:
12212 group.RootPart.KeyframeMotion.Stop();
12213 break;
12214 case ScriptBaseClass.KFM_CMD_PAUSE:
12215 group.RootPart.KeyframeMotion.Pause();
12216 break;
12217 }
12218 break;
12219 }
12220 }
12221 }
12222 }
10886 } 12223 }
10887 12224
10888 public class NotecardCache 12225 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index a5dcba4..0dc2aa2 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)
@@ -2272,7 +2281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2272 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2281 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2273 m_host.AddScriptLPS(1); 2282 m_host.AddScriptLPS(1);
2274 2283
2275 return NpcCreate(firstname, lastname, position, notecard, false, false); 2284 return NpcCreate(firstname, lastname, position, notecard, true, false);
2276 } 2285 }
2277 2286
2278 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2287 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2283,24 +2292,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2283 return NpcCreate( 2292 return NpcCreate(
2284 firstname, lastname, position, notecard, 2293 firstname, lastname, position, notecard,
2285 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2294 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2286 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2295 false);
2296// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2287 } 2297 }
2288 2298
2289 private LSL_Key NpcCreate( 2299 private LSL_Key NpcCreate(
2290 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2300 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2291 { 2301 {
2302 if (!owned)
2303 OSSLError("Unowned NPCs are unsupported");
2304
2305 string groupTitle = String.Empty;
2306
2307 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2308 return new LSL_Key(UUID.Zero.ToString());
2309
2310 if (firstname != String.Empty || lastname != String.Empty)
2311 {
2312 if (firstname != "Shown outfit:")
2313 groupTitle = "- NPC -";
2314 }
2315
2292 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2316 INPCModule module = World.RequestModuleInterface<INPCModule>();
2293 if (module != null) 2317 if (module != null)
2294 { 2318 {
2295 AvatarAppearance appearance = null; 2319 AvatarAppearance appearance = null;
2296 2320
2297 UUID id; 2321// UUID id;
2298 if (UUID.TryParse(notecard, out id)) 2322// if (UUID.TryParse(notecard, out id))
2299 { 2323// {
2300 ScenePresence clonePresence = World.GetScenePresence(id); 2324// ScenePresence clonePresence = World.GetScenePresence(id);
2301 if (clonePresence != null) 2325// if (clonePresence != null)
2302 appearance = clonePresence.Appearance; 2326// appearance = clonePresence.Appearance;
2303 } 2327// }
2304 2328
2305 if (appearance == null) 2329 if (appearance == null)
2306 { 2330 {
@@ -2328,6 +2352,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2328 World, 2352 World,
2329 appearance); 2353 appearance);
2330 2354
2355 ScenePresence sp;
2356 if (World.TryGetScenePresence(x, out sp))
2357 {
2358 sp.Grouptitle = groupTitle;
2359 sp.SendAvatarDataToAllAgents();
2360 }
2331 return new LSL_Key(x.ToString()); 2361 return new LSL_Key(x.ToString());
2332 } 2362 }
2333 2363
@@ -2596,16 +2626,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2596 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2626 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2597 m_host.AddScriptLPS(1); 2627 m_host.AddScriptLPS(1);
2598 2628
2599 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2629 ManualResetEvent ev = new ManualResetEvent(false);
2600 if (module != null)
2601 {
2602 UUID npcId = new UUID(npc.m_string);
2603 2630
2604 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2631 Util.FireAndForget(delegate(object x) {
2605 return; 2632 try
2633 {
2634 INPCModule module = World.RequestModuleInterface<INPCModule>();
2635 if (module != null)
2636 {
2637 UUID npcId = new UUID(npc.m_string);
2606 2638
2607 module.DeleteNPC(npcId, World); 2639 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2608 } 2640 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2641 {
2642 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2643 return;
2644 }
2645
2646 module.DeleteNPC(npcId, World);
2647 }
2648 }
2649 finally
2650 {
2651 ev.Set();
2652 }
2653 });
2654 ev.WaitOne();
2609 } 2655 }
2610 2656
2611 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2657 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3050,4 +3096,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 return ScriptBaseClass.TRUE; 3096 return ScriptBaseClass.TRUE;
3051 } 3097 }
3052 } 3098 }
3053} \ No newline at end of file 3099}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 1c272f8..1373971 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
222 // Is the sensor type is AGENT and not SCRIPTED then include agents 222 // Is the sensor type is AGENT and not SCRIPTED then include agents
223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) 223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
224 { 224 {
225 sensedEntities.AddRange(doAgentSensor(ts)); 225 sensedEntities.AddRange(doAgentSensor(ts));
226 } 226 }
227 227
228 // If SCRIPTED or PASSIVE or ACTIVE check objects 228 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -319,13 +319,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.RotationOffset; 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, the sensor cone always orients with the 326 // In attachments, the sensor cone always orients with the
326 // avatar rotation. This may include a nonzero elevation if 327 // avatar rotation. This may include a nonzero elevation if
327 // in mouselook. 328 // in mouselook.
328 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 329 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
330 fromRegionPos = avatar.AbsolutePosition;
329 q = avatar.Rotation; 331 q = avatar.Rotation;
330 } 332 }
331 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 333 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -448,6 +450,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
448 // avatar rotation. This may include a nonzero elevation if 450 // avatar rotation. This may include a nonzero elevation if
449 // in mouselook. 451 // in mouselook.
450 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 452 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
453 if (avatar == null)
454 return sensedEntities;
455 fromRegionPos = avatar.AbsolutePosition;
451 q = avatar.Rotation; 456 q = avatar.Rotation;
452 } 457 }
453 458
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
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..b976dc3 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);
@@ -396,6 +399,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
396 void llTargetOmega(LSL_Vector axis, double spinrate, double gain); 399 void llTargetOmega(LSL_Vector axis, double spinrate, double gain);
397 void llTargetRemove(int number); 400 void llTargetRemove(int number);
398 void llTeleportAgentHome(string agent); 401 void llTeleportAgentHome(string agent);
402 void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt);
399 void llTextBox(string avatar, string message, int chat_channel); 403 void llTextBox(string avatar, string message, int chat_channel);
400 LSL_String llToLower(string source); 404 LSL_String llToLower(string source);
401 LSL_String llToUpper(string source); 405 LSL_String llToUpper(string source);
@@ -412,9 +416,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
412 LSL_Vector llWind(LSL_Vector offset); 416 LSL_Vector llWind(LSL_Vector offset);
413 LSL_String llXorBase64Strings(string str1, string str2); 417 LSL_String llXorBase64Strings(string str1, string str2);
414 LSL_String llXorBase64StringsCorrect(string str1, string str2); 418 LSL_String llXorBase64StringsCorrect(string str1, string str2);
415 void print(string str); 419 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
420 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
416 421
417 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 422 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
418 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 423 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
424 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
419 } 425 }
420} 426}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 30bd3ef..444a681 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..4ce3cf1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
95 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
96 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
97 98
98 //Particle Systems 99 //Particle Systems
99 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -282,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -568,6 +570,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
568 public const int PRIM_MEDIA_PERM_OWNER = 1; 570 public const int PRIM_MEDIA_PERM_OWNER = 1;
569 public const int PRIM_MEDIA_PERM_GROUP = 2; 571 public const int PRIM_MEDIA_PERM_GROUP = 2;
570 public const int PRIM_MEDIA_PERM_ANYONE = 4; 572 public const int PRIM_MEDIA_PERM_ANYONE = 4;
573
574 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
575 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
576 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
577 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
578
579 public const int PRIM_PHYSICS_MATERIAL = 31;
580 public const int DENSITY = 1;
581 public const int FRICTION = 2;
582 public const int RESTITUTION = 4;
583 public const int GRAVITY_MULTIPLIER = 8;
571 584
572 // extra constants for llSetPrimMediaParams 585 // extra constants for llSetPrimMediaParams
573 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 586 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -640,5 +653,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
640 public static readonly LSLInteger RCERR_UNKNOWN = -1; 653 public static readonly LSLInteger RCERR_UNKNOWN = -1;
641 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 654 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
642 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 655 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
656
657 public const int KFM_MODE = 1;
658 public const int KFM_LOOP = 1;
659 public const int KFM_REVERSE = 3;
660 public const int KFM_FORWARD = 0;
661 public const int KFM_PING_PONG = 2;
662 public const int KFM_DATA = 2;
663 public const int KFM_TRANSLATION = 2;
664 public const int KFM_ROTATION = 1;
665 public const int KFM_COMMAND = 0;
666 public const int KFM_CMD_PLAY = 0;
667 public const int KFM_CMD_STOP = 1;
668 public const int KFM_CMD_PAUSE = 2;
643 } 669 }
644} 670}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index f8e3c36..bf58d13 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);
@@ -1798,6 +1820,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1798 m_LSL_Functions.llTargetRemove(number); 1820 m_LSL_Functions.llTargetRemove(number);
1799 } 1821 }
1800 1822
1823 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
1824 {
1825 m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt);
1826 }
1827
1801 public void llTeleportAgentHome(string agent) 1828 public void llTeleportAgentHome(string agent)
1802 { 1829 {
1803 m_LSL_Functions.llTeleportAgentHome(agent); 1830 m_LSL_Functions.llTeleportAgentHome(agent);
@@ -1913,9 +1940,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1913 return m_LSL_Functions.llClearLinkMedia(link, face); 1940 return m_LSL_Functions.llClearLinkMedia(link, face);
1914 } 1941 }
1915 1942
1916 public void print(string str) 1943 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1944 {
1945 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1946 }
1947
1948 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1949 {
1950 m_LSL_Functions.llSetKeyframedMotion(frames, options);
1951 }
1952
1953 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1917 { 1954 {
1918 m_LSL_Functions.print(str); 1955 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1919 } 1956 }
1920 } 1957 }
1921} 1958}
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 6e36742..ff1f277 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;
@@ -218,13 +219,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
218 219
219 if (part != null) 220 if (part != null)
220 { 221 {
221 lock (part.TaskInventory) 222 part.TaskInventory.LockItemsForRead(true);
223 if (part.TaskInventory.ContainsKey(ItemID))
222 { 224 {
223 if (part.TaskInventory.ContainsKey(ItemID)) 225 ScriptTask = part.TaskInventory[ItemID];
224 {
225 ScriptTask = part.TaskInventory[ItemID];
226 }
227 } 226 }
227 part.TaskInventory.LockItemsForRead(false);
228 } 228 }
229 229
230 ApiManager am = new ApiManager(); 230 ApiManager am = new ApiManager();
@@ -416,14 +416,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
416 { 416 {
417 int permsMask; 417 int permsMask;
418 UUID permsGranter; 418 UUID permsGranter;
419 lock (part.TaskInventory) 419 part.TaskInventory.LockItemsForRead(true);
420 if (!part.TaskInventory.ContainsKey(ItemID))
420 { 421 {
421 if (!part.TaskInventory.ContainsKey(ItemID)) 422 part.TaskInventory.LockItemsForRead(false);
422 return; 423 return;
423
424 permsGranter = part.TaskInventory[ItemID].PermsGranter;
425 permsMask = part.TaskInventory[ItemID].PermsMask;
426 } 424 }
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 part.TaskInventory.LockItemsForRead(false);
427 428
428 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
429 { 430 {
@@ -551,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
551 return true; 552 return true;
552 } 553 }
553 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
554 public void SetState(string state) 556 public void SetState(string state)
555 { 557 {
556 if (state == State) 558 if (state == State)
@@ -562,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
562 new DetectParams[0])); 564 new DetectParams[0]));
563 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
564 new DetectParams[0])); 566 new DetectParams[0]));
565 567
566 throw new EventAbortException(); 568 throw new EventAbortException();
567 } 569 }
568 570
@@ -652,45 +654,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
652 /// <returns></returns> 654 /// <returns></returns>
653 public object EventProcessor() 655 public object EventProcessor()
654 { 656 {
657 EventParams data = null;
655 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 658 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
656 if (!Running) 659 if (!Running)
657 return 0; 660 return 0;
658 661
659 lock (m_Script)
660 {
661// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
662 663
663 if (Suspended) 664 if (Suspended)
664 return 0; 665 return 0;
665
666 EventParams data = null;
667 666
668 lock (EventQueue) 667 lock (EventQueue)
668 {
669 data = (EventParams) EventQueue.Dequeue();
670 if (data == null) // Shouldn't happen
669 { 671 {
670 data = (EventParams)EventQueue.Dequeue(); 672 if (EventQueue.Count > 0 && Running && !ShuttingDown)
671 if (data == null) // Shouldn't happen
672 { 673 {
673 if (EventQueue.Count > 0 && Running && !ShuttingDown) 674 m_CurrentWorkItem = Engine.QueueEventHandler(this);
674 {
675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
676 }
677 else
678 {
679 m_CurrentWorkItem = null;
680 }
681 return 0;
682 } 675 }
683 676 else
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 { 677 {
688 if (m_ControlEventsInQueue > 0) 678 m_CurrentWorkItem = null;
689 m_ControlEventsInQueue--;
690 } 679 }
691 if (data.EventName == "collision") 680 return 0;
692 m_CollisionInQueue = false;
693 } 681 }
682
683 if (data.EventName == "timer")
684 m_TimerQueued = false;
685 if (data.EventName == "control")
686 {
687 if (m_ControlEventsInQueue > 0)
688 m_ControlEventsInQueue--;
689 }
690 if (data.EventName == "collision")
691 m_CollisionInQueue = false;
692 }
693
694 lock(m_Script)
695 {
694 696
695// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 697// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
696 698
@@ -859,6 +861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
859 new Object[0], new DetectParams[0])); 861 new Object[0], new DetectParams[0]));
860 } 862 }
861 863
864 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
862 public void ApiResetScript() 865 public void ApiResetScript()
863 { 866 {
864 // bool running = Running; 867 // bool running = Running;
@@ -890,10 +893,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
890 893
891 public Dictionary<string, object> GetVars() 894 public Dictionary<string, object> GetVars()
892 { 895 {
893 if (m_Script != null) 896 return m_Script.GetVars();
894 return m_Script.GetVars();
895 else
896 return new Dictionary<string, object>();
897 } 897 }
898 898
899 public void SetVars(Dictionary<string, object> vars) 899 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..8adf4c5 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 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 7712076..1e0f01f 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Reflection; 34using System.Reflection;
@@ -112,6 +113,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
112 private Dictionary<UUID, IScriptInstance> m_Scripts = 113 private Dictionary<UUID, IScriptInstance> m_Scripts =
113 new Dictionary<UUID, IScriptInstance>(); 114 new Dictionary<UUID, IScriptInstance>();
114 115
116 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
117
115 // Maps the asset ID to the assembly 118 // Maps the asset ID to the assembly
116 119
117 private Dictionary<UUID, string> m_Assemblies = 120 private Dictionary<UUID, string> m_Assemblies =
@@ -134,6 +137,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
134 IWorkItemResult m_CurrentCompile = null; 137 IWorkItemResult m_CurrentCompile = null;
135 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 138 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
136 139
140 private void lockScriptsForRead(bool locked)
141 {
142 if (locked)
143 {
144 if (m_scriptsLock.RecursiveReadCount > 0)
145 {
146 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
147 m_scriptsLock.ExitReadLock();
148 }
149 if (m_scriptsLock.RecursiveWriteCount > 0)
150 {
151 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
152 m_scriptsLock.ExitWriteLock();
153 }
154
155 while (!m_scriptsLock.TryEnterReadLock(60000))
156 {
157 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
158 if (m_scriptsLock.IsWriteLockHeld)
159 {
160 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
161 }
162 }
163 }
164 else
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_scriptsLock.ExitReadLock();
169 }
170 }
171 }
172 private void lockScriptsForWrite(bool locked)
173 {
174 if (locked)
175 {
176 if (m_scriptsLock.RecursiveReadCount > 0)
177 {
178 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
179 m_scriptsLock.ExitReadLock();
180 }
181 if (m_scriptsLock.RecursiveWriteCount > 0)
182 {
183 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
184 m_scriptsLock.ExitWriteLock();
185 }
186
187 while (!m_scriptsLock.TryEnterWriteLock(60000))
188 {
189 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
190 if (m_scriptsLock.IsWriteLockHeld)
191 {
192 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
193 }
194 }
195 }
196 else
197 {
198 if (m_scriptsLock.RecursiveWriteCount > 0)
199 {
200 m_scriptsLock.ExitWriteLock();
201 }
202 }
203 }
204
137 public string ScriptEngineName 205 public string ScriptEngineName
138 { 206 {
139 get { return "XEngine"; } 207 get { return "XEngine"; }
@@ -527,44 +595,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine
527 { 595 {
528 if (!m_Enabled) 596 if (!m_Enabled)
529 return; 597 return;
530 598 lockScriptsForRead(true);
531 lock (m_Scripts) 599 foreach (IScriptInstance instance in m_Scripts.Values)
532 { 600 {
533 m_log.InfoFormat( 601 // Force a final state save
534 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 602 //
535 603 if (m_Assemblies.ContainsKey(instance.AssetID))
536 foreach (IScriptInstance instance in m_Scripts.Values)
537 { 604 {
538 // Force a final state save 605 string assembly = m_Assemblies[instance.AssetID];
539 // 606 instance.SaveState(assembly);
540 if (m_Assemblies.ContainsKey(instance.AssetID)) 607 }
541 {
542 string assembly = m_Assemblies[instance.AssetID];
543 instance.SaveState(assembly);
544 }
545 608
546 // Clear the event queue and abort the instance thread 609 // Clear the event queue and abort the instance thread
547 // 610 //
548 instance.ClearQueue(); 611 instance.ClearQueue();
549 instance.Stop(0); 612 instance.Stop(0);
550 613
551 // Release events, timer, etc 614 // Release events, timer, etc
552 // 615 //
553 instance.DestroyScriptInstance(); 616 instance.DestroyScriptInstance();
554 617
555 // Unload scripts and app domains. 618 // Unload scripts and app domains
556 // Must be done explicitly because they have infinite 619 // Must be done explicitly because they have infinite
557 // lifetime. 620 // lifetime
558 // However, don't bother to do this if the simulator is shutting 621 //
559 // down since it takes a long time with many scripts. 622 if (!m_SimulatorShuttingDown)
560 if (!m_SimulatorShuttingDown) 623 {
624 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
625 if (m_DomainScripts[instance.AppDomain].Count == 0)
561 { 626 {
562 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 627 m_DomainScripts.Remove(instance.AppDomain);
563 if (m_DomainScripts[instance.AppDomain].Count == 0) 628 UnloadAppDomain(instance.AppDomain);
564 {
565 m_DomainScripts.Remove(instance.AppDomain);
566 UnloadAppDomain(instance.AppDomain);
567 }
568 } 629 }
569 } 630 }
570 631
@@ -573,6 +634,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
573 m_Assemblies.Clear(); 634 m_Assemblies.Clear();
574 m_DomainScripts.Clear(); 635 m_DomainScripts.Clear();
575 } 636 }
637 lockScriptsForRead(false);
638 lockScriptsForWrite(true);
639 m_Scripts.Clear();
640 lockScriptsForWrite(false);
641 m_PrimObjects.Clear();
642 m_Assemblies.Clear();
643 m_DomainScripts.Clear();
644
576 lock (m_ScriptEngines) 645 lock (m_ScriptEngines)
577 { 646 {
578 m_ScriptEngines.Remove(this); 647 m_ScriptEngines.Remove(this);
@@ -637,22 +706,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
637 706
638 List<IScriptInstance> instances = new List<IScriptInstance>(); 707 List<IScriptInstance> instances = new List<IScriptInstance>();
639 708
640 lock (m_Scripts) 709 lockScriptsForRead(true);
641 { 710 foreach (IScriptInstance instance in m_Scripts.Values)
642 foreach (IScriptInstance instance in m_Scripts.Values)
643 instances.Add(instance); 711 instances.Add(instance);
644 } 712 lockScriptsForRead(false);
645 713
646 foreach (IScriptInstance i in instances) 714 foreach (IScriptInstance i in instances)
647 { 715 {
648 string assembly = String.Empty; 716 string assembly = String.Empty;
649 717
650 lock (m_Scripts) 718
651 {
652 if (!m_Assemblies.ContainsKey(i.AssetID)) 719 if (!m_Assemblies.ContainsKey(i.AssetID))
653 continue; 720 continue;
654 assembly = m_Assemblies[i.AssetID]; 721 assembly = m_Assemblies[i.AssetID];
655 } 722
656 723
657 i.SaveState(assembly); 724 i.SaveState(assembly);
658 } 725 }
@@ -996,91 +1063,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
996 } 1063 }
997 1064
998 ScriptInstance instance = null; 1065 ScriptInstance instance = null;
999 lock (m_Scripts) 1066 // Create the object record
1067 lockScriptsForRead(true);
1068 if ((!m_Scripts.ContainsKey(itemID)) ||
1069 (m_Scripts[itemID].AssetID != assetID))
1000 { 1070 {
1001 // Create the object record 1071 lockScriptsForRead(false);
1002 if ((!m_Scripts.ContainsKey(itemID)) ||
1003 (m_Scripts[itemID].AssetID != assetID))
1004 {
1005 UUID appDomain = assetID;
1006 1072
1007 if (part.ParentGroup.IsAttachment) 1073 UUID appDomain = assetID;
1008 appDomain = part.ParentGroup.RootPart.UUID;
1009 1074
1010 if (!m_AppDomains.ContainsKey(appDomain)) 1075 if (part.ParentGroup.IsAttachment)
1011 { 1076 appDomain = part.ParentGroup.RootPart.UUID;
1012 try
1013 {
1014 AppDomainSetup appSetup = new AppDomainSetup();
1015 appSetup.PrivateBinPath = Path.Combine(
1016 m_ScriptEnginesPath,
1017 m_Scene.RegionInfo.RegionID.ToString());
1018
1019 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1020 Evidence evidence = new Evidence(baseEvidence);
1021
1022 AppDomain sandbox;
1023 if (m_AppDomainLoading)
1024 sandbox = AppDomain.CreateDomain(
1025 m_Scene.RegionInfo.RegionID.ToString(),
1026 evidence, appSetup);
1027 else
1028 sandbox = AppDomain.CurrentDomain;
1029
1030 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1031 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1032 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1033 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1034 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1035 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1036 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1037
1038 m_AppDomains[appDomain] = sandbox;
1039 1077
1040 m_AppDomains[appDomain].AssemblyResolve += 1078 if (!m_AppDomains.ContainsKey(appDomain))
1041 new ResolveEventHandler( 1079 {
1042 AssemblyResolver.OnAssemblyResolve); 1080 try
1043 m_DomainScripts[appDomain] = new List<UUID>(); 1081 {
1044 } 1082 AppDomainSetup appSetup = new AppDomainSetup();
1045 catch (Exception e) 1083 appSetup.PrivateBinPath = Path.Combine(
1084 m_ScriptEnginesPath,
1085 m_Scene.RegionInfo.RegionID.ToString());
1086
1087 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1088 Evidence evidence = new Evidence(baseEvidence);
1089
1090 AppDomain sandbox;
1091 if (m_AppDomainLoading)
1092 sandbox = AppDomain.CreateDomain(
1093 m_Scene.RegionInfo.RegionID.ToString(),
1094 evidence, appSetup);
1095 else
1096 sandbox = AppDomain.CurrentDomain;
1097
1098 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1099 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1100 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1101 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1102 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1103 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1104 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1105
1106 m_AppDomains[appDomain] = sandbox;
1107
1108 m_AppDomains[appDomain].AssemblyResolve +=
1109 new ResolveEventHandler(
1110 AssemblyResolver.OnAssemblyResolve);
1111 m_DomainScripts[appDomain] = new List<UUID>();
1112 }
1113 catch (Exception e)
1114 {
1115 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1116 m_ScriptErrorMessage += "Exception creating app domain:\n";
1117 m_ScriptFailCount++;
1118 lock (m_AddingAssemblies)
1046 { 1119 {
1047 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1120 m_AddingAssemblies[assembly]--;
1048 m_ScriptErrorMessage += "Exception creating app domain:\n";
1049 m_ScriptFailCount++;
1050 lock (m_AddingAssemblies)
1051 {
1052 m_AddingAssemblies[assembly]--;
1053 }
1054 return false;
1055 } 1121 }
1122 return false;
1056 } 1123 }
1057 m_DomainScripts[appDomain].Add(itemID); 1124 }
1058 1125 m_DomainScripts[appDomain].Add(itemID);
1059 instance = new ScriptInstance(this, part, 1126
1060 itemID, assetID, assembly, 1127 instance = new ScriptInstance(this, part,
1061 m_AppDomains[appDomain], 1128 itemID, assetID, assembly,
1062 part.ParentGroup.RootPart.Name, 1129 m_AppDomains[appDomain],
1063 item.Name, startParam, postOnRez, 1130 part.ParentGroup.RootPart.Name,
1064 stateSource, m_MaxScriptQueue); 1131 item.Name, startParam, postOnRez,
1065 1132 stateSource, m_MaxScriptQueue);
1066 m_log.DebugFormat( 1133
1067 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1134 m_log.DebugFormat(
1068 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1135 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1136 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1069 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1137 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1070 1138
1071 if (presence != null) 1139 if (presence != null)
1072 { 1140 {
1073 ShowScriptSaveResponse(item.OwnerID, 1141 ShowScriptSaveResponse(item.OwnerID,
1074 assetID, "Compile successful", true); 1142 assetID, "Compile successful", true);
1075 }
1076
1077 instance.AppDomain = appDomain;
1078 instance.LineMap = linemap;
1079
1080 m_Scripts[itemID] = instance;
1081 } 1143 }
1082 }
1083 1144
1145 instance.AppDomain = appDomain;
1146 instance.LineMap = linemap;
1147 lockScriptsForWrite(true);
1148 m_Scripts[itemID] = instance;
1149 lockScriptsForWrite(false);
1150 }
1151 else
1152 {
1153 lockScriptsForRead(false);
1154 }
1084 lock (m_PrimObjects) 1155 lock (m_PrimObjects)
1085 { 1156 {
1086 if (!m_PrimObjects.ContainsKey(localID)) 1157 if (!m_PrimObjects.ContainsKey(localID))
@@ -1098,9 +1169,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1098 m_AddingAssemblies[assembly]--; 1169 m_AddingAssemblies[assembly]--;
1099 } 1170 }
1100 1171
1101 if (instance != null) 1172 if (instance!=null)
1102 instance.Init(); 1173 instance.Init();
1103 1174
1104 return true; 1175 return true;
1105 } 1176 }
1106 1177
@@ -1113,18 +1184,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1113 m_CompileDict.Remove(itemID); 1184 m_CompileDict.Remove(itemID);
1114 } 1185 }
1115 1186
1116 IScriptInstance instance = null; 1187 lockScriptsForRead(true);
1117 1188 // Do we even have it?
1118 lock (m_Scripts) 1189 if (!m_Scripts.ContainsKey(itemID))
1119 { 1190 {
1120 // Do we even have it? 1191 // Do we even have it?
1121 if (!m_Scripts.ContainsKey(itemID)) 1192 if (!m_Scripts.ContainsKey(itemID))
1122 return; 1193 return;
1123 1194
1124 instance = m_Scripts[itemID]; 1195 lockScriptsForRead(false);
1196 lockScriptsForWrite(true);
1125 m_Scripts.Remove(itemID); 1197 m_Scripts.Remove(itemID);
1198 lockScriptsForWrite(false);
1199
1200 return;
1126 } 1201 }
1202
1127 1203
1204 IScriptInstance instance=m_Scripts[itemID];
1205 lockScriptsForRead(false);
1206 lockScriptsForWrite(true);
1207 m_Scripts.Remove(itemID);
1208 lockScriptsForWrite(false);
1128 instance.ClearQueue(); 1209 instance.ClearQueue();
1129 1210
1130 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1211 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1163,8 +1244,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1163 1244
1164 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1245 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1165 if (handlerObjectRemoved != null) 1246 if (handlerObjectRemoved != null)
1166 handlerObjectRemoved(instance.ObjectID); 1247 {
1248 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1249 handlerObjectRemoved(part.UUID);
1250 }
1167 1251
1252 CleanAssemblies();
1253
1168 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1254 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1169 if (handlerScriptRemoved != null) 1255 if (handlerScriptRemoved != null)
1170 handlerScriptRemoved(itemID); 1256 handlerScriptRemoved(itemID);
@@ -1306,7 +1392,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1306 return false; 1392 return false;
1307 1393
1308 uuids = m_PrimObjects[localID]; 1394 uuids = m_PrimObjects[localID];
1309 } 1395
1310 1396
1311 foreach (UUID itemID in uuids) 1397 foreach (UUID itemID in uuids)
1312 { 1398 {
@@ -1324,6 +1410,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1324 result = true; 1410 result = true;
1325 } 1411 }
1326 } 1412 }
1413 }
1327 1414
1328 return result; 1415 return result;
1329 } 1416 }
@@ -1425,12 +1512,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1425 private IScriptInstance GetInstance(UUID itemID) 1512 private IScriptInstance GetInstance(UUID itemID)
1426 { 1513 {
1427 IScriptInstance instance; 1514 IScriptInstance instance;
1428 lock (m_Scripts) 1515 lockScriptsForRead(true);
1516 if (!m_Scripts.ContainsKey(itemID))
1429 { 1517 {
1430 if (!m_Scripts.ContainsKey(itemID)) 1518 lockScriptsForRead(false);
1431 return null; 1519 return null;
1432 instance = m_Scripts[itemID];
1433 } 1520 }
1521 instance = m_Scripts[itemID];
1522 lockScriptsForRead(false);
1434 return instance; 1523 return instance;
1435 } 1524 }
1436 1525
@@ -1454,6 +1543,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1454 return false; 1543 return false;
1455 } 1544 }
1456 1545
1546 [DebuggerNonUserCode]
1457 public void ApiResetScript(UUID itemID) 1547 public void ApiResetScript(UUID itemID)
1458 { 1548 {
1459 IScriptInstance instance = GetInstance(itemID); 1549 IScriptInstance instance = GetInstance(itemID);
@@ -1505,6 +1595,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1505 return UUID.Zero; 1595 return UUID.Zero;
1506 } 1596 }
1507 1597
1598 [DebuggerNonUserCode]
1508 public void SetState(UUID itemID, string newState) 1599 public void SetState(UUID itemID, string newState)
1509 { 1600 {
1510 IScriptInstance instance = GetInstance(itemID); 1601 IScriptInstance instance = GetInstance(itemID);
@@ -1527,11 +1618,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1527 1618
1528 List<IScriptInstance> instances = new List<IScriptInstance>(); 1619 List<IScriptInstance> instances = new List<IScriptInstance>();
1529 1620
1530 lock (m_Scripts) 1621 lockScriptsForRead(true);
1531 { 1622 foreach (IScriptInstance instance in m_Scripts.Values)
1532 foreach (IScriptInstance instance in m_Scripts.Values)
1533 instances.Add(instance); 1623 instances.Add(instance);
1534 } 1624 lockScriptsForRead(false);
1535 1625
1536 foreach (IScriptInstance i in instances) 1626 foreach (IScriptInstance i in instances)
1537 { 1627 {
@@ -1969,5 +2059,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1969// else 2059// else
1970// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 2060// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
1971 } 2061 }
2062
2063 public bool HasScript(UUID itemID, out bool running)
2064 {
2065 running = true;
2066
2067 IScriptInstance instance = GetInstance(itemID);
2068 if (instance == null)
2069 return false;
2070
2071 running = instance.Running;
2072 return true;
2073 }
1972 } 2074 }
1973} \ No newline at end of file 2075}