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.cs3155
-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, 2996 insertions, 1168 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 c38a52e..76106a0 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();
@@ -2032,17 +2281,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2032 else 2281 else
2033 { 2282 {
2034 if (part.ParentGroup.IsAttachment) 2283 if (part.ParentGroup.IsAttachment)
2035 {
2036 pos = part.AttachedPos; 2284 pos = part.AttachedPos;
2037 }
2038 else 2285 else
2039 {
2040 pos = part.AbsolutePosition; 2286 pos = part.AbsolutePosition;
2041 }
2042 } 2287 }
2043 2288
2044// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2045
2046 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2289 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2047 } 2290 }
2048 2291
@@ -2051,9 +2294,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2051 m_host.AddScriptLPS(1); 2294 m_host.AddScriptLPS(1);
2052 2295
2053 // try to let this work as in SL... 2296 // try to let this work as in SL...
2054 if (m_host.ParentID == 0) 2297 if (m_host.LinkNum < 2)
2055 { 2298 {
2056 // special case: If we are root, rotate complete SOG to new rotation 2299 // Special case: If we are root, rotate complete SOG to new
2300 // rotation.
2301 // We are root if the link number is 0 (single prim) or 1
2302 // (root prim). ParentID may be nonzero in attachments and
2303 // using it would cause attachments and HUDs to rotate
2304 // to the wrong positions.
2057 SetRot(m_host, Rot2Quaternion(rot)); 2305 SetRot(m_host, Rot2Quaternion(rot));
2058 } 2306 }
2059 else 2307 else
@@ -2078,6 +2326,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2078 2326
2079 protected void SetRot(SceneObjectPart part, Quaternion rot) 2327 protected void SetRot(SceneObjectPart part, Quaternion rot)
2080 { 2328 {
2329 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2330 return;
2331
2081 part.UpdateRotation(rot); 2332 part.UpdateRotation(rot);
2082 // Update rotation does not move the object in the physics scene if it's a linkset. 2333 // Update rotation does not move the object in the physics scene if it's a linkset.
2083 2334
@@ -2232,13 +2483,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2232 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2483 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2233 { 2484 {
2234 m_host.AddScriptLPS(1); 2485 m_host.AddScriptLPS(1);
2235 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2486 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2236 } 2487 }
2237 2488
2238 public void llSetTorque(LSL_Vector torque, int local) 2489 public void llSetTorque(LSL_Vector torque, int local)
2239 { 2490 {
2240 m_host.AddScriptLPS(1); 2491 m_host.AddScriptLPS(1);
2241 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2492 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2242 } 2493 }
2243 2494
2244 public LSL_Vector llGetTorque() 2495 public LSL_Vector llGetTorque()
@@ -2703,12 +2954,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2703 2954
2704 m_host.AddScriptLPS(1); 2955 m_host.AddScriptLPS(1);
2705 2956
2957 m_host.TaskInventory.LockItemsForRead(true);
2706 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2958 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2707 2959 m_host.TaskInventory.LockItemsForRead(false);
2708 lock (m_host.TaskInventory)
2709 {
2710 item = m_host.TaskInventory[invItemID];
2711 }
2712 2960
2713 if (item.PermsGranter == UUID.Zero) 2961 if (item.PermsGranter == UUID.Zero)
2714 return 0; 2962 return 0;
@@ -2851,35 +3099,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2851 public void llLookAt(LSL_Vector target, double strength, double damping) 3099 public void llLookAt(LSL_Vector target, double strength, double damping)
2852 { 3100 {
2853 m_host.AddScriptLPS(1); 3101 m_host.AddScriptLPS(1);
2854 // Determine where we are looking from
2855 LSL_Vector from = llGetPos();
2856 3102
2857 // Work out the normalised vector from the source to the target 3103 // Get the normalized vector to the target
2858 LSL_Vector delta = llVecNorm(target - from); 3104 LSL_Vector d1 = llVecNorm(target - llGetPos());
2859 LSL_Vector angle = new LSL_Vector(0,0,0);
2860 3105
2861 // Calculate the yaw 3106 // Get the bearing (yaw)
2862 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3107 LSL_Vector a1 = new LSL_Vector(0,0,0);
2863 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3108 a1.z = llAtan2(d1.y, d1.x);
2864 3109
2865 // Calculate pitch 3110 // Get the elevation (pitch)
2866 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3111 LSL_Vector a2 = new LSL_Vector(0,0,0);
3112 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2867 3113
2868 // we need to convert from a vector describing 3114 LSL_Rotation r1 = llEuler2Rot(a1);
2869 // the angles of rotation in radians into rotation value 3115 LSL_Rotation r2 = llEuler2Rot(a2);
2870 LSL_Rotation rot = llEuler2Rot(angle); 3116 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2871
2872 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2873 // set the rotation of the object, copy that behavior
2874 PhysicsActor pa = m_host.PhysActor;
2875 3117
2876 if (strength == 0 || pa == null || !pa.IsPhysical) 3118 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2877 { 3119 {
2878 llSetRot(rot); 3120 // Do nothing if either value is 0 (this has been checked in SL)
3121 if (strength <= 0.0 || damping <= 0.0)
3122 return;
3123
3124 llSetRot(r3 * r2 * r1);
2879 } 3125 }
2880 else 3126 else
2881 { 3127 {
2882 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3128 if (strength == 0)
3129 {
3130 llSetRot(r3 * r2 * r1);
3131 return;
3132 }
3133
3134 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2883 } 3135 }
2884 } 3136 }
2885 3137
@@ -2953,13 +3205,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 { 3205 {
2954 TaskInventoryItem item; 3206 TaskInventoryItem item;
2955 3207
2956 lock (m_host.TaskInventory) 3208 m_host.TaskInventory.LockItemsForRead(true);
3209 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2957 { 3210 {
2958 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3211 m_host.TaskInventory.LockItemsForRead(false);
2959 return; 3212 return;
2960 else
2961 item = m_host.TaskInventory[InventorySelf()];
2962 } 3213 }
3214 else
3215 {
3216 item = m_host.TaskInventory[InventorySelf()];
3217 }
3218 m_host.TaskInventory.LockItemsForRead(false);
2963 3219
2964 if (item.PermsGranter != UUID.Zero) 3220 if (item.PermsGranter != UUID.Zero)
2965 { 3221 {
@@ -2981,13 +3237,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2981 { 3237 {
2982 TaskInventoryItem item; 3238 TaskInventoryItem item;
2983 3239
3240 m_host.TaskInventory.LockItemsForRead(true);
2984 lock (m_host.TaskInventory) 3241 lock (m_host.TaskInventory)
2985 { 3242 {
3243
2986 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3244 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3245 {
3246 m_host.TaskInventory.LockItemsForRead(false);
2987 return; 3247 return;
3248 }
2988 else 3249 else
3250 {
2989 item = m_host.TaskInventory[InventorySelf()]; 3251 item = m_host.TaskInventory[InventorySelf()];
3252 }
2990 } 3253 }
3254 m_host.TaskInventory.LockItemsForRead(false);
2991 3255
2992 m_host.AddScriptLPS(1); 3256 m_host.AddScriptLPS(1);
2993 3257
@@ -3019,18 +3283,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 { 3283 {
3020 m_host.AddScriptLPS(1); 3284 m_host.AddScriptLPS(1);
3021 3285
3022// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3023// return;
3024
3025 TaskInventoryItem item; 3286 TaskInventoryItem item;
3026 3287
3027 lock (m_host.TaskInventory) 3288 m_host.TaskInventory.LockItemsForRead(true);
3289
3290 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3028 { 3291 {
3029 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3292 m_host.TaskInventory.LockItemsForRead(false);
3030 return; 3293 return;
3031 else
3032 item = m_host.TaskInventory[InventorySelf()];
3033 } 3294 }
3295 else
3296 {
3297 item = m_host.TaskInventory[InventorySelf()];
3298 }
3299
3300 m_host.TaskInventory.LockItemsForRead(false);
3034 3301
3035 if (item.PermsGranter != m_host.OwnerID) 3302 if (item.PermsGranter != m_host.OwnerID)
3036 return; 3303 return;
@@ -3056,13 +3323,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3056 3323
3057 TaskInventoryItem item; 3324 TaskInventoryItem item;
3058 3325
3059 lock (m_host.TaskInventory) 3326 m_host.TaskInventory.LockItemsForRead(true);
3327
3328 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3060 { 3329 {
3061 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3330 m_host.TaskInventory.LockItemsForRead(false);
3062 return; 3331 return;
3063 else 3332 }
3064 item = m_host.TaskInventory[InventorySelf()]; 3333 else
3334 {
3335 item = m_host.TaskInventory[InventorySelf()];
3065 } 3336 }
3337 m_host.TaskInventory.LockItemsForRead(false);
3338
3066 3339
3067 if (item.PermsGranter != m_host.OwnerID) 3340 if (item.PermsGranter != m_host.OwnerID)
3068 return; 3341 return;
@@ -3109,6 +3382,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3109 3382
3110 public void llInstantMessage(string user, string message) 3383 public void llInstantMessage(string user, string message)
3111 { 3384 {
3385 UUID result;
3386 if (!UUID.TryParse(user, out result))
3387 {
3388 ShoutError("An invalid key was passed to llInstantMessage");
3389 ScriptSleep(2000);
3390 return;
3391 }
3392
3393
3112 m_host.AddScriptLPS(1); 3394 m_host.AddScriptLPS(1);
3113 3395
3114 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3396 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3123,14 +3405,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 UUID friendTransactionID = UUID.Random(); 3405 UUID friendTransactionID = UUID.Random();
3124 3406
3125 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3407 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3126 3408
3127 GridInstantMessage msg = new GridInstantMessage(); 3409 GridInstantMessage msg = new GridInstantMessage();
3128 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3410 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3129 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3411 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3130 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3412 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3131// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3413// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3132// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3414// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3133 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3415// DateTime dt = DateTime.UtcNow;
3416//
3417// // Ticks from UtcNow, but make it look like local. Evil, huh?
3418// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3419//
3420// try
3421// {
3422// // Convert that to the PST timezone
3423// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3424// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3425// }
3426// catch
3427// {
3428// // No logging here, as it could be VERY spammy
3429// }
3430//
3431// // And make it look local again to fool the unix time util
3432// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3433
3434 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3435
3134 //if (client != null) 3436 //if (client != null)
3135 //{ 3437 //{
3136 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3438 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3144,12 +3446,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3144 msg.message = message.Substring(0, 1024); 3446 msg.message = message.Substring(0, 1024);
3145 else 3447 else
3146 msg.message = message; 3448 msg.message = message;
3147 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3449 msg.dialog = (byte)19; // MessageFromObject
3148 msg.fromGroup = false;// fromGroup; 3450 msg.fromGroup = false;// fromGroup;
3149 msg.offline = (byte)0; //offline; 3451 msg.offline = (byte)0; //offline;
3150 msg.ParentEstateID = 0; //ParentEstateID; 3452 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3151 msg.Position = new Vector3(m_host.AbsolutePosition); 3453 msg.Position = new Vector3(m_host.AbsolutePosition);
3152 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3454 msg.RegionID = World.RegionInfo.RegionID.Guid;
3153 msg.binaryBucket 3455 msg.binaryBucket
3154 = Util.StringToBytes256( 3456 = Util.StringToBytes256(
3155 "{0}/{1}/{2}/{3}", 3457 "{0}/{1}/{2}/{3}",
@@ -3177,7 +3479,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3177 } 3479 }
3178 3480
3179 emailModule.SendEmail(m_host.UUID, address, subject, message); 3481 emailModule.SendEmail(m_host.UUID, address, subject, message);
3180 ScriptSleep(20000); 3482 ScriptSleep(15000);
3181 } 3483 }
3182 3484
3183 public void llGetNextEmail(string address, string subject) 3485 public void llGetNextEmail(string address, string subject)
@@ -3319,14 +3621,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3319 3621
3320 TaskInventoryItem item; 3622 TaskInventoryItem item;
3321 3623
3322 lock (m_host.TaskInventory) 3624 m_host.TaskInventory.LockItemsForRead(true);
3625 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3323 { 3626 {
3324 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3627 m_host.TaskInventory.LockItemsForRead(false);
3325 return; 3628 return;
3326 else
3327 item = m_host.TaskInventory[InventorySelf()];
3328 } 3629 }
3329 3630 else
3631 {
3632 item = m_host.TaskInventory[InventorySelf()];
3633 }
3634 m_host.TaskInventory.LockItemsForRead(false);
3330 if (item.PermsGranter == UUID.Zero) 3635 if (item.PermsGranter == UUID.Zero)
3331 return; 3636 return;
3332 3637
@@ -3356,13 +3661,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3356 3661
3357 TaskInventoryItem item; 3662 TaskInventoryItem item;
3358 3663
3359 lock (m_host.TaskInventory) 3664 m_host.TaskInventory.LockItemsForRead(true);
3665 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3360 { 3666 {
3361 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3667 m_host.TaskInventory.LockItemsForRead(false);
3362 return; 3668 return;
3363 else 3669 }
3364 item = m_host.TaskInventory[InventorySelf()]; 3670 else
3671 {
3672 item = m_host.TaskInventory[InventorySelf()];
3365 } 3673 }
3674 m_host.TaskInventory.LockItemsForRead(false);
3675
3366 3676
3367 if (item.PermsGranter == UUID.Zero) 3677 if (item.PermsGranter == UUID.Zero)
3368 return; 3678 return;
@@ -3429,10 +3739,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 3739
3430 TaskInventoryItem item; 3740 TaskInventoryItem item;
3431 3741
3432 lock (m_host.TaskInventory) 3742
3743 m_host.TaskInventory.LockItemsForRead(true);
3744 if (!m_host.TaskInventory.ContainsKey(invItemID))
3745 {
3746 m_host.TaskInventory.LockItemsForRead(false);
3747 return;
3748 }
3749 else
3433 { 3750 {
3434 item = m_host.TaskInventory[invItemID]; 3751 item = m_host.TaskInventory[invItemID];
3435 } 3752 }
3753 m_host.TaskInventory.LockItemsForRead(false);
3436 3754
3437 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3755 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3438 { 3756 {
@@ -3460,15 +3778,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3460 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3778 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3461 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3779 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3462 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3780 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3781 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3463 ScriptBaseClass.PERMISSION_ATTACH; 3782 ScriptBaseClass.PERMISSION_ATTACH;
3464 3783
3465 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3784 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3466 { 3785 {
3467 lock (m_host.TaskInventory) 3786 m_host.TaskInventory.LockItemsForWrite(true);
3468 { 3787 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3469 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3788 m_host.TaskInventory[invItemID].PermsMask = perm;
3470 m_host.TaskInventory[invItemID].PermsMask = perm; 3789 m_host.TaskInventory.LockItemsForWrite(false);
3471 }
3472 3790
3473 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3791 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3474 "run_time_permissions", new Object[] { 3792 "run_time_permissions", new Object[] {
@@ -3478,28 +3796,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 return; 3796 return;
3479 } 3797 }
3480 } 3798 }
3481 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3799 else
3482 { 3800 {
3483 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3801 bool sitting = false;
3484 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3802 if (m_host.SitTargetAvatar == agentID)
3485 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3803 {
3486 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3804 sitting = true;
3487 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3805 }
3806 else
3807 {
3808 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3809 {
3810 if (p.SitTargetAvatar == agentID)
3811 sitting = true;
3812 }
3813 }
3488 3814
3489 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3815 if (sitting)
3490 { 3816 {
3491 lock (m_host.TaskInventory) 3817 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3818 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3819 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3820 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3821 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3822
3823 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3492 { 3824 {
3825 m_host.TaskInventory.LockItemsForWrite(true);
3493 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3826 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3494 m_host.TaskInventory[invItemID].PermsMask = perm; 3827 m_host.TaskInventory[invItemID].PermsMask = perm;
3495 } 3828 m_host.TaskInventory.LockItemsForWrite(false);
3496 3829
3497 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3830 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3498 "run_time_permissions", new Object[] { 3831 "run_time_permissions", new Object[] {
3499 new LSL_Integer(perm) }, 3832 new LSL_Integer(perm) },
3500 new DetectParams[0])); 3833 new DetectParams[0]));
3501 3834
3502 return; 3835 return;
3836 }
3503 } 3837 }
3504 } 3838 }
3505 3839
@@ -3513,11 +3847,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3513 3847
3514 if (!m_waitingForScriptAnswer) 3848 if (!m_waitingForScriptAnswer)
3515 { 3849 {
3516 lock (m_host.TaskInventory) 3850 m_host.TaskInventory.LockItemsForWrite(true);
3517 { 3851 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3518 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3852 m_host.TaskInventory[invItemID].PermsMask = 0;
3519 m_host.TaskInventory[invItemID].PermsMask = 0; 3853 m_host.TaskInventory.LockItemsForWrite(false);
3520 }
3521 3854
3522 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3855 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3523 m_waitingForScriptAnswer=true; 3856 m_waitingForScriptAnswer=true;
@@ -3552,10 +3885,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3552 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3885 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3553 llReleaseControls(); 3886 llReleaseControls();
3554 3887
3555 lock (m_host.TaskInventory) 3888
3556 { 3889 m_host.TaskInventory.LockItemsForWrite(true);
3557 m_host.TaskInventory[invItemID].PermsMask = answer; 3890 m_host.TaskInventory[invItemID].PermsMask = answer;
3558 } 3891 m_host.TaskInventory.LockItemsForWrite(false);
3892
3559 3893
3560 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3894 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3561 "run_time_permissions", new Object[] { 3895 "run_time_permissions", new Object[] {
@@ -3567,16 +3901,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3567 { 3901 {
3568 m_host.AddScriptLPS(1); 3902 m_host.AddScriptLPS(1);
3569 3903
3570 lock (m_host.TaskInventory) 3904 m_host.TaskInventory.LockItemsForRead(true);
3905
3906 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3571 { 3907 {
3572 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3908 if (item.Type == 10 && item.ItemID == m_itemID)
3573 { 3909 {
3574 if (item.Type == 10 && item.ItemID == m_itemID) 3910 m_host.TaskInventory.LockItemsForRead(false);
3575 { 3911 return item.PermsGranter.ToString();
3576 return item.PermsGranter.ToString();
3577 }
3578 } 3912 }
3579 } 3913 }
3914 m_host.TaskInventory.LockItemsForRead(false);
3580 3915
3581 return UUID.Zero.ToString(); 3916 return UUID.Zero.ToString();
3582 } 3917 }
@@ -3585,19 +3920,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3585 { 3920 {
3586 m_host.AddScriptLPS(1); 3921 m_host.AddScriptLPS(1);
3587 3922
3588 lock (m_host.TaskInventory) 3923 m_host.TaskInventory.LockItemsForRead(true);
3924
3925 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3589 { 3926 {
3590 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3927 if (item.Type == 10 && item.ItemID == m_itemID)
3591 { 3928 {
3592 if (item.Type == 10 && item.ItemID == m_itemID) 3929 int perms = item.PermsMask;
3593 { 3930 if (m_automaticLinkPermission)
3594 int perms = item.PermsMask; 3931 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3595 if (m_automaticLinkPermission) 3932 m_host.TaskInventory.LockItemsForRead(false);
3596 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3933 return perms;
3597 return perms;
3598 }
3599 } 3934 }
3600 } 3935 }
3936 m_host.TaskInventory.LockItemsForRead(false);
3601 3937
3602 return 0; 3938 return 0;
3603 } 3939 }
@@ -3619,9 +3955,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3619 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3955 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3620 { 3956 {
3621 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3957 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3622 3958 if (parts.Count > 0)
3623 foreach (SceneObjectPart part in parts) 3959 {
3624 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3960 try
3961 {
3962 parts[0].ParentGroup.areUpdatesSuspended = true;
3963 foreach (SceneObjectPart part in parts)
3964 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3965 }
3966 finally
3967 {
3968 parts[0].ParentGroup.areUpdatesSuspended = false;
3969 }
3970 }
3625 } 3971 }
3626 3972
3627 public void llCreateLink(string target, int parent) 3973 public void llCreateLink(string target, int parent)
@@ -3634,11 +3980,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3634 return; 3980 return;
3635 3981
3636 TaskInventoryItem item; 3982 TaskInventoryItem item;
3637 lock (m_host.TaskInventory) 3983 m_host.TaskInventory.LockItemsForRead(true);
3638 { 3984 item = m_host.TaskInventory[invItemID];
3639 item = m_host.TaskInventory[invItemID]; 3985 m_host.TaskInventory.LockItemsForRead(false);
3640 } 3986
3641
3642 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3987 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3643 && !m_automaticLinkPermission) 3988 && !m_automaticLinkPermission)
3644 { 3989 {
@@ -3655,11 +4000,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3655 4000
3656 if (targetPart.ParentGroup.AttachmentPoint != 0) 4001 if (targetPart.ParentGroup.AttachmentPoint != 0)
3657 return; // Fail silently if attached 4002 return; // Fail silently if attached
4003
4004 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
4005 return;
4006
3658 SceneObjectGroup parentPrim = null, childPrim = null; 4007 SceneObjectGroup parentPrim = null, childPrim = null;
3659 4008
3660 if (targetPart != null) 4009 if (targetPart != null)
3661 { 4010 {
3662 if (parent != 0) { 4011 if (parent != 0)
4012 {
3663 parentPrim = m_host.ParentGroup; 4013 parentPrim = m_host.ParentGroup;
3664 childPrim = targetPart.ParentGroup; 4014 childPrim = targetPart.ParentGroup;
3665 } 4015 }
@@ -3671,7 +4021,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3671 4021
3672 // Required for linking 4022 // Required for linking
3673 childPrim.RootPart.ClearUpdateSchedule(); 4023 childPrim.RootPart.ClearUpdateSchedule();
3674 parentPrim.LinkToGroup(childPrim); 4024 parentPrim.LinkToGroup(childPrim, true);
3675 } 4025 }
3676 4026
3677 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4027 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3690,16 +4040,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3690 m_host.AddScriptLPS(1); 4040 m_host.AddScriptLPS(1);
3691 UUID invItemID = InventorySelf(); 4041 UUID invItemID = InventorySelf();
3692 4042
3693 lock (m_host.TaskInventory) 4043 m_host.TaskInventory.LockItemsForRead(true);
3694 {
3695 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4044 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3696 && !m_automaticLinkPermission) 4045 && !m_automaticLinkPermission)
3697 { 4046 {
3698 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4047 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4048 m_host.TaskInventory.LockItemsForRead(false);
3699 return; 4049 return;
3700 } 4050 }
3701 } 4051 m_host.TaskInventory.LockItemsForRead(false);
3702 4052
3703 if (linknum < ScriptBaseClass.LINK_THIS) 4053 if (linknum < ScriptBaseClass.LINK_THIS)
3704 return; 4054 return;
3705 4055
@@ -3738,10 +4088,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3738 // Restructuring Multiple Prims. 4088 // Restructuring Multiple Prims.
3739 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4089 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3740 parts.Remove(parentPrim.RootPart); 4090 parts.Remove(parentPrim.RootPart);
3741 foreach (SceneObjectPart part in parts) 4091 if (parts.Count > 0)
3742 { 4092 {
3743 parentPrim.DelinkFromGroup(part.LocalId, true); 4093 try
4094 {
4095 parts[0].ParentGroup.areUpdatesSuspended = true;
4096 foreach (SceneObjectPart part in parts)
4097 {
4098 parentPrim.DelinkFromGroup(part.LocalId, true);
4099 }
4100 }
4101 finally
4102 {
4103 parts[0].ParentGroup.areUpdatesSuspended = false;
4104 }
3744 } 4105 }
4106
3745 parentPrim.HasGroupChanged = true; 4107 parentPrim.HasGroupChanged = true;
3746 parentPrim.ScheduleGroupForFullUpdate(); 4108 parentPrim.ScheduleGroupForFullUpdate();
3747 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4109 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3750,12 +4112,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3750 { 4112 {
3751 SceneObjectPart newRoot = parts[0]; 4113 SceneObjectPart newRoot = parts[0];
3752 parts.Remove(newRoot); 4114 parts.Remove(newRoot);
3753 foreach (SceneObjectPart part in parts) 4115
4116 try
3754 { 4117 {
3755 // Required for linking 4118 parts[0].ParentGroup.areUpdatesSuspended = true;
3756 part.ClearUpdateSchedule(); 4119 foreach (SceneObjectPart part in parts)
3757 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4120 {
4121 part.ClearUpdateSchedule();
4122 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4123 }
3758 } 4124 }
4125 finally
4126 {
4127 parts[0].ParentGroup.areUpdatesSuspended = false;
4128 }
4129
4130
3759 newRoot.ParentGroup.HasGroupChanged = true; 4131 newRoot.ParentGroup.HasGroupChanged = true;
3760 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4132 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3761 } 4133 }
@@ -3775,6 +4147,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3775 public void llBreakAllLinks() 4147 public void llBreakAllLinks()
3776 { 4148 {
3777 m_host.AddScriptLPS(1); 4149 m_host.AddScriptLPS(1);
4150
4151 UUID invItemID = InventorySelf();
4152
4153 TaskInventoryItem item;
4154 m_host.TaskInventory.LockItemsForRead(true);
4155 item = m_host.TaskInventory[invItemID];
4156 m_host.TaskInventory.LockItemsForRead(false);
4157
4158 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4159 && !m_automaticLinkPermission)
4160 {
4161 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4162 return;
4163 }
4164
3778 SceneObjectGroup parentPrim = m_host.ParentGroup; 4165 SceneObjectGroup parentPrim = m_host.ParentGroup;
3779 if (parentPrim.AttachmentPoint != 0) 4166 if (parentPrim.AttachmentPoint != 0)
3780 return; // Fail silently if attached 4167 return; // Fail silently if attached
@@ -3794,25 +4181,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3794 public LSL_String llGetLinkKey(int linknum) 4181 public LSL_String llGetLinkKey(int linknum)
3795 { 4182 {
3796 m_host.AddScriptLPS(1); 4183 m_host.AddScriptLPS(1);
3797 List<UUID> keytable = new List<UUID>();
3798 // parse for sitting avatare-uuids
3799 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3800 {
3801 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3802 keytable.Add(presence.UUID);
3803 });
3804
3805 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3806 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3807 {
3808 return keytable[totalprims - linknum].ToString();
3809 }
3810
3811 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3812 {
3813 return m_host.UUID.ToString();
3814 }
3815
3816 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4184 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3817 if (part != null) 4185 if (part != null)
3818 { 4186 {
@@ -3820,6 +4188,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3820 } 4188 }
3821 else 4189 else
3822 { 4190 {
4191 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4192 {
4193 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4194
4195 if (linknum < 0)
4196 return UUID.Zero.ToString();
4197
4198 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4199 if (avatars.Count > linknum)
4200 {
4201 return avatars[linknum].UUID.ToString();
4202 }
4203 }
3823 return UUID.Zero.ToString(); 4204 return UUID.Zero.ToString();
3824 } 4205 }
3825 } 4206 }
@@ -3919,17 +4300,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3919 m_host.AddScriptLPS(1); 4300 m_host.AddScriptLPS(1);
3920 int count = 0; 4301 int count = 0;
3921 4302
3922 lock (m_host.TaskInventory) 4303 m_host.TaskInventory.LockItemsForRead(true);
4304 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3923 { 4305 {
3924 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4306 if (inv.Value.Type == type || type == -1)
3925 { 4307 {
3926 if (inv.Value.Type == type || type == -1) 4308 count = count + 1;
3927 {
3928 count = count + 1;
3929 }
3930 } 4309 }
3931 } 4310 }
3932 4311
4312 m_host.TaskInventory.LockItemsForRead(false);
3933 return count; 4313 return count;
3934 } 4314 }
3935 4315
@@ -3938,16 +4318,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3938 m_host.AddScriptLPS(1); 4318 m_host.AddScriptLPS(1);
3939 ArrayList keys = new ArrayList(); 4319 ArrayList keys = new ArrayList();
3940 4320
3941 lock (m_host.TaskInventory) 4321 m_host.TaskInventory.LockItemsForRead(true);
4322 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3942 { 4323 {
3943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4324 if (inv.Value.Type == type || type == -1)
3944 { 4325 {
3945 if (inv.Value.Type == type || type == -1) 4326 keys.Add(inv.Value.Name);
3946 {
3947 keys.Add(inv.Value.Name);
3948 }
3949 } 4327 }
3950 } 4328 }
4329 m_host.TaskInventory.LockItemsForRead(false);
3951 4330
3952 if (keys.Count == 0) 4331 if (keys.Count == 0)
3953 { 4332 {
@@ -3984,25 +4363,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3984 } 4363 }
3985 4364
3986 // move the first object found with this inventory name 4365 // move the first object found with this inventory name
3987 lock (m_host.TaskInventory) 4366 m_host.TaskInventory.LockItemsForRead(true);
4367 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3988 { 4368 {
3989 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4369 if (inv.Value.Name == inventory)
3990 { 4370 {
3991 if (inv.Value.Name == inventory) 4371 found = true;
3992 { 4372 objId = inv.Key;
3993 found = true; 4373 assetType = inv.Value.Type;
3994 objId = inv.Key; 4374 objName = inv.Value.Name;
3995 assetType = inv.Value.Type; 4375 break;
3996 objName = inv.Value.Name;
3997 break;
3998 }
3999 } 4376 }
4000 } 4377 }
4378 m_host.TaskInventory.LockItemsForRead(false);
4001 4379
4002 if (!found) 4380 if (!found)
4003 { 4381 {
4004 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4382 llSay(0, String.Format("Could not find object '{0}'", inventory));
4005 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4383 return;
4384// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4006 } 4385 }
4007 4386
4008 // check if destination is an object 4387 // check if destination is an object
@@ -4028,48 +4407,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4028 return; 4407 return;
4029 } 4408 }
4030 } 4409 }
4410
4031 // destination is an avatar 4411 // destination is an avatar
4032 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4412 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4033 4413
4034 if (agentItem == null) 4414 if (agentItem == null)
4035 return; 4415 return;
4036 4416
4037 byte[] bucket = new byte[17]; 4417 byte[] bucket = new byte[1];
4038 bucket[0] = (byte)assetType; 4418 bucket[0] = (byte)assetType;
4039 byte[] objBytes = agentItem.ID.GetBytes(); 4419 //byte[] objBytes = agentItem.ID.GetBytes();
4040 Array.Copy(objBytes, 0, bucket, 1, 16); 4420 //Array.Copy(objBytes, 0, bucket, 1, 16);
4041 4421
4042 GridInstantMessage msg = new GridInstantMessage(World, 4422 GridInstantMessage msg = new GridInstantMessage(World,
4043 m_host.UUID, m_host.Name+", an object owned by "+ 4423 m_host.OwnerID, m_host.Name, destId,
4044 resolveName(m_host.OwnerID)+",", destId,
4045 (byte)InstantMessageDialog.TaskInventoryOffered, 4424 (byte)InstantMessageDialog.TaskInventoryOffered,
4046 false, objName+"\n"+m_host.Name+" is located at "+ 4425 false, objName+". "+m_host.Name+" is located at "+
4047 World.RegionInfo.RegionName+" "+ 4426 World.RegionInfo.RegionName+" "+
4048 m_host.AbsolutePosition.ToString(), 4427 m_host.AbsolutePosition.ToString(),
4049 agentItem.ID, true, m_host.AbsolutePosition, 4428 agentItem.ID, true, m_host.AbsolutePosition,
4050 bucket); 4429 bucket);
4051 if (m_TransferModule != null) 4430
4052 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4431 ScenePresence sp;
4432
4433 if (World.TryGetScenePresence(destId, out sp))
4434 {
4435 sp.ControllingClient.SendInstantMessage(msg);
4436 }
4437 else
4438 {
4439 if (m_TransferModule != null)
4440 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4441 }
4442
4443 //This delay should only occur when giving inventory to avatars.
4053 ScriptSleep(3000); 4444 ScriptSleep(3000);
4054 } 4445 }
4055 } 4446 }
4056 4447
4448 [DebuggerNonUserCode]
4057 public void llRemoveInventory(string name) 4449 public void llRemoveInventory(string name)
4058 { 4450 {
4059 m_host.AddScriptLPS(1); 4451 m_host.AddScriptLPS(1);
4060 4452
4061 lock (m_host.TaskInventory) 4453 List<TaskInventoryItem> inv;
4454 try
4062 { 4455 {
4063 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4456 m_host.TaskInventory.LockItemsForRead(true);
4457 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4458 }
4459 finally
4460 {
4461 m_host.TaskInventory.LockItemsForRead(false);
4462 }
4463 foreach (TaskInventoryItem item in inv)
4464 {
4465 if (item.Name == name)
4064 { 4466 {
4065 if (item.Name == name) 4467 if (item.ItemID == m_itemID)
4066 { 4468 throw new ScriptDeleteException();
4067 if (item.ItemID == m_itemID) 4469 else
4068 throw new ScriptDeleteException(); 4470 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4069 else 4471 return;
4070 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4071 return;
4072 }
4073 } 4472 }
4074 } 4473 }
4075 } 4474 }
@@ -4104,115 +4503,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4104 { 4503 {
4105 m_host.AddScriptLPS(1); 4504 m_host.AddScriptLPS(1);
4106 4505
4107 UUID uuid = (UUID)id; 4506 UUID uuid;
4108 PresenceInfo pinfo = null; 4507 if (UUID.TryParse(id, out uuid))
4109 UserAccount account;
4110
4111 UserInfoCacheEntry ce;
4112 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4113 { 4508 {
4114 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4509 PresenceInfo pinfo = null;
4115 if (account == null) 4510 UserAccount account;
4511
4512 UserInfoCacheEntry ce;
4513 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4116 { 4514 {
4117 m_userInfoCache[uuid] = null; // Cache negative 4515 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4118 return UUID.Zero.ToString(); 4516 if (account == null)
4119 } 4517 {
4518 m_userInfoCache[uuid] = null; // Cache negative
4519 return UUID.Zero.ToString();
4520 }
4120 4521
4121 4522
4122 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4523 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4123 if (pinfos != null && pinfos.Length > 0) 4524 if (pinfos != null && pinfos.Length > 0)
4124 {
4125 foreach (PresenceInfo p in pinfos)
4126 { 4525 {
4127 if (p.RegionID != UUID.Zero) 4526 foreach (PresenceInfo p in pinfos)
4128 { 4527 {
4129 pinfo = p; 4528 if (p.RegionID != UUID.Zero)
4529 {
4530 pinfo = p;
4531 }
4130 } 4532 }
4131 } 4533 }
4132 }
4133 4534
4134 ce = new UserInfoCacheEntry(); 4535 ce = new UserInfoCacheEntry();
4135 ce.time = Util.EnvironmentTickCount(); 4536 ce.time = Util.EnvironmentTickCount();
4136 ce.account = account; 4537 ce.account = account;
4137 ce.pinfo = pinfo; 4538 ce.pinfo = pinfo;
4138 } 4539 m_userInfoCache[uuid] = ce;
4139 else 4540 }
4140 { 4541 else
4141 if (ce == null) 4542 {
4142 return UUID.Zero.ToString(); 4543 if (ce == null)
4544 return UUID.Zero.ToString();
4143 4545
4144 account = ce.account; 4546 account = ce.account;
4145 pinfo = ce.pinfo; 4547 pinfo = ce.pinfo;
4146 } 4548 }
4147 4549
4148 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4550 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4149 {
4150 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4151 if (pinfos != null && pinfos.Length > 0)
4152 { 4551 {
4153 foreach (PresenceInfo p in pinfos) 4552 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4553 if (pinfos != null && pinfos.Length > 0)
4154 { 4554 {
4155 if (p.RegionID != UUID.Zero) 4555 foreach (PresenceInfo p in pinfos)
4156 { 4556 {
4157 pinfo = p; 4557 if (p.RegionID != UUID.Zero)
4558 {
4559 pinfo = p;
4560 }
4158 } 4561 }
4159 } 4562 }
4160 } 4563 else
4161 else 4564 pinfo = null;
4162 pinfo = null;
4163 4565
4164 ce.time = Util.EnvironmentTickCount(); 4566 ce.time = Util.EnvironmentTickCount();
4165 ce.pinfo = pinfo; 4567 ce.pinfo = pinfo;
4166 } 4568 }
4167 4569
4168 string reply = String.Empty; 4570 string reply = String.Empty;
4169 4571
4170 switch (data) 4572 switch (data)
4171 { 4573 {
4172 case 1: // DATA_ONLINE (0|1) 4574 case 1: // DATA_ONLINE (0|1)
4173 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4575 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4174 reply = "1"; 4576 reply = "1";
4175 else 4577 else
4176 reply = "0"; 4578 reply = "0";
4177 break; 4579 break;
4178 case 2: // DATA_NAME (First Last) 4580 case 2: // DATA_NAME (First Last)
4179 reply = account.FirstName + " " + account.LastName; 4581 reply = account.FirstName + " " + account.LastName;
4180 break; 4582 break;
4181 case 3: // DATA_BORN (YYYY-MM-DD) 4583 case 3: // DATA_BORN (YYYY-MM-DD)
4182 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4584 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4183 born = born.AddSeconds(account.Created); 4585 born = born.AddSeconds(account.Created);
4184 reply = born.ToString("yyyy-MM-dd"); 4586 reply = born.ToString("yyyy-MM-dd");
4185 break; 4587 break;
4186 case 4: // DATA_RATING (0,0,0,0,0,0) 4588 case 4: // DATA_RATING (0,0,0,0,0,0)
4187 reply = "0,0,0,0,0,0"; 4589 reply = "0,0,0,0,0,0";
4188 break; 4590 break;
4189 case 7: // DATA_USERLEVEL (integer) 4591 case 8: // DATA_PAYINFO (0|1|2|3)
4190 reply = account.UserLevel.ToString(); 4592 reply = "0";
4191 break; 4593 break;
4192 case 8: // DATA_PAYINFO (0|1|2|3) 4594 default:
4193 reply = "0"; 4595 return UUID.Zero.ToString(); // Raise no event
4194 break; 4596 }
4195 default:
4196 return UUID.Zero.ToString(); // Raise no event
4197 }
4198 4597
4199 UUID rq = UUID.Random(); 4598 UUID rq = UUID.Random();
4200 4599
4201 UUID tid = AsyncCommands. 4600 UUID tid = AsyncCommands.
4202 DataserverPlugin.RegisterRequest(m_localID, 4601 DataserverPlugin.RegisterRequest(m_localID,
4203 m_itemID, rq.ToString()); 4602 m_itemID, rq.ToString());
4204 4603
4205 AsyncCommands. 4604 AsyncCommands.
4206 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4605 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4207 4606
4208 ScriptSleep(100); 4607 ScriptSleep(100);
4209 return tid.ToString(); 4608 return tid.ToString();
4609 }
4610 else
4611 {
4612 ShoutError("Invalid UUID passed to llRequestAgentData.");
4613 }
4614 return "";
4210 } 4615 }
4211 4616
4212 public LSL_String llRequestInventoryData(string name) 4617 public LSL_String llRequestInventoryData(string name)
4213 { 4618 {
4214 m_host.AddScriptLPS(1); 4619 m_host.AddScriptLPS(1);
4215 4620
4621 //Clone is thread safe
4216 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4622 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4217 4623
4218 foreach (TaskInventoryItem item in itemDictionary.Values) 4624 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4264,19 +4670,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4264 if (UUID.TryParse(agent, out agentId)) 4670 if (UUID.TryParse(agent, out agentId))
4265 { 4671 {
4266 ScenePresence presence = World.GetScenePresence(agentId); 4672 ScenePresence presence = World.GetScenePresence(agentId);
4267 if (presence != null) 4673 if (presence != null && presence.PresenceType != PresenceType.Npc)
4268 { 4674 {
4675 // agent must not be a god
4676 if (presence.UserLevel >= 200) return;
4677
4269 // agent must be over the owners land 4678 // agent must be over the owners land
4270 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4679 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4271 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4680 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4272 { 4681 {
4273 World.TeleportClientHome(agentId, presence.ControllingClient); 4682 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4683 {
4684 // They can't be teleported home for some reason
4685 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4686 if (regionInfo != null)
4687 {
4688 World.RequestTeleportLocation(
4689 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4690 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4691 }
4692 }
4274 } 4693 }
4275 } 4694 }
4276 } 4695 }
4277 ScriptSleep(5000); 4696 ScriptSleep(5000);
4278 } 4697 }
4279 4698
4699 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4700 {
4701 m_host.AddScriptLPS(1);
4702 UUID agentId = new UUID();
4703 if (UUID.TryParse(agent, out agentId))
4704 {
4705 ScenePresence presence = World.GetScenePresence(agentId);
4706 if (presence != null && presence.PresenceType != PresenceType.Npc)
4707 {
4708 // agent must not be a god
4709 if (presence.GodLevel >= 200) return;
4710
4711 if (simname == String.Empty)
4712 simname = World.RegionInfo.RegionName;
4713
4714 // agent must be over the owners land
4715 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4716 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4717 {
4718 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);
4719 }
4720 else // or must be wearing the prim
4721 {
4722 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4723 {
4724 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);
4725 }
4726 }
4727 }
4728 }
4729 }
4730
4280 public void llTextBox(string agent, string message, int chatChannel) 4731 public void llTextBox(string agent, string message, int chatChannel)
4281 { 4732 {
4282 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4733 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4288,7 +4739,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4288 UUID av = new UUID(); 4739 UUID av = new UUID();
4289 if (!UUID.TryParse(agent,out av)) 4740 if (!UUID.TryParse(agent,out av))
4290 { 4741 {
4291 LSLError("First parameter to llDialog needs to be a key"); 4742 //LSLError("First parameter to llDialog needs to be a key");
4292 return; 4743 return;
4293 } 4744 }
4294 4745
@@ -4325,17 +4776,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4325 UUID soundId = UUID.Zero; 4776 UUID soundId = UUID.Zero;
4326 if (!UUID.TryParse(impact_sound, out soundId)) 4777 if (!UUID.TryParse(impact_sound, out soundId))
4327 { 4778 {
4328 lock (m_host.TaskInventory) 4779 m_host.TaskInventory.LockItemsForRead(true);
4780 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4329 { 4781 {
4330 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4782 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4331 { 4783 {
4332 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4784 soundId = item.AssetID;
4333 { 4785 break;
4334 soundId = item.AssetID;
4335 break;
4336 }
4337 } 4786 }
4338 } 4787 }
4788 m_host.TaskInventory.LockItemsForRead(false);
4339 } 4789 }
4340 m_host.CollisionSound = soundId; 4790 m_host.CollisionSound = soundId;
4341 m_host.CollisionSoundVolume = (float)impact_volume; 4791 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4375,6 +4825,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4375 UUID partItemID; 4825 UUID partItemID;
4376 foreach (SceneObjectPart part in parts) 4826 foreach (SceneObjectPart part in parts)
4377 { 4827 {
4828 //Clone is thread safe
4378 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4829 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4379 4830
4380 foreach (TaskInventoryItem item in itemsDictionary.Values) 4831 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4578,17 +5029,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4578 5029
4579 m_host.AddScriptLPS(1); 5030 m_host.AddScriptLPS(1);
4580 5031
4581 lock (m_host.TaskInventory) 5032 m_host.TaskInventory.LockItemsForRead(true);
5033 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4582 { 5034 {
4583 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 5035 if (item.Type == 10 && item.ItemID == m_itemID)
4584 { 5036 {
4585 if (item.Type == 10 && item.ItemID == m_itemID) 5037 result = item.Name!=null?item.Name:String.Empty;
4586 { 5038 break;
4587 result = item.Name != null ? item.Name : String.Empty;
4588 break;
4589 }
4590 } 5039 }
4591 } 5040 }
5041 m_host.TaskInventory.LockItemsForRead(false);
4592 5042
4593 return result; 5043 return result;
4594 } 5044 }
@@ -4761,23 +5211,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5211 {
4762 m_host.AddScriptLPS(1); 5212 m_host.AddScriptLPS(1);
4763 5213
4764 lock (m_host.TaskInventory) 5214 m_host.TaskInventory.LockItemsForRead(true);
5215 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4765 { 5216 {
4766 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5217 if (inv.Value.Name == name)
4767 { 5218 {
4768 if (inv.Value.Name == name) 5219 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4769 { 5220 {
4770 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5221 m_host.TaskInventory.LockItemsForRead(false);
4771 { 5222 return inv.Value.AssetID.ToString();
4772 return inv.Value.AssetID.ToString(); 5223 }
4773 } 5224 else
4774 else 5225 {
4775 { 5226 m_host.TaskInventory.LockItemsForRead(false);
4776 return UUID.Zero.ToString(); 5227 return UUID.Zero.ToString();
4777 }
4778 } 5228 }
4779 } 5229 }
4780 } 5230 }
5231 m_host.TaskInventory.LockItemsForRead(false);
4781 5232
4782 return UUID.Zero.ToString(); 5233 return UUID.Zero.ToString();
4783 } 5234 }
@@ -4930,14 +5381,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 { 5381 {
4931 m_host.AddScriptLPS(1); 5382 m_host.AddScriptLPS(1);
4932 5383
4933 if (src == null) 5384 return src.Length;
4934 {
4935 return 0;
4936 }
4937 else
4938 {
4939 return src.Length;
4940 }
4941 } 5385 }
4942 5386
4943 public LSL_Integer llList2Integer(LSL_List src, int index) 5387 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4983,7 +5427,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4983 else if (src.Data[index] is LSL_Float) 5427 else if (src.Data[index] is LSL_Float)
4984 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5428 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4985 else if (src.Data[index] is LSL_String) 5429 else if (src.Data[index] is LSL_String)
4986 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5430 {
5431 string str = ((LSL_String) src.Data[index]).m_string;
5432 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5433 if (m != Match.Empty)
5434 {
5435 str = m.Value;
5436 double d = 0.0;
5437 if (!Double.TryParse(str, out d))
5438 return 0.0;
5439
5440 return d;
5441 }
5442 return 0.0;
5443 }
4987 return Convert.ToDouble(src.Data[index]); 5444 return Convert.ToDouble(src.Data[index]);
4988 } 5445 }
4989 catch (FormatException) 5446 catch (FormatException)
@@ -5256,7 +5713,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5256 } 5713 }
5257 } 5714 }
5258 } 5715 }
5259 else { 5716 else
5717 {
5260 object[] array = new object[src.Length]; 5718 object[] array = new object[src.Length];
5261 Array.Copy(src.Data, 0, array, 0, src.Length); 5719 Array.Copy(src.Data, 0, array, 0, src.Length);
5262 result = new LSL_List(array); 5720 result = new LSL_List(array);
@@ -5363,7 +5821,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5363 public LSL_Integer llGetRegionAgentCount() 5821 public LSL_Integer llGetRegionAgentCount()
5364 { 5822 {
5365 m_host.AddScriptLPS(1); 5823 m_host.AddScriptLPS(1);
5366 return new LSL_Integer(World.GetRootAgentCount()); 5824
5825 int count = 0;
5826 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5827 count++;
5828 });
5829
5830 return new LSL_Integer(count);
5367 } 5831 }
5368 5832
5369 public LSL_Vector llGetRegionCorner() 5833 public LSL_Vector llGetRegionCorner()
@@ -5643,6 +6107,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5643 flags |= ScriptBaseClass.AGENT_SITTING; 6107 flags |= ScriptBaseClass.AGENT_SITTING;
5644 } 6108 }
5645 6109
6110 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6111 {
6112 flags |= ScriptBaseClass.AGENT_MALE;
6113 }
6114
5646 return flags; 6115 return flags;
5647 } 6116 }
5648 6117
@@ -5705,10 +6174,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5705 m_host.AddScriptLPS(1); 6174 m_host.AddScriptLPS(1);
5706 6175
5707 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6176 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5708 6177 if (parts.Count > 0)
5709 foreach (var part in parts)
5710 { 6178 {
5711 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6179 try
6180 {
6181 parts[0].ParentGroup.areUpdatesSuspended = true;
6182 foreach (var part in parts)
6183 {
6184 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6185 }
6186 }
6187 finally
6188 {
6189 parts[0].ParentGroup.areUpdatesSuspended = false;
6190 }
5712 } 6191 }
5713 } 6192 }
5714 6193
@@ -5760,13 +6239,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5760 6239
5761 if (m_host.OwnerID == land.LandData.OwnerID) 6240 if (m_host.OwnerID == land.LandData.OwnerID)
5762 { 6241 {
5763 World.TeleportClientHome(agentID, presence.ControllingClient); 6242 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6243 presence.TeleportWithMomentum(pos);
6244 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5764 } 6245 }
5765 } 6246 }
5766 } 6247 }
5767 ScriptSleep(5000); 6248 ScriptSleep(5000);
5768 } 6249 }
5769 6250
6251 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6252 {
6253 return ParseString2List(str, separators, in_spacers, false);
6254 }
6255
5770 public LSL_Integer llOverMyLand(string id) 6256 public LSL_Integer llOverMyLand(string id)
5771 { 6257 {
5772 m_host.AddScriptLPS(1); 6258 m_host.AddScriptLPS(1);
@@ -5831,8 +6317,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5831 UUID agentId = new UUID(); 6317 UUID agentId = new UUID();
5832 if (!UUID.TryParse(agent, out agentId)) 6318 if (!UUID.TryParse(agent, out agentId))
5833 return new LSL_Integer(0); 6319 return new LSL_Integer(0);
6320 if (agentId == m_host.GroupID)
6321 return new LSL_Integer(1);
5834 ScenePresence presence = World.GetScenePresence(agentId); 6322 ScenePresence presence = World.GetScenePresence(agentId);
5835 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6323 if (presence == null || presence.IsChildAgent) // Return false for child agents
5836 return new LSL_Integer(0); 6324 return new LSL_Integer(0);
5837 IClientAPI client = presence.ControllingClient; 6325 IClientAPI client = presence.ControllingClient;
5838 if (m_host.GroupID == client.ActiveGroupId) 6326 if (m_host.GroupID == client.ActiveGroupId)
@@ -5967,7 +6455,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5967 return m_host.ParentGroup.AttachmentPoint; 6455 return m_host.ParentGroup.AttachmentPoint;
5968 } 6456 }
5969 6457
5970 public LSL_Integer llGetFreeMemory() 6458 public virtual LSL_Integer llGetFreeMemory()
5971 { 6459 {
5972 m_host.AddScriptLPS(1); 6460 m_host.AddScriptLPS(1);
5973 // Make scripts designed for LSO happy 6461 // Make scripts designed for LSO happy
@@ -6084,7 +6572,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6084 SetParticleSystem(m_host, rules); 6572 SetParticleSystem(m_host, rules);
6085 } 6573 }
6086 6574
6087 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6575 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6576 {
6088 6577
6089 6578
6090 if (rules.Length == 0) 6579 if (rules.Length == 0)
@@ -6278,14 +6767,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6278 6767
6279 protected UUID GetTaskInventoryItem(string name) 6768 protected UUID GetTaskInventoryItem(string name)
6280 { 6769 {
6281 lock (m_host.TaskInventory) 6770 m_host.TaskInventory.LockItemsForRead(true);
6771 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6282 { 6772 {
6283 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6773 if (inv.Value.Name == name)
6284 { 6774 {
6285 if (inv.Value.Name == name) 6775 m_host.TaskInventory.LockItemsForRead(false);
6286 return inv.Key; 6776 return inv.Key;
6287 } 6777 }
6288 } 6778 }
6779 m_host.TaskInventory.LockItemsForRead(false);
6289 6780
6290 return UUID.Zero; 6781 return UUID.Zero;
6291 } 6782 }
@@ -6323,16 +6814,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6323 if (folderID == UUID.Zero) 6814 if (folderID == UUID.Zero)
6324 return; 6815 return;
6325 6816
6326 byte[] bucket = new byte[17]; 6817 byte[] bucket = new byte[1];
6327 bucket[0] = (byte)AssetType.Folder; 6818 bucket[0] = (byte)AssetType.Folder;
6328 byte[] objBytes = folderID.GetBytes(); 6819 //byte[] objBytes = folderID.GetBytes();
6329 Array.Copy(objBytes, 0, bucket, 1, 16); 6820 //Array.Copy(objBytes, 0, bucket, 1, 16);
6330 6821
6331 GridInstantMessage msg = new GridInstantMessage(World, 6822 GridInstantMessage msg = new GridInstantMessage(World,
6332 m_host.UUID, m_host.Name+", an object owned by "+ 6823 m_host.OwnerID, m_host.Name, destID,
6333 resolveName(m_host.OwnerID)+",", destID, 6824 (byte)InstantMessageDialog.TaskInventoryOffered,
6334 (byte)InstantMessageDialog.InventoryOffered, 6825 false, category+". "+m_host.Name+" is located at "+
6335 false, category+"\n"+m_host.Name+" is located at "+
6336 World.RegionInfo.RegionName+" "+ 6826 World.RegionInfo.RegionName+" "+
6337 m_host.AbsolutePosition.ToString(), 6827 m_host.AbsolutePosition.ToString(),
6338 folderID, true, m_host.AbsolutePosition, 6828 folderID, true, m_host.AbsolutePosition,
@@ -6570,13 +7060,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6570 UUID av = new UUID(); 7060 UUID av = new UUID();
6571 if (!UUID.TryParse(avatar,out av)) 7061 if (!UUID.TryParse(avatar,out av))
6572 { 7062 {
6573 LSLError("First parameter to llDialog needs to be a key"); 7063 //LSLError("First parameter to llDialog needs to be a key");
6574 return; 7064 return;
6575 } 7065 }
6576 if (buttons.Length < 1) 7066 if (buttons.Length < 1)
6577 { 7067 {
6578 LSLError("No less than 1 button can be shown"); 7068 buttons.Add("OK");
6579 return;
6580 } 7069 }
6581 if (buttons.Length > 12) 7070 if (buttons.Length > 12)
6582 { 7071 {
@@ -6593,7 +7082,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6593 } 7082 }
6594 if (buttons.Data[i].ToString().Length > 24) 7083 if (buttons.Data[i].ToString().Length > 24)
6595 { 7084 {
6596 LSLError("button label cannot be longer than 24 characters"); 7085 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6597 return; 7086 return;
6598 } 7087 }
6599 buts[i] = buttons.Data[i].ToString(); 7088 buts[i] = buttons.Data[i].ToString();
@@ -6652,22 +7141,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6652 } 7141 }
6653 7142
6654 // copy the first script found with this inventory name 7143 // copy the first script found with this inventory name
6655 lock (m_host.TaskInventory) 7144 TaskInventoryItem scriptItem = null;
7145 m_host.TaskInventory.LockItemsForRead(true);
7146 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6656 { 7147 {
6657 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7148 if (inv.Value.Name == name)
6658 { 7149 {
6659 if (inv.Value.Name == name) 7150 // make sure the object is a script
7151 if (10 == inv.Value.Type)
6660 { 7152 {
6661 // make sure the object is a script 7153 found = true;
6662 if (10 == inv.Value.Type) 7154 srcId = inv.Key;
6663 { 7155 scriptItem = inv.Value;
6664 found = true; 7156 break;
6665 srcId = inv.Key;
6666 break;
6667 }
6668 } 7157 }
6669 } 7158 }
6670 } 7159 }
7160 m_host.TaskInventory.LockItemsForRead(false);
6671 7161
6672 if (!found) 7162 if (!found)
6673 { 7163 {
@@ -6675,9 +7165,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6675 return; 7165 return;
6676 } 7166 }
6677 7167
6678 // the rest of the permission checks are done in RezScript, so check the pin there as well 7168 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6679 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7169 if (dest != null)
7170 {
7171 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7172 {
7173 // the rest of the permission checks are done in RezScript, so check the pin there as well
7174 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6680 7175
7176 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7177 m_host.Inventory.RemoveInventoryItem(srcId);
7178 }
7179 }
6681 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7180 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6682 ScriptSleep(3000); 7181 ScriptSleep(3000);
6683 } 7182 }
@@ -6740,19 +7239,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6740 public LSL_String llMD5String(string src, int nonce) 7239 public LSL_String llMD5String(string src, int nonce)
6741 { 7240 {
6742 m_host.AddScriptLPS(1); 7241 m_host.AddScriptLPS(1);
6743 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7242 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6744 } 7243 }
6745 7244
6746 public LSL_String llSHA1String(string src) 7245 public LSL_String llSHA1String(string src)
6747 { 7246 {
6748 m_host.AddScriptLPS(1); 7247 m_host.AddScriptLPS(1);
6749 return Util.SHA1Hash(src).ToLower(); 7248 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6750 } 7249 }
6751 7250
6752 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7251 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6753 { 7252 {
6754 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7253 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6755 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7254 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7255 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7256 return shapeBlock;
6756 7257
6757 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7258 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6758 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7259 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6857,6 +7358,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6857 // Prim type box, cylinder and prism. 7358 // Prim type box, cylinder and prism.
6858 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) 7359 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)
6859 { 7360 {
7361 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7362 return;
7363
6860 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7364 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6861 ObjectShapePacket.ObjectDataBlock shapeBlock; 7365 ObjectShapePacket.ObjectDataBlock shapeBlock;
6862 7366
@@ -6910,6 +7414,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6910 // Prim type sphere. 7414 // Prim type sphere.
6911 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7415 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6912 { 7416 {
7417 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7418 return;
7419
6913 ObjectShapePacket.ObjectDataBlock shapeBlock; 7420 ObjectShapePacket.ObjectDataBlock shapeBlock;
6914 7421
6915 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7422 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6951,6 +7458,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 // Prim type torus, tube and ring. 7458 // Prim type torus, tube and ring.
6952 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) 7459 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)
6953 { 7460 {
7461 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7462 return;
7463
6954 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7464 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6955 ObjectShapePacket.ObjectDataBlock shapeBlock; 7465 ObjectShapePacket.ObjectDataBlock shapeBlock;
6956 7466
@@ -7086,6 +7596,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7086 // Prim type sculpt. 7596 // Prim type sculpt.
7087 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7597 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7088 { 7598 {
7599 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7600 return;
7601
7089 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7602 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7090 UUID sculptId; 7603 UUID sculptId;
7091 7604
@@ -7110,7 +7623,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7110 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7623 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7111 { 7624 {
7112 // default 7625 // default
7113 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7626 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7114 } 7627 }
7115 7628
7116 part.Shape.SetSculptProperties((byte)type, sculptId); 7629 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7126,32 +7639,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7126 ScriptSleep(200); 7639 ScriptSleep(200);
7127 } 7640 }
7128 7641
7129 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7642 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7130 { 7643 {
7131 m_host.AddScriptLPS(1); 7644 m_host.AddScriptLPS(1);
7132 7645
7133 setLinkPrimParams(linknumber, rules); 7646 setLinkPrimParams(linknumber, rules);
7647 }
7134 7648
7135 ScriptSleep(200); 7649 private void setLinkPrimParams(int linknumber, LSL_List rules)
7650 {
7651 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7652 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7653 if (parts.Count>0)
7654 {
7655 try
7656 {
7657 parts[0].ParentGroup.areUpdatesSuspended = true;
7658 foreach (SceneObjectPart part in parts)
7659 SetPrimParams(part, rules);
7660 }
7661 finally
7662 {
7663 parts[0].ParentGroup.areUpdatesSuspended = false;
7664 }
7665 }
7666 if (avatars.Count > 0)
7667 {
7668 foreach (ScenePresence avatar in avatars)
7669 SetPrimParams(avatar, rules);
7670 }
7136 } 7671 }
7137 7672
7138 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7673 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7674 float material_density, float material_friction,
7675 float material_restitution, float material_gravity_modifier)
7139 { 7676 {
7140 m_host.AddScriptLPS(1); 7677 ExtraPhysicsData physdata = new ExtraPhysicsData();
7678 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7679 physdata.Density = part.Density;
7680 physdata.Friction = part.Friction;
7681 physdata.Bounce = part.Bounciness;
7682 physdata.GravitationModifier = part.GravityModifier;
7141 7683
7142 setLinkPrimParams(linknumber, rules); 7684 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7685 physdata.Density = material_density;
7686 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7687 physdata.Friction = material_friction;
7688 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7689 physdata.Bounce = material_restitution;
7690 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7691 physdata.GravitationModifier = material_gravity_modifier;
7692
7693 part.UpdateExtraPhysics(physdata);
7143 } 7694 }
7144 7695
7145 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7696 public void llSetPhysicsMaterial(int material_bits,
7697 float material_gravity_modifier, float material_restitution,
7698 float material_friction, float material_density)
7146 { 7699 {
7147 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7700 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7701 }
7148 7702
7149 foreach (SceneObjectPart part in parts) 7703 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7150 SetPrimParams(part, rules); 7704 {
7705 llSetLinkPrimitiveParamsFast(linknumber, rules);
7706 ScriptSleep(200);
7707 }
7708
7709 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7710 {
7711 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7712 //We only support PRIM_POSITION and PRIM_ROTATION
7713
7714 int idx = 0;
7715
7716 while (idx < rules.Length)
7717 {
7718 int code = rules.GetLSLIntegerItem(idx++);
7719
7720 int remain = rules.Length - idx;
7721
7722 switch (code)
7723 {
7724 case (int)ScriptBaseClass.PRIM_POSITION:
7725 {
7726 if (remain < 1)
7727 return;
7728 LSL_Vector v;
7729 v = rules.GetVector3Item(idx++);
7730
7731 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7732 if (part == null)
7733 break;
7734
7735 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7736 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7737 if (llGetLinkNumber() > 1)
7738 {
7739 localRot = llGetLocalRot();
7740 localPos = llGetLocalPos();
7741 }
7742
7743 v -= localPos;
7744 v /= localRot;
7745
7746 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7747
7748 v = v + 2 * sitOffset;
7749
7750 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7751 av.SendAvatarDataToAllAgents();
7752
7753 }
7754 break;
7755
7756 case (int)ScriptBaseClass.PRIM_ROTATION:
7757 {
7758 if (remain < 1)
7759 return;
7760
7761 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7762 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7763 if (llGetLinkNumber() > 1)
7764 {
7765 localRot = llGetLocalRot();
7766 localPos = llGetLocalPos();
7767 }
7768
7769 LSL_Rotation r;
7770 r = rules.GetQuaternionItem(idx++);
7771 r = r * llGetRootRotation() / localRot;
7772 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7773 av.SendAvatarDataToAllAgents();
7774 }
7775 break;
7776 }
7777 }
7151 } 7778 }
7152 7779
7153 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7780 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7154 { 7781 {
7782 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7783 return;
7784
7155 int idx = 0; 7785 int idx = 0;
7156 7786
7157 bool positionChanged = false; 7787 bool positionChanged = false;
@@ -7473,6 +8103,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7473 part.ScriptSetPhysicsStatus(physics); 8103 part.ScriptSetPhysicsStatus(physics);
7474 break; 8104 break;
7475 8105
8106 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8107 if (remain < 1)
8108 return;
8109
8110 int shape_type = rules.GetLSLIntegerItem(idx++);
8111
8112 ExtraPhysicsData physdata = new ExtraPhysicsData();
8113 physdata.Density = part.Density;
8114 physdata.Bounce = part.Bounciness;
8115 physdata.GravitationModifier = part.GravityModifier;
8116 physdata.PhysShapeType = (PhysShapeType)shape_type;
8117
8118 part.UpdateExtraPhysics(physdata);
8119
8120 break;
8121
8122 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8123 if (remain < 5)
8124 return;
8125
8126 int material_bits = rules.GetLSLIntegerItem(idx++);
8127 float material_density = (float)rules.GetLSLFloatItem(idx++);
8128 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8129 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8130 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8131
8132 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8133
8134 break;
8135
7476 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8136 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7477 if (remain < 1) 8137 if (remain < 1)
7478 return; 8138 return;
@@ -7546,7 +8206,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7546 if (part.ParentGroup.RootPart == part) 8206 if (part.ParentGroup.RootPart == part)
7547 { 8207 {
7548 SceneObjectGroup parent = part.ParentGroup; 8208 SceneObjectGroup parent = part.ParentGroup;
7549 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8209 Util.FireAndForget(delegate(object x) {
8210 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8211 });
7550 } 8212 }
7551 else 8213 else
7552 { 8214 {
@@ -7557,6 +8219,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7557 } 8219 }
7558 } 8220 }
7559 } 8221 }
8222
8223 if (positionChanged)
8224 {
8225 if (part.ParentGroup.RootPart == part)
8226 {
8227 SceneObjectGroup parent = part.ParentGroup;
8228 Util.FireAndForget(delegate(object x) {
8229 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8230 });
8231 }
8232 else
8233 {
8234 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8235 SceneObjectGroup parent = part.ParentGroup;
8236 parent.HasGroupChanged = true;
8237 parent.ScheduleGroupForTerseUpdate();
8238 }
8239 }
7560 } 8240 }
7561 8241
7562 public LSL_String llStringToBase64(string str) 8242 public LSL_String llStringToBase64(string str)
@@ -7717,13 +8397,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7717 public LSL_Integer llGetNumberOfPrims() 8397 public LSL_Integer llGetNumberOfPrims()
7718 { 8398 {
7719 m_host.AddScriptLPS(1); 8399 m_host.AddScriptLPS(1);
7720 int avatarCount = 0; 8400 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7721 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8401
7722 {
7723 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7724 avatarCount++;
7725 });
7726
7727 return m_host.ParentGroup.PrimCount + avatarCount; 8402 return m_host.ParentGroup.PrimCount + avatarCount;
7728 } 8403 }
7729 8404
@@ -7739,55 +8414,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7739 m_host.AddScriptLPS(1); 8414 m_host.AddScriptLPS(1);
7740 UUID objID = UUID.Zero; 8415 UUID objID = UUID.Zero;
7741 LSL_List result = new LSL_List(); 8416 LSL_List result = new LSL_List();
8417
8418 // If the ID is not valid, return null result
7742 if (!UUID.TryParse(obj, out objID)) 8419 if (!UUID.TryParse(obj, out objID))
7743 { 8420 {
7744 result.Add(new LSL_Vector()); 8421 result.Add(new LSL_Vector());
7745 result.Add(new LSL_Vector()); 8422 result.Add(new LSL_Vector());
7746 return result; 8423 return result;
7747 } 8424 }
8425
8426 // Check if this is an attached prim. If so, replace
8427 // the UUID with the avatar UUID and report it's bounding box
8428 SceneObjectPart part = World.GetSceneObjectPart(objID);
8429 if (part != null && part.ParentGroup.IsAttachment)
8430 objID = part.ParentGroup.AttachedAvatar;
8431
8432 // Find out if this is an avatar ID. If so, return it's box
7748 ScenePresence presence = World.GetScenePresence(objID); 8433 ScenePresence presence = World.GetScenePresence(objID);
7749 if (presence != null) 8434 if (presence != null)
7750 { 8435 {
7751 if (presence.ParentID == 0) // not sat on an object 8436 // As per LSL Wiki, there is no difference between sitting
8437 // and standing avatar since server 1.36
8438 LSL_Vector lower;
8439 LSL_Vector upper;
8440 if (presence.Animator.Animations.DefaultAnimation.AnimID
8441 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7752 { 8442 {
7753 LSL_Vector lower; 8443 // This is for ground sitting avatars
7754 LSL_Vector upper; 8444 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7755 if (presence.Animator.Animations.DefaultAnimation.AnimID 8445 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7756 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8446 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7757 {
7758 // This is for ground sitting avatars
7759 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7760 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7761 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7762 }
7763 else
7764 {
7765 // This is for standing/flying avatars
7766 float height = presence.Appearance.AvatarHeight / 2.0f;
7767 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7768 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7769 }
7770 result.Add(lower);
7771 result.Add(upper);
7772 return result;
7773 } 8447 }
7774 else 8448 else
7775 { 8449 {
7776 // sitting on an object so we need the bounding box of that 8450 // This is for standing/flying avatars
7777 // which should include the avatar so set the UUID to the 8451 float height = presence.Appearance.AvatarHeight / 2.0f;
7778 // UUID of the object the avatar is sat on and allow it to fall through 8452 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7779 // to processing an object 8453 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7780 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7781 objID = p.UUID;
7782 } 8454 }
8455
8456 // Adjust to the documented error offsets (see LSL Wiki)
8457 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8458 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8459
8460 if (lower.x > upper.x)
8461 lower.x = upper.x;
8462 if (lower.y > upper.y)
8463 lower.y = upper.y;
8464 if (lower.z > upper.z)
8465 lower.z = upper.z;
8466
8467 result.Add(lower);
8468 result.Add(upper);
8469 return result;
7783 } 8470 }
7784 SceneObjectPart part = World.GetSceneObjectPart(objID); 8471
8472 part = World.GetSceneObjectPart(objID);
7785 // Currently only works for single prims without a sitting avatar 8473 // Currently only works for single prims without a sitting avatar
7786 if (part != null) 8474 if (part != null)
7787 { 8475 {
7788 Vector3 halfSize = part.Scale / 2.0f; 8476 float minX;
7789 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8477 float maxX;
7790 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8478 float minY;
8479 float maxY;
8480 float minZ;
8481 float maxZ;
8482
8483 // This BBox is in sim coordinates, with the offset being
8484 // a contained point.
8485 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8486 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8487
8488 minX -= offsets[0].X;
8489 maxX -= offsets[0].X;
8490 minY -= offsets[0].Y;
8491 maxY -= offsets[0].Y;
8492 minZ -= offsets[0].Z;
8493 maxZ -= offsets[0].Z;
8494
8495 LSL_Vector lower;
8496 LSL_Vector upper;
8497
8498 // Adjust to the documented error offsets (see LSL Wiki)
8499 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8500 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8501
8502 if (lower.x > upper.x)
8503 lower.x = upper.x;
8504 if (lower.y > upper.y)
8505 lower.y = upper.y;
8506 if (lower.z > upper.z)
8507 lower.z = upper.z;
8508
7791 result.Add(lower); 8509 result.Add(lower);
7792 result.Add(upper); 8510 result.Add(upper);
7793 return result; 8511 return result;
@@ -7867,13 +8585,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7867 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8585 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7868 part.AbsolutePosition.Y, 8586 part.AbsolutePosition.Y,
7869 part.AbsolutePosition.Z); 8587 part.AbsolutePosition.Z);
7870 // For some reason, the part.AbsolutePosition.* values do not change if the
7871 // linkset is rotated; they always reflect the child prim's world position
7872 // as though the linkset is unrotated. This is incompatible behavior with SL's
7873 // implementation, so will break scripts imported from there (not to mention it
7874 // makes it more difficult to determine a child prim's actual inworld position).
7875 if (part.ParentID != 0)
7876 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7877 res.Add(v); 8588 res.Add(v);
7878 break; 8589 break;
7879 8590
@@ -8044,56 +8755,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8044 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8755 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8045 if (remain < 1) 8756 if (remain < 1)
8046 return res; 8757 return res;
8047 8758 face = (int)rules.GetLSLIntegerItem(idx++);
8048 face=(int)rules.GetLSLIntegerItem(idx++);
8049 8759
8050 tex = part.Shape.Textures; 8760 tex = part.Shape.Textures;
8761 int shiny;
8051 if (face == ScriptBaseClass.ALL_SIDES) 8762 if (face == ScriptBaseClass.ALL_SIDES)
8052 { 8763 {
8053 for (face = 0; face < GetNumberOfSides(part); face++) 8764 for (face = 0; face < GetNumberOfSides(part); face++)
8054 { 8765 {
8055 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8766 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8056 // Convert Shininess to PRIM_SHINY_* 8767 if (shinyness == Shininess.High)
8057 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8768 {
8058 // PRIM_BUMP_* 8769 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8059 res.Add(new LSL_Integer((int)texface.Bump)); 8770 }
8771 else if (shinyness == Shininess.Medium)
8772 {
8773 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8774 }
8775 else if (shinyness == Shininess.Low)
8776 {
8777 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8778 }
8779 else
8780 {
8781 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8782 }
8783 res.Add(new LSL_Integer(shiny));
8784 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8060 } 8785 }
8061 } 8786 }
8062 else 8787 else
8063 { 8788 {
8064 if (face >= 0 && face < GetNumberOfSides(part)) 8789 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8790 if (shinyness == Shininess.High)
8065 { 8791 {
8066 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8792 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8067 // Convert Shininess to PRIM_SHINY_*
8068 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8069 // PRIM_BUMP_*
8070 res.Add(new LSL_Integer((int)texface.Bump));
8071 } 8793 }
8794 else if (shinyness == Shininess.Medium)
8795 {
8796 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8797 }
8798 else if (shinyness == Shininess.Low)
8799 {
8800 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8801 }
8802 else
8803 {
8804 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8805 }
8806 res.Add(new LSL_Integer(shiny));
8807 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8072 } 8808 }
8073 break; 8809 break;
8074 8810
8075 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8811 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8076 if (remain < 1) 8812 if (remain < 1)
8077 return res; 8813 return res;
8078 8814 face = (int)rules.GetLSLIntegerItem(idx++);
8079 face=(int)rules.GetLSLIntegerItem(idx++);
8080 8815
8081 tex = part.Shape.Textures; 8816 tex = part.Shape.Textures;
8817 int fullbright;
8082 if (face == ScriptBaseClass.ALL_SIDES) 8818 if (face == ScriptBaseClass.ALL_SIDES)
8083 { 8819 {
8084 for (face = 0; face < GetNumberOfSides(part); face++) 8820 for (face = 0; face < GetNumberOfSides(part); face++)
8085 { 8821 {
8086 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8822 if (tex.GetFace((uint)face).Fullbright == true)
8087 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8823 {
8824 fullbright = ScriptBaseClass.TRUE;
8825 }
8826 else
8827 {
8828 fullbright = ScriptBaseClass.FALSE;
8829 }
8830 res.Add(new LSL_Integer(fullbright));
8088 } 8831 }
8089 } 8832 }
8090 else 8833 else
8091 { 8834 {
8092 if (face >= 0 && face < GetNumberOfSides(part)) 8835 if (tex.GetFace((uint)face).Fullbright == true)
8093 { 8836 {
8094 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8837 fullbright = ScriptBaseClass.TRUE;
8095 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8838 }
8839 else
8840 {
8841 fullbright = ScriptBaseClass.FALSE;
8096 } 8842 }
8843 res.Add(new LSL_Integer(fullbright));
8097 } 8844 }
8098 break; 8845 break;
8099 8846
@@ -8115,27 +8862,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8115 break; 8862 break;
8116 8863
8117 case (int)ScriptBaseClass.PRIM_TEXGEN: 8864 case (int)ScriptBaseClass.PRIM_TEXGEN:
8865 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8118 if (remain < 1) 8866 if (remain < 1)
8119 return res; 8867 return res;
8120 8868 face = (int)rules.GetLSLIntegerItem(idx++);
8121 face=(int)rules.GetLSLIntegerItem(idx++);
8122 8869
8123 tex = part.Shape.Textures; 8870 tex = part.Shape.Textures;
8124 if (face == ScriptBaseClass.ALL_SIDES) 8871 if (face == ScriptBaseClass.ALL_SIDES)
8125 { 8872 {
8126 for (face = 0; face < GetNumberOfSides(part); face++) 8873 for (face = 0; face < GetNumberOfSides(part); face++)
8127 { 8874 {
8128 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8875 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8129 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8876 {
8130 res.Add(new LSL_Integer((uint)texgen >> 1)); 8877 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8878 }
8879 else
8880 {
8881 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8882 }
8131 } 8883 }
8132 } 8884 }
8133 else 8885 else
8134 { 8886 {
8135 if (face >= 0 && face < GetNumberOfSides(part)) 8887 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8888 {
8889 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8890 }
8891 else
8136 { 8892 {
8137 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8893 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8138 res.Add(new LSL_Integer((uint)texgen >> 1));
8139 } 8894 }
8140 } 8895 }
8141 break; 8896 break;
@@ -8158,28 +8913,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8158 case (int)ScriptBaseClass.PRIM_GLOW: 8913 case (int)ScriptBaseClass.PRIM_GLOW:
8159 if (remain < 1) 8914 if (remain < 1)
8160 return res; 8915 return res;
8161 8916 face = (int)rules.GetLSLIntegerItem(idx++);
8162 face=(int)rules.GetLSLIntegerItem(idx++);
8163 8917
8164 tex = part.Shape.Textures; 8918 tex = part.Shape.Textures;
8919 float primglow;
8165 if (face == ScriptBaseClass.ALL_SIDES) 8920 if (face == ScriptBaseClass.ALL_SIDES)
8166 { 8921 {
8167 for (face = 0; face < GetNumberOfSides(part); face++) 8922 for (face = 0; face < GetNumberOfSides(part); face++)
8168 { 8923 {
8169 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8924 primglow = tex.GetFace((uint)face).Glow;
8170 res.Add(new LSL_Float(texface.Glow)); 8925 res.Add(new LSL_Float(primglow));
8171 } 8926 }
8172 } 8927 }
8173 else 8928 else
8174 { 8929 {
8175 if (face >= 0 && face < GetNumberOfSides(part)) 8930 primglow = tex.GetFace((uint)face).Glow;
8176 { 8931 res.Add(new LSL_Float(primglow));
8177 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8178 res.Add(new LSL_Float(texface.Glow));
8179 }
8180 } 8932 }
8181 break; 8933 break;
8182
8183 case (int)ScriptBaseClass.PRIM_TEXT: 8934 case (int)ScriptBaseClass.PRIM_TEXT:
8184 Color4 textColor = part.GetTextColor(); 8935 Color4 textColor = part.GetTextColor();
8185 res.Add(new LSL_String(part.Text)); 8936 res.Add(new LSL_String(part.Text));
@@ -8791,8 +9542,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8791 // The function returns an ordered list 9542 // The function returns an ordered list
8792 // representing the tokens found in the supplied 9543 // representing the tokens found in the supplied
8793 // sources string. If two successive tokenizers 9544 // sources string. If two successive tokenizers
8794 // are encountered, then a NULL entry is added 9545 // are encountered, then a null-string entry is
8795 // to the list. 9546 // added to the list.
8796 // 9547 //
8797 // It is a precondition that the source and 9548 // It is a precondition that the source and
8798 // toekizer lisst are non-null. If they are null, 9549 // toekizer lisst are non-null. If they are null,
@@ -8800,7 +9551,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8800 // while their lengths are being determined. 9551 // while their lengths are being determined.
8801 // 9552 //
8802 // A small amount of working memoryis required 9553 // A small amount of working memoryis required
8803 // of approximately 8*#tokenizers. 9554 // of approximately 8*#tokenizers + 8*srcstrlen.
8804 // 9555 //
8805 // There are many ways in which this function 9556 // There are many ways in which this function
8806 // can be implemented, this implementation is 9557 // can be implemented, this implementation is
@@ -8816,155 +9567,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8816 // and eliminates redundant tokenizers as soon 9567 // and eliminates redundant tokenizers as soon
8817 // as is possible. 9568 // as is possible.
8818 // 9569 //
8819 // The implementation tries to avoid any copying 9570 // The implementation tries to minimize temporary
8820 // of arrays or other objects. 9571 // garbage generation.
8821 // </remarks> 9572 // </remarks>
8822 9573
8823 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9574 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8824 { 9575 {
8825 int beginning = 0; 9576 return ParseString2List(src, separators, spacers, true);
8826 int srclen = src.Length; 9577 }
8827 int seplen = separators.Length;
8828 object[] separray = separators.Data;
8829 int spclen = spacers.Length;
8830 object[] spcarray = spacers.Data;
8831 int mlen = seplen+spclen;
8832
8833 int[] offset = new int[mlen+1];
8834 bool[] active = new bool[mlen];
8835
8836 int best;
8837 int j;
8838
8839 // Initial capacity reduces resize cost
8840 9578
8841 LSL_List tokens = new LSL_List(); 9579 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9580 {
9581 int srclen = src.Length;
9582 int seplen = separators.Length;
9583 object[] separray = separators.Data;
9584 int spclen = spacers.Length;
9585 object[] spcarray = spacers.Data;
9586 int dellen = 0;
9587 string[] delarray = new string[seplen+spclen];
8842 9588
8843 // All entries are initially valid 9589 int outlen = 0;
9590 string[] outarray = new string[srclen*2+1];
8844 9591
8845 for (int i = 0; i < mlen; i++) 9592 int i, j;
8846 active[i] = true; 9593 string d;
8847 9594
8848 offset[mlen] = srclen; 9595 m_host.AddScriptLPS(1);
8849 9596
8850 while (beginning < srclen) 9597 /*
9598 * Convert separator and spacer lists to C# strings.
9599 * Also filter out null strings so we don't hang.
9600 */
9601 for (i = 0; i < seplen; i ++)
8851 { 9602 {
9603 d = separray[i].ToString();
9604 if (d.Length > 0)
9605 {
9606 delarray[dellen++] = d;
9607 }
9608 }
9609 seplen = dellen;
8852 9610
8853 best = mlen; // as bad as it gets 9611 for (i = 0; i < spclen; i ++)
9612 {
9613 d = spcarray[i].ToString();
9614 if (d.Length > 0)
9615 {
9616 delarray[dellen++] = d;
9617 }
9618 }
8854 9619
8855 // Scan for separators 9620 /*
9621 * Scan through source string from beginning to end.
9622 */
9623 for (i = 0;;)
9624 {
8856 9625
8857 for (j = 0; j < seplen; j++) 9626 /*
9627 * Find earliest delimeter in src starting at i (if any).
9628 */
9629 int earliestDel = -1;
9630 int earliestSrc = srclen;
9631 string earliestStr = null;
9632 for (j = 0; j < dellen; j ++)
8858 { 9633 {
8859 if (separray[j].ToString() == String.Empty) 9634 d = delarray[j];
8860 active[j] = false; 9635 if (d != null)
8861
8862 if (active[j])
8863 { 9636 {
8864 // scan all of the markers 9637 int index = src.IndexOf(d, i);
8865 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9638 if (index < 0)
8866 { 9639 {
8867 // not present at all 9640 delarray[j] = null; // delim nowhere in src, don't check it anymore
8868 active[j] = false;
8869 } 9641 }
8870 else 9642 else if (index < earliestSrc)
8871 { 9643 {
8872 // present and correct 9644 earliestSrc = index; // where delimeter starts in source string
8873 if (offset[j] < offset[best]) 9645 earliestDel = j; // where delimeter is in delarray[]
8874 { 9646 earliestStr = d; // the delimeter string from delarray[]
8875 // closest so far 9647 if (index == i) break; // can't do any better than found at beg of string
8876 best = j;
8877 if (offset[best] == beginning)
8878 break;
8879 }
8880 } 9648 }
8881 } 9649 }
8882 } 9650 }
8883 9651
8884 // Scan for spacers 9652 /*
8885 9653 * Output source string starting at i through start of earliest delimeter.
8886 if (offset[best] != beginning) 9654 */
9655 if (keepNulls || (earliestSrc > i))
8887 { 9656 {
8888 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9657 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8889 {
8890 if (spcarray[j-seplen].ToString() == String.Empty)
8891 active[j] = false;
8892
8893 if (active[j])
8894 {
8895 // scan all of the markers
8896 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8897 {
8898 // not present at all
8899 active[j] = false;
8900 }
8901 else
8902 {
8903 // present and correct
8904 if (offset[j] < offset[best])
8905 {
8906 // closest so far
8907 best = j;
8908 }
8909 }
8910 }
8911 }
8912 } 9658 }
8913 9659
8914 // This is the normal exit from the scanning loop 9660 /*
9661 * If no delimeter found at or after i, we're done scanning.
9662 */
9663 if (earliestDel < 0) break;
8915 9664
8916 if (best == mlen) 9665 /*
9666 * If delimeter was a spacer, output the spacer.
9667 */
9668 if (earliestDel >= seplen)
8917 { 9669 {
8918 // no markers were found on this pass 9670 outarray[outlen++] = earliestStr;
8919 // so we're pretty much done
8920 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8921 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8922 break;
8923 } 9671 }
8924 9672
8925 // Otherwise we just add the newly delimited token 9673 /*
8926 // and recalculate where the search should continue. 9674 * Look at rest of src string following delimeter.
8927 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9675 */
8928 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9676 i = earliestSrc + earliestStr.Length;
8929
8930 if (best < seplen)
8931 {
8932 beginning = offset[best] + (separray[best].ToString()).Length;
8933 }
8934 else
8935 {
8936 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8937 string str = spcarray[best - seplen].ToString();
8938 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8939 tokens.Add(new LSL_String(str));
8940 }
8941 } 9677 }
8942 9678
8943 // This an awkward an not very intuitive boundary case. If the 9679 /*
8944 // last substring is a tokenizer, then there is an implied trailing 9680 * Make up an exact-sized output array suitable for an LSL_List object.
8945 // null list entry. Hopefully the single comparison will not be too 9681 */
8946 // arduous. Alternatively the 'break' could be replced with a return 9682 object[] outlist = new object[outlen];
8947 // but that's shabby programming. 9683 for (i = 0; i < outlen; i ++)
8948
8949 if ((beginning == srclen) && (keepNulls))
8950 { 9684 {
8951 if (srclen != 0) 9685 outlist[i] = new LSL_String(outarray[i]);
8952 tokens.Add(new LSL_String(""));
8953 } 9686 }
8954 9687 return new LSL_List(outlist);
8955 return tokens;
8956 }
8957
8958 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8959 {
8960 m_host.AddScriptLPS(1);
8961 return this.ParseString(src, separators, spacers, false);
8962 }
8963
8964 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8965 {
8966 m_host.AddScriptLPS(1);
8967 return this.ParseString(src, separators, spacers, true);
8968 } 9688 }
8969 9689
8970 public LSL_Integer llGetObjectPermMask(int mask) 9690 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9041,28 +9761,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9041 { 9761 {
9042 m_host.AddScriptLPS(1); 9762 m_host.AddScriptLPS(1);
9043 9763
9044 lock (m_host.TaskInventory) 9764 m_host.TaskInventory.LockItemsForRead(true);
9765 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9045 { 9766 {
9046 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9767 if (inv.Value.Name == item)
9047 { 9768 {
9048 if (inv.Value.Name == item) 9769 m_host.TaskInventory.LockItemsForRead(false);
9770 switch (mask)
9049 { 9771 {
9050 switch (mask) 9772 case 0:
9051 { 9773 return (int)inv.Value.BasePermissions;
9052 case 0: 9774 case 1:
9053 return (int)inv.Value.BasePermissions; 9775 return (int)inv.Value.CurrentPermissions;
9054 case 1: 9776 case 2:
9055 return (int)inv.Value.CurrentPermissions; 9777 return (int)inv.Value.GroupPermissions;
9056 case 2: 9778 case 3:
9057 return (int)inv.Value.GroupPermissions; 9779 return (int)inv.Value.EveryonePermissions;
9058 case 3: 9780 case 4:
9059 return (int)inv.Value.EveryonePermissions; 9781 return (int)inv.Value.NextPermissions;
9060 case 4:
9061 return (int)inv.Value.NextPermissions;
9062 }
9063 } 9782 }
9064 } 9783 }
9065 } 9784 }
9785 m_host.TaskInventory.LockItemsForRead(false);
9066 9786
9067 return -1; 9787 return -1;
9068 } 9788 }
@@ -9109,16 +9829,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9109 { 9829 {
9110 m_host.AddScriptLPS(1); 9830 m_host.AddScriptLPS(1);
9111 9831
9112 lock (m_host.TaskInventory) 9832 m_host.TaskInventory.LockItemsForRead(true);
9833 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9113 { 9834 {
9114 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9835 if (inv.Value.Name == item)
9115 { 9836 {
9116 if (inv.Value.Name == item) 9837 m_host.TaskInventory.LockItemsForRead(false);
9117 { 9838 return inv.Value.CreatorID.ToString();
9118 return inv.Value.CreatorID.ToString();
9119 }
9120 } 9839 }
9121 } 9840 }
9841 m_host.TaskInventory.LockItemsForRead(false);
9122 9842
9123 llSay(0, "No item name '" + item + "'"); 9843 llSay(0, "No item name '" + item + "'");
9124 9844
@@ -9266,7 +9986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9266 } 9986 }
9267 9987
9268 /// <summary> 9988 /// <summary>
9269 /// illListReplaceList removes the sub-list defined by the inclusive indices 9989 /// llListReplaceList removes the sub-list defined by the inclusive indices
9270 /// start and end and inserts the src list in its place. The inclusive 9990 /// start and end and inserts the src list in its place. The inclusive
9271 /// nature of the indices means that at least one element must be deleted 9991 /// nature of the indices means that at least one element must be deleted
9272 /// if the indices are within the bounds of the existing list. I.e. 2,2 9992 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9323,16 +10043,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9323 // based upon end. Note that if end exceeds the upper 10043 // based upon end. Note that if end exceeds the upper
9324 // bound in this case, the entire destination list 10044 // bound in this case, the entire destination list
9325 // is removed. 10045 // is removed.
9326 else 10046 else if (start == 0)
9327 { 10047 {
9328 if (end + 1 < dest.Length) 10048 if (end + 1 < dest.Length)
9329 {
9330 return src + dest.GetSublist(end + 1, -1); 10049 return src + dest.GetSublist(end + 1, -1);
9331 }
9332 else 10050 else
9333 {
9334 return src; 10051 return src;
9335 } 10052 }
10053 else // Start < 0
10054 {
10055 if (end + 1 < dest.Length)
10056 return dest.GetSublist(end + 1, -1);
10057 else
10058 return new LSL_List();
9336 } 10059 }
9337 } 10060 }
9338 // Finally, if start > end, we strip away a prefix and 10061 // Finally, if start > end, we strip away a prefix and
@@ -9383,17 +10106,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9383 int width = 0; 10106 int width = 0;
9384 int height = 0; 10107 int height = 0;
9385 10108
9386 ParcelMediaCommandEnum? commandToSend = null; 10109 uint commandToSend = 0;
9387 float time = 0.0f; // default is from start 10110 float time = 0.0f; // default is from start
9388 10111
9389 ScenePresence presence = null; 10112 ScenePresence presence = null;
9390 10113
9391 for (int i = 0; i < commandList.Data.Length; i++) 10114 for (int i = 0; i < commandList.Data.Length; i++)
9392 { 10115 {
9393 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10116 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9394 switch (command) 10117 switch (command)
9395 { 10118 {
9396 case ParcelMediaCommandEnum.Agent: 10119 case (uint)ParcelMediaCommandEnum.Agent:
9397 // we send only to one agent 10120 // we send only to one agent
9398 if ((i + 1) < commandList.Length) 10121 if ((i + 1) < commandList.Length)
9399 { 10122 {
@@ -9410,25 +10133,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9410 } 10133 }
9411 break; 10134 break;
9412 10135
9413 case ParcelMediaCommandEnum.Loop: 10136 case (uint)ParcelMediaCommandEnum.Loop:
9414 loop = 1; 10137 loop = 1;
9415 commandToSend = command; 10138 commandToSend = command;
9416 update = true; //need to send the media update packet to set looping 10139 update = true; //need to send the media update packet to set looping
9417 break; 10140 break;
9418 10141
9419 case ParcelMediaCommandEnum.Play: 10142 case (uint)ParcelMediaCommandEnum.Play:
9420 loop = 0; 10143 loop = 0;
9421 commandToSend = command; 10144 commandToSend = command;
9422 update = true; //need to send the media update packet to make sure it doesn't loop 10145 update = true; //need to send the media update packet to make sure it doesn't loop
9423 break; 10146 break;
9424 10147
9425 case ParcelMediaCommandEnum.Pause: 10148 case (uint)ParcelMediaCommandEnum.Pause:
9426 case ParcelMediaCommandEnum.Stop: 10149 case (uint)ParcelMediaCommandEnum.Stop:
9427 case ParcelMediaCommandEnum.Unload: 10150 case (uint)ParcelMediaCommandEnum.Unload:
9428 commandToSend = command; 10151 commandToSend = command;
9429 break; 10152 break;
9430 10153
9431 case ParcelMediaCommandEnum.Url: 10154 case (uint)ParcelMediaCommandEnum.Url:
9432 if ((i + 1) < commandList.Length) 10155 if ((i + 1) < commandList.Length)
9433 { 10156 {
9434 if (commandList.Data[i + 1] is LSL_String) 10157 if (commandList.Data[i + 1] is LSL_String)
@@ -9441,7 +10164,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 } 10164 }
9442 break; 10165 break;
9443 10166
9444 case ParcelMediaCommandEnum.Texture: 10167 case (uint)ParcelMediaCommandEnum.Texture:
9445 if ((i + 1) < commandList.Length) 10168 if ((i + 1) < commandList.Length)
9446 { 10169 {
9447 if (commandList.Data[i + 1] is LSL_String) 10170 if (commandList.Data[i + 1] is LSL_String)
@@ -9454,7 +10177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9454 } 10177 }
9455 break; 10178 break;
9456 10179
9457 case ParcelMediaCommandEnum.Time: 10180 case (uint)ParcelMediaCommandEnum.Time:
9458 if ((i + 1) < commandList.Length) 10181 if ((i + 1) < commandList.Length)
9459 { 10182 {
9460 if (commandList.Data[i + 1] is LSL_Float) 10183 if (commandList.Data[i + 1] is LSL_Float)
@@ -9466,7 +10189,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9466 } 10189 }
9467 break; 10190 break;
9468 10191
9469 case ParcelMediaCommandEnum.AutoAlign: 10192 case (uint)ParcelMediaCommandEnum.AutoAlign:
9470 if ((i + 1) < commandList.Length) 10193 if ((i + 1) < commandList.Length)
9471 { 10194 {
9472 if (commandList.Data[i + 1] is LSL_Integer) 10195 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9480,7 +10203,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 } 10203 }
9481 break; 10204 break;
9482 10205
9483 case ParcelMediaCommandEnum.Type: 10206 case (uint)ParcelMediaCommandEnum.Type:
9484 if ((i + 1) < commandList.Length) 10207 if ((i + 1) < commandList.Length)
9485 { 10208 {
9486 if (commandList.Data[i + 1] is LSL_String) 10209 if (commandList.Data[i + 1] is LSL_String)
@@ -9493,7 +10216,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9493 } 10216 }
9494 break; 10217 break;
9495 10218
9496 case ParcelMediaCommandEnum.Desc: 10219 case (uint)ParcelMediaCommandEnum.Desc:
9497 if ((i + 1) < commandList.Length) 10220 if ((i + 1) < commandList.Length)
9498 { 10221 {
9499 if (commandList.Data[i + 1] is LSL_String) 10222 if (commandList.Data[i + 1] is LSL_String)
@@ -9506,7 +10229,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9506 } 10229 }
9507 break; 10230 break;
9508 10231
9509 case ParcelMediaCommandEnum.Size: 10232 case (uint)ParcelMediaCommandEnum.Size:
9510 if ((i + 2) < commandList.Length) 10233 if ((i + 2) < commandList.Length)
9511 { 10234 {
9512 if (commandList.Data[i + 1] is LSL_Integer) 10235 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9576,7 +10299,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9576 } 10299 }
9577 } 10300 }
9578 10301
9579 if (commandToSend != null) 10302 if (commandToSend != 0)
9580 { 10303 {
9581 // the commandList contained a start/stop/... command, too 10304 // the commandList contained a start/stop/... command, too
9582 if (presence == null) 10305 if (presence == null)
@@ -9613,7 +10336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9613 10336
9614 if (aList.Data[i] != null) 10337 if (aList.Data[i] != null)
9615 { 10338 {
9616 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10339 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9617 { 10340 {
9618 case ParcelMediaCommandEnum.Url: 10341 case ParcelMediaCommandEnum.Url:
9619 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10342 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9656,16 +10379,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 { 10379 {
9657 m_host.AddScriptLPS(1); 10380 m_host.AddScriptLPS(1);
9658 10381
9659 lock (m_host.TaskInventory) 10382 m_host.TaskInventory.LockItemsForRead(true);
10383 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9660 { 10384 {
9661 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10385 if (inv.Value.Name == name)
9662 { 10386 {
9663 if (inv.Value.Name == name) 10387 m_host.TaskInventory.LockItemsForRead(false);
9664 { 10388 return inv.Value.Type;
9665 return inv.Value.Type;
9666 }
9667 } 10389 }
9668 } 10390 }
10391 m_host.TaskInventory.LockItemsForRead(false);
9669 10392
9670 return -1; 10393 return -1;
9671 } 10394 }
@@ -9676,15 +10399,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9676 10399
9677 if (quick_pay_buttons.Data.Length < 4) 10400 if (quick_pay_buttons.Data.Length < 4)
9678 { 10401 {
9679 LSLError("List must have at least 4 elements"); 10402 int x;
9680 return; 10403 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10404 {
10405 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10406 }
9681 } 10407 }
9682 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10408 int[] nPrice = new int[5];
9683 10409 nPrice[0] = price;
9684 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10410 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9685 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10411 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9686 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10412 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9687 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10413 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10414 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9688 m_host.ParentGroup.HasGroupChanged = true; 10415 m_host.ParentGroup.HasGroupChanged = true;
9689 } 10416 }
9690 10417
@@ -9696,17 +10423,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9696 if (invItemID == UUID.Zero) 10423 if (invItemID == UUID.Zero)
9697 return new LSL_Vector(); 10424 return new LSL_Vector();
9698 10425
9699 lock (m_host.TaskInventory) 10426 m_host.TaskInventory.LockItemsForRead(true);
10427 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9700 { 10428 {
9701 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10429 m_host.TaskInventory.LockItemsForRead(false);
9702 return new LSL_Vector(); 10430 return new LSL_Vector();
10431 }
9703 10432
9704 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10433 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9705 { 10434 {
9706 ShoutError("No permissions to track the camera"); 10435 ShoutError("No permissions to track the camera");
9707 return new LSL_Vector(); 10436 m_host.TaskInventory.LockItemsForRead(false);
9708 } 10437 return new LSL_Vector();
9709 } 10438 }
10439 m_host.TaskInventory.LockItemsForRead(false);
9710 10440
9711 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10441 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9712 if (presence != null) 10442 if (presence != null)
@@ -9724,17 +10454,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9724 if (invItemID == UUID.Zero) 10454 if (invItemID == UUID.Zero)
9725 return new LSL_Rotation(); 10455 return new LSL_Rotation();
9726 10456
9727 lock (m_host.TaskInventory) 10457 m_host.TaskInventory.LockItemsForRead(true);
10458 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9728 { 10459 {
9729 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10460 m_host.TaskInventory.LockItemsForRead(false);
9730 return new LSL_Rotation(); 10461 return new LSL_Rotation();
9731 10462 }
9732 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10463 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9733 { 10464 {
9734 ShoutError("No permissions to track the camera"); 10465 ShoutError("No permissions to track the camera");
9735 return new LSL_Rotation(); 10466 m_host.TaskInventory.LockItemsForRead(false);
9736 } 10467 return new LSL_Rotation();
9737 } 10468 }
10469 m_host.TaskInventory.LockItemsForRead(false);
9738 10470
9739 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10471 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9740 if (presence != null) 10472 if (presence != null)
@@ -9796,8 +10528,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9796 { 10528 {
9797 m_host.AddScriptLPS(1); 10529 m_host.AddScriptLPS(1);
9798 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10530 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9799 if (detectedParams == null) return; // only works on the first detected avatar 10531 if (detectedParams == null)
9800 10532 {
10533 if (m_host.ParentGroup.IsAttachment == true)
10534 {
10535 detectedParams = new DetectParams();
10536 detectedParams.Key = m_host.OwnerID;
10537 }
10538 else
10539 {
10540 return;
10541 }
10542 }
10543
9801 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10544 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9802 if (avatar != null) 10545 if (avatar != null)
9803 { 10546 {
@@ -9805,6 +10548,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9805 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10548 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9806 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10549 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9807 } 10550 }
10551
9808 ScriptSleep(1000); 10552 ScriptSleep(1000);
9809 } 10553 }
9810 10554
@@ -9916,14 +10660,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9916 if (objectID == UUID.Zero) return; 10660 if (objectID == UUID.Zero) return;
9917 10661
9918 UUID agentID; 10662 UUID agentID;
9919 lock (m_host.TaskInventory) 10663 m_host.TaskInventory.LockItemsForRead(true);
9920 { 10664 // we need the permission first, to know which avatar we want to set the camera for
9921 // we need the permission first, to know which avatar we want to set the camera for 10665 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9922 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9923 10666
9924 if (agentID == UUID.Zero) return; 10667 if (agentID == UUID.Zero)
9925 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10668 {
10669 m_host.TaskInventory.LockItemsForRead(false);
10670 return;
10671 }
10672 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10673 {
10674 m_host.TaskInventory.LockItemsForRead(false);
10675 return;
9926 } 10676 }
10677 m_host.TaskInventory.LockItemsForRead(false);
9927 10678
9928 ScenePresence presence = World.GetScenePresence(agentID); 10679 ScenePresence presence = World.GetScenePresence(agentID);
9929 10680
@@ -9932,12 +10683,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9932 10683
9933 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10684 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9934 object[] data = rules.Data; 10685 object[] data = rules.Data;
9935 for (int i = 0; i < data.Length; ++i) { 10686 for (int i = 0; i < data.Length; ++i)
10687 {
9936 int type = Convert.ToInt32(data[i++].ToString()); 10688 int type = Convert.ToInt32(data[i++].ToString());
9937 if (i >= data.Length) break; // odd number of entries => ignore the last 10689 if (i >= data.Length) break; // odd number of entries => ignore the last
9938 10690
9939 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10691 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9940 switch (type) { 10692 switch (type)
10693 {
9941 case ScriptBaseClass.CAMERA_FOCUS: 10694 case ScriptBaseClass.CAMERA_FOCUS:
9942 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10695 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9943 case ScriptBaseClass.CAMERA_POSITION: 10696 case ScriptBaseClass.CAMERA_POSITION:
@@ -9973,12 +10726,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9973 10726
9974 // we need the permission first, to know which avatar we want to clear the camera for 10727 // we need the permission first, to know which avatar we want to clear the camera for
9975 UUID agentID; 10728 UUID agentID;
9976 lock (m_host.TaskInventory) 10729 m_host.TaskInventory.LockItemsForRead(true);
10730 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10731 if (agentID == UUID.Zero)
9977 { 10732 {
9978 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10733 m_host.TaskInventory.LockItemsForRead(false);
9979 if (agentID == UUID.Zero) return; 10734 return;
9980 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9981 } 10735 }
10736 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10737 {
10738 m_host.TaskInventory.LockItemsForRead(false);
10739 return;
10740 }
10741 m_host.TaskInventory.LockItemsForRead(false);
9982 10742
9983 ScenePresence presence = World.GetScenePresence(agentID); 10743 ScenePresence presence = World.GetScenePresence(agentID);
9984 10744
@@ -10045,19 +10805,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10045 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10805 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10046 { 10806 {
10047 m_host.AddScriptLPS(1); 10807 m_host.AddScriptLPS(1);
10048 string ret = String.Empty; 10808
10049 string src1 = llBase64ToString(str1); 10809 if (str1 == String.Empty)
10050 string src2 = llBase64ToString(str2); 10810 return String.Empty;
10051 int c = 0; 10811 if (str2 == String.Empty)
10052 for (int i = 0; i < src1.Length; i++) 10812 return str1;
10813
10814 int len = str2.Length;
10815 if ((len % 4) != 0) // LL is EVIL!!!!
10053 { 10816 {
10054 ret += (char) (src1[i] ^ src2[c]); 10817 while (str2.EndsWith("="))
10818 str2 = str2.Substring(0, str2.Length - 1);
10055 10819
10056 c++; 10820 len = str2.Length;
10057 if (c >= src2.Length) 10821 int mod = len % 4;
10058 c = 0; 10822
10823 if (mod == 1)
10824 str2 = str2.Substring(0, str2.Length - 1);
10825 else if (mod == 2)
10826 str2 += "==";
10827 else if (mod == 3)
10828 str2 += "=";
10059 } 10829 }
10060 return llStringToBase64(ret); 10830
10831 byte[] data1;
10832 byte[] data2;
10833 try
10834 {
10835 data1 = Convert.FromBase64String(str1);
10836 data2 = Convert.FromBase64String(str2);
10837 }
10838 catch (Exception)
10839 {
10840 return new LSL_String(String.Empty);
10841 }
10842
10843 byte[] d2 = new Byte[data1.Length];
10844 int pos = 0;
10845
10846 if (data1.Length <= data2.Length)
10847 {
10848 Array.Copy(data2, 0, d2, 0, data1.Length);
10849 }
10850 else
10851 {
10852 while (pos < data1.Length)
10853 {
10854 len = data1.Length - pos;
10855 if (len > data2.Length)
10856 len = data2.Length;
10857
10858 Array.Copy(data2, 0, d2, pos, len);
10859 pos += len;
10860 }
10861 }
10862
10863 for (pos = 0 ; pos < data1.Length ; pos++ )
10864 data1[pos] ^= d2[pos];
10865
10866 return Convert.ToBase64String(data1);
10061 } 10867 }
10062 10868
10063 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10869 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10114,12 +10920,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10114 Regex r = new Regex(authregex); 10920 Regex r = new Regex(authregex);
10115 int[] gnums = r.GetGroupNumbers(); 10921 int[] gnums = r.GetGroupNumbers();
10116 Match m = r.Match(url); 10922 Match m = r.Match(url);
10117 if (m.Success) { 10923 if (m.Success)
10118 for (int i = 1; i < gnums.Length; i++) { 10924 {
10925 for (int i = 1; i < gnums.Length; i++)
10926 {
10119 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10927 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10120 //CaptureCollection cc = g.Captures; 10928 //CaptureCollection cc = g.Captures;
10121 } 10929 }
10122 if (m.Groups.Count == 5) { 10930 if (m.Groups.Count == 5)
10931 {
10123 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10932 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10124 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10933 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10125 } 10934 }
@@ -10483,15 +11292,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10483 11292
10484 internal UUID ScriptByName(string name) 11293 internal UUID ScriptByName(string name)
10485 { 11294 {
10486 lock (m_host.TaskInventory) 11295 m_host.TaskInventory.LockItemsForRead(true);
11296
11297 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10487 { 11298 {
10488 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11299 if (item.Type == 10 && item.Name == name)
10489 { 11300 {
10490 if (item.Type == 10 && item.Name == name) 11301 m_host.TaskInventory.LockItemsForRead(false);
10491 return item.ItemID; 11302 return item.ItemID;
10492 } 11303 }
10493 } 11304 }
10494 11305
11306 m_host.TaskInventory.LockItemsForRead(false);
11307
10495 return UUID.Zero; 11308 return UUID.Zero;
10496 } 11309 }
10497 11310
@@ -10532,6 +11345,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10532 { 11345 {
10533 m_host.AddScriptLPS(1); 11346 m_host.AddScriptLPS(1);
10534 11347
11348 //Clone is thread safe
10535 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11349 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10536 11350
10537 UUID assetID = UUID.Zero; 11351 UUID assetID = UUID.Zero;
@@ -10594,6 +11408,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10594 { 11408 {
10595 m_host.AddScriptLPS(1); 11409 m_host.AddScriptLPS(1);
10596 11410
11411 //Clone is thread safe
10597 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11412 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10598 11413
10599 UUID assetID = UUID.Zero; 11414 UUID assetID = UUID.Zero;
@@ -10674,15 +11489,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10674 return GetLinkPrimitiveParams(obj, rules); 11489 return GetLinkPrimitiveParams(obj, rules);
10675 } 11490 }
10676 11491
10677 public void print(string str) 11492 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10678 { 11493 {
10679 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11494 List<SceneObjectPart> parts = GetLinkParts(link);
10680 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11495 if (parts.Count < 1)
10681 if (ossl != null) 11496 return 0;
10682 { 11497
10683 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11498 return GetNumberOfSides(parts[0]);
10684 m_log.Info("LSL print():" + str);
10685 }
10686 } 11499 }
10687 11500
10688 private string Name2Username(string name) 11501 private string Name2Username(string name)
@@ -10728,155 +11541,397 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10728 return rq.ToString(); 11541 return rq.ToString();
10729 } 11542 }
10730 11543
11544 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11545 {
11546 m_SayShoutCount = 0;
11547 }
11548
11549 private struct Tri
11550 {
11551 public Vector3 p1;
11552 public Vector3 p2;
11553 public Vector3 p3;
11554 }
11555
11556 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11557 {
11558 float height = avatar.Appearance.AvatarHeight;
11559 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11560 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11561
11562 if (point.X > b1.X && point.X < b2.X &&
11563 point.Y > b1.Y && point.Y < b2.Y &&
11564 point.Z > b1.Z && point.Z < b2.Z)
11565 return true;
11566 return false;
11567 }
11568
11569 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11570 {
11571 List<ContactResult> contacts = new List<ContactResult>();
11572
11573 Vector3 ab = rayEnd - rayStart;
11574
11575 World.ForEachScenePresence(delegate(ScenePresence sp)
11576 {
11577 Vector3 ac = sp.AbsolutePosition - rayStart;
11578 Vector3 bc = sp.AbsolutePosition - rayEnd;
11579
11580 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11581
11582 if (d > 1.5)
11583 return;
11584
11585 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11586
11587 if (d2 > 0)
11588 return;
11589
11590 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11591 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11592
11593 if (!InBoundingBox(sp, p))
11594 return;
11595
11596 ContactResult result = new ContactResult ();
11597 result.ConsumerID = sp.LocalId;
11598 result.Depth = Vector3.Distance(rayStart, p);
11599 result.Normal = Vector3.Zero;
11600 result.Pos = p;
11601
11602 contacts.Add(result);
11603 });
11604
11605 return contacts.ToArray();
11606 }
11607
11608 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11609 {
11610 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11611 List<ContactResult> contacts = new List<ContactResult>();
11612
11613 Vector3 ab = rayEnd - rayStart;
11614
11615 World.ForEachSOG(delegate(SceneObjectGroup group)
11616 {
11617 if (m_host.ParentGroup == group)
11618 return;
11619
11620 if (group.IsAttachment)
11621 return;
11622
11623 if (group.RootPart.PhysActor == null)
11624 {
11625 if (!includePhantom)
11626 return;
11627 }
11628 else
11629 {
11630 if (group.RootPart.PhysActor.IsPhysical)
11631 {
11632 if (!includePhysical)
11633 return;
11634 }
11635 else
11636 {
11637 if (!includeNonPhysical)
11638 return;
11639 }
11640 }
11641
11642 // Find the radius ouside of which we don't even need to hit test
11643 float minX;
11644 float maxX;
11645 float minY;
11646 float maxY;
11647 float minZ;
11648 float maxZ;
11649
11650 float radius = 0.0f;
11651
11652 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11653
11654 if (Math.Abs(minX) > radius)
11655 radius = Math.Abs(minX);
11656 if (Math.Abs(minY) > radius)
11657 radius = Math.Abs(minY);
11658 if (Math.Abs(minZ) > radius)
11659 radius = Math.Abs(minZ);
11660 if (Math.Abs(maxX) > radius)
11661 radius = Math.Abs(maxX);
11662 if (Math.Abs(maxY) > radius)
11663 radius = Math.Abs(maxY);
11664 if (Math.Abs(maxZ) > radius)
11665 radius = Math.Abs(maxZ);
11666
11667 Vector3 ac = group.AbsolutePosition - rayStart;
11668 Vector3 bc = group.AbsolutePosition - rayEnd;
11669
11670 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11671
11672 // Too far off ray, don't bother
11673 if (d > radius)
11674 return;
11675
11676 // Behind ray, drop
11677 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11678 if (d2 > 0)
11679 return;
11680
11681 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11682 // Miss.
11683 if (!intersection.HitTF)
11684 return;
11685
11686 ContactResult result = new ContactResult ();
11687 result.ConsumerID = group.LocalId;
11688 result.Depth = intersection.distance;
11689 result.Normal = intersection.normal;
11690 result.Pos = intersection.ipoint;
11691
11692 contacts.Add(result);
11693 });
11694
11695 return contacts.ToArray();
11696 }
11697
11698 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11699 {
11700 double[,] heightfield = World.Heightmap.GetDoubles();
11701 List<ContactResult> contacts = new List<ContactResult>();
11702
11703 double min = 2048.0;
11704 double max = 0.0;
11705
11706 // Find the min and max of the heightfield
11707 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11708 {
11709 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11710 {
11711 if (heightfield[x, y] > max)
11712 max = heightfield[x, y];
11713 if (heightfield[x, y] < min)
11714 min = heightfield[x, y];
11715 }
11716 }
11717
11718
11719 // A ray extends past rayEnd, but doesn't go back before
11720 // rayStart. If the start is above the highest point of the ground
11721 // and the ray goes up, we can't hit the ground. Ever.
11722 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11723 return null;
11724
11725 // Same for going down
11726 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11727 return null;
11728
11729 List<Tri> trilist = new List<Tri>();
11730
11731 // Create our triangle list
11732 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11733 {
11734 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11735 {
11736 Tri t1 = new Tri();
11737 Tri t2 = new Tri();
11738
11739 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11740 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11741 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11742 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11743
11744 t1.p1 = p1;
11745 t1.p2 = p2;
11746 t1.p3 = p3;
11747
11748 t2.p1 = p3;
11749 t2.p2 = p4;
11750 t2.p3 = p1;
11751
11752 trilist.Add(t1);
11753 trilist.Add(t2);
11754 }
11755 }
11756
11757 // Ray direction
11758 Vector3 rayDirection = rayEnd - rayStart;
11759
11760 foreach (Tri t in trilist)
11761 {
11762 // Compute triangle plane normal and edges
11763 Vector3 u = t.p2 - t.p1;
11764 Vector3 v = t.p3 - t.p1;
11765 Vector3 n = Vector3.Cross(u, v);
11766
11767 if (n == Vector3.Zero)
11768 continue;
11769
11770 Vector3 w0 = rayStart - t.p1;
11771 double a = -Vector3.Dot(n, w0);
11772 double b = Vector3.Dot(n, rayDirection);
11773
11774 // Not intersecting the plane, or in plane (same thing)
11775 // Ignoring this MAY cause the ground to not be detected
11776 // sometimes
11777 if (Math.Abs(b) < 0.000001)
11778 continue;
11779
11780 double r = a / b;
11781
11782 // ray points away from plane
11783 if (r < 0.0)
11784 continue;
11785
11786 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11787
11788 float uu = Vector3.Dot(u, u);
11789 float uv = Vector3.Dot(u, v);
11790 float vv = Vector3.Dot(v, v);
11791 Vector3 w = ip - t.p1;
11792 float wu = Vector3.Dot(w, u);
11793 float wv = Vector3.Dot(w, v);
11794 float d = uv * uv - uu * vv;
11795
11796 float cs = (uv * wv - vv * wu) / d;
11797 if (cs < 0 || cs > 1.0)
11798 continue;
11799 float ct = (uv * wu - uu * wv) / d;
11800 if (ct < 0 || (cs + ct) > 1.0)
11801 continue;
11802
11803 // Add contact point
11804 ContactResult result = new ContactResult ();
11805 result.ConsumerID = 0;
11806 result.Depth = Vector3.Distance(rayStart, ip);
11807 result.Normal = n;
11808 result.Pos = ip;
11809
11810 contacts.Add(result);
11811 }
11812
11813 if (contacts.Count == 0)
11814 return null;
11815
11816 contacts.Sort(delegate(ContactResult a, ContactResult b)
11817 {
11818 return (int)(a.Depth - b.Depth);
11819 });
11820
11821 return contacts[0];
11822 }
11823
10731 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11824 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10732 { 11825 {
11826 LSL_List list = new LSL_List();
11827
10733 m_host.AddScriptLPS(1); 11828 m_host.AddScriptLPS(1);
10734 11829
10735 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11830 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10736 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11831 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10737 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11832 Vector3 dir = rayEnd - rayStart;
10738 11833
10739 int count = 0; 11834 float dist = Vector3.Mag(dir);
10740// int detectPhantom = 0; 11835
11836 int count = 1;
11837 bool detectPhantom = false;
10741 int dataFlags = 0; 11838 int dataFlags = 0;
10742 int rejectTypes = 0; 11839 int rejectTypes = 0;
10743 11840
10744 for (int i = 0; i < options.Length; i += 2) 11841 for (int i = 0; i < options.Length; i += 2)
10745 { 11842 {
10746 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11843 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10747 {
10748 count = options.GetLSLIntegerItem(i + 1); 11844 count = options.GetLSLIntegerItem(i + 1);
10749 } 11845 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10750// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11846 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10751// {
10752// detectPhantom = options.GetLSLIntegerItem(i + 1);
10753// }
10754 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11847 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10755 {
10756 dataFlags = options.GetLSLIntegerItem(i + 1); 11848 dataFlags = options.GetLSLIntegerItem(i + 1);
10757 }
10758 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11849 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10759 {
10760 rejectTypes = options.GetLSLIntegerItem(i + 1); 11850 rejectTypes = options.GetLSLIntegerItem(i + 1);
10761 }
10762 } 11851 }
10763 11852
10764 LSL_List list = new LSL_List(); 11853 if (count > 16)
10765 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11854 count = 16;
10766
10767 double distance = Util.GetDistanceTo(startvector, endvector);
10768 11855
10769 if (distance == 0) 11856 List<ContactResult> results = new List<ContactResult>();
10770 distance = 0.001;
10771
10772 Vector3 posToCheck = startvector;
10773 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10774 11857
10775 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11858 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10776 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11859 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10777 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11860 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10778 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11861 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10779 11862
10780 for (float i = 0; i <= distance; i += 0.1f) 11863 if (checkTerrain)
10781 { 11864 {
10782 posToCheck = startvector + (dir * (i / (float)distance)); 11865 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11866 if (groundContact != null)
11867 results.Add((ContactResult)groundContact);
11868 }
10783 11869
10784 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11870 if (checkAgents)
10785 { 11871 {
10786 ContactResult result = new ContactResult(); 11872 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10787 result.ConsumerID = 0; 11873 foreach (ContactResult r in agentHits)
10788 result.Depth = 0; 11874 results.Add(r);
10789 result.Normal = Vector3.Zero; 11875 }
10790 result.Pos = posToCheck;
10791 results.Add(result);
10792 checkTerrain = false;
10793 }
10794 11876
10795 if (checkAgents) 11877 if (checkPhysical || checkNonPhysical)
10796 { 11878 {
10797 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11879 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10798 { 11880 foreach (ContactResult r in objectHits)
10799 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11881 results.Add(r);
10800 {
10801 ContactResult result = new ContactResult ();
10802 result.ConsumerID = sp.LocalId;
10803 result.Depth = 0;
10804 result.Normal = Vector3.Zero;
10805 result.Pos = posToCheck;
10806 results.Add(result);
10807 }
10808 });
10809 }
10810 } 11882 }
10811 11883
10812 int refcount = 0; 11884 results.Sort(delegate(ContactResult a, ContactResult b)
11885 {
11886 return (int)(a.Depth - b.Depth);
11887 });
11888
11889 int values = 0;
10813 foreach (ContactResult result in results) 11890 foreach (ContactResult result in results)
10814 { 11891 {
10815 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11892 if (result.Depth > dist)
10816 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10817 continue; 11893 continue;
10818 11894
10819 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11895 UUID itemID = UUID.Zero;
11896 int linkNum = 0;
10820 11897
10821 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11898 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
10822 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11899 // It's a prim!
10823 11900 if (part != null)
10824 if (entity == null)
10825 { 11901 {
10826 list.Add(UUID.Zero); 11902 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10827 11903 itemID = part.ParentGroup.UUID;
10828 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11904 else
10829 list.Add(0); 11905 itemID = part.UUID;
10830
10831 list.Add(result.Pos);
10832
10833 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10834 list.Add(result.Normal);
10835 11906
10836 continue; //Can't find it, so add UUID.Zero 11907 linkNum = part.LinkNum;
10837 } 11908 }
10838 11909 else
10839 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10840 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10841 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10842
10843 if (entity is SceneObjectPart)
10844 { 11910 {
10845 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 11911 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10846 11912 /// It it a boy? a girl?
10847 if (pa != null && pa.IsPhysical) 11913 if (sp != null)
10848 { 11914 itemID = sp.UUID;
10849 if (!checkPhysical)
10850 continue;
10851 }
10852 else
10853 {
10854 if (!checkNonPhysical)
10855 continue;
10856 }
10857 } 11915 }
10858 11916
10859 refcount++; 11917 list.Add(new LSL_String(itemID.ToString()));
10860 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11918 list.Add(new LSL_String(result.Pos.ToString()));
10861 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10862 else
10863 list.Add(entity.UUID);
10864 11919
10865 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11920 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10866 { 11921 list.Add(new LSL_Integer(linkNum));
10867 if (entity is SceneObjectPart)
10868 list.Add(((SceneObjectPart)entity).LinkNum);
10869 else
10870 list.Add(0);
10871 }
10872 11922
10873 list.Add(result.Pos);
10874 11923
10875 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11924 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10876 list.Add(result.Normal); 11925 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11926
11927 values++;
11928 count--;
11929
11930 if (count == 0)
11931 break;
10877 } 11932 }
10878 11933
10879 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11934 list.Add(new LSL_Integer(values));
10880 11935
10881 return list; 11936 return list;
10882 } 11937 }
@@ -10916,7 +11971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10916 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11971 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10917 if (!isAccount) return 0; 11972 if (!isAccount) return 0;
10918 if (estate.HasAccess(id)) return 1; 11973 if (estate.HasAccess(id)) return 1;
10919 if (estate.IsBanned(id)) 11974 if (estate.IsBanned(id, World.GetUserFlags(id)))
10920 estate.RemoveBan(id); 11975 estate.RemoveBan(id);
10921 estate.AddEstateUser(id); 11976 estate.AddEstateUser(id);
10922 break; 11977 break;
@@ -10935,14 +11990,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10935 break; 11990 break;
10936 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11991 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10937 if (!isAccount) return 0; 11992 if (!isAccount) return 0;
10938 if (estate.IsBanned(id)) return 1; 11993 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10939 EstateBan ban = new EstateBan(); 11994 EstateBan ban = new EstateBan();
10940 ban.EstateID = estate.EstateID; 11995 ban.EstateID = estate.EstateID;
10941 ban.BannedUserID = id; 11996 ban.BannedUserID = id;
10942 estate.AddBan(ban); 11997 estate.AddBan(ban);
10943 break; 11998 break;
10944 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11999 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10945 if (!isAccount || !estate.IsBanned(id)) return 0; 12000 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10946 estate.RemoveBan(id); 12001 estate.RemoveBan(id);
10947 break; 12002 break;
10948 default: return 0; 12003 default: return 0;
@@ -10968,22 +12023,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10968 NotImplemented("llGetSPMaxMemory"); 12023 NotImplemented("llGetSPMaxMemory");
10969 } 12024 }
10970 12025
10971 public void llGetUsedMemory() 12026 public virtual LSL_Integer llGetUsedMemory()
10972 { 12027 {
10973 m_host.AddScriptLPS(1); 12028 m_host.AddScriptLPS(1);
10974 NotImplemented("llGetUsedMemory"); 12029 NotImplemented("llGetUsedMemory");
12030 return 0;
10975 } 12031 }
10976 12032
10977 public void llScriptProfiler(LSL_Integer flags) 12033 public void llScriptProfiler(LSL_Integer flags)
10978 { 12034 {
10979 m_host.AddScriptLPS(1); 12035 m_host.AddScriptLPS(1);
10980 NotImplemented("llScriptProfiler"); 12036 //NotImplemented("llScriptProfiler");
10981 } 12037 }
10982 12038
10983 public void llSetSoundQueueing(int queue) 12039 public void llSetSoundQueueing(int queue)
10984 { 12040 {
10985 m_host.AddScriptLPS(1); 12041 m_host.AddScriptLPS(1);
10986 NotImplemented("llSetSoundQueueing");
10987 } 12042 }
10988 12043
10989 public void llCollisionSprite(string impact_sprite) 12044 public void llCollisionSprite(string impact_sprite)
@@ -10995,10 +12050,274 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10995 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12050 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10996 { 12051 {
10997 m_host.AddScriptLPS(1); 12052 m_host.AddScriptLPS(1);
10998 NotImplemented("llGodLikeRezObject"); 12053
12054 if (!World.Permissions.IsGod(m_host.OwnerID))
12055 NotImplemented("llGodLikeRezObject");
12056
12057 AssetBase rezAsset = World.AssetService.Get(inventory);
12058 if (rezAsset == null)
12059 {
12060 llSay(0, "Asset not found");
12061 return;
12062 }
12063
12064 SceneObjectGroup group = null;
12065
12066 try
12067 {
12068 string xmlData = Utils.BytesToString(rezAsset.Data);
12069 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12070 }
12071 catch
12072 {
12073 llSay(0, "Asset not found");
12074 return;
12075 }
12076
12077 if (group == null)
12078 {
12079 llSay(0, "Asset not found");
12080 return;
12081 }
12082
12083 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12084 group.RootPart.AttachOffset = group.AbsolutePosition;
12085
12086 group.ResetIDs();
12087
12088 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12089 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12090 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12091 group.ScheduleGroupForFullUpdate();
12092
12093 // objects rezzed with this method are die_at_edge by default.
12094 group.RootPart.SetDieAtEdge(true);
12095
12096 group.ResumeScripts();
12097
12098 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12099 "object_rez", new Object[] {
12100 new LSL_String(
12101 group.RootPart.UUID.ToString()) },
12102 new DetectParams[0]));
12103 }
12104
12105 public LSL_String llTransferLindenDollars(string destination, int amount)
12106 {
12107 UUID txn = UUID.Random();
12108
12109 Util.FireAndForget(delegate(object x)
12110 {
12111 int replycode = 0;
12112 string replydata = destination + "," + amount.ToString();
12113
12114 try
12115 {
12116 UUID invItemID=InventorySelf();
12117 if (invItemID == UUID.Zero)
12118 {
12119 replydata = "SERVICE_ERROR";
12120 return;
12121 }
12122
12123 m_host.AddScriptLPS(1);
12124
12125 m_host.TaskInventory.LockItemsForRead(true);
12126 TaskInventoryItem item = m_host.TaskInventory[invItemID];
12127 m_host.TaskInventory.LockItemsForRead(false);
12128
12129 if (item.PermsGranter == UUID.Zero)
12130 {
12131 replydata = "MISSING_PERMISSION_DEBIT";
12132 return;
12133 }
12134
12135 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12136 {
12137 replydata = "MISSING_PERMISSION_DEBIT";
12138 return;
12139 }
12140
12141 UUID toID = new UUID();
12142
12143 if (!UUID.TryParse(destination, out toID))
12144 {
12145 replydata = "INVALID_AGENT";
12146 return;
12147 }
12148
12149 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12150
12151 if (money == null)
12152 {
12153 replydata = "TRANSFERS_DISABLED";
12154 return;
12155 }
12156
12157 bool result = money.ObjectGiveMoney(
12158 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12159
12160 if (result)
12161 {
12162 replycode = 1;
12163 return;
12164 }
12165
12166 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12167 }
12168 finally
12169 {
12170 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12171 "transaction_result", new Object[] {
12172 new LSL_String(txn.ToString()),
12173 new LSL_Integer(replycode),
12174 new LSL_String(replydata) },
12175 new DetectParams[0]));
12176 }
12177 });
12178
12179 return txn.ToString();
10999 } 12180 }
11000 12181
11001 #endregion 12182 #endregion
12183
12184 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12185 {
12186 SceneObjectGroup group = m_host.ParentGroup;
12187
12188 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12189 return;
12190 if (group.IsAttachment)
12191 return;
12192
12193 if (frames.Data.Length > 0) // We are getting a new motion
12194 {
12195 if (group.RootPart.KeyframeMotion != null)
12196 group.RootPart.KeyframeMotion.Stop();
12197 group.RootPart.KeyframeMotion = null;
12198
12199 int idx = 0;
12200
12201 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12202 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12203
12204 while (idx < options.Data.Length)
12205 {
12206 int option = (int)options.GetLSLIntegerItem(idx++);
12207 int remain = options.Data.Length - idx;
12208
12209 switch (option)
12210 {
12211 case ScriptBaseClass.KFM_MODE:
12212 if (remain < 1)
12213 break;
12214 int modeval = (int)options.GetLSLIntegerItem(idx++);
12215 switch(modeval)
12216 {
12217 case ScriptBaseClass.KFM_FORWARD:
12218 mode = KeyframeMotion.PlayMode.Forward;
12219 break;
12220 case ScriptBaseClass.KFM_REVERSE:
12221 mode = KeyframeMotion.PlayMode.Reverse;
12222 break;
12223 case ScriptBaseClass.KFM_LOOP:
12224 mode = KeyframeMotion.PlayMode.Loop;
12225 break;
12226 case ScriptBaseClass.KFM_PING_PONG:
12227 mode = KeyframeMotion.PlayMode.PingPong;
12228 break;
12229 }
12230 break;
12231 case ScriptBaseClass.KFM_DATA:
12232 if (remain < 1)
12233 break;
12234 int dataval = (int)options.GetLSLIntegerItem(idx++);
12235 data = (KeyframeMotion.DataFormat)dataval;
12236 break;
12237 }
12238 }
12239
12240 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12241
12242 idx = 0;
12243
12244 int elemLength = 2;
12245 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12246 elemLength = 3;
12247
12248 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12249 while (idx < frames.Data.Length)
12250 {
12251 int remain = frames.Data.Length - idx;
12252
12253 if (remain < elemLength)
12254 break;
12255
12256 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12257 frame.Position = null;
12258 frame.Rotation = null;
12259
12260 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12261 {
12262 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12263 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12264 }
12265 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12266 {
12267 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12268 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12269 }
12270
12271 float tempf = (float)frames.GetLSLFloatItem(idx++);
12272 frame.TimeMS = (int)(tempf * 1000.0f);
12273
12274 keyframes.Add(frame);
12275 }
12276
12277 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12278 group.RootPart.KeyframeMotion.Start();
12279 }
12280 else
12281 {
12282 if (group.RootPart.KeyframeMotion == null)
12283 return;
12284
12285 if (options.Data.Length == 0)
12286 {
12287 group.RootPart.KeyframeMotion.Stop();
12288 return;
12289 }
12290
12291 int code = (int)options.GetLSLIntegerItem(0);
12292
12293 int idx = 0;
12294
12295 while (idx < options.Data.Length)
12296 {
12297 int option = (int)options.GetLSLIntegerItem(idx++);
12298 int remain = options.Data.Length - idx;
12299
12300 switch (option)
12301 {
12302 case ScriptBaseClass.KFM_COMMAND:
12303 int cmd = (int)options.GetLSLIntegerItem(idx++);
12304 switch (cmd)
12305 {
12306 case ScriptBaseClass.KFM_CMD_PLAY:
12307 group.RootPart.KeyframeMotion.Start();
12308 break;
12309 case ScriptBaseClass.KFM_CMD_STOP:
12310 group.RootPart.KeyframeMotion.Stop();
12311 break;
12312 case ScriptBaseClass.KFM_CMD_PAUSE:
12313 group.RootPart.KeyframeMotion.Pause();
12314 break;
12315 }
12316 break;
12317 }
12318 }
12319 }
12320 }
11002 } 12321 }
11003 12322
11004 public class NotecardCache 12323 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 339166b..2899774 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)
@@ -3105,4 +3151,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3105 } 3151 }
3106 } 3152 }
3107 } 3153 }
3108} \ No newline at end of file 3154}
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 545bbee..2fcc443 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 f58f9d6..6246b57 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;
@@ -578,6 +580,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
578 public const int PRIM_MEDIA_PERM_OWNER = 1; 580 public const int PRIM_MEDIA_PERM_OWNER = 1;
579 public const int PRIM_MEDIA_PERM_GROUP = 2; 581 public const int PRIM_MEDIA_PERM_GROUP = 2;
580 public const int PRIM_MEDIA_PERM_ANYONE = 4; 582 public const int PRIM_MEDIA_PERM_ANYONE = 4;
583
584 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
585 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
586 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
587 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
588
589 public const int PRIM_PHYSICS_MATERIAL = 31;
590 public const int DENSITY = 1;
591 public const int FRICTION = 2;
592 public const int RESTITUTION = 4;
593 public const int GRAVITY_MULTIPLIER = 8;
581 594
582 // extra constants for llSetPrimMediaParams 595 // extra constants for llSetPrimMediaParams
583 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 596 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -650,5 +663,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
650 public static readonly LSLInteger RCERR_UNKNOWN = -1; 663 public static readonly LSLInteger RCERR_UNKNOWN = -1;
651 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 664 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
652 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 665 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
666
667 public const int KFM_MODE = 1;
668 public const int KFM_LOOP = 1;
669 public const int KFM_REVERSE = 3;
670 public const int KFM_FORWARD = 0;
671 public const int KFM_PING_PONG = 2;
672 public const int KFM_DATA = 2;
673 public const int KFM_TRANSLATION = 2;
674 public const int KFM_ROTATION = 1;
675 public const int KFM_COMMAND = 0;
676 public const int KFM_CMD_PLAY = 0;
677 public const int KFM_CMD_STOP = 1;
678 public const int KFM_CMD_PAUSE = 2;
653 } 679 }
654} 680}
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}