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.cs3166
-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, 1166 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 8d25a62..5268ade 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;
@@ -1408,6 +1520,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1408 { 1520 {
1409 m_host.AddScriptLPS(1); 1521 m_host.AddScriptLPS(1);
1410 1522
1523 SetColor(m_host, color, face);
1524 }
1525
1526 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1527 {
1528 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1529 return;
1530
1531 Primitive.TextureEntry tex = part.Shape.Textures;
1532 Color4 texcolor;
1533 if (face >= 0 && face < GetNumberOfSides(part))
1534 {
1535 texcolor = tex.CreateFace((uint)face).RGBA;
1536 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1537 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1538 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1539 tex.FaceTextures[face].RGBA = texcolor;
1540 part.UpdateTextureEntry(tex.GetBytes());
1541 return;
1542 }
1543 else if (face == ScriptBaseClass.ALL_SIDES)
1544 {
1545 for (uint i = 0; i < GetNumberOfSides(part); i++)
1546 {
1547 if (tex.FaceTextures[i] != null)
1548 {
1549 texcolor = tex.FaceTextures[i].RGBA;
1550 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1551 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1552 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1553 tex.FaceTextures[i].RGBA = texcolor;
1554 }
1555 texcolor = tex.DefaultTexture.RGBA;
1556 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1557 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1558 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1559 tex.DefaultTexture.RGBA = texcolor;
1560 }
1561 part.UpdateTextureEntry(tex.GetBytes());
1562 return;
1563 }
1564
1411 if (face == ScriptBaseClass.ALL_SIDES) 1565 if (face == ScriptBaseClass.ALL_SIDES)
1412 face = SceneObjectPart.ALL_SIDES; 1566 face = SceneObjectPart.ALL_SIDES;
1413 1567
@@ -1416,6 +1570,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1416 1570
1417 public void SetTexGen(SceneObjectPart part, int face,int style) 1571 public void SetTexGen(SceneObjectPart part, int face,int style)
1418 { 1572 {
1573 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1574 return;
1575
1419 Primitive.TextureEntry tex = part.Shape.Textures; 1576 Primitive.TextureEntry tex = part.Shape.Textures;
1420 MappingType textype; 1577 MappingType textype;
1421 textype = MappingType.Default; 1578 textype = MappingType.Default;
@@ -1446,6 +1603,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1446 1603
1447 public void SetGlow(SceneObjectPart part, int face, float glow) 1604 public void SetGlow(SceneObjectPart part, int face, float glow)
1448 { 1605 {
1606 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1607 return;
1608
1449 Primitive.TextureEntry tex = part.Shape.Textures; 1609 Primitive.TextureEntry tex = part.Shape.Textures;
1450 if (face >= 0 && face < GetNumberOfSides(part)) 1610 if (face >= 0 && face < GetNumberOfSides(part))
1451 { 1611 {
@@ -1471,6 +1631,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1471 1631
1472 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1632 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1473 { 1633 {
1634 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1635 return;
1474 1636
1475 Shininess sval = new Shininess(); 1637 Shininess sval = new Shininess();
1476 1638
@@ -1521,6 +1683,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1521 1683
1522 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1684 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1523 { 1685 {
1686 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1687 return;
1688
1524 Primitive.TextureEntry tex = part.Shape.Textures; 1689 Primitive.TextureEntry tex = part.Shape.Textures;
1525 if (face >= 0 && face < GetNumberOfSides(part)) 1690 if (face >= 0 && face < GetNumberOfSides(part))
1526 { 1691 {
@@ -1581,13 +1746,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1581 m_host.AddScriptLPS(1); 1746 m_host.AddScriptLPS(1);
1582 1747
1583 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1748 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1584 1749 if (parts.Count > 0)
1585 foreach (SceneObjectPart part in parts) 1750 {
1586 SetAlpha(part, alpha, face); 1751 try
1752 {
1753 parts[0].ParentGroup.areUpdatesSuspended = true;
1754 foreach (SceneObjectPart part in parts)
1755 SetAlpha(part, alpha, face);
1756 }
1757 finally
1758 {
1759 parts[0].ParentGroup.areUpdatesSuspended = false;
1760 }
1761 }
1587 } 1762 }
1588 1763
1589 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1764 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1590 { 1765 {
1766 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1767 return;
1768
1591 Primitive.TextureEntry tex = part.Shape.Textures; 1769 Primitive.TextureEntry tex = part.Shape.Textures;
1592 Color4 texcolor; 1770 Color4 texcolor;
1593 if (face >= 0 && face < GetNumberOfSides(part)) 1771 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1640,7 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1640 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1818 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1641 float wind, float tension, LSL_Vector Force) 1819 float wind, float tension, LSL_Vector Force)
1642 { 1820 {
1643 if (part == null) 1821 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1644 return; 1822 return;
1645 1823
1646 if (flexi) 1824 if (flexi)
@@ -1674,7 +1852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1674 /// <param name="falloff"></param> 1852 /// <param name="falloff"></param>
1675 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1853 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1676 { 1854 {
1677 if (part == null) 1855 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1678 return; 1856 return;
1679 1857
1680 if (light) 1858 if (light)
@@ -1751,15 +1929,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1751 m_host.AddScriptLPS(1); 1929 m_host.AddScriptLPS(1);
1752 1930
1753 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1931 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1754 1932 if (parts.Count > 0)
1755 foreach (SceneObjectPart part in parts) 1933 {
1756 SetTexture(part, texture, face); 1934 try
1757 1935 {
1936 parts[0].ParentGroup.areUpdatesSuspended = true;
1937 foreach (SceneObjectPart part in parts)
1938 SetTexture(part, texture, face);
1939 }
1940 finally
1941 {
1942 parts[0].ParentGroup.areUpdatesSuspended = false;
1943 }
1944 }
1758 ScriptSleep(200); 1945 ScriptSleep(200);
1759 } 1946 }
1760 1947
1761 protected void SetTexture(SceneObjectPart part, string texture, int face) 1948 protected void SetTexture(SceneObjectPart part, string texture, int face)
1762 { 1949 {
1950 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1951 return;
1952
1763 UUID textureID = new UUID(); 1953 UUID textureID = new UUID();
1764 1954
1765 textureID = InventoryKey(texture, (int)AssetType.Texture); 1955 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1804,6 +1994,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1804 1994
1805 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1995 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1806 { 1996 {
1997 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1998 return;
1999
1807 Primitive.TextureEntry tex = part.Shape.Textures; 2000 Primitive.TextureEntry tex = part.Shape.Textures;
1808 if (face >= 0 && face < GetNumberOfSides(part)) 2001 if (face >= 0 && face < GetNumberOfSides(part))
1809 { 2002 {
@@ -1840,6 +2033,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1840 2033
1841 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2034 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1842 { 2035 {
2036 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2037 return;
2038
1843 Primitive.TextureEntry tex = part.Shape.Textures; 2039 Primitive.TextureEntry tex = part.Shape.Textures;
1844 if (face >= 0 && face < GetNumberOfSides(part)) 2040 if (face >= 0 && face < GetNumberOfSides(part))
1845 { 2041 {
@@ -1876,6 +2072,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1876 2072
1877 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2073 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1878 { 2074 {
2075 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2076 return;
2077
1879 Primitive.TextureEntry tex = part.Shape.Textures; 2078 Primitive.TextureEntry tex = part.Shape.Textures;
1880 if (face >= 0 && face < GetNumberOfSides(part)) 2079 if (face >= 0 && face < GetNumberOfSides(part))
1881 { 2080 {
@@ -1980,26 +2179,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 return real_vec; 2179 return real_vec;
1981 } 2180 }
1982 2181
2182 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2183 {
2184 return new LSL_Integer(SetRegionPos(m_host, pos));
2185 }
2186
2187 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2188 {
2189 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2190 return 0;
2191
2192 SceneObjectGroup grp = part.ParentGroup;
2193
2194 if (grp.IsAttachment)
2195 return 0;
2196
2197 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2198 return 0;
2199
2200 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)
2201 return 0;
2202
2203 float constrainedX = (float)targetPos.x;
2204 float constrainedY = (float)targetPos.y;
2205
2206 if (constrainedX < 0.0f)
2207 constrainedX = 0.0f;
2208 if (constrainedY < 0.0f)
2209 constrainedY = 0.0f;
2210 if (constrainedX >= (float)Constants.RegionSize)
2211 constrainedX = (float)Constants.RegionSize - 0.1f;
2212 if (constrainedY >= (float)Constants.RegionSize)
2213 constrainedY = (float)Constants.RegionSize -0.1f;
2214
2215 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2216
2217 if (targetPos.z < ground)
2218 targetPos.z = ground;
2219
2220 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2221
2222 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2223 return 0;
2224
2225 grp.UpdateGroupPosition(dest);
2226
2227 return 1;
2228 }
2229
1983 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2230 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1984 { 2231 {
1985 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2232 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2233 return;
2234
1986 LSL_Vector currentPos = GetPartLocalPos(part); 2235 LSL_Vector currentPos = GetPartLocalPos(part);
2236 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1987 2237
1988 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1989 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1990 2238
1991 if (part.ParentGroup.RootPart == part) 2239 if (part.ParentGroup.RootPart == part)
1992 { 2240 {
1993 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1994 targetPos.z = ground;
1995 SceneObjectGroup parent = part.ParentGroup; 2241 SceneObjectGroup parent = part.ParentGroup;
1996 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2242 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1997 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2243 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2244 return;
2245 Util.FireAndForget(delegate(object x) {
2246 parent.UpdateGroupPosition(dest);
2247 });
1998 } 2248 }
1999 else 2249 else
2000 { 2250 {
2001 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2251 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2002 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2003 SceneObjectGroup parent = part.ParentGroup; 2252 SceneObjectGroup parent = part.ParentGroup;
2004 parent.HasGroupChanged = true; 2253 parent.HasGroupChanged = true;
2005 parent.ScheduleGroupForTerseUpdate(); 2254 parent.ScheduleGroupForTerseUpdate();
@@ -2030,11 +2279,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2030 } 2279 }
2031 else 2280 else
2032 { 2281 {
2033 if (m_host.IsRoot) 2282 if (part.IsRoot)
2034 { 2283 {
2035 return new LSL_Vector(m_host.AttachedPos.X, 2284 return new LSL_Vector(part.AttachedPos.X,
2036 m_host.AttachedPos.Y, 2285 part.AttachedPos.Y,
2037 m_host.AttachedPos.Z); 2286 part.AttachedPos.Z);
2038 } 2287 }
2039 else 2288 else
2040 { 2289 {
@@ -2050,9 +2299,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2050 m_host.AddScriptLPS(1); 2299 m_host.AddScriptLPS(1);
2051 2300
2052 // try to let this work as in SL... 2301 // try to let this work as in SL...
2053 if (m_host.ParentID == 0) 2302 if (m_host.LinkNum < 2)
2054 { 2303 {
2055 // special case: If we are root, rotate complete SOG to new rotation 2304 // Special case: If we are root, rotate complete SOG to new
2305 // rotation.
2306 // We are root if the link number is 0 (single prim) or 1
2307 // (root prim). ParentID may be nonzero in attachments and
2308 // using it would cause attachments and HUDs to rotate
2309 // to the wrong positions.
2056 SetRot(m_host, Rot2Quaternion(rot)); 2310 SetRot(m_host, Rot2Quaternion(rot));
2057 } 2311 }
2058 else 2312 else
@@ -2077,6 +2331,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2077 2331
2078 protected void SetRot(SceneObjectPart part, Quaternion rot) 2332 protected void SetRot(SceneObjectPart part, Quaternion rot)
2079 { 2333 {
2334 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2335 return;
2336
2080 part.UpdateRotation(rot); 2337 part.UpdateRotation(rot);
2081 // Update rotation does not move the object in the physics scene if it's a linkset. 2338 // Update rotation does not move the object in the physics scene if it's a linkset.
2082 2339
@@ -2231,13 +2488,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2231 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2488 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2232 { 2489 {
2233 m_host.AddScriptLPS(1); 2490 m_host.AddScriptLPS(1);
2234 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2491 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2235 } 2492 }
2236 2493
2237 public void llSetTorque(LSL_Vector torque, int local) 2494 public void llSetTorque(LSL_Vector torque, int local)
2238 { 2495 {
2239 m_host.AddScriptLPS(1); 2496 m_host.AddScriptLPS(1);
2240 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2497 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2241 } 2498 }
2242 2499
2243 public LSL_Vector llGetTorque() 2500 public LSL_Vector llGetTorque()
@@ -2702,12 +2959,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2702 2959
2703 m_host.AddScriptLPS(1); 2960 m_host.AddScriptLPS(1);
2704 2961
2962 m_host.TaskInventory.LockItemsForRead(true);
2705 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2963 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2706 2964 m_host.TaskInventory.LockItemsForRead(false);
2707 lock (m_host.TaskInventory)
2708 {
2709 item = m_host.TaskInventory[invItemID];
2710 }
2711 2965
2712 if (item.PermsGranter == UUID.Zero) 2966 if (item.PermsGranter == UUID.Zero)
2713 return 0; 2967 return 0;
@@ -2850,35 +3104,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2850 public void llLookAt(LSL_Vector target, double strength, double damping) 3104 public void llLookAt(LSL_Vector target, double strength, double damping)
2851 { 3105 {
2852 m_host.AddScriptLPS(1); 3106 m_host.AddScriptLPS(1);
2853 // Determine where we are looking from
2854 LSL_Vector from = llGetPos();
2855 3107
2856 // Work out the normalised vector from the source to the target 3108 // Get the normalized vector to the target
2857 LSL_Vector delta = llVecNorm(target - from); 3109 LSL_Vector d1 = llVecNorm(target - llGetPos());
2858 LSL_Vector angle = new LSL_Vector(0,0,0);
2859 3110
2860 // Calculate the yaw 3111 // Get the bearing (yaw)
2861 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3112 LSL_Vector a1 = new LSL_Vector(0,0,0);
2862 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3113 a1.z = llAtan2(d1.y, d1.x);
2863 3114
2864 // Calculate pitch 3115 // Get the elevation (pitch)
2865 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3116 LSL_Vector a2 = new LSL_Vector(0,0,0);
3117 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2866 3118
2867 // we need to convert from a vector describing 3119 LSL_Rotation r1 = llEuler2Rot(a1);
2868 // the angles of rotation in radians into rotation value 3120 LSL_Rotation r2 = llEuler2Rot(a2);
2869 LSL_Rotation rot = llEuler2Rot(angle); 3121 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2870
2871 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2872 // set the rotation of the object, copy that behavior
2873 PhysicsActor pa = m_host.PhysActor;
2874 3122
2875 if (strength == 0 || pa == null || !pa.IsPhysical) 3123 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2876 { 3124 {
2877 llSetRot(rot); 3125 // Do nothing if either value is 0 (this has been checked in SL)
3126 if (strength <= 0.0 || damping <= 0.0)
3127 return;
3128
3129 llSetRot(r3 * r2 * r1);
2878 } 3130 }
2879 else 3131 else
2880 { 3132 {
2881 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3133 if (strength == 0)
3134 {
3135 llSetRot(r3 * r2 * r1);
3136 return;
3137 }
3138
3139 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2882 } 3140 }
2883 } 3141 }
2884 3142
@@ -2928,13 +3186,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2928 { 3186 {
2929 TaskInventoryItem item; 3187 TaskInventoryItem item;
2930 3188
2931 lock (m_host.TaskInventory) 3189 m_host.TaskInventory.LockItemsForRead(true);
3190 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2932 { 3191 {
2933 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3192 m_host.TaskInventory.LockItemsForRead(false);
2934 return; 3193 return;
2935 else
2936 item = m_host.TaskInventory[InventorySelf()];
2937 } 3194 }
3195 else
3196 {
3197 item = m_host.TaskInventory[InventorySelf()];
3198 }
3199 m_host.TaskInventory.LockItemsForRead(false);
2938 3200
2939 if (item.PermsGranter != UUID.Zero) 3201 if (item.PermsGranter != UUID.Zero)
2940 { 3202 {
@@ -2956,13 +3218,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2956 { 3218 {
2957 TaskInventoryItem item; 3219 TaskInventoryItem item;
2958 3220
3221 m_host.TaskInventory.LockItemsForRead(true);
2959 lock (m_host.TaskInventory) 3222 lock (m_host.TaskInventory)
2960 { 3223 {
3224
2961 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3225 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3226 {
3227 m_host.TaskInventory.LockItemsForRead(false);
2962 return; 3228 return;
3229 }
2963 else 3230 else
3231 {
2964 item = m_host.TaskInventory[InventorySelf()]; 3232 item = m_host.TaskInventory[InventorySelf()];
3233 }
2965 } 3234 }
3235 m_host.TaskInventory.LockItemsForRead(false);
2966 3236
2967 m_host.AddScriptLPS(1); 3237 m_host.AddScriptLPS(1);
2968 3238
@@ -2994,18 +3264,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2994 { 3264 {
2995 m_host.AddScriptLPS(1); 3265 m_host.AddScriptLPS(1);
2996 3266
2997// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2998// return;
2999
3000 TaskInventoryItem item; 3267 TaskInventoryItem item;
3001 3268
3002 lock (m_host.TaskInventory) 3269 m_host.TaskInventory.LockItemsForRead(true);
3270
3271 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3003 { 3272 {
3004 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3273 m_host.TaskInventory.LockItemsForRead(false);
3005 return; 3274 return;
3006 else
3007 item = m_host.TaskInventory[InventorySelf()];
3008 } 3275 }
3276 else
3277 {
3278 item = m_host.TaskInventory[InventorySelf()];
3279 }
3280
3281 m_host.TaskInventory.LockItemsForRead(false);
3009 3282
3010 if (item.PermsGranter != m_host.OwnerID) 3283 if (item.PermsGranter != m_host.OwnerID)
3011 return; 3284 return;
@@ -3031,13 +3304,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3031 3304
3032 TaskInventoryItem item; 3305 TaskInventoryItem item;
3033 3306
3034 lock (m_host.TaskInventory) 3307 m_host.TaskInventory.LockItemsForRead(true);
3308
3309 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3035 { 3310 {
3036 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3311 m_host.TaskInventory.LockItemsForRead(false);
3037 return; 3312 return;
3038 else 3313 }
3039 item = m_host.TaskInventory[InventorySelf()]; 3314 else
3315 {
3316 item = m_host.TaskInventory[InventorySelf()];
3040 } 3317 }
3318 m_host.TaskInventory.LockItemsForRead(false);
3319
3041 3320
3042 if (item.PermsGranter != m_host.OwnerID) 3321 if (item.PermsGranter != m_host.OwnerID)
3043 return; 3322 return;
@@ -3084,6 +3363,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3084 3363
3085 public void llInstantMessage(string user, string message) 3364 public void llInstantMessage(string user, string message)
3086 { 3365 {
3366 UUID result;
3367 if (!UUID.TryParse(user, out result))
3368 {
3369 ShoutError("An invalid key was passed to llInstantMessage");
3370 ScriptSleep(2000);
3371 return;
3372 }
3373
3374
3087 m_host.AddScriptLPS(1); 3375 m_host.AddScriptLPS(1);
3088 3376
3089 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3377 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3098,14 +3386,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3098 UUID friendTransactionID = UUID.Random(); 3386 UUID friendTransactionID = UUID.Random();
3099 3387
3100 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3388 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3101 3389
3102 GridInstantMessage msg = new GridInstantMessage(); 3390 GridInstantMessage msg = new GridInstantMessage();
3103 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3391 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3104 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3392 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3105 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3393 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3106// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3394// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3107// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3395// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3108 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3396// DateTime dt = DateTime.UtcNow;
3397//
3398// // Ticks from UtcNow, but make it look like local. Evil, huh?
3399// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3400//
3401// try
3402// {
3403// // Convert that to the PST timezone
3404// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3405// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3406// }
3407// catch
3408// {
3409// // No logging here, as it could be VERY spammy
3410// }
3411//
3412// // And make it look local again to fool the unix time util
3413// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3414
3415 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3416
3109 //if (client != null) 3417 //if (client != null)
3110 //{ 3418 //{
3111 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3419 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3119,12 +3427,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3119 msg.message = message.Substring(0, 1024); 3427 msg.message = message.Substring(0, 1024);
3120 else 3428 else
3121 msg.message = message; 3429 msg.message = message;
3122 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3430 msg.dialog = (byte)19; // MessageFromObject
3123 msg.fromGroup = false;// fromGroup; 3431 msg.fromGroup = false;// fromGroup;
3124 msg.offline = (byte)0; //offline; 3432 msg.offline = (byte)0; //offline;
3125 msg.ParentEstateID = 0; //ParentEstateID; 3433 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3126 msg.Position = new Vector3(m_host.AbsolutePosition); 3434 msg.Position = new Vector3(m_host.AbsolutePosition);
3127 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3435 msg.RegionID = World.RegionInfo.RegionID.Guid;
3128 msg.binaryBucket 3436 msg.binaryBucket
3129 = Util.StringToBytes256( 3437 = Util.StringToBytes256(
3130 "{0}/{1}/{2}/{3}", 3438 "{0}/{1}/{2}/{3}",
@@ -3152,7 +3460,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3152 } 3460 }
3153 3461
3154 emailModule.SendEmail(m_host.UUID, address, subject, message); 3462 emailModule.SendEmail(m_host.UUID, address, subject, message);
3155 ScriptSleep(20000); 3463 ScriptSleep(15000);
3156 } 3464 }
3157 3465
3158 public void llGetNextEmail(string address, string subject) 3466 public void llGetNextEmail(string address, string subject)
@@ -3294,14 +3602,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3294 3602
3295 TaskInventoryItem item; 3603 TaskInventoryItem item;
3296 3604
3297 lock (m_host.TaskInventory) 3605 m_host.TaskInventory.LockItemsForRead(true);
3606 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3298 { 3607 {
3299 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3608 m_host.TaskInventory.LockItemsForRead(false);
3300 return; 3609 return;
3301 else
3302 item = m_host.TaskInventory[InventorySelf()];
3303 } 3610 }
3304 3611 else
3612 {
3613 item = m_host.TaskInventory[InventorySelf()];
3614 }
3615 m_host.TaskInventory.LockItemsForRead(false);
3305 if (item.PermsGranter == UUID.Zero) 3616 if (item.PermsGranter == UUID.Zero)
3306 return; 3617 return;
3307 3618
@@ -3331,13 +3642,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3331 3642
3332 TaskInventoryItem item; 3643 TaskInventoryItem item;
3333 3644
3334 lock (m_host.TaskInventory) 3645 m_host.TaskInventory.LockItemsForRead(true);
3646 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3335 { 3647 {
3336 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3648 m_host.TaskInventory.LockItemsForRead(false);
3337 return; 3649 return;
3338 else
3339 item = m_host.TaskInventory[InventorySelf()];
3340 } 3650 }
3651 else
3652 {
3653 item = m_host.TaskInventory[InventorySelf()];
3654 }
3655 m_host.TaskInventory.LockItemsForRead(false);
3656
3341 3657
3342 if (item.PermsGranter == UUID.Zero) 3658 if (item.PermsGranter == UUID.Zero)
3343 return; 3659 return;
@@ -3404,10 +3720,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3404 3720
3405 TaskInventoryItem item; 3721 TaskInventoryItem item;
3406 3722
3407 lock (m_host.TaskInventory) 3723
3724 m_host.TaskInventory.LockItemsForRead(true);
3725 if (!m_host.TaskInventory.ContainsKey(invItemID))
3726 {
3727 m_host.TaskInventory.LockItemsForRead(false);
3728 return;
3729 }
3730 else
3408 { 3731 {
3409 item = m_host.TaskInventory[invItemID]; 3732 item = m_host.TaskInventory[invItemID];
3410 } 3733 }
3734 m_host.TaskInventory.LockItemsForRead(false);
3411 3735
3412 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3736 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3413 { 3737 {
@@ -3435,15 +3759,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3435 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3759 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3436 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3760 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3437 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3761 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3762 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3438 ScriptBaseClass.PERMISSION_ATTACH; 3763 ScriptBaseClass.PERMISSION_ATTACH;
3439 3764
3440 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3765 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3441 { 3766 {
3442 lock (m_host.TaskInventory) 3767 m_host.TaskInventory.LockItemsForWrite(true);
3443 { 3768 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3444 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3769 m_host.TaskInventory[invItemID].PermsMask = perm;
3445 m_host.TaskInventory[invItemID].PermsMask = perm; 3770 m_host.TaskInventory.LockItemsForWrite(false);
3446 }
3447 3771
3448 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3772 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3449 "run_time_permissions", new Object[] { 3773 "run_time_permissions", new Object[] {
@@ -3453,28 +3777,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3453 return; 3777 return;
3454 } 3778 }
3455 } 3779 }
3456 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3780 else
3457 { 3781 {
3458 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3782 bool sitting = false;
3459 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3783 if (m_host.SitTargetAvatar == agentID)
3460 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3784 {
3461 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3785 sitting = true;
3462 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3786 }
3787 else
3788 {
3789 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3790 {
3791 if (p.SitTargetAvatar == agentID)
3792 sitting = true;
3793 }
3794 }
3463 3795
3464 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3796 if (sitting)
3465 { 3797 {
3466 lock (m_host.TaskInventory) 3798 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3799 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3800 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3801 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3802 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3803
3804 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3467 { 3805 {
3806 m_host.TaskInventory.LockItemsForWrite(true);
3468 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3807 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3469 m_host.TaskInventory[invItemID].PermsMask = perm; 3808 m_host.TaskInventory[invItemID].PermsMask = perm;
3470 } 3809 m_host.TaskInventory.LockItemsForWrite(false);
3471 3810
3472 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3811 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3473 "run_time_permissions", new Object[] { 3812 "run_time_permissions", new Object[] {
3474 new LSL_Integer(perm) }, 3813 new LSL_Integer(perm) },
3475 new DetectParams[0])); 3814 new DetectParams[0]));
3476 3815
3477 return; 3816 return;
3817 }
3478 } 3818 }
3479 } 3819 }
3480 3820
@@ -3488,11 +3828,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3488 3828
3489 if (!m_waitingForScriptAnswer) 3829 if (!m_waitingForScriptAnswer)
3490 { 3830 {
3491 lock (m_host.TaskInventory) 3831 m_host.TaskInventory.LockItemsForWrite(true);
3492 { 3832 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3493 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3833 m_host.TaskInventory[invItemID].PermsMask = 0;
3494 m_host.TaskInventory[invItemID].PermsMask = 0; 3834 m_host.TaskInventory.LockItemsForWrite(false);
3495 }
3496 3835
3497 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3836 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3498 m_waitingForScriptAnswer=true; 3837 m_waitingForScriptAnswer=true;
@@ -3527,10 +3866,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3866 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3528 llReleaseControls(); 3867 llReleaseControls();
3529 3868
3530 lock (m_host.TaskInventory) 3869
3531 { 3870 m_host.TaskInventory.LockItemsForWrite(true);
3532 m_host.TaskInventory[invItemID].PermsMask = answer; 3871 m_host.TaskInventory[invItemID].PermsMask = answer;
3533 } 3872 m_host.TaskInventory.LockItemsForWrite(false);
3873
3534 3874
3535 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3875 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3536 "run_time_permissions", new Object[] { 3876 "run_time_permissions", new Object[] {
@@ -3542,16 +3882,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3542 { 3882 {
3543 m_host.AddScriptLPS(1); 3883 m_host.AddScriptLPS(1);
3544 3884
3545 lock (m_host.TaskInventory) 3885 m_host.TaskInventory.LockItemsForRead(true);
3886
3887 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3546 { 3888 {
3547 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3889 if (item.Type == 10 && item.ItemID == m_itemID)
3548 { 3890 {
3549 if (item.Type == 10 && item.ItemID == m_itemID) 3891 m_host.TaskInventory.LockItemsForRead(false);
3550 { 3892 return item.PermsGranter.ToString();
3551 return item.PermsGranter.ToString();
3552 }
3553 } 3893 }
3554 } 3894 }
3895 m_host.TaskInventory.LockItemsForRead(false);
3555 3896
3556 return UUID.Zero.ToString(); 3897 return UUID.Zero.ToString();
3557 } 3898 }
@@ -3560,19 +3901,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3560 { 3901 {
3561 m_host.AddScriptLPS(1); 3902 m_host.AddScriptLPS(1);
3562 3903
3563 lock (m_host.TaskInventory) 3904 m_host.TaskInventory.LockItemsForRead(true);
3905
3906 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3564 { 3907 {
3565 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3908 if (item.Type == 10 && item.ItemID == m_itemID)
3566 { 3909 {
3567 if (item.Type == 10 && item.ItemID == m_itemID) 3910 int perms = item.PermsMask;
3568 { 3911 if (m_automaticLinkPermission)
3569 int perms = item.PermsMask; 3912 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3570 if (m_automaticLinkPermission) 3913 m_host.TaskInventory.LockItemsForRead(false);
3571 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3914 return perms;
3572 return perms;
3573 }
3574 } 3915 }
3575 } 3916 }
3917 m_host.TaskInventory.LockItemsForRead(false);
3576 3918
3577 return 0; 3919 return 0;
3578 } 3920 }
@@ -3594,9 +3936,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3594 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3936 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3595 { 3937 {
3596 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3938 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3597 3939 if (parts.Count > 0)
3598 foreach (SceneObjectPart part in parts) 3940 {
3599 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3941 try
3942 {
3943 parts[0].ParentGroup.areUpdatesSuspended = true;
3944 foreach (SceneObjectPart part in parts)
3945 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3946 }
3947 finally
3948 {
3949 parts[0].ParentGroup.areUpdatesSuspended = false;
3950 }
3951 }
3600 } 3952 }
3601 3953
3602 public void llCreateLink(string target, int parent) 3954 public void llCreateLink(string target, int parent)
@@ -3609,11 +3961,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3609 return; 3961 return;
3610 3962
3611 TaskInventoryItem item; 3963 TaskInventoryItem item;
3612 lock (m_host.TaskInventory) 3964 m_host.TaskInventory.LockItemsForRead(true);
3613 { 3965 item = m_host.TaskInventory[invItemID];
3614 item = m_host.TaskInventory[invItemID]; 3966 m_host.TaskInventory.LockItemsForRead(false);
3615 } 3967
3616
3617 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3968 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3618 && !m_automaticLinkPermission) 3969 && !m_automaticLinkPermission)
3619 { 3970 {
@@ -3630,11 +3981,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3630 3981
3631 if (targetPart.ParentGroup.AttachmentPoint != 0) 3982 if (targetPart.ParentGroup.AttachmentPoint != 0)
3632 return; // Fail silently if attached 3983 return; // Fail silently if attached
3984
3985 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3986 return;
3987
3633 SceneObjectGroup parentPrim = null, childPrim = null; 3988 SceneObjectGroup parentPrim = null, childPrim = null;
3634 3989
3635 if (targetPart != null) 3990 if (targetPart != null)
3636 { 3991 {
3637 if (parent != 0) { 3992 if (parent != 0)
3993 {
3638 parentPrim = m_host.ParentGroup; 3994 parentPrim = m_host.ParentGroup;
3639 childPrim = targetPart.ParentGroup; 3995 childPrim = targetPart.ParentGroup;
3640 } 3996 }
@@ -3646,7 +4002,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3646 4002
3647 // Required for linking 4003 // Required for linking
3648 childPrim.RootPart.ClearUpdateSchedule(); 4004 childPrim.RootPart.ClearUpdateSchedule();
3649 parentPrim.LinkToGroup(childPrim); 4005 parentPrim.LinkToGroup(childPrim, true);
3650 } 4006 }
3651 4007
3652 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4008 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3665,16 +4021,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3665 m_host.AddScriptLPS(1); 4021 m_host.AddScriptLPS(1);
3666 UUID invItemID = InventorySelf(); 4022 UUID invItemID = InventorySelf();
3667 4023
3668 lock (m_host.TaskInventory) 4024 m_host.TaskInventory.LockItemsForRead(true);
3669 {
3670 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4025 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3671 && !m_automaticLinkPermission) 4026 && !m_automaticLinkPermission)
3672 { 4027 {
3673 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4028 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4029 m_host.TaskInventory.LockItemsForRead(false);
3674 return; 4030 return;
3675 } 4031 }
3676 } 4032 m_host.TaskInventory.LockItemsForRead(false);
3677 4033
3678 if (linknum < ScriptBaseClass.LINK_THIS) 4034 if (linknum < ScriptBaseClass.LINK_THIS)
3679 return; 4035 return;
3680 4036
@@ -3713,10 +4069,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3713 // Restructuring Multiple Prims. 4069 // Restructuring Multiple Prims.
3714 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4070 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3715 parts.Remove(parentPrim.RootPart); 4071 parts.Remove(parentPrim.RootPart);
3716 foreach (SceneObjectPart part in parts) 4072 if (parts.Count > 0)
3717 { 4073 {
3718 parentPrim.DelinkFromGroup(part.LocalId, true); 4074 try
4075 {
4076 parts[0].ParentGroup.areUpdatesSuspended = true;
4077 foreach (SceneObjectPart part in parts)
4078 {
4079 parentPrim.DelinkFromGroup(part.LocalId, true);
4080 }
4081 }
4082 finally
4083 {
4084 parts[0].ParentGroup.areUpdatesSuspended = false;
4085 }
3719 } 4086 }
4087
3720 parentPrim.HasGroupChanged = true; 4088 parentPrim.HasGroupChanged = true;
3721 parentPrim.ScheduleGroupForFullUpdate(); 4089 parentPrim.ScheduleGroupForFullUpdate();
3722 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4090 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3725,12 +4093,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3725 { 4093 {
3726 SceneObjectPart newRoot = parts[0]; 4094 SceneObjectPart newRoot = parts[0];
3727 parts.Remove(newRoot); 4095 parts.Remove(newRoot);
3728 foreach (SceneObjectPart part in parts) 4096
4097 try
3729 { 4098 {
3730 // Required for linking 4099 parts[0].ParentGroup.areUpdatesSuspended = true;
3731 part.ClearUpdateSchedule(); 4100 foreach (SceneObjectPart part in parts)
3732 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4101 {
4102 part.ClearUpdateSchedule();
4103 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4104 }
3733 } 4105 }
4106 finally
4107 {
4108 parts[0].ParentGroup.areUpdatesSuspended = false;
4109 }
4110
4111
3734 newRoot.ParentGroup.HasGroupChanged = true; 4112 newRoot.ParentGroup.HasGroupChanged = true;
3735 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4113 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3736 } 4114 }
@@ -3750,6 +4128,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3750 public void llBreakAllLinks() 4128 public void llBreakAllLinks()
3751 { 4129 {
3752 m_host.AddScriptLPS(1); 4130 m_host.AddScriptLPS(1);
4131
4132 UUID invItemID = InventorySelf();
4133
4134 TaskInventoryItem item;
4135 m_host.TaskInventory.LockItemsForRead(true);
4136 item = m_host.TaskInventory[invItemID];
4137 m_host.TaskInventory.LockItemsForRead(false);
4138
4139 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4140 && !m_automaticLinkPermission)
4141 {
4142 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4143 return;
4144 }
4145
3753 SceneObjectGroup parentPrim = m_host.ParentGroup; 4146 SceneObjectGroup parentPrim = m_host.ParentGroup;
3754 if (parentPrim.AttachmentPoint != 0) 4147 if (parentPrim.AttachmentPoint != 0)
3755 return; // Fail silently if attached 4148 return; // Fail silently if attached
@@ -3769,25 +4162,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3769 public LSL_String llGetLinkKey(int linknum) 4162 public LSL_String llGetLinkKey(int linknum)
3770 { 4163 {
3771 m_host.AddScriptLPS(1); 4164 m_host.AddScriptLPS(1);
3772 List<UUID> keytable = new List<UUID>();
3773 // parse for sitting avatare-uuids
3774 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3775 {
3776 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3777 keytable.Add(presence.UUID);
3778 });
3779
3780 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3781 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3782 {
3783 return keytable[totalprims - linknum].ToString();
3784 }
3785
3786 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3787 {
3788 return m_host.UUID.ToString();
3789 }
3790
3791 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4165 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3792 if (part != null) 4166 if (part != null)
3793 { 4167 {
@@ -3795,6 +4169,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3795 } 4169 }
3796 else 4170 else
3797 { 4171 {
4172 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4173 {
4174 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4175
4176 if (linknum < 0)
4177 return UUID.Zero.ToString();
4178
4179 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4180 if (avatars.Count > linknum)
4181 {
4182 return avatars[linknum].UUID.ToString();
4183 }
4184 }
3798 return UUID.Zero.ToString(); 4185 return UUID.Zero.ToString();
3799 } 4186 }
3800 } 4187 }
@@ -3894,17 +4281,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3894 m_host.AddScriptLPS(1); 4281 m_host.AddScriptLPS(1);
3895 int count = 0; 4282 int count = 0;
3896 4283
3897 lock (m_host.TaskInventory) 4284 m_host.TaskInventory.LockItemsForRead(true);
4285 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3898 { 4286 {
3899 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4287 if (inv.Value.Type == type || type == -1)
3900 { 4288 {
3901 if (inv.Value.Type == type || type == -1) 4289 count = count + 1;
3902 {
3903 count = count + 1;
3904 }
3905 } 4290 }
3906 } 4291 }
3907 4292
4293 m_host.TaskInventory.LockItemsForRead(false);
3908 return count; 4294 return count;
3909 } 4295 }
3910 4296
@@ -3913,16 +4299,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3913 m_host.AddScriptLPS(1); 4299 m_host.AddScriptLPS(1);
3914 ArrayList keys = new ArrayList(); 4300 ArrayList keys = new ArrayList();
3915 4301
3916 lock (m_host.TaskInventory) 4302 m_host.TaskInventory.LockItemsForRead(true);
4303 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3917 { 4304 {
3918 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4305 if (inv.Value.Type == type || type == -1)
3919 { 4306 {
3920 if (inv.Value.Type == type || type == -1) 4307 keys.Add(inv.Value.Name);
3921 {
3922 keys.Add(inv.Value.Name);
3923 }
3924 } 4308 }
3925 } 4309 }
4310 m_host.TaskInventory.LockItemsForRead(false);
3926 4311
3927 if (keys.Count == 0) 4312 if (keys.Count == 0)
3928 { 4313 {
@@ -3959,25 +4344,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3959 } 4344 }
3960 4345
3961 // move the first object found with this inventory name 4346 // move the first object found with this inventory name
3962 lock (m_host.TaskInventory) 4347 m_host.TaskInventory.LockItemsForRead(true);
4348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3963 { 4349 {
3964 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4350 if (inv.Value.Name == inventory)
3965 { 4351 {
3966 if (inv.Value.Name == inventory) 4352 found = true;
3967 { 4353 objId = inv.Key;
3968 found = true; 4354 assetType = inv.Value.Type;
3969 objId = inv.Key; 4355 objName = inv.Value.Name;
3970 assetType = inv.Value.Type; 4356 break;
3971 objName = inv.Value.Name;
3972 break;
3973 }
3974 } 4357 }
3975 } 4358 }
4359 m_host.TaskInventory.LockItemsForRead(false);
3976 4360
3977 if (!found) 4361 if (!found)
3978 { 4362 {
3979 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4363 llSay(0, String.Format("Could not find object '{0}'", inventory));
3980 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4364 return;
4365// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3981 } 4366 }
3982 4367
3983 // check if destination is an object 4368 // check if destination is an object
@@ -4003,48 +4388,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4003 return; 4388 return;
4004 } 4389 }
4005 } 4390 }
4391
4006 // destination is an avatar 4392 // destination is an avatar
4007 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4393 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4008 4394
4009 if (agentItem == null) 4395 if (agentItem == null)
4010 return; 4396 return;
4011 4397
4012 byte[] bucket = new byte[17]; 4398 byte[] bucket = new byte[1];
4013 bucket[0] = (byte)assetType; 4399 bucket[0] = (byte)assetType;
4014 byte[] objBytes = agentItem.ID.GetBytes(); 4400 //byte[] objBytes = agentItem.ID.GetBytes();
4015 Array.Copy(objBytes, 0, bucket, 1, 16); 4401 //Array.Copy(objBytes, 0, bucket, 1, 16);
4016 4402
4017 GridInstantMessage msg = new GridInstantMessage(World, 4403 GridInstantMessage msg = new GridInstantMessage(World,
4018 m_host.UUID, m_host.Name+", an object owned by "+ 4404 m_host.OwnerID, m_host.Name, destId,
4019 resolveName(m_host.OwnerID)+",", destId,
4020 (byte)InstantMessageDialog.TaskInventoryOffered, 4405 (byte)InstantMessageDialog.TaskInventoryOffered,
4021 false, objName+"\n"+m_host.Name+" is located at "+ 4406 false, objName+". "+m_host.Name+" is located at "+
4022 World.RegionInfo.RegionName+" "+ 4407 World.RegionInfo.RegionName+" "+
4023 m_host.AbsolutePosition.ToString(), 4408 m_host.AbsolutePosition.ToString(),
4024 agentItem.ID, true, m_host.AbsolutePosition, 4409 agentItem.ID, true, m_host.AbsolutePosition,
4025 bucket); 4410 bucket);
4026 if (m_TransferModule != null) 4411
4027 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4412 ScenePresence sp;
4413
4414 if (World.TryGetScenePresence(destId, out sp))
4415 {
4416 sp.ControllingClient.SendInstantMessage(msg);
4417 }
4418 else
4419 {
4420 if (m_TransferModule != null)
4421 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4422 }
4423
4424 //This delay should only occur when giving inventory to avatars.
4028 ScriptSleep(3000); 4425 ScriptSleep(3000);
4029 } 4426 }
4030 } 4427 }
4031 4428
4429 [DebuggerNonUserCode]
4032 public void llRemoveInventory(string name) 4430 public void llRemoveInventory(string name)
4033 { 4431 {
4034 m_host.AddScriptLPS(1); 4432 m_host.AddScriptLPS(1);
4035 4433
4036 lock (m_host.TaskInventory) 4434 List<TaskInventoryItem> inv;
4435 try
4037 { 4436 {
4038 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4437 m_host.TaskInventory.LockItemsForRead(true);
4438 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4439 }
4440 finally
4441 {
4442 m_host.TaskInventory.LockItemsForRead(false);
4443 }
4444 foreach (TaskInventoryItem item in inv)
4445 {
4446 if (item.Name == name)
4039 { 4447 {
4040 if (item.Name == name) 4448 if (item.ItemID == m_itemID)
4041 { 4449 throw new ScriptDeleteException();
4042 if (item.ItemID == m_itemID) 4450 else
4043 throw new ScriptDeleteException(); 4451 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4044 else 4452 return;
4045 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4046 return;
4047 }
4048 } 4453 }
4049 } 4454 }
4050 } 4455 }
@@ -4079,115 +4484,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4079 { 4484 {
4080 m_host.AddScriptLPS(1); 4485 m_host.AddScriptLPS(1);
4081 4486
4082 UUID uuid = (UUID)id; 4487 UUID uuid;
4083 PresenceInfo pinfo = null; 4488 if (UUID.TryParse(id, out uuid))
4084 UserAccount account;
4085
4086 UserInfoCacheEntry ce;
4087 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4088 { 4489 {
4089 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4490 PresenceInfo pinfo = null;
4090 if (account == null) 4491 UserAccount account;
4492
4493 UserInfoCacheEntry ce;
4494 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4091 { 4495 {
4092 m_userInfoCache[uuid] = null; // Cache negative 4496 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4093 return UUID.Zero.ToString(); 4497 if (account == null)
4094 } 4498 {
4499 m_userInfoCache[uuid] = null; // Cache negative
4500 return UUID.Zero.ToString();
4501 }
4095 4502
4096 4503
4097 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4504 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4098 if (pinfos != null && pinfos.Length > 0) 4505 if (pinfos != null && pinfos.Length > 0)
4099 {
4100 foreach (PresenceInfo p in pinfos)
4101 { 4506 {
4102 if (p.RegionID != UUID.Zero) 4507 foreach (PresenceInfo p in pinfos)
4103 { 4508 {
4104 pinfo = p; 4509 if (p.RegionID != UUID.Zero)
4510 {
4511 pinfo = p;
4512 }
4105 } 4513 }
4106 } 4514 }
4107 }
4108 4515
4109 ce = new UserInfoCacheEntry(); 4516 ce = new UserInfoCacheEntry();
4110 ce.time = Util.EnvironmentTickCount(); 4517 ce.time = Util.EnvironmentTickCount();
4111 ce.account = account; 4518 ce.account = account;
4112 ce.pinfo = pinfo; 4519 ce.pinfo = pinfo;
4113 } 4520 m_userInfoCache[uuid] = ce;
4114 else 4521 }
4115 { 4522 else
4116 if (ce == null) 4523 {
4117 return UUID.Zero.ToString(); 4524 if (ce == null)
4525 return UUID.Zero.ToString();
4118 4526
4119 account = ce.account; 4527 account = ce.account;
4120 pinfo = ce.pinfo; 4528 pinfo = ce.pinfo;
4121 } 4529 }
4122 4530
4123 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4531 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4124 {
4125 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4126 if (pinfos != null && pinfos.Length > 0)
4127 { 4532 {
4128 foreach (PresenceInfo p in pinfos) 4533 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4534 if (pinfos != null && pinfos.Length > 0)
4129 { 4535 {
4130 if (p.RegionID != UUID.Zero) 4536 foreach (PresenceInfo p in pinfos)
4131 { 4537 {
4132 pinfo = p; 4538 if (p.RegionID != UUID.Zero)
4539 {
4540 pinfo = p;
4541 }
4133 } 4542 }
4134 } 4543 }
4135 } 4544 else
4136 else 4545 pinfo = null;
4137 pinfo = null;
4138 4546
4139 ce.time = Util.EnvironmentTickCount(); 4547 ce.time = Util.EnvironmentTickCount();
4140 ce.pinfo = pinfo; 4548 ce.pinfo = pinfo;
4141 } 4549 }
4142 4550
4143 string reply = String.Empty; 4551 string reply = String.Empty;
4144 4552
4145 switch (data) 4553 switch (data)
4146 { 4554 {
4147 case 1: // DATA_ONLINE (0|1) 4555 case 1: // DATA_ONLINE (0|1)
4148 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4556 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4149 reply = "1"; 4557 reply = "1";
4150 else 4558 else
4151 reply = "0"; 4559 reply = "0";
4152 break; 4560 break;
4153 case 2: // DATA_NAME (First Last) 4561 case 2: // DATA_NAME (First Last)
4154 reply = account.FirstName + " " + account.LastName; 4562 reply = account.FirstName + " " + account.LastName;
4155 break; 4563 break;
4156 case 3: // DATA_BORN (YYYY-MM-DD) 4564 case 3: // DATA_BORN (YYYY-MM-DD)
4157 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4565 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4158 born = born.AddSeconds(account.Created); 4566 born = born.AddSeconds(account.Created);
4159 reply = born.ToString("yyyy-MM-dd"); 4567 reply = born.ToString("yyyy-MM-dd");
4160 break; 4568 break;
4161 case 4: // DATA_RATING (0,0,0,0,0,0) 4569 case 4: // DATA_RATING (0,0,0,0,0,0)
4162 reply = "0,0,0,0,0,0"; 4570 reply = "0,0,0,0,0,0";
4163 break; 4571 break;
4164 case 7: // DATA_USERLEVEL (integer) 4572 case 8: // DATA_PAYINFO (0|1|2|3)
4165 reply = account.UserLevel.ToString(); 4573 reply = "0";
4166 break; 4574 break;
4167 case 8: // DATA_PAYINFO (0|1|2|3) 4575 default:
4168 reply = "0"; 4576 return UUID.Zero.ToString(); // Raise no event
4169 break; 4577 }
4170 default:
4171 return UUID.Zero.ToString(); // Raise no event
4172 }
4173 4578
4174 UUID rq = UUID.Random(); 4579 UUID rq = UUID.Random();
4175 4580
4176 UUID tid = AsyncCommands. 4581 UUID tid = AsyncCommands.
4177 DataserverPlugin.RegisterRequest(m_localID, 4582 DataserverPlugin.RegisterRequest(m_localID,
4178 m_itemID, rq.ToString()); 4583 m_itemID, rq.ToString());
4179 4584
4180 AsyncCommands. 4585 AsyncCommands.
4181 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4586 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4182 4587
4183 ScriptSleep(100); 4588 ScriptSleep(100);
4184 return tid.ToString(); 4589 return tid.ToString();
4590 }
4591 else
4592 {
4593 ShoutError("Invalid UUID passed to llRequestAgentData.");
4594 }
4595 return "";
4185 } 4596 }
4186 4597
4187 public LSL_String llRequestInventoryData(string name) 4598 public LSL_String llRequestInventoryData(string name)
4188 { 4599 {
4189 m_host.AddScriptLPS(1); 4600 m_host.AddScriptLPS(1);
4190 4601
4602 //Clone is thread safe
4191 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4603 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4192 4604
4193 foreach (TaskInventoryItem item in itemDictionary.Values) 4605 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4239,19 +4651,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4239 if (UUID.TryParse(agent, out agentId)) 4651 if (UUID.TryParse(agent, out agentId))
4240 { 4652 {
4241 ScenePresence presence = World.GetScenePresence(agentId); 4653 ScenePresence presence = World.GetScenePresence(agentId);
4242 if (presence != null) 4654 if (presence != null && presence.PresenceType != PresenceType.Npc)
4243 { 4655 {
4656 // agent must not be a god
4657 if (presence.UserLevel >= 200) return;
4658
4244 // agent must be over the owners land 4659 // agent must be over the owners land
4245 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4660 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4246 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4661 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4247 { 4662 {
4248 World.TeleportClientHome(agentId, presence.ControllingClient); 4663 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4664 {
4665 // They can't be teleported home for some reason
4666 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4667 if (regionInfo != null)
4668 {
4669 World.RequestTeleportLocation(
4670 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4671 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4672 }
4673 }
4249 } 4674 }
4250 } 4675 }
4251 } 4676 }
4252 ScriptSleep(5000); 4677 ScriptSleep(5000);
4253 } 4678 }
4254 4679
4680 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4681 {
4682 m_host.AddScriptLPS(1);
4683 UUID agentId = new UUID();
4684 if (UUID.TryParse(agent, out agentId))
4685 {
4686 ScenePresence presence = World.GetScenePresence(agentId);
4687 if (presence != null && presence.PresenceType != PresenceType.Npc)
4688 {
4689 // agent must not be a god
4690 if (presence.GodLevel >= 200) return;
4691
4692 if (simname == String.Empty)
4693 simname = World.RegionInfo.RegionName;
4694
4695 // agent must be over the owners land
4696 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4697 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4698 {
4699 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);
4700 }
4701 else // or must be wearing the prim
4702 {
4703 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4704 {
4705 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);
4706 }
4707 }
4708 }
4709 }
4710 }
4711
4255 public void llTextBox(string agent, string message, int chatChannel) 4712 public void llTextBox(string agent, string message, int chatChannel)
4256 { 4713 {
4257 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4714 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4263,7 +4720,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4263 UUID av = new UUID(); 4720 UUID av = new UUID();
4264 if (!UUID.TryParse(agent,out av)) 4721 if (!UUID.TryParse(agent,out av))
4265 { 4722 {
4266 LSLError("First parameter to llDialog needs to be a key"); 4723 //LSLError("First parameter to llDialog needs to be a key");
4267 return; 4724 return;
4268 } 4725 }
4269 4726
@@ -4300,17 +4757,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4300 UUID soundId = UUID.Zero; 4757 UUID soundId = UUID.Zero;
4301 if (!UUID.TryParse(impact_sound, out soundId)) 4758 if (!UUID.TryParse(impact_sound, out soundId))
4302 { 4759 {
4303 lock (m_host.TaskInventory) 4760 m_host.TaskInventory.LockItemsForRead(true);
4761 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4304 { 4762 {
4305 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4763 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4306 { 4764 {
4307 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4765 soundId = item.AssetID;
4308 { 4766 break;
4309 soundId = item.AssetID;
4310 break;
4311 }
4312 } 4767 }
4313 } 4768 }
4769 m_host.TaskInventory.LockItemsForRead(false);
4314 } 4770 }
4315 m_host.CollisionSound = soundId; 4771 m_host.CollisionSound = soundId;
4316 m_host.CollisionSoundVolume = (float)impact_volume; 4772 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4350,6 +4806,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4350 UUID partItemID; 4806 UUID partItemID;
4351 foreach (SceneObjectPart part in parts) 4807 foreach (SceneObjectPart part in parts)
4352 { 4808 {
4809 //Clone is thread safe
4353 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4810 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4354 4811
4355 foreach (TaskInventoryItem item in itemsDictionary.Values) 4812 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4553,17 +5010,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4553 5010
4554 m_host.AddScriptLPS(1); 5011 m_host.AddScriptLPS(1);
4555 5012
4556 lock (m_host.TaskInventory) 5013 m_host.TaskInventory.LockItemsForRead(true);
5014 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4557 { 5015 {
4558 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 5016 if (item.Type == 10 && item.ItemID == m_itemID)
4559 { 5017 {
4560 if (item.Type == 10 && item.ItemID == m_itemID) 5018 result = item.Name!=null?item.Name:String.Empty;
4561 { 5019 break;
4562 result = item.Name != null ? item.Name : String.Empty;
4563 break;
4564 }
4565 } 5020 }
4566 } 5021 }
5022 m_host.TaskInventory.LockItemsForRead(false);
4567 5023
4568 return result; 5024 return result;
4569 } 5025 }
@@ -4736,23 +5192,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4736 { 5192 {
4737 m_host.AddScriptLPS(1); 5193 m_host.AddScriptLPS(1);
4738 5194
4739 lock (m_host.TaskInventory) 5195 m_host.TaskInventory.LockItemsForRead(true);
5196 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4740 { 5197 {
4741 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5198 if (inv.Value.Name == name)
4742 { 5199 {
4743 if (inv.Value.Name == name) 5200 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4744 { 5201 {
4745 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5202 m_host.TaskInventory.LockItemsForRead(false);
4746 { 5203 return inv.Value.AssetID.ToString();
4747 return inv.Value.AssetID.ToString(); 5204 }
4748 } 5205 else
4749 else 5206 {
4750 { 5207 m_host.TaskInventory.LockItemsForRead(false);
4751 return UUID.Zero.ToString(); 5208 return UUID.Zero.ToString();
4752 }
4753 } 5209 }
4754 } 5210 }
4755 } 5211 }
5212 m_host.TaskInventory.LockItemsForRead(false);
4756 5213
4757 return UUID.Zero.ToString(); 5214 return UUID.Zero.ToString();
4758 } 5215 }
@@ -4905,14 +5362,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4905 { 5362 {
4906 m_host.AddScriptLPS(1); 5363 m_host.AddScriptLPS(1);
4907 5364
4908 if (src == null) 5365 return src.Length;
4909 {
4910 return 0;
4911 }
4912 else
4913 {
4914 return src.Length;
4915 }
4916 } 5366 }
4917 5367
4918 public LSL_Integer llList2Integer(LSL_List src, int index) 5368 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4958,7 +5408,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4958 else if (src.Data[index] is LSL_Float) 5408 else if (src.Data[index] is LSL_Float)
4959 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5409 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4960 else if (src.Data[index] is LSL_String) 5410 else if (src.Data[index] is LSL_String)
4961 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5411 {
5412 string str = ((LSL_String) src.Data[index]).m_string;
5413 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5414 if (m != Match.Empty)
5415 {
5416 str = m.Value;
5417 double d = 0.0;
5418 if (!Double.TryParse(str, out d))
5419 return 0.0;
5420
5421 return d;
5422 }
5423 return 0.0;
5424 }
4962 return Convert.ToDouble(src.Data[index]); 5425 return Convert.ToDouble(src.Data[index]);
4963 } 5426 }
4964 catch (FormatException) 5427 catch (FormatException)
@@ -5231,7 +5694,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5231 } 5694 }
5232 } 5695 }
5233 } 5696 }
5234 else { 5697 else
5698 {
5235 object[] array = new object[src.Length]; 5699 object[] array = new object[src.Length];
5236 Array.Copy(src.Data, 0, array, 0, src.Length); 5700 Array.Copy(src.Data, 0, array, 0, src.Length);
5237 result = new LSL_List(array); 5701 result = new LSL_List(array);
@@ -5338,7 +5802,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5338 public LSL_Integer llGetRegionAgentCount() 5802 public LSL_Integer llGetRegionAgentCount()
5339 { 5803 {
5340 m_host.AddScriptLPS(1); 5804 m_host.AddScriptLPS(1);
5341 return new LSL_Integer(World.GetRootAgentCount()); 5805
5806 int count = 0;
5807 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5808 count++;
5809 });
5810
5811 return new LSL_Integer(count);
5342 } 5812 }
5343 5813
5344 public LSL_Vector llGetRegionCorner() 5814 public LSL_Vector llGetRegionCorner()
@@ -5618,6 +6088,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5618 flags |= ScriptBaseClass.AGENT_SITTING; 6088 flags |= ScriptBaseClass.AGENT_SITTING;
5619 } 6089 }
5620 6090
6091 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6092 {
6093 flags |= ScriptBaseClass.AGENT_MALE;
6094 }
6095
5621 return flags; 6096 return flags;
5622 } 6097 }
5623 6098
@@ -5680,10 +6155,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5680 m_host.AddScriptLPS(1); 6155 m_host.AddScriptLPS(1);
5681 6156
5682 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6157 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5683 6158 if (parts.Count > 0)
5684 foreach (var part in parts)
5685 { 6159 {
5686 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6160 try
6161 {
6162 parts[0].ParentGroup.areUpdatesSuspended = true;
6163 foreach (var part in parts)
6164 {
6165 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6166 }
6167 }
6168 finally
6169 {
6170 parts[0].ParentGroup.areUpdatesSuspended = false;
6171 }
5687 } 6172 }
5688 } 6173 }
5689 6174
@@ -5735,13 +6220,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5735 6220
5736 if (m_host.OwnerID == land.LandData.OwnerID) 6221 if (m_host.OwnerID == land.LandData.OwnerID)
5737 { 6222 {
5738 World.TeleportClientHome(agentID, presence.ControllingClient); 6223 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6224 presence.TeleportWithMomentum(pos);
6225 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5739 } 6226 }
5740 } 6227 }
5741 } 6228 }
5742 ScriptSleep(5000); 6229 ScriptSleep(5000);
5743 } 6230 }
5744 6231
6232 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6233 {
6234 return ParseString2List(str, separators, in_spacers, false);
6235 }
6236
5745 public LSL_Integer llOverMyLand(string id) 6237 public LSL_Integer llOverMyLand(string id)
5746 { 6238 {
5747 m_host.AddScriptLPS(1); 6239 m_host.AddScriptLPS(1);
@@ -5806,8 +6298,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5806 UUID agentId = new UUID(); 6298 UUID agentId = new UUID();
5807 if (!UUID.TryParse(agent, out agentId)) 6299 if (!UUID.TryParse(agent, out agentId))
5808 return new LSL_Integer(0); 6300 return new LSL_Integer(0);
6301 if (agentId == m_host.GroupID)
6302 return new LSL_Integer(1);
5809 ScenePresence presence = World.GetScenePresence(agentId); 6303 ScenePresence presence = World.GetScenePresence(agentId);
5810 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6304 if (presence == null || presence.IsChildAgent) // Return false for child agents
5811 return new LSL_Integer(0); 6305 return new LSL_Integer(0);
5812 IClientAPI client = presence.ControllingClient; 6306 IClientAPI client = presence.ControllingClient;
5813 if (m_host.GroupID == client.ActiveGroupId) 6307 if (m_host.GroupID == client.ActiveGroupId)
@@ -5942,7 +6436,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5942 return m_host.ParentGroup.AttachmentPoint; 6436 return m_host.ParentGroup.AttachmentPoint;
5943 } 6437 }
5944 6438
5945 public LSL_Integer llGetFreeMemory() 6439 public virtual LSL_Integer llGetFreeMemory()
5946 { 6440 {
5947 m_host.AddScriptLPS(1); 6441 m_host.AddScriptLPS(1);
5948 // Make scripts designed for LSO happy 6442 // Make scripts designed for LSO happy
@@ -6059,7 +6553,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6059 SetParticleSystem(m_host, rules); 6553 SetParticleSystem(m_host, rules);
6060 } 6554 }
6061 6555
6062 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6556 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6557 {
6063 6558
6064 6559
6065 if (rules.Length == 0) 6560 if (rules.Length == 0)
@@ -6253,14 +6748,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6253 6748
6254 protected UUID GetTaskInventoryItem(string name) 6749 protected UUID GetTaskInventoryItem(string name)
6255 { 6750 {
6256 lock (m_host.TaskInventory) 6751 m_host.TaskInventory.LockItemsForRead(true);
6752 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6257 { 6753 {
6258 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6754 if (inv.Value.Name == name)
6259 { 6755 {
6260 if (inv.Value.Name == name) 6756 m_host.TaskInventory.LockItemsForRead(false);
6261 return inv.Key; 6757 return inv.Key;
6262 } 6758 }
6263 } 6759 }
6760 m_host.TaskInventory.LockItemsForRead(false);
6264 6761
6265 return UUID.Zero; 6762 return UUID.Zero;
6266 } 6763 }
@@ -6298,16 +6795,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6298 if (folderID == UUID.Zero) 6795 if (folderID == UUID.Zero)
6299 return; 6796 return;
6300 6797
6301 byte[] bucket = new byte[17]; 6798 byte[] bucket = new byte[1];
6302 bucket[0] = (byte)AssetType.Folder; 6799 bucket[0] = (byte)AssetType.Folder;
6303 byte[] objBytes = folderID.GetBytes(); 6800 //byte[] objBytes = folderID.GetBytes();
6304 Array.Copy(objBytes, 0, bucket, 1, 16); 6801 //Array.Copy(objBytes, 0, bucket, 1, 16);
6305 6802
6306 GridInstantMessage msg = new GridInstantMessage(World, 6803 GridInstantMessage msg = new GridInstantMessage(World,
6307 m_host.UUID, m_host.Name+", an object owned by "+ 6804 m_host.OwnerID, m_host.Name, destID,
6308 resolveName(m_host.OwnerID)+",", destID, 6805 (byte)InstantMessageDialog.TaskInventoryOffered,
6309 (byte)InstantMessageDialog.InventoryOffered, 6806 false, category+". "+m_host.Name+" is located at "+
6310 false, category+"\n"+m_host.Name+" is located at "+
6311 World.RegionInfo.RegionName+" "+ 6807 World.RegionInfo.RegionName+" "+
6312 m_host.AbsolutePosition.ToString(), 6808 m_host.AbsolutePosition.ToString(),
6313 folderID, true, m_host.AbsolutePosition, 6809 folderID, true, m_host.AbsolutePosition,
@@ -6545,13 +7041,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6545 UUID av = new UUID(); 7041 UUID av = new UUID();
6546 if (!UUID.TryParse(avatar,out av)) 7042 if (!UUID.TryParse(avatar,out av))
6547 { 7043 {
6548 LSLError("First parameter to llDialog needs to be a key"); 7044 //LSLError("First parameter to llDialog needs to be a key");
6549 return; 7045 return;
6550 } 7046 }
6551 if (buttons.Length < 1) 7047 if (buttons.Length < 1)
6552 { 7048 {
6553 LSLError("No less than 1 button can be shown"); 7049 buttons.Add("OK");
6554 return;
6555 } 7050 }
6556 if (buttons.Length > 12) 7051 if (buttons.Length > 12)
6557 { 7052 {
@@ -6568,7 +7063,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6568 } 7063 }
6569 if (buttons.Data[i].ToString().Length > 24) 7064 if (buttons.Data[i].ToString().Length > 24)
6570 { 7065 {
6571 LSLError("button label cannot be longer than 24 characters"); 7066 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6572 return; 7067 return;
6573 } 7068 }
6574 buts[i] = buttons.Data[i].ToString(); 7069 buts[i] = buttons.Data[i].ToString();
@@ -6627,22 +7122,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6627 } 7122 }
6628 7123
6629 // copy the first script found with this inventory name 7124 // copy the first script found with this inventory name
6630 lock (m_host.TaskInventory) 7125 TaskInventoryItem scriptItem = null;
7126 m_host.TaskInventory.LockItemsForRead(true);
7127 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6631 { 7128 {
6632 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7129 if (inv.Value.Name == name)
6633 { 7130 {
6634 if (inv.Value.Name == name) 7131 // make sure the object is a script
7132 if (10 == inv.Value.Type)
6635 { 7133 {
6636 // make sure the object is a script 7134 found = true;
6637 if (10 == inv.Value.Type) 7135 srcId = inv.Key;
6638 { 7136 scriptItem = inv.Value;
6639 found = true; 7137 break;
6640 srcId = inv.Key;
6641 break;
6642 }
6643 } 7138 }
6644 } 7139 }
6645 } 7140 }
7141 m_host.TaskInventory.LockItemsForRead(false);
6646 7142
6647 if (!found) 7143 if (!found)
6648 { 7144 {
@@ -6650,9 +7146,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6650 return; 7146 return;
6651 } 7147 }
6652 7148
6653 // the rest of the permission checks are done in RezScript, so check the pin there as well 7149 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6654 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7150 if (dest != null)
7151 {
7152 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7153 {
7154 // the rest of the permission checks are done in RezScript, so check the pin there as well
7155 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6655 7156
7157 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7158 m_host.Inventory.RemoveInventoryItem(srcId);
7159 }
7160 }
6656 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7161 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6657 ScriptSleep(3000); 7162 ScriptSleep(3000);
6658 } 7163 }
@@ -6715,19 +7220,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6715 public LSL_String llMD5String(string src, int nonce) 7220 public LSL_String llMD5String(string src, int nonce)
6716 { 7221 {
6717 m_host.AddScriptLPS(1); 7222 m_host.AddScriptLPS(1);
6718 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7223 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6719 } 7224 }
6720 7225
6721 public LSL_String llSHA1String(string src) 7226 public LSL_String llSHA1String(string src)
6722 { 7227 {
6723 m_host.AddScriptLPS(1); 7228 m_host.AddScriptLPS(1);
6724 return Util.SHA1Hash(src).ToLower(); 7229 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6725 } 7230 }
6726 7231
6727 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7232 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6728 { 7233 {
6729 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7234 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6730 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7235 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7236 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7237 return shapeBlock;
6731 7238
6732 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7239 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6733 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7240 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6832,6 +7339,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6832 // Prim type box, cylinder and prism. 7339 // Prim type box, cylinder and prism.
6833 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) 7340 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)
6834 { 7341 {
7342 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7343 return;
7344
6835 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7345 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6836 ObjectShapePacket.ObjectDataBlock shapeBlock; 7346 ObjectShapePacket.ObjectDataBlock shapeBlock;
6837 7347
@@ -6885,6 +7395,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6885 // Prim type sphere. 7395 // Prim type sphere.
6886 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7396 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6887 { 7397 {
7398 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7399 return;
7400
6888 ObjectShapePacket.ObjectDataBlock shapeBlock; 7401 ObjectShapePacket.ObjectDataBlock shapeBlock;
6889 7402
6890 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7403 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6926,6 +7439,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6926 // Prim type torus, tube and ring. 7439 // Prim type torus, tube and ring.
6927 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) 7440 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)
6928 { 7441 {
7442 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7443 return;
7444
6929 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7445 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6930 ObjectShapePacket.ObjectDataBlock shapeBlock; 7446 ObjectShapePacket.ObjectDataBlock shapeBlock;
6931 7447
@@ -7061,6 +7577,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7061 // Prim type sculpt. 7577 // Prim type sculpt.
7062 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7578 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7063 { 7579 {
7580 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7581 return;
7582
7064 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7583 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7065 UUID sculptId; 7584 UUID sculptId;
7066 7585
@@ -7085,7 +7604,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7085 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7604 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7086 { 7605 {
7087 // default 7606 // default
7088 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7607 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7089 } 7608 }
7090 7609
7091 part.Shape.SetSculptProperties((byte)type, sculptId); 7610 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7101,32 +7620,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7101 ScriptSleep(200); 7620 ScriptSleep(200);
7102 } 7621 }
7103 7622
7104 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7623 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7105 { 7624 {
7106 m_host.AddScriptLPS(1); 7625 m_host.AddScriptLPS(1);
7107 7626
7108 setLinkPrimParams(linknumber, rules); 7627 setLinkPrimParams(linknumber, rules);
7628 }
7109 7629
7110 ScriptSleep(200); 7630 private void setLinkPrimParams(int linknumber, LSL_List rules)
7631 {
7632 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7633 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7634 if (parts.Count>0)
7635 {
7636 try
7637 {
7638 parts[0].ParentGroup.areUpdatesSuspended = true;
7639 foreach (SceneObjectPart part in parts)
7640 SetPrimParams(part, rules);
7641 }
7642 finally
7643 {
7644 parts[0].ParentGroup.areUpdatesSuspended = false;
7645 }
7646 }
7647 if (avatars.Count > 0)
7648 {
7649 foreach (ScenePresence avatar in avatars)
7650 SetPrimParams(avatar, rules);
7651 }
7111 } 7652 }
7112 7653
7113 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7654 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7655 float material_density, float material_friction,
7656 float material_restitution, float material_gravity_modifier)
7114 { 7657 {
7115 m_host.AddScriptLPS(1); 7658 ExtraPhysicsData physdata = new ExtraPhysicsData();
7659 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7660 physdata.Density = part.Density;
7661 physdata.Friction = part.Friction;
7662 physdata.Bounce = part.Bounciness;
7663 physdata.GravitationModifier = part.GravityModifier;
7116 7664
7117 setLinkPrimParams(linknumber, rules); 7665 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7666 physdata.Density = material_density;
7667 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7668 physdata.Friction = material_friction;
7669 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7670 physdata.Bounce = material_restitution;
7671 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7672 physdata.GravitationModifier = material_gravity_modifier;
7673
7674 part.UpdateExtraPhysics(physdata);
7118 } 7675 }
7119 7676
7120 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7677 public void llSetPhysicsMaterial(int material_bits,
7678 float material_gravity_modifier, float material_restitution,
7679 float material_friction, float material_density)
7121 { 7680 {
7122 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7681 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7682 }
7123 7683
7124 foreach (SceneObjectPart part in parts) 7684 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7125 SetPrimParams(part, rules); 7685 {
7686 llSetLinkPrimitiveParamsFast(linknumber, rules);
7687 ScriptSleep(200);
7688 }
7689
7690 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7691 {
7692 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7693 //We only support PRIM_POSITION and PRIM_ROTATION
7694
7695 int idx = 0;
7696
7697 while (idx < rules.Length)
7698 {
7699 int code = rules.GetLSLIntegerItem(idx++);
7700
7701 int remain = rules.Length - idx;
7702
7703 switch (code)
7704 {
7705 case (int)ScriptBaseClass.PRIM_POSITION:
7706 {
7707 if (remain < 1)
7708 return;
7709 LSL_Vector v;
7710 v = rules.GetVector3Item(idx++);
7711
7712 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7713 if (part == null)
7714 break;
7715
7716 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7717 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7718 if (llGetLinkNumber() > 1)
7719 {
7720 localRot = llGetLocalRot();
7721 localPos = llGetLocalPos();
7722 }
7723
7724 v -= localPos;
7725 v /= localRot;
7726
7727 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7728
7729 v = v + 2 * sitOffset;
7730
7731 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7732 av.SendAvatarDataToAllAgents();
7733
7734 }
7735 break;
7736
7737 case (int)ScriptBaseClass.PRIM_ROTATION:
7738 {
7739 if (remain < 1)
7740 return;
7741
7742 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7743 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7744 if (llGetLinkNumber() > 1)
7745 {
7746 localRot = llGetLocalRot();
7747 localPos = llGetLocalPos();
7748 }
7749
7750 LSL_Rotation r;
7751 r = rules.GetQuaternionItem(idx++);
7752 r = r * llGetRootRotation() / localRot;
7753 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7754 av.SendAvatarDataToAllAgents();
7755 }
7756 break;
7757 }
7758 }
7126 } 7759 }
7127 7760
7128 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7761 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7129 { 7762 {
7763 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7764 return;
7765
7130 int idx = 0; 7766 int idx = 0;
7131 7767
7132 bool positionChanged = false; 7768 bool positionChanged = false;
@@ -7154,6 +7790,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7154 currentPosition = GetSetPosTarget(part, v, currentPosition); 7790 currentPosition = GetSetPosTarget(part, v, currentPosition);
7155 7791
7156 break; 7792 break;
7793 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7794 if (remain < 1)
7795 return;
7796
7797 v=rules.GetVector3Item(idx++);
7798 positionChanged = true;
7799 currentPosition = GetSetPosTarget(part, v, currentPosition);
7800
7801 break;
7157 case (int)ScriptBaseClass.PRIM_SIZE: 7802 case (int)ScriptBaseClass.PRIM_SIZE:
7158 if (remain < 1) 7803 if (remain < 1)
7159 return; 7804 return;
@@ -7447,6 +8092,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7447 part.ScriptSetPhysicsStatus(physics); 8092 part.ScriptSetPhysicsStatus(physics);
7448 break; 8093 break;
7449 8094
8095 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8096 if (remain < 1)
8097 return;
8098
8099 int shape_type = rules.GetLSLIntegerItem(idx++);
8100
8101 ExtraPhysicsData physdata = new ExtraPhysicsData();
8102 physdata.Density = part.Density;
8103 physdata.Bounce = part.Bounciness;
8104 physdata.GravitationModifier = part.GravityModifier;
8105 physdata.PhysShapeType = (PhysShapeType)shape_type;
8106
8107 part.UpdateExtraPhysics(physdata);
8108
8109 break;
8110
8111 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8112 if (remain < 5)
8113 return;
8114
8115 int material_bits = rules.GetLSLIntegerItem(idx++);
8116 float material_density = (float)rules.GetLSLFloatItem(idx++);
8117 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8118 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8119 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8120
8121 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8122
8123 break;
8124
7450 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8125 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7451 if (remain < 1) 8126 if (remain < 1)
7452 return; 8127 return;
@@ -7520,7 +8195,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7520 if (part.ParentGroup.RootPart == part) 8195 if (part.ParentGroup.RootPart == part)
7521 { 8196 {
7522 SceneObjectGroup parent = part.ParentGroup; 8197 SceneObjectGroup parent = part.ParentGroup;
7523 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8198 Util.FireAndForget(delegate(object x) {
8199 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8200 });
7524 } 8201 }
7525 else 8202 else
7526 { 8203 {
@@ -7531,6 +8208,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7531 } 8208 }
7532 } 8209 }
7533 } 8210 }
8211
8212 if (positionChanged)
8213 {
8214 if (part.ParentGroup.RootPart == part)
8215 {
8216 SceneObjectGroup parent = part.ParentGroup;
8217 Util.FireAndForget(delegate(object x) {
8218 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8219 });
8220 }
8221 else
8222 {
8223 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8224 SceneObjectGroup parent = part.ParentGroup;
8225 parent.HasGroupChanged = true;
8226 parent.ScheduleGroupForTerseUpdate();
8227 }
8228 }
7534 } 8229 }
7535 8230
7536 public LSL_String llStringToBase64(string str) 8231 public LSL_String llStringToBase64(string str)
@@ -7691,13 +8386,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7691 public LSL_Integer llGetNumberOfPrims() 8386 public LSL_Integer llGetNumberOfPrims()
7692 { 8387 {
7693 m_host.AddScriptLPS(1); 8388 m_host.AddScriptLPS(1);
7694 int avatarCount = 0; 8389 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7695 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8390
7696 {
7697 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7698 avatarCount++;
7699 });
7700
7701 return m_host.ParentGroup.PrimCount + avatarCount; 8391 return m_host.ParentGroup.PrimCount + avatarCount;
7702 } 8392 }
7703 8393
@@ -7713,55 +8403,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7713 m_host.AddScriptLPS(1); 8403 m_host.AddScriptLPS(1);
7714 UUID objID = UUID.Zero; 8404 UUID objID = UUID.Zero;
7715 LSL_List result = new LSL_List(); 8405 LSL_List result = new LSL_List();
8406
8407 // If the ID is not valid, return null result
7716 if (!UUID.TryParse(obj, out objID)) 8408 if (!UUID.TryParse(obj, out objID))
7717 { 8409 {
7718 result.Add(new LSL_Vector()); 8410 result.Add(new LSL_Vector());
7719 result.Add(new LSL_Vector()); 8411 result.Add(new LSL_Vector());
7720 return result; 8412 return result;
7721 } 8413 }
8414
8415 // Check if this is an attached prim. If so, replace
8416 // the UUID with the avatar UUID and report it's bounding box
8417 SceneObjectPart part = World.GetSceneObjectPart(objID);
8418 if (part != null && part.ParentGroup.IsAttachment)
8419 objID = part.ParentGroup.AttachedAvatar;
8420
8421 // Find out if this is an avatar ID. If so, return it's box
7722 ScenePresence presence = World.GetScenePresence(objID); 8422 ScenePresence presence = World.GetScenePresence(objID);
7723 if (presence != null) 8423 if (presence != null)
7724 { 8424 {
7725 if (presence.ParentID == 0) // not sat on an object 8425 // As per LSL Wiki, there is no difference between sitting
8426 // and standing avatar since server 1.36
8427 LSL_Vector lower;
8428 LSL_Vector upper;
8429 if (presence.Animator.Animations.DefaultAnimation.AnimID
8430 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7726 { 8431 {
7727 LSL_Vector lower; 8432 // This is for ground sitting avatars
7728 LSL_Vector upper; 8433 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7729 if (presence.Animator.Animations.DefaultAnimation.AnimID 8434 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7730 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8435 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7731 {
7732 // This is for ground sitting avatars
7733 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7734 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7735 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7736 }
7737 else
7738 {
7739 // This is for standing/flying avatars
7740 float height = presence.Appearance.AvatarHeight / 2.0f;
7741 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7742 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7743 }
7744 result.Add(lower);
7745 result.Add(upper);
7746 return result;
7747 } 8436 }
7748 else 8437 else
7749 { 8438 {
7750 // sitting on an object so we need the bounding box of that 8439 // This is for standing/flying avatars
7751 // which should include the avatar so set the UUID to the 8440 float height = presence.Appearance.AvatarHeight / 2.0f;
7752 // UUID of the object the avatar is sat on and allow it to fall through 8441 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7753 // to processing an object 8442 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7754 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7755 objID = p.UUID;
7756 } 8443 }
8444
8445 // Adjust to the documented error offsets (see LSL Wiki)
8446 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8447 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8448
8449 if (lower.x > upper.x)
8450 lower.x = upper.x;
8451 if (lower.y > upper.y)
8452 lower.y = upper.y;
8453 if (lower.z > upper.z)
8454 lower.z = upper.z;
8455
8456 result.Add(lower);
8457 result.Add(upper);
8458 return result;
7757 } 8459 }
7758 SceneObjectPart part = World.GetSceneObjectPart(objID); 8460
8461 part = World.GetSceneObjectPart(objID);
7759 // Currently only works for single prims without a sitting avatar 8462 // Currently only works for single prims without a sitting avatar
7760 if (part != null) 8463 if (part != null)
7761 { 8464 {
7762 Vector3 halfSize = part.Scale / 2.0f; 8465 float minX;
7763 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8466 float maxX;
7764 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8467 float minY;
8468 float maxY;
8469 float minZ;
8470 float maxZ;
8471
8472 // This BBox is in sim coordinates, with the offset being
8473 // a contained point.
8474 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8475 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8476
8477 minX -= offsets[0].X;
8478 maxX -= offsets[0].X;
8479 minY -= offsets[0].Y;
8480 maxY -= offsets[0].Y;
8481 minZ -= offsets[0].Z;
8482 maxZ -= offsets[0].Z;
8483
8484 LSL_Vector lower;
8485 LSL_Vector upper;
8486
8487 // Adjust to the documented error offsets (see LSL Wiki)
8488 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8489 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8490
8491 if (lower.x > upper.x)
8492 lower.x = upper.x;
8493 if (lower.y > upper.y)
8494 lower.y = upper.y;
8495 if (lower.z > upper.z)
8496 lower.z = upper.z;
8497
7765 result.Add(lower); 8498 result.Add(lower);
7766 result.Add(upper); 8499 result.Add(upper);
7767 return result; 8500 return result;
@@ -7841,13 +8574,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7841 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8574 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7842 part.AbsolutePosition.Y, 8575 part.AbsolutePosition.Y,
7843 part.AbsolutePosition.Z); 8576 part.AbsolutePosition.Z);
7844 // For some reason, the part.AbsolutePosition.* values do not change if the
7845 // linkset is rotated; they always reflect the child prim's world position
7846 // as though the linkset is unrotated. This is incompatible behavior with SL's
7847 // implementation, so will break scripts imported from there (not to mention it
7848 // makes it more difficult to determine a child prim's actual inworld position).
7849 if (part.ParentID != 0)
7850 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7851 res.Add(v); 8577 res.Add(v);
7852 break; 8578 break;
7853 8579
@@ -8018,56 +8744,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8018 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8744 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8019 if (remain < 1) 8745 if (remain < 1)
8020 return res; 8746 return res;
8021 8747 face = (int)rules.GetLSLIntegerItem(idx++);
8022 face=(int)rules.GetLSLIntegerItem(idx++);
8023 8748
8024 tex = part.Shape.Textures; 8749 tex = part.Shape.Textures;
8750 int shiny;
8025 if (face == ScriptBaseClass.ALL_SIDES) 8751 if (face == ScriptBaseClass.ALL_SIDES)
8026 { 8752 {
8027 for (face = 0; face < GetNumberOfSides(part); face++) 8753 for (face = 0; face < GetNumberOfSides(part); face++)
8028 { 8754 {
8029 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8755 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8030 // Convert Shininess to PRIM_SHINY_* 8756 if (shinyness == Shininess.High)
8031 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8757 {
8032 // PRIM_BUMP_* 8758 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8033 res.Add(new LSL_Integer((int)texface.Bump)); 8759 }
8760 else if (shinyness == Shininess.Medium)
8761 {
8762 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8763 }
8764 else if (shinyness == Shininess.Low)
8765 {
8766 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8767 }
8768 else
8769 {
8770 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8771 }
8772 res.Add(new LSL_Integer(shiny));
8773 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8034 } 8774 }
8035 } 8775 }
8036 else 8776 else
8037 { 8777 {
8038 if (face >= 0 && face < GetNumberOfSides(part)) 8778 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8779 if (shinyness == Shininess.High)
8039 { 8780 {
8040 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8781 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8041 // Convert Shininess to PRIM_SHINY_* 8782 }
8042 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8783 else if (shinyness == Shininess.Medium)
8043 // PRIM_BUMP_* 8784 {
8044 res.Add(new LSL_Integer((int)texface.Bump)); 8785 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8786 }
8787 else if (shinyness == Shininess.Low)
8788 {
8789 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8045 } 8790 }
8791 else
8792 {
8793 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8794 }
8795 res.Add(new LSL_Integer(shiny));
8796 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8046 } 8797 }
8047 break; 8798 break;
8048 8799
8049 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8800 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8050 if (remain < 1) 8801 if (remain < 1)
8051 return res; 8802 return res;
8052 8803 face = (int)rules.GetLSLIntegerItem(idx++);
8053 face=(int)rules.GetLSLIntegerItem(idx++);
8054 8804
8055 tex = part.Shape.Textures; 8805 tex = part.Shape.Textures;
8806 int fullbright;
8056 if (face == ScriptBaseClass.ALL_SIDES) 8807 if (face == ScriptBaseClass.ALL_SIDES)
8057 { 8808 {
8058 for (face = 0; face < GetNumberOfSides(part); face++) 8809 for (face = 0; face < GetNumberOfSides(part); face++)
8059 { 8810 {
8060 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8811 if (tex.GetFace((uint)face).Fullbright == true)
8061 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8812 {
8813 fullbright = ScriptBaseClass.TRUE;
8814 }
8815 else
8816 {
8817 fullbright = ScriptBaseClass.FALSE;
8818 }
8819 res.Add(new LSL_Integer(fullbright));
8062 } 8820 }
8063 } 8821 }
8064 else 8822 else
8065 { 8823 {
8066 if (face >= 0 && face < GetNumberOfSides(part)) 8824 if (tex.GetFace((uint)face).Fullbright == true)
8067 { 8825 {
8068 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8826 fullbright = ScriptBaseClass.TRUE;
8069 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8070 } 8827 }
8828 else
8829 {
8830 fullbright = ScriptBaseClass.FALSE;
8831 }
8832 res.Add(new LSL_Integer(fullbright));
8071 } 8833 }
8072 break; 8834 break;
8073 8835
@@ -8089,27 +8851,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8089 break; 8851 break;
8090 8852
8091 case (int)ScriptBaseClass.PRIM_TEXGEN: 8853 case (int)ScriptBaseClass.PRIM_TEXGEN:
8854 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8092 if (remain < 1) 8855 if (remain < 1)
8093 return res; 8856 return res;
8094 8857 face = (int)rules.GetLSLIntegerItem(idx++);
8095 face=(int)rules.GetLSLIntegerItem(idx++);
8096 8858
8097 tex = part.Shape.Textures; 8859 tex = part.Shape.Textures;
8098 if (face == ScriptBaseClass.ALL_SIDES) 8860 if (face == ScriptBaseClass.ALL_SIDES)
8099 { 8861 {
8100 for (face = 0; face < GetNumberOfSides(part); face++) 8862 for (face = 0; face < GetNumberOfSides(part); face++)
8101 { 8863 {
8102 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8864 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8103 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8865 {
8104 res.Add(new LSL_Integer((uint)texgen >> 1)); 8866 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8867 }
8868 else
8869 {
8870 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8871 }
8105 } 8872 }
8106 } 8873 }
8107 else 8874 else
8108 { 8875 {
8109 if (face >= 0 && face < GetNumberOfSides(part)) 8876 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8877 {
8878 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8879 }
8880 else
8110 { 8881 {
8111 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8882 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8112 res.Add(new LSL_Integer((uint)texgen >> 1));
8113 } 8883 }
8114 } 8884 }
8115 break; 8885 break;
@@ -8132,28 +8902,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8132 case (int)ScriptBaseClass.PRIM_GLOW: 8902 case (int)ScriptBaseClass.PRIM_GLOW:
8133 if (remain < 1) 8903 if (remain < 1)
8134 return res; 8904 return res;
8135 8905 face = (int)rules.GetLSLIntegerItem(idx++);
8136 face=(int)rules.GetLSLIntegerItem(idx++);
8137 8906
8138 tex = part.Shape.Textures; 8907 tex = part.Shape.Textures;
8908 float primglow;
8139 if (face == ScriptBaseClass.ALL_SIDES) 8909 if (face == ScriptBaseClass.ALL_SIDES)
8140 { 8910 {
8141 for (face = 0; face < GetNumberOfSides(part); face++) 8911 for (face = 0; face < GetNumberOfSides(part); face++)
8142 { 8912 {
8143 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8913 primglow = tex.GetFace((uint)face).Glow;
8144 res.Add(new LSL_Float(texface.Glow)); 8914 res.Add(new LSL_Float(primglow));
8145 } 8915 }
8146 } 8916 }
8147 else 8917 else
8148 { 8918 {
8149 if (face >= 0 && face < GetNumberOfSides(part)) 8919 primglow = tex.GetFace((uint)face).Glow;
8150 { 8920 res.Add(new LSL_Float(primglow));
8151 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8152 res.Add(new LSL_Float(texface.Glow));
8153 }
8154 } 8921 }
8155 break; 8922 break;
8156
8157 case (int)ScriptBaseClass.PRIM_TEXT: 8923 case (int)ScriptBaseClass.PRIM_TEXT:
8158 Color4 textColor = part.GetTextColor(); 8924 Color4 textColor = part.GetTextColor();
8159 res.Add(new LSL_String(part.Text)); 8925 res.Add(new LSL_String(part.Text));
@@ -8765,8 +9531,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8765 // The function returns an ordered list 9531 // The function returns an ordered list
8766 // representing the tokens found in the supplied 9532 // representing the tokens found in the supplied
8767 // sources string. If two successive tokenizers 9533 // sources string. If two successive tokenizers
8768 // are encountered, then a NULL entry is added 9534 // are encountered, then a null-string entry is
8769 // to the list. 9535 // added to the list.
8770 // 9536 //
8771 // It is a precondition that the source and 9537 // It is a precondition that the source and
8772 // toekizer lisst are non-null. If they are null, 9538 // toekizer lisst are non-null. If they are null,
@@ -8774,7 +9540,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8774 // while their lengths are being determined. 9540 // while their lengths are being determined.
8775 // 9541 //
8776 // A small amount of working memoryis required 9542 // A small amount of working memoryis required
8777 // of approximately 8*#tokenizers. 9543 // of approximately 8*#tokenizers + 8*srcstrlen.
8778 // 9544 //
8779 // There are many ways in which this function 9545 // There are many ways in which this function
8780 // can be implemented, this implementation is 9546 // can be implemented, this implementation is
@@ -8790,155 +9556,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8790 // and eliminates redundant tokenizers as soon 9556 // and eliminates redundant tokenizers as soon
8791 // as is possible. 9557 // as is possible.
8792 // 9558 //
8793 // The implementation tries to avoid any copying 9559 // The implementation tries to minimize temporary
8794 // of arrays or other objects. 9560 // garbage generation.
8795 // </remarks> 9561 // </remarks>
8796 9562
8797 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9563 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8798 { 9564 {
8799 int beginning = 0; 9565 return ParseString2List(src, separators, spacers, true);
8800 int srclen = src.Length; 9566 }
8801 int seplen = separators.Length;
8802 object[] separray = separators.Data;
8803 int spclen = spacers.Length;
8804 object[] spcarray = spacers.Data;
8805 int mlen = seplen+spclen;
8806
8807 int[] offset = new int[mlen+1];
8808 bool[] active = new bool[mlen];
8809
8810 int best;
8811 int j;
8812
8813 // Initial capacity reduces resize cost
8814 9567
8815 LSL_List tokens = new LSL_List(); 9568 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9569 {
9570 int srclen = src.Length;
9571 int seplen = separators.Length;
9572 object[] separray = separators.Data;
9573 int spclen = spacers.Length;
9574 object[] spcarray = spacers.Data;
9575 int dellen = 0;
9576 string[] delarray = new string[seplen+spclen];
8816 9577
8817 // All entries are initially valid 9578 int outlen = 0;
9579 string[] outarray = new string[srclen*2+1];
8818 9580
8819 for (int i = 0; i < mlen; i++) 9581 int i, j;
8820 active[i] = true; 9582 string d;
8821 9583
8822 offset[mlen] = srclen; 9584 m_host.AddScriptLPS(1);
8823 9585
8824 while (beginning < srclen) 9586 /*
9587 * Convert separator and spacer lists to C# strings.
9588 * Also filter out null strings so we don't hang.
9589 */
9590 for (i = 0; i < seplen; i ++)
8825 { 9591 {
9592 d = separray[i].ToString();
9593 if (d.Length > 0)
9594 {
9595 delarray[dellen++] = d;
9596 }
9597 }
9598 seplen = dellen;
8826 9599
8827 best = mlen; // as bad as it gets 9600 for (i = 0; i < spclen; i ++)
9601 {
9602 d = spcarray[i].ToString();
9603 if (d.Length > 0)
9604 {
9605 delarray[dellen++] = d;
9606 }
9607 }
8828 9608
8829 // Scan for separators 9609 /*
9610 * Scan through source string from beginning to end.
9611 */
9612 for (i = 0;;)
9613 {
8830 9614
8831 for (j = 0; j < seplen; j++) 9615 /*
9616 * Find earliest delimeter in src starting at i (if any).
9617 */
9618 int earliestDel = -1;
9619 int earliestSrc = srclen;
9620 string earliestStr = null;
9621 for (j = 0; j < dellen; j ++)
8832 { 9622 {
8833 if (separray[j].ToString() == String.Empty) 9623 d = delarray[j];
8834 active[j] = false; 9624 if (d != null)
8835
8836 if (active[j])
8837 { 9625 {
8838 // scan all of the markers 9626 int index = src.IndexOf(d, i);
8839 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9627 if (index < 0)
8840 { 9628 {
8841 // not present at all 9629 delarray[j] = null; // delim nowhere in src, don't check it anymore
8842 active[j] = false;
8843 } 9630 }
8844 else 9631 else if (index < earliestSrc)
8845 { 9632 {
8846 // present and correct 9633 earliestSrc = index; // where delimeter starts in source string
8847 if (offset[j] < offset[best]) 9634 earliestDel = j; // where delimeter is in delarray[]
8848 { 9635 earliestStr = d; // the delimeter string from delarray[]
8849 // closest so far 9636 if (index == i) break; // can't do any better than found at beg of string
8850 best = j;
8851 if (offset[best] == beginning)
8852 break;
8853 }
8854 } 9637 }
8855 } 9638 }
8856 } 9639 }
8857 9640
8858 // Scan for spacers 9641 /*
8859 9642 * Output source string starting at i through start of earliest delimeter.
8860 if (offset[best] != beginning) 9643 */
9644 if (keepNulls || (earliestSrc > i))
8861 { 9645 {
8862 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9646 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8863 {
8864 if (spcarray[j-seplen].ToString() == String.Empty)
8865 active[j] = false;
8866
8867 if (active[j])
8868 {
8869 // scan all of the markers
8870 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8871 {
8872 // not present at all
8873 active[j] = false;
8874 }
8875 else
8876 {
8877 // present and correct
8878 if (offset[j] < offset[best])
8879 {
8880 // closest so far
8881 best = j;
8882 }
8883 }
8884 }
8885 }
8886 } 9647 }
8887 9648
8888 // This is the normal exit from the scanning loop 9649 /*
9650 * If no delimeter found at or after i, we're done scanning.
9651 */
9652 if (earliestDel < 0) break;
8889 9653
8890 if (best == mlen) 9654 /*
9655 * If delimeter was a spacer, output the spacer.
9656 */
9657 if (earliestDel >= seplen)
8891 { 9658 {
8892 // no markers were found on this pass 9659 outarray[outlen++] = earliestStr;
8893 // so we're pretty much done
8894 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8895 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8896 break;
8897 } 9660 }
8898 9661
8899 // Otherwise we just add the newly delimited token 9662 /*
8900 // and recalculate where the search should continue. 9663 * Look at rest of src string following delimeter.
8901 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9664 */
8902 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9665 i = earliestSrc + earliestStr.Length;
8903
8904 if (best < seplen)
8905 {
8906 beginning = offset[best] + (separray[best].ToString()).Length;
8907 }
8908 else
8909 {
8910 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8911 string str = spcarray[best - seplen].ToString();
8912 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8913 tokens.Add(new LSL_String(str));
8914 }
8915 } 9666 }
8916 9667
8917 // This an awkward an not very intuitive boundary case. If the 9668 /*
8918 // last substring is a tokenizer, then there is an implied trailing 9669 * Make up an exact-sized output array suitable for an LSL_List object.
8919 // null list entry. Hopefully the single comparison will not be too 9670 */
8920 // arduous. Alternatively the 'break' could be replced with a return 9671 object[] outlist = new object[outlen];
8921 // but that's shabby programming. 9672 for (i = 0; i < outlen; i ++)
8922
8923 if ((beginning == srclen) && (keepNulls))
8924 { 9673 {
8925 if (srclen != 0) 9674 outlist[i] = new LSL_String(outarray[i]);
8926 tokens.Add(new LSL_String(""));
8927 } 9675 }
8928 9676 return new LSL_List(outlist);
8929 return tokens;
8930 }
8931
8932 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8933 {
8934 m_host.AddScriptLPS(1);
8935 return this.ParseString(src, separators, spacers, false);
8936 }
8937
8938 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8939 {
8940 m_host.AddScriptLPS(1);
8941 return this.ParseString(src, separators, spacers, true);
8942 } 9677 }
8943 9678
8944 public LSL_Integer llGetObjectPermMask(int mask) 9679 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9015,28 +9750,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9015 { 9750 {
9016 m_host.AddScriptLPS(1); 9751 m_host.AddScriptLPS(1);
9017 9752
9018 lock (m_host.TaskInventory) 9753 m_host.TaskInventory.LockItemsForRead(true);
9754 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9019 { 9755 {
9020 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9756 if (inv.Value.Name == item)
9021 { 9757 {
9022 if (inv.Value.Name == item) 9758 m_host.TaskInventory.LockItemsForRead(false);
9759 switch (mask)
9023 { 9760 {
9024 switch (mask) 9761 case 0:
9025 { 9762 return (int)inv.Value.BasePermissions;
9026 case 0: 9763 case 1:
9027 return (int)inv.Value.BasePermissions; 9764 return (int)inv.Value.CurrentPermissions;
9028 case 1: 9765 case 2:
9029 return (int)inv.Value.CurrentPermissions; 9766 return (int)inv.Value.GroupPermissions;
9030 case 2: 9767 case 3:
9031 return (int)inv.Value.GroupPermissions; 9768 return (int)inv.Value.EveryonePermissions;
9032 case 3: 9769 case 4:
9033 return (int)inv.Value.EveryonePermissions; 9770 return (int)inv.Value.NextPermissions;
9034 case 4:
9035 return (int)inv.Value.NextPermissions;
9036 }
9037 } 9771 }
9038 } 9772 }
9039 } 9773 }
9774 m_host.TaskInventory.LockItemsForRead(false);
9040 9775
9041 return -1; 9776 return -1;
9042 } 9777 }
@@ -9083,16 +9818,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9083 { 9818 {
9084 m_host.AddScriptLPS(1); 9819 m_host.AddScriptLPS(1);
9085 9820
9086 lock (m_host.TaskInventory) 9821 m_host.TaskInventory.LockItemsForRead(true);
9822 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9087 { 9823 {
9088 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9824 if (inv.Value.Name == item)
9089 { 9825 {
9090 if (inv.Value.Name == item) 9826 m_host.TaskInventory.LockItemsForRead(false);
9091 { 9827 return inv.Value.CreatorID.ToString();
9092 return inv.Value.CreatorID.ToString();
9093 }
9094 } 9828 }
9095 } 9829 }
9830 m_host.TaskInventory.LockItemsForRead(false);
9096 9831
9097 llSay(0, "No item name '" + item + "'"); 9832 llSay(0, "No item name '" + item + "'");
9098 9833
@@ -9240,7 +9975,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9240 } 9975 }
9241 9976
9242 /// <summary> 9977 /// <summary>
9243 /// illListReplaceList removes the sub-list defined by the inclusive indices 9978 /// llListReplaceList removes the sub-list defined by the inclusive indices
9244 /// start and end and inserts the src list in its place. The inclusive 9979 /// start and end and inserts the src list in its place. The inclusive
9245 /// nature of the indices means that at least one element must be deleted 9980 /// nature of the indices means that at least one element must be deleted
9246 /// if the indices are within the bounds of the existing list. I.e. 2,2 9981 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9297,16 +10032,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9297 // based upon end. Note that if end exceeds the upper 10032 // based upon end. Note that if end exceeds the upper
9298 // bound in this case, the entire destination list 10033 // bound in this case, the entire destination list
9299 // is removed. 10034 // is removed.
9300 else 10035 else if (start == 0)
9301 { 10036 {
9302 if (end + 1 < dest.Length) 10037 if (end + 1 < dest.Length)
9303 {
9304 return src + dest.GetSublist(end + 1, -1); 10038 return src + dest.GetSublist(end + 1, -1);
9305 }
9306 else 10039 else
9307 {
9308 return src; 10040 return src;
9309 } 10041 }
10042 else // Start < 0
10043 {
10044 if (end + 1 < dest.Length)
10045 return dest.GetSublist(end + 1, -1);
10046 else
10047 return new LSL_List();
9310 } 10048 }
9311 } 10049 }
9312 // Finally, if start > end, we strip away a prefix and 10050 // Finally, if start > end, we strip away a prefix and
@@ -9357,17 +10095,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9357 int width = 0; 10095 int width = 0;
9358 int height = 0; 10096 int height = 0;
9359 10097
9360 ParcelMediaCommandEnum? commandToSend = null; 10098 uint commandToSend = 0;
9361 float time = 0.0f; // default is from start 10099 float time = 0.0f; // default is from start
9362 10100
9363 ScenePresence presence = null; 10101 ScenePresence presence = null;
9364 10102
9365 for (int i = 0; i < commandList.Data.Length; i++) 10103 for (int i = 0; i < commandList.Data.Length; i++)
9366 { 10104 {
9367 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10105 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9368 switch (command) 10106 switch (command)
9369 { 10107 {
9370 case ParcelMediaCommandEnum.Agent: 10108 case (uint)ParcelMediaCommandEnum.Agent:
9371 // we send only to one agent 10109 // we send only to one agent
9372 if ((i + 1) < commandList.Length) 10110 if ((i + 1) < commandList.Length)
9373 { 10111 {
@@ -9384,25 +10122,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9384 } 10122 }
9385 break; 10123 break;
9386 10124
9387 case ParcelMediaCommandEnum.Loop: 10125 case (uint)ParcelMediaCommandEnum.Loop:
9388 loop = 1; 10126 loop = 1;
9389 commandToSend = command; 10127 commandToSend = command;
9390 update = true; //need to send the media update packet to set looping 10128 update = true; //need to send the media update packet to set looping
9391 break; 10129 break;
9392 10130
9393 case ParcelMediaCommandEnum.Play: 10131 case (uint)ParcelMediaCommandEnum.Play:
9394 loop = 0; 10132 loop = 0;
9395 commandToSend = command; 10133 commandToSend = command;
9396 update = true; //need to send the media update packet to make sure it doesn't loop 10134 update = true; //need to send the media update packet to make sure it doesn't loop
9397 break; 10135 break;
9398 10136
9399 case ParcelMediaCommandEnum.Pause: 10137 case (uint)ParcelMediaCommandEnum.Pause:
9400 case ParcelMediaCommandEnum.Stop: 10138 case (uint)ParcelMediaCommandEnum.Stop:
9401 case ParcelMediaCommandEnum.Unload: 10139 case (uint)ParcelMediaCommandEnum.Unload:
9402 commandToSend = command; 10140 commandToSend = command;
9403 break; 10141 break;
9404 10142
9405 case ParcelMediaCommandEnum.Url: 10143 case (uint)ParcelMediaCommandEnum.Url:
9406 if ((i + 1) < commandList.Length) 10144 if ((i + 1) < commandList.Length)
9407 { 10145 {
9408 if (commandList.Data[i + 1] is LSL_String) 10146 if (commandList.Data[i + 1] is LSL_String)
@@ -9415,7 +10153,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9415 } 10153 }
9416 break; 10154 break;
9417 10155
9418 case ParcelMediaCommandEnum.Texture: 10156 case (uint)ParcelMediaCommandEnum.Texture:
9419 if ((i + 1) < commandList.Length) 10157 if ((i + 1) < commandList.Length)
9420 { 10158 {
9421 if (commandList.Data[i + 1] is LSL_String) 10159 if (commandList.Data[i + 1] is LSL_String)
@@ -9428,7 +10166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9428 } 10166 }
9429 break; 10167 break;
9430 10168
9431 case ParcelMediaCommandEnum.Time: 10169 case (uint)ParcelMediaCommandEnum.Time:
9432 if ((i + 1) < commandList.Length) 10170 if ((i + 1) < commandList.Length)
9433 { 10171 {
9434 if (commandList.Data[i + 1] is LSL_Float) 10172 if (commandList.Data[i + 1] is LSL_Float)
@@ -9440,7 +10178,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9440 } 10178 }
9441 break; 10179 break;
9442 10180
9443 case ParcelMediaCommandEnum.AutoAlign: 10181 case (uint)ParcelMediaCommandEnum.AutoAlign:
9444 if ((i + 1) < commandList.Length) 10182 if ((i + 1) < commandList.Length)
9445 { 10183 {
9446 if (commandList.Data[i + 1] is LSL_Integer) 10184 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9454,7 +10192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9454 } 10192 }
9455 break; 10193 break;
9456 10194
9457 case ParcelMediaCommandEnum.Type: 10195 case (uint)ParcelMediaCommandEnum.Type:
9458 if ((i + 1) < commandList.Length) 10196 if ((i + 1) < commandList.Length)
9459 { 10197 {
9460 if (commandList.Data[i + 1] is LSL_String) 10198 if (commandList.Data[i + 1] is LSL_String)
@@ -9467,7 +10205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9467 } 10205 }
9468 break; 10206 break;
9469 10207
9470 case ParcelMediaCommandEnum.Desc: 10208 case (uint)ParcelMediaCommandEnum.Desc:
9471 if ((i + 1) < commandList.Length) 10209 if ((i + 1) < commandList.Length)
9472 { 10210 {
9473 if (commandList.Data[i + 1] is LSL_String) 10211 if (commandList.Data[i + 1] is LSL_String)
@@ -9480,7 +10218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 } 10218 }
9481 break; 10219 break;
9482 10220
9483 case ParcelMediaCommandEnum.Size: 10221 case (uint)ParcelMediaCommandEnum.Size:
9484 if ((i + 2) < commandList.Length) 10222 if ((i + 2) < commandList.Length)
9485 { 10223 {
9486 if (commandList.Data[i + 1] is LSL_Integer) 10224 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9550,7 +10288,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9550 } 10288 }
9551 } 10289 }
9552 10290
9553 if (commandToSend != null) 10291 if (commandToSend != 0)
9554 { 10292 {
9555 // the commandList contained a start/stop/... command, too 10293 // the commandList contained a start/stop/... command, too
9556 if (presence == null) 10294 if (presence == null)
@@ -9587,7 +10325,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9587 10325
9588 if (aList.Data[i] != null) 10326 if (aList.Data[i] != null)
9589 { 10327 {
9590 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10328 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9591 { 10329 {
9592 case ParcelMediaCommandEnum.Url: 10330 case ParcelMediaCommandEnum.Url:
9593 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10331 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9630,16 +10368,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9630 { 10368 {
9631 m_host.AddScriptLPS(1); 10369 m_host.AddScriptLPS(1);
9632 10370
9633 lock (m_host.TaskInventory) 10371 m_host.TaskInventory.LockItemsForRead(true);
10372 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9634 { 10373 {
9635 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10374 if (inv.Value.Name == name)
9636 { 10375 {
9637 if (inv.Value.Name == name) 10376 m_host.TaskInventory.LockItemsForRead(false);
9638 { 10377 return inv.Value.Type;
9639 return inv.Value.Type;
9640 }
9641 } 10378 }
9642 } 10379 }
10380 m_host.TaskInventory.LockItemsForRead(false);
9643 10381
9644 return -1; 10382 return -1;
9645 } 10383 }
@@ -9650,15 +10388,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9650 10388
9651 if (quick_pay_buttons.Data.Length < 4) 10389 if (quick_pay_buttons.Data.Length < 4)
9652 { 10390 {
9653 LSLError("List must have at least 4 elements"); 10391 int x;
9654 return; 10392 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10393 {
10394 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10395 }
9655 } 10396 }
9656 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10397 int[] nPrice = new int[5];
9657 10398 nPrice[0] = price;
9658 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10399 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9659 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10400 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9660 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10401 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9661 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10402 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10403 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9662 m_host.ParentGroup.HasGroupChanged = true; 10404 m_host.ParentGroup.HasGroupChanged = true;
9663 } 10405 }
9664 10406
@@ -9670,17 +10412,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9670 if (invItemID == UUID.Zero) 10412 if (invItemID == UUID.Zero)
9671 return new LSL_Vector(); 10413 return new LSL_Vector();
9672 10414
9673 lock (m_host.TaskInventory) 10415 m_host.TaskInventory.LockItemsForRead(true);
10416 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9674 { 10417 {
9675 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10418 m_host.TaskInventory.LockItemsForRead(false);
9676 return new LSL_Vector(); 10419 return new LSL_Vector();
10420 }
9677 10421
9678 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10422 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9679 { 10423 {
9680 ShoutError("No permissions to track the camera"); 10424 ShoutError("No permissions to track the camera");
9681 return new LSL_Vector(); 10425 m_host.TaskInventory.LockItemsForRead(false);
9682 } 10426 return new LSL_Vector();
9683 } 10427 }
10428 m_host.TaskInventory.LockItemsForRead(false);
9684 10429
9685 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10430 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9686 if (presence != null) 10431 if (presence != null)
@@ -9698,17 +10443,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9698 if (invItemID == UUID.Zero) 10443 if (invItemID == UUID.Zero)
9699 return new LSL_Rotation(); 10444 return new LSL_Rotation();
9700 10445
9701 lock (m_host.TaskInventory) 10446 m_host.TaskInventory.LockItemsForRead(true);
10447 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9702 { 10448 {
9703 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10449 m_host.TaskInventory.LockItemsForRead(false);
9704 return new LSL_Rotation(); 10450 return new LSL_Rotation();
9705
9706 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9707 {
9708 ShoutError("No permissions to track the camera");
9709 return new LSL_Rotation();
9710 }
9711 } 10451 }
10452 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10453 {
10454 ShoutError("No permissions to track the camera");
10455 m_host.TaskInventory.LockItemsForRead(false);
10456 return new LSL_Rotation();
10457 }
10458 m_host.TaskInventory.LockItemsForRead(false);
9712 10459
9713 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10460 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9714 if (presence != null) 10461 if (presence != null)
@@ -9770,8 +10517,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9770 { 10517 {
9771 m_host.AddScriptLPS(1); 10518 m_host.AddScriptLPS(1);
9772 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10519 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9773 if (detectedParams == null) return; // only works on the first detected avatar 10520 if (detectedParams == null)
9774 10521 {
10522 if (m_host.ParentGroup.IsAttachment == true)
10523 {
10524 detectedParams = new DetectParams();
10525 detectedParams.Key = m_host.OwnerID;
10526 }
10527 else
10528 {
10529 return;
10530 }
10531 }
10532
9775 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10533 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9776 if (avatar != null) 10534 if (avatar != null)
9777 { 10535 {
@@ -9779,6 +10537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9779 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10537 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9780 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10538 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9781 } 10539 }
10540
9782 ScriptSleep(1000); 10541 ScriptSleep(1000);
9783 } 10542 }
9784 10543
@@ -9890,14 +10649,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9890 if (objectID == UUID.Zero) return; 10649 if (objectID == UUID.Zero) return;
9891 10650
9892 UUID agentID; 10651 UUID agentID;
9893 lock (m_host.TaskInventory) 10652 m_host.TaskInventory.LockItemsForRead(true);
9894 { 10653 // we need the permission first, to know which avatar we want to set the camera for
9895 // we need the permission first, to know which avatar we want to set the camera for 10654 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9896 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9897 10655
9898 if (agentID == UUID.Zero) return; 10656 if (agentID == UUID.Zero)
9899 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10657 {
10658 m_host.TaskInventory.LockItemsForRead(false);
10659 return;
9900 } 10660 }
10661 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10662 {
10663 m_host.TaskInventory.LockItemsForRead(false);
10664 return;
10665 }
10666 m_host.TaskInventory.LockItemsForRead(false);
9901 10667
9902 ScenePresence presence = World.GetScenePresence(agentID); 10668 ScenePresence presence = World.GetScenePresence(agentID);
9903 10669
@@ -9906,12 +10672,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9906 10672
9907 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10673 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9908 object[] data = rules.Data; 10674 object[] data = rules.Data;
9909 for (int i = 0; i < data.Length; ++i) { 10675 for (int i = 0; i < data.Length; ++i)
10676 {
9910 int type = Convert.ToInt32(data[i++].ToString()); 10677 int type = Convert.ToInt32(data[i++].ToString());
9911 if (i >= data.Length) break; // odd number of entries => ignore the last 10678 if (i >= data.Length) break; // odd number of entries => ignore the last
9912 10679
9913 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10680 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9914 switch (type) { 10681 switch (type)
10682 {
9915 case ScriptBaseClass.CAMERA_FOCUS: 10683 case ScriptBaseClass.CAMERA_FOCUS:
9916 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10684 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9917 case ScriptBaseClass.CAMERA_POSITION: 10685 case ScriptBaseClass.CAMERA_POSITION:
@@ -9947,12 +10715,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9947 10715
9948 // we need the permission first, to know which avatar we want to clear the camera for 10716 // we need the permission first, to know which avatar we want to clear the camera for
9949 UUID agentID; 10717 UUID agentID;
9950 lock (m_host.TaskInventory) 10718 m_host.TaskInventory.LockItemsForRead(true);
10719 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10720 if (agentID == UUID.Zero)
9951 { 10721 {
9952 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10722 m_host.TaskInventory.LockItemsForRead(false);
9953 if (agentID == UUID.Zero) return; 10723 return;
9954 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10724 }
10725 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10726 {
10727 m_host.TaskInventory.LockItemsForRead(false);
10728 return;
9955 } 10729 }
10730 m_host.TaskInventory.LockItemsForRead(false);
9956 10731
9957 ScenePresence presence = World.GetScenePresence(agentID); 10732 ScenePresence presence = World.GetScenePresence(agentID);
9958 10733
@@ -10019,19 +10794,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10019 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10794 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10020 { 10795 {
10021 m_host.AddScriptLPS(1); 10796 m_host.AddScriptLPS(1);
10022 string ret = String.Empty; 10797
10023 string src1 = llBase64ToString(str1); 10798 if (str1 == String.Empty)
10024 string src2 = llBase64ToString(str2); 10799 return String.Empty;
10025 int c = 0; 10800 if (str2 == String.Empty)
10026 for (int i = 0; i < src1.Length; i++) 10801 return str1;
10802
10803 int len = str2.Length;
10804 if ((len % 4) != 0) // LL is EVIL!!!!
10027 { 10805 {
10028 ret += (char) (src1[i] ^ src2[c]); 10806 while (str2.EndsWith("="))
10807 str2 = str2.Substring(0, str2.Length - 1);
10808
10809 len = str2.Length;
10810 int mod = len % 4;
10029 10811
10030 c++; 10812 if (mod == 1)
10031 if (c >= src2.Length) 10813 str2 = str2.Substring(0, str2.Length - 1);
10032 c = 0; 10814 else if (mod == 2)
10815 str2 += "==";
10816 else if (mod == 3)
10817 str2 += "=";
10033 } 10818 }
10034 return llStringToBase64(ret); 10819
10820 byte[] data1;
10821 byte[] data2;
10822 try
10823 {
10824 data1 = Convert.FromBase64String(str1);
10825 data2 = Convert.FromBase64String(str2);
10826 }
10827 catch (Exception)
10828 {
10829 return new LSL_String(String.Empty);
10830 }
10831
10832 byte[] d2 = new Byte[data1.Length];
10833 int pos = 0;
10834
10835 if (data1.Length <= data2.Length)
10836 {
10837 Array.Copy(data2, 0, d2, 0, data1.Length);
10838 }
10839 else
10840 {
10841 while (pos < data1.Length)
10842 {
10843 len = data1.Length - pos;
10844 if (len > data2.Length)
10845 len = data2.Length;
10846
10847 Array.Copy(data2, 0, d2, pos, len);
10848 pos += len;
10849 }
10850 }
10851
10852 for (pos = 0 ; pos < data1.Length ; pos++ )
10853 data1[pos] ^= d2[pos];
10854
10855 return Convert.ToBase64String(data1);
10035 } 10856 }
10036 10857
10037 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10858 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10088,12 +10909,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10088 Regex r = new Regex(authregex); 10909 Regex r = new Regex(authregex);
10089 int[] gnums = r.GetGroupNumbers(); 10910 int[] gnums = r.GetGroupNumbers();
10090 Match m = r.Match(url); 10911 Match m = r.Match(url);
10091 if (m.Success) { 10912 if (m.Success)
10092 for (int i = 1; i < gnums.Length; i++) { 10913 {
10914 for (int i = 1; i < gnums.Length; i++)
10915 {
10093 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10916 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10094 //CaptureCollection cc = g.Captures; 10917 //CaptureCollection cc = g.Captures;
10095 } 10918 }
10096 if (m.Groups.Count == 5) { 10919 if (m.Groups.Count == 5)
10920 {
10097 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10921 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10098 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10922 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10099 } 10923 }
@@ -10379,15 +11203,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10379 11203
10380 internal UUID ScriptByName(string name) 11204 internal UUID ScriptByName(string name)
10381 { 11205 {
10382 lock (m_host.TaskInventory) 11206 m_host.TaskInventory.LockItemsForRead(true);
11207
11208 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10383 { 11209 {
10384 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11210 if (item.Type == 10 && item.Name == name)
10385 { 11211 {
10386 if (item.Type == 10 && item.Name == name) 11212 m_host.TaskInventory.LockItemsForRead(false);
10387 return item.ItemID; 11213 return item.ItemID;
10388 } 11214 }
10389 } 11215 }
10390 11216
11217 m_host.TaskInventory.LockItemsForRead(false);
11218
10391 return UUID.Zero; 11219 return UUID.Zero;
10392 } 11220 }
10393 11221
@@ -10428,6 +11256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10428 { 11256 {
10429 m_host.AddScriptLPS(1); 11257 m_host.AddScriptLPS(1);
10430 11258
11259 //Clone is thread safe
10431 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11260 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10432 11261
10433 UUID assetID = UUID.Zero; 11262 UUID assetID = UUID.Zero;
@@ -10490,6 +11319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10490 { 11319 {
10491 m_host.AddScriptLPS(1); 11320 m_host.AddScriptLPS(1);
10492 11321
11322 //Clone is thread safe
10493 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11323 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10494 11324
10495 UUID assetID = UUID.Zero; 11325 UUID assetID = UUID.Zero;
@@ -10570,15 +11400,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10570 return GetLinkPrimitiveParams(obj, rules); 11400 return GetLinkPrimitiveParams(obj, rules);
10571 } 11401 }
10572 11402
10573 public void print(string str) 11403 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10574 { 11404 {
10575 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11405 List<SceneObjectPart> parts = GetLinkParts(link);
10576 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11406 if (parts.Count < 1)
10577 if (ossl != null) 11407 return 0;
10578 { 11408
10579 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11409 return GetNumberOfSides(parts[0]);
10580 m_log.Info("LSL print():" + str);
10581 }
10582 } 11410 }
10583 11411
10584 private string Name2Username(string name) 11412 private string Name2Username(string name)
@@ -10624,155 +11452,397 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10624 return rq.ToString(); 11452 return rq.ToString();
10625 } 11453 }
10626 11454
11455 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11456 {
11457 m_SayShoutCount = 0;
11458 }
11459
11460 private struct Tri
11461 {
11462 public Vector3 p1;
11463 public Vector3 p2;
11464 public Vector3 p3;
11465 }
11466
11467 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11468 {
11469 float height = avatar.Appearance.AvatarHeight;
11470 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11471 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11472
11473 if (point.X > b1.X && point.X < b2.X &&
11474 point.Y > b1.Y && point.Y < b2.Y &&
11475 point.Z > b1.Z && point.Z < b2.Z)
11476 return true;
11477 return false;
11478 }
11479
11480 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11481 {
11482 List<ContactResult> contacts = new List<ContactResult>();
11483
11484 Vector3 ab = rayEnd - rayStart;
11485
11486 World.ForEachScenePresence(delegate(ScenePresence sp)
11487 {
11488 Vector3 ac = sp.AbsolutePosition - rayStart;
11489 Vector3 bc = sp.AbsolutePosition - rayEnd;
11490
11491 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11492
11493 if (d > 1.5)
11494 return;
11495
11496 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11497
11498 if (d2 > 0)
11499 return;
11500
11501 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11502 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11503
11504 if (!InBoundingBox(sp, p))
11505 return;
11506
11507 ContactResult result = new ContactResult ();
11508 result.ConsumerID = sp.LocalId;
11509 result.Depth = Vector3.Distance(rayStart, p);
11510 result.Normal = Vector3.Zero;
11511 result.Pos = p;
11512
11513 contacts.Add(result);
11514 });
11515
11516 return contacts.ToArray();
11517 }
11518
11519 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11520 {
11521 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11522 List<ContactResult> contacts = new List<ContactResult>();
11523
11524 Vector3 ab = rayEnd - rayStart;
11525
11526 World.ForEachSOG(delegate(SceneObjectGroup group)
11527 {
11528 if (m_host.ParentGroup == group)
11529 return;
11530
11531 if (group.IsAttachment)
11532 return;
11533
11534 if (group.RootPart.PhysActor == null)
11535 {
11536 if (!includePhantom)
11537 return;
11538 }
11539 else
11540 {
11541 if (group.RootPart.PhysActor.IsPhysical)
11542 {
11543 if (!includePhysical)
11544 return;
11545 }
11546 else
11547 {
11548 if (!includeNonPhysical)
11549 return;
11550 }
11551 }
11552
11553 // Find the radius ouside of which we don't even need to hit test
11554 float minX;
11555 float maxX;
11556 float minY;
11557 float maxY;
11558 float minZ;
11559 float maxZ;
11560
11561 float radius = 0.0f;
11562
11563 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11564
11565 if (Math.Abs(minX) > radius)
11566 radius = Math.Abs(minX);
11567 if (Math.Abs(minY) > radius)
11568 radius = Math.Abs(minY);
11569 if (Math.Abs(minZ) > radius)
11570 radius = Math.Abs(minZ);
11571 if (Math.Abs(maxX) > radius)
11572 radius = Math.Abs(maxX);
11573 if (Math.Abs(maxY) > radius)
11574 radius = Math.Abs(maxY);
11575 if (Math.Abs(maxZ) > radius)
11576 radius = Math.Abs(maxZ);
11577
11578 Vector3 ac = group.AbsolutePosition - rayStart;
11579 Vector3 bc = group.AbsolutePosition - rayEnd;
11580
11581 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11582
11583 // Too far off ray, don't bother
11584 if (d > radius)
11585 return;
11586
11587 // Behind ray, drop
11588 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11589 if (d2 > 0)
11590 return;
11591
11592 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11593 // Miss.
11594 if (!intersection.HitTF)
11595 return;
11596
11597 ContactResult result = new ContactResult ();
11598 result.ConsumerID = group.LocalId;
11599 result.Depth = intersection.distance;
11600 result.Normal = intersection.normal;
11601 result.Pos = intersection.ipoint;
11602
11603 contacts.Add(result);
11604 });
11605
11606 return contacts.ToArray();
11607 }
11608
11609 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11610 {
11611 double[,] heightfield = World.Heightmap.GetDoubles();
11612 List<ContactResult> contacts = new List<ContactResult>();
11613
11614 double min = 2048.0;
11615 double max = 0.0;
11616
11617 // Find the min and max of the heightfield
11618 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11619 {
11620 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11621 {
11622 if (heightfield[x, y] > max)
11623 max = heightfield[x, y];
11624 if (heightfield[x, y] < min)
11625 min = heightfield[x, y];
11626 }
11627 }
11628
11629
11630 // A ray extends past rayEnd, but doesn't go back before
11631 // rayStart. If the start is above the highest point of the ground
11632 // and the ray goes up, we can't hit the ground. Ever.
11633 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11634 return null;
11635
11636 // Same for going down
11637 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11638 return null;
11639
11640 List<Tri> trilist = new List<Tri>();
11641
11642 // Create our triangle list
11643 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11644 {
11645 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11646 {
11647 Tri t1 = new Tri();
11648 Tri t2 = new Tri();
11649
11650 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11651 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11652 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11653 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11654
11655 t1.p1 = p1;
11656 t1.p2 = p2;
11657 t1.p3 = p3;
11658
11659 t2.p1 = p3;
11660 t2.p2 = p4;
11661 t2.p3 = p1;
11662
11663 trilist.Add(t1);
11664 trilist.Add(t2);
11665 }
11666 }
11667
11668 // Ray direction
11669 Vector3 rayDirection = rayEnd - rayStart;
11670
11671 foreach (Tri t in trilist)
11672 {
11673 // Compute triangle plane normal and edges
11674 Vector3 u = t.p2 - t.p1;
11675 Vector3 v = t.p3 - t.p1;
11676 Vector3 n = Vector3.Cross(u, v);
11677
11678 if (n == Vector3.Zero)
11679 continue;
11680
11681 Vector3 w0 = rayStart - t.p1;
11682 double a = -Vector3.Dot(n, w0);
11683 double b = Vector3.Dot(n, rayDirection);
11684
11685 // Not intersecting the plane, or in plane (same thing)
11686 // Ignoring this MAY cause the ground to not be detected
11687 // sometimes
11688 if (Math.Abs(b) < 0.000001)
11689 continue;
11690
11691 double r = a / b;
11692
11693 // ray points away from plane
11694 if (r < 0.0)
11695 continue;
11696
11697 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11698
11699 float uu = Vector3.Dot(u, u);
11700 float uv = Vector3.Dot(u, v);
11701 float vv = Vector3.Dot(v, v);
11702 Vector3 w = ip - t.p1;
11703 float wu = Vector3.Dot(w, u);
11704 float wv = Vector3.Dot(w, v);
11705 float d = uv * uv - uu * vv;
11706
11707 float cs = (uv * wv - vv * wu) / d;
11708 if (cs < 0 || cs > 1.0)
11709 continue;
11710 float ct = (uv * wu - uu * wv) / d;
11711 if (ct < 0 || (cs + ct) > 1.0)
11712 continue;
11713
11714 // Add contact point
11715 ContactResult result = new ContactResult ();
11716 result.ConsumerID = 0;
11717 result.Depth = Vector3.Distance(rayStart, ip);
11718 result.Normal = n;
11719 result.Pos = ip;
11720
11721 contacts.Add(result);
11722 }
11723
11724 if (contacts.Count == 0)
11725 return null;
11726
11727 contacts.Sort(delegate(ContactResult a, ContactResult b)
11728 {
11729 return (int)(a.Depth - b.Depth);
11730 });
11731
11732 return contacts[0];
11733 }
11734
10627 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11735 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10628 { 11736 {
11737 LSL_List list = new LSL_List();
11738
10629 m_host.AddScriptLPS(1); 11739 m_host.AddScriptLPS(1);
10630 11740
10631 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11741 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10632 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11742 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10633 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11743 Vector3 dir = rayEnd - rayStart;
10634 11744
10635 int count = 0; 11745 float dist = Vector3.Mag(dir);
10636// int detectPhantom = 0; 11746
11747 int count = 1;
11748 bool detectPhantom = false;
10637 int dataFlags = 0; 11749 int dataFlags = 0;
10638 int rejectTypes = 0; 11750 int rejectTypes = 0;
10639 11751
10640 for (int i = 0; i < options.Length; i += 2) 11752 for (int i = 0; i < options.Length; i += 2)
10641 { 11753 {
10642 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11754 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10643 {
10644 count = options.GetLSLIntegerItem(i + 1); 11755 count = options.GetLSLIntegerItem(i + 1);
10645 } 11756 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10646// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11757 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10647// {
10648// detectPhantom = options.GetLSLIntegerItem(i + 1);
10649// }
10650 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11758 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10651 {
10652 dataFlags = options.GetLSLIntegerItem(i + 1); 11759 dataFlags = options.GetLSLIntegerItem(i + 1);
10653 }
10654 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11760 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10655 {
10656 rejectTypes = options.GetLSLIntegerItem(i + 1); 11761 rejectTypes = options.GetLSLIntegerItem(i + 1);
10657 }
10658 } 11762 }
10659 11763
10660 LSL_List list = new LSL_List(); 11764 if (count > 16)
10661 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11765 count = 16;
10662
10663 double distance = Util.GetDistanceTo(startvector, endvector);
10664 11766
10665 if (distance == 0) 11767 List<ContactResult> results = new List<ContactResult>();
10666 distance = 0.001;
10667
10668 Vector3 posToCheck = startvector;
10669 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10670 11768
10671 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11769 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10672 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11770 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10673 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11771 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10674 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11772 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10675 11773
10676 for (float i = 0; i <= distance; i += 0.1f) 11774 if (checkTerrain)
10677 { 11775 {
10678 posToCheck = startvector + (dir * (i / (float)distance)); 11776 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11777 if (groundContact != null)
11778 results.Add((ContactResult)groundContact);
11779 }
10679 11780
10680 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11781 if (checkAgents)
10681 { 11782 {
10682 ContactResult result = new ContactResult(); 11783 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10683 result.ConsumerID = 0; 11784 foreach (ContactResult r in agentHits)
10684 result.Depth = 0; 11785 results.Add(r);
10685 result.Normal = Vector3.Zero; 11786 }
10686 result.Pos = posToCheck;
10687 results.Add(result);
10688 checkTerrain = false;
10689 }
10690 11787
10691 if (checkAgents) 11788 if (checkPhysical || checkNonPhysical)
10692 { 11789 {
10693 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11790 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10694 { 11791 foreach (ContactResult r in objectHits)
10695 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11792 results.Add(r);
10696 {
10697 ContactResult result = new ContactResult ();
10698 result.ConsumerID = sp.LocalId;
10699 result.Depth = 0;
10700 result.Normal = Vector3.Zero;
10701 result.Pos = posToCheck;
10702 results.Add(result);
10703 }
10704 });
10705 }
10706 } 11793 }
10707 11794
10708 int refcount = 0; 11795 results.Sort(delegate(ContactResult a, ContactResult b)
11796 {
11797 return (int)(a.Depth - b.Depth);
11798 });
11799
11800 int values = 0;
10709 foreach (ContactResult result in results) 11801 foreach (ContactResult result in results)
10710 { 11802 {
10711 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11803 if (result.Depth > dist)
10712 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10713 continue; 11804 continue;
10714 11805
10715 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11806 UUID itemID = UUID.Zero;
11807 int linkNum = 0;
10716 11808
10717 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11809 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
10718 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11810 // It's a prim!
10719 11811 if (part != null)
10720 if (entity == null)
10721 { 11812 {
10722 list.Add(UUID.Zero); 11813 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10723 11814 itemID = part.ParentGroup.UUID;
10724 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11815 else
10725 list.Add(0); 11816 itemID = part.UUID;
10726
10727 list.Add(result.Pos);
10728
10729 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10730 list.Add(result.Normal);
10731 11817
10732 continue; //Can't find it, so add UUID.Zero 11818 linkNum = part.LinkNum;
10733 } 11819 }
10734 11820 else
10735 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10736 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10737 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10738
10739 if (entity is SceneObjectPart)
10740 { 11821 {
10741 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 11822 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10742 11823 /// It it a boy? a girl?
10743 if (pa != null && pa.IsPhysical) 11824 if (sp != null)
10744 { 11825 itemID = sp.UUID;
10745 if (!checkPhysical)
10746 continue;
10747 }
10748 else
10749 {
10750 if (!checkNonPhysical)
10751 continue;
10752 }
10753 } 11826 }
10754 11827
10755 refcount++; 11828 list.Add(new LSL_String(itemID.ToString()));
10756 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11829 list.Add(new LSL_String(result.Pos.ToString()));
10757 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10758 else
10759 list.Add(entity.UUID);
10760 11830
10761 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11831 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10762 { 11832 list.Add(new LSL_Integer(linkNum));
10763 if (entity is SceneObjectPart)
10764 list.Add(((SceneObjectPart)entity).LinkNum);
10765 else
10766 list.Add(0);
10767 }
10768 11833
10769 list.Add(result.Pos);
10770 11834
10771 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11835 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10772 list.Add(result.Normal); 11836 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11837
11838 values++;
11839 count--;
11840
11841 if (count == 0)
11842 break;
10773 } 11843 }
10774 11844
10775 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11845 list.Add(new LSL_Integer(values));
10776 11846
10777 return list; 11847 return list;
10778 } 11848 }
@@ -10812,7 +11882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10812 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11882 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10813 if (!isAccount) return 0; 11883 if (!isAccount) return 0;
10814 if (estate.HasAccess(id)) return 1; 11884 if (estate.HasAccess(id)) return 1;
10815 if (estate.IsBanned(id)) 11885 if (estate.IsBanned(id, World.GetUserFlags(id)))
10816 estate.RemoveBan(id); 11886 estate.RemoveBan(id);
10817 estate.AddEstateUser(id); 11887 estate.AddEstateUser(id);
10818 break; 11888 break;
@@ -10831,14 +11901,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10831 break; 11901 break;
10832 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11902 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10833 if (!isAccount) return 0; 11903 if (!isAccount) return 0;
10834 if (estate.IsBanned(id)) return 1; 11904 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10835 EstateBan ban = new EstateBan(); 11905 EstateBan ban = new EstateBan();
10836 ban.EstateID = estate.EstateID; 11906 ban.EstateID = estate.EstateID;
10837 ban.BannedUserID = id; 11907 ban.BannedUserID = id;
10838 estate.AddBan(ban); 11908 estate.AddBan(ban);
10839 break; 11909 break;
10840 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11910 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10841 if (!isAccount || !estate.IsBanned(id)) return 0; 11911 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10842 estate.RemoveBan(id); 11912 estate.RemoveBan(id);
10843 break; 11913 break;
10844 default: return 0; 11914 default: return 0;
@@ -10864,22 +11934,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10864 NotImplemented("llGetSPMaxMemory"); 11934 NotImplemented("llGetSPMaxMemory");
10865 } 11935 }
10866 11936
10867 public void llGetUsedMemory() 11937 public virtual LSL_Integer llGetUsedMemory()
10868 { 11938 {
10869 m_host.AddScriptLPS(1); 11939 m_host.AddScriptLPS(1);
10870 NotImplemented("llGetUsedMemory"); 11940 NotImplemented("llGetUsedMemory");
11941 return 0;
10871 } 11942 }
10872 11943
10873 public void llScriptProfiler(LSL_Integer flags) 11944 public void llScriptProfiler(LSL_Integer flags)
10874 { 11945 {
10875 m_host.AddScriptLPS(1); 11946 m_host.AddScriptLPS(1);
10876 NotImplemented("llScriptProfiler"); 11947 //NotImplemented("llScriptProfiler");
10877 } 11948 }
10878 11949
10879 public void llSetSoundQueueing(int queue) 11950 public void llSetSoundQueueing(int queue)
10880 { 11951 {
10881 m_host.AddScriptLPS(1); 11952 m_host.AddScriptLPS(1);
10882 NotImplemented("llSetSoundQueueing");
10883 } 11953 }
10884 11954
10885 public void llCollisionSprite(string impact_sprite) 11955 public void llCollisionSprite(string impact_sprite)
@@ -10891,10 +11961,274 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10891 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11961 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10892 { 11962 {
10893 m_host.AddScriptLPS(1); 11963 m_host.AddScriptLPS(1);
10894 NotImplemented("llGodLikeRezObject"); 11964
11965 if (!World.Permissions.IsGod(m_host.OwnerID))
11966 NotImplemented("llGodLikeRezObject");
11967
11968 AssetBase rezAsset = World.AssetService.Get(inventory);
11969 if (rezAsset == null)
11970 {
11971 llSay(0, "Asset not found");
11972 return;
11973 }
11974
11975 SceneObjectGroup group = null;
11976
11977 try
11978 {
11979 string xmlData = Utils.BytesToString(rezAsset.Data);
11980 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11981 }
11982 catch
11983 {
11984 llSay(0, "Asset not found");
11985 return;
11986 }
11987
11988 if (group == null)
11989 {
11990 llSay(0, "Asset not found");
11991 return;
11992 }
11993
11994 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11995 group.RootPart.AttachOffset = group.AbsolutePosition;
11996
11997 group.ResetIDs();
11998
11999 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12000 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12001 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12002 group.ScheduleGroupForFullUpdate();
12003
12004 // objects rezzed with this method are die_at_edge by default.
12005 group.RootPart.SetDieAtEdge(true);
12006
12007 group.ResumeScripts();
12008
12009 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12010 "object_rez", new Object[] {
12011 new LSL_String(
12012 group.RootPart.UUID.ToString()) },
12013 new DetectParams[0]));
12014 }
12015
12016 public LSL_String llTransferLindenDollars(string destination, int amount)
12017 {
12018 UUID txn = UUID.Random();
12019
12020 Util.FireAndForget(delegate(object x)
12021 {
12022 int replycode = 0;
12023 string replydata = destination + "," + amount.ToString();
12024
12025 try
12026 {
12027 UUID invItemID=InventorySelf();
12028 if (invItemID == UUID.Zero)
12029 {
12030 replydata = "SERVICE_ERROR";
12031 return;
12032 }
12033
12034 m_host.AddScriptLPS(1);
12035
12036 m_host.TaskInventory.LockItemsForRead(true);
12037 TaskInventoryItem item = m_host.TaskInventory[invItemID];
12038 m_host.TaskInventory.LockItemsForRead(false);
12039
12040 if (item.PermsGranter == UUID.Zero)
12041 {
12042 replydata = "MISSING_PERMISSION_DEBIT";
12043 return;
12044 }
12045
12046 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12047 {
12048 replydata = "MISSING_PERMISSION_DEBIT";
12049 return;
12050 }
12051
12052 UUID toID = new UUID();
12053
12054 if (!UUID.TryParse(destination, out toID))
12055 {
12056 replydata = "INVALID_AGENT";
12057 return;
12058 }
12059
12060 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12061
12062 if (money == null)
12063 {
12064 replydata = "TRANSFERS_DISABLED";
12065 return;
12066 }
12067
12068 bool result = money.ObjectGiveMoney(
12069 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12070
12071 if (result)
12072 {
12073 replycode = 1;
12074 return;
12075 }
12076
12077 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12078 }
12079 finally
12080 {
12081 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12082 "transaction_result", new Object[] {
12083 new LSL_String(txn.ToString()),
12084 new LSL_Integer(replycode),
12085 new LSL_String(replydata) },
12086 new DetectParams[0]));
12087 }
12088 });
12089
12090 return txn.ToString();
10895 } 12091 }
10896 12092
10897 #endregion 12093 #endregion
12094
12095 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12096 {
12097 SceneObjectGroup group = m_host.ParentGroup;
12098
12099 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12100 return;
12101 if (group.IsAttachment)
12102 return;
12103
12104 if (frames.Data.Length > 0) // We are getting a new motion
12105 {
12106 if (group.RootPart.KeyframeMotion != null)
12107 group.RootPart.KeyframeMotion.Stop();
12108 group.RootPart.KeyframeMotion = null;
12109
12110 int idx = 0;
12111
12112 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12113 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12114
12115 while (idx < options.Data.Length)
12116 {
12117 int option = (int)options.GetLSLIntegerItem(idx++);
12118 int remain = options.Data.Length - idx;
12119
12120 switch (option)
12121 {
12122 case ScriptBaseClass.KFM_MODE:
12123 if (remain < 1)
12124 break;
12125 int modeval = (int)options.GetLSLIntegerItem(idx++);
12126 switch(modeval)
12127 {
12128 case ScriptBaseClass.KFM_FORWARD:
12129 mode = KeyframeMotion.PlayMode.Forward;
12130 break;
12131 case ScriptBaseClass.KFM_REVERSE:
12132 mode = KeyframeMotion.PlayMode.Reverse;
12133 break;
12134 case ScriptBaseClass.KFM_LOOP:
12135 mode = KeyframeMotion.PlayMode.Loop;
12136 break;
12137 case ScriptBaseClass.KFM_PING_PONG:
12138 mode = KeyframeMotion.PlayMode.PingPong;
12139 break;
12140 }
12141 break;
12142 case ScriptBaseClass.KFM_DATA:
12143 if (remain < 1)
12144 break;
12145 int dataval = (int)options.GetLSLIntegerItem(idx++);
12146 data = (KeyframeMotion.DataFormat)dataval;
12147 break;
12148 }
12149 }
12150
12151 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12152
12153 idx = 0;
12154
12155 int elemLength = 2;
12156 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12157 elemLength = 3;
12158
12159 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12160 while (idx < frames.Data.Length)
12161 {
12162 int remain = frames.Data.Length - idx;
12163
12164 if (remain < elemLength)
12165 break;
12166
12167 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12168 frame.Position = null;
12169 frame.Rotation = null;
12170
12171 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12172 {
12173 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12174 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12175 }
12176 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12177 {
12178 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12179 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12180 }
12181
12182 float tempf = (float)frames.GetLSLFloatItem(idx++);
12183 frame.TimeMS = (int)(tempf * 1000.0f);
12184
12185 keyframes.Add(frame);
12186 }
12187
12188 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12189 group.RootPart.KeyframeMotion.Start();
12190 }
12191 else
12192 {
12193 if (group.RootPart.KeyframeMotion == null)
12194 return;
12195
12196 if (options.Data.Length == 0)
12197 {
12198 group.RootPart.KeyframeMotion.Stop();
12199 return;
12200 }
12201
12202 int code = (int)options.GetLSLIntegerItem(0);
12203
12204 int idx = 0;
12205
12206 while (idx < options.Data.Length)
12207 {
12208 int option = (int)options.GetLSLIntegerItem(idx++);
12209 int remain = options.Data.Length - idx;
12210
12211 switch (option)
12212 {
12213 case ScriptBaseClass.KFM_COMMAND:
12214 int cmd = (int)options.GetLSLIntegerItem(idx++);
12215 switch (cmd)
12216 {
12217 case ScriptBaseClass.KFM_CMD_PLAY:
12218 group.RootPart.KeyframeMotion.Start();
12219 break;
12220 case ScriptBaseClass.KFM_CMD_STOP:
12221 group.RootPart.KeyframeMotion.Stop();
12222 break;
12223 case ScriptBaseClass.KFM_CMD_PAUSE:
12224 group.RootPart.KeyframeMotion.Pause();
12225 break;
12226 }
12227 break;
12228 }
12229 }
12230 }
12231 }
10898 } 12232 }
10899 12233
10900 public class NotecardCache 12234 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}