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.cs2812
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs60
-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.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs21
-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.cs92
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs362
19 files changed, 2599 insertions, 1118 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index ee32755..61e4934 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -248,6 +248,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
248 248
249 } 249 }
250 250
251 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
252 {
253 // Remove a specific script
254
255 // Remove dataserver events
256 m_Dataserver[engine].RemoveEvents(localID, itemID);
257
258 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
259 if (comms != null)
260 comms.DeleteListener(itemID);
261
262 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
263 xmlrpc.DeleteChannels(itemID);
264 xmlrpc.CancelSRDRequests(itemID);
265
266 // Remove Sensors
267 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
268
269 }
270
251 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 271 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
252 { 272 {
253 List<Object> data = new List<Object>(); 273 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..489c1c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal uint m_localID;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true;
75 }
76
77 public override Object InitializeLifetimeService()
78 {
79 ILease lease = (ILease)base.InitializeLifetimeService();
80
81 if (lease.CurrentState == LeaseState.Initial)
82 {
83 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
84 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
85 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
86 }
87 return lease;
88 }
89
90 public Scene World
91 {
92 get { return m_ScriptEngine.World; }
93 }
94
95 public string cmDetectedCountry(int number)
96 {
97 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
99 if (detectedParams == null)
100 return String.Empty;
101 return detectedParams.Country;
102 }
103
104 public string cmGetAgentCountry(LSL_Key key)
105 {
106 if (!World.Permissions.IsGod(m_host.OwnerID))
107 return String.Empty;
108
109 UUID uuid;
110
111 if (!UUID.TryParse(key, out uuid))
112 return String.Empty;
113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
116 }
117 }
118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index fb930e0..943f37d 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); 561
486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
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))); 563 {
488 double z = Math.Atan2(v.y, v.x); 564 m_host.AddScriptLPS(1);
565 LSL_Vector eul = new LSL_Vector();
489 566
490 return new LSL_Vector(x, y, z); 567 double sqw = q1.s*q1.s;
568 double sqx = q1.x*q1.x;
569 double sqy = q1.z*q1.z;
570 double sqz = q1.y*q1.y;
571 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
572 double test = q1.x*q1.z + q1.y*q1.s;
573 if (test > 0.4999*unit) { // singularity at north pole
574 eul.z = 2 * Math.Atan2(q1.x,q1.s);
575 eul.y = Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 if (test < -0.4999*unit) { // singularity at south pole
580 eul.z = -2 * Math.Atan2(q1.x,q1.s);
581 eul.y = -Math.PI/2;
582 eul.x = 0;
583 return eul;
584 }
585 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
586 eul.y = Math.Asin(2*test/unit);
587 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
588 return eul;
491 } 589 }
492 590
493 /* From wiki: 591 /* From wiki:
@@ -689,77 +787,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 787 {
690 //A and B should both be normalized 788 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 789 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 790 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 791 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 792
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 793 double dotProduct = LSL_Vector.Dot(a, b);
794 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
795 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
796 double angle = Math.Acos(dotProduct / magProduct);
797 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
798 double s = Math.Sin(angle / 2);
799
800 double x = axis.x * s;
801 double y = axis.y * s;
802 double z = axis.z * s;
803 double w = Math.Cos(angle / 2);
804
805 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
806 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
807
808 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
809 */
810
811 // This method mimics the 180 errors found in SL
812 // See www.euclideanspace.com... angleBetween
813 LSL_Vector vec_a = a;
814 LSL_Vector vec_b = b;
815
816 // Eliminate zero length
817 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
818 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
819 if (vec_a_mag < 0.00001 ||
820 vec_b_mag < 0.00001)
696 { 821 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 822 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 823 }
699 else 824
825 // Normalize
826 vec_a = llVecNorm(vec_a);
827 vec_b = llVecNorm(vec_b);
828
829 // Calculate axis and rotation angle
830 LSL_Vector axis = vec_a % vec_b;
831 LSL_Float cos_theta = vec_a * vec_b;
832
833 // Check if parallel
834 if (cos_theta > 0.99999)
700 { 835 {
701 a = LSL_Vector.Norm(a); 836 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 837 }
703 double dotProduct = LSL_Vector.Dot(a, b); 838
704 // There are two degenerate cases possible. These are for vectors 180 or 839 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 840 else if (cos_theta < -0.99999)
706 // 841 {
707 // Check for vectors 180 degrees apart. 842 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 843 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 844 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 845 }
711 // First assume X axis is orthogonal to the vectors. 846 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 847 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 848 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 849 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 850 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 851 s = Math.Cos(theta);
717 { 852 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 853 x = axis.x * t;
719 } 854 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 855 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 856 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 857 }
760 return rotBetween;
761 } 858 }
762 859
763 public void llWhisper(int channelID, string text) 860 public void llWhisper(int channelID, string text)
764 { 861 {
765 m_host.AddScriptLPS(1); 862 m_host.AddScriptLPS(1);
@@ -779,6 +876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 876 {
780 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
781 878
879 if (channelID == 0)
880 m_SayShoutCount++;
881
882 if (m_SayShoutCount >= 11)
883 ScriptSleep(2000);
884
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 885 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 886 {
784 Console.WriteLine(text); 887 Console.WriteLine(text);
@@ -801,6 +904,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 904 {
802 m_host.AddScriptLPS(1); 905 m_host.AddScriptLPS(1);
803 906
907 if (channelID == 0)
908 m_SayShoutCount++;
909
910 if (m_SayShoutCount >= 11)
911 ScriptSleep(2000);
912
804 if (text.Length > 1023) 913 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 914 text = text.Substring(0, 1023);
806 915
@@ -1101,10 +1210,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1210 return detectedParams.TouchUV;
1102 } 1211 }
1103 1212
1213 [DebuggerNonUserCode]
1104 public virtual void llDie() 1214 public virtual void llDie()
1105 { 1215 {
1106 m_host.AddScriptLPS(1); 1216 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1217 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1218 }
1109 1219
1110 public LSL_Float llGround(LSL_Vector offset) 1220 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1287
1178 public void llSetStatus(int status, int value) 1288 public void llSetStatus(int status, int value)
1179 { 1289 {
1290 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1291 return;
1180 m_host.AddScriptLPS(1); 1292 m_host.AddScriptLPS(1);
1181 1293
1182 int statusrotationaxis = 0; 1294 int statusrotationaxis = 0;
@@ -1406,6 +1518,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1518 {
1407 m_host.AddScriptLPS(1); 1519 m_host.AddScriptLPS(1);
1408 1520
1521 SetColor(m_host, color, face);
1522 }
1523
1524 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1525 {
1526 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1527 return;
1528
1529 Primitive.TextureEntry tex = part.Shape.Textures;
1530 Color4 texcolor;
1531 if (face >= 0 && face < GetNumberOfSides(part))
1532 {
1533 texcolor = tex.CreateFace((uint)face).RGBA;
1534 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1535 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1536 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1537 tex.FaceTextures[face].RGBA = texcolor;
1538 part.UpdateTextureEntry(tex.GetBytes());
1539 return;
1540 }
1541 else if (face == ScriptBaseClass.ALL_SIDES)
1542 {
1543 for (uint i = 0; i < GetNumberOfSides(part); i++)
1544 {
1545 if (tex.FaceTextures[i] != null)
1546 {
1547 texcolor = tex.FaceTextures[i].RGBA;
1548 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1549 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1550 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1551 tex.FaceTextures[i].RGBA = texcolor;
1552 }
1553 texcolor = tex.DefaultTexture.RGBA;
1554 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1555 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1556 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1557 tex.DefaultTexture.RGBA = texcolor;
1558 }
1559 part.UpdateTextureEntry(tex.GetBytes());
1560 return;
1561 }
1562
1409 if (face == ScriptBaseClass.ALL_SIDES) 1563 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1564 face = SceneObjectPart.ALL_SIDES;
1411 1565
@@ -1414,6 +1568,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1568
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1569 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1570 {
1571 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1572 return;
1573
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1574 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1575 MappingType textype;
1419 textype = MappingType.Default; 1576 textype = MappingType.Default;
@@ -1444,6 +1601,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1601
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1602 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1603 {
1604 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1605 return;
1606
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1607 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1608 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1609 {
@@ -1469,6 +1629,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1629
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1630 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1631 {
1632 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1633 return;
1472 1634
1473 Shininess sval = new Shininess(); 1635 Shininess sval = new Shininess();
1474 1636
@@ -1519,6 +1681,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1681
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1682 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1686
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1687 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1688 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1689 {
@@ -1579,13 +1744,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1744 m_host.AddScriptLPS(1);
1580 1745
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1746 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1747 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1748 {
1584 SetAlpha(part, alpha, face); 1749 try
1750 {
1751 parts[0].ParentGroup.areUpdatesSuspended = true;
1752 foreach (SceneObjectPart part in parts)
1753 SetAlpha(part, alpha, face);
1754 }
1755 finally
1756 {
1757 parts[0].ParentGroup.areUpdatesSuspended = false;
1758 }
1759 }
1585 } 1760 }
1586 1761
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1762 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1763 {
1764 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1765 return;
1766
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1767 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1768 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1769 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1816,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1816 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1817 float wind, float tension, LSL_Vector Force)
1640 { 1818 {
1641 if (part == null) 1819 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1820 return;
1643 1821
1644 if (flexi) 1822 if (flexi)
@@ -1672,7 +1850,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1672 /// <param name="falloff"></param> 1850 /// <param name="falloff"></param>
1673 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1851 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1674 { 1852 {
1675 if (part == null) 1853 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1676 return; 1854 return;
1677 1855
1678 if (light) 1856 if (light)
@@ -1749,15 +1927,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1749 m_host.AddScriptLPS(1); 1927 m_host.AddScriptLPS(1);
1750 1928
1751 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1929 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1752 1930 if (parts.Count > 0)
1753 foreach (SceneObjectPart part in parts) 1931 {
1754 SetTexture(part, texture, face); 1932 try
1755 1933 {
1934 parts[0].ParentGroup.areUpdatesSuspended = true;
1935 foreach (SceneObjectPart part in parts)
1936 SetTexture(part, texture, face);
1937 }
1938 finally
1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = false;
1941 }
1942 }
1756 ScriptSleep(200); 1943 ScriptSleep(200);
1757 } 1944 }
1758 1945
1759 protected void SetTexture(SceneObjectPart part, string texture, int face) 1946 protected void SetTexture(SceneObjectPart part, string texture, int face)
1760 { 1947 {
1948 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1949 return;
1950
1761 UUID textureID = new UUID(); 1951 UUID textureID = new UUID();
1762 1952
1763 textureID = InventoryKey(texture, (int)AssetType.Texture); 1953 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1802,6 +1992,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1802 1992
1803 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1993 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1804 { 1994 {
1995 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1996 return;
1997
1805 Primitive.TextureEntry tex = part.Shape.Textures; 1998 Primitive.TextureEntry tex = part.Shape.Textures;
1806 if (face >= 0 && face < GetNumberOfSides(part)) 1999 if (face >= 0 && face < GetNumberOfSides(part))
1807 { 2000 {
@@ -1838,6 +2031,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1838 2031
1839 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2032 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1840 { 2033 {
2034 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2035 return;
2036
1841 Primitive.TextureEntry tex = part.Shape.Textures; 2037 Primitive.TextureEntry tex = part.Shape.Textures;
1842 if (face >= 0 && face < GetNumberOfSides(part)) 2038 if (face >= 0 && face < GetNumberOfSides(part))
1843 { 2039 {
@@ -1874,6 +2070,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 2070
1875 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2071 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1876 { 2072 {
2073 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2074 return;
2075
1877 Primitive.TextureEntry tex = part.Shape.Textures; 2076 Primitive.TextureEntry tex = part.Shape.Textures;
1878 if (face >= 0 && face < GetNumberOfSides(part)) 2077 if (face >= 0 && face < GetNumberOfSides(part))
1879 { 2078 {
@@ -1980,24 +2179,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 2179
1981 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2180 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1982 { 2181 {
1983 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2182 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1984 LSL_Vector currentPos = GetPartLocalPos(part); 2183 return;
1985 2184
1986 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2185 LSL_Vector currentPos = GetPartLocalPos(part);
1987 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2186 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1988 2187
1989 if (part.ParentGroup.RootPart == part) 2188 if (part.ParentGroup.RootPart == part)
1990 { 2189 {
1991 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1992 targetPos.z = ground;
1993 SceneObjectGroup parent = part.ParentGroup; 2190 SceneObjectGroup parent = part.ParentGroup;
1994 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2191 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1995 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1996 } 2192 }
1997 else 2193 else
1998 { 2194 {
1999 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2195 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2000 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2001 SceneObjectGroup parent = part.ParentGroup; 2196 SceneObjectGroup parent = part.ParentGroup;
2002 parent.HasGroupChanged = true; 2197 parent.HasGroupChanged = true;
2003 parent.ScheduleGroupForTerseUpdate(); 2198 parent.ScheduleGroupForTerseUpdate();
@@ -2048,9 +2243,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2048 m_host.AddScriptLPS(1); 2243 m_host.AddScriptLPS(1);
2049 2244
2050 // try to let this work as in SL... 2245 // try to let this work as in SL...
2051 if (m_host.ParentID == 0) 2246 if (m_host.LinkNum < 2)
2052 { 2247 {
2053 // special case: If we are root, rotate complete SOG to new rotation 2248 // Special case: If we are root, rotate complete SOG to new
2249 // rotation.
2250 // We are root if the link number is 0 (single prim) or 1
2251 // (root prim). ParentID may be nonzero in attachments and
2252 // using it would cause attachments and HUDs to rotate
2253 // to the wrong positions.
2054 SetRot(m_host, Rot2Quaternion(rot)); 2254 SetRot(m_host, Rot2Quaternion(rot));
2055 } 2255 }
2056 else 2256 else
@@ -2075,6 +2275,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 2275
2076 protected void SetRot(SceneObjectPart part, Quaternion rot) 2276 protected void SetRot(SceneObjectPart part, Quaternion rot)
2077 { 2277 {
2278 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2279 return;
2280
2078 part.UpdateRotation(rot); 2281 part.UpdateRotation(rot);
2079 // Update rotation does not move the object in the physics scene if it's a linkset. 2282 // Update rotation does not move the object in the physics scene if it's a linkset.
2080 2283
@@ -2698,12 +2901,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2698 2901
2699 m_host.AddScriptLPS(1); 2902 m_host.AddScriptLPS(1);
2700 2903
2904 m_host.TaskInventory.LockItemsForRead(true);
2701 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2905 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2702 2906 m_host.TaskInventory.LockItemsForRead(false);
2703 lock (m_host.TaskInventory)
2704 {
2705 item = m_host.TaskInventory[invItemID];
2706 }
2707 2907
2708 if (item.PermsGranter == UUID.Zero) 2908 if (item.PermsGranter == UUID.Zero)
2709 return 0; 2909 return 0;
@@ -2778,6 +2978,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2778 if (dist > m_ScriptDistanceFactor * 10.0f) 2978 if (dist > m_ScriptDistanceFactor * 10.0f)
2779 return; 2979 return;
2780 2980
2981 //Clone is thread-safe
2781 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2982 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2782 2983
2783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2984 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2838,6 +3039,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2838 3039
2839 public void llLookAt(LSL_Vector target, double strength, double damping) 3040 public void llLookAt(LSL_Vector target, double strength, double damping)
2840 { 3041 {
3042 /*
2841 m_host.AddScriptLPS(1); 3043 m_host.AddScriptLPS(1);
2842 // Determine where we are looking from 3044 // Determine where we are looking from
2843 LSL_Vector from = llGetPos(); 3045 LSL_Vector from = llGetPos();
@@ -2856,18 +3058,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2856 // we need to convert from a vector describing 3058 // we need to convert from a vector describing
2857 // the angles of rotation in radians into rotation value 3059 // the angles of rotation in radians into rotation value
2858 3060
3061<<<<<<< HEAD:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
3062 LSL_Types.Quaternion rot = llEuler2Rot(angle);
3063
3064 // This would only work if your physics system contains an APID controller:
3065 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3066 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3067
3068 // Orient the object to the angle calculated
3069 llSetRot(rot);
3070 */
3071
3072 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3073 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3074 // http://bugs.meta7.com/view.php?id=28
3075 // - Tom
3076
3077 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3078 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3079 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3080 */
3081 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3082 {
3083 // Part is non-phys, convert this to a llSetRot()
3084 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3085 Vector3 dir = tgt - m_host.GroupPosition;
3086 dir.Normalize();
3087 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3088 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3089 float terot = (float)Math.Atan2(-dir.Z, txy);
3090 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3091 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3092 LSL_Types.Quaternion spin = llEuler2Rot(az);
3093 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3094=======
2859 LSL_Rotation rot = llEuler2Rot(angle); 3095 LSL_Rotation rot = llEuler2Rot(angle);
2860 3096
2861 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3097 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2862 // set the rotation of the object, copy that behavior 3098 // set the rotation of the object, copy that behavior
2863 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical) 3099 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2864 { 3100 {
3101>>>>>>> master:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
2865 llSetRot(rot); 3102 llSetRot(rot);
2866 } 3103 }
2867 else 3104 else
2868 { 3105 {
3106<<<<<<< HEAD:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
3107 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3108 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3109 m_host.RotLookAt(q, (float)strength, (float)damping);
3110 }
3111
3112 }
3113
3114 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3115 {
3116 m_host.AddScriptLPS(1);
3117// NotImplemented("llRotLookAt");
3118 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3119
3120=======
2869 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3121 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping);
2870 } 3122 }
3123>>>>>>> master:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
2871 } 3124 }
2872 3125
2873 public void llStopLookAt() 3126 public void llStopLookAt()
@@ -2916,13 +3169,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2916 { 3169 {
2917 TaskInventoryItem item; 3170 TaskInventoryItem item;
2918 3171
2919 lock (m_host.TaskInventory) 3172 m_host.TaskInventory.LockItemsForRead(true);
3173 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2920 { 3174 {
2921 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3175 m_host.TaskInventory.LockItemsForRead(false);
2922 return; 3176 return;
2923 else 3177 }
2924 item = m_host.TaskInventory[InventorySelf()]; 3178 else
3179 {
3180 item = m_host.TaskInventory[InventorySelf()];
2925 } 3181 }
3182 m_host.TaskInventory.LockItemsForRead(false);
2926 3183
2927 if (item.PermsGranter != UUID.Zero) 3184 if (item.PermsGranter != UUID.Zero)
2928 { 3185 {
@@ -2944,13 +3201,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2944 { 3201 {
2945 TaskInventoryItem item; 3202 TaskInventoryItem item;
2946 3203
3204 m_host.TaskInventory.LockItemsForRead(true);
2947 lock (m_host.TaskInventory) 3205 lock (m_host.TaskInventory)
2948 { 3206 {
3207
2949 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3208 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3209 {
3210 m_host.TaskInventory.LockItemsForRead(false);
2950 return; 3211 return;
3212 }
2951 else 3213 else
3214 {
2952 item = m_host.TaskInventory[InventorySelf()]; 3215 item = m_host.TaskInventory[InventorySelf()];
3216 }
2953 } 3217 }
3218 m_host.TaskInventory.LockItemsForRead(false);
2954 3219
2955 m_host.AddScriptLPS(1); 3220 m_host.AddScriptLPS(1);
2956 3221
@@ -2982,18 +3247,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2982 { 3247 {
2983 m_host.AddScriptLPS(1); 3248 m_host.AddScriptLPS(1);
2984 3249
2985// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2986// return;
2987
2988 TaskInventoryItem item; 3250 TaskInventoryItem item;
2989 3251
2990 lock (m_host.TaskInventory) 3252 m_host.TaskInventory.LockItemsForRead(true);
3253
3254 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2991 { 3255 {
2992 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3256 m_host.TaskInventory.LockItemsForRead(false);
2993 return; 3257 return;
2994 else
2995 item = m_host.TaskInventory[InventorySelf()];
2996 } 3258 }
3259 else
3260 {
3261 item = m_host.TaskInventory[InventorySelf()];
3262 }
3263
3264 m_host.TaskInventory.LockItemsForRead(false);
2997 3265
2998 if (item.PermsGranter != m_host.OwnerID) 3266 if (item.PermsGranter != m_host.OwnerID)
2999 return; 3267 return;
@@ -3019,13 +3287,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 3287
3020 TaskInventoryItem item; 3288 TaskInventoryItem item;
3021 3289
3022 lock (m_host.TaskInventory) 3290 m_host.TaskInventory.LockItemsForRead(true);
3291
3292 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3023 { 3293 {
3024 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3294 m_host.TaskInventory.LockItemsForRead(false);
3025 return; 3295 return;
3026 else
3027 item = m_host.TaskInventory[InventorySelf()];
3028 } 3296 }
3297 else
3298 {
3299 item = m_host.TaskInventory[InventorySelf()];
3300 }
3301 m_host.TaskInventory.LockItemsForRead(false);
3302
3029 3303
3030 if (item.PermsGranter != m_host.OwnerID) 3304 if (item.PermsGranter != m_host.OwnerID)
3031 return; 3305 return;
@@ -3072,6 +3346,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3072 3346
3073 public void llInstantMessage(string user, string message) 3347 public void llInstantMessage(string user, string message)
3074 { 3348 {
3349 UUID result;
3350 if (!UUID.TryParse(user, out result))
3351 {
3352 ShoutError("An invalid key was passed to llInstantMessage");
3353 ScriptSleep(2000);
3354 return;
3355 }
3356
3357
3075 m_host.AddScriptLPS(1); 3358 m_host.AddScriptLPS(1);
3076 3359
3077 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3360 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3086,14 +3369,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3086 UUID friendTransactionID = UUID.Random(); 3369 UUID friendTransactionID = UUID.Random();
3087 3370
3088 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3371 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3089 3372
3090 GridInstantMessage msg = new GridInstantMessage(); 3373 GridInstantMessage msg = new GridInstantMessage();
3091 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3374 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3092 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3375 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3093 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3376 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3094// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3377// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3095// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3378// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3096 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3379// DateTime dt = DateTime.UtcNow;
3380//
3381// // Ticks from UtcNow, but make it look like local. Evil, huh?
3382// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3383//
3384// try
3385// {
3386// // Convert that to the PST timezone
3387// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3388// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3389// }
3390// catch
3391// {
3392// // No logging here, as it could be VERY spammy
3393// }
3394//
3395// // And make it look local again to fool the unix time util
3396// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3397
3398 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3399
3097 //if (client != null) 3400 //if (client != null)
3098 //{ 3401 //{
3099 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3402 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3107,12 +3410,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3107 msg.message = message.Substring(0, 1024); 3410 msg.message = message.Substring(0, 1024);
3108 else 3411 else
3109 msg.message = message; 3412 msg.message = message;
3110 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3413 msg.dialog = (byte)19; // MessageFromObject
3111 msg.fromGroup = false;// fromGroup; 3414 msg.fromGroup = false;// fromGroup;
3112 msg.offline = (byte)0; //offline; 3415 msg.offline = (byte)0; //offline;
3113 msg.ParentEstateID = 0; //ParentEstateID; 3416 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3114 msg.Position = new Vector3(m_host.AbsolutePosition); 3417 msg.Position = new Vector3(m_host.AbsolutePosition);
3115 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3418 msg.RegionID = World.RegionInfo.RegionID.Guid;
3116 msg.binaryBucket 3419 msg.binaryBucket
3117 = Util.StringToBytes256( 3420 = Util.StringToBytes256(
3118 "{0}/{1}/{2}/{3}", 3421 "{0}/{1}/{2}/{3}",
@@ -3140,7 +3443,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3140 } 3443 }
3141 3444
3142 emailModule.SendEmail(m_host.UUID, address, subject, message); 3445 emailModule.SendEmail(m_host.UUID, address, subject, message);
3143 ScriptSleep(20000); 3446 ScriptSleep(15000);
3144 } 3447 }
3145 3448
3146 public void llGetNextEmail(string address, string subject) 3449 public void llGetNextEmail(string address, string subject)
@@ -3240,6 +3543,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3240 m_host.AddScriptLPS(1); 3543 m_host.AddScriptLPS(1);
3241 } 3544 }
3242 3545
3546<<<<<<< HEAD:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
3547=======
3243 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3548 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3244 { 3549 {
3245 m_host.AddScriptLPS(1); 3550 m_host.AddScriptLPS(1);
@@ -3256,6 +3561,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3256 } 3561 }
3257 } 3562 }
3258 3563
3564>>>>>>> master:OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
3259 public LSL_Integer llStringLength(string str) 3565 public LSL_Integer llStringLength(string str)
3260 { 3566 {
3261 m_host.AddScriptLPS(1); 3567 m_host.AddScriptLPS(1);
@@ -3279,14 +3585,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3279 3585
3280 TaskInventoryItem item; 3586 TaskInventoryItem item;
3281 3587
3282 lock (m_host.TaskInventory) 3588 m_host.TaskInventory.LockItemsForRead(true);
3589 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3283 { 3590 {
3284 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3591 m_host.TaskInventory.LockItemsForRead(false);
3285 return; 3592 return;
3286 else
3287 item = m_host.TaskInventory[InventorySelf()];
3288 } 3593 }
3289 3594 else
3595 {
3596 item = m_host.TaskInventory[InventorySelf()];
3597 }
3598 m_host.TaskInventory.LockItemsForRead(false);
3290 if (item.PermsGranter == UUID.Zero) 3599 if (item.PermsGranter == UUID.Zero)
3291 return; 3600 return;
3292 3601
@@ -3316,13 +3625,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3316 3625
3317 TaskInventoryItem item; 3626 TaskInventoryItem item;
3318 3627
3319 lock (m_host.TaskInventory) 3628 m_host.TaskInventory.LockItemsForRead(true);
3629 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3320 { 3630 {
3321 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3631 m_host.TaskInventory.LockItemsForRead(false);
3322 return; 3632 return;
3323 else 3633 }
3324 item = m_host.TaskInventory[InventorySelf()]; 3634 else
3635 {
3636 item = m_host.TaskInventory[InventorySelf()];
3325 } 3637 }
3638 m_host.TaskInventory.LockItemsForRead(false);
3639
3326 3640
3327 if (item.PermsGranter == UUID.Zero) 3641 if (item.PermsGranter == UUID.Zero)
3328 return; 3642 return;
@@ -3389,10 +3703,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3389 3703
3390 TaskInventoryItem item; 3704 TaskInventoryItem item;
3391 3705
3392 lock (m_host.TaskInventory) 3706
3707 m_host.TaskInventory.LockItemsForRead(true);
3708 if (!m_host.TaskInventory.ContainsKey(invItemID))
3709 {
3710 m_host.TaskInventory.LockItemsForRead(false);
3711 return;
3712 }
3713 else
3393 { 3714 {
3394 item = m_host.TaskInventory[invItemID]; 3715 item = m_host.TaskInventory[invItemID];
3395 } 3716 }
3717 m_host.TaskInventory.LockItemsForRead(false);
3396 3718
3397 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3719 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3398 { 3720 {
@@ -3420,15 +3742,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3420 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3742 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3421 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3743 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3422 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3744 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3745 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3423 ScriptBaseClass.PERMISSION_ATTACH; 3746 ScriptBaseClass.PERMISSION_ATTACH;
3424 3747
3425 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3748 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3426 { 3749 {
3427 lock (m_host.TaskInventory) 3750 m_host.TaskInventory.LockItemsForWrite(true);
3428 { 3751 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3429 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3752 m_host.TaskInventory[invItemID].PermsMask = perm;
3430 m_host.TaskInventory[invItemID].PermsMask = perm; 3753 m_host.TaskInventory.LockItemsForWrite(false);
3431 }
3432 3754
3433 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3755 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3434 "run_time_permissions", new Object[] { 3756 "run_time_permissions", new Object[] {
@@ -3438,28 +3760,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 return; 3760 return;
3439 } 3761 }
3440 } 3762 }
3441 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3763 else
3442 { 3764 {
3443 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3765 bool sitting = false;
3444 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3766 if (m_host.SitTargetAvatar == agentID)
3445 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3767 {
3446 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3768 sitting = true;
3447 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3769 }
3770 else
3771 {
3772 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3773 {
3774 if (p.SitTargetAvatar == agentID)
3775 sitting = true;
3776 }
3777 }
3448 3778
3449 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3779 if (sitting)
3450 { 3780 {
3451 lock (m_host.TaskInventory) 3781 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3782 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3783 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3784 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3785 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3786
3787 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3452 { 3788 {
3789 m_host.TaskInventory.LockItemsForWrite(true);
3453 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3790 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3454 m_host.TaskInventory[invItemID].PermsMask = perm; 3791 m_host.TaskInventory[invItemID].PermsMask = perm;
3455 } 3792 m_host.TaskInventory.LockItemsForWrite(false);
3456 3793
3457 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3794 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3458 "run_time_permissions", new Object[] { 3795 "run_time_permissions", new Object[] {
3459 new LSL_Integer(perm) }, 3796 new LSL_Integer(perm) },
3460 new DetectParams[0])); 3797 new DetectParams[0]));
3461 3798
3462 return; 3799 return;
3800 }
3463 } 3801 }
3464 } 3802 }
3465 3803
@@ -3473,11 +3811,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3473 3811
3474 if (!m_waitingForScriptAnswer) 3812 if (!m_waitingForScriptAnswer)
3475 { 3813 {
3476 lock (m_host.TaskInventory) 3814 m_host.TaskInventory.LockItemsForWrite(true);
3477 { 3815 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3478 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3816 m_host.TaskInventory[invItemID].PermsMask = 0;
3479 m_host.TaskInventory[invItemID].PermsMask = 0; 3817 m_host.TaskInventory.LockItemsForWrite(false);
3480 }
3481 3818
3482 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3819 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3483 m_waitingForScriptAnswer=true; 3820 m_waitingForScriptAnswer=true;
@@ -3512,10 +3849,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3512 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3849 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3513 llReleaseControls(); 3850 llReleaseControls();
3514 3851
3515 lock (m_host.TaskInventory) 3852
3516 { 3853 m_host.TaskInventory.LockItemsForWrite(true);
3517 m_host.TaskInventory[invItemID].PermsMask = answer; 3854 m_host.TaskInventory[invItemID].PermsMask = answer;
3518 } 3855 m_host.TaskInventory.LockItemsForWrite(false);
3856
3519 3857
3520 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3858 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3521 "run_time_permissions", new Object[] { 3859 "run_time_permissions", new Object[] {
@@ -3527,16 +3865,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3527 { 3865 {
3528 m_host.AddScriptLPS(1); 3866 m_host.AddScriptLPS(1);
3529 3867
3530 lock (m_host.TaskInventory) 3868 m_host.TaskInventory.LockItemsForRead(true);
3869
3870 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3531 { 3871 {
3532 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3872 if (item.Type == 10 && item.ItemID == m_itemID)
3533 { 3873 {
3534 if (item.Type == 10 && item.ItemID == m_itemID) 3874 m_host.TaskInventory.LockItemsForRead(false);
3535 { 3875 return item.PermsGranter.ToString();
3536 return item.PermsGranter.ToString();
3537 }
3538 } 3876 }
3539 } 3877 }
3878 m_host.TaskInventory.LockItemsForRead(false);
3540 3879
3541 return UUID.Zero.ToString(); 3880 return UUID.Zero.ToString();
3542 } 3881 }
@@ -3545,19 +3884,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3545 { 3884 {
3546 m_host.AddScriptLPS(1); 3885 m_host.AddScriptLPS(1);
3547 3886
3548 lock (m_host.TaskInventory) 3887 m_host.TaskInventory.LockItemsForRead(true);
3888
3889 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3549 { 3890 {
3550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3891 if (item.Type == 10 && item.ItemID == m_itemID)
3551 { 3892 {
3552 if (item.Type == 10 && item.ItemID == m_itemID) 3893 int perms = item.PermsMask;
3553 { 3894 if (m_automaticLinkPermission)
3554 int perms = item.PermsMask; 3895 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3555 if (m_automaticLinkPermission) 3896 m_host.TaskInventory.LockItemsForRead(false);
3556 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3897 return perms;
3557 return perms;
3558 }
3559 } 3898 }
3560 } 3899 }
3900 m_host.TaskInventory.LockItemsForRead(false);
3561 3901
3562 return 0; 3902 return 0;
3563 } 3903 }
@@ -3579,9 +3919,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3579 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3919 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3580 { 3920 {
3581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3921 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3582 3922 if (parts.Count > 0)
3583 foreach (SceneObjectPart part in parts) 3923 {
3584 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3924 try
3925 {
3926 parts[0].ParentGroup.areUpdatesSuspended = true;
3927 foreach (SceneObjectPart part in parts)
3928 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3929 }
3930 finally
3931 {
3932 parts[0].ParentGroup.areUpdatesSuspended = false;
3933 }
3934 }
3585 } 3935 }
3586 3936
3587 public void llCreateLink(string target, int parent) 3937 public void llCreateLink(string target, int parent)
@@ -3594,11 +3944,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3594 return; 3944 return;
3595 3945
3596 TaskInventoryItem item; 3946 TaskInventoryItem item;
3597 lock (m_host.TaskInventory) 3947 m_host.TaskInventory.LockItemsForRead(true);
3598 { 3948 item = m_host.TaskInventory[invItemID];
3599 item = m_host.TaskInventory[invItemID]; 3949 m_host.TaskInventory.LockItemsForRead(false);
3600 } 3950
3601
3602 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3951 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3603 && !m_automaticLinkPermission) 3952 && !m_automaticLinkPermission)
3604 { 3953 {
@@ -3615,11 +3964,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3615 3964
3616 if (targetPart.ParentGroup.AttachmentPoint != 0) 3965 if (targetPart.ParentGroup.AttachmentPoint != 0)
3617 return; // Fail silently if attached 3966 return; // Fail silently if attached
3967
3968 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3969 return;
3970
3618 SceneObjectGroup parentPrim = null, childPrim = null; 3971 SceneObjectGroup parentPrim = null, childPrim = null;
3619 3972
3620 if (targetPart != null) 3973 if (targetPart != null)
3621 { 3974 {
3622 if (parent != 0) { 3975 if (parent != 0)
3976 {
3623 parentPrim = m_host.ParentGroup; 3977 parentPrim = m_host.ParentGroup;
3624 childPrim = targetPart.ParentGroup; 3978 childPrim = targetPart.ParentGroup;
3625 } 3979 }
@@ -3650,16 +4004,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3650 m_host.AddScriptLPS(1); 4004 m_host.AddScriptLPS(1);
3651 UUID invItemID = InventorySelf(); 4005 UUID invItemID = InventorySelf();
3652 4006
3653 lock (m_host.TaskInventory) 4007 m_host.TaskInventory.LockItemsForRead(true);
3654 {
3655 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4008 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3656 && !m_automaticLinkPermission) 4009 && !m_automaticLinkPermission)
3657 { 4010 {
3658 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4011 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4012 m_host.TaskInventory.LockItemsForRead(false);
3659 return; 4013 return;
3660 } 4014 }
3661 } 4015 m_host.TaskInventory.LockItemsForRead(false);
3662 4016
3663 if (linknum < ScriptBaseClass.LINK_THIS) 4017 if (linknum < ScriptBaseClass.LINK_THIS)
3664 return; 4018 return;
3665 4019
@@ -3698,10 +4052,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3698 // Restructuring Multiple Prims. 4052 // Restructuring Multiple Prims.
3699 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4053 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3700 parts.Remove(parentPrim.RootPart); 4054 parts.Remove(parentPrim.RootPart);
3701 foreach (SceneObjectPart part in parts) 4055 if (parts.Count > 0)
3702 { 4056 {
3703 parentPrim.DelinkFromGroup(part.LocalId, true); 4057 try
4058 {
4059 parts[0].ParentGroup.areUpdatesSuspended = true;
4060 foreach (SceneObjectPart part in parts)
4061 {
4062 parentPrim.DelinkFromGroup(part.LocalId, true);
4063 }
4064 }
4065 finally
4066 {
4067 parts[0].ParentGroup.areUpdatesSuspended = false;
4068 }
3704 } 4069 }
4070
3705 parentPrim.HasGroupChanged = true; 4071 parentPrim.HasGroupChanged = true;
3706 parentPrim.ScheduleGroupForFullUpdate(); 4072 parentPrim.ScheduleGroupForFullUpdate();
3707 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4073 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3710,12 +4076,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3710 { 4076 {
3711 SceneObjectPart newRoot = parts[0]; 4077 SceneObjectPart newRoot = parts[0];
3712 parts.Remove(newRoot); 4078 parts.Remove(newRoot);
3713 foreach (SceneObjectPart part in parts) 4079
4080 try
3714 { 4081 {
3715 // Required for linking 4082 parts[0].ParentGroup.areUpdatesSuspended = true;
3716 part.ClearUpdateSchedule(); 4083 foreach (SceneObjectPart part in parts)
3717 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4084 {
4085 part.ClearUpdateSchedule();
4086 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4087 }
3718 } 4088 }
4089 finally
4090 {
4091 parts[0].ParentGroup.areUpdatesSuspended = false;
4092 }
4093
4094
3719 newRoot.ParentGroup.HasGroupChanged = true; 4095 newRoot.ParentGroup.HasGroupChanged = true;
3720 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4096 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3721 } 4097 }
@@ -3735,6 +4111,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 public void llBreakAllLinks() 4111 public void llBreakAllLinks()
3736 { 4112 {
3737 m_host.AddScriptLPS(1); 4113 m_host.AddScriptLPS(1);
4114
4115 UUID invItemID = InventorySelf();
4116
4117 TaskInventoryItem item;
4118 m_host.TaskInventory.LockItemsForRead(true);
4119 item = m_host.TaskInventory[invItemID];
4120 m_host.TaskInventory.LockItemsForRead(false);
4121
4122 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4123 && !m_automaticLinkPermission)
4124 {
4125 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4126 return;
4127 }
4128
3738 SceneObjectGroup parentPrim = m_host.ParentGroup; 4129 SceneObjectGroup parentPrim = m_host.ParentGroup;
3739 if (parentPrim.AttachmentPoint != 0) 4130 if (parentPrim.AttachmentPoint != 0)
3740 return; // Fail silently if attached 4131 return; // Fail silently if attached
@@ -3754,25 +4145,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 public LSL_String llGetLinkKey(int linknum) 4145 public LSL_String llGetLinkKey(int linknum)
3755 { 4146 {
3756 m_host.AddScriptLPS(1); 4147 m_host.AddScriptLPS(1);
3757 List<UUID> keytable = new List<UUID>();
3758 // parse for sitting avatare-uuids
3759 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3760 {
3761 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
3762 keytable.Add(presence.UUID);
3763 });
3764
3765 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3766 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3767 {
3768 return keytable[totalprims - linknum].ToString();
3769 }
3770
3771 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3772 {
3773 return m_host.UUID.ToString();
3774 }
3775
3776 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4148 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3777 if (part != null) 4149 if (part != null)
3778 { 4150 {
@@ -3780,6 +4152,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3780 } 4152 }
3781 else 4153 else
3782 { 4154 {
4155 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4156 {
4157 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4158
4159 if (linknum < 0)
4160 return UUID.Zero.ToString();
4161
4162 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4163 if (avatars.Count > linknum)
4164 {
4165 return avatars[linknum].UUID.ToString();
4166 }
4167 }
3783 return UUID.Zero.ToString(); 4168 return UUID.Zero.ToString();
3784 } 4169 }
3785 } 4170 }
@@ -3878,17 +4263,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3878 m_host.AddScriptLPS(1); 4263 m_host.AddScriptLPS(1);
3879 int count = 0; 4264 int count = 0;
3880 4265
3881 lock (m_host.TaskInventory) 4266 m_host.TaskInventory.LockItemsForRead(true);
4267 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3882 { 4268 {
3883 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4269 if (inv.Value.Type == type || type == -1)
3884 { 4270 {
3885 if (inv.Value.Type == type || type == -1) 4271 count = count + 1;
3886 {
3887 count = count + 1;
3888 }
3889 } 4272 }
3890 } 4273 }
3891 4274
4275 m_host.TaskInventory.LockItemsForRead(false);
3892 return count; 4276 return count;
3893 } 4277 }
3894 4278
@@ -3897,16 +4281,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 m_host.AddScriptLPS(1); 4281 m_host.AddScriptLPS(1);
3898 ArrayList keys = new ArrayList(); 4282 ArrayList keys = new ArrayList();
3899 4283
3900 lock (m_host.TaskInventory) 4284 m_host.TaskInventory.LockItemsForRead(true);
4285 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3901 { 4286 {
3902 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4287 if (inv.Value.Type == type || type == -1)
3903 { 4288 {
3904 if (inv.Value.Type == type || type == -1) 4289 keys.Add(inv.Value.Name);
3905 {
3906 keys.Add(inv.Value.Name);
3907 }
3908 } 4290 }
3909 } 4291 }
4292 m_host.TaskInventory.LockItemsForRead(false);
3910 4293
3911 if (keys.Count == 0) 4294 if (keys.Count == 0)
3912 { 4295 {
@@ -3943,25 +4326,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3943 } 4326 }
3944 4327
3945 // move the first object found with this inventory name 4328 // move the first object found with this inventory name
3946 lock (m_host.TaskInventory) 4329 m_host.TaskInventory.LockItemsForRead(true);
4330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3947 { 4331 {
3948 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4332 if (inv.Value.Name == inventory)
3949 { 4333 {
3950 if (inv.Value.Name == inventory) 4334 found = true;
3951 { 4335 objId = inv.Key;
3952 found = true; 4336 assetType = inv.Value.Type;
3953 objId = inv.Key; 4337 objName = inv.Value.Name;
3954 assetType = inv.Value.Type; 4338 break;
3955 objName = inv.Value.Name;
3956 break;
3957 }
3958 } 4339 }
3959 } 4340 }
4341 m_host.TaskInventory.LockItemsForRead(false);
3960 4342
3961 if (!found) 4343 if (!found)
3962 { 4344 {
3963 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4345 llSay(0, String.Format("Could not find object '{0}'", inventory));
3964 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4346 return;
4347// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3965 } 4348 }
3966 4349
3967 // check if destination is an object 4350 // check if destination is an object
@@ -3987,48 +4370,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3987 return; 4370 return;
3988 } 4371 }
3989 } 4372 }
4373
3990 // destination is an avatar 4374 // destination is an avatar
3991 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4375 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3992 4376
3993 if (agentItem == null) 4377 if (agentItem == null)
3994 return; 4378 return;
3995 4379
3996 byte[] bucket = new byte[17]; 4380 byte[] bucket = new byte[1];
3997 bucket[0] = (byte)assetType; 4381 bucket[0] = (byte)assetType;
3998 byte[] objBytes = agentItem.ID.GetBytes(); 4382 //byte[] objBytes = agentItem.ID.GetBytes();
3999 Array.Copy(objBytes, 0, bucket, 1, 16); 4383 //Array.Copy(objBytes, 0, bucket, 1, 16);
4000 4384
4001 GridInstantMessage msg = new GridInstantMessage(World, 4385 GridInstantMessage msg = new GridInstantMessage(World,
4002 m_host.UUID, m_host.Name+", an object owned by "+ 4386 m_host.OwnerID, m_host.Name, destId,
4003 resolveName(m_host.OwnerID)+",", destId,
4004 (byte)InstantMessageDialog.TaskInventoryOffered, 4387 (byte)InstantMessageDialog.TaskInventoryOffered,
4005 false, objName+"\n"+m_host.Name+" is located at "+ 4388 false, objName+". "+m_host.Name+" is located at "+
4006 World.RegionInfo.RegionName+" "+ 4389 World.RegionInfo.RegionName+" "+
4007 m_host.AbsolutePosition.ToString(), 4390 m_host.AbsolutePosition.ToString(),
4008 agentItem.ID, true, m_host.AbsolutePosition, 4391 agentItem.ID, true, m_host.AbsolutePosition,
4009 bucket); 4392 bucket);
4010 if (m_TransferModule != null) 4393
4011 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4394 ScenePresence sp;
4395
4396 if (World.TryGetScenePresence(destId, out sp))
4397 {
4398 sp.ControllingClient.SendInstantMessage(msg);
4399 }
4400 else
4401 {
4402 if (m_TransferModule != null)
4403 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4404 }
4405
4406 //This delay should only occur when giving inventory to avatars.
4012 ScriptSleep(3000); 4407 ScriptSleep(3000);
4013 } 4408 }
4014 } 4409 }
4015 4410
4411 [DebuggerNonUserCode]
4016 public void llRemoveInventory(string name) 4412 public void llRemoveInventory(string name)
4017 { 4413 {
4018 m_host.AddScriptLPS(1); 4414 m_host.AddScriptLPS(1);
4019 4415
4020 lock (m_host.TaskInventory) 4416 List<TaskInventoryItem> inv;
4417 try
4021 { 4418 {
4022 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4419 m_host.TaskInventory.LockItemsForRead(true);
4420 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4421 }
4422 finally
4423 {
4424 m_host.TaskInventory.LockItemsForRead(false);
4425 }
4426 foreach (TaskInventoryItem item in inv)
4427 {
4428 if (item.Name == name)
4023 { 4429 {
4024 if (item.Name == name) 4430 if (item.ItemID == m_itemID)
4025 { 4431 throw new ScriptDeleteException();
4026 if (item.ItemID == m_itemID) 4432 else
4027 throw new ScriptDeleteException(); 4433 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4028 else 4434 return;
4029 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4030 return;
4031 }
4032 } 4435 }
4033 } 4436 }
4034 } 4437 }
@@ -4063,112 +4466,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4063 { 4466 {
4064 m_host.AddScriptLPS(1); 4467 m_host.AddScriptLPS(1);
4065 4468
4066 UUID uuid = (UUID)id; 4469 UUID uuid;
4067 PresenceInfo pinfo = null; 4470 if (UUID.TryParse(id, out uuid))
4068 UserAccount account;
4069
4070 UserInfoCacheEntry ce;
4071 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4072 { 4471 {
4073 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4472 PresenceInfo pinfo = null;
4074 if (account == null) 4473 UserAccount account;
4474
4475 UserInfoCacheEntry ce;
4476 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4075 { 4477 {
4076 m_userInfoCache[uuid] = null; // Cache negative 4478 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4077 return UUID.Zero.ToString(); 4479 if (account == null)
4078 } 4480 {
4481 m_userInfoCache[uuid] = null; // Cache negative
4482 return UUID.Zero.ToString();
4483 }
4079 4484
4080 4485
4081 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4486 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4082 if (pinfos != null && pinfos.Length > 0) 4487 if (pinfos != null && pinfos.Length > 0)
4083 {
4084 foreach (PresenceInfo p in pinfos)
4085 { 4488 {
4086 if (p.RegionID != UUID.Zero) 4489 foreach (PresenceInfo p in pinfos)
4087 { 4490 {
4088 pinfo = p; 4491 if (p.RegionID != UUID.Zero)
4492 {
4493 pinfo = p;
4494 }
4089 } 4495 }
4090 } 4496 }
4091 }
4092 4497
4093 ce = new UserInfoCacheEntry(); 4498 ce = new UserInfoCacheEntry();
4094 ce.time = Util.EnvironmentTickCount(); 4499 ce.time = Util.EnvironmentTickCount();
4095 ce.account = account; 4500 ce.account = account;
4096 ce.pinfo = pinfo; 4501 ce.pinfo = pinfo;
4097 } 4502 m_userInfoCache[uuid] = ce;
4098 else 4503 }
4099 { 4504 else
4100 if (ce == null) 4505 {
4101 return UUID.Zero.ToString(); 4506 if (ce == null)
4507 return UUID.Zero.ToString();
4102 4508
4103 account = ce.account; 4509 account = ce.account;
4104 pinfo = ce.pinfo; 4510 pinfo = ce.pinfo;
4105 } 4511 }
4106 4512
4107 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4513 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4108 {
4109 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4110 if (pinfos != null && pinfos.Length > 0)
4111 { 4514 {
4112 foreach (PresenceInfo p in pinfos) 4515 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4516 if (pinfos != null && pinfos.Length > 0)
4113 { 4517 {
4114 if (p.RegionID != UUID.Zero) 4518 foreach (PresenceInfo p in pinfos)
4115 { 4519 {
4116 pinfo = p; 4520 if (p.RegionID != UUID.Zero)
4521 {
4522 pinfo = p;
4523 }
4117 } 4524 }
4118 } 4525 }
4119 } 4526 else
4120 else 4527 pinfo = null;
4121 pinfo = null;
4122 4528
4123 ce.time = Util.EnvironmentTickCount(); 4529 ce.time = Util.EnvironmentTickCount();
4124 ce.pinfo = pinfo; 4530 ce.pinfo = pinfo;
4125 } 4531 }
4126 4532
4127 string reply = String.Empty; 4533 string reply = String.Empty;
4128 4534
4129 switch (data) 4535 switch (data)
4130 { 4536 {
4131 case 1: // DATA_ONLINE (0|1) 4537 case 1: // DATA_ONLINE (0|1)
4132 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4538 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4133 reply = "1"; 4539 reply = "1";
4134 else 4540 else
4135 reply = "0"; 4541 reply = "0";
4136 break; 4542 break;
4137 case 2: // DATA_NAME (First Last) 4543 case 2: // DATA_NAME (First Last)
4138 reply = account.FirstName + " " + account.LastName; 4544 reply = account.FirstName + " " + account.LastName;
4139 break; 4545 break;
4140 case 3: // DATA_BORN (YYYY-MM-DD) 4546 case 3: // DATA_BORN (YYYY-MM-DD)
4141 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4547 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4142 born = born.AddSeconds(account.Created); 4548 born = born.AddSeconds(account.Created);
4143 reply = born.ToString("yyyy-MM-dd"); 4549 reply = born.ToString("yyyy-MM-dd");
4144 break; 4550 break;
4145 case 4: // DATA_RATING (0,0,0,0,0,0) 4551 case 4: // DATA_RATING (0,0,0,0,0,0)
4146 reply = "0,0,0,0,0,0"; 4552 reply = "0,0,0,0,0,0";
4147 break; 4553 break;
4148 case 8: // DATA_PAYINFO (0|1|2|3) 4554 case 8: // DATA_PAYINFO (0|1|2|3)
4149 reply = "0"; 4555 reply = "0";
4150 break; 4556 break;
4151 default: 4557 default:
4152 return UUID.Zero.ToString(); // Raise no event 4558 return UUID.Zero.ToString(); // Raise no event
4153 } 4559 }
4154 4560
4155 UUID rq = UUID.Random(); 4561 UUID rq = UUID.Random();
4156 4562
4157 UUID tid = AsyncCommands. 4563 UUID tid = AsyncCommands.
4158 DataserverPlugin.RegisterRequest(m_localID, 4564 DataserverPlugin.RegisterRequest(m_localID,
4159 m_itemID, rq.ToString()); 4565 m_itemID, rq.ToString());
4160 4566
4161 AsyncCommands. 4567 AsyncCommands.
4162 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4568 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4163 4569
4164 ScriptSleep(100); 4570 ScriptSleep(100);
4165 return tid.ToString(); 4571 return tid.ToString();
4572 }
4573 else
4574 {
4575 ShoutError("Invalid UUID passed to llRequestAgentData.");
4576 }
4577 return "";
4166 } 4578 }
4167 4579
4168 public LSL_String llRequestInventoryData(string name) 4580 public LSL_String llRequestInventoryData(string name)
4169 { 4581 {
4170 m_host.AddScriptLPS(1); 4582 m_host.AddScriptLPS(1);
4171 4583
4584 //Clone is thread safe
4172 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4585 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4173 4586
4174 foreach (TaskInventoryItem item in itemDictionary.Values) 4587 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4222,6 +4635,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4222 ScenePresence presence = World.GetScenePresence(agentId); 4635 ScenePresence presence = World.GetScenePresence(agentId);
4223 if (presence != null) 4636 if (presence != null)
4224 { 4637 {
4638 // agent must not be a god
4639 if (presence.UserLevel >= 200) return;
4640
4225 // agent must be over the owners land 4641 // agent must be over the owners land
4226 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4642 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4227 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4643 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4244,7 +4660,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4244 UUID av = new UUID(); 4660 UUID av = new UUID();
4245 if (!UUID.TryParse(agent,out av)) 4661 if (!UUID.TryParse(agent,out av))
4246 { 4662 {
4247 LSLError("First parameter to llDialog needs to be a key"); 4663 //LSLError("First parameter to llDialog needs to be a key");
4248 return; 4664 return;
4249 } 4665 }
4250 4666
@@ -4281,17 +4697,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4281 UUID soundId = UUID.Zero; 4697 UUID soundId = UUID.Zero;
4282 if (!UUID.TryParse(impact_sound, out soundId)) 4698 if (!UUID.TryParse(impact_sound, out soundId))
4283 { 4699 {
4284 lock (m_host.TaskInventory) 4700 m_host.TaskInventory.LockItemsForRead(true);
4701 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4285 { 4702 {
4286 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4703 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4287 { 4704 {
4288 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4705 soundId = item.AssetID;
4289 { 4706 break;
4290 soundId = item.AssetID;
4291 break;
4292 }
4293 } 4707 }
4294 } 4708 }
4709 m_host.TaskInventory.LockItemsForRead(false);
4295 } 4710 }
4296 m_host.CollisionSound = soundId; 4711 m_host.CollisionSound = soundId;
4297 m_host.CollisionSoundVolume = (float)impact_volume; 4712 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4331,6 +4746,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4331 UUID partItemID; 4746 UUID partItemID;
4332 foreach (SceneObjectPart part in parts) 4747 foreach (SceneObjectPart part in parts)
4333 { 4748 {
4749 //Clone is thread safe
4334 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4750 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4335 4751
4336 foreach (TaskInventoryItem item in itemsDictionary.Values) 4752 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4545,17 +4961,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4545 4961
4546 m_host.AddScriptLPS(1); 4962 m_host.AddScriptLPS(1);
4547 4963
4548 lock (m_host.TaskInventory) 4964 m_host.TaskInventory.LockItemsForRead(true);
4965 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4549 { 4966 {
4550 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4967 if (item.Type == 10 && item.ItemID == m_itemID)
4551 { 4968 {
4552 if (item.Type == 10 && item.ItemID == m_itemID) 4969 result = item.Name!=null?item.Name:String.Empty;
4553 { 4970 break;
4554 result = item.Name != null ? item.Name : String.Empty;
4555 break;
4556 }
4557 } 4971 }
4558 } 4972 }
4973 m_host.TaskInventory.LockItemsForRead(false);
4559 4974
4560 return result; 4975 return result;
4561 } 4976 }
@@ -4728,23 +5143,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4728 { 5143 {
4729 m_host.AddScriptLPS(1); 5144 m_host.AddScriptLPS(1);
4730 5145
4731 lock (m_host.TaskInventory) 5146 m_host.TaskInventory.LockItemsForRead(true);
5147 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4732 { 5148 {
4733 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5149 if (inv.Value.Name == name)
4734 { 5150 {
4735 if (inv.Value.Name == name) 5151 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4736 { 5152 {
4737 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5153 m_host.TaskInventory.LockItemsForRead(false);
4738 { 5154 return inv.Value.AssetID.ToString();
4739 return inv.Value.AssetID.ToString(); 5155 }
4740 } 5156 else
4741 else 5157 {
4742 { 5158 m_host.TaskInventory.LockItemsForRead(false);
4743 return UUID.Zero.ToString(); 5159 return UUID.Zero.ToString();
4744 }
4745 } 5160 }
4746 } 5161 }
4747 } 5162 }
5163 m_host.TaskInventory.LockItemsForRead(false);
4748 5164
4749 return UUID.Zero.ToString(); 5165 return UUID.Zero.ToString();
4750 } 5166 }
@@ -4897,14 +5313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4897 { 5313 {
4898 m_host.AddScriptLPS(1); 5314 m_host.AddScriptLPS(1);
4899 5315
4900 if (src == null) 5316 return src.Length;
4901 {
4902 return 0;
4903 }
4904 else
4905 {
4906 return src.Length;
4907 }
4908 } 5317 }
4909 5318
4910 public LSL_Integer llList2Integer(LSL_List src, int index) 5319 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4950,7 +5359,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4950 else if (src.Data[index] is LSL_Float) 5359 else if (src.Data[index] is LSL_Float)
4951 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5360 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4952 else if (src.Data[index] is LSL_String) 5361 else if (src.Data[index] is LSL_String)
4953 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5362 {
5363 string str = ((LSL_String) src.Data[index]).m_string;
5364 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5365 if (m != Match.Empty)
5366 {
5367 str = m.Value;
5368 double d = 0.0;
5369 if (!Double.TryParse(str, out d))
5370 return 0.0;
5371
5372 return d;
5373 }
5374 return 0.0;
5375 }
4954 return Convert.ToDouble(src.Data[index]); 5376 return Convert.ToDouble(src.Data[index]);
4955 } 5377 }
4956 catch (FormatException) 5378 catch (FormatException)
@@ -5223,7 +5645,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5223 } 5645 }
5224 } 5646 }
5225 } 5647 }
5226 else { 5648 else
5649 {
5227 object[] array = new object[src.Length]; 5650 object[] array = new object[src.Length];
5228 Array.Copy(src.Data, 0, array, 0, src.Length); 5651 Array.Copy(src.Data, 0, array, 0, src.Length);
5229 result = new LSL_List(array); 5652 result = new LSL_List(array);
@@ -5672,10 +6095,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5672 m_host.AddScriptLPS(1); 6095 m_host.AddScriptLPS(1);
5673 6096
5674 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6097 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5675 6098 if (parts.Count > 0)
5676 foreach (var part in parts)
5677 { 6099 {
5678 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6100 try
6101 {
6102 parts[0].ParentGroup.areUpdatesSuspended = true;
6103 foreach (var part in parts)
6104 {
6105 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6106 }
6107 }
6108 finally
6109 {
6110 parts[0].ParentGroup.areUpdatesSuspended = false;
6111 }
5679 } 6112 }
5680 } 6113 }
5681 6114
@@ -5729,6 +6162,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5729 ScriptSleep(5000); 6162 ScriptSleep(5000);
5730 } 6163 }
5731 6164
6165 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6166 {
6167 return ParseString2List(str, separators, in_spacers, false);
6168 }
6169
5732 public LSL_Integer llOverMyLand(string id) 6170 public LSL_Integer llOverMyLand(string id)
5733 { 6171 {
5734 m_host.AddScriptLPS(1); 6172 m_host.AddScriptLPS(1);
@@ -5793,8 +6231,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5793 UUID agentId = new UUID(); 6231 UUID agentId = new UUID();
5794 if (!UUID.TryParse(agent, out agentId)) 6232 if (!UUID.TryParse(agent, out agentId))
5795 return new LSL_Integer(0); 6233 return new LSL_Integer(0);
6234 if (agentId == m_host.GroupID)
6235 return new LSL_Integer(1);
5796 ScenePresence presence = World.GetScenePresence(agentId); 6236 ScenePresence presence = World.GetScenePresence(agentId);
5797 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6237 if (presence == null || presence.IsChildAgent) // Return false for child agents
5798 return new LSL_Integer(0); 6238 return new LSL_Integer(0);
5799 IClientAPI client = presence.ControllingClient; 6239 IClientAPI client = presence.ControllingClient;
5800 if (m_host.GroupID == client.ActiveGroupId) 6240 if (m_host.GroupID == client.ActiveGroupId)
@@ -5929,7 +6369,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5929 return m_host.ParentGroup.AttachmentPoint; 6369 return m_host.ParentGroup.AttachmentPoint;
5930 } 6370 }
5931 6371
5932 public LSL_Integer llGetFreeMemory() 6372 public virtual LSL_Integer llGetFreeMemory()
5933 { 6373 {
5934 m_host.AddScriptLPS(1); 6374 m_host.AddScriptLPS(1);
5935 // Make scripts designed for LSO happy 6375 // Make scripts designed for LSO happy
@@ -6046,7 +6486,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6046 SetParticleSystem(m_host, rules); 6486 SetParticleSystem(m_host, rules);
6047 } 6487 }
6048 6488
6049 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6489 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6490 {
6050 6491
6051 6492
6052 if (rules.Length == 0) 6493 if (rules.Length == 0)
@@ -6240,14 +6681,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6240 6681
6241 protected UUID GetTaskInventoryItem(string name) 6682 protected UUID GetTaskInventoryItem(string name)
6242 { 6683 {
6243 lock (m_host.TaskInventory) 6684 m_host.TaskInventory.LockItemsForRead(true);
6685 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6244 { 6686 {
6245 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6687 if (inv.Value.Name == name)
6246 { 6688 {
6247 if (inv.Value.Name == name) 6689 m_host.TaskInventory.LockItemsForRead(false);
6248 return inv.Key; 6690 return inv.Key;
6249 } 6691 }
6250 } 6692 }
6693 m_host.TaskInventory.LockItemsForRead(false);
6251 6694
6252 return UUID.Zero; 6695 return UUID.Zero;
6253 } 6696 }
@@ -6285,16 +6728,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6285 if (folderID == UUID.Zero) 6728 if (folderID == UUID.Zero)
6286 return; 6729 return;
6287 6730
6288 byte[] bucket = new byte[17]; 6731 byte[] bucket = new byte[1];
6289 bucket[0] = (byte)AssetType.Folder; 6732 bucket[0] = (byte)AssetType.Folder;
6290 byte[] objBytes = folderID.GetBytes(); 6733 //byte[] objBytes = folderID.GetBytes();
6291 Array.Copy(objBytes, 0, bucket, 1, 16); 6734 //Array.Copy(objBytes, 0, bucket, 1, 16);
6292 6735
6293 GridInstantMessage msg = new GridInstantMessage(World, 6736 GridInstantMessage msg = new GridInstantMessage(World,
6294 m_host.UUID, m_host.Name+", an object owned by "+ 6737 m_host.OwnerID, m_host.Name, destID,
6295 resolveName(m_host.OwnerID)+",", destID, 6738 (byte)InstantMessageDialog.TaskInventoryOffered,
6296 (byte)InstantMessageDialog.InventoryOffered, 6739 false, category+". "+m_host.Name+" is located at "+
6297 false, category+"\n"+m_host.Name+" is located at "+
6298 World.RegionInfo.RegionName+" "+ 6740 World.RegionInfo.RegionName+" "+
6299 m_host.AbsolutePosition.ToString(), 6741 m_host.AbsolutePosition.ToString(),
6300 folderID, true, m_host.AbsolutePosition, 6742 folderID, true, m_host.AbsolutePosition,
@@ -6497,13 +6939,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6497 UUID av = new UUID(); 6939 UUID av = new UUID();
6498 if (!UUID.TryParse(avatar,out av)) 6940 if (!UUID.TryParse(avatar,out av))
6499 { 6941 {
6500 LSLError("First parameter to llDialog needs to be a key"); 6942 //LSLError("First parameter to llDialog needs to be a key");
6501 return; 6943 return;
6502 } 6944 }
6503 if (buttons.Length < 1) 6945 if (buttons.Length < 1)
6504 { 6946 {
6505 LSLError("No less than 1 button can be shown"); 6947 buttons.Add("OK");
6506 return;
6507 } 6948 }
6508 if (buttons.Length > 12) 6949 if (buttons.Length > 12)
6509 { 6950 {
@@ -6520,7 +6961,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6520 } 6961 }
6521 if (buttons.Data[i].ToString().Length > 24) 6962 if (buttons.Data[i].ToString().Length > 24)
6522 { 6963 {
6523 LSLError("button label cannot be longer than 24 characters"); 6964 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6524 return; 6965 return;
6525 } 6966 }
6526 buts[i] = buttons.Data[i].ToString(); 6967 buts[i] = buttons.Data[i].ToString();
@@ -6579,22 +7020,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6579 } 7020 }
6580 7021
6581 // copy the first script found with this inventory name 7022 // copy the first script found with this inventory name
6582 lock (m_host.TaskInventory) 7023 TaskInventoryItem scriptItem = null;
7024 m_host.TaskInventory.LockItemsForRead(true);
7025 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6583 { 7026 {
6584 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7027 if (inv.Value.Name == name)
6585 { 7028 {
6586 if (inv.Value.Name == name) 7029 // make sure the object is a script
7030 if (10 == inv.Value.Type)
6587 { 7031 {
6588 // make sure the object is a script 7032 found = true;
6589 if (10 == inv.Value.Type) 7033 srcId = inv.Key;
6590 { 7034 scriptItem = inv.Value;
6591 found = true; 7035 break;
6592 srcId = inv.Key;
6593 break;
6594 }
6595 } 7036 }
6596 } 7037 }
6597 } 7038 }
7039 m_host.TaskInventory.LockItemsForRead(false);
6598 7040
6599 if (!found) 7041 if (!found)
6600 { 7042 {
@@ -6602,8 +7044,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6602 return; 7044 return;
6603 } 7045 }
6604 7046
6605 // the rest of the permission checks are done in RezScript, so check the pin there as well 7047 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6606 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7048 if (dest != null)
7049 {
7050 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7051 {
7052 // the rest of the permission checks are done in RezScript, so check the pin there as well
7053 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7054
7055 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7056 m_host.Inventory.RemoveInventoryItem(srcId);
7057 }
7058 }
6607 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7059 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6608 ScriptSleep(3000); 7060 ScriptSleep(3000);
6609 } 7061 }
@@ -6666,19 +7118,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6666 public LSL_String llMD5String(string src, int nonce) 7118 public LSL_String llMD5String(string src, int nonce)
6667 { 7119 {
6668 m_host.AddScriptLPS(1); 7120 m_host.AddScriptLPS(1);
6669 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7121 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6670 } 7122 }
6671 7123
6672 public LSL_String llSHA1String(string src) 7124 public LSL_String llSHA1String(string src)
6673 { 7125 {
6674 m_host.AddScriptLPS(1); 7126 m_host.AddScriptLPS(1);
6675 return Util.SHA1Hash(src).ToLower(); 7127 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6676 } 7128 }
6677 7129
6678 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7130 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6679 { 7131 {
6680 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7132 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6681 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7133 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7134 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7135 return shapeBlock;
6682 7136
6683 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7137 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6684 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7138 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6783,6 +7237,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6783 // Prim type box, cylinder and prism. 7237 // Prim type box, cylinder and prism.
6784 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) 7238 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)
6785 { 7239 {
7240 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7241 return;
7242
6786 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7243 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6787 ObjectShapePacket.ObjectDataBlock shapeBlock; 7244 ObjectShapePacket.ObjectDataBlock shapeBlock;
6788 7245
@@ -6836,6 +7293,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6836 // Prim type sphere. 7293 // Prim type sphere.
6837 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7294 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6838 { 7295 {
7296 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7297 return;
7298
6839 ObjectShapePacket.ObjectDataBlock shapeBlock; 7299 ObjectShapePacket.ObjectDataBlock shapeBlock;
6840 7300
6841 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7301 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6877,6 +7337,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 // Prim type torus, tube and ring. 7337 // Prim type torus, tube and ring.
6878 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) 7338 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)
6879 { 7339 {
7340 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7341 return;
7342
6880 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7343 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6881 ObjectShapePacket.ObjectDataBlock shapeBlock; 7344 ObjectShapePacket.ObjectDataBlock shapeBlock;
6882 7345
@@ -7012,6 +7475,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7012 // Prim type sculpt. 7475 // Prim type sculpt.
7013 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7476 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7014 { 7477 {
7478 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7479 return;
7480
7015 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7481 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7016 UUID sculptId; 7482 UUID sculptId;
7017 7483
@@ -7028,13 +7494,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7028 shapeBlock.PathScaleX = 100; 7494 shapeBlock.PathScaleX = 100;
7029 shapeBlock.PathScaleY = 150; 7495 shapeBlock.PathScaleY = 150;
7030 7496
7031 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7497 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7032 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7498 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7033 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7499 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7034 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7500 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7035 { 7501 {
7036 // default 7502 // default
7037 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7503 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7038 } 7504 }
7039 7505
7040 part.Shape.SetSculptProperties((byte)type, sculptId); 7506 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7050,32 +7516,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7050 ScriptSleep(200); 7516 ScriptSleep(200);
7051 } 7517 }
7052 7518
7053 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7519 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7054 { 7520 {
7055 m_host.AddScriptLPS(1); 7521 m_host.AddScriptLPS(1);
7056 7522
7057 setLinkPrimParams(linknumber, rules); 7523 setLinkPrimParams(linknumber, rules);
7058
7059 ScriptSleep(200);
7060 } 7524 }
7061 7525
7062 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7526 private void setLinkPrimParams(int linknumber, LSL_List rules)
7063 { 7527 {
7064 m_host.AddScriptLPS(1); 7528 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7529 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7530 if (parts.Count>0)
7531 {
7532 try
7533 {
7534 parts[0].ParentGroup.areUpdatesSuspended = true;
7535 foreach (SceneObjectPart part in parts)
7536 SetPrimParams(part, rules);
7537 }
7538 finally
7539 {
7540 parts[0].ParentGroup.areUpdatesSuspended = false;
7541 }
7542 }
7543 if (avatars.Count > 0)
7544 {
7545 foreach (ScenePresence avatar in avatars)
7546 SetPrimParams(avatar, rules);
7547 }
7548 }
7065 7549
7066 setLinkPrimParams(linknumber, rules); 7550 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7551 {
7552 llSetLinkPrimitiveParamsFast(linknumber, rules);
7553 ScriptSleep(200);
7067 } 7554 }
7068 7555
7069 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7556 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7070 { 7557 {
7071 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7558 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7559 //We only support PRIM_POSITION and PRIM_ROTATION
7072 7560
7073 foreach (SceneObjectPart part in parts) 7561 int idx = 0;
7074 SetPrimParams(part, rules); 7562
7563 while (idx < rules.Length)
7564 {
7565 int code = rules.GetLSLIntegerItem(idx++);
7566
7567 int remain = rules.Length - idx;
7568
7569
7570
7571 switch (code)
7572 {
7573 case (int)ScriptBaseClass.PRIM_POSITION:
7574 if (remain < 1)
7575 return;
7576 LSL_Vector v;
7577 v = rules.GetVector3Item(idx++);
7578 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7579 av.SendAvatarDataToAllAgents();
7580
7581 break;
7582
7583 case (int)ScriptBaseClass.PRIM_ROTATION:
7584 if (remain < 1)
7585 return;
7586 LSL_Rotation r;
7587 r = rules.GetQuaternionItem(idx++);
7588 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7589 av.SendAvatarDataToAllAgents();
7590 break;
7591 }
7592 }
7075 } 7593 }
7076 7594
7077 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7595 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7078 { 7596 {
7597 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7598 return;
7599
7079 int idx = 0; 7600 int idx = 0;
7080 7601
7081 bool positionChanged = false; 7602 bool positionChanged = false;
@@ -7103,6 +7624,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7103 currentPosition = GetSetPosTarget(part, v, currentPosition); 7624 currentPosition = GetSetPosTarget(part, v, currentPosition);
7104 7625
7105 break; 7626 break;
7627 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7628 if (remain < 1)
7629 return;
7630
7631 v=rules.GetVector3Item(idx++);
7632 positionChanged = true;
7633 currentPosition = GetSetPosTarget(part, v, currentPosition);
7634
7635 break;
7106 case (int)ScriptBaseClass.PRIM_SIZE: 7636 case (int)ScriptBaseClass.PRIM_SIZE:
7107 if (remain < 1) 7637 if (remain < 1)
7108 return; 7638 return;
@@ -7480,6 +8010,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7480 } 8010 }
7481 } 8011 }
7482 } 8012 }
8013
8014 if (positionChanged)
8015 {
8016 if (part.ParentGroup.RootPart == part)
8017 {
8018 SceneObjectGroup parent = part.ParentGroup;
8019 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8020 }
8021 else
8022 {
8023 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8024 SceneObjectGroup parent = part.ParentGroup;
8025 parent.HasGroupChanged = true;
8026 parent.ScheduleGroupForTerseUpdate();
8027 }
8028 }
7483 } 8029 }
7484 8030
7485 public LSL_String llStringToBase64(string str) 8031 public LSL_String llStringToBase64(string str)
@@ -7628,13 +8174,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7628 public LSL_Integer llGetNumberOfPrims() 8174 public LSL_Integer llGetNumberOfPrims()
7629 { 8175 {
7630 m_host.AddScriptLPS(1); 8176 m_host.AddScriptLPS(1);
7631 int avatarCount = 0; 8177 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7632 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8178
7633 {
7634 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7635 avatarCount++;
7636 });
7637
7638 return m_host.ParentGroup.PrimCount + avatarCount; 8179 return m_host.ParentGroup.PrimCount + avatarCount;
7639 } 8180 }
7640 8181
@@ -7650,55 +8191,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7650 m_host.AddScriptLPS(1); 8191 m_host.AddScriptLPS(1);
7651 UUID objID = UUID.Zero; 8192 UUID objID = UUID.Zero;
7652 LSL_List result = new LSL_List(); 8193 LSL_List result = new LSL_List();
8194
8195 // If the ID is not valid, return null result
7653 if (!UUID.TryParse(obj, out objID)) 8196 if (!UUID.TryParse(obj, out objID))
7654 { 8197 {
7655 result.Add(new LSL_Vector()); 8198 result.Add(new LSL_Vector());
7656 result.Add(new LSL_Vector()); 8199 result.Add(new LSL_Vector());
7657 return result; 8200 return result;
7658 } 8201 }
8202
8203 // Check if this is an attached prim. If so, replace
8204 // the UUID with the avatar UUID and report it's bounding box
8205 SceneObjectPart part = World.GetSceneObjectPart(objID);
8206 if (part != null && part.ParentGroup.IsAttachment)
8207 objID = part.ParentGroup.AttachedAvatar;
8208
8209 // Find out if this is an avatar ID. If so, return it's box
7659 ScenePresence presence = World.GetScenePresence(objID); 8210 ScenePresence presence = World.GetScenePresence(objID);
7660 if (presence != null) 8211 if (presence != null)
7661 { 8212 {
7662 if (presence.ParentID == 0) // not sat on an object 8213 // As per LSL Wiki, there is no difference between sitting
8214 // and standing avatar since server 1.36
8215 LSL_Vector lower;
8216 LSL_Vector upper;
8217 if (presence.Animator.Animations.DefaultAnimation.AnimID
8218 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7663 { 8219 {
7664 LSL_Vector lower; 8220 // This is for ground sitting avatars
7665 LSL_Vector upper; 8221 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7666 if (presence.Animator.Animations.DefaultAnimation.AnimID 8222 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7667 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8223 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7668 {
7669 // This is for ground sitting avatars
7670 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7671 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7672 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7673 }
7674 else
7675 {
7676 // This is for standing/flying avatars
7677 float height = presence.Appearance.AvatarHeight / 2.0f;
7678 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7679 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7680 }
7681 result.Add(lower);
7682 result.Add(upper);
7683 return result;
7684 } 8224 }
7685 else 8225 else
7686 { 8226 {
7687 // sitting on an object so we need the bounding box of that 8227 // This is for standing/flying avatars
7688 // which should include the avatar so set the UUID to the 8228 float height = presence.Appearance.AvatarHeight / 2.0f;
7689 // UUID of the object the avatar is sat on and allow it to fall through 8229 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7690 // to processing an object 8230 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7691 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7692 objID = p.UUID;
7693 } 8231 }
8232
8233 // Adjust to the documented error offsets (see LSL Wiki)
8234 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8235 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8236
8237 if (lower.x > upper.x)
8238 lower.x = upper.x;
8239 if (lower.y > upper.y)
8240 lower.y = upper.y;
8241 if (lower.z > upper.z)
8242 lower.z = upper.z;
8243
8244 result.Add(lower);
8245 result.Add(upper);
8246 return result;
7694 } 8247 }
7695 SceneObjectPart part = World.GetSceneObjectPart(objID); 8248
8249 part = World.GetSceneObjectPart(objID);
7696 // Currently only works for single prims without a sitting avatar 8250 // Currently only works for single prims without a sitting avatar
7697 if (part != null) 8251 if (part != null)
7698 { 8252 {
7699 Vector3 halfSize = part.Scale / 2.0f; 8253 float minX;
7700 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8254 float maxX;
7701 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8255 float minY;
8256 float maxY;
8257 float minZ;
8258 float maxZ;
8259
8260 // This BBox is in sim coordinates, with the offset being
8261 // a contained point.
8262 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8263 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8264
8265 minX -= offsets[0].X;
8266 maxX -= offsets[0].X;
8267 minY -= offsets[0].Y;
8268 maxY -= offsets[0].Y;
8269 minZ -= offsets[0].Z;
8270 maxZ -= offsets[0].Z;
8271
8272 LSL_Vector lower;
8273 LSL_Vector upper;
8274
8275 // Adjust to the documented error offsets (see LSL Wiki)
8276 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8277 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8278
8279 if (lower.x > upper.x)
8280 lower.x = upper.x;
8281 if (lower.y > upper.y)
8282 lower.y = upper.y;
8283 if (lower.z > upper.z)
8284 lower.z = upper.z;
8285
7702 result.Add(lower); 8286 result.Add(lower);
7703 result.Add(upper); 8287 result.Add(upper);
7704 return result; 8288 return result;
@@ -7778,13 +8362,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7778 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8362 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7779 part.AbsolutePosition.Y, 8363 part.AbsolutePosition.Y,
7780 part.AbsolutePosition.Z); 8364 part.AbsolutePosition.Z);
7781 // For some reason, the part.AbsolutePosition.* values do not change if the
7782 // linkset is rotated; they always reflect the child prim's world position
7783 // as though the linkset is unrotated. This is incompatible behavior with SL's
7784 // implementation, so will break scripts imported from there (not to mention it
7785 // makes it more difficult to determine a child prim's actual inworld position).
7786 if (part.ParentID != 0)
7787 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7788 res.Add(v); 8365 res.Add(v);
7789 break; 8366 break;
7790 8367
@@ -7955,56 +8532,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7955 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8532 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7956 if (remain < 1) 8533 if (remain < 1)
7957 return res; 8534 return res;
7958 8535 face = (int)rules.GetLSLIntegerItem(idx++);
7959 face=(int)rules.GetLSLIntegerItem(idx++);
7960 8536
7961 tex = part.Shape.Textures; 8537 tex = part.Shape.Textures;
8538 int shiny;
7962 if (face == ScriptBaseClass.ALL_SIDES) 8539 if (face == ScriptBaseClass.ALL_SIDES)
7963 { 8540 {
7964 for (face = 0; face < GetNumberOfSides(part); face++) 8541 for (face = 0; face < GetNumberOfSides(part); face++)
7965 { 8542 {
7966 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8543 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7967 // Convert Shininess to PRIM_SHINY_* 8544 if (shinyness == Shininess.High)
7968 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8545 {
7969 // PRIM_BUMP_* 8546 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7970 res.Add(new LSL_Integer((int)texface.Bump)); 8547 }
8548 else if (shinyness == Shininess.Medium)
8549 {
8550 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8551 }
8552 else if (shinyness == Shininess.Low)
8553 {
8554 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8555 }
8556 else
8557 {
8558 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8559 }
8560 res.Add(new LSL_Integer(shiny));
8561 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7971 } 8562 }
7972 } 8563 }
7973 else 8564 else
7974 { 8565 {
7975 if (face >= 0 && face < GetNumberOfSides(part)) 8566 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8567 if (shinyness == Shininess.High)
7976 { 8568 {
7977 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8569 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7978 // Convert Shininess to PRIM_SHINY_* 8570 }
7979 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8571 else if (shinyness == Shininess.Medium)
7980 // PRIM_BUMP_* 8572 {
7981 res.Add(new LSL_Integer((int)texface.Bump)); 8573 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8574 }
8575 else if (shinyness == Shininess.Low)
8576 {
8577 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
7982 } 8578 }
8579 else
8580 {
8581 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8582 }
8583 res.Add(new LSL_Integer(shiny));
8584 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7983 } 8585 }
7984 break; 8586 break;
7985 8587
7986 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8588 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7987 if (remain < 1) 8589 if (remain < 1)
7988 return res; 8590 return res;
7989 8591 face = (int)rules.GetLSLIntegerItem(idx++);
7990 face=(int)rules.GetLSLIntegerItem(idx++);
7991 8592
7992 tex = part.Shape.Textures; 8593 tex = part.Shape.Textures;
8594 int fullbright;
7993 if (face == ScriptBaseClass.ALL_SIDES) 8595 if (face == ScriptBaseClass.ALL_SIDES)
7994 { 8596 {
7995 for (face = 0; face < GetNumberOfSides(part); face++) 8597 for (face = 0; face < GetNumberOfSides(part); face++)
7996 { 8598 {
7997 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8599 if (tex.GetFace((uint)face).Fullbright == true)
7998 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8600 {
8601 fullbright = ScriptBaseClass.TRUE;
8602 }
8603 else
8604 {
8605 fullbright = ScriptBaseClass.FALSE;
8606 }
8607 res.Add(new LSL_Integer(fullbright));
7999 } 8608 }
8000 } 8609 }
8001 else 8610 else
8002 { 8611 {
8003 if (face >= 0 && face < GetNumberOfSides(part)) 8612 if (tex.GetFace((uint)face).Fullbright == true)
8004 { 8613 {
8005 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8614 fullbright = ScriptBaseClass.TRUE;
8006 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8007 } 8615 }
8616 else
8617 {
8618 fullbright = ScriptBaseClass.FALSE;
8619 }
8620 res.Add(new LSL_Integer(fullbright));
8008 } 8621 }
8009 break; 8622 break;
8010 8623
@@ -8026,27 +8639,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8026 break; 8639 break;
8027 8640
8028 case (int)ScriptBaseClass.PRIM_TEXGEN: 8641 case (int)ScriptBaseClass.PRIM_TEXGEN:
8642 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8029 if (remain < 1) 8643 if (remain < 1)
8030 return res; 8644 return res;
8031 8645 face = (int)rules.GetLSLIntegerItem(idx++);
8032 face=(int)rules.GetLSLIntegerItem(idx++);
8033 8646
8034 tex = part.Shape.Textures; 8647 tex = part.Shape.Textures;
8035 if (face == ScriptBaseClass.ALL_SIDES) 8648 if (face == ScriptBaseClass.ALL_SIDES)
8036 { 8649 {
8037 for (face = 0; face < GetNumberOfSides(part); face++) 8650 for (face = 0; face < GetNumberOfSides(part); face++)
8038 { 8651 {
8039 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8652 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8040 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8653 {
8041 res.Add(new LSL_Integer((uint)texgen >> 1)); 8654 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8655 }
8656 else
8657 {
8658 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8659 }
8042 } 8660 }
8043 } 8661 }
8044 else 8662 else
8045 { 8663 {
8046 if (face >= 0 && face < GetNumberOfSides(part)) 8664 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8665 {
8666 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8667 }
8668 else
8047 { 8669 {
8048 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8670 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8049 res.Add(new LSL_Integer((uint)texgen >> 1));
8050 } 8671 }
8051 } 8672 }
8052 break; 8673 break;
@@ -8069,28 +8690,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8069 case (int)ScriptBaseClass.PRIM_GLOW: 8690 case (int)ScriptBaseClass.PRIM_GLOW:
8070 if (remain < 1) 8691 if (remain < 1)
8071 return res; 8692 return res;
8072 8693 face = (int)rules.GetLSLIntegerItem(idx++);
8073 face=(int)rules.GetLSLIntegerItem(idx++);
8074 8694
8075 tex = part.Shape.Textures; 8695 tex = part.Shape.Textures;
8696 float primglow;
8076 if (face == ScriptBaseClass.ALL_SIDES) 8697 if (face == ScriptBaseClass.ALL_SIDES)
8077 { 8698 {
8078 for (face = 0; face < GetNumberOfSides(part); face++) 8699 for (face = 0; face < GetNumberOfSides(part); face++)
8079 { 8700 {
8080 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8701 primglow = tex.GetFace((uint)face).Glow;
8081 res.Add(new LSL_Float(texface.Glow)); 8702 res.Add(new LSL_Float(primglow));
8082 } 8703 }
8083 } 8704 }
8084 else 8705 else
8085 { 8706 {
8086 if (face >= 0 && face < GetNumberOfSides(part)) 8707 primglow = tex.GetFace((uint)face).Glow;
8087 { 8708 res.Add(new LSL_Float(primglow));
8088 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8089 res.Add(new LSL_Float(texface.Glow));
8090 }
8091 } 8709 }
8092 break; 8710 break;
8093
8094 case (int)ScriptBaseClass.PRIM_TEXT: 8711 case (int)ScriptBaseClass.PRIM_TEXT:
8095 Color4 textColor = part.GetTextColor(); 8712 Color4 textColor = part.GetTextColor();
8096 res.Add(new LSL_String(part.Text)); 8713 res.Add(new LSL_String(part.Text));
@@ -8642,8 +9259,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8642 // The function returns an ordered list 9259 // The function returns an ordered list
8643 // representing the tokens found in the supplied 9260 // representing the tokens found in the supplied
8644 // sources string. If two successive tokenizers 9261 // sources string. If two successive tokenizers
8645 // are encountered, then a NULL entry is added 9262 // are encountered, then a null-string entry is
8646 // to the list. 9263 // added to the list.
8647 // 9264 //
8648 // It is a precondition that the source and 9265 // It is a precondition that the source and
8649 // toekizer lisst are non-null. If they are null, 9266 // toekizer lisst are non-null. If they are null,
@@ -8651,7 +9268,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8651 // while their lengths are being determined. 9268 // while their lengths are being determined.
8652 // 9269 //
8653 // A small amount of working memoryis required 9270 // A small amount of working memoryis required
8654 // of approximately 8*#tokenizers. 9271 // of approximately 8*#tokenizers + 8*srcstrlen.
8655 // 9272 //
8656 // There are many ways in which this function 9273 // There are many ways in which this function
8657 // can be implemented, this implementation is 9274 // can be implemented, this implementation is
@@ -8667,155 +9284,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8667 // and eliminates redundant tokenizers as soon 9284 // and eliminates redundant tokenizers as soon
8668 // as is possible. 9285 // as is possible.
8669 // 9286 //
8670 // The implementation tries to avoid any copying 9287 // The implementation tries to minimize temporary
8671 // of arrays or other objects. 9288 // garbage generation.
8672 // </remarks> 9289 // </remarks>
8673 9290
8674 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9291 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8675 { 9292 {
8676 int beginning = 0; 9293 return ParseString2List(src, separators, spacers, true);
8677 int srclen = src.Length; 9294 }
8678 int seplen = separators.Length;
8679 object[] separray = separators.Data;
8680 int spclen = spacers.Length;
8681 object[] spcarray = spacers.Data;
8682 int mlen = seplen+spclen;
8683
8684 int[] offset = new int[mlen+1];
8685 bool[] active = new bool[mlen];
8686
8687 int best;
8688 int j;
8689
8690 // Initial capacity reduces resize cost
8691 9295
8692 LSL_List tokens = new LSL_List(); 9296 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9297 {
9298 int srclen = src.Length;
9299 int seplen = separators.Length;
9300 object[] separray = separators.Data;
9301 int spclen = spacers.Length;
9302 object[] spcarray = spacers.Data;
9303 int dellen = 0;
9304 string[] delarray = new string[seplen+spclen];
8693 9305
8694 // All entries are initially valid 9306 int outlen = 0;
9307 string[] outarray = new string[srclen*2+1];
8695 9308
8696 for (int i = 0; i < mlen; i++) 9309 int i, j;
8697 active[i] = true; 9310 string d;
8698 9311
8699 offset[mlen] = srclen; 9312 m_host.AddScriptLPS(1);
8700 9313
8701 while (beginning < srclen) 9314 /*
9315 * Convert separator and spacer lists to C# strings.
9316 * Also filter out null strings so we don't hang.
9317 */
9318 for (i = 0; i < seplen; i ++)
8702 { 9319 {
9320 d = separray[i].ToString();
9321 if (d.Length > 0)
9322 {
9323 delarray[dellen++] = d;
9324 }
9325 }
9326 seplen = dellen;
8703 9327
8704 best = mlen; // as bad as it gets 9328 for (i = 0; i < spclen; i ++)
9329 {
9330 d = spcarray[i].ToString();
9331 if (d.Length > 0)
9332 {
9333 delarray[dellen++] = d;
9334 }
9335 }
8705 9336
8706 // Scan for separators 9337 /*
9338 * Scan through source string from beginning to end.
9339 */
9340 for (i = 0;;)
9341 {
8707 9342
8708 for (j = 0; j < seplen; j++) 9343 /*
9344 * Find earliest delimeter in src starting at i (if any).
9345 */
9346 int earliestDel = -1;
9347 int earliestSrc = srclen;
9348 string earliestStr = null;
9349 for (j = 0; j < dellen; j ++)
8709 { 9350 {
8710 if (separray[j].ToString() == String.Empty) 9351 d = delarray[j];
8711 active[j] = false; 9352 if (d != null)
8712
8713 if (active[j])
8714 { 9353 {
8715 // scan all of the markers 9354 int index = src.IndexOf(d, i);
8716 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9355 if (index < 0)
8717 { 9356 {
8718 // not present at all 9357 delarray[j] = null; // delim nowhere in src, don't check it anymore
8719 active[j] = false;
8720 } 9358 }
8721 else 9359 else if (index < earliestSrc)
8722 { 9360 {
8723 // present and correct 9361 earliestSrc = index; // where delimeter starts in source string
8724 if (offset[j] < offset[best]) 9362 earliestDel = j; // where delimeter is in delarray[]
8725 { 9363 earliestStr = d; // the delimeter string from delarray[]
8726 // closest so far 9364 if (index == i) break; // can't do any better than found at beg of string
8727 best = j;
8728 if (offset[best] == beginning)
8729 break;
8730 }
8731 } 9365 }
8732 } 9366 }
8733 } 9367 }
8734 9368
8735 // Scan for spacers 9369 /*
8736 9370 * Output source string starting at i through start of earliest delimeter.
8737 if (offset[best] != beginning) 9371 */
9372 if (keepNulls || (earliestSrc > i))
8738 { 9373 {
8739 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9374 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8740 {
8741 if (spcarray[j-seplen].ToString() == String.Empty)
8742 active[j] = false;
8743
8744 if (active[j])
8745 {
8746 // scan all of the markers
8747 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8748 {
8749 // not present at all
8750 active[j] = false;
8751 }
8752 else
8753 {
8754 // present and correct
8755 if (offset[j] < offset[best])
8756 {
8757 // closest so far
8758 best = j;
8759 }
8760 }
8761 }
8762 }
8763 } 9375 }
8764 9376
8765 // This is the normal exit from the scanning loop 9377 /*
9378 * If no delimeter found at or after i, we're done scanning.
9379 */
9380 if (earliestDel < 0) break;
8766 9381
8767 if (best == mlen) 9382 /*
9383 * If delimeter was a spacer, output the spacer.
9384 */
9385 if (earliestDel >= seplen)
8768 { 9386 {
8769 // no markers were found on this pass 9387 outarray[outlen++] = earliestStr;
8770 // so we're pretty much done
8771 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8772 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8773 break;
8774 } 9388 }
8775 9389
8776 // Otherwise we just add the newly delimited token 9390 /*
8777 // and recalculate where the search should continue. 9391 * Look at rest of src string following delimeter.
8778 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9392 */
8779 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9393 i = earliestSrc + earliestStr.Length;
8780
8781 if (best < seplen)
8782 {
8783 beginning = offset[best] + (separray[best].ToString()).Length;
8784 }
8785 else
8786 {
8787 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8788 string str = spcarray[best - seplen].ToString();
8789 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8790 tokens.Add(new LSL_String(str));
8791 }
8792 } 9394 }
8793 9395
8794 // This an awkward an not very intuitive boundary case. If the 9396 /*
8795 // last substring is a tokenizer, then there is an implied trailing 9397 * Make up an exact-sized output array suitable for an LSL_List object.
8796 // null list entry. Hopefully the single comparison will not be too 9398 */
8797 // arduous. Alternatively the 'break' could be replced with a return 9399 object[] outlist = new object[outlen];
8798 // but that's shabby programming. 9400 for (i = 0; i < outlen; i ++)
8799
8800 if ((beginning == srclen) && (keepNulls))
8801 { 9401 {
8802 if (srclen != 0) 9402 outlist[i] = new LSL_String(outarray[i]);
8803 tokens.Add(new LSL_String(""));
8804 } 9403 }
8805 9404 return new LSL_List(outlist);
8806 return tokens;
8807 }
8808
8809 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8810 {
8811 m_host.AddScriptLPS(1);
8812 return this.ParseString(src, separators, spacers, false);
8813 }
8814
8815 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8816 {
8817 m_host.AddScriptLPS(1);
8818 return this.ParseString(src, separators, spacers, true);
8819 } 9405 }
8820 9406
8821 public LSL_Integer llGetObjectPermMask(int mask) 9407 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8892,28 +9478,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8892 { 9478 {
8893 m_host.AddScriptLPS(1); 9479 m_host.AddScriptLPS(1);
8894 9480
8895 lock (m_host.TaskInventory) 9481 m_host.TaskInventory.LockItemsForRead(true);
9482 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8896 { 9483 {
8897 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9484 if (inv.Value.Name == item)
8898 { 9485 {
8899 if (inv.Value.Name == item) 9486 m_host.TaskInventory.LockItemsForRead(false);
9487 switch (mask)
8900 { 9488 {
8901 switch (mask) 9489 case 0:
8902 { 9490 return (int)inv.Value.BasePermissions;
8903 case 0: 9491 case 1:
8904 return (int)inv.Value.BasePermissions; 9492 return (int)inv.Value.CurrentPermissions;
8905 case 1: 9493 case 2:
8906 return (int)inv.Value.CurrentPermissions; 9494 return (int)inv.Value.GroupPermissions;
8907 case 2: 9495 case 3:
8908 return (int)inv.Value.GroupPermissions; 9496 return (int)inv.Value.EveryonePermissions;
8909 case 3: 9497 case 4:
8910 return (int)inv.Value.EveryonePermissions; 9498 return (int)inv.Value.NextPermissions;
8911 case 4:
8912 return (int)inv.Value.NextPermissions;
8913 }
8914 } 9499 }
8915 } 9500 }
8916 } 9501 }
9502 m_host.TaskInventory.LockItemsForRead(false);
8917 9503
8918 return -1; 9504 return -1;
8919 } 9505 }
@@ -8960,16 +9546,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8960 { 9546 {
8961 m_host.AddScriptLPS(1); 9547 m_host.AddScriptLPS(1);
8962 9548
8963 lock (m_host.TaskInventory) 9549 m_host.TaskInventory.LockItemsForRead(true);
9550 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8964 { 9551 {
8965 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9552 if (inv.Value.Name == item)
8966 { 9553 {
8967 if (inv.Value.Name == item) 9554 m_host.TaskInventory.LockItemsForRead(false);
8968 { 9555 return inv.Value.CreatorID.ToString();
8969 return inv.Value.CreatorID.ToString();
8970 }
8971 } 9556 }
8972 } 9557 }
9558 m_host.TaskInventory.LockItemsForRead(false);
8973 9559
8974 llSay(0, "No item name '" + item + "'"); 9560 llSay(0, "No item name '" + item + "'");
8975 9561
@@ -9117,7 +9703,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9117 } 9703 }
9118 9704
9119 /// <summary> 9705 /// <summary>
9120 /// illListReplaceList removes the sub-list defined by the inclusive indices 9706 /// llListReplaceList removes the sub-list defined by the inclusive indices
9121 /// start and end and inserts the src list in its place. The inclusive 9707 /// start and end and inserts the src list in its place. The inclusive
9122 /// nature of the indices means that at least one element must be deleted 9708 /// nature of the indices means that at least one element must be deleted
9123 /// if the indices are within the bounds of the existing list. I.e. 2,2 9709 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9174,16 +9760,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9174 // based upon end. Note that if end exceeds the upper 9760 // based upon end. Note that if end exceeds the upper
9175 // bound in this case, the entire destination list 9761 // bound in this case, the entire destination list
9176 // is removed. 9762 // is removed.
9177 else 9763 else if (start == 0)
9178 { 9764 {
9179 if (end + 1 < dest.Length) 9765 if (end + 1 < dest.Length)
9180 {
9181 return src + dest.GetSublist(end + 1, -1); 9766 return src + dest.GetSublist(end + 1, -1);
9182 }
9183 else 9767 else
9184 {
9185 return src; 9768 return src;
9186 } 9769 }
9770 else // Start < 0
9771 {
9772 if (end + 1 < dest.Length)
9773 return dest.GetSublist(end + 1, -1);
9774 else
9775 return new LSL_List();
9187 } 9776 }
9188 } 9777 }
9189 // Finally, if start > end, we strip away a prefix and 9778 // Finally, if start > end, we strip away a prefix and
@@ -9234,17 +9823,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9234 int width = 0; 9823 int width = 0;
9235 int height = 0; 9824 int height = 0;
9236 9825
9237 ParcelMediaCommandEnum? commandToSend = null; 9826 uint commandToSend = 0;
9238 float time = 0.0f; // default is from start 9827 float time = 0.0f; // default is from start
9239 9828
9240 ScenePresence presence = null; 9829 ScenePresence presence = null;
9241 9830
9242 for (int i = 0; i < commandList.Data.Length; i++) 9831 for (int i = 0; i < commandList.Data.Length; i++)
9243 { 9832 {
9244 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9833 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9245 switch (command) 9834 switch (command)
9246 { 9835 {
9247 case ParcelMediaCommandEnum.Agent: 9836 case (uint)ParcelMediaCommandEnum.Agent:
9248 // we send only to one agent 9837 // we send only to one agent
9249 if ((i + 1) < commandList.Length) 9838 if ((i + 1) < commandList.Length)
9250 { 9839 {
@@ -9261,25 +9850,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9261 } 9850 }
9262 break; 9851 break;
9263 9852
9264 case ParcelMediaCommandEnum.Loop: 9853 case (uint)ParcelMediaCommandEnum.Loop:
9265 loop = 1; 9854 loop = 1;
9266 commandToSend = command; 9855 commandToSend = command;
9267 update = true; //need to send the media update packet to set looping 9856 update = true; //need to send the media update packet to set looping
9268 break; 9857 break;
9269 9858
9270 case ParcelMediaCommandEnum.Play: 9859 case (uint)ParcelMediaCommandEnum.Play:
9271 loop = 0; 9860 loop = 0;
9272 commandToSend = command; 9861 commandToSend = command;
9273 update = true; //need to send the media update packet to make sure it doesn't loop 9862 update = true; //need to send the media update packet to make sure it doesn't loop
9274 break; 9863 break;
9275 9864
9276 case ParcelMediaCommandEnum.Pause: 9865 case (uint)ParcelMediaCommandEnum.Pause:
9277 case ParcelMediaCommandEnum.Stop: 9866 case (uint)ParcelMediaCommandEnum.Stop:
9278 case ParcelMediaCommandEnum.Unload: 9867 case (uint)ParcelMediaCommandEnum.Unload:
9279 commandToSend = command; 9868 commandToSend = command;
9280 break; 9869 break;
9281 9870
9282 case ParcelMediaCommandEnum.Url: 9871 case (uint)ParcelMediaCommandEnum.Url:
9283 if ((i + 1) < commandList.Length) 9872 if ((i + 1) < commandList.Length)
9284 { 9873 {
9285 if (commandList.Data[i + 1] is LSL_String) 9874 if (commandList.Data[i + 1] is LSL_String)
@@ -9292,7 +9881,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9292 } 9881 }
9293 break; 9882 break;
9294 9883
9295 case ParcelMediaCommandEnum.Texture: 9884 case (uint)ParcelMediaCommandEnum.Texture:
9296 if ((i + 1) < commandList.Length) 9885 if ((i + 1) < commandList.Length)
9297 { 9886 {
9298 if (commandList.Data[i + 1] is LSL_String) 9887 if (commandList.Data[i + 1] is LSL_String)
@@ -9305,7 +9894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9305 } 9894 }
9306 break; 9895 break;
9307 9896
9308 case ParcelMediaCommandEnum.Time: 9897 case (uint)ParcelMediaCommandEnum.Time:
9309 if ((i + 1) < commandList.Length) 9898 if ((i + 1) < commandList.Length)
9310 { 9899 {
9311 if (commandList.Data[i + 1] is LSL_Float) 9900 if (commandList.Data[i + 1] is LSL_Float)
@@ -9317,7 +9906,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9317 } 9906 }
9318 break; 9907 break;
9319 9908
9320 case ParcelMediaCommandEnum.AutoAlign: 9909 case (uint)ParcelMediaCommandEnum.AutoAlign:
9321 if ((i + 1) < commandList.Length) 9910 if ((i + 1) < commandList.Length)
9322 { 9911 {
9323 if (commandList.Data[i + 1] is LSL_Integer) 9912 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9331,7 +9920,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9331 } 9920 }
9332 break; 9921 break;
9333 9922
9334 case ParcelMediaCommandEnum.Type: 9923 case (uint)ParcelMediaCommandEnum.Type:
9335 if ((i + 1) < commandList.Length) 9924 if ((i + 1) < commandList.Length)
9336 { 9925 {
9337 if (commandList.Data[i + 1] is LSL_String) 9926 if (commandList.Data[i + 1] is LSL_String)
@@ -9344,7 +9933,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9344 } 9933 }
9345 break; 9934 break;
9346 9935
9347 case ParcelMediaCommandEnum.Desc: 9936 case (uint)ParcelMediaCommandEnum.Desc:
9348 if ((i + 1) < commandList.Length) 9937 if ((i + 1) < commandList.Length)
9349 { 9938 {
9350 if (commandList.Data[i + 1] is LSL_String) 9939 if (commandList.Data[i + 1] is LSL_String)
@@ -9357,7 +9946,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9357 } 9946 }
9358 break; 9947 break;
9359 9948
9360 case ParcelMediaCommandEnum.Size: 9949 case (uint)ParcelMediaCommandEnum.Size:
9361 if ((i + 2) < commandList.Length) 9950 if ((i + 2) < commandList.Length)
9362 { 9951 {
9363 if (commandList.Data[i + 1] is LSL_Integer) 9952 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9427,7 +10016,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9427 } 10016 }
9428 } 10017 }
9429 10018
9430 if (commandToSend != null) 10019 if (commandToSend != 0)
9431 { 10020 {
9432 // the commandList contained a start/stop/... command, too 10021 // the commandList contained a start/stop/... command, too
9433 if (presence == null) 10022 if (presence == null)
@@ -9464,7 +10053,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9464 10053
9465 if (aList.Data[i] != null) 10054 if (aList.Data[i] != null)
9466 { 10055 {
9467 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10056 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9468 { 10057 {
9469 case ParcelMediaCommandEnum.Url: 10058 case ParcelMediaCommandEnum.Url:
9470 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10059 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9507,16 +10096,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9507 { 10096 {
9508 m_host.AddScriptLPS(1); 10097 m_host.AddScriptLPS(1);
9509 10098
9510 lock (m_host.TaskInventory) 10099 m_host.TaskInventory.LockItemsForRead(true);
10100 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9511 { 10101 {
9512 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10102 if (inv.Value.Name == name)
9513 { 10103 {
9514 if (inv.Value.Name == name) 10104 m_host.TaskInventory.LockItemsForRead(false);
9515 { 10105 return inv.Value.Type;
9516 return inv.Value.Type;
9517 }
9518 } 10106 }
9519 } 10107 }
10108 m_host.TaskInventory.LockItemsForRead(false);
9520 10109
9521 return -1; 10110 return -1;
9522 } 10111 }
@@ -9527,15 +10116,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9527 10116
9528 if (quick_pay_buttons.Data.Length < 4) 10117 if (quick_pay_buttons.Data.Length < 4)
9529 { 10118 {
9530 LSLError("List must have at least 4 elements"); 10119 int x;
9531 return; 10120 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10121 {
10122 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10123 }
9532 } 10124 }
9533 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10125 int[] nPrice = new int[5];
9534 10126 nPrice[0] = price;
9535 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10127 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9536 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10128 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9537 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10129 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9538 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10130 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10131 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9539 m_host.ParentGroup.HasGroupChanged = true; 10132 m_host.ParentGroup.HasGroupChanged = true;
9540 } 10133 }
9541 10134
@@ -9547,17 +10140,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9547 if (invItemID == UUID.Zero) 10140 if (invItemID == UUID.Zero)
9548 return new LSL_Vector(); 10141 return new LSL_Vector();
9549 10142
9550 lock (m_host.TaskInventory) 10143 m_host.TaskInventory.LockItemsForRead(true);
10144 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9551 { 10145 {
9552 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10146 m_host.TaskInventory.LockItemsForRead(false);
9553 return new LSL_Vector(); 10147 return new LSL_Vector();
10148 }
9554 10149
9555 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10150 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9556 { 10151 {
9557 ShoutError("No permissions to track the camera"); 10152 ShoutError("No permissions to track the camera");
9558 return new LSL_Vector(); 10153 m_host.TaskInventory.LockItemsForRead(false);
9559 } 10154 return new LSL_Vector();
9560 } 10155 }
10156 m_host.TaskInventory.LockItemsForRead(false);
9561 10157
9562 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10158 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9563 if (presence != null) 10159 if (presence != null)
@@ -9575,17 +10171,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9575 if (invItemID == UUID.Zero) 10171 if (invItemID == UUID.Zero)
9576 return new LSL_Rotation(); 10172 return new LSL_Rotation();
9577 10173
9578 lock (m_host.TaskInventory) 10174 m_host.TaskInventory.LockItemsForRead(true);
10175 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9579 { 10176 {
9580 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10177 m_host.TaskInventory.LockItemsForRead(false);
9581 return new LSL_Rotation(); 10178 return new LSL_Rotation();
9582
9583 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9584 {
9585 ShoutError("No permissions to track the camera");
9586 return new LSL_Rotation();
9587 }
9588 } 10179 }
10180 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10181 {
10182 ShoutError("No permissions to track the camera");
10183 m_host.TaskInventory.LockItemsForRead(false);
10184 return new LSL_Rotation();
10185 }
10186 m_host.TaskInventory.LockItemsForRead(false);
9589 10187
9590 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10188 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9591 if (presence != null) 10189 if (presence != null)
@@ -9647,8 +10245,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9647 { 10245 {
9648 m_host.AddScriptLPS(1); 10246 m_host.AddScriptLPS(1);
9649 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10247 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9650 if (detectedParams == null) return; // only works on the first detected avatar 10248 if (detectedParams == null)
9651 10249 {
10250 if (m_host.ParentGroup.IsAttachment == true)
10251 {
10252 detectedParams = new DetectParams();
10253 detectedParams.Key = m_host.OwnerID;
10254 }
10255 else
10256 {
10257 return;
10258 }
10259 }
10260
9652 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10261 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9653 if (avatar != null) 10262 if (avatar != null)
9654 { 10263 {
@@ -9656,6 +10265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10265 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9657 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10266 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9658 } 10267 }
10268
9659 ScriptSleep(1000); 10269 ScriptSleep(1000);
9660 } 10270 }
9661 10271
@@ -9748,14 +10358,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9748 if (objectID == UUID.Zero) return; 10358 if (objectID == UUID.Zero) return;
9749 10359
9750 UUID agentID; 10360 UUID agentID;
9751 lock (m_host.TaskInventory) 10361 m_host.TaskInventory.LockItemsForRead(true);
9752 { 10362 // we need the permission first, to know which avatar we want to set the camera for
9753 // we need the permission first, to know which avatar we want to set the camera for 10363 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9754 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9755 10364
9756 if (agentID == UUID.Zero) return; 10365 if (agentID == UUID.Zero)
9757 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10366 {
10367 m_host.TaskInventory.LockItemsForRead(false);
10368 return;
10369 }
10370 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10371 {
10372 m_host.TaskInventory.LockItemsForRead(false);
10373 return;
9758 } 10374 }
10375 m_host.TaskInventory.LockItemsForRead(false);
9759 10376
9760 ScenePresence presence = World.GetScenePresence(agentID); 10377 ScenePresence presence = World.GetScenePresence(agentID);
9761 10378
@@ -9764,12 +10381,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9764 10381
9765 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10382 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9766 object[] data = rules.Data; 10383 object[] data = rules.Data;
9767 for (int i = 0; i < data.Length; ++i) { 10384 for (int i = 0; i < data.Length; ++i)
10385 {
9768 int type = Convert.ToInt32(data[i++].ToString()); 10386 int type = Convert.ToInt32(data[i++].ToString());
9769 if (i >= data.Length) break; // odd number of entries => ignore the last 10387 if (i >= data.Length) break; // odd number of entries => ignore the last
9770 10388
9771 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10389 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9772 switch (type) { 10390 switch (type)
10391 {
9773 case ScriptBaseClass.CAMERA_FOCUS: 10392 case ScriptBaseClass.CAMERA_FOCUS:
9774 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10393 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9775 case ScriptBaseClass.CAMERA_POSITION: 10394 case ScriptBaseClass.CAMERA_POSITION:
@@ -9805,12 +10424,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9805 10424
9806 // we need the permission first, to know which avatar we want to clear the camera for 10425 // we need the permission first, to know which avatar we want to clear the camera for
9807 UUID agentID; 10426 UUID agentID;
9808 lock (m_host.TaskInventory) 10427 m_host.TaskInventory.LockItemsForRead(true);
10428 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10429 if (agentID == UUID.Zero)
10430 {
10431 m_host.TaskInventory.LockItemsForRead(false);
10432 return;
10433 }
10434 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
9809 { 10435 {
9810 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10436 m_host.TaskInventory.LockItemsForRead(false);
9811 if (agentID == UUID.Zero) return; 10437 return;
9812 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9813 } 10438 }
10439 m_host.TaskInventory.LockItemsForRead(false);
9814 10440
9815 ScenePresence presence = World.GetScenePresence(agentID); 10441 ScenePresence presence = World.GetScenePresence(agentID);
9816 10442
@@ -9877,19 +10503,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9877 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10503 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9878 { 10504 {
9879 m_host.AddScriptLPS(1); 10505 m_host.AddScriptLPS(1);
9880 string ret = String.Empty; 10506
9881 string src1 = llBase64ToString(str1); 10507 if (str1 == String.Empty)
9882 string src2 = llBase64ToString(str2); 10508 return String.Empty;
9883 int c = 0; 10509 if (str2 == String.Empty)
9884 for (int i = 0; i < src1.Length; i++) 10510 return str1;
10511
10512 int len = str2.Length;
10513 if ((len % 4) != 0) // LL is EVIL!!!!
10514 {
10515 while (str2.EndsWith("="))
10516 str2 = str2.Substring(0, str2.Length - 1);
10517
10518 len = str2.Length;
10519 int mod = len % 4;
10520
10521 if (mod == 1)
10522 str2 = str2.Substring(0, str2.Length - 1);
10523 else if (mod == 2)
10524 str2 += "==";
10525 else if (mod == 3)
10526 str2 += "=";
10527 }
10528
10529 byte[] data1;
10530 byte[] data2;
10531 try
9885 { 10532 {
9886 ret += (char) (src1[i] ^ src2[c]); 10533 data1 = Convert.FromBase64String(str1);
10534 data2 = Convert.FromBase64String(str2);
10535 }
10536 catch (Exception)
10537 {
10538 return new LSL_String(String.Empty);
10539 }
9887 10540
9888 c++; 10541 byte[] d2 = new Byte[data1.Length];
9889 if (c >= src2.Length) 10542 int pos = 0;
9890 c = 0; 10543
10544 if (data1.Length <= data2.Length)
10545 {
10546 Array.Copy(data2, 0, d2, 0, data1.Length);
9891 } 10547 }
9892 return llStringToBase64(ret); 10548 else
10549 {
10550 while (pos < data1.Length)
10551 {
10552 len = data1.Length - pos;
10553 if (len > data2.Length)
10554 len = data2.Length;
10555
10556 Array.Copy(data2, 0, d2, pos, len);
10557 pos += len;
10558 }
10559 }
10560
10561 for (pos = 0 ; pos < data1.Length ; pos++ )
10562 data1[pos] ^= d2[pos];
10563
10564 return Convert.ToBase64String(data1);
9893 } 10565 }
9894 10566
9895 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10567 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9946,12 +10618,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9946 Regex r = new Regex(authregex); 10618 Regex r = new Regex(authregex);
9947 int[] gnums = r.GetGroupNumbers(); 10619 int[] gnums = r.GetGroupNumbers();
9948 Match m = r.Match(url); 10620 Match m = r.Match(url);
9949 if (m.Success) { 10621 if (m.Success)
9950 for (int i = 1; i < gnums.Length; i++) { 10622 {
10623 for (int i = 1; i < gnums.Length; i++)
10624 {
9951 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10625 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9952 //CaptureCollection cc = g.Captures; 10626 //CaptureCollection cc = g.Captures;
9953 } 10627 }
9954 if (m.Groups.Count == 5) { 10628 if (m.Groups.Count == 5)
10629 {
9955 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10630 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9956 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10631 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9957 } 10632 }
@@ -10237,15 +10912,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10237 10912
10238 internal UUID ScriptByName(string name) 10913 internal UUID ScriptByName(string name)
10239 { 10914 {
10240 lock (m_host.TaskInventory) 10915 m_host.TaskInventory.LockItemsForRead(true);
10916
10917 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10241 { 10918 {
10242 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10919 if (item.Type == 10 && item.Name == name)
10243 { 10920 {
10244 if (item.Type == 10 && item.Name == name) 10921 m_host.TaskInventory.LockItemsForRead(false);
10245 return item.ItemID; 10922 return item.ItemID;
10246 } 10923 }
10247 } 10924 }
10248 10925
10926 m_host.TaskInventory.LockItemsForRead(false);
10927
10249 return UUID.Zero; 10928 return UUID.Zero;
10250 } 10929 }
10251 10930
@@ -10286,6 +10965,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10286 { 10965 {
10287 m_host.AddScriptLPS(1); 10966 m_host.AddScriptLPS(1);
10288 10967
10968 //Clone is thread safe
10289 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10969 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10290 10970
10291 UUID assetID = UUID.Zero; 10971 UUID assetID = UUID.Zero;
@@ -10348,6 +11028,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10348 { 11028 {
10349 m_host.AddScriptLPS(1); 11029 m_host.AddScriptLPS(1);
10350 11030
11031 //Clone is thread safe
10351 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11032 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10352 11033
10353 UUID assetID = UUID.Zero; 11034 UUID assetID = UUID.Zero;
@@ -10428,15 +11109,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10428 return GetLinkPrimitiveParams(obj, rules); 11109 return GetLinkPrimitiveParams(obj, rules);
10429 } 11110 }
10430 11111
10431 public void print(string str) 11112 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10432 { 11113 {
10433 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11114 List<SceneObjectPart> parts = GetLinkParts(link);
10434 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11115 if (parts.Count < 1)
10435 if (ossl != null) 11116 return 0;
10436 { 11117
10437 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11118 return GetNumberOfSides(parts[0]);
10438 m_log.Info("LSL print():" + str);
10439 }
10440 } 11119 }
10441 11120
10442 private string Name2Username(string name) 11121 private string Name2Username(string name)
@@ -10482,153 +11161,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10482 return rq.ToString(); 11161 return rq.ToString();
10483 } 11162 }
10484 11163
11164 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11165 {
11166 m_SayShoutCount = 0;
11167 }
11168
11169 private struct Tri
11170 {
11171 public Vector3 p1;
11172 public Vector3 p2;
11173 public Vector3 p3;
11174 }
11175
11176 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11177 {
11178 float height = avatar.Appearance.AvatarHeight;
11179 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11180 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11181
11182 if (point.X > b1.X && point.X < b2.X &&
11183 point.Y > b1.Y && point.Y < b2.Y &&
11184 point.Z > b1.Z && point.Z < b2.Z)
11185 return true;
11186 return false;
11187 }
11188
11189 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11190 {
11191 List<ContactResult> contacts = new List<ContactResult>();
11192
11193 Vector3 ab = rayEnd - rayStart;
11194
11195 World.ForEachScenePresence(delegate(ScenePresence sp)
11196 {
11197 Vector3 ac = sp.AbsolutePosition - rayStart;
11198 Vector3 bc = sp.AbsolutePosition - rayEnd;
11199
11200 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11201
11202 if (d > 1.5)
11203 return;
11204
11205 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11206
11207 if (d2 > 0)
11208 return;
11209
11210 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11211 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11212
11213 if (!InBoundingBox(sp, p))
11214 return;
11215
11216 ContactResult result = new ContactResult ();
11217 result.ConsumerID = sp.LocalId;
11218 result.Depth = Vector3.Distance(rayStart, p);
11219 result.Normal = Vector3.Zero;
11220 result.Pos = p;
11221
11222 contacts.Add(result);
11223 });
11224
11225 return contacts.ToArray();
11226 }
11227
11228 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11229 {
11230 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11231 List<ContactResult> contacts = new List<ContactResult>();
11232
11233 Vector3 ab = rayEnd - rayStart;
11234
11235 World.ForEachSOG(delegate(SceneObjectGroup group)
11236 {
11237 if (m_host.ParentGroup == group)
11238 return;
11239
11240 if (group.IsAttachment)
11241 return;
11242
11243 if (group.RootPart.PhysActor == null)
11244 {
11245 if (!includePhantom)
11246 return;
11247 }
11248 else
11249 {
11250 if (group.RootPart.PhysActor.IsPhysical)
11251 {
11252 if (!includePhysical)
11253 return;
11254 }
11255 else
11256 {
11257 if (!includeNonPhysical)
11258 return;
11259 }
11260 }
11261
11262 // Find the radius ouside of which we don't even need to hit test
11263 float minX;
11264 float maxX;
11265 float minY;
11266 float maxY;
11267 float minZ;
11268 float maxZ;
11269
11270 float radius = 0.0f;
11271
11272 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11273
11274 if (Math.Abs(minX) > radius)
11275 radius = Math.Abs(minX);
11276 if (Math.Abs(minY) > radius)
11277 radius = Math.Abs(minY);
11278 if (Math.Abs(minZ) > radius)
11279 radius = Math.Abs(minZ);
11280 if (Math.Abs(maxX) > radius)
11281 radius = Math.Abs(maxX);
11282 if (Math.Abs(maxY) > radius)
11283 radius = Math.Abs(maxY);
11284 if (Math.Abs(maxZ) > radius)
11285 radius = Math.Abs(maxZ);
11286
11287 Vector3 ac = group.AbsolutePosition - rayStart;
11288 Vector3 bc = group.AbsolutePosition - rayEnd;
11289
11290 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11291
11292 // Too far off ray, don't bother
11293 if (d > radius)
11294 return;
11295
11296 // Behind ray, drop
11297 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11298 if (d2 > 0)
11299 return;
11300
11301 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11302 // Miss.
11303 if (!intersection.HitTF)
11304 return;
11305
11306 ContactResult result = new ContactResult ();
11307 result.ConsumerID = group.LocalId;
11308 result.Depth = intersection.distance;
11309 result.Normal = intersection.normal;
11310 result.Pos = intersection.ipoint;
11311
11312 contacts.Add(result);
11313 });
11314
11315 return contacts.ToArray();
11316 }
11317
11318 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11319 {
11320 double[,] heightfield = World.Heightmap.GetDoubles();
11321 List<ContactResult> contacts = new List<ContactResult>();
11322
11323 double min = 2048.0;
11324 double max = 0.0;
11325
11326 // Find the min and max of the heightfield
11327 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11328 {
11329 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11330 {
11331 if (heightfield[x, y] > max)
11332 max = heightfield[x, y];
11333 if (heightfield[x, y] < min)
11334 min = heightfield[x, y];
11335 }
11336 }
11337
11338
11339 // A ray extends past rayEnd, but doesn't go back before
11340 // rayStart. If the start is above the highest point of the ground
11341 // and the ray goes up, we can't hit the ground. Ever.
11342 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11343 return null;
11344
11345 // Same for going down
11346 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11347 return null;
11348
11349 List<Tri> trilist = new List<Tri>();
11350
11351 // Create our triangle list
11352 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11353 {
11354 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11355 {
11356 Tri t1 = new Tri();
11357 Tri t2 = new Tri();
11358
11359 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11360 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11361 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11362 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11363
11364 t1.p1 = p1;
11365 t1.p2 = p2;
11366 t1.p3 = p3;
11367
11368 t2.p1 = p3;
11369 t2.p2 = p4;
11370 t2.p3 = p1;
11371
11372 trilist.Add(t1);
11373 trilist.Add(t2);
11374 }
11375 }
11376
11377 // Ray direction
11378 Vector3 rayDirection = rayEnd - rayStart;
11379
11380 foreach (Tri t in trilist)
11381 {
11382 // Compute triangle plane normal and edges
11383 Vector3 u = t.p2 - t.p1;
11384 Vector3 v = t.p3 - t.p1;
11385 Vector3 n = Vector3.Cross(u, v);
11386
11387 if (n == Vector3.Zero)
11388 continue;
11389
11390 Vector3 w0 = rayStart - t.p1;
11391 double a = -Vector3.Dot(n, w0);
11392 double b = Vector3.Dot(n, rayDirection);
11393
11394 // Not intersecting the plane, or in plane (same thing)
11395 // Ignoring this MAY cause the ground to not be detected
11396 // sometimes
11397 if (Math.Abs(b) < 0.000001)
11398 continue;
11399
11400 double r = a / b;
11401
11402 // ray points away from plane
11403 if (r < 0.0)
11404 continue;
11405
11406 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11407
11408 float uu = Vector3.Dot(u, u);
11409 float uv = Vector3.Dot(u, v);
11410 float vv = Vector3.Dot(v, v);
11411 Vector3 w = ip - t.p1;
11412 float wu = Vector3.Dot(w, u);
11413 float wv = Vector3.Dot(w, v);
11414 float d = uv * uv - uu * vv;
11415
11416 float cs = (uv * wv - vv * wu) / d;
11417 if (cs < 0 || cs > 1.0)
11418 continue;
11419 float ct = (uv * wu - uu * wv) / d;
11420 if (ct < 0 || (cs + ct) > 1.0)
11421 continue;
11422
11423 // Add contact point
11424 ContactResult result = new ContactResult ();
11425 result.ConsumerID = 0;
11426 result.Depth = Vector3.Distance(rayStart, ip);
11427 result.Normal = n;
11428 result.Pos = ip;
11429
11430 contacts.Add(result);
11431 }
11432
11433 if (contacts.Count == 0)
11434 return null;
11435
11436 contacts.Sort(delegate(ContactResult a, ContactResult b)
11437 {
11438 return (int)(a.Depth - b.Depth);
11439 });
11440
11441 return contacts[0];
11442 }
11443
10485 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11444 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10486 { 11445 {
11446 LSL_List list = new LSL_List();
11447
10487 m_host.AddScriptLPS(1); 11448 m_host.AddScriptLPS(1);
10488 11449
10489 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11450 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10490 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11451 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10491 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11452 Vector3 dir = rayEnd - rayStart;
10492 11453
10493 int count = 0; 11454 int count = 1;
10494// int detectPhantom = 0; 11455 bool detectPhantom = false;
10495 int dataFlags = 0; 11456 int dataFlags = 0;
10496 int rejectTypes = 0; 11457 int rejectTypes = 0;
10497 11458
10498 for (int i = 0; i < options.Length; i += 2) 11459 for (int i = 0; i < options.Length; i += 2)
10499 { 11460 {
10500 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11461 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10501 {
10502 count = options.GetLSLIntegerItem(i + 1); 11462 count = options.GetLSLIntegerItem(i + 1);
10503 } 11463 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10504// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11464 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10505// {
10506// detectPhantom = options.GetLSLIntegerItem(i + 1);
10507// }
10508 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11465 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10509 {
10510 dataFlags = options.GetLSLIntegerItem(i + 1); 11466 dataFlags = options.GetLSLIntegerItem(i + 1);
10511 }
10512 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11467 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10513 {
10514 rejectTypes = options.GetLSLIntegerItem(i + 1); 11468 rejectTypes = options.GetLSLIntegerItem(i + 1);
10515 }
10516 } 11469 }
10517 11470
10518 LSL_List list = new LSL_List(); 11471 if (count > 16)
10519 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11472 count = 16;
10520
10521 double distance = Util.GetDistanceTo(startvector, endvector);
10522 11473
10523 if (distance == 0) 11474 List<ContactResult> results = new List<ContactResult>();
10524 distance = 0.001;
10525
10526 Vector3 posToCheck = startvector;
10527 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10528 11475
10529 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11476 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10530 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11477 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10531 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11478 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10532 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11479 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10533 11480
10534 for (float i = 0; i <= distance; i += 0.1f) 11481 if (checkTerrain)
10535 { 11482 {
10536 posToCheck = startvector + (dir * (i / (float)distance)); 11483 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11484 if (groundContact != null)
11485 results.Add((ContactResult)groundContact);
11486 }
10537 11487
10538 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11488 if (checkAgents)
10539 { 11489 {
10540 ContactResult result = new ContactResult(); 11490 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10541 result.ConsumerID = 0; 11491 foreach (ContactResult r in agentHits)
10542 result.Depth = 0; 11492 results.Add(r);
10543 result.Normal = Vector3.Zero; 11493 }
10544 result.Pos = posToCheck;
10545 results.Add(result);
10546 checkTerrain = false;
10547 }
10548 11494
10549 if (checkAgents) 11495 if (checkPhysical || checkNonPhysical)
10550 { 11496 {
10551 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11497 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10552 { 11498 foreach (ContactResult r in objectHits)
10553 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11499 results.Add(r);
10554 {
10555 ContactResult result = new ContactResult ();
10556 result.ConsumerID = sp.LocalId;
10557 result.Depth = 0;
10558 result.Normal = Vector3.Zero;
10559 result.Pos = posToCheck;
10560 results.Add(result);
10561 }
10562 });
10563 }
10564 } 11500 }
10565 11501
10566 int refcount = 0; 11502 results.Sort(delegate(ContactResult a, ContactResult b)
11503 {
11504 return (int)(a.Depth - b.Depth);
11505 });
11506
11507 int values = 0;
10567 foreach (ContactResult result in results) 11508 foreach (ContactResult result in results)
10568 { 11509 {
10569 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11510 UUID itemID = UUID.Zero;
10570 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11511 int linkNum = 0;
10571 continue;
10572
10573 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
10574 11512
10575 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11513 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
10576 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11514 // It's a prim!
10577 11515 if (part != null)
10578 if (entity == null)
10579 { 11516 {
10580 list.Add(UUID.Zero); 11517 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10581 11518 itemID = part.ParentGroup.UUID;
10582 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11519 else
10583 list.Add(0); 11520 itemID = part.UUID;
10584
10585 list.Add(result.Pos);
10586
10587 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10588 list.Add(result.Normal);
10589 11521
10590 continue; //Can't find it, so add UUID.Zero 11522 linkNum = part.LinkNum;
10591 } 11523 }
10592 11524 else
10593 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10594 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10595 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10596
10597 if (entity is SceneObjectPart)
10598 { 11525 {
10599 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11526 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10600 { 11527 /// It it a boy? a girl?
10601 if (!checkPhysical) 11528 if (sp != null)
10602 continue; 11529 itemID = sp.UUID;
10603 }
10604 else
10605 {
10606 if (!checkNonPhysical)
10607 continue;
10608 }
10609 } 11530 }
10610 11531
10611 refcount++; 11532 list.Add(new LSL_String(itemID.ToString()));
10612 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11533 list.Add(new LSL_String(result.Pos.ToString()));
10613 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10614 else
10615 list.Add(entity.UUID);
10616 11534
10617 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11535 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10618 { 11536 list.Add(new LSL_Integer(linkNum));
10619 if (entity is SceneObjectPart)
10620 list.Add(((SceneObjectPart)entity).LinkNum);
10621 else
10622 list.Add(0);
10623 }
10624 11537
10625 list.Add(result.Pos);
10626 11538
10627 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11539 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10628 list.Add(result.Normal); 11540 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11541
11542 values++;
11543 count--;
11544
11545 if (count == 0)
11546 break;
10629 } 11547 }
10630 11548
10631 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11549 list.Add(new LSL_Integer(values));
10632 11550
10633 return list; 11551 return list;
10634 } 11552 }
@@ -10651,22 +11569,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 NotImplemented("llGetSPMaxMemory"); 11569 NotImplemented("llGetSPMaxMemory");
10652 } 11570 }
10653 11571
10654 public void llGetUsedMemory() 11572 public virtual LSL_Integer llGetUsedMemory()
10655 { 11573 {
10656 m_host.AddScriptLPS(1); 11574 m_host.AddScriptLPS(1);
10657 NotImplemented("llGetUsedMemory"); 11575 NotImplemented("llGetUsedMemory");
11576 return 0;
10658 } 11577 }
10659 11578
10660 public void llScriptProfiler(LSL_Integer flags) 11579 public void llScriptProfiler(LSL_Integer flags)
10661 { 11580 {
10662 m_host.AddScriptLPS(1); 11581 m_host.AddScriptLPS(1);
10663 NotImplemented("llScriptProfiler"); 11582 //NotImplemented("llScriptProfiler");
10664 } 11583 }
10665 11584
10666 public void llSetSoundQueueing(int queue) 11585 public void llSetSoundQueueing(int queue)
10667 { 11586 {
10668 m_host.AddScriptLPS(1); 11587 m_host.AddScriptLPS(1);
10669 NotImplemented("llSetSoundQueueing");
10670 } 11588 }
10671 11589
10672 public void llCollisionSprite(string impact_sprite) 11590 public void llCollisionSprite(string impact_sprite)
@@ -10678,7 +11596,133 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10678 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11596 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10679 { 11597 {
10680 m_host.AddScriptLPS(1); 11598 m_host.AddScriptLPS(1);
10681 NotImplemented("llGodLikeRezObject"); 11599
11600 if (!World.Permissions.IsGod(m_host.OwnerID))
11601 NotImplemented("llGodLikeRezObject");
11602
11603 AssetBase rezAsset = World.AssetService.Get(inventory);
11604 if (rezAsset == null)
11605 {
11606 llSay(0, "Asset not found");
11607 return;
11608 }
11609
11610 SceneObjectGroup group = null;
11611
11612 try
11613 {
11614 string xmlData = Utils.BytesToString(rezAsset.Data);
11615 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11616 }
11617 catch
11618 {
11619 llSay(0, "Asset not found");
11620 return;
11621 }
11622
11623 if (group == null)
11624 {
11625 llSay(0, "Asset not found");
11626 return;
11627 }
11628
11629 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11630 group.RootPart.AttachOffset = group.AbsolutePosition;
11631
11632 group.ResetIDs();
11633
11634 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11635 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11636 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11637 group.ScheduleGroupForFullUpdate();
11638
11639 // objects rezzed with this method are die_at_edge by default.
11640 group.RootPart.SetDieAtEdge(true);
11641
11642 group.ResumeScripts();
11643
11644 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11645 "object_rez", new Object[] {
11646 new LSL_String(
11647 group.RootPart.UUID.ToString()) },
11648 new DetectParams[0]));
11649 }
11650
11651 public LSL_String llTransferLindenDollars(string destination, int amount)
11652 {
11653 UUID txn = UUID.Random();
11654
11655 Util.FireAndForget(delegate(object x)
11656 {
11657 int replycode = 0;
11658 string replydata = destination + "," + amount.ToString();
11659
11660 try
11661 {
11662 UUID invItemID=InventorySelf();
11663 if (invItemID == UUID.Zero)
11664 {
11665 replydata = "SERVICE_ERROR";
11666 return;
11667 }
11668
11669 m_host.AddScriptLPS(1);
11670
11671 m_host.TaskInventory.LockItemsForRead(true);
11672 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11673 m_host.TaskInventory.LockItemsForRead(false);
11674
11675 if (item.PermsGranter == UUID.Zero)
11676 {
11677 replydata = "MISSING_PERMISSION_DEBIT";
11678 return;
11679 }
11680
11681 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11682 {
11683 replydata = "MISSING_PERMISSION_DEBIT";
11684 return;
11685 }
11686
11687 UUID toID = new UUID();
11688
11689 if (!UUID.TryParse(destination, out toID))
11690 {
11691 replydata = "INVALID_AGENT";
11692 return;
11693 }
11694
11695 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11696
11697 if (money == null)
11698 {
11699 replydata = "TRANSFERS_DISABLED";
11700 return;
11701 }
11702
11703 bool result = money.ObjectGiveMoney(
11704 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11705
11706 if (result)
11707 {
11708 replycode = 1;
11709 return;
11710 }
11711
11712 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11713 }
11714 finally
11715 {
11716 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11717 "transaction_result", new Object[] {
11718 new LSL_String(txn.ToString()),
11719 new LSL_Integer(replycode),
11720 new LSL_String(replydata) },
11721 new DetectParams[0]));
11722 }
11723 });
11724
11725 return txn.ToString();
10682 } 11726 }
10683 11727
10684 #endregion 11728 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 40d9d6f..78c3fa0 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()
@@ -902,18 +911,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
902 if (target != null) 911 if (target != null)
903 { 912 {
904 UUID animID=UUID.Zero; 913 UUID animID=UUID.Zero;
905 lock (m_host.TaskInventory) 914 m_host.TaskInventory.LockItemsForRead(true);
915 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
906 { 916 {
907 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 917 if (inv.Value.Name == animation)
908 { 918 {
909 if (inv.Value.Name == animation) 919 if (inv.Value.Type == (int)AssetType.Animation)
910 { 920 animID = inv.Value.AssetID;
911 if (inv.Value.Type == (int)AssetType.Animation) 921 continue;
912 animID = inv.Value.AssetID;
913 continue;
914 }
915 } 922 }
916 } 923 }
924 m_host.TaskInventory.LockItemsForRead(false);
917 if (animID == UUID.Zero) 925 if (animID == UUID.Zero)
918 target.Animator.AddAnimation(animation, m_host.UUID); 926 target.Animator.AddAnimation(animation, m_host.UUID);
919 else 927 else
@@ -940,18 +948,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
940 if (target != null) 948 if (target != null)
941 { 949 {
942 UUID animID = UUID.Zero; 950 UUID animID = UUID.Zero;
943 lock (m_host.TaskInventory) 951 m_host.TaskInventory.LockItemsForRead(true);
952 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
944 { 953 {
945 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 954 if (inv.Value.Name == animation)
946 { 955 {
947 if (inv.Value.Name == animation) 956 if (inv.Value.Type == (int)AssetType.Animation)
948 { 957 animID = inv.Value.AssetID;
949 if (inv.Value.Type == (int)AssetType.Animation) 958 continue;
950 animID = inv.Value.AssetID;
951 continue;
952 }
953 } 959 }
954 } 960 }
961 m_host.TaskInventory.LockItemsForRead(false);
955 962
956 if (animID == UUID.Zero) 963 if (animID == UUID.Zero)
957 target.Animator.RemoveAnimation(animation); 964 target.Animator.RemoveAnimation(animation);
@@ -1782,6 +1789,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1782 1789
1783 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1790 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1784 { 1791 {
1792 m_host.TaskInventory.LockItemsForRead(true);
1785 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1793 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1786 { 1794 {
1787 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1795 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1789,6 +1797,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1789 assetID = item.AssetID; 1797 assetID = item.AssetID;
1790 } 1798 }
1791 } 1799 }
1800 m_host.TaskInventory.LockItemsForRead(false);
1792 } 1801 }
1793 1802
1794 if (assetID == UUID.Zero) 1803 if (assetID == UUID.Zero)
@@ -2091,6 +2100,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2091 2100
2092 private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned) 2101 private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned)
2093 { 2102 {
2103 if (!owned)
2104 OSSLError("Unowned NPCs are unsupported");
2105
2106 string groupTitle = String.Empty;
2107
2108 if (firstname != String.Empty || lastname != String.Empty)
2109 {
2110 if (firstname != "Shown outfit:")
2111 groupTitle = "- NPC -";
2112 }
2113
2094 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2114 INPCModule module = World.RequestModuleInterface<INPCModule>();
2095 if (module != null) 2115 if (module != null)
2096 { 2116 {
@@ -2128,6 +2148,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2128 ownerID, 2148 ownerID,
2129 World,appearance); 2149 World,appearance);
2130 2150
2151 ScenePresence sp;
2152 if (World.TryGetScenePresence(x, out sp))
2153 {
2154 sp.Grouptitle = groupTitle;
2155 sp.SendAvatarDataToAllAgents();
2156 }
2131 return new LSL_Key(x.ToString()); 2157 return new LSL_Key(x.ToString());
2132 } 2158 }
2133 2159
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 8356dce..dddf913 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -209,7 +209,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
209 // Is the sensor type is AGENT and not SCRIPTED then include agents 209 // Is the sensor type is AGENT and not SCRIPTED then include agents
210 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) 210 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
211 { 211 {
212 sensedEntities.AddRange(doAgentSensor(ts)); 212 sensedEntities.AddRange(doAgentSensor(ts));
213 } 213 }
214 214
215 // If SCRIPTED or PASSIVE or ACTIVE check objects 215 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -306,13 +306,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
306 float dy; 306 float dy;
307 float dz; 307 float dz;
308 308
309 Quaternion q = SensePoint.RotationOffset; 309// Quaternion q = SensePoint.RotationOffset;
310 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
310 if (SensePoint.ParentGroup.IsAttachment) 311 if (SensePoint.ParentGroup.IsAttachment)
311 { 312 {
312 // In attachments, the sensor cone always orients with the 313 // In attachments, the sensor cone always orients with the
313 // avatar rotation. This may include a nonzero elevation if 314 // avatar rotation. This may include a nonzero elevation if
314 // in mouselook. 315 // in mouselook.
315 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 316 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
317 fromRegionPos = avatar.AbsolutePosition;
316 q = avatar.Rotation; 318 q = avatar.Rotation;
317 } 319 }
318 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 320 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -435,6 +437,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
435 // avatar rotation. This may include a nonzero elevation if 437 // avatar rotation. This may include a nonzero elevation if
436 // in mouselook. 438 // in mouselook.
437 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 439 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
440 if (avatar == null)
441 return sensedEntities;
442 fromRegionPos = avatar.AbsolutePosition;
438 q = avatar.Rotation; 443 q = avatar.Rotation;
439 } 444 }
440 445
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 62e2854..e0027b2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
124 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
125 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
126 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
127 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
128 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -199,6 +200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
199 void llGiveInventory(string destination, string inventory); 200 void llGiveInventory(string destination, string inventory);
200 void llGiveInventoryList(string destination, string category, LSL_List inventory); 201 void llGiveInventoryList(string destination, string category, LSL_List inventory);
201 LSL_Integer llGiveMoney(string destination, int amount); 202 LSL_Integer llGiveMoney(string destination, int amount);
203 LSL_String llTransferLindenDollars(string destination, int amount);
202 void llGodLikeRezObject(string inventory, LSL_Vector pos); 204 void llGodLikeRezObject(string inventory, LSL_Vector pos);
203 LSL_Float llGround(LSL_Vector offset); 205 LSL_Float llGround(LSL_Vector offset);
204 LSL_Vector llGroundContour(LSL_Vector offset); 206 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -405,7 +407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_Vector llWind(LSL_Vector offset); 407 LSL_Vector llWind(LSL_Vector offset);
406 LSL_String llXorBase64Strings(string str1, string str2); 408 LSL_String llXorBase64Strings(string str1, string str2);
407 LSL_String llXorBase64StringsCorrect(string str1, string str2); 409 LSL_String llXorBase64StringsCorrect(string str1, string str2);
408 void print(string str); 410 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
409 411
410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 412 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 413 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index af6be5f..403e491 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 176dc56..32226f9 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -282,6 +282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 283 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 284 public const int CHANGED_ANIMATION = 16384;
285 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 286 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 287 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 288 public const int TYPE_FLOAT = 2;
@@ -378,6 +379,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
378 public const int PRIM_SCULPT_TYPE_TORUS = 2; 379 public const int PRIM_SCULPT_TYPE_TORUS = 2;
379 public const int PRIM_SCULPT_TYPE_PLANE = 3; 380 public const int PRIM_SCULPT_TYPE_PLANE = 3;
380 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 381 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
382 public const int PRIM_SCULPT_FLAG_INVERT = 64;
383 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
381 384
382 public const int MASK_BASE = 0; 385 public const int MASK_BASE = 0;
383 public const int MASK_OWNER = 1; 386 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..231cd7e 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();
@@ -839,6 +851,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
839 return m_LSL_Functions.llGiveMoney(destination, amount); 851 return m_LSL_Functions.llGiveMoney(destination, amount);
840 } 852 }
841 853
854 public LSL_String llTransferLindenDollars(string destination, int amount)
855 {
856 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
857 }
858
842 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 859 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
843 { 860 {
844 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 861 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1878,9 +1895,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1878 return m_LSL_Functions.llClearPrimMedia(face); 1895 return m_LSL_Functions.llClearPrimMedia(face);
1879 } 1896 }
1880 1897
1881 public void print(string str) 1898 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1882 { 1899 {
1883 m_LSL_Functions.print(str); 1900 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1884 } 1901 }
1885 } 1902 }
1886} 1903}
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 f9d6eee..9ff2e4d 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;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -263,13 +264,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
263 264
264 if (part != null) 265 if (part != null)
265 { 266 {
266 lock (part.TaskInventory) 267 part.TaskInventory.LockItemsForRead(true);
268 if (part.TaskInventory.ContainsKey(m_ItemID))
267 { 269 {
268 if (part.TaskInventory.ContainsKey(m_ItemID)) 270 m_thisScriptTask = part.TaskInventory[m_ItemID];
269 {
270 m_thisScriptTask = part.TaskInventory[m_ItemID];
271 }
272 } 271 }
272 part.TaskInventory.LockItemsForRead(false);
273 } 273 }
274 274
275 ApiManager am = new ApiManager(); 275 ApiManager am = new ApiManager();
@@ -296,9 +296,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297// lease.Register(this); 297// lease.Register(this);
298 } 298 }
299 catch (Exception) 299 catch (Exception e)
300 { 300 {
301 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 301 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
302 throw;
302 } 303 }
303 304
304 try 305 try
@@ -459,14 +460,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
459 { 460 {
460 int permsMask; 461 int permsMask;
461 UUID permsGranter; 462 UUID permsGranter;
462 lock (part.TaskInventory) 463 part.TaskInventory.LockItemsForRead(true);
464 if (!part.TaskInventory.ContainsKey(m_ItemID))
463 { 465 {
464 if (!part.TaskInventory.ContainsKey(m_ItemID)) 466 part.TaskInventory.LockItemsForRead(false);
465 return; 467 return;
466
467 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
468 permsMask = part.TaskInventory[m_ItemID].PermsMask;
469 } 468 }
469 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
470 permsMask = part.TaskInventory[m_ItemID].PermsMask;
471 part.TaskInventory.LockItemsForRead(false);
470 472
471 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 473 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
472 { 474 {
@@ -575,6 +577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
575 return true; 577 return true;
576 } 578 }
577 579
580 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
578 public void SetState(string state) 581 public void SetState(string state)
579 { 582 {
580 if (state == State) 583 if (state == State)
@@ -586,7 +589,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
586 new DetectParams[0])); 589 new DetectParams[0]));
587 PostEvent(new EventParams("state_entry", new Object[0], 590 PostEvent(new EventParams("state_entry", new Object[0],
588 new DetectParams[0])); 591 new DetectParams[0]));
589 592
590 throw new EventAbortException(); 593 throw new EventAbortException();
591 } 594 }
592 595
@@ -669,41 +672,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
669 /// <returns></returns> 672 /// <returns></returns>
670 public object EventProcessor() 673 public object EventProcessor()
671 { 674 {
672 lock (m_Script) 675 EventParams data = null;
673 {
674// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
675 676
676 if (Suspended) 677// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
677 return 0;
678 678
679 EventParams data = null; 679 if (Suspended)
680 return 0;
680 681
681 lock (m_EventQueue) 682 lock (m_EventQueue)
683 {
684 data = (EventParams) m_EventQueue.Dequeue();
685 if (data == null) // Shouldn't happen
682 { 686 {
683 data = (EventParams) m_EventQueue.Dequeue(); 687 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown))
684 if (data == null) // Shouldn't happen
685 { 688 {
686 if ((m_EventQueue.Count > 0) && m_RunEvents && (!m_ShuttingDown)) 689 m_CurrentResult = m_Engine.QueueEventHandler(this);
687 {
688 m_CurrentResult = m_Engine.QueueEventHandler(this);
689 }
690 else
691 {
692 m_CurrentResult = null;
693 }
694 return 0;
695 } 690 }
696 691 else
697 if (data.EventName == "timer")
698 m_TimerQueued = false;
699 if (data.EventName == "control")
700 { 692 {
701 if (m_ControlEventsInQueue > 0) 693 m_CurrentResult = null;
702 m_ControlEventsInQueue--;
703 } 694 }
704 if (data.EventName == "collision") 695 return 0;
705 m_CollisionInQueue = false; 696 }
697
698 if (data.EventName == "timer")
699 m_TimerQueued = false;
700 if (data.EventName == "control")
701 {
702 if (m_ControlEventsInQueue > 0)
703 m_ControlEventsInQueue--;
706 } 704 }
705 if (data.EventName == "collision")
706 m_CollisionInQueue = false;
707 }
708
709 lock(m_Script)
710 {
707 711
708// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 712// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
709 713
@@ -860,6 +864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
860 new Object[0], new DetectParams[0])); 864 new Object[0], new DetectParams[0]));
861 } 865 }
862 866
867 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
863 public void ApiResetScript() 868 public void ApiResetScript()
864 { 869 {
865 // bool running = Running; 870 // bool running = Running;
@@ -891,10 +896,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
891 896
892 public Dictionary<string, object> GetVars() 897 public Dictionary<string, object> GetVars()
893 { 898 {
894 if (m_Script != null) 899 return m_Script.GetVars();
895 return m_Script.GetVars();
896 else
897 return new Dictionary<string, object>();
898 } 900 }
899 901
900 public void SetVars(Dictionary<string, object> vars) 902 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index c9bbf0e..23531a9 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -108,6 +109,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
108 private Dictionary<UUID, IScriptInstance> m_Scripts = 109 private Dictionary<UUID, IScriptInstance> m_Scripts =
109 new Dictionary<UUID, IScriptInstance>(); 110 new Dictionary<UUID, IScriptInstance>();
110 111
112 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
113
111 // Maps the asset ID to the assembly 114 // Maps the asset ID to the assembly
112 115
113 private Dictionary<UUID, string> m_Assemblies = 116 private Dictionary<UUID, string> m_Assemblies =
@@ -130,6 +133,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
130 IWorkItemResult m_CurrentCompile = null; 133 IWorkItemResult m_CurrentCompile = null;
131 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 134 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
132 135
136 private void lockScriptsForRead(bool locked)
137 {
138 if (locked)
139 {
140 if (m_scriptsLock.RecursiveReadCount > 0)
141 {
142 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.");
143 m_scriptsLock.ExitReadLock();
144 }
145 if (m_scriptsLock.RecursiveWriteCount > 0)
146 {
147 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
148 m_scriptsLock.ExitWriteLock();
149 }
150
151 while (!m_scriptsLock.TryEnterReadLock(60000))
152 {
153 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.");
154 if (m_scriptsLock.IsWriteLockHeld)
155 {
156 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
157 }
158 }
159 }
160 else
161 {
162 if (m_scriptsLock.RecursiveReadCount > 0)
163 {
164 m_scriptsLock.ExitReadLock();
165 }
166 }
167 }
168 private void lockScriptsForWrite(bool locked)
169 {
170 if (locked)
171 {
172 if (m_scriptsLock.RecursiveReadCount > 0)
173 {
174 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.");
175 m_scriptsLock.ExitReadLock();
176 }
177 if (m_scriptsLock.RecursiveWriteCount > 0)
178 {
179 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
180 m_scriptsLock.ExitWriteLock();
181 }
182
183 while (!m_scriptsLock.TryEnterWriteLock(60000))
184 {
185 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.");
186 if (m_scriptsLock.IsWriteLockHeld)
187 {
188 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
189 }
190 }
191 }
192 else
193 {
194 if (m_scriptsLock.RecursiveWriteCount > 0)
195 {
196 m_scriptsLock.ExitWriteLock();
197 }
198 }
199 }
200
133 public string ScriptEngineName 201 public string ScriptEngineName
134 { 202 {
135 get { return "XEngine"; } 203 get { return "XEngine"; }
@@ -457,44 +525,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine
457 { 525 {
458 if (!m_Enabled) 526 if (!m_Enabled)
459 return; 527 return;
460 528 lockScriptsForRead(true);
461 lock (m_Scripts) 529 foreach (IScriptInstance instance in m_Scripts.Values)
462 { 530 {
463 m_log.InfoFormat( 531 // Force a final state save
464 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 532 //
465 533 if (m_Assemblies.ContainsKey(instance.AssetID))
466 foreach (IScriptInstance instance in m_Scripts.Values)
467 { 534 {
468 // Force a final state save 535 string assembly = m_Assemblies[instance.AssetID];
469 // 536 instance.SaveState(assembly);
470 if (m_Assemblies.ContainsKey(instance.AssetID)) 537 }
471 {
472 string assembly = m_Assemblies[instance.AssetID];
473 instance.SaveState(assembly);
474 }
475 538
476 // Clear the event queue and abort the instance thread 539 // Clear the event queue and abort the instance thread
477 // 540 //
478 instance.ClearQueue(); 541 instance.ClearQueue();
479 instance.Stop(0); 542 instance.Stop(0);
480 543
481 // Release events, timer, etc 544 // Release events, timer, etc
482 // 545 //
483 instance.DestroyScriptInstance(); 546 instance.DestroyScriptInstance();
484 547
485 // Unload scripts and app domains. 548 // Unload scripts and app domains
486 // Must be done explicitly because they have infinite 549 // Must be done explicitly because they have infinite
487 // lifetime. 550 // lifetime
488 // However, don't bother to do this if the simulator is shutting 551 //
489 // down since it takes a long time with many scripts. 552 if (!m_SimulatorShuttingDown)
490 if (!m_SimulatorShuttingDown) 553 {
554 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
555 if (m_DomainScripts[instance.AppDomain].Count == 0)
491 { 556 {
492 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 557 m_DomainScripts.Remove(instance.AppDomain);
493 if (m_DomainScripts[instance.AppDomain].Count == 0) 558 UnloadAppDomain(instance.AppDomain);
494 {
495 m_DomainScripts.Remove(instance.AppDomain);
496 UnloadAppDomain(instance.AppDomain);
497 }
498 } 559 }
499 } 560 }
500 561
@@ -503,6 +564,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
503 m_Assemblies.Clear(); 564 m_Assemblies.Clear();
504 m_DomainScripts.Clear(); 565 m_DomainScripts.Clear();
505 } 566 }
567 lockScriptsForRead(false);
568 lockScriptsForWrite(true);
569 m_Scripts.Clear();
570 lockScriptsForWrite(false);
571 m_PrimObjects.Clear();
572 m_Assemblies.Clear();
573 m_DomainScripts.Clear();
574
506 lock (m_ScriptEngines) 575 lock (m_ScriptEngines)
507 { 576 {
508 m_ScriptEngines.Remove(this); 577 m_ScriptEngines.Remove(this);
@@ -567,22 +636,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
567 636
568 List<IScriptInstance> instances = new List<IScriptInstance>(); 637 List<IScriptInstance> instances = new List<IScriptInstance>();
569 638
570 lock (m_Scripts) 639 lockScriptsForRead(true);
571 { 640 foreach (IScriptInstance instance in m_Scripts.Values)
572 foreach (IScriptInstance instance in m_Scripts.Values)
573 instances.Add(instance); 641 instances.Add(instance);
574 } 642 lockScriptsForRead(false);
575 643
576 foreach (IScriptInstance i in instances) 644 foreach (IScriptInstance i in instances)
577 { 645 {
578 string assembly = String.Empty; 646 string assembly = String.Empty;
579 647
580 lock (m_Scripts) 648
581 {
582 if (!m_Assemblies.ContainsKey(i.AssetID)) 649 if (!m_Assemblies.ContainsKey(i.AssetID))
583 continue; 650 continue;
584 assembly = m_Assemblies[i.AssetID]; 651 assembly = m_Assemblies[i.AssetID];
585 } 652
586 653
587 i.SaveState(assembly); 654 i.SaveState(assembly);
588 } 655 }
@@ -916,92 +983,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
916 } 983 }
917 984
918 ScriptInstance instance = null; 985 ScriptInstance instance = null;
919 lock (m_Scripts) 986 // Create the object record
987 lockScriptsForRead(true);
988 if ((!m_Scripts.ContainsKey(itemID)) ||
989 (m_Scripts[itemID].AssetID != assetID))
920 { 990 {
921 // Create the object record 991 lockScriptsForRead(false);
922 992
923 if ((!m_Scripts.ContainsKey(itemID)) || 993 UUID appDomain = assetID;
924 (m_Scripts[itemID].AssetID != assetID))
925 {
926 UUID appDomain = assetID;
927 994
928 if (part.ParentGroup.IsAttachment) 995 if (part.ParentGroup.IsAttachment)
929 appDomain = part.ParentGroup.RootPart.UUID; 996 appDomain = part.ParentGroup.RootPart.UUID;
930 997
931 if (!m_AppDomains.ContainsKey(appDomain)) 998 if (!m_AppDomains.ContainsKey(appDomain))
999 {
1000 try
932 { 1001 {
933 try 1002 AppDomainSetup appSetup = new AppDomainSetup();
934 { 1003 appSetup.PrivateBinPath = Path.Combine(
935 AppDomainSetup appSetup = new AppDomainSetup(); 1004 m_ScriptEnginesPath,
936 appSetup.PrivateBinPath = Path.Combine( 1005 m_Scene.RegionInfo.RegionID.ToString());
937 m_ScriptEnginesPath, 1006
938 m_Scene.RegionInfo.RegionID.ToString()); 1007 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
939 1008 Evidence evidence = new Evidence(baseEvidence);
940 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1009
941 Evidence evidence = new Evidence(baseEvidence); 1010 AppDomain sandbox;
942 1011 if (m_AppDomainLoading)
943 AppDomain sandbox; 1012 sandbox = AppDomain.CreateDomain(
944 if (m_AppDomainLoading) 1013 m_Scene.RegionInfo.RegionID.ToString(),
945 sandbox = AppDomain.CreateDomain( 1014 evidence, appSetup);
946 m_Scene.RegionInfo.RegionID.ToString(), 1015 else
947 evidence, appSetup); 1016 sandbox = AppDomain.CurrentDomain;
948 else 1017
949 sandbox = AppDomain.CurrentDomain; 1018 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
950 1019 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
951 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 1020 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
952 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 1021 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
953 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 1022 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
954 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 1023 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
955 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 1024 //sandbox.SetAppDomainPolicy(sandboxPolicy);
956 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 1025
957 //sandbox.SetAppDomainPolicy(sandboxPolicy); 1026 m_AppDomains[appDomain] = sandbox;
958 1027
959 m_AppDomains[appDomain] = sandbox; 1028 m_AppDomains[appDomain].AssemblyResolve +=
960 1029 new ResolveEventHandler(
961 m_AppDomains[appDomain].AssemblyResolve += 1030 AssemblyResolver.OnAssemblyResolve);
962 new ResolveEventHandler( 1031 m_DomainScripts[appDomain] = new List<UUID>();
963 AssemblyResolver.OnAssemblyResolve); 1032 }
964 m_DomainScripts[appDomain] = new List<UUID>(); 1033 catch (Exception e)
965 } 1034 {
966 catch (Exception e) 1035 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1036 m_ScriptErrorMessage += "Exception creating app domain:\n";
1037 m_ScriptFailCount++;
1038 lock (m_AddingAssemblies)
967 { 1039 {
968 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1040 m_AddingAssemblies[assembly]--;
969 m_ScriptErrorMessage += "Exception creating app domain:\n";
970 m_ScriptFailCount++;
971 lock (m_AddingAssemblies)
972 {
973 m_AddingAssemblies[assembly]--;
974 }
975 return false;
976 } 1041 }
1042 return false;
977 } 1043 }
978 m_DomainScripts[appDomain].Add(itemID); 1044 }
979 1045 m_DomainScripts[appDomain].Add(itemID);
980 instance = new ScriptInstance(this, part, 1046
981 itemID, assetID, assembly, 1047 instance = new ScriptInstance(this, part,
982 m_AppDomains[appDomain], 1048 itemID, assetID, assembly,
983 part.ParentGroup.RootPart.Name, 1049 m_AppDomains[appDomain],
984 item.Name, startParam, postOnRez, 1050 part.ParentGroup.RootPart.Name,
985 stateSource, m_MaxScriptQueue); 1051 item.Name, startParam, postOnRez,
986 1052 stateSource, m_MaxScriptQueue);
987 m_log.DebugFormat( 1053
988 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}", 1054 m_log.DebugFormat(
989 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID, 1055 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1056 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
990 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 1057 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
991 1058
992 if (presence != null) 1059 if (presence != null)
993 { 1060 {
994 ShowScriptSaveResponse(item.OwnerID, 1061 ShowScriptSaveResponse(item.OwnerID,
995 assetID, "Compile successful", true); 1062 assetID, "Compile successful", true);
996 }
997
998 instance.AppDomain = appDomain;
999 instance.LineMap = linemap;
1000
1001 m_Scripts[itemID] = instance;
1002 } 1063 }
1003 }
1004 1064
1065 instance.AppDomain = appDomain;
1066 instance.LineMap = linemap;
1067 lockScriptsForWrite(true);
1068 m_Scripts[itemID] = instance;
1069 lockScriptsForWrite(false);
1070 }
1071 else
1072 {
1073 lockScriptsForRead(false);
1074 }
1005 lock (m_PrimObjects) 1075 lock (m_PrimObjects)
1006 { 1076 {
1007 if (!m_PrimObjects.ContainsKey(localID)) 1077 if (!m_PrimObjects.ContainsKey(localID))
@@ -1020,9 +1090,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1020 m_AddingAssemblies[assembly]--; 1090 m_AddingAssemblies[assembly]--;
1021 } 1091 }
1022 1092
1023 if (instance != null) 1093 if (instance!=null)
1024 instance.Init(); 1094 instance.Init();
1025 1095
1026 return true; 1096 return true;
1027 } 1097 }
1028 1098
@@ -1035,20 +1105,31 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1035 m_CompileDict.Remove(itemID); 1105 m_CompileDict.Remove(itemID);
1036 } 1106 }
1037 1107
1038 IScriptInstance instance = null; 1108 lockScriptsForRead(true);
1039 1109 // Do we even have it?
1040 lock (m_Scripts) 1110 if (!m_Scripts.ContainsKey(itemID))
1041 { 1111 {
1042 // Do we even have it? 1112 // Do we even have it?
1043 if (!m_Scripts.ContainsKey(itemID)) 1113 if (!m_Scripts.ContainsKey(itemID))
1044 return; 1114 return;
1045 1115
1046 instance = m_Scripts[itemID]; 1116 lockScriptsForRead(false);
1117 lockScriptsForWrite(true);
1047 m_Scripts.Remove(itemID); 1118 m_Scripts.Remove(itemID);
1119 lockScriptsForWrite(false);
1120
1121 return;
1048 } 1122 }
1123
1049 1124
1125 IScriptInstance instance=m_Scripts[itemID];
1126 lockScriptsForRead(false);
1127 lockScriptsForWrite(true);
1128 m_Scripts.Remove(itemID);
1129 lockScriptsForWrite(false);
1050 instance.ClearQueue(); 1130 instance.ClearQueue();
1051 instance.Stop(0); 1131 instance.Stop(0);
1132
1052// bool objectRemoved = false; 1133// bool objectRemoved = false;
1053 1134
1054 lock (m_PrimObjects) 1135 lock (m_PrimObjects)
@@ -1084,11 +1165,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1084 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1165 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1085 if (handlerObjectRemoved != null) 1166 if (handlerObjectRemoved != null)
1086 { 1167 {
1087 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 1168 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1088 handlerObjectRemoved(part.UUID); 1169 handlerObjectRemoved(part.UUID);
1089 } 1170 }
1090 1171
1091 1172 CleanAssemblies();
1173
1092 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1174 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1093 if (handlerScriptRemoved != null) 1175 if (handlerScriptRemoved != null)
1094 handlerScriptRemoved(itemID); 1176 handlerScriptRemoved(itemID);
@@ -1230,7 +1312,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1230 return false; 1312 return false;
1231 1313
1232 uuids = m_PrimObjects[localID]; 1314 uuids = m_PrimObjects[localID];
1233 } 1315
1234 1316
1235 foreach (UUID itemID in uuids) 1317 foreach (UUID itemID in uuids)
1236 { 1318 {
@@ -1248,6 +1330,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1248 result = true; 1330 result = true;
1249 } 1331 }
1250 } 1332 }
1333 }
1251 1334
1252 return result; 1335 return result;
1253 } 1336 }
@@ -1347,12 +1430,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1347 private IScriptInstance GetInstance(UUID itemID) 1430 private IScriptInstance GetInstance(UUID itemID)
1348 { 1431 {
1349 IScriptInstance instance; 1432 IScriptInstance instance;
1350 lock (m_Scripts) 1433 lockScriptsForRead(true);
1434 if (!m_Scripts.ContainsKey(itemID))
1351 { 1435 {
1352 if (!m_Scripts.ContainsKey(itemID)) 1436 lockScriptsForRead(false);
1353 return null; 1437 return null;
1354 instance = m_Scripts[itemID];
1355 } 1438 }
1439 instance = m_Scripts[itemID];
1440 lockScriptsForRead(false);
1356 return instance; 1441 return instance;
1357 } 1442 }
1358 1443
@@ -1376,6 +1461,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1376 return false; 1461 return false;
1377 } 1462 }
1378 1463
1464 [DebuggerNonUserCode]
1379 public void ApiResetScript(UUID itemID) 1465 public void ApiResetScript(UUID itemID)
1380 { 1466 {
1381 IScriptInstance instance = GetInstance(itemID); 1467 IScriptInstance instance = GetInstance(itemID);
@@ -1427,6 +1513,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1427 return UUID.Zero; 1513 return UUID.Zero;
1428 } 1514 }
1429 1515
1516 [DebuggerNonUserCode]
1430 public void SetState(UUID itemID, string newState) 1517 public void SetState(UUID itemID, string newState)
1431 { 1518 {
1432 IScriptInstance instance = GetInstance(itemID); 1519 IScriptInstance instance = GetInstance(itemID);
@@ -1449,11 +1536,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1449 1536
1450 List<IScriptInstance> instances = new List<IScriptInstance>(); 1537 List<IScriptInstance> instances = new List<IScriptInstance>();
1451 1538
1452 lock (m_Scripts) 1539 lockScriptsForRead(true);
1453 { 1540 foreach (IScriptInstance instance in m_Scripts.Values)
1454 foreach (IScriptInstance instance in m_Scripts.Values)
1455 instances.Add(instance); 1541 instances.Add(instance);
1456 } 1542 lockScriptsForRead(false);
1457 1543
1458 foreach (IScriptInstance i in instances) 1544 foreach (IScriptInstance i in instances)
1459 { 1545 {
@@ -1830,5 +1916,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1830 if (instance != null) 1916 if (instance != null)
1831 instance.Resume(); 1917 instance.Resume();
1832 } 1918 }
1919
1920 public bool HasScript(UUID itemID, out bool running)
1921 {
1922 running = true;
1923
1924 IScriptInstance instance = GetInstance(itemID);
1925 if (instance == null)
1926 return false;
1927
1928 running = instance.Running;
1929 return true;
1930 }
1833 } 1931 }
1834} \ No newline at end of file 1932}