aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-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.cs3254
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs26
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs51
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs84
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs362
19 files changed, 3100 insertions, 1173 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 993d10f..3cbdde5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -301,6 +301,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
301 return null; 301 return null;
302 } 302 }
303 303
304 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
305 {
306 // Remove a specific script
307
308 // Remove dataserver events
309 m_Dataserver[engine].RemoveEvents(localID, itemID);
310
311 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
312 if (comms != null)
313 comms.DeleteListener(itemID);
314
315 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
316 xmlrpc.DeleteChannels(itemID);
317 xmlrpc.CancelSRDRequests(itemID);
318
319 // Remove Sensors
320 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
321
322 }
323
304 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 324 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
305 { 325 {
306 List<Object> data = new List<Object>(); 326 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..489c1c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal uint m_localID;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true;
75 }
76
77 public override Object InitializeLifetimeService()
78 {
79 ILease lease = (ILease)base.InitializeLifetimeService();
80
81 if (lease.CurrentState == LeaseState.Initial)
82 {
83 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
84 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
85 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
86 }
87 return lease;
88 }
89
90 public Scene World
91 {
92 get { return m_ScriptEngine.World; }
93 }
94
95 public string cmDetectedCountry(int number)
96 {
97 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
99 if (detectedParams == null)
100 return String.Empty;
101 return detectedParams.Country;
102 }
103
104 public string cmGetAgentCountry(LSL_Key key)
105 {
106 if (!World.Permissions.IsGod(m_host.OwnerID))
107 return String.Empty;
108
109 UUID uuid;
110
111 if (!UUID.TryParse(key, out uuid))
112 return String.Empty;
113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
116 }
117 }
118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 36c9d5e..e9ec314 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())
344 {
345 m_host.TaskInventory.LockItemsForRead(true);
346 unlock = true;
347 }
348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
275 { 349 {
276 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 350 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
277 { 351 {
278 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 352 invItemID = inv.Key;
279 { 353 break;
280 invItemID = inv.Key;
281 break;
282 }
283 } 354 }
284 } 355 }
285 356 if (unlock)
357 {
358 m_host.TaskInventory.LockItemsForRead(false);
359 }
286 return invItemID; 360 return invItemID;
287 } 361 }
288 362
289 protected UUID InventoryKey(string name, int type) 363 protected UUID InventoryKey(string name, int type)
290 { 364 {
291 m_host.AddScriptLPS(1); 365 m_host.AddScriptLPS(1);
292 366 m_host.TaskInventory.LockItemsForRead(true);
293 lock (m_host.TaskInventory) 367
368 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
294 { 369 {
295 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 370 if (inv.Value.Name == name)
296 { 371 {
297 if (inv.Value.Name == name) 372 m_host.TaskInventory.LockItemsForRead(false);
373
374 if (inv.Value.Type != type)
298 { 375 {
299 if (inv.Value.Type != type) 376 return UUID.Zero;
300 return UUID.Zero;
301
302 return inv.Value.AssetID;
303 } 377 }
378
379 return inv.Value.AssetID;
304 } 380 }
305 } 381 }
306 382
383 m_host.TaskInventory.LockItemsForRead(false);
307 return UUID.Zero; 384 return UUID.Zero;
308 } 385 }
309 386
@@ -311,17 +388,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
311 { 388 {
312 m_host.AddScriptLPS(1); 389 m_host.AddScriptLPS(1);
313 390
314 lock (m_host.TaskInventory) 391
392 m_host.TaskInventory.LockItemsForRead(true);
393
394 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 395 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 396 if (inv.Value.Name == name)
317 { 397 {
318 if (inv.Value.Name == name) 398 m_host.TaskInventory.LockItemsForRead(false);
319 { 399 return inv.Value.AssetID;
320 return inv.Value.AssetID;
321 }
322 } 400 }
323 } 401 }
324 402
403 m_host.TaskInventory.LockItemsForRead(false);
404
405
325 return UUID.Zero; 406 return UUID.Zero;
326 } 407 }
327 408
@@ -463,31 +544,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
463 544
464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 545 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
465 546
466 /// <summary> 547 // Utility function for llRot2Euler
467 /// Convert an LSL rotation to a Euler vector. 548
468 /// </summary> 549 // normalize an angle between -PI and PI (-180 to +180 degrees)
469 /// <remarks> 550 protected double NormalizeAngle(double angle)
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
475 public LSL_Vector llRot2Euler(LSL_Rotation r)
476 { 551 {
477 m_host.AddScriptLPS(1); 552 if (angle > -Math.PI && angle < Math.PI)
553 return angle;
554
555 int numPis = (int)(Math.PI / angle);
556 double remainder = angle - Math.PI * numPis;
557 if (numPis % 2 == 1)
558 return Math.PI - angle;
559 return remainder;
560 }
478 561
479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 562 public LSL_Vector llRot2Euler(LSL_Rotation q1)
480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 563 {
481 if (m == 0.0) return new LSL_Vector(); 564 m_host.AddScriptLPS(1);
482 double x = Math.Atan2(-v.y, v.z); 565 LSL_Vector eul = new LSL_Vector();
483 double sin = v.x / m;
484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
485 double y = Math.Asin(sin);
486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
487 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
488 double z = Math.Atan2(v.y, v.x);
489 566
490 return new LSL_Vector(x, y, z); 567 double sqw = q1.s*q1.s;
568 double sqx = q1.x*q1.x;
569 double sqy = q1.z*q1.z;
570 double sqz = q1.y*q1.y;
571 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
572 double test = q1.x*q1.z + q1.y*q1.s;
573 if (test > 0.4999*unit) { // singularity at north pole
574 eul.z = 2 * Math.Atan2(q1.x,q1.s);
575 eul.y = Math.PI/2;
576 eul.x = 0;
577 return eul;
578 }
579 if (test < -0.4999*unit) { // singularity at south pole
580 eul.z = -2 * Math.Atan2(q1.x,q1.s);
581 eul.y = -Math.PI/2;
582 eul.x = 0;
583 return eul;
584 }
585 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
586 eul.y = Math.Asin(2*test/unit);
587 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
588 return eul;
491 } 589 }
492 590
493 /* From wiki: 591 /* From wiki:
@@ -689,77 +787,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 787 {
690 //A and B should both be normalized 788 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 789 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 790 /* This method is more accurate than the SL one, and thus causes problems
693 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 791 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 792
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 793 double dotProduct = LSL_Vector.Dot(a, b);
794 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
795 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
796 double angle = Math.Acos(dotProduct / magProduct);
797 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
798 double s = Math.Sin(angle / 2);
799
800 double x = axis.x * s;
801 double y = axis.y * s;
802 double z = axis.z * s;
803 double w = Math.Cos(angle / 2);
804
805 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
806 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
807
808 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
809 */
810
811 // This method mimics the 180 errors found in SL
812 // See www.euclideanspace.com... angleBetween
813 LSL_Vector vec_a = a;
814 LSL_Vector vec_b = b;
815
816 // Eliminate zero length
817 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
818 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
819 if (vec_a_mag < 0.00001 ||
820 vec_b_mag < 0.00001)
696 { 821 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 822 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 823 }
699 else 824
825 // Normalize
826 vec_a = llVecNorm(vec_a);
827 vec_b = llVecNorm(vec_b);
828
829 // Calculate axis and rotation angle
830 LSL_Vector axis = vec_a % vec_b;
831 LSL_Float cos_theta = vec_a * vec_b;
832
833 // Check if parallel
834 if (cos_theta > 0.99999)
700 { 835 {
701 a = LSL_Vector.Norm(a); 836 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 837 }
703 double dotProduct = LSL_Vector.Dot(a, b); 838
704 // There are two degenerate cases possible. These are for vectors 180 or 839 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 840 else if (cos_theta < -0.99999)
706 // 841 {
707 // Check for vectors 180 degrees apart. 842 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
708 // A dot product of -1 would mean the angle between vectors is 180 degrees. 843 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 844 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 845 }
711 // First assume X axis is orthogonal to the vectors. 846 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 847 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 848 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
714 // Check for near zero vector. A very small non-zero number here will create 849 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 850 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 851 s = Math.Cos(theta);
717 { 852 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 853 x = axis.x * t;
719 } 854 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 855 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 856 return new LSL_Rotation(x,y,z,s);
722 else
723 {
724 // Set 180 z rotation.
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
726 }
727 }
728 // Check for parallel vectors.
729 // A dot product of 1 would mean the angle between vectors is 0 degrees.
730 else if (dotProduct > 0.9999999f)
731 {
732 // Set zero rotation.
733 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
734 }
735 else
736 {
737 // All special checks have been performed so get the axis of rotation.
738 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
739 // Quarternion s value is the length of the unit vector + dot product.
740 double qs = 1.0 + dotProduct;
741 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
742 // Normalize the rotation.
743 double mag = LSL_Rotation.Mag(rotBetween);
744 // We shouldn't have to worry about a divide by zero here. The qs value will be
745 // non-zero because we already know if we're here, then the dotProduct is not -1 so
746 // qs will not be zero. Also, we've already handled the input vectors being zero so the
747 // crossProduct vector should also not be zero.
748 rotBetween.x = rotBetween.x / mag;
749 rotBetween.y = rotBetween.y / mag;
750 rotBetween.z = rotBetween.z / mag;
751 rotBetween.s = rotBetween.s / mag;
752 // Check for undefined values and set zero rotation if any found. This code might not actually be required
753 // any longer since zero vectors are checked for at the top.
754 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
755 {
756 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
757 }
758 }
759 } 857 }
760 return rotBetween;
761 } 858 }
762 859
763 public void llWhisper(int channelID, string text) 860 public void llWhisper(int channelID, string text)
764 { 861 {
765 m_host.AddScriptLPS(1); 862 m_host.AddScriptLPS(1);
@@ -779,6 +876,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 876 {
780 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
781 878
879 if (channelID == 0)
880 m_SayShoutCount++;
881
882 if (m_SayShoutCount >= 11)
883 ScriptSleep(2000);
884
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 885 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 886 {
784 Console.WriteLine(text); 887 Console.WriteLine(text);
@@ -801,6 +904,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 904 {
802 m_host.AddScriptLPS(1); 905 m_host.AddScriptLPS(1);
803 906
907 if (channelID == 0)
908 m_SayShoutCount++;
909
910 if (m_SayShoutCount >= 11)
911 ScriptSleep(2000);
912
804 if (text.Length > 1023) 913 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 914 text = text.Substring(0, 1023);
806 915
@@ -1101,10 +1210,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1210 return detectedParams.TouchUV;
1102 } 1211 }
1103 1212
1213 [DebuggerNonUserCode]
1104 public virtual void llDie() 1214 public virtual void llDie()
1105 { 1215 {
1106 m_host.AddScriptLPS(1); 1216 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1217 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1218 }
1109 1219
1110 public LSL_Float llGround(LSL_Vector offset) 1220 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1287
1178 public void llSetStatus(int status, int value) 1288 public void llSetStatus(int status, int value)
1179 { 1289 {
1290 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1291 return;
1180 m_host.AddScriptLPS(1); 1292 m_host.AddScriptLPS(1);
1181 1293
1182 int statusrotationaxis = 0; 1294 int statusrotationaxis = 0;
@@ -1408,6 +1520,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1408 { 1520 {
1409 m_host.AddScriptLPS(1); 1521 m_host.AddScriptLPS(1);
1410 1522
1523 SetColor(m_host, color, face);
1524 }
1525
1526 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1527 {
1528 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1529 return;
1530
1531 Primitive.TextureEntry tex = part.Shape.Textures;
1532 Color4 texcolor;
1533 if (face >= 0 && face < GetNumberOfSides(part))
1534 {
1535 texcolor = tex.CreateFace((uint)face).RGBA;
1536 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1537 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1538 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1539 tex.FaceTextures[face].RGBA = texcolor;
1540 part.UpdateTextureEntry(tex.GetBytes());
1541 return;
1542 }
1543 else if (face == ScriptBaseClass.ALL_SIDES)
1544 {
1545 for (uint i = 0; i < GetNumberOfSides(part); i++)
1546 {
1547 if (tex.FaceTextures[i] != null)
1548 {
1549 texcolor = tex.FaceTextures[i].RGBA;
1550 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1551 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1552 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1553 tex.FaceTextures[i].RGBA = texcolor;
1554 }
1555 texcolor = tex.DefaultTexture.RGBA;
1556 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1557 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1558 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1559 tex.DefaultTexture.RGBA = texcolor;
1560 }
1561 part.UpdateTextureEntry(tex.GetBytes());
1562 return;
1563 }
1564
1411 if (face == ScriptBaseClass.ALL_SIDES) 1565 if (face == ScriptBaseClass.ALL_SIDES)
1412 face = SceneObjectPart.ALL_SIDES; 1566 face = SceneObjectPart.ALL_SIDES;
1413 1567
@@ -1416,6 +1570,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1416 1570
1417 public void SetTexGen(SceneObjectPart part, int face,int style) 1571 public void SetTexGen(SceneObjectPart part, int face,int style)
1418 { 1572 {
1573 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1574 return;
1575
1419 Primitive.TextureEntry tex = part.Shape.Textures; 1576 Primitive.TextureEntry tex = part.Shape.Textures;
1420 MappingType textype; 1577 MappingType textype;
1421 textype = MappingType.Default; 1578 textype = MappingType.Default;
@@ -1446,6 +1603,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1446 1603
1447 public void SetGlow(SceneObjectPart part, int face, float glow) 1604 public void SetGlow(SceneObjectPart part, int face, float glow)
1448 { 1605 {
1606 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1607 return;
1608
1449 Primitive.TextureEntry tex = part.Shape.Textures; 1609 Primitive.TextureEntry tex = part.Shape.Textures;
1450 if (face >= 0 && face < GetNumberOfSides(part)) 1610 if (face >= 0 && face < GetNumberOfSides(part))
1451 { 1611 {
@@ -1471,6 +1631,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1471 1631
1472 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1632 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1473 { 1633 {
1634 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1635 return;
1474 1636
1475 Shininess sval = new Shininess(); 1637 Shininess sval = new Shininess();
1476 1638
@@ -1521,6 +1683,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1521 1683
1522 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1684 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1523 { 1685 {
1686 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1687 return;
1688
1524 Primitive.TextureEntry tex = part.Shape.Textures; 1689 Primitive.TextureEntry tex = part.Shape.Textures;
1525 if (face >= 0 && face < GetNumberOfSides(part)) 1690 if (face >= 0 && face < GetNumberOfSides(part))
1526 { 1691 {
@@ -1581,13 +1746,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1581 m_host.AddScriptLPS(1); 1746 m_host.AddScriptLPS(1);
1582 1747
1583 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1748 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1584 1749 if (parts.Count > 0)
1585 foreach (SceneObjectPart part in parts) 1750 {
1586 SetAlpha(part, alpha, face); 1751 try
1752 {
1753 parts[0].ParentGroup.areUpdatesSuspended = true;
1754 foreach (SceneObjectPart part in parts)
1755 SetAlpha(part, alpha, face);
1756 }
1757 finally
1758 {
1759 parts[0].ParentGroup.areUpdatesSuspended = false;
1760 }
1761 }
1587 } 1762 }
1588 1763
1589 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1764 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1590 { 1765 {
1766 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1767 return;
1768
1591 Primitive.TextureEntry tex = part.Shape.Textures; 1769 Primitive.TextureEntry tex = part.Shape.Textures;
1592 Color4 texcolor; 1770 Color4 texcolor;
1593 if (face >= 0 && face < GetNumberOfSides(part)) 1771 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1640,7 +1818,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1640 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1818 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1641 float wind, float tension, LSL_Vector Force) 1819 float wind, float tension, LSL_Vector Force)
1642 { 1820 {
1643 if (part == null) 1821 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1644 return; 1822 return;
1645 1823
1646 if (flexi) 1824 if (flexi)
@@ -1674,7 +1852,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1674 /// <param name="falloff"></param> 1852 /// <param name="falloff"></param>
1675 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1853 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1676 { 1854 {
1677 if (part == null) 1855 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1678 return; 1856 return;
1679 1857
1680 if (light) 1858 if (light)
@@ -1751,15 +1929,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1751 m_host.AddScriptLPS(1); 1929 m_host.AddScriptLPS(1);
1752 1930
1753 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1931 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1754 1932 if (parts.Count > 0)
1755 foreach (SceneObjectPart part in parts) 1933 {
1756 SetTexture(part, texture, face); 1934 try
1757 1935 {
1936 parts[0].ParentGroup.areUpdatesSuspended = true;
1937 foreach (SceneObjectPart part in parts)
1938 SetTexture(part, texture, face);
1939 }
1940 finally
1941 {
1942 parts[0].ParentGroup.areUpdatesSuspended = false;
1943 }
1944 }
1758 ScriptSleep(200); 1945 ScriptSleep(200);
1759 } 1946 }
1760 1947
1761 protected void SetTexture(SceneObjectPart part, string texture, int face) 1948 protected void SetTexture(SceneObjectPart part, string texture, int face)
1762 { 1949 {
1950 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1951 return;
1952
1763 UUID textureID = new UUID(); 1953 UUID textureID = new UUID();
1764 1954
1765 textureID = InventoryKey(texture, (int)AssetType.Texture); 1955 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1804,6 +1994,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1804 1994
1805 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1995 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1806 { 1996 {
1997 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1998 return;
1999
1807 Primitive.TextureEntry tex = part.Shape.Textures; 2000 Primitive.TextureEntry tex = part.Shape.Textures;
1808 if (face >= 0 && face < GetNumberOfSides(part)) 2001 if (face >= 0 && face < GetNumberOfSides(part))
1809 { 2002 {
@@ -1840,6 +2033,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1840 2033
1841 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2034 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1842 { 2035 {
2036 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2037 return;
2038
1843 Primitive.TextureEntry tex = part.Shape.Textures; 2039 Primitive.TextureEntry tex = part.Shape.Textures;
1844 if (face >= 0 && face < GetNumberOfSides(part)) 2040 if (face >= 0 && face < GetNumberOfSides(part))
1845 { 2041 {
@@ -1876,6 +2072,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1876 2072
1877 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2073 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1878 { 2074 {
2075 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2076 return;
2077
1879 Primitive.TextureEntry tex = part.Shape.Textures; 2078 Primitive.TextureEntry tex = part.Shape.Textures;
1880 if (face >= 0 && face < GetNumberOfSides(part)) 2079 if (face >= 0 && face < GetNumberOfSides(part))
1881 { 2080 {
@@ -1980,26 +2179,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 return real_vec; 2179 return real_vec;
1981 } 2180 }
1982 2181
2182 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2183 {
2184 return new LSL_Integer(SetRegionPos(m_host, pos));
2185 }
2186
2187 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2188 {
2189 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2190 return 0;
2191
2192 SceneObjectGroup grp = part.ParentGroup;
2193
2194 if (grp.IsAttachment)
2195 return 0;
2196
2197 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2198 return 0;
2199
2200 if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
2201 return 0;
2202
2203 float constrainedX = (float)targetPos.x;
2204 float constrainedY = (float)targetPos.y;
2205
2206 if (constrainedX < 0.0f)
2207 constrainedX = 0.0f;
2208 if (constrainedY < 0.0f)
2209 constrainedY = 0.0f;
2210 if (constrainedX >= (float)Constants.RegionSize)
2211 constrainedX = (float)Constants.RegionSize - 0.1f;
2212 if (constrainedY >= (float)Constants.RegionSize)
2213 constrainedY = (float)Constants.RegionSize -0.1f;
2214
2215 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2216
2217 if (targetPos.z < ground)
2218 targetPos.z = ground;
2219
2220 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2221
2222 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2223 return 0;
2224
2225 grp.UpdateGroupPosition(dest);
2226
2227 return 1;
2228 }
2229
1983 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2230 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1984 { 2231 {
1985 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2232 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2233 return;
2234
1986 LSL_Vector currentPos = GetPartLocalPos(part); 2235 LSL_Vector currentPos = GetPartLocalPos(part);
2236 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1987 2237
1988 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1989 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1990 2238
1991 if (part.ParentGroup.RootPart == part) 2239 if (part.ParentGroup.RootPart == part)
1992 { 2240 {
1993 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1994 targetPos.z = ground;
1995 SceneObjectGroup parent = part.ParentGroup; 2241 SceneObjectGroup parent = part.ParentGroup;
1996 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2242 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1997 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2243 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2244 return;
2245 Util.FireAndForget(delegate(object x) {
2246 parent.UpdateGroupPosition(dest);
2247 });
1998 } 2248 }
1999 else 2249 else
2000 { 2250 {
2001 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2251 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2002 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2003 SceneObjectGroup parent = part.ParentGroup; 2252 SceneObjectGroup parent = part.ParentGroup;
2004 parent.HasGroupChanged = true; 2253 parent.HasGroupChanged = true;
2005 parent.ScheduleGroupForTerseUpdate(); 2254 parent.ScheduleGroupForTerseUpdate();
@@ -2032,17 +2281,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2032 else 2281 else
2033 { 2282 {
2034 if (part.ParentGroup.IsAttachment) 2283 if (part.ParentGroup.IsAttachment)
2035 {
2036 pos = part.AttachedPos; 2284 pos = part.AttachedPos;
2037 }
2038 else 2285 else
2039 {
2040 pos = part.AbsolutePosition; 2286 pos = part.AbsolutePosition;
2041 }
2042 } 2287 }
2043 2288
2044// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2045
2046 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2289 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2047 } 2290 }
2048 2291
@@ -2051,9 +2294,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2051 m_host.AddScriptLPS(1); 2294 m_host.AddScriptLPS(1);
2052 2295
2053 // try to let this work as in SL... 2296 // try to let this work as in SL...
2054 if (m_host.ParentID == 0) 2297 if (m_host.LinkNum < 2)
2055 { 2298 {
2056 // special case: If we are root, rotate complete SOG to new rotation 2299 // Special case: If we are root, rotate complete SOG to new
2300 // rotation.
2301 // We are root if the link number is 0 (single prim) or 1
2302 // (root prim). ParentID may be nonzero in attachments and
2303 // using it would cause attachments and HUDs to rotate
2304 // to the wrong positions.
2057 SetRot(m_host, Rot2Quaternion(rot)); 2305 SetRot(m_host, Rot2Quaternion(rot));
2058 } 2306 }
2059 else 2307 else
@@ -2078,6 +2326,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2078 2326
2079 protected void SetRot(SceneObjectPart part, Quaternion rot) 2327 protected void SetRot(SceneObjectPart part, Quaternion rot)
2080 { 2328 {
2329 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2330 return;
2331
2081 part.UpdateRotation(rot); 2332 part.UpdateRotation(rot);
2082 // Update rotation does not move the object in the physics scene if it's a linkset. 2333 // Update rotation does not move the object in the physics scene if it's a linkset.
2083 2334
@@ -2232,13 +2483,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2232 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2483 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2233 { 2484 {
2234 m_host.AddScriptLPS(1); 2485 m_host.AddScriptLPS(1);
2235 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2486 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2236 } 2487 }
2237 2488
2238 public void llSetTorque(LSL_Vector torque, int local) 2489 public void llSetTorque(LSL_Vector torque, int local)
2239 { 2490 {
2240 m_host.AddScriptLPS(1); 2491 m_host.AddScriptLPS(1);
2241 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2492 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2242 } 2493 }
2243 2494
2244 public LSL_Vector llGetTorque() 2495 public LSL_Vector llGetTorque()
@@ -2703,12 +2954,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2703 2954
2704 m_host.AddScriptLPS(1); 2955 m_host.AddScriptLPS(1);
2705 2956
2957 m_host.TaskInventory.LockItemsForRead(true);
2706 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2958 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2707 2959 m_host.TaskInventory.LockItemsForRead(false);
2708 lock (m_host.TaskInventory)
2709 {
2710 item = m_host.TaskInventory[invItemID];
2711 }
2712 2960
2713 if (item.PermsGranter == UUID.Zero) 2961 if (item.PermsGranter == UUID.Zero)
2714 return 0; 2962 return 0;
@@ -2851,35 +3099,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2851 public void llLookAt(LSL_Vector target, double strength, double damping) 3099 public void llLookAt(LSL_Vector target, double strength, double damping)
2852 { 3100 {
2853 m_host.AddScriptLPS(1); 3101 m_host.AddScriptLPS(1);
2854 // Determine where we are looking from
2855 LSL_Vector from = llGetPos();
2856 3102
2857 // Work out the normalised vector from the source to the target 3103 // Get the normalized vector to the target
2858 LSL_Vector delta = llVecNorm(target - from); 3104 LSL_Vector d1 = llVecNorm(target - llGetPos());
2859 LSL_Vector angle = new LSL_Vector(0,0,0);
2860 3105
2861 // Calculate the yaw 3106 // Get the bearing (yaw)
2862 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3107 LSL_Vector a1 = new LSL_Vector(0,0,0);
2863 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3108 a1.z = llAtan2(d1.y, d1.x);
2864 3109
2865 // Calculate pitch 3110 // Get the elevation (pitch)
2866 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3111 LSL_Vector a2 = new LSL_Vector(0,0,0);
3112 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2867 3113
2868 // we need to convert from a vector describing 3114 LSL_Rotation r1 = llEuler2Rot(a1);
2869 // the angles of rotation in radians into rotation value 3115 LSL_Rotation r2 = llEuler2Rot(a2);
2870 LSL_Rotation rot = llEuler2Rot(angle); 3116 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2871
2872 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2873 // set the rotation of the object, copy that behavior
2874 PhysicsActor pa = m_host.PhysActor;
2875 3117
2876 if (strength == 0 || pa == null || !pa.IsPhysical) 3118 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2877 { 3119 {
2878 llSetRot(rot); 3120 // Do nothing if either value is 0 (this has been checked in SL)
3121 if (strength <= 0.0 || damping <= 0.0)
3122 return;
3123
3124 llSetRot(r3 * r2 * r1);
2879 } 3125 }
2880 else 3126 else
2881 { 3127 {
2882 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3128 if (strength == 0)
3129 {
3130 llSetRot(r3 * r2 * r1);
3131 return;
3132 }
3133
3134 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2883 } 3135 }
2884 } 3136 }
2885 3137
@@ -2924,17 +3176,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2924 } 3176 }
2925 else 3177 else
2926 { 3178 {
2927 if (m_host.IsRoot) 3179 // new SL always returns object mass
2928 { 3180// if (m_host.IsRoot)
3181// {
2929 return m_host.ParentGroup.GetMass(); 3182 return m_host.ParentGroup.GetMass();
2930 } 3183// }
2931 else 3184// else
2932 { 3185// {
2933 return m_host.GetMass(); 3186// return m_host.GetMass();
2934 } 3187// }
2935 } 3188 }
2936 } 3189 }
2937 3190
3191
3192 public LSL_Float llGetMassMKS()
3193 {
3194 return 100f * llGetMass();
3195 }
3196
2938 public void llCollisionFilter(string name, string id, int accept) 3197 public void llCollisionFilter(string name, string id, int accept)
2939 { 3198 {
2940 m_host.AddScriptLPS(1); 3199 m_host.AddScriptLPS(1);
@@ -2953,13 +3212,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2953 { 3212 {
2954 TaskInventoryItem item; 3213 TaskInventoryItem item;
2955 3214
2956 lock (m_host.TaskInventory) 3215 m_host.TaskInventory.LockItemsForRead(true);
3216 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2957 { 3217 {
2958 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3218 m_host.TaskInventory.LockItemsForRead(false);
2959 return; 3219 return;
2960 else
2961 item = m_host.TaskInventory[InventorySelf()];
2962 } 3220 }
3221 else
3222 {
3223 item = m_host.TaskInventory[InventorySelf()];
3224 }
3225 m_host.TaskInventory.LockItemsForRead(false);
2963 3226
2964 if (item.PermsGranter != UUID.Zero) 3227 if (item.PermsGranter != UUID.Zero)
2965 { 3228 {
@@ -2981,13 +3244,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2981 { 3244 {
2982 TaskInventoryItem item; 3245 TaskInventoryItem item;
2983 3246
3247 m_host.TaskInventory.LockItemsForRead(true);
2984 lock (m_host.TaskInventory) 3248 lock (m_host.TaskInventory)
2985 { 3249 {
3250
2986 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3251 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3252 {
3253 m_host.TaskInventory.LockItemsForRead(false);
2987 return; 3254 return;
3255 }
2988 else 3256 else
3257 {
2989 item = m_host.TaskInventory[InventorySelf()]; 3258 item = m_host.TaskInventory[InventorySelf()];
3259 }
2990 } 3260 }
3261 m_host.TaskInventory.LockItemsForRead(false);
2991 3262
2992 m_host.AddScriptLPS(1); 3263 m_host.AddScriptLPS(1);
2993 3264
@@ -3019,19 +3290,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3019 { 3290 {
3020 m_host.AddScriptLPS(1); 3291 m_host.AddScriptLPS(1);
3021 3292
3022// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3023// return;
3024
3025 TaskInventoryItem item; 3293 TaskInventoryItem item;
3026 3294
3027 lock (m_host.TaskInventory) 3295 m_host.TaskInventory.LockItemsForRead(true);
3296
3297 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3028 { 3298 {
3029 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3299 m_host.TaskInventory.LockItemsForRead(false);
3030 return; 3300 return;
3031 else 3301 }
3032 item = m_host.TaskInventory[InventorySelf()]; 3302 else
3303 {
3304 item = m_host.TaskInventory[InventorySelf()];
3033 } 3305 }
3034 3306
3307 m_host.TaskInventory.LockItemsForRead(false);
3308
3035 if (item.PermsGranter != m_host.OwnerID) 3309 if (item.PermsGranter != m_host.OwnerID)
3036 return; 3310 return;
3037 3311
@@ -3056,13 +3330,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3056 3330
3057 TaskInventoryItem item; 3331 TaskInventoryItem item;
3058 3332
3059 lock (m_host.TaskInventory) 3333 m_host.TaskInventory.LockItemsForRead(true);
3334
3335 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3060 { 3336 {
3061 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3337 m_host.TaskInventory.LockItemsForRead(false);
3062 return; 3338 return;
3063 else
3064 item = m_host.TaskInventory[InventorySelf()];
3065 } 3339 }
3340 else
3341 {
3342 item = m_host.TaskInventory[InventorySelf()];
3343 }
3344 m_host.TaskInventory.LockItemsForRead(false);
3345
3066 3346
3067 if (item.PermsGranter != m_host.OwnerID) 3347 if (item.PermsGranter != m_host.OwnerID)
3068 return; 3348 return;
@@ -3109,6 +3389,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3109 3389
3110 public void llInstantMessage(string user, string message) 3390 public void llInstantMessage(string user, string message)
3111 { 3391 {
3392 UUID result;
3393 if (!UUID.TryParse(user, out result))
3394 {
3395 ShoutError("An invalid key was passed to llInstantMessage");
3396 ScriptSleep(2000);
3397 return;
3398 }
3399
3400
3112 m_host.AddScriptLPS(1); 3401 m_host.AddScriptLPS(1);
3113 3402
3114 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3403 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3123,14 +3412,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 UUID friendTransactionID = UUID.Random(); 3412 UUID friendTransactionID = UUID.Random();
3124 3413
3125 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3414 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3126 3415
3127 GridInstantMessage msg = new GridInstantMessage(); 3416 GridInstantMessage msg = new GridInstantMessage();
3128 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3417 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3129 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3418 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3130 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3419 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3131// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3420// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3132// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3421// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3133 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3422// DateTime dt = DateTime.UtcNow;
3423//
3424// // Ticks from UtcNow, but make it look like local. Evil, huh?
3425// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3426//
3427// try
3428// {
3429// // Convert that to the PST timezone
3430// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3431// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3432// }
3433// catch
3434// {
3435// // No logging here, as it could be VERY spammy
3436// }
3437//
3438// // And make it look local again to fool the unix time util
3439// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3440
3441 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3442
3134 //if (client != null) 3443 //if (client != null)
3135 //{ 3444 //{
3136 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3445 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3144,12 +3453,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3144 msg.message = message.Substring(0, 1024); 3453 msg.message = message.Substring(0, 1024);
3145 else 3454 else
3146 msg.message = message; 3455 msg.message = message;
3147 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3456 msg.dialog = (byte)19; // MessageFromObject
3148 msg.fromGroup = false;// fromGroup; 3457 msg.fromGroup = false;// fromGroup;
3149 msg.offline = (byte)0; //offline; 3458 msg.offline = (byte)0; //offline;
3150 msg.ParentEstateID = 0; //ParentEstateID; 3459 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3151 msg.Position = new Vector3(m_host.AbsolutePosition); 3460 msg.Position = new Vector3(m_host.AbsolutePosition);
3152 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3461 msg.RegionID = World.RegionInfo.RegionID.Guid;
3153 msg.binaryBucket 3462 msg.binaryBucket
3154 = Util.StringToBytes256( 3463 = Util.StringToBytes256(
3155 "{0}/{1}/{2}/{3}", 3464 "{0}/{1}/{2}/{3}",
@@ -3177,7 +3486,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3177 } 3486 }
3178 3487
3179 emailModule.SendEmail(m_host.UUID, address, subject, message); 3488 emailModule.SendEmail(m_host.UUID, address, subject, message);
3180 ScriptSleep(20000); 3489 ScriptSleep(15000);
3181 } 3490 }
3182 3491
3183 public void llGetNextEmail(string address, string subject) 3492 public void llGetNextEmail(string address, string subject)
@@ -3319,14 +3628,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3319 3628
3320 TaskInventoryItem item; 3629 TaskInventoryItem item;
3321 3630
3322 lock (m_host.TaskInventory) 3631 m_host.TaskInventory.LockItemsForRead(true);
3632 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3323 { 3633 {
3324 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3634 m_host.TaskInventory.LockItemsForRead(false);
3325 return; 3635 return;
3326 else
3327 item = m_host.TaskInventory[InventorySelf()];
3328 } 3636 }
3329 3637 else
3638 {
3639 item = m_host.TaskInventory[InventorySelf()];
3640 }
3641 m_host.TaskInventory.LockItemsForRead(false);
3330 if (item.PermsGranter == UUID.Zero) 3642 if (item.PermsGranter == UUID.Zero)
3331 return; 3643 return;
3332 3644
@@ -3356,13 +3668,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3356 3668
3357 TaskInventoryItem item; 3669 TaskInventoryItem item;
3358 3670
3359 lock (m_host.TaskInventory) 3671 m_host.TaskInventory.LockItemsForRead(true);
3672 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3360 { 3673 {
3361 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3674 m_host.TaskInventory.LockItemsForRead(false);
3362 return; 3675 return;
3363 else
3364 item = m_host.TaskInventory[InventorySelf()];
3365 } 3676 }
3677 else
3678 {
3679 item = m_host.TaskInventory[InventorySelf()];
3680 }
3681 m_host.TaskInventory.LockItemsForRead(false);
3682
3366 3683
3367 if (item.PermsGranter == UUID.Zero) 3684 if (item.PermsGranter == UUID.Zero)
3368 return; 3685 return;
@@ -3429,10 +3746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 3746
3430 TaskInventoryItem item; 3747 TaskInventoryItem item;
3431 3748
3432 lock (m_host.TaskInventory) 3749
3750 m_host.TaskInventory.LockItemsForRead(true);
3751 if (!m_host.TaskInventory.ContainsKey(invItemID))
3752 {
3753 m_host.TaskInventory.LockItemsForRead(false);
3754 return;
3755 }
3756 else
3433 { 3757 {
3434 item = m_host.TaskInventory[invItemID]; 3758 item = m_host.TaskInventory[invItemID];
3435 } 3759 }
3760 m_host.TaskInventory.LockItemsForRead(false);
3436 3761
3437 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3762 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3438 { 3763 {
@@ -3460,15 +3785,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3460 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3785 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3461 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3786 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3462 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3787 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3788 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3463 ScriptBaseClass.PERMISSION_ATTACH; 3789 ScriptBaseClass.PERMISSION_ATTACH;
3464 3790
3465 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3791 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3466 { 3792 {
3467 lock (m_host.TaskInventory) 3793 m_host.TaskInventory.LockItemsForWrite(true);
3468 { 3794 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3469 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3795 m_host.TaskInventory[invItemID].PermsMask = perm;
3470 m_host.TaskInventory[invItemID].PermsMask = perm; 3796 m_host.TaskInventory.LockItemsForWrite(false);
3471 }
3472 3797
3473 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3798 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3474 "run_time_permissions", new Object[] { 3799 "run_time_permissions", new Object[] {
@@ -3478,28 +3803,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 return; 3803 return;
3479 } 3804 }
3480 } 3805 }
3481 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3806 else
3482 { 3807 {
3483 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3808 bool sitting = false;
3484 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3809 if (m_host.SitTargetAvatar == agentID)
3485 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3810 {
3486 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3811 sitting = true;
3487 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3812 }
3813 else
3814 {
3815 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3816 {
3817 if (p.SitTargetAvatar == agentID)
3818 sitting = true;
3819 }
3820 }
3488 3821
3489 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3822 if (sitting)
3490 { 3823 {
3491 lock (m_host.TaskInventory) 3824 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3825 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3826 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3827 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3828 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3829
3830 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3492 { 3831 {
3832 m_host.TaskInventory.LockItemsForWrite(true);
3493 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3833 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3494 m_host.TaskInventory[invItemID].PermsMask = perm; 3834 m_host.TaskInventory[invItemID].PermsMask = perm;
3495 } 3835 m_host.TaskInventory.LockItemsForWrite(false);
3496 3836
3497 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3837 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3498 "run_time_permissions", new Object[] { 3838 "run_time_permissions", new Object[] {
3499 new LSL_Integer(perm) }, 3839 new LSL_Integer(perm) },
3500 new DetectParams[0])); 3840 new DetectParams[0]));
3501 3841
3502 return; 3842 return;
3843 }
3503 } 3844 }
3504 } 3845 }
3505 3846
@@ -3513,11 +3854,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3513 3854
3514 if (!m_waitingForScriptAnswer) 3855 if (!m_waitingForScriptAnswer)
3515 { 3856 {
3516 lock (m_host.TaskInventory) 3857 m_host.TaskInventory.LockItemsForWrite(true);
3517 { 3858 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3518 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3859 m_host.TaskInventory[invItemID].PermsMask = 0;
3519 m_host.TaskInventory[invItemID].PermsMask = 0; 3860 m_host.TaskInventory.LockItemsForWrite(false);
3520 }
3521 3861
3522 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3862 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3523 m_waitingForScriptAnswer=true; 3863 m_waitingForScriptAnswer=true;
@@ -3552,10 +3892,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3552 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3892 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3553 llReleaseControls(); 3893 llReleaseControls();
3554 3894
3555 lock (m_host.TaskInventory) 3895
3556 { 3896 m_host.TaskInventory.LockItemsForWrite(true);
3557 m_host.TaskInventory[invItemID].PermsMask = answer; 3897 m_host.TaskInventory[invItemID].PermsMask = answer;
3558 } 3898 m_host.TaskInventory.LockItemsForWrite(false);
3899
3559 3900
3560 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3901 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3561 "run_time_permissions", new Object[] { 3902 "run_time_permissions", new Object[] {
@@ -3567,16 +3908,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3567 { 3908 {
3568 m_host.AddScriptLPS(1); 3909 m_host.AddScriptLPS(1);
3569 3910
3570 lock (m_host.TaskInventory) 3911 m_host.TaskInventory.LockItemsForRead(true);
3912
3913 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3571 { 3914 {
3572 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3915 if (item.Type == 10 && item.ItemID == m_itemID)
3573 { 3916 {
3574 if (item.Type == 10 && item.ItemID == m_itemID) 3917 m_host.TaskInventory.LockItemsForRead(false);
3575 { 3918 return item.PermsGranter.ToString();
3576 return item.PermsGranter.ToString();
3577 }
3578 } 3919 }
3579 } 3920 }
3921 m_host.TaskInventory.LockItemsForRead(false);
3580 3922
3581 return UUID.Zero.ToString(); 3923 return UUID.Zero.ToString();
3582 } 3924 }
@@ -3585,19 +3927,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3585 { 3927 {
3586 m_host.AddScriptLPS(1); 3928 m_host.AddScriptLPS(1);
3587 3929
3588 lock (m_host.TaskInventory) 3930 m_host.TaskInventory.LockItemsForRead(true);
3931
3932 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3589 { 3933 {
3590 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3934 if (item.Type == 10 && item.ItemID == m_itemID)
3591 { 3935 {
3592 if (item.Type == 10 && item.ItemID == m_itemID) 3936 int perms = item.PermsMask;
3593 { 3937 if (m_automaticLinkPermission)
3594 int perms = item.PermsMask; 3938 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3595 if (m_automaticLinkPermission) 3939 m_host.TaskInventory.LockItemsForRead(false);
3596 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3940 return perms;
3597 return perms;
3598 }
3599 } 3941 }
3600 } 3942 }
3943 m_host.TaskInventory.LockItemsForRead(false);
3601 3944
3602 return 0; 3945 return 0;
3603 } 3946 }
@@ -3619,9 +3962,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3619 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3962 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3620 { 3963 {
3621 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3964 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3622 3965 if (parts.Count > 0)
3623 foreach (SceneObjectPart part in parts) 3966 {
3624 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3967 try
3968 {
3969 parts[0].ParentGroup.areUpdatesSuspended = true;
3970 foreach (SceneObjectPart part in parts)
3971 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3972 }
3973 finally
3974 {
3975 parts[0].ParentGroup.areUpdatesSuspended = false;
3976 }
3977 }
3625 } 3978 }
3626 3979
3627 public void llCreateLink(string target, int parent) 3980 public void llCreateLink(string target, int parent)
@@ -3634,11 +3987,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3634 return; 3987 return;
3635 3988
3636 TaskInventoryItem item; 3989 TaskInventoryItem item;
3637 lock (m_host.TaskInventory) 3990 m_host.TaskInventory.LockItemsForRead(true);
3638 { 3991 item = m_host.TaskInventory[invItemID];
3639 item = m_host.TaskInventory[invItemID]; 3992 m_host.TaskInventory.LockItemsForRead(false);
3640 } 3993
3641
3642 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3994 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3643 && !m_automaticLinkPermission) 3995 && !m_automaticLinkPermission)
3644 { 3996 {
@@ -3655,11 +4007,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3655 4007
3656 if (targetPart.ParentGroup.AttachmentPoint != 0) 4008 if (targetPart.ParentGroup.AttachmentPoint != 0)
3657 return; // Fail silently if attached 4009 return; // Fail silently if attached
4010
4011 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
4012 return;
4013
3658 SceneObjectGroup parentPrim = null, childPrim = null; 4014 SceneObjectGroup parentPrim = null, childPrim = null;
3659 4015
3660 if (targetPart != null) 4016 if (targetPart != null)
3661 { 4017 {
3662 if (parent != 0) { 4018 if (parent != 0)
4019 {
3663 parentPrim = m_host.ParentGroup; 4020 parentPrim = m_host.ParentGroup;
3664 childPrim = targetPart.ParentGroup; 4021 childPrim = targetPart.ParentGroup;
3665 } 4022 }
@@ -3671,7 +4028,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3671 4028
3672 // Required for linking 4029 // Required for linking
3673 childPrim.RootPart.ClearUpdateSchedule(); 4030 childPrim.RootPart.ClearUpdateSchedule();
3674 parentPrim.LinkToGroup(childPrim); 4031 parentPrim.LinkToGroup(childPrim, true);
3675 } 4032 }
3676 4033
3677 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4034 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3690,16 +4047,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3690 m_host.AddScriptLPS(1); 4047 m_host.AddScriptLPS(1);
3691 UUID invItemID = InventorySelf(); 4048 UUID invItemID = InventorySelf();
3692 4049
3693 lock (m_host.TaskInventory) 4050 m_host.TaskInventory.LockItemsForRead(true);
3694 {
3695 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4051 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3696 && !m_automaticLinkPermission) 4052 && !m_automaticLinkPermission)
3697 { 4053 {
3698 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4054 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4055 m_host.TaskInventory.LockItemsForRead(false);
3699 return; 4056 return;
3700 } 4057 }
3701 } 4058 m_host.TaskInventory.LockItemsForRead(false);
3702 4059
3703 if (linknum < ScriptBaseClass.LINK_THIS) 4060 if (linknum < ScriptBaseClass.LINK_THIS)
3704 return; 4061 return;
3705 4062
@@ -3738,10 +4095,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3738 // Restructuring Multiple Prims. 4095 // Restructuring Multiple Prims.
3739 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4096 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3740 parts.Remove(parentPrim.RootPart); 4097 parts.Remove(parentPrim.RootPart);
3741 foreach (SceneObjectPart part in parts) 4098 if (parts.Count > 0)
3742 { 4099 {
3743 parentPrim.DelinkFromGroup(part.LocalId, true); 4100 try
4101 {
4102 parts[0].ParentGroup.areUpdatesSuspended = true;
4103 foreach (SceneObjectPart part in parts)
4104 {
4105 parentPrim.DelinkFromGroup(part.LocalId, true);
4106 }
4107 }
4108 finally
4109 {
4110 parts[0].ParentGroup.areUpdatesSuspended = false;
4111 }
3744 } 4112 }
4113
3745 parentPrim.HasGroupChanged = true; 4114 parentPrim.HasGroupChanged = true;
3746 parentPrim.ScheduleGroupForFullUpdate(); 4115 parentPrim.ScheduleGroupForFullUpdate();
3747 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4116 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3750,12 +4119,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3750 { 4119 {
3751 SceneObjectPart newRoot = parts[0]; 4120 SceneObjectPart newRoot = parts[0];
3752 parts.Remove(newRoot); 4121 parts.Remove(newRoot);
3753 foreach (SceneObjectPart part in parts) 4122
4123 try
3754 { 4124 {
3755 // Required for linking 4125 parts[0].ParentGroup.areUpdatesSuspended = true;
3756 part.ClearUpdateSchedule(); 4126 foreach (SceneObjectPart part in parts)
3757 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4127 {
4128 part.ClearUpdateSchedule();
4129 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4130 }
3758 } 4131 }
4132 finally
4133 {
4134 parts[0].ParentGroup.areUpdatesSuspended = false;
4135 }
4136
4137
3759 newRoot.ParentGroup.HasGroupChanged = true; 4138 newRoot.ParentGroup.HasGroupChanged = true;
3760 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4139 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3761 } 4140 }
@@ -3775,6 +4154,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3775 public void llBreakAllLinks() 4154 public void llBreakAllLinks()
3776 { 4155 {
3777 m_host.AddScriptLPS(1); 4156 m_host.AddScriptLPS(1);
4157
4158 UUID invItemID = InventorySelf();
4159
4160 TaskInventoryItem item;
4161 m_host.TaskInventory.LockItemsForRead(true);
4162 item = m_host.TaskInventory[invItemID];
4163 m_host.TaskInventory.LockItemsForRead(false);
4164
4165 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4166 && !m_automaticLinkPermission)
4167 {
4168 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4169 return;
4170 }
4171
3778 SceneObjectGroup parentPrim = m_host.ParentGroup; 4172 SceneObjectGroup parentPrim = m_host.ParentGroup;
3779 if (parentPrim.AttachmentPoint != 0) 4173 if (parentPrim.AttachmentPoint != 0)
3780 return; // Fail silently if attached 4174 return; // Fail silently if attached
@@ -3794,25 +4188,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3794 public LSL_String llGetLinkKey(int linknum) 4188 public LSL_String llGetLinkKey(int linknum)
3795 { 4189 {
3796 m_host.AddScriptLPS(1); 4190 m_host.AddScriptLPS(1);
3797 List<UUID> keytable = new List<UUID>();
3798 // parse for sitting avatare-uuids
3799 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3800 {
3801 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3802 keytable.Add(presence.UUID);
3803 });
3804
3805 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3806 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3807 {
3808 return keytable[totalprims - linknum].ToString();
3809 }
3810
3811 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3812 {
3813 return m_host.UUID.ToString();
3814 }
3815
3816 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4191 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3817 if (part != null) 4192 if (part != null)
3818 { 4193 {
@@ -3820,6 +4195,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3820 } 4195 }
3821 else 4196 else
3822 { 4197 {
4198 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4199 {
4200 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4201
4202 if (linknum < 0)
4203 return UUID.Zero.ToString();
4204
4205 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4206 if (avatars.Count > linknum)
4207 {
4208 return avatars[linknum].UUID.ToString();
4209 }
4210 }
3823 return UUID.Zero.ToString(); 4211 return UUID.Zero.ToString();
3824 } 4212 }
3825 } 4213 }
@@ -3919,17 +4307,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3919 m_host.AddScriptLPS(1); 4307 m_host.AddScriptLPS(1);
3920 int count = 0; 4308 int count = 0;
3921 4309
3922 lock (m_host.TaskInventory) 4310 m_host.TaskInventory.LockItemsForRead(true);
4311 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3923 { 4312 {
3924 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4313 if (inv.Value.Type == type || type == -1)
3925 { 4314 {
3926 if (inv.Value.Type == type || type == -1) 4315 count = count + 1;
3927 {
3928 count = count + 1;
3929 }
3930 } 4316 }
3931 } 4317 }
3932 4318
4319 m_host.TaskInventory.LockItemsForRead(false);
3933 return count; 4320 return count;
3934 } 4321 }
3935 4322
@@ -3938,16 +4325,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3938 m_host.AddScriptLPS(1); 4325 m_host.AddScriptLPS(1);
3939 ArrayList keys = new ArrayList(); 4326 ArrayList keys = new ArrayList();
3940 4327
3941 lock (m_host.TaskInventory) 4328 m_host.TaskInventory.LockItemsForRead(true);
4329 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3942 { 4330 {
3943 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4331 if (inv.Value.Type == type || type == -1)
3944 { 4332 {
3945 if (inv.Value.Type == type || type == -1) 4333 keys.Add(inv.Value.Name);
3946 {
3947 keys.Add(inv.Value.Name);
3948 }
3949 } 4334 }
3950 } 4335 }
4336 m_host.TaskInventory.LockItemsForRead(false);
3951 4337
3952 if (keys.Count == 0) 4338 if (keys.Count == 0)
3953 { 4339 {
@@ -3984,25 +4370,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3984 } 4370 }
3985 4371
3986 // move the first object found with this inventory name 4372 // move the first object found with this inventory name
3987 lock (m_host.TaskInventory) 4373 m_host.TaskInventory.LockItemsForRead(true);
4374 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3988 { 4375 {
3989 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4376 if (inv.Value.Name == inventory)
3990 { 4377 {
3991 if (inv.Value.Name == inventory) 4378 found = true;
3992 { 4379 objId = inv.Key;
3993 found = true; 4380 assetType = inv.Value.Type;
3994 objId = inv.Key; 4381 objName = inv.Value.Name;
3995 assetType = inv.Value.Type; 4382 break;
3996 objName = inv.Value.Name;
3997 break;
3998 }
3999 } 4383 }
4000 } 4384 }
4385 m_host.TaskInventory.LockItemsForRead(false);
4001 4386
4002 if (!found) 4387 if (!found)
4003 { 4388 {
4004 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4389 llSay(0, String.Format("Could not find object '{0}'", inventory));
4005 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4390 return;
4391// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4006 } 4392 }
4007 4393
4008 // check if destination is an object 4394 // check if destination is an object
@@ -4028,48 +4414,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4028 return; 4414 return;
4029 } 4415 }
4030 } 4416 }
4417
4031 // destination is an avatar 4418 // destination is an avatar
4032 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4419 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4033 4420
4034 if (agentItem == null) 4421 if (agentItem == null)
4035 return; 4422 return;
4036 4423
4037 byte[] bucket = new byte[17]; 4424 byte[] bucket = new byte[1];
4038 bucket[0] = (byte)assetType; 4425 bucket[0] = (byte)assetType;
4039 byte[] objBytes = agentItem.ID.GetBytes(); 4426 //byte[] objBytes = agentItem.ID.GetBytes();
4040 Array.Copy(objBytes, 0, bucket, 1, 16); 4427 //Array.Copy(objBytes, 0, bucket, 1, 16);
4041 4428
4042 GridInstantMessage msg = new GridInstantMessage(World, 4429 GridInstantMessage msg = new GridInstantMessage(World,
4043 m_host.UUID, m_host.Name+", an object owned by "+ 4430 m_host.OwnerID, m_host.Name, destId,
4044 resolveName(m_host.OwnerID)+",", destId,
4045 (byte)InstantMessageDialog.TaskInventoryOffered, 4431 (byte)InstantMessageDialog.TaskInventoryOffered,
4046 false, objName+"\n"+m_host.Name+" is located at "+ 4432 false, objName+". "+m_host.Name+" is located at "+
4047 World.RegionInfo.RegionName+" "+ 4433 World.RegionInfo.RegionName+" "+
4048 m_host.AbsolutePosition.ToString(), 4434 m_host.AbsolutePosition.ToString(),
4049 agentItem.ID, true, m_host.AbsolutePosition, 4435 agentItem.ID, true, m_host.AbsolutePosition,
4050 bucket); 4436 bucket);
4051 if (m_TransferModule != null) 4437
4052 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4438 ScenePresence sp;
4439
4440 if (World.TryGetScenePresence(destId, out sp))
4441 {
4442 sp.ControllingClient.SendInstantMessage(msg);
4443 }
4444 else
4445 {
4446 if (m_TransferModule != null)
4447 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4448 }
4449
4450 //This delay should only occur when giving inventory to avatars.
4053 ScriptSleep(3000); 4451 ScriptSleep(3000);
4054 } 4452 }
4055 } 4453 }
4056 4454
4455 [DebuggerNonUserCode]
4057 public void llRemoveInventory(string name) 4456 public void llRemoveInventory(string name)
4058 { 4457 {
4059 m_host.AddScriptLPS(1); 4458 m_host.AddScriptLPS(1);
4060 4459
4061 lock (m_host.TaskInventory) 4460 List<TaskInventoryItem> inv;
4461 try
4062 { 4462 {
4063 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4463 m_host.TaskInventory.LockItemsForRead(true);
4464 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4465 }
4466 finally
4467 {
4468 m_host.TaskInventory.LockItemsForRead(false);
4469 }
4470 foreach (TaskInventoryItem item in inv)
4471 {
4472 if (item.Name == name)
4064 { 4473 {
4065 if (item.Name == name) 4474 if (item.ItemID == m_itemID)
4066 { 4475 throw new ScriptDeleteException();
4067 if (item.ItemID == m_itemID) 4476 else
4068 throw new ScriptDeleteException(); 4477 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4069 else 4478 return;
4070 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4071 return;
4072 }
4073 } 4479 }
4074 } 4480 }
4075 } 4481 }
@@ -4104,115 +4510,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4104 { 4510 {
4105 m_host.AddScriptLPS(1); 4511 m_host.AddScriptLPS(1);
4106 4512
4107 UUID uuid = (UUID)id; 4513 UUID uuid;
4108 PresenceInfo pinfo = null; 4514 if (UUID.TryParse(id, out uuid))
4109 UserAccount account;
4110
4111 UserInfoCacheEntry ce;
4112 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4113 { 4515 {
4114 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4516 PresenceInfo pinfo = null;
4115 if (account == null) 4517 UserAccount account;
4518
4519 UserInfoCacheEntry ce;
4520 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4116 { 4521 {
4117 m_userInfoCache[uuid] = null; // Cache negative 4522 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4118 return UUID.Zero.ToString(); 4523 if (account == null)
4119 } 4524 {
4525 m_userInfoCache[uuid] = null; // Cache negative
4526 return UUID.Zero.ToString();
4527 }
4120 4528
4121 4529
4122 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4530 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4123 if (pinfos != null && pinfos.Length > 0) 4531 if (pinfos != null && pinfos.Length > 0)
4124 {
4125 foreach (PresenceInfo p in pinfos)
4126 { 4532 {
4127 if (p.RegionID != UUID.Zero) 4533 foreach (PresenceInfo p in pinfos)
4128 { 4534 {
4129 pinfo = p; 4535 if (p.RegionID != UUID.Zero)
4536 {
4537 pinfo = p;
4538 }
4130 } 4539 }
4131 } 4540 }
4132 }
4133 4541
4134 ce = new UserInfoCacheEntry(); 4542 ce = new UserInfoCacheEntry();
4135 ce.time = Util.EnvironmentTickCount(); 4543 ce.time = Util.EnvironmentTickCount();
4136 ce.account = account; 4544 ce.account = account;
4137 ce.pinfo = pinfo; 4545 ce.pinfo = pinfo;
4138 } 4546 m_userInfoCache[uuid] = ce;
4139 else 4547 }
4140 { 4548 else
4141 if (ce == null) 4549 {
4142 return UUID.Zero.ToString(); 4550 if (ce == null)
4551 return UUID.Zero.ToString();
4143 4552
4144 account = ce.account; 4553 account = ce.account;
4145 pinfo = ce.pinfo; 4554 pinfo = ce.pinfo;
4146 } 4555 }
4147 4556
4148 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4557 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4149 {
4150 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4151 if (pinfos != null && pinfos.Length > 0)
4152 { 4558 {
4153 foreach (PresenceInfo p in pinfos) 4559 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4560 if (pinfos != null && pinfos.Length > 0)
4154 { 4561 {
4155 if (p.RegionID != UUID.Zero) 4562 foreach (PresenceInfo p in pinfos)
4156 { 4563 {
4157 pinfo = p; 4564 if (p.RegionID != UUID.Zero)
4565 {
4566 pinfo = p;
4567 }
4158 } 4568 }
4159 } 4569 }
4160 } 4570 else
4161 else 4571 pinfo = null;
4162 pinfo = null;
4163 4572
4164 ce.time = Util.EnvironmentTickCount(); 4573 ce.time = Util.EnvironmentTickCount();
4165 ce.pinfo = pinfo; 4574 ce.pinfo = pinfo;
4166 } 4575 }
4167 4576
4168 string reply = String.Empty; 4577 string reply = String.Empty;
4169 4578
4170 switch (data) 4579 switch (data)
4171 { 4580 {
4172 case 1: // DATA_ONLINE (0|1) 4581 case 1: // DATA_ONLINE (0|1)
4173 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4582 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4174 reply = "1"; 4583 reply = "1";
4175 else 4584 else
4176 reply = "0"; 4585 reply = "0";
4177 break; 4586 break;
4178 case 2: // DATA_NAME (First Last) 4587 case 2: // DATA_NAME (First Last)
4179 reply = account.FirstName + " " + account.LastName; 4588 reply = account.FirstName + " " + account.LastName;
4180 break; 4589 break;
4181 case 3: // DATA_BORN (YYYY-MM-DD) 4590 case 3: // DATA_BORN (YYYY-MM-DD)
4182 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4591 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4183 born = born.AddSeconds(account.Created); 4592 born = born.AddSeconds(account.Created);
4184 reply = born.ToString("yyyy-MM-dd"); 4593 reply = born.ToString("yyyy-MM-dd");
4185 break; 4594 break;
4186 case 4: // DATA_RATING (0,0,0,0,0,0) 4595 case 4: // DATA_RATING (0,0,0,0,0,0)
4187 reply = "0,0,0,0,0,0"; 4596 reply = "0,0,0,0,0,0";
4188 break; 4597 break;
4189 case 7: // DATA_USERLEVEL (integer) 4598 case 8: // DATA_PAYINFO (0|1|2|3)
4190 reply = account.UserLevel.ToString(); 4599 reply = "0";
4191 break; 4600 break;
4192 case 8: // DATA_PAYINFO (0|1|2|3) 4601 default:
4193 reply = "0"; 4602 return UUID.Zero.ToString(); // Raise no event
4194 break; 4603 }
4195 default:
4196 return UUID.Zero.ToString(); // Raise no event
4197 }
4198 4604
4199 UUID rq = UUID.Random(); 4605 UUID rq = UUID.Random();
4200 4606
4201 UUID tid = AsyncCommands. 4607 UUID tid = AsyncCommands.
4202 DataserverPlugin.RegisterRequest(m_localID, 4608 DataserverPlugin.RegisterRequest(m_localID,
4203 m_itemID, rq.ToString()); 4609 m_itemID, rq.ToString());
4204 4610
4205 AsyncCommands. 4611 AsyncCommands.
4206 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4612 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4207 4613
4208 ScriptSleep(100); 4614 ScriptSleep(100);
4209 return tid.ToString(); 4615 return tid.ToString();
4616 }
4617 else
4618 {
4619 ShoutError("Invalid UUID passed to llRequestAgentData.");
4620 }
4621 return "";
4210 } 4622 }
4211 4623
4212 public LSL_String llRequestInventoryData(string name) 4624 public LSL_String llRequestInventoryData(string name)
4213 { 4625 {
4214 m_host.AddScriptLPS(1); 4626 m_host.AddScriptLPS(1);
4215 4627
4628 //Clone is thread safe
4216 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4629 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4217 4630
4218 foreach (TaskInventoryItem item in itemDictionary.Values) 4631 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4264,19 +4677,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4264 if (UUID.TryParse(agent, out agentId)) 4677 if (UUID.TryParse(agent, out agentId))
4265 { 4678 {
4266 ScenePresence presence = World.GetScenePresence(agentId); 4679 ScenePresence presence = World.GetScenePresence(agentId);
4267 if (presence != null) 4680 if (presence != null && presence.PresenceType != PresenceType.Npc)
4268 { 4681 {
4682 // agent must not be a god
4683 if (presence.UserLevel >= 200) return;
4684
4269 // agent must be over the owners land 4685 // agent must be over the owners land
4270 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4686 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4271 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4687 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4272 { 4688 {
4273 World.TeleportClientHome(agentId, presence.ControllingClient); 4689 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4690 {
4691 // They can't be teleported home for some reason
4692 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4693 if (regionInfo != null)
4694 {
4695 World.RequestTeleportLocation(
4696 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4697 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4698 }
4699 }
4274 } 4700 }
4275 } 4701 }
4276 } 4702 }
4277 ScriptSleep(5000); 4703 ScriptSleep(5000);
4278 } 4704 }
4279 4705
4706 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4707 {
4708 m_host.AddScriptLPS(1);
4709 UUID agentId = new UUID();
4710 if (UUID.TryParse(agent, out agentId))
4711 {
4712 ScenePresence presence = World.GetScenePresence(agentId);
4713 if (presence != null && presence.PresenceType != PresenceType.Npc)
4714 {
4715 // agent must not be a god
4716 if (presence.GodLevel >= 200) return;
4717
4718 if (simname == String.Empty)
4719 simname = World.RegionInfo.RegionName;
4720
4721 // agent must be over the owners land
4722 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4723 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4724 {
4725 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4726 }
4727 else // or must be wearing the prim
4728 {
4729 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4730 {
4731 World.RequestTeleportLocation(presence.ControllingClient, simname, new Vector3((float)pos.x, (float)pos.y, (float)pos.z), new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z), (uint)TeleportFlags.ViaLocation);
4732 }
4733 }
4734 }
4735 }
4736 }
4737
4280 public void llTextBox(string agent, string message, int chatChannel) 4738 public void llTextBox(string agent, string message, int chatChannel)
4281 { 4739 {
4282 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4740 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4288,7 +4746,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4288 UUID av = new UUID(); 4746 UUID av = new UUID();
4289 if (!UUID.TryParse(agent,out av)) 4747 if (!UUID.TryParse(agent,out av))
4290 { 4748 {
4291 LSLError("First parameter to llDialog needs to be a key"); 4749 //LSLError("First parameter to llDialog needs to be a key");
4292 return; 4750 return;
4293 } 4751 }
4294 4752
@@ -4325,17 +4783,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4325 UUID soundId = UUID.Zero; 4783 UUID soundId = UUID.Zero;
4326 if (!UUID.TryParse(impact_sound, out soundId)) 4784 if (!UUID.TryParse(impact_sound, out soundId))
4327 { 4785 {
4328 lock (m_host.TaskInventory) 4786 m_host.TaskInventory.LockItemsForRead(true);
4787 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4329 { 4788 {
4330 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4789 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4331 { 4790 {
4332 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4791 soundId = item.AssetID;
4333 { 4792 break;
4334 soundId = item.AssetID;
4335 break;
4336 }
4337 } 4793 }
4338 } 4794 }
4795 m_host.TaskInventory.LockItemsForRead(false);
4339 } 4796 }
4340 m_host.CollisionSound = soundId; 4797 m_host.CollisionSound = soundId;
4341 m_host.CollisionSoundVolume = (float)impact_volume; 4798 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4375,6 +4832,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4375 UUID partItemID; 4832 UUID partItemID;
4376 foreach (SceneObjectPart part in parts) 4833 foreach (SceneObjectPart part in parts)
4377 { 4834 {
4835 //Clone is thread safe
4378 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4836 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4379 4837
4380 foreach (TaskInventoryItem item in itemsDictionary.Values) 4838 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4508,7 +4966,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4508 { 4966 {
4509 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4967 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4510 float distance_term = distance * distance * distance; // Script Energy 4968 float distance_term = distance * distance * distance; // Script Energy
4511 float pusher_mass = m_host.GetMass(); 4969 // use total object mass and not part
4970 float pusher_mass = m_host.ParentGroup.GetMass();
4512 4971
4513 float PUSH_ATTENUATION_DISTANCE = 17f; 4972 float PUSH_ATTENUATION_DISTANCE = 17f;
4514 float PUSH_ATTENUATION_SCALE = 5f; 4973 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4578,17 +5037,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4578 5037
4579 m_host.AddScriptLPS(1); 5038 m_host.AddScriptLPS(1);
4580 5039
4581 lock (m_host.TaskInventory) 5040 m_host.TaskInventory.LockItemsForRead(true);
5041 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4582 { 5042 {
4583 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 5043 if (item.Type == 10 && item.ItemID == m_itemID)
4584 { 5044 {
4585 if (item.Type == 10 && item.ItemID == m_itemID) 5045 result = item.Name!=null?item.Name:String.Empty;
4586 { 5046 break;
4587 result = item.Name != null ? item.Name : String.Empty;
4588 break;
4589 }
4590 } 5047 }
4591 } 5048 }
5049 m_host.TaskInventory.LockItemsForRead(false);
4592 5050
4593 return result; 5051 return result;
4594 } 5052 }
@@ -4761,23 +5219,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5219 {
4762 m_host.AddScriptLPS(1); 5220 m_host.AddScriptLPS(1);
4763 5221
4764 lock (m_host.TaskInventory) 5222 m_host.TaskInventory.LockItemsForRead(true);
5223 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4765 { 5224 {
4766 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5225 if (inv.Value.Name == name)
4767 { 5226 {
4768 if (inv.Value.Name == name) 5227 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4769 { 5228 {
4770 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5229 m_host.TaskInventory.LockItemsForRead(false);
4771 { 5230 return inv.Value.AssetID.ToString();
4772 return inv.Value.AssetID.ToString(); 5231 }
4773 } 5232 else
4774 else 5233 {
4775 { 5234 m_host.TaskInventory.LockItemsForRead(false);
4776 return UUID.Zero.ToString(); 5235 return UUID.Zero.ToString();
4777 }
4778 } 5236 }
4779 } 5237 }
4780 } 5238 }
5239 m_host.TaskInventory.LockItemsForRead(false);
4781 5240
4782 return UUID.Zero.ToString(); 5241 return UUID.Zero.ToString();
4783 } 5242 }
@@ -4930,14 +5389,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 { 5389 {
4931 m_host.AddScriptLPS(1); 5390 m_host.AddScriptLPS(1);
4932 5391
4933 if (src == null) 5392 return src.Length;
4934 {
4935 return 0;
4936 }
4937 else
4938 {
4939 return src.Length;
4940 }
4941 } 5393 }
4942 5394
4943 public LSL_Integer llList2Integer(LSL_List src, int index) 5395 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4983,7 +5435,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4983 else if (src.Data[index] is LSL_Float) 5435 else if (src.Data[index] is LSL_Float)
4984 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5436 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4985 else if (src.Data[index] is LSL_String) 5437 else if (src.Data[index] is LSL_String)
4986 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5438 {
5439 string str = ((LSL_String) src.Data[index]).m_string;
5440 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5441 if (m != Match.Empty)
5442 {
5443 str = m.Value;
5444 double d = 0.0;
5445 if (!Double.TryParse(str, out d))
5446 return 0.0;
5447
5448 return d;
5449 }
5450 return 0.0;
5451 }
4987 return Convert.ToDouble(src.Data[index]); 5452 return Convert.ToDouble(src.Data[index]);
4988 } 5453 }
4989 catch (FormatException) 5454 catch (FormatException)
@@ -5256,7 +5721,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5256 } 5721 }
5257 } 5722 }
5258 } 5723 }
5259 else { 5724 else
5725 {
5260 object[] array = new object[src.Length]; 5726 object[] array = new object[src.Length];
5261 Array.Copy(src.Data, 0, array, 0, src.Length); 5727 Array.Copy(src.Data, 0, array, 0, src.Length);
5262 result = new LSL_List(array); 5728 result = new LSL_List(array);
@@ -5363,7 +5829,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5363 public LSL_Integer llGetRegionAgentCount() 5829 public LSL_Integer llGetRegionAgentCount()
5364 { 5830 {
5365 m_host.AddScriptLPS(1); 5831 m_host.AddScriptLPS(1);
5366 return new LSL_Integer(World.GetRootAgentCount()); 5832
5833 int count = 0;
5834 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5835 count++;
5836 });
5837
5838 return new LSL_Integer(count);
5367 } 5839 }
5368 5840
5369 public LSL_Vector llGetRegionCorner() 5841 public LSL_Vector llGetRegionCorner()
@@ -5643,6 +6115,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5643 flags |= ScriptBaseClass.AGENT_SITTING; 6115 flags |= ScriptBaseClass.AGENT_SITTING;
5644 } 6116 }
5645 6117
6118 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6119 {
6120 flags |= ScriptBaseClass.AGENT_MALE;
6121 }
6122
5646 return flags; 6123 return flags;
5647 } 6124 }
5648 6125
@@ -5705,10 +6182,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5705 m_host.AddScriptLPS(1); 6182 m_host.AddScriptLPS(1);
5706 6183
5707 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6184 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5708 6185 if (parts.Count > 0)
5709 foreach (var part in parts)
5710 { 6186 {
5711 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6187 try
6188 {
6189 parts[0].ParentGroup.areUpdatesSuspended = true;
6190 foreach (var part in parts)
6191 {
6192 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6193 }
6194 }
6195 finally
6196 {
6197 parts[0].ParentGroup.areUpdatesSuspended = false;
6198 }
5712 } 6199 }
5713 } 6200 }
5714 6201
@@ -5760,13 +6247,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5760 6247
5761 if (m_host.OwnerID == land.LandData.OwnerID) 6248 if (m_host.OwnerID == land.LandData.OwnerID)
5762 { 6249 {
5763 World.TeleportClientHome(agentID, presence.ControllingClient); 6250 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6251 presence.TeleportWithMomentum(pos);
6252 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5764 } 6253 }
5765 } 6254 }
5766 } 6255 }
5767 ScriptSleep(5000); 6256 ScriptSleep(5000);
5768 } 6257 }
5769 6258
6259 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6260 {
6261 return ParseString2List(str, separators, in_spacers, false);
6262 }
6263
5770 public LSL_Integer llOverMyLand(string id) 6264 public LSL_Integer llOverMyLand(string id)
5771 { 6265 {
5772 m_host.AddScriptLPS(1); 6266 m_host.AddScriptLPS(1);
@@ -5831,8 +6325,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5831 UUID agentId = new UUID(); 6325 UUID agentId = new UUID();
5832 if (!UUID.TryParse(agent, out agentId)) 6326 if (!UUID.TryParse(agent, out agentId))
5833 return new LSL_Integer(0); 6327 return new LSL_Integer(0);
6328 if (agentId == m_host.GroupID)
6329 return new LSL_Integer(1);
5834 ScenePresence presence = World.GetScenePresence(agentId); 6330 ScenePresence presence = World.GetScenePresence(agentId);
5835 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6331 if (presence == null || presence.IsChildAgent) // Return false for child agents
5836 return new LSL_Integer(0); 6332 return new LSL_Integer(0);
5837 IClientAPI client = presence.ControllingClient; 6333 IClientAPI client = presence.ControllingClient;
5838 if (m_host.GroupID == client.ActiveGroupId) 6334 if (m_host.GroupID == client.ActiveGroupId)
@@ -5967,7 +6463,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5967 return m_host.ParentGroup.AttachmentPoint; 6463 return m_host.ParentGroup.AttachmentPoint;
5968 } 6464 }
5969 6465
5970 public LSL_Integer llGetFreeMemory() 6466 public virtual LSL_Integer llGetFreeMemory()
5971 { 6467 {
5972 m_host.AddScriptLPS(1); 6468 m_host.AddScriptLPS(1);
5973 // Make scripts designed for LSO happy 6469 // Make scripts designed for LSO happy
@@ -6084,7 +6580,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6084 SetParticleSystem(m_host, rules); 6580 SetParticleSystem(m_host, rules);
6085 } 6581 }
6086 6582
6087 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6583 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6584 {
6088 6585
6089 6586
6090 if (rules.Length == 0) 6587 if (rules.Length == 0)
@@ -6278,14 +6775,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6278 6775
6279 protected UUID GetTaskInventoryItem(string name) 6776 protected UUID GetTaskInventoryItem(string name)
6280 { 6777 {
6281 lock (m_host.TaskInventory) 6778 m_host.TaskInventory.LockItemsForRead(true);
6779 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6282 { 6780 {
6283 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6781 if (inv.Value.Name == name)
6284 { 6782 {
6285 if (inv.Value.Name == name) 6783 m_host.TaskInventory.LockItemsForRead(false);
6286 return inv.Key; 6784 return inv.Key;
6287 } 6785 }
6288 } 6786 }
6787 m_host.TaskInventory.LockItemsForRead(false);
6289 6788
6290 return UUID.Zero; 6789 return UUID.Zero;
6291 } 6790 }
@@ -6323,16 +6822,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6323 if (folderID == UUID.Zero) 6822 if (folderID == UUID.Zero)
6324 return; 6823 return;
6325 6824
6326 byte[] bucket = new byte[17]; 6825 byte[] bucket = new byte[1];
6327 bucket[0] = (byte)AssetType.Folder; 6826 bucket[0] = (byte)AssetType.Folder;
6328 byte[] objBytes = folderID.GetBytes(); 6827 //byte[] objBytes = folderID.GetBytes();
6329 Array.Copy(objBytes, 0, bucket, 1, 16); 6828 //Array.Copy(objBytes, 0, bucket, 1, 16);
6330 6829
6331 GridInstantMessage msg = new GridInstantMessage(World, 6830 GridInstantMessage msg = new GridInstantMessage(World,
6332 m_host.UUID, m_host.Name+", an object owned by "+ 6831 m_host.OwnerID, m_host.Name, destID,
6333 resolveName(m_host.OwnerID)+",", destID, 6832 (byte)InstantMessageDialog.TaskInventoryOffered,
6334 (byte)InstantMessageDialog.InventoryOffered, 6833 false, category+". "+m_host.Name+" is located at "+
6335 false, category+"\n"+m_host.Name+" is located at "+
6336 World.RegionInfo.RegionName+" "+ 6834 World.RegionInfo.RegionName+" "+
6337 m_host.AbsolutePosition.ToString(), 6835 m_host.AbsolutePosition.ToString(),
6338 folderID, true, m_host.AbsolutePosition, 6836 folderID, true, m_host.AbsolutePosition,
@@ -6570,13 +7068,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6570 UUID av = new UUID(); 7068 UUID av = new UUID();
6571 if (!UUID.TryParse(avatar,out av)) 7069 if (!UUID.TryParse(avatar,out av))
6572 { 7070 {
6573 LSLError("First parameter to llDialog needs to be a key"); 7071 //LSLError("First parameter to llDialog needs to be a key");
6574 return; 7072 return;
6575 } 7073 }
6576 if (buttons.Length < 1) 7074 if (buttons.Length < 1)
6577 { 7075 {
6578 LSLError("No less than 1 button can be shown"); 7076 buttons.Add("OK");
6579 return;
6580 } 7077 }
6581 if (buttons.Length > 12) 7078 if (buttons.Length > 12)
6582 { 7079 {
@@ -6593,7 +7090,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6593 } 7090 }
6594 if (buttons.Data[i].ToString().Length > 24) 7091 if (buttons.Data[i].ToString().Length > 24)
6595 { 7092 {
6596 LSLError("button label cannot be longer than 24 characters"); 7093 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6597 return; 7094 return;
6598 } 7095 }
6599 buts[i] = buttons.Data[i].ToString(); 7096 buts[i] = buttons.Data[i].ToString();
@@ -6652,22 +7149,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6652 } 7149 }
6653 7150
6654 // copy the first script found with this inventory name 7151 // copy the first script found with this inventory name
6655 lock (m_host.TaskInventory) 7152 TaskInventoryItem scriptItem = null;
7153 m_host.TaskInventory.LockItemsForRead(true);
7154 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6656 { 7155 {
6657 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7156 if (inv.Value.Name == name)
6658 { 7157 {
6659 if (inv.Value.Name == name) 7158 // make sure the object is a script
7159 if (10 == inv.Value.Type)
6660 { 7160 {
6661 // make sure the object is a script 7161 found = true;
6662 if (10 == inv.Value.Type) 7162 srcId = inv.Key;
6663 { 7163 scriptItem = inv.Value;
6664 found = true; 7164 break;
6665 srcId = inv.Key;
6666 break;
6667 }
6668 } 7165 }
6669 } 7166 }
6670 } 7167 }
7168 m_host.TaskInventory.LockItemsForRead(false);
6671 7169
6672 if (!found) 7170 if (!found)
6673 { 7171 {
@@ -6675,9 +7173,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6675 return; 7173 return;
6676 } 7174 }
6677 7175
6678 // the rest of the permission checks are done in RezScript, so check the pin there as well 7176 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6679 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7177 if (dest != null)
7178 {
7179 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7180 {
7181 // the rest of the permission checks are done in RezScript, so check the pin there as well
7182 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6680 7183
7184 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7185 m_host.Inventory.RemoveInventoryItem(srcId);
7186 }
7187 }
6681 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7188 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6682 ScriptSleep(3000); 7189 ScriptSleep(3000);
6683 } 7190 }
@@ -6740,19 +7247,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6740 public LSL_String llMD5String(string src, int nonce) 7247 public LSL_String llMD5String(string src, int nonce)
6741 { 7248 {
6742 m_host.AddScriptLPS(1); 7249 m_host.AddScriptLPS(1);
6743 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7250 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6744 } 7251 }
6745 7252
6746 public LSL_String llSHA1String(string src) 7253 public LSL_String llSHA1String(string src)
6747 { 7254 {
6748 m_host.AddScriptLPS(1); 7255 m_host.AddScriptLPS(1);
6749 return Util.SHA1Hash(src).ToLower(); 7256 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6750 } 7257 }
6751 7258
6752 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7259 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6753 { 7260 {
6754 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7261 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6755 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7262 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7263 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7264 return shapeBlock;
6756 7265
6757 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7266 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6758 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7267 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6857,6 +7366,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6857 // Prim type box, cylinder and prism. 7366 // Prim type box, cylinder and prism.
6858 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve) 7367 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector taper_b, LSL_Vector topshear, byte profileshape, byte pathcurve)
6859 { 7368 {
7369 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7370 return;
7371
6860 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7372 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6861 ObjectShapePacket.ObjectDataBlock shapeBlock; 7373 ObjectShapePacket.ObjectDataBlock shapeBlock;
6862 7374
@@ -6910,6 +7422,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6910 // Prim type sphere. 7422 // Prim type sphere.
6911 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7423 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6912 { 7424 {
7425 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7426 return;
7427
6913 ObjectShapePacket.ObjectDataBlock shapeBlock; 7428 ObjectShapePacket.ObjectDataBlock shapeBlock;
6914 7429
6915 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7430 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6951,6 +7466,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6951 // Prim type torus, tube and ring. 7466 // Prim type torus, tube and ring.
6952 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve) 7467 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector holesize, LSL_Vector topshear, LSL_Vector profilecut, LSL_Vector taper_a, float revolutions, float radiusoffset, float skew, byte profileshape, byte pathcurve)
6953 { 7468 {
7469 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7470 return;
7471
6954 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7472 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6955 ObjectShapePacket.ObjectDataBlock shapeBlock; 7473 ObjectShapePacket.ObjectDataBlock shapeBlock;
6956 7474
@@ -7086,6 +7604,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7086 // Prim type sculpt. 7604 // Prim type sculpt.
7087 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7605 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7088 { 7606 {
7607 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7608 return;
7609
7089 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7610 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7090 UUID sculptId; 7611 UUID sculptId;
7091 7612
@@ -7110,7 +7631,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7110 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7631 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7111 { 7632 {
7112 // default 7633 // default
7113 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7634 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7114 } 7635 }
7115 7636
7116 part.Shape.SetSculptProperties((byte)type, sculptId); 7637 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7126,32 +7647,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7126 ScriptSleep(200); 7647 ScriptSleep(200);
7127 } 7648 }
7128 7649
7129 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7650 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7130 { 7651 {
7131 m_host.AddScriptLPS(1); 7652 m_host.AddScriptLPS(1);
7132 7653
7133 setLinkPrimParams(linknumber, rules); 7654 setLinkPrimParams(linknumber, rules);
7655 }
7134 7656
7135 ScriptSleep(200); 7657 private void setLinkPrimParams(int linknumber, LSL_List rules)
7658 {
7659 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7660 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7661 if (parts.Count>0)
7662 {
7663 try
7664 {
7665 parts[0].ParentGroup.areUpdatesSuspended = true;
7666 foreach (SceneObjectPart part in parts)
7667 SetPrimParams(part, rules);
7668 }
7669 finally
7670 {
7671 parts[0].ParentGroup.areUpdatesSuspended = false;
7672 }
7673 }
7674 if (avatars.Count > 0)
7675 {
7676 foreach (ScenePresence avatar in avatars)
7677 SetPrimParams(avatar, rules);
7678 }
7136 } 7679 }
7137 7680
7138 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7681 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7682 float material_density, float material_friction,
7683 float material_restitution, float material_gravity_modifier)
7139 { 7684 {
7140 m_host.AddScriptLPS(1); 7685 ExtraPhysicsData physdata = new ExtraPhysicsData();
7686 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7687 physdata.Density = part.Density;
7688 physdata.Friction = part.Friction;
7689 physdata.Bounce = part.Bounciness;
7690 physdata.GravitationModifier = part.GravityModifier;
7141 7691
7142 setLinkPrimParams(linknumber, rules); 7692 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7693 physdata.Density = material_density;
7694 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7695 physdata.Friction = material_friction;
7696 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7697 physdata.Bounce = material_restitution;
7698 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7699 physdata.GravitationModifier = material_gravity_modifier;
7700
7701 part.UpdateExtraPhysics(physdata);
7143 } 7702 }
7144 7703
7145 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7704 public void llSetPhysicsMaterial(int material_bits,
7705 float material_gravity_modifier, float material_restitution,
7706 float material_friction, float material_density)
7146 { 7707 {
7147 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7708 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7709 }
7148 7710
7149 foreach (SceneObjectPart part in parts) 7711 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7150 SetPrimParams(part, rules); 7712 {
7713 llSetLinkPrimitiveParamsFast(linknumber, rules);
7714 ScriptSleep(200);
7715 }
7716
7717 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7718 {
7719 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7720 //We only support PRIM_POSITION and PRIM_ROTATION
7721
7722 int idx = 0;
7723
7724 while (idx < rules.Length)
7725 {
7726 int code = rules.GetLSLIntegerItem(idx++);
7727
7728 int remain = rules.Length - idx;
7729
7730 switch (code)
7731 {
7732 case (int)ScriptBaseClass.PRIM_POSITION:
7733 {
7734 if (remain < 1)
7735 return;
7736 LSL_Vector v;
7737 v = rules.GetVector3Item(idx++);
7738
7739 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7740 if (part == null)
7741 break;
7742
7743 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7744 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7745 if (llGetLinkNumber() > 1)
7746 {
7747 localRot = llGetLocalRot();
7748 localPos = llGetLocalPos();
7749 }
7750
7751 v -= localPos;
7752 v /= localRot;
7753
7754 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7755
7756 v = v + 2 * sitOffset;
7757
7758 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7759 av.SendAvatarDataToAllAgents();
7760
7761 }
7762 break;
7763
7764 case (int)ScriptBaseClass.PRIM_ROTATION:
7765 {
7766 if (remain < 1)
7767 return;
7768
7769 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7770 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7771 if (llGetLinkNumber() > 1)
7772 {
7773 localRot = llGetLocalRot();
7774 localPos = llGetLocalPos();
7775 }
7776
7777 LSL_Rotation r;
7778 r = rules.GetQuaternionItem(idx++);
7779 r = r * llGetRootRotation() / localRot;
7780 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7781 av.SendAvatarDataToAllAgents();
7782 }
7783 break;
7784 }
7785 }
7151 } 7786 }
7152 7787
7153 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7788 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7154 { 7789 {
7790 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7791 return;
7792
7155 int idx = 0; 7793 int idx = 0;
7156 7794
7157 bool positionChanged = false; 7795 bool positionChanged = false;
@@ -7473,6 +8111,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7473 part.ScriptSetPhysicsStatus(physics); 8111 part.ScriptSetPhysicsStatus(physics);
7474 break; 8112 break;
7475 8113
8114 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8115 if (remain < 1)
8116 return;
8117
8118 int shape_type = rules.GetLSLIntegerItem(idx++);
8119
8120 ExtraPhysicsData physdata = new ExtraPhysicsData();
8121 physdata.Density = part.Density;
8122 physdata.Bounce = part.Bounciness;
8123 physdata.GravitationModifier = part.GravityModifier;
8124 physdata.PhysShapeType = (PhysShapeType)shape_type;
8125
8126 part.UpdateExtraPhysics(physdata);
8127
8128 break;
8129
8130 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8131 if (remain < 5)
8132 return;
8133
8134 int material_bits = rules.GetLSLIntegerItem(idx++);
8135 float material_density = (float)rules.GetLSLFloatItem(idx++);
8136 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8137 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8138 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8139
8140 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8141
8142 break;
8143
7476 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8144 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7477 if (remain < 1) 8145 if (remain < 1)
7478 return; 8146 return;
@@ -7546,7 +8214,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7546 if (part.ParentGroup.RootPart == part) 8214 if (part.ParentGroup.RootPart == part)
7547 { 8215 {
7548 SceneObjectGroup parent = part.ParentGroup; 8216 SceneObjectGroup parent = part.ParentGroup;
7549 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8217 Util.FireAndForget(delegate(object x) {
8218 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8219 });
7550 } 8220 }
7551 else 8221 else
7552 { 8222 {
@@ -7557,6 +8227,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7557 } 8227 }
7558 } 8228 }
7559 } 8229 }
8230
8231 if (positionChanged)
8232 {
8233 if (part.ParentGroup.RootPart == part)
8234 {
8235 SceneObjectGroup parent = part.ParentGroup;
8236 Util.FireAndForget(delegate(object x) {
8237 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8238 });
8239 }
8240 else
8241 {
8242 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8243 SceneObjectGroup parent = part.ParentGroup;
8244 parent.HasGroupChanged = true;
8245 parent.ScheduleGroupForTerseUpdate();
8246 }
8247 }
7560 } 8248 }
7561 8249
7562 public LSL_String llStringToBase64(string str) 8250 public LSL_String llStringToBase64(string str)
@@ -7717,13 +8405,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7717 public LSL_Integer llGetNumberOfPrims() 8405 public LSL_Integer llGetNumberOfPrims()
7718 { 8406 {
7719 m_host.AddScriptLPS(1); 8407 m_host.AddScriptLPS(1);
7720 int avatarCount = 0; 8408 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7721 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8409
7722 {
7723 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7724 avatarCount++;
7725 });
7726
7727 return m_host.ParentGroup.PrimCount + avatarCount; 8410 return m_host.ParentGroup.PrimCount + avatarCount;
7728 } 8411 }
7729 8412
@@ -7739,55 +8422,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7739 m_host.AddScriptLPS(1); 8422 m_host.AddScriptLPS(1);
7740 UUID objID = UUID.Zero; 8423 UUID objID = UUID.Zero;
7741 LSL_List result = new LSL_List(); 8424 LSL_List result = new LSL_List();
8425
8426 // If the ID is not valid, return null result
7742 if (!UUID.TryParse(obj, out objID)) 8427 if (!UUID.TryParse(obj, out objID))
7743 { 8428 {
7744 result.Add(new LSL_Vector()); 8429 result.Add(new LSL_Vector());
7745 result.Add(new LSL_Vector()); 8430 result.Add(new LSL_Vector());
7746 return result; 8431 return result;
7747 } 8432 }
8433
8434 // Check if this is an attached prim. If so, replace
8435 // the UUID with the avatar UUID and report it's bounding box
8436 SceneObjectPart part = World.GetSceneObjectPart(objID);
8437 if (part != null && part.ParentGroup.IsAttachment)
8438 objID = part.ParentGroup.AttachedAvatar;
8439
8440 // Find out if this is an avatar ID. If so, return it's box
7748 ScenePresence presence = World.GetScenePresence(objID); 8441 ScenePresence presence = World.GetScenePresence(objID);
7749 if (presence != null) 8442 if (presence != null)
7750 { 8443 {
7751 if (presence.ParentID == 0) // not sat on an object 8444 // As per LSL Wiki, there is no difference between sitting
8445 // and standing avatar since server 1.36
8446 LSL_Vector lower;
8447 LSL_Vector upper;
8448 if (presence.Animator.Animations.DefaultAnimation.AnimID
8449 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7752 { 8450 {
7753 LSL_Vector lower; 8451 // This is for ground sitting avatars
7754 LSL_Vector upper; 8452 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7755 if (presence.Animator.Animations.DefaultAnimation.AnimID 8453 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7756 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8454 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7757 {
7758 // This is for ground sitting avatars
7759 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7760 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7761 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7762 }
7763 else
7764 {
7765 // This is for standing/flying avatars
7766 float height = presence.Appearance.AvatarHeight / 2.0f;
7767 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7768 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7769 }
7770 result.Add(lower);
7771 result.Add(upper);
7772 return result;
7773 } 8455 }
7774 else 8456 else
7775 { 8457 {
7776 // sitting on an object so we need the bounding box of that 8458 // This is for standing/flying avatars
7777 // which should include the avatar so set the UUID to the 8459 float height = presence.Appearance.AvatarHeight / 2.0f;
7778 // UUID of the object the avatar is sat on and allow it to fall through 8460 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7779 // to processing an object 8461 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7780 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7781 objID = p.UUID;
7782 } 8462 }
8463
8464 // Adjust to the documented error offsets (see LSL Wiki)
8465 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8466 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8467
8468 if (lower.x > upper.x)
8469 lower.x = upper.x;
8470 if (lower.y > upper.y)
8471 lower.y = upper.y;
8472 if (lower.z > upper.z)
8473 lower.z = upper.z;
8474
8475 result.Add(lower);
8476 result.Add(upper);
8477 return result;
7783 } 8478 }
7784 SceneObjectPart part = World.GetSceneObjectPart(objID); 8479
8480 part = World.GetSceneObjectPart(objID);
7785 // Currently only works for single prims without a sitting avatar 8481 // Currently only works for single prims without a sitting avatar
7786 if (part != null) 8482 if (part != null)
7787 { 8483 {
7788 Vector3 halfSize = part.Scale / 2.0f; 8484 float minX;
7789 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8485 float maxX;
7790 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8486 float minY;
8487 float maxY;
8488 float minZ;
8489 float maxZ;
8490
8491 // This BBox is in sim coordinates, with the offset being
8492 // a contained point.
8493 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8494 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8495
8496 minX -= offsets[0].X;
8497 maxX -= offsets[0].X;
8498 minY -= offsets[0].Y;
8499 maxY -= offsets[0].Y;
8500 minZ -= offsets[0].Z;
8501 maxZ -= offsets[0].Z;
8502
8503 LSL_Vector lower;
8504 LSL_Vector upper;
8505
8506 // Adjust to the documented error offsets (see LSL Wiki)
8507 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8508 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8509
8510 if (lower.x > upper.x)
8511 lower.x = upper.x;
8512 if (lower.y > upper.y)
8513 lower.y = upper.y;
8514 if (lower.z > upper.z)
8515 lower.z = upper.z;
8516
7791 result.Add(lower); 8517 result.Add(lower);
7792 result.Add(upper); 8518 result.Add(upper);
7793 return result; 8519 return result;
@@ -7867,13 +8593,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7867 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8593 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7868 part.AbsolutePosition.Y, 8594 part.AbsolutePosition.Y,
7869 part.AbsolutePosition.Z); 8595 part.AbsolutePosition.Z);
7870 // For some reason, the part.AbsolutePosition.* values do not change if the
7871 // linkset is rotated; they always reflect the child prim's world position
7872 // as though the linkset is unrotated. This is incompatible behavior with SL's
7873 // implementation, so will break scripts imported from there (not to mention it
7874 // makes it more difficult to determine a child prim's actual inworld position).
7875 if (part.ParentID != 0)
7876 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7877 res.Add(v); 8596 res.Add(v);
7878 break; 8597 break;
7879 8598
@@ -8044,56 +8763,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8044 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8763 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8045 if (remain < 1) 8764 if (remain < 1)
8046 return res; 8765 return res;
8047 8766 face = (int)rules.GetLSLIntegerItem(idx++);
8048 face=(int)rules.GetLSLIntegerItem(idx++);
8049 8767
8050 tex = part.Shape.Textures; 8768 tex = part.Shape.Textures;
8769 int shiny;
8051 if (face == ScriptBaseClass.ALL_SIDES) 8770 if (face == ScriptBaseClass.ALL_SIDES)
8052 { 8771 {
8053 for (face = 0; face < GetNumberOfSides(part); face++) 8772 for (face = 0; face < GetNumberOfSides(part); face++)
8054 { 8773 {
8055 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8774 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8056 // Convert Shininess to PRIM_SHINY_* 8775 if (shinyness == Shininess.High)
8057 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8776 {
8058 // PRIM_BUMP_* 8777 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8059 res.Add(new LSL_Integer((int)texface.Bump)); 8778 }
8779 else if (shinyness == Shininess.Medium)
8780 {
8781 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8782 }
8783 else if (shinyness == Shininess.Low)
8784 {
8785 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8786 }
8787 else
8788 {
8789 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8790 }
8791 res.Add(new LSL_Integer(shiny));
8792 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8060 } 8793 }
8061 } 8794 }
8062 else 8795 else
8063 { 8796 {
8064 if (face >= 0 && face < GetNumberOfSides(part)) 8797 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8798 if (shinyness == Shininess.High)
8065 { 8799 {
8066 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8800 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8067 // Convert Shininess to PRIM_SHINY_* 8801 }
8068 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8802 else if (shinyness == Shininess.Medium)
8069 // PRIM_BUMP_* 8803 {
8070 res.Add(new LSL_Integer((int)texface.Bump)); 8804 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8805 }
8806 else if (shinyness == Shininess.Low)
8807 {
8808 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8809 }
8810 else
8811 {
8812 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8071 } 8813 }
8814 res.Add(new LSL_Integer(shiny));
8815 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8072 } 8816 }
8073 break; 8817 break;
8074 8818
8075 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8819 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8076 if (remain < 1) 8820 if (remain < 1)
8077 return res; 8821 return res;
8078 8822 face = (int)rules.GetLSLIntegerItem(idx++);
8079 face=(int)rules.GetLSLIntegerItem(idx++);
8080 8823
8081 tex = part.Shape.Textures; 8824 tex = part.Shape.Textures;
8825 int fullbright;
8082 if (face == ScriptBaseClass.ALL_SIDES) 8826 if (face == ScriptBaseClass.ALL_SIDES)
8083 { 8827 {
8084 for (face = 0; face < GetNumberOfSides(part); face++) 8828 for (face = 0; face < GetNumberOfSides(part); face++)
8085 { 8829 {
8086 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8830 if (tex.GetFace((uint)face).Fullbright == true)
8087 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8831 {
8832 fullbright = ScriptBaseClass.TRUE;
8833 }
8834 else
8835 {
8836 fullbright = ScriptBaseClass.FALSE;
8837 }
8838 res.Add(new LSL_Integer(fullbright));
8088 } 8839 }
8089 } 8840 }
8090 else 8841 else
8091 { 8842 {
8092 if (face >= 0 && face < GetNumberOfSides(part)) 8843 if (tex.GetFace((uint)face).Fullbright == true)
8093 { 8844 {
8094 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8845 fullbright = ScriptBaseClass.TRUE;
8095 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8096 } 8846 }
8847 else
8848 {
8849 fullbright = ScriptBaseClass.FALSE;
8850 }
8851 res.Add(new LSL_Integer(fullbright));
8097 } 8852 }
8098 break; 8853 break;
8099 8854
@@ -8115,27 +8870,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8115 break; 8870 break;
8116 8871
8117 case (int)ScriptBaseClass.PRIM_TEXGEN: 8872 case (int)ScriptBaseClass.PRIM_TEXGEN:
8873 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8118 if (remain < 1) 8874 if (remain < 1)
8119 return res; 8875 return res;
8120 8876 face = (int)rules.GetLSLIntegerItem(idx++);
8121 face=(int)rules.GetLSLIntegerItem(idx++);
8122 8877
8123 tex = part.Shape.Textures; 8878 tex = part.Shape.Textures;
8124 if (face == ScriptBaseClass.ALL_SIDES) 8879 if (face == ScriptBaseClass.ALL_SIDES)
8125 { 8880 {
8126 for (face = 0; face < GetNumberOfSides(part); face++) 8881 for (face = 0; face < GetNumberOfSides(part); face++)
8127 { 8882 {
8128 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8883 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8129 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8884 {
8130 res.Add(new LSL_Integer((uint)texgen >> 1)); 8885 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8886 }
8887 else
8888 {
8889 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8890 }
8131 } 8891 }
8132 } 8892 }
8133 else 8893 else
8134 { 8894 {
8135 if (face >= 0 && face < GetNumberOfSides(part)) 8895 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8136 { 8896 {
8137 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8897 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8138 res.Add(new LSL_Integer((uint)texgen >> 1)); 8898 }
8899 else
8900 {
8901 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8139 } 8902 }
8140 } 8903 }
8141 break; 8904 break;
@@ -8158,28 +8921,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8158 case (int)ScriptBaseClass.PRIM_GLOW: 8921 case (int)ScriptBaseClass.PRIM_GLOW:
8159 if (remain < 1) 8922 if (remain < 1)
8160 return res; 8923 return res;
8161 8924 face = (int)rules.GetLSLIntegerItem(idx++);
8162 face=(int)rules.GetLSLIntegerItem(idx++);
8163 8925
8164 tex = part.Shape.Textures; 8926 tex = part.Shape.Textures;
8927 float primglow;
8165 if (face == ScriptBaseClass.ALL_SIDES) 8928 if (face == ScriptBaseClass.ALL_SIDES)
8166 { 8929 {
8167 for (face = 0; face < GetNumberOfSides(part); face++) 8930 for (face = 0; face < GetNumberOfSides(part); face++)
8168 { 8931 {
8169 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8932 primglow = tex.GetFace((uint)face).Glow;
8170 res.Add(new LSL_Float(texface.Glow)); 8933 res.Add(new LSL_Float(primglow));
8171 } 8934 }
8172 } 8935 }
8173 else 8936 else
8174 { 8937 {
8175 if (face >= 0 && face < GetNumberOfSides(part)) 8938 primglow = tex.GetFace((uint)face).Glow;
8176 { 8939 res.Add(new LSL_Float(primglow));
8177 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8178 res.Add(new LSL_Float(texface.Glow));
8179 }
8180 } 8940 }
8181 break; 8941 break;
8182
8183 case (int)ScriptBaseClass.PRIM_TEXT: 8942 case (int)ScriptBaseClass.PRIM_TEXT:
8184 Color4 textColor = part.GetTextColor(); 8943 Color4 textColor = part.GetTextColor();
8185 res.Add(new LSL_String(part.Text)); 8944 res.Add(new LSL_String(part.Text));
@@ -8791,8 +9550,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8791 // The function returns an ordered list 9550 // The function returns an ordered list
8792 // representing the tokens found in the supplied 9551 // representing the tokens found in the supplied
8793 // sources string. If two successive tokenizers 9552 // sources string. If two successive tokenizers
8794 // are encountered, then a NULL entry is added 9553 // are encountered, then a null-string entry is
8795 // to the list. 9554 // added to the list.
8796 // 9555 //
8797 // It is a precondition that the source and 9556 // It is a precondition that the source and
8798 // toekizer lisst are non-null. If they are null, 9557 // toekizer lisst are non-null. If they are null,
@@ -8800,7 +9559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8800 // while their lengths are being determined. 9559 // while their lengths are being determined.
8801 // 9560 //
8802 // A small amount of working memoryis required 9561 // A small amount of working memoryis required
8803 // of approximately 8*#tokenizers. 9562 // of approximately 8*#tokenizers + 8*srcstrlen.
8804 // 9563 //
8805 // There are many ways in which this function 9564 // There are many ways in which this function
8806 // can be implemented, this implementation is 9565 // can be implemented, this implementation is
@@ -8816,155 +9575,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8816 // and eliminates redundant tokenizers as soon 9575 // and eliminates redundant tokenizers as soon
8817 // as is possible. 9576 // as is possible.
8818 // 9577 //
8819 // The implementation tries to avoid any copying 9578 // The implementation tries to minimize temporary
8820 // of arrays or other objects. 9579 // garbage generation.
8821 // </remarks> 9580 // </remarks>
8822 9581
8823 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9582 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8824 { 9583 {
8825 int beginning = 0; 9584 return ParseString2List(src, separators, spacers, true);
8826 int srclen = src.Length; 9585 }
8827 int seplen = separators.Length;
8828 object[] separray = separators.Data;
8829 int spclen = spacers.Length;
8830 object[] spcarray = spacers.Data;
8831 int mlen = seplen+spclen;
8832
8833 int[] offset = new int[mlen+1];
8834 bool[] active = new bool[mlen];
8835
8836 int best;
8837 int j;
8838
8839 // Initial capacity reduces resize cost
8840 9586
8841 LSL_List tokens = new LSL_List(); 9587 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9588 {
9589 int srclen = src.Length;
9590 int seplen = separators.Length;
9591 object[] separray = separators.Data;
9592 int spclen = spacers.Length;
9593 object[] spcarray = spacers.Data;
9594 int dellen = 0;
9595 string[] delarray = new string[seplen+spclen];
8842 9596
8843 // All entries are initially valid 9597 int outlen = 0;
9598 string[] outarray = new string[srclen*2+1];
8844 9599
8845 for (int i = 0; i < mlen; i++) 9600 int i, j;
8846 active[i] = true; 9601 string d;
8847 9602
8848 offset[mlen] = srclen; 9603 m_host.AddScriptLPS(1);
8849 9604
8850 while (beginning < srclen) 9605 /*
9606 * Convert separator and spacer lists to C# strings.
9607 * Also filter out null strings so we don't hang.
9608 */
9609 for (i = 0; i < seplen; i ++)
8851 { 9610 {
9611 d = separray[i].ToString();
9612 if (d.Length > 0)
9613 {
9614 delarray[dellen++] = d;
9615 }
9616 }
9617 seplen = dellen;
8852 9618
8853 best = mlen; // as bad as it gets 9619 for (i = 0; i < spclen; i ++)
9620 {
9621 d = spcarray[i].ToString();
9622 if (d.Length > 0)
9623 {
9624 delarray[dellen++] = d;
9625 }
9626 }
8854 9627
8855 // Scan for separators 9628 /*
9629 * Scan through source string from beginning to end.
9630 */
9631 for (i = 0;;)
9632 {
8856 9633
8857 for (j = 0; j < seplen; j++) 9634 /*
9635 * Find earliest delimeter in src starting at i (if any).
9636 */
9637 int earliestDel = -1;
9638 int earliestSrc = srclen;
9639 string earliestStr = null;
9640 for (j = 0; j < dellen; j ++)
8858 { 9641 {
8859 if (separray[j].ToString() == String.Empty) 9642 d = delarray[j];
8860 active[j] = false; 9643 if (d != null)
8861
8862 if (active[j])
8863 { 9644 {
8864 // scan all of the markers 9645 int index = src.IndexOf(d, i);
8865 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9646 if (index < 0)
8866 { 9647 {
8867 // not present at all 9648 delarray[j] = null; // delim nowhere in src, don't check it anymore
8868 active[j] = false;
8869 } 9649 }
8870 else 9650 else if (index < earliestSrc)
8871 { 9651 {
8872 // present and correct 9652 earliestSrc = index; // where delimeter starts in source string
8873 if (offset[j] < offset[best]) 9653 earliestDel = j; // where delimeter is in delarray[]
8874 { 9654 earliestStr = d; // the delimeter string from delarray[]
8875 // closest so far 9655 if (index == i) break; // can't do any better than found at beg of string
8876 best = j;
8877 if (offset[best] == beginning)
8878 break;
8879 }
8880 } 9656 }
8881 } 9657 }
8882 } 9658 }
8883 9659
8884 // Scan for spacers 9660 /*
8885 9661 * Output source string starting at i through start of earliest delimeter.
8886 if (offset[best] != beginning) 9662 */
9663 if (keepNulls || (earliestSrc > i))
8887 { 9664 {
8888 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9665 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8889 {
8890 if (spcarray[j-seplen].ToString() == String.Empty)
8891 active[j] = false;
8892
8893 if (active[j])
8894 {
8895 // scan all of the markers
8896 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8897 {
8898 // not present at all
8899 active[j] = false;
8900 }
8901 else
8902 {
8903 // present and correct
8904 if (offset[j] < offset[best])
8905 {
8906 // closest so far
8907 best = j;
8908 }
8909 }
8910 }
8911 }
8912 } 9666 }
8913 9667
8914 // This is the normal exit from the scanning loop 9668 /*
9669 * If no delimeter found at or after i, we're done scanning.
9670 */
9671 if (earliestDel < 0) break;
8915 9672
8916 if (best == mlen) 9673 /*
9674 * If delimeter was a spacer, output the spacer.
9675 */
9676 if (earliestDel >= seplen)
8917 { 9677 {
8918 // no markers were found on this pass 9678 outarray[outlen++] = earliestStr;
8919 // so we're pretty much done
8920 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8921 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8922 break;
8923 } 9679 }
8924 9680
8925 // Otherwise we just add the newly delimited token 9681 /*
8926 // and recalculate where the search should continue. 9682 * Look at rest of src string following delimeter.
8927 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9683 */
8928 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9684 i = earliestSrc + earliestStr.Length;
8929
8930 if (best < seplen)
8931 {
8932 beginning = offset[best] + (separray[best].ToString()).Length;
8933 }
8934 else
8935 {
8936 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8937 string str = spcarray[best - seplen].ToString();
8938 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8939 tokens.Add(new LSL_String(str));
8940 }
8941 } 9685 }
8942 9686
8943 // This an awkward an not very intuitive boundary case. If the 9687 /*
8944 // last substring is a tokenizer, then there is an implied trailing 9688 * Make up an exact-sized output array suitable for an LSL_List object.
8945 // null list entry. Hopefully the single comparison will not be too 9689 */
8946 // arduous. Alternatively the 'break' could be replced with a return 9690 object[] outlist = new object[outlen];
8947 // but that's shabby programming. 9691 for (i = 0; i < outlen; i ++)
8948
8949 if ((beginning == srclen) && (keepNulls))
8950 { 9692 {
8951 if (srclen != 0) 9693 outlist[i] = new LSL_String(outarray[i]);
8952 tokens.Add(new LSL_String(""));
8953 } 9694 }
8954 9695 return new LSL_List(outlist);
8955 return tokens;
8956 }
8957
8958 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8959 {
8960 m_host.AddScriptLPS(1);
8961 return this.ParseString(src, separators, spacers, false);
8962 }
8963
8964 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8965 {
8966 m_host.AddScriptLPS(1);
8967 return this.ParseString(src, separators, spacers, true);
8968 } 9696 }
8969 9697
8970 public LSL_Integer llGetObjectPermMask(int mask) 9698 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9041,28 +9769,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9041 { 9769 {
9042 m_host.AddScriptLPS(1); 9770 m_host.AddScriptLPS(1);
9043 9771
9044 lock (m_host.TaskInventory) 9772 m_host.TaskInventory.LockItemsForRead(true);
9773 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9045 { 9774 {
9046 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9775 if (inv.Value.Name == item)
9047 { 9776 {
9048 if (inv.Value.Name == item) 9777 m_host.TaskInventory.LockItemsForRead(false);
9778 switch (mask)
9049 { 9779 {
9050 switch (mask) 9780 case 0:
9051 { 9781 return (int)inv.Value.BasePermissions;
9052 case 0: 9782 case 1:
9053 return (int)inv.Value.BasePermissions; 9783 return (int)inv.Value.CurrentPermissions;
9054 case 1: 9784 case 2:
9055 return (int)inv.Value.CurrentPermissions; 9785 return (int)inv.Value.GroupPermissions;
9056 case 2: 9786 case 3:
9057 return (int)inv.Value.GroupPermissions; 9787 return (int)inv.Value.EveryonePermissions;
9058 case 3: 9788 case 4:
9059 return (int)inv.Value.EveryonePermissions; 9789 return (int)inv.Value.NextPermissions;
9060 case 4:
9061 return (int)inv.Value.NextPermissions;
9062 }
9063 } 9790 }
9064 } 9791 }
9065 } 9792 }
9793 m_host.TaskInventory.LockItemsForRead(false);
9066 9794
9067 return -1; 9795 return -1;
9068 } 9796 }
@@ -9109,16 +9837,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9109 { 9837 {
9110 m_host.AddScriptLPS(1); 9838 m_host.AddScriptLPS(1);
9111 9839
9112 lock (m_host.TaskInventory) 9840 m_host.TaskInventory.LockItemsForRead(true);
9841 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9113 { 9842 {
9114 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9843 if (inv.Value.Name == item)
9115 { 9844 {
9116 if (inv.Value.Name == item) 9845 m_host.TaskInventory.LockItemsForRead(false);
9117 { 9846 return inv.Value.CreatorID.ToString();
9118 return inv.Value.CreatorID.ToString();
9119 }
9120 } 9847 }
9121 } 9848 }
9849 m_host.TaskInventory.LockItemsForRead(false);
9122 9850
9123 llSay(0, "No item name '" + item + "'"); 9851 llSay(0, "No item name '" + item + "'");
9124 9852
@@ -9244,9 +9972,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9244 { 9972 {
9245 try 9973 try
9246 { 9974 {
9975 /*
9247 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9976 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9248 if (obj != null) 9977 if (obj != null)
9249 return (double)obj.GetMass(); 9978 return (double)obj.GetMass();
9979 */
9980 // return total object mass
9981 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
9982 if (obj != null)
9983 return obj.GetMass();
9984
9250 // the object is null so the key is for an avatar 9985 // the object is null so the key is for an avatar
9251 ScenePresence avatar = World.GetScenePresence(key); 9986 ScenePresence avatar = World.GetScenePresence(key);
9252 if (avatar != null) 9987 if (avatar != null)
@@ -9266,7 +10001,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9266 } 10001 }
9267 10002
9268 /// <summary> 10003 /// <summary>
9269 /// illListReplaceList removes the sub-list defined by the inclusive indices 10004 /// llListReplaceList removes the sub-list defined by the inclusive indices
9270 /// start and end and inserts the src list in its place. The inclusive 10005 /// start and end and inserts the src list in its place. The inclusive
9271 /// nature of the indices means that at least one element must be deleted 10006 /// nature of the indices means that at least one element must be deleted
9272 /// if the indices are within the bounds of the existing list. I.e. 2,2 10007 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9323,16 +10058,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9323 // based upon end. Note that if end exceeds the upper 10058 // based upon end. Note that if end exceeds the upper
9324 // bound in this case, the entire destination list 10059 // bound in this case, the entire destination list
9325 // is removed. 10060 // is removed.
9326 else 10061 else if (start == 0)
9327 { 10062 {
9328 if (end + 1 < dest.Length) 10063 if (end + 1 < dest.Length)
9329 {
9330 return src + dest.GetSublist(end + 1, -1); 10064 return src + dest.GetSublist(end + 1, -1);
9331 }
9332 else 10065 else
9333 {
9334 return src; 10066 return src;
9335 } 10067 }
10068 else // Start < 0
10069 {
10070 if (end + 1 < dest.Length)
10071 return dest.GetSublist(end + 1, -1);
10072 else
10073 return new LSL_List();
9336 } 10074 }
9337 } 10075 }
9338 // Finally, if start > end, we strip away a prefix and 10076 // Finally, if start > end, we strip away a prefix and
@@ -9383,17 +10121,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9383 int width = 0; 10121 int width = 0;
9384 int height = 0; 10122 int height = 0;
9385 10123
9386 ParcelMediaCommandEnum? commandToSend = null; 10124 uint commandToSend = 0;
9387 float time = 0.0f; // default is from start 10125 float time = 0.0f; // default is from start
9388 10126
9389 ScenePresence presence = null; 10127 ScenePresence presence = null;
9390 10128
9391 for (int i = 0; i < commandList.Data.Length; i++) 10129 for (int i = 0; i < commandList.Data.Length; i++)
9392 { 10130 {
9393 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10131 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9394 switch (command) 10132 switch (command)
9395 { 10133 {
9396 case ParcelMediaCommandEnum.Agent: 10134 case (uint)ParcelMediaCommandEnum.Agent:
9397 // we send only to one agent 10135 // we send only to one agent
9398 if ((i + 1) < commandList.Length) 10136 if ((i + 1) < commandList.Length)
9399 { 10137 {
@@ -9410,25 +10148,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9410 } 10148 }
9411 break; 10149 break;
9412 10150
9413 case ParcelMediaCommandEnum.Loop: 10151 case (uint)ParcelMediaCommandEnum.Loop:
9414 loop = 1; 10152 loop = 1;
9415 commandToSend = command; 10153 commandToSend = command;
9416 update = true; //need to send the media update packet to set looping 10154 update = true; //need to send the media update packet to set looping
9417 break; 10155 break;
9418 10156
9419 case ParcelMediaCommandEnum.Play: 10157 case (uint)ParcelMediaCommandEnum.Play:
9420 loop = 0; 10158 loop = 0;
9421 commandToSend = command; 10159 commandToSend = command;
9422 update = true; //need to send the media update packet to make sure it doesn't loop 10160 update = true; //need to send the media update packet to make sure it doesn't loop
9423 break; 10161 break;
9424 10162
9425 case ParcelMediaCommandEnum.Pause: 10163 case (uint)ParcelMediaCommandEnum.Pause:
9426 case ParcelMediaCommandEnum.Stop: 10164 case (uint)ParcelMediaCommandEnum.Stop:
9427 case ParcelMediaCommandEnum.Unload: 10165 case (uint)ParcelMediaCommandEnum.Unload:
9428 commandToSend = command; 10166 commandToSend = command;
9429 break; 10167 break;
9430 10168
9431 case ParcelMediaCommandEnum.Url: 10169 case (uint)ParcelMediaCommandEnum.Url:
9432 if ((i + 1) < commandList.Length) 10170 if ((i + 1) < commandList.Length)
9433 { 10171 {
9434 if (commandList.Data[i + 1] is LSL_String) 10172 if (commandList.Data[i + 1] is LSL_String)
@@ -9441,7 +10179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 } 10179 }
9442 break; 10180 break;
9443 10181
9444 case ParcelMediaCommandEnum.Texture: 10182 case (uint)ParcelMediaCommandEnum.Texture:
9445 if ((i + 1) < commandList.Length) 10183 if ((i + 1) < commandList.Length)
9446 { 10184 {
9447 if (commandList.Data[i + 1] is LSL_String) 10185 if (commandList.Data[i + 1] is LSL_String)
@@ -9454,7 +10192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9454 } 10192 }
9455 break; 10193 break;
9456 10194
9457 case ParcelMediaCommandEnum.Time: 10195 case (uint)ParcelMediaCommandEnum.Time:
9458 if ((i + 1) < commandList.Length) 10196 if ((i + 1) < commandList.Length)
9459 { 10197 {
9460 if (commandList.Data[i + 1] is LSL_Float) 10198 if (commandList.Data[i + 1] is LSL_Float)
@@ -9466,7 +10204,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9466 } 10204 }
9467 break; 10205 break;
9468 10206
9469 case ParcelMediaCommandEnum.AutoAlign: 10207 case (uint)ParcelMediaCommandEnum.AutoAlign:
9470 if ((i + 1) < commandList.Length) 10208 if ((i + 1) < commandList.Length)
9471 { 10209 {
9472 if (commandList.Data[i + 1] is LSL_Integer) 10210 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9480,7 +10218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9480 } 10218 }
9481 break; 10219 break;
9482 10220
9483 case ParcelMediaCommandEnum.Type: 10221 case (uint)ParcelMediaCommandEnum.Type:
9484 if ((i + 1) < commandList.Length) 10222 if ((i + 1) < commandList.Length)
9485 { 10223 {
9486 if (commandList.Data[i + 1] is LSL_String) 10224 if (commandList.Data[i + 1] is LSL_String)
@@ -9493,7 +10231,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9493 } 10231 }
9494 break; 10232 break;
9495 10233
9496 case ParcelMediaCommandEnum.Desc: 10234 case (uint)ParcelMediaCommandEnum.Desc:
9497 if ((i + 1) < commandList.Length) 10235 if ((i + 1) < commandList.Length)
9498 { 10236 {
9499 if (commandList.Data[i + 1] is LSL_String) 10237 if (commandList.Data[i + 1] is LSL_String)
@@ -9506,7 +10244,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9506 } 10244 }
9507 break; 10245 break;
9508 10246
9509 case ParcelMediaCommandEnum.Size: 10247 case (uint)ParcelMediaCommandEnum.Size:
9510 if ((i + 2) < commandList.Length) 10248 if ((i + 2) < commandList.Length)
9511 { 10249 {
9512 if (commandList.Data[i + 1] is LSL_Integer) 10250 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9576,7 +10314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9576 } 10314 }
9577 } 10315 }
9578 10316
9579 if (commandToSend != null) 10317 if (commandToSend != 0)
9580 { 10318 {
9581 // the commandList contained a start/stop/... command, too 10319 // the commandList contained a start/stop/... command, too
9582 if (presence == null) 10320 if (presence == null)
@@ -9613,7 +10351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9613 10351
9614 if (aList.Data[i] != null) 10352 if (aList.Data[i] != null)
9615 { 10353 {
9616 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10354 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9617 { 10355 {
9618 case ParcelMediaCommandEnum.Url: 10356 case ParcelMediaCommandEnum.Url:
9619 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10357 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9656,16 +10394,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9656 { 10394 {
9657 m_host.AddScriptLPS(1); 10395 m_host.AddScriptLPS(1);
9658 10396
9659 lock (m_host.TaskInventory) 10397 m_host.TaskInventory.LockItemsForRead(true);
10398 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9660 { 10399 {
9661 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10400 if (inv.Value.Name == name)
9662 { 10401 {
9663 if (inv.Value.Name == name) 10402 m_host.TaskInventory.LockItemsForRead(false);
9664 { 10403 return inv.Value.Type;
9665 return inv.Value.Type;
9666 }
9667 } 10404 }
9668 } 10405 }
10406 m_host.TaskInventory.LockItemsForRead(false);
9669 10407
9670 return -1; 10408 return -1;
9671 } 10409 }
@@ -9676,15 +10414,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9676 10414
9677 if (quick_pay_buttons.Data.Length < 4) 10415 if (quick_pay_buttons.Data.Length < 4)
9678 { 10416 {
9679 LSLError("List must have at least 4 elements"); 10417 int x;
9680 return; 10418 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10419 {
10420 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10421 }
9681 } 10422 }
9682 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10423 int[] nPrice = new int[5];
9683 10424 nPrice[0] = price;
9684 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10425 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9685 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10426 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9686 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10427 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9687 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10428 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10429 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9688 m_host.ParentGroup.HasGroupChanged = true; 10430 m_host.ParentGroup.HasGroupChanged = true;
9689 } 10431 }
9690 10432
@@ -9696,17 +10438,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9696 if (invItemID == UUID.Zero) 10438 if (invItemID == UUID.Zero)
9697 return new LSL_Vector(); 10439 return new LSL_Vector();
9698 10440
9699 lock (m_host.TaskInventory) 10441 m_host.TaskInventory.LockItemsForRead(true);
10442 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9700 { 10443 {
9701 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10444 m_host.TaskInventory.LockItemsForRead(false);
9702 return new LSL_Vector(); 10445 return new LSL_Vector();
10446 }
9703 10447
9704 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10448 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9705 { 10449 {
9706 ShoutError("No permissions to track the camera"); 10450 ShoutError("No permissions to track the camera");
9707 return new LSL_Vector(); 10451 m_host.TaskInventory.LockItemsForRead(false);
9708 } 10452 return new LSL_Vector();
9709 } 10453 }
10454 m_host.TaskInventory.LockItemsForRead(false);
9710 10455
9711 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10456 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9712 if (presence != null) 10457 if (presence != null)
@@ -9724,17 +10469,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9724 if (invItemID == UUID.Zero) 10469 if (invItemID == UUID.Zero)
9725 return new LSL_Rotation(); 10470 return new LSL_Rotation();
9726 10471
9727 lock (m_host.TaskInventory) 10472 m_host.TaskInventory.LockItemsForRead(true);
10473 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9728 { 10474 {
9729 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10475 m_host.TaskInventory.LockItemsForRead(false);
9730 return new LSL_Rotation(); 10476 return new LSL_Rotation();
9731
9732 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9733 {
9734 ShoutError("No permissions to track the camera");
9735 return new LSL_Rotation();
9736 }
9737 } 10477 }
10478 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10479 {
10480 ShoutError("No permissions to track the camera");
10481 m_host.TaskInventory.LockItemsForRead(false);
10482 return new LSL_Rotation();
10483 }
10484 m_host.TaskInventory.LockItemsForRead(false);
9738 10485
9739 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10486 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9740 if (presence != null) 10487 if (presence != null)
@@ -9796,8 +10543,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9796 { 10543 {
9797 m_host.AddScriptLPS(1); 10544 m_host.AddScriptLPS(1);
9798 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10545 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9799 if (detectedParams == null) return; // only works on the first detected avatar 10546 if (detectedParams == null)
9800 10547 {
10548 if (m_host.ParentGroup.IsAttachment == true)
10549 {
10550 detectedParams = new DetectParams();
10551 detectedParams.Key = m_host.OwnerID;
10552 }
10553 else
10554 {
10555 return;
10556 }
10557 }
10558
9801 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10559 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9802 if (avatar != null) 10560 if (avatar != null)
9803 { 10561 {
@@ -9805,6 +10563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9805 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10563 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9806 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10564 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9807 } 10565 }
10566
9808 ScriptSleep(1000); 10567 ScriptSleep(1000);
9809 } 10568 }
9810 10569
@@ -9916,14 +10675,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9916 if (objectID == UUID.Zero) return; 10675 if (objectID == UUID.Zero) return;
9917 10676
9918 UUID agentID; 10677 UUID agentID;
9919 lock (m_host.TaskInventory) 10678 m_host.TaskInventory.LockItemsForRead(true);
9920 { 10679 // we need the permission first, to know which avatar we want to set the camera for
9921 // we need the permission first, to know which avatar we want to set the camera for 10680 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9922 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9923 10681
9924 if (agentID == UUID.Zero) return; 10682 if (agentID == UUID.Zero)
9925 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10683 {
10684 m_host.TaskInventory.LockItemsForRead(false);
10685 return;
9926 } 10686 }
10687 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10688 {
10689 m_host.TaskInventory.LockItemsForRead(false);
10690 return;
10691 }
10692 m_host.TaskInventory.LockItemsForRead(false);
9927 10693
9928 ScenePresence presence = World.GetScenePresence(agentID); 10694 ScenePresence presence = World.GetScenePresence(agentID);
9929 10695
@@ -9932,12 +10698,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9932 10698
9933 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10699 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9934 object[] data = rules.Data; 10700 object[] data = rules.Data;
9935 for (int i = 0; i < data.Length; ++i) { 10701 for (int i = 0; i < data.Length; ++i)
10702 {
9936 int type = Convert.ToInt32(data[i++].ToString()); 10703 int type = Convert.ToInt32(data[i++].ToString());
9937 if (i >= data.Length) break; // odd number of entries => ignore the last 10704 if (i >= data.Length) break; // odd number of entries => ignore the last
9938 10705
9939 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10706 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9940 switch (type) { 10707 switch (type)
10708 {
9941 case ScriptBaseClass.CAMERA_FOCUS: 10709 case ScriptBaseClass.CAMERA_FOCUS:
9942 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10710 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9943 case ScriptBaseClass.CAMERA_POSITION: 10711 case ScriptBaseClass.CAMERA_POSITION:
@@ -9973,12 +10741,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9973 10741
9974 // we need the permission first, to know which avatar we want to clear the camera for 10742 // we need the permission first, to know which avatar we want to clear the camera for
9975 UUID agentID; 10743 UUID agentID;
9976 lock (m_host.TaskInventory) 10744 m_host.TaskInventory.LockItemsForRead(true);
10745 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10746 if (agentID == UUID.Zero)
9977 { 10747 {
9978 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10748 m_host.TaskInventory.LockItemsForRead(false);
9979 if (agentID == UUID.Zero) return; 10749 return;
9980 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10750 }
10751 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10752 {
10753 m_host.TaskInventory.LockItemsForRead(false);
10754 return;
9981 } 10755 }
10756 m_host.TaskInventory.LockItemsForRead(false);
9982 10757
9983 ScenePresence presence = World.GetScenePresence(agentID); 10758 ScenePresence presence = World.GetScenePresence(agentID);
9984 10759
@@ -10045,19 +10820,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10045 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10820 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10046 { 10821 {
10047 m_host.AddScriptLPS(1); 10822 m_host.AddScriptLPS(1);
10048 string ret = String.Empty; 10823
10049 string src1 = llBase64ToString(str1); 10824 if (str1 == String.Empty)
10050 string src2 = llBase64ToString(str2); 10825 return String.Empty;
10051 int c = 0; 10826 if (str2 == String.Empty)
10052 for (int i = 0; i < src1.Length; i++) 10827 return str1;
10828
10829 int len = str2.Length;
10830 if ((len % 4) != 0) // LL is EVIL!!!!
10831 {
10832 while (str2.EndsWith("="))
10833 str2 = str2.Substring(0, str2.Length - 1);
10834
10835 len = str2.Length;
10836 int mod = len % 4;
10837
10838 if (mod == 1)
10839 str2 = str2.Substring(0, str2.Length - 1);
10840 else if (mod == 2)
10841 str2 += "==";
10842 else if (mod == 3)
10843 str2 += "=";
10844 }
10845
10846 byte[] data1;
10847 byte[] data2;
10848 try
10053 { 10849 {
10054 ret += (char) (src1[i] ^ src2[c]); 10850 data1 = Convert.FromBase64String(str1);
10851 data2 = Convert.FromBase64String(str2);
10852 }
10853 catch (Exception)
10854 {
10855 return new LSL_String(String.Empty);
10856 }
10857
10858 byte[] d2 = new Byte[data1.Length];
10859 int pos = 0;
10860
10861 if (data1.Length <= data2.Length)
10862 {
10863 Array.Copy(data2, 0, d2, 0, data1.Length);
10864 }
10865 else
10866 {
10867 while (pos < data1.Length)
10868 {
10869 len = data1.Length - pos;
10870 if (len > data2.Length)
10871 len = data2.Length;
10055 10872
10056 c++; 10873 Array.Copy(data2, 0, d2, pos, len);
10057 if (c >= src2.Length) 10874 pos += len;
10058 c = 0; 10875 }
10059 } 10876 }
10060 return llStringToBase64(ret); 10877
10878 for (pos = 0 ; pos < data1.Length ; pos++ )
10879 data1[pos] ^= d2[pos];
10880
10881 return Convert.ToBase64String(data1);
10061 } 10882 }
10062 10883
10063 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10884 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10114,12 +10935,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10114 Regex r = new Regex(authregex); 10935 Regex r = new Regex(authregex);
10115 int[] gnums = r.GetGroupNumbers(); 10936 int[] gnums = r.GetGroupNumbers();
10116 Match m = r.Match(url); 10937 Match m = r.Match(url);
10117 if (m.Success) { 10938 if (m.Success)
10118 for (int i = 1; i < gnums.Length; i++) { 10939 {
10940 for (int i = 1; i < gnums.Length; i++)
10941 {
10119 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10942 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10120 //CaptureCollection cc = g.Captures; 10943 //CaptureCollection cc = g.Captures;
10121 } 10944 }
10122 if (m.Groups.Count == 5) { 10945 if (m.Groups.Count == 5)
10946 {
10123 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10947 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10124 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10948 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10125 } 10949 }
@@ -10482,15 +11306,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10482 11306
10483 internal UUID ScriptByName(string name) 11307 internal UUID ScriptByName(string name)
10484 { 11308 {
10485 lock (m_host.TaskInventory) 11309 m_host.TaskInventory.LockItemsForRead(true);
11310
11311 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10486 { 11312 {
10487 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11313 if (item.Type == 10 && item.Name == name)
10488 { 11314 {
10489 if (item.Type == 10 && item.Name == name) 11315 m_host.TaskInventory.LockItemsForRead(false);
10490 return item.ItemID; 11316 return item.ItemID;
10491 } 11317 }
10492 } 11318 }
10493 11319
11320 m_host.TaskInventory.LockItemsForRead(false);
11321
10494 return UUID.Zero; 11322 return UUID.Zero;
10495 } 11323 }
10496 11324
@@ -10531,6 +11359,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10531 { 11359 {
10532 m_host.AddScriptLPS(1); 11360 m_host.AddScriptLPS(1);
10533 11361
11362 //Clone is thread safe
10534 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11363 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10535 11364
10536 UUID assetID = UUID.Zero; 11365 UUID assetID = UUID.Zero;
@@ -10593,6 +11422,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10593 { 11422 {
10594 m_host.AddScriptLPS(1); 11423 m_host.AddScriptLPS(1);
10595 11424
11425 //Clone is thread safe
10596 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11426 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10597 11427
10598 UUID assetID = UUID.Zero; 11428 UUID assetID = UUID.Zero;
@@ -10673,15 +11503,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10673 return GetLinkPrimitiveParams(obj, rules); 11503 return GetLinkPrimitiveParams(obj, rules);
10674 } 11504 }
10675 11505
10676 public void print(string str) 11506 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10677 { 11507 {
10678 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11508 List<SceneObjectPart> parts = GetLinkParts(link);
10679 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11509 if (parts.Count < 1)
10680 if (ossl != null) 11510 return 0;
10681 { 11511
10682 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11512 return GetNumberOfSides(parts[0]);
10683 m_log.Info("LSL print():" + str);
10684 }
10685 } 11513 }
10686 11514
10687 private string Name2Username(string name) 11515 private string Name2Username(string name)
@@ -10727,155 +11555,482 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10727 return rq.ToString(); 11555 return rq.ToString();
10728 } 11556 }
10729 11557
11558 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11559 {
11560 m_SayShoutCount = 0;
11561 }
11562
11563 private struct Tri
11564 {
11565 public Vector3 p1;
11566 public Vector3 p2;
11567 public Vector3 p3;
11568 }
11569
11570 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11571 {
11572 float height = avatar.Appearance.AvatarHeight;
11573 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11574 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11575
11576 if (point.X > b1.X && point.X < b2.X &&
11577 point.Y > b1.Y && point.Y < b2.Y &&
11578 point.Z > b1.Z && point.Z < b2.Z)
11579 return true;
11580 return false;
11581 }
11582
11583 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11584 {
11585 List<ContactResult> contacts = new List<ContactResult>();
11586
11587 Vector3 ab = rayEnd - rayStart;
11588
11589 World.ForEachScenePresence(delegate(ScenePresence sp)
11590 {
11591 Vector3 ac = sp.AbsolutePosition - rayStart;
11592 Vector3 bc = sp.AbsolutePosition - rayEnd;
11593
11594 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11595
11596 if (d > 1.5)
11597 return;
11598
11599 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11600
11601 if (d2 > 0)
11602 return;
11603
11604 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11605 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11606
11607 if (!InBoundingBox(sp, p))
11608 return;
11609
11610 ContactResult result = new ContactResult ();
11611 result.ConsumerID = sp.LocalId;
11612 result.Depth = Vector3.Distance(rayStart, p);
11613 result.Normal = Vector3.Zero;
11614 result.Pos = p;
11615
11616 contacts.Add(result);
11617 });
11618
11619 return contacts.ToArray();
11620 }
11621
11622 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11623 {
11624 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11625 List<ContactResult> contacts = new List<ContactResult>();
11626
11627 Vector3 ab = rayEnd - rayStart;
11628
11629 World.ForEachSOG(delegate(SceneObjectGroup group)
11630 {
11631 if (m_host.ParentGroup == group)
11632 return;
11633
11634 if (group.IsAttachment)
11635 return;
11636
11637 if (group.RootPart.PhysActor == null)
11638 {
11639 if (!includePhantom)
11640 return;
11641 }
11642 else
11643 {
11644 if (group.RootPart.PhysActor.IsPhysical)
11645 {
11646 if (!includePhysical)
11647 return;
11648 }
11649 else
11650 {
11651 if (!includeNonPhysical)
11652 return;
11653 }
11654 }
11655
11656 // Find the radius ouside of which we don't even need to hit test
11657 float minX;
11658 float maxX;
11659 float minY;
11660 float maxY;
11661 float minZ;
11662 float maxZ;
11663
11664 float radius = 0.0f;
11665
11666 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11667
11668 if (Math.Abs(minX) > radius)
11669 radius = Math.Abs(minX);
11670 if (Math.Abs(minY) > radius)
11671 radius = Math.Abs(minY);
11672 if (Math.Abs(minZ) > radius)
11673 radius = Math.Abs(minZ);
11674 if (Math.Abs(maxX) > radius)
11675 radius = Math.Abs(maxX);
11676 if (Math.Abs(maxY) > radius)
11677 radius = Math.Abs(maxY);
11678 if (Math.Abs(maxZ) > radius)
11679 radius = Math.Abs(maxZ);
11680
11681 Vector3 ac = group.AbsolutePosition - rayStart;
11682 Vector3 bc = group.AbsolutePosition - rayEnd;
11683
11684 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11685
11686 // Too far off ray, don't bother
11687 if (d > radius)
11688 return;
11689
11690 // Behind ray, drop
11691 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11692 if (d2 > 0)
11693 return;
11694
11695 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11696 // Miss.
11697 if (!intersection.HitTF)
11698 return;
11699
11700 ContactResult result = new ContactResult ();
11701 result.ConsumerID = group.LocalId;
11702 result.Depth = intersection.distance;
11703 result.Normal = intersection.normal;
11704 result.Pos = intersection.ipoint;
11705
11706 contacts.Add(result);
11707 });
11708
11709 return contacts.ToArray();
11710 }
11711
11712 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11713 {
11714 double[,] heightfield = World.Heightmap.GetDoubles();
11715 List<ContactResult> contacts = new List<ContactResult>();
11716
11717 double min = 2048.0;
11718 double max = 0.0;
11719
11720 // Find the min and max of the heightfield
11721 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11722 {
11723 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11724 {
11725 if (heightfield[x, y] > max)
11726 max = heightfield[x, y];
11727 if (heightfield[x, y] < min)
11728 min = heightfield[x, y];
11729 }
11730 }
11731
11732
11733 // A ray extends past rayEnd, but doesn't go back before
11734 // rayStart. If the start is above the highest point of the ground
11735 // and the ray goes up, we can't hit the ground. Ever.
11736 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11737 return null;
11738
11739 // Same for going down
11740 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11741 return null;
11742
11743 List<Tri> trilist = new List<Tri>();
11744
11745 // Create our triangle list
11746 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11747 {
11748 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11749 {
11750 Tri t1 = new Tri();
11751 Tri t2 = new Tri();
11752
11753 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11754 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11755 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11756 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11757
11758 t1.p1 = p1;
11759 t1.p2 = p2;
11760 t1.p3 = p3;
11761
11762 t2.p1 = p3;
11763 t2.p2 = p4;
11764 t2.p3 = p1;
11765
11766 trilist.Add(t1);
11767 trilist.Add(t2);
11768 }
11769 }
11770
11771 // Ray direction
11772 Vector3 rayDirection = rayEnd - rayStart;
11773
11774 foreach (Tri t in trilist)
11775 {
11776 // Compute triangle plane normal and edges
11777 Vector3 u = t.p2 - t.p1;
11778 Vector3 v = t.p3 - t.p1;
11779 Vector3 n = Vector3.Cross(u, v);
11780
11781 if (n == Vector3.Zero)
11782 continue;
11783
11784 Vector3 w0 = rayStart - t.p1;
11785 double a = -Vector3.Dot(n, w0);
11786 double b = Vector3.Dot(n, rayDirection);
11787
11788 // Not intersecting the plane, or in plane (same thing)
11789 // Ignoring this MAY cause the ground to not be detected
11790 // sometimes
11791 if (Math.Abs(b) < 0.000001)
11792 continue;
11793
11794 double r = a / b;
11795
11796 // ray points away from plane
11797 if (r < 0.0)
11798 continue;
11799
11800 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11801
11802 float uu = Vector3.Dot(u, u);
11803 float uv = Vector3.Dot(u, v);
11804 float vv = Vector3.Dot(v, v);
11805 Vector3 w = ip - t.p1;
11806 float wu = Vector3.Dot(w, u);
11807 float wv = Vector3.Dot(w, v);
11808 float d = uv * uv - uu * vv;
11809
11810 float cs = (uv * wv - vv * wu) / d;
11811 if (cs < 0 || cs > 1.0)
11812 continue;
11813 float ct = (uv * wu - uu * wv) / d;
11814 if (ct < 0 || (cs + ct) > 1.0)
11815 continue;
11816
11817 // Add contact point
11818 ContactResult result = new ContactResult ();
11819 result.ConsumerID = 0;
11820 result.Depth = Vector3.Distance(rayStart, ip);
11821 result.Normal = n;
11822 result.Pos = ip;
11823
11824 contacts.Add(result);
11825 }
11826
11827 if (contacts.Count == 0)
11828 return null;
11829
11830 contacts.Sort(delegate(ContactResult a, ContactResult b)
11831 {
11832 return (int)(a.Depth - b.Depth);
11833 });
11834
11835 return contacts[0];
11836 }
11837/*
11838 // not done:
11839 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
11840 {
11841 ContactResult[] contacts = null;
11842 World.ForEachSOG(delegate(SceneObjectGroup group)
11843 {
11844 if (m_host.ParentGroup == group)
11845 return;
11846
11847 if (group.IsAttachment)
11848 return;
11849
11850 if(group.RootPart.PhysActor != null)
11851 return;
11852
11853 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
11854 });
11855 return contacts;
11856 }
11857*/
11858
10730 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11859 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10731 { 11860 {
11861 LSL_List list = new LSL_List();
11862
10732 m_host.AddScriptLPS(1); 11863 m_host.AddScriptLPS(1);
10733 11864
10734 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11865 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10735 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11866 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10736 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11867 Vector3 dir = rayEnd - rayStart;
10737 11868
10738 int count = 0; 11869 float dist = Vector3.Mag(dir);
10739// int detectPhantom = 0; 11870
11871 int count = 1;
11872 bool detectPhantom = false;
10740 int dataFlags = 0; 11873 int dataFlags = 0;
10741 int rejectTypes = 0; 11874 int rejectTypes = 0;
10742 11875
10743 for (int i = 0; i < options.Length; i += 2) 11876 for (int i = 0; i < options.Length; i += 2)
10744 { 11877 {
10745 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11878 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10746 {
10747 count = options.GetLSLIntegerItem(i + 1); 11879 count = options.GetLSLIntegerItem(i + 1);
10748 } 11880 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10749// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11881 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10750// {
10751// detectPhantom = options.GetLSLIntegerItem(i + 1);
10752// }
10753 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11882 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10754 {
10755 dataFlags = options.GetLSLIntegerItem(i + 1); 11883 dataFlags = options.GetLSLIntegerItem(i + 1);
10756 }
10757 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11884 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10758 {
10759 rejectTypes = options.GetLSLIntegerItem(i + 1); 11885 rejectTypes = options.GetLSLIntegerItem(i + 1);
10760 }
10761 } 11886 }
10762 11887
10763 LSL_List list = new LSL_List(); 11888 if (count > 16)
10764 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11889 count = 16;
10765
10766 double distance = Util.GetDistanceTo(startvector, endvector);
10767
10768 if (distance == 0)
10769 distance = 0.001;
10770 11890
10771 Vector3 posToCheck = startvector; 11891 List<ContactResult> results = new List<ContactResult>();
10772 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10773 11892
10774 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11893 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10775 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11894 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10776 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11895 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10777 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11896 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10778 11897
10779 for (float i = 0; i <= distance; i += 0.1f) 11898
11899 if (World.SuportsRayCastFiltered())
10780 { 11900 {
10781 posToCheck = startvector + (dir * (i / (float)distance)); 11901 if (dist == 0)
11902 return list;
11903
11904 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11905 if (checkTerrain)
11906 rayfilter |= RayFilterFlags.land;
11907// if (checkAgents)
11908// rayfilter |= RayFilterFlags.agent;
11909 if (checkPhysical)
11910 rayfilter |= RayFilterFlags.physical;
11911 if (checkNonPhysical)
11912 rayfilter |= RayFilterFlags.nonphysical;
11913 if (detectPhantom)
11914 rayfilter |= RayFilterFlags.LSLPhanton;
11915
11916 Vector3 direction = dir * ( 1/dist);
10782 11917
10783 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11918 if(rayfilter == 0)
10784 { 11919 {
10785 ContactResult result = new ContactResult(); 11920 list.Add(new LSL_Integer(0));
10786 result.ConsumerID = 0; 11921 return list;
10787 result.Depth = 0;
10788 result.Normal = Vector3.Zero;
10789 result.Pos = posToCheck;
10790 results.Add(result);
10791 checkTerrain = false;
10792 } 11922 }
10793 11923
10794 if (checkAgents) 11924 // get some more contacts to sort ???
11925 int physcount = 4 * count;
11926 if (physcount > 20)
11927 physcount = 20;
11928
11929 object physresults;
11930 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11931
11932 if (physresults == null)
10795 { 11933 {
10796 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11934 list.Add(new LSL_Integer(-3)); // timeout error
10797 { 11935 return list;
10798 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
10799 {
10800 ContactResult result = new ContactResult ();
10801 result.ConsumerID = sp.LocalId;
10802 result.Depth = 0;
10803 result.Normal = Vector3.Zero;
10804 result.Pos = posToCheck;
10805 results.Add(result);
10806 }
10807 });
10808 } 11936 }
10809 }
10810 11937
10811 int refcount = 0; 11938 results = (List<ContactResult>)physresults;
10812 foreach (ContactResult result in results)
10813 {
10814 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
10815 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10816 continue;
10817 11939
10818 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11940 // for now physics doesn't detect sitted avatars so do it outside physics
11941 if (checkAgents)
11942 {
11943 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11944 foreach (ContactResult r in agentHits)
11945 results.Add(r);
11946 }
10819 11947
10820 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11948 // bug: will not detect phantom unless they are physical
10821 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11949 // don't use ObjectIntersection because its also bad
11950
11951 }
11952 else
11953 {
11954 if (checkTerrain)
11955 {
11956 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11957 if (groundContact != null)
11958 results.Add((ContactResult)groundContact);
11959 }
10822 11960
10823 if (entity == null) 11961 if (checkAgents)
10824 { 11962 {
10825 list.Add(UUID.Zero); 11963 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11964 foreach (ContactResult r in agentHits)
11965 results.Add(r);
11966 }
10826 11967
10827 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11968 if (checkPhysical || checkNonPhysical || detectPhantom)
10828 list.Add(0); 11969 {
11970 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11971 foreach (ContactResult r in objectHits)
11972 results.Add(r);
11973 }
11974 }
10829 11975
10830 list.Add(result.Pos); 11976 results.Sort(delegate(ContactResult a, ContactResult b)
11977 {
11978 return a.Depth.CompareTo(b.Depth);
11979 });
11980
11981 int values = 0;
11982 SceneObjectGroup thisgrp = m_host.ParentGroup;
10831 11983
10832 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11984 foreach (ContactResult result in results)
10833 list.Add(result.Normal); 11985 {
11986 if (result.Depth > dist)
11987 continue;
10834 11988
10835 continue; //Can't find it, so add UUID.Zero 11989 // physics ray can return colisions with host prim
10836 } 11990 if (m_host.LocalId == result.ConsumerID)
11991 continue;
10837 11992
10838 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && 11993 UUID itemID = UUID.Zero;
10839 ((ISceneChildEntity)intersection.obj).PhysActor == null) 11994 int linkNum = 0;
10840 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10841 11995
10842 if (entity is SceneObjectPart) 11996 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11997 // It's a prim!
11998 if (part != null)
10843 { 11999 {
10844 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 12000 // dont detect members of same object ???
12001 if (part.ParentGroup == thisgrp)
12002 continue;
10845 12003
10846 if (pa != null && pa.IsPhysical) 12004 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10847 { 12005 itemID = part.ParentGroup.UUID;
10848 if (!checkPhysical)
10849 continue;
10850 }
10851 else 12006 else
10852 { 12007 itemID = part.UUID;
10853 if (!checkNonPhysical)
10854 continue;
10855 }
10856 }
10857 12008
10858 refcount++; 12009 linkNum = part.LinkNum;
10859 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 12010 }
10860 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10861 else 12011 else
10862 list.Add(entity.UUID);
10863
10864 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10865 { 12012 {
10866 if (entity is SceneObjectPart) 12013 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10867 list.Add(((SceneObjectPart)entity).LinkNum); 12014 /// It it a boy? a girl?
10868 else 12015 if (sp != null)
10869 list.Add(0); 12016 itemID = sp.UUID;
10870 } 12017 }
10871 12018
10872 list.Add(result.Pos); 12019 list.Add(new LSL_String(itemID.ToString()));
12020 list.Add(new LSL_String(result.Pos.ToString()));
12021
12022 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
12023 list.Add(new LSL_Integer(linkNum));
10873 12024
10874 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 12025 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10875 list.Add(result.Normal); 12026 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
12027
12028 values++;
12029 if (values >= count)
12030 break;
10876 } 12031 }
10877 12032
10878 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 12033 list.Add(new LSL_Integer(values));
10879 12034
10880 return list; 12035 return list;
10881 } 12036 }
@@ -10915,7 +12070,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10915 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12070 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10916 if (!isAccount) return 0; 12071 if (!isAccount) return 0;
10917 if (estate.HasAccess(id)) return 1; 12072 if (estate.HasAccess(id)) return 1;
10918 if (estate.IsBanned(id)) 12073 if (estate.IsBanned(id, World.GetUserFlags(id)))
10919 estate.RemoveBan(id); 12074 estate.RemoveBan(id);
10920 estate.AddEstateUser(id); 12075 estate.AddEstateUser(id);
10921 break; 12076 break;
@@ -10934,14 +12089,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10934 break; 12089 break;
10935 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12090 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10936 if (!isAccount) return 0; 12091 if (!isAccount) return 0;
10937 if (estate.IsBanned(id)) return 1; 12092 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10938 EstateBan ban = new EstateBan(); 12093 EstateBan ban = new EstateBan();
10939 ban.EstateID = estate.EstateID; 12094 ban.EstateID = estate.EstateID;
10940 ban.BannedUserID = id; 12095 ban.BannedUserID = id;
10941 estate.AddBan(ban); 12096 estate.AddBan(ban);
10942 break; 12097 break;
10943 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12098 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10944 if (!isAccount || !estate.IsBanned(id)) return 0; 12099 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10945 estate.RemoveBan(id); 12100 estate.RemoveBan(id);
10946 break; 12101 break;
10947 default: return 0; 12102 default: return 0;
@@ -10970,7 +12125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10970 return 16384; 12125 return 16384;
10971 } 12126 }
10972 12127
10973 public LSL_Integer llGetUsedMemory() 12128 public virtual LSL_Integer llGetUsedMemory()
10974 { 12129 {
10975 m_host.AddScriptLPS(1); 12130 m_host.AddScriptLPS(1);
10976 // The value returned for LSO scripts in SL 12131 // The value returned for LSO scripts in SL
@@ -10998,7 +12153,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10998 public void llSetSoundQueueing(int queue) 12153 public void llSetSoundQueueing(int queue)
10999 { 12154 {
11000 m_host.AddScriptLPS(1); 12155 m_host.AddScriptLPS(1);
11001 NotImplemented("llSetSoundQueueing");
11002 } 12156 }
11003 12157
11004 public void llCollisionSprite(string impact_sprite) 12158 public void llCollisionSprite(string impact_sprite)
@@ -11010,10 +12164,274 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11010 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12164 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11011 { 12165 {
11012 m_host.AddScriptLPS(1); 12166 m_host.AddScriptLPS(1);
11013 NotImplemented("llGodLikeRezObject"); 12167
12168 if (!World.Permissions.IsGod(m_host.OwnerID))
12169 NotImplemented("llGodLikeRezObject");
12170
12171 AssetBase rezAsset = World.AssetService.Get(inventory);
12172 if (rezAsset == null)
12173 {
12174 llSay(0, "Asset not found");
12175 return;
12176 }
12177
12178 SceneObjectGroup group = null;
12179
12180 try
12181 {
12182 string xmlData = Utils.BytesToString(rezAsset.Data);
12183 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12184 }
12185 catch
12186 {
12187 llSay(0, "Asset not found");
12188 return;
12189 }
12190
12191 if (group == null)
12192 {
12193 llSay(0, "Asset not found");
12194 return;
12195 }
12196
12197 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12198 group.RootPart.AttachOffset = group.AbsolutePosition;
12199
12200 group.ResetIDs();
12201
12202 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12203 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12204 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12205 group.ScheduleGroupForFullUpdate();
12206
12207 // objects rezzed with this method are die_at_edge by default.
12208 group.RootPart.SetDieAtEdge(true);
12209
12210 group.ResumeScripts();
12211
12212 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12213 "object_rez", new Object[] {
12214 new LSL_String(
12215 group.RootPart.UUID.ToString()) },
12216 new DetectParams[0]));
12217 }
12218
12219 public LSL_String llTransferLindenDollars(string destination, int amount)
12220 {
12221 UUID txn = UUID.Random();
12222
12223 Util.FireAndForget(delegate(object x)
12224 {
12225 int replycode = 0;
12226 string replydata = destination + "," + amount.ToString();
12227
12228 try
12229 {
12230 UUID invItemID=InventorySelf();
12231 if (invItemID == UUID.Zero)
12232 {
12233 replydata = "SERVICE_ERROR";
12234 return;
12235 }
12236
12237 m_host.AddScriptLPS(1);
12238
12239 m_host.TaskInventory.LockItemsForRead(true);
12240 TaskInventoryItem item = m_host.TaskInventory[invItemID];
12241 m_host.TaskInventory.LockItemsForRead(false);
12242
12243 if (item.PermsGranter == UUID.Zero)
12244 {
12245 replydata = "MISSING_PERMISSION_DEBIT";
12246 return;
12247 }
12248
12249 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12250 {
12251 replydata = "MISSING_PERMISSION_DEBIT";
12252 return;
12253 }
12254
12255 UUID toID = new UUID();
12256
12257 if (!UUID.TryParse(destination, out toID))
12258 {
12259 replydata = "INVALID_AGENT";
12260 return;
12261 }
12262
12263 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12264
12265 if (money == null)
12266 {
12267 replydata = "TRANSFERS_DISABLED";
12268 return;
12269 }
12270
12271 bool result = money.ObjectGiveMoney(
12272 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12273
12274 if (result)
12275 {
12276 replycode = 1;
12277 return;
12278 }
12279
12280 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12281 }
12282 finally
12283 {
12284 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12285 "transaction_result", new Object[] {
12286 new LSL_String(txn.ToString()),
12287 new LSL_Integer(replycode),
12288 new LSL_String(replydata) },
12289 new DetectParams[0]));
12290 }
12291 });
12292
12293 return txn.ToString();
11014 } 12294 }
11015 12295
11016 #endregion 12296 #endregion
12297
12298 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12299 {
12300 SceneObjectGroup group = m_host.ParentGroup;
12301
12302 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12303 return;
12304 if (group.IsAttachment)
12305 return;
12306
12307 if (frames.Data.Length > 0) // We are getting a new motion
12308 {
12309 if (group.RootPart.KeyframeMotion != null)
12310 group.RootPart.KeyframeMotion.Stop();
12311 group.RootPart.KeyframeMotion = null;
12312
12313 int idx = 0;
12314
12315 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12316 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12317
12318 while (idx < options.Data.Length)
12319 {
12320 int option = (int)options.GetLSLIntegerItem(idx++);
12321 int remain = options.Data.Length - idx;
12322
12323 switch (option)
12324 {
12325 case ScriptBaseClass.KFM_MODE:
12326 if (remain < 1)
12327 break;
12328 int modeval = (int)options.GetLSLIntegerItem(idx++);
12329 switch(modeval)
12330 {
12331 case ScriptBaseClass.KFM_FORWARD:
12332 mode = KeyframeMotion.PlayMode.Forward;
12333 break;
12334 case ScriptBaseClass.KFM_REVERSE:
12335 mode = KeyframeMotion.PlayMode.Reverse;
12336 break;
12337 case ScriptBaseClass.KFM_LOOP:
12338 mode = KeyframeMotion.PlayMode.Loop;
12339 break;
12340 case ScriptBaseClass.KFM_PING_PONG:
12341 mode = KeyframeMotion.PlayMode.PingPong;
12342 break;
12343 }
12344 break;
12345 case ScriptBaseClass.KFM_DATA:
12346 if (remain < 1)
12347 break;
12348 int dataval = (int)options.GetLSLIntegerItem(idx++);
12349 data = (KeyframeMotion.DataFormat)dataval;
12350 break;
12351 }
12352 }
12353
12354 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12355
12356 idx = 0;
12357
12358 int elemLength = 2;
12359 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12360 elemLength = 3;
12361
12362 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12363 while (idx < frames.Data.Length)
12364 {
12365 int remain = frames.Data.Length - idx;
12366
12367 if (remain < elemLength)
12368 break;
12369
12370 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12371 frame.Position = null;
12372 frame.Rotation = null;
12373
12374 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12375 {
12376 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12377 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12378 }
12379 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12380 {
12381 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12382 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12383 }
12384
12385 float tempf = (float)frames.GetLSLFloatItem(idx++);
12386 frame.TimeMS = (int)(tempf * 1000.0f);
12387
12388 keyframes.Add(frame);
12389 }
12390
12391 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12392 group.RootPart.KeyframeMotion.Start();
12393 }
12394 else
12395 {
12396 if (group.RootPart.KeyframeMotion == null)
12397 return;
12398
12399 if (options.Data.Length == 0)
12400 {
12401 group.RootPart.KeyframeMotion.Stop();
12402 return;
12403 }
12404
12405 int code = (int)options.GetLSLIntegerItem(0);
12406
12407 int idx = 0;
12408
12409 while (idx < options.Data.Length)
12410 {
12411 int option = (int)options.GetLSLIntegerItem(idx++);
12412 int remain = options.Data.Length - idx;
12413
12414 switch (option)
12415 {
12416 case ScriptBaseClass.KFM_COMMAND:
12417 int cmd = (int)options.GetLSLIntegerItem(idx++);
12418 switch (cmd)
12419 {
12420 case ScriptBaseClass.KFM_CMD_PLAY:
12421 group.RootPart.KeyframeMotion.Start();
12422 break;
12423 case ScriptBaseClass.KFM_CMD_STOP:
12424 group.RootPart.KeyframeMotion.Stop();
12425 break;
12426 case ScriptBaseClass.KFM_CMD_PAUSE:
12427 group.RootPart.KeyframeMotion.Pause();
12428 break;
12429 }
12430 break;
12431 }
12432 }
12433 }
12434 }
11017 } 12435 }
11018 12436
11019 public class NotecardCache 12437 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index fe94b79..89e85a0 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 private void InitLSL() 221 private void InitLSL()
@@ -917,18 +926,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
917 if (target != null) 926 if (target != null)
918 { 927 {
919 UUID animID=UUID.Zero; 928 UUID animID=UUID.Zero;
920 lock (m_host.TaskInventory) 929 m_host.TaskInventory.LockItemsForRead(true);
930 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
921 { 931 {
922 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 932 if (inv.Value.Name == animation)
923 { 933 {
924 if (inv.Value.Name == animation) 934 if (inv.Value.Type == (int)AssetType.Animation)
925 { 935 animID = inv.Value.AssetID;
926 if (inv.Value.Type == (int)AssetType.Animation) 936 continue;
927 animID = inv.Value.AssetID;
928 continue;
929 }
930 } 937 }
931 } 938 }
939 m_host.TaskInventory.LockItemsForRead(false);
932 if (animID == UUID.Zero) 940 if (animID == UUID.Zero)
933 target.Animator.AddAnimation(animation, m_host.UUID); 941 target.Animator.AddAnimation(animation, m_host.UUID);
934 else 942 else
@@ -955,18 +963,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
955 if (target != null) 963 if (target != null)
956 { 964 {
957 UUID animID = UUID.Zero; 965 UUID animID = UUID.Zero;
958 lock (m_host.TaskInventory) 966 m_host.TaskInventory.LockItemsForRead(true);
967 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
959 { 968 {
960 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 969 if (inv.Value.Name == animation)
961 { 970 {
962 if (inv.Value.Name == animation) 971 if (inv.Value.Type == (int)AssetType.Animation)
963 { 972 animID = inv.Value.AssetID;
964 if (inv.Value.Type == (int)AssetType.Animation) 973 continue;
965 animID = inv.Value.AssetID;
966 continue;
967 }
968 } 974 }
969 } 975 }
976 m_host.TaskInventory.LockItemsForRead(false);
970 977
971 if (animID == UUID.Zero) 978 if (animID == UUID.Zero)
972 target.Animator.RemoveAnimation(animation); 979 target.Animator.RemoveAnimation(animation);
@@ -1787,6 +1794,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1787 1794
1788 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1795 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1789 { 1796 {
1797 m_host.TaskInventory.LockItemsForRead(true);
1790 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1798 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1791 { 1799 {
1792 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1800 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1794,6 +1802,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1794 assetID = item.AssetID; 1802 assetID = item.AssetID;
1795 } 1803 }
1796 } 1804 }
1805 m_host.TaskInventory.LockItemsForRead(false);
1797 } 1806 }
1798 1807
1799 if (assetID == UUID.Zero) 1808 if (assetID == UUID.Zero)
@@ -2261,7 +2270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2261 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2270 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2262 m_host.AddScriptLPS(1); 2271 m_host.AddScriptLPS(1);
2263 2272
2264 return NpcCreate(firstname, lastname, position, notecard, false, false); 2273 return NpcCreate(firstname, lastname, position, notecard, true, false);
2265 } 2274 }
2266 2275
2267 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2276 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2272,24 +2281,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2272 return NpcCreate( 2281 return NpcCreate(
2273 firstname, lastname, position, notecard, 2282 firstname, lastname, position, notecard,
2274 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2283 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2275 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2284 false);
2285// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2276 } 2286 }
2277 2287
2278 private LSL_Key NpcCreate( 2288 private LSL_Key NpcCreate(
2279 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2289 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2280 { 2290 {
2291 if (!owned)
2292 OSSLError("Unowned NPCs are unsupported");
2293
2294 string groupTitle = String.Empty;
2295
2296 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2297 return new LSL_Key(UUID.Zero.ToString());
2298
2299 if (firstname != String.Empty || lastname != String.Empty)
2300 {
2301 if (firstname != "Shown outfit:")
2302 groupTitle = "- NPC -";
2303 }
2304
2281 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2305 INPCModule module = World.RequestModuleInterface<INPCModule>();
2282 if (module != null) 2306 if (module != null)
2283 { 2307 {
2284 AvatarAppearance appearance = null; 2308 AvatarAppearance appearance = null;
2285 2309
2286 UUID id; 2310// UUID id;
2287 if (UUID.TryParse(notecard, out id)) 2311// if (UUID.TryParse(notecard, out id))
2288 { 2312// {
2289 ScenePresence clonePresence = World.GetScenePresence(id); 2313// ScenePresence clonePresence = World.GetScenePresence(id);
2290 if (clonePresence != null) 2314// if (clonePresence != null)
2291 appearance = clonePresence.Appearance; 2315// appearance = clonePresence.Appearance;
2292 } 2316// }
2293 2317
2294 if (appearance == null) 2318 if (appearance == null)
2295 { 2319 {
@@ -2317,6 +2341,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2317 World, 2341 World,
2318 appearance); 2342 appearance);
2319 2343
2344 ScenePresence sp;
2345 if (World.TryGetScenePresence(x, out sp))
2346 {
2347 sp.Grouptitle = groupTitle;
2348 sp.SendAvatarDataToAllAgents();
2349 }
2320 return new LSL_Key(x.ToString()); 2350 return new LSL_Key(x.ToString());
2321 } 2351 }
2322 2352
@@ -2585,16 +2615,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2585 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2615 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2586 m_host.AddScriptLPS(1); 2616 m_host.AddScriptLPS(1);
2587 2617
2588 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2618 ManualResetEvent ev = new ManualResetEvent(false);
2589 if (module != null)
2590 {
2591 UUID npcId = new UUID(npc.m_string);
2592 2619
2593 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2620 Util.FireAndForget(delegate(object x) {
2594 return; 2621 try
2622 {
2623 INPCModule module = World.RequestModuleInterface<INPCModule>();
2624 if (module != null)
2625 {
2626 UUID npcId = new UUID(npc.m_string);
2595 2627
2596 module.DeleteNPC(npcId, World); 2628 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2597 } 2629 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2630 {
2631 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2632 return;
2633 }
2634
2635 module.DeleteNPC(npcId, World);
2636 }
2637 }
2638 finally
2639 {
2640 ev.Set();
2641 }
2642 });
2643 ev.WaitOne();
2598 } 2644 }
2599 2645
2600 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2646 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3094,4 +3140,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3094 } 3140 }
3095 } 3141 }
3096 } 3142 }
3097} \ No newline at end of file 3143}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 1c272f8..1373971 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -222,7 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
222 // Is the sensor type is AGENT and not SCRIPTED then include agents 222 // Is the sensor type is AGENT and not SCRIPTED then include agents
223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0) 223 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
224 { 224 {
225 sensedEntities.AddRange(doAgentSensor(ts)); 225 sensedEntities.AddRange(doAgentSensor(ts));
226 } 226 }
227 227
228 // If SCRIPTED or PASSIVE or ACTIVE check objects 228 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -319,13 +319,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.RotationOffset; 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, the sensor cone always orients with the 326 // In attachments, the sensor cone always orients with the
326 // avatar rotation. This may include a nonzero elevation if 327 // avatar rotation. This may include a nonzero elevation if
327 // in mouselook. 328 // in mouselook.
328 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 329 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
330 fromRegionPos = avatar.AbsolutePosition;
329 q = avatar.Rotation; 331 q = avatar.Rotation;
330 } 332 }
331 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 333 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -448,6 +450,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
448 // avatar rotation. This may include a nonzero elevation if 450 // avatar rotation. This may include a nonzero elevation if
449 // in mouselook. 451 // in mouselook.
450 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 452 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
453 if (avatar == null)
454 return sensedEntities;
455 fromRegionPos = avatar.AbsolutePosition;
451 q = avatar.Rotation; 456 q = avatar.Rotation;
452 } 457 }
453 458
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 69df392..eab6851 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -124,6 +124,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
124 LSL_Float llGetEnergy(); 124 LSL_Float llGetEnergy();
125 LSL_Vector llGetForce(); 125 LSL_Vector llGetForce();
126 LSL_Integer llGetFreeMemory(); 126 LSL_Integer llGetFreeMemory();
127 LSL_Integer llGetUsedMemory();
127 LSL_Integer llGetFreeURLs(); 128 LSL_Integer llGetFreeURLs();
128 LSL_Vector llGetGeometricCenter(); 129 LSL_Vector llGetGeometricCenter();
129 LSL_Float llGetGMTclock(); 130 LSL_Float llGetGMTclock();
@@ -147,6 +148,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
147 LSL_Vector llGetLocalPos(); 148 LSL_Vector llGetLocalPos();
148 LSL_Rotation llGetLocalRot(); 149 LSL_Rotation llGetLocalRot();
149 LSL_Float llGetMass(); 150 LSL_Float llGetMass();
151 LSL_Float llGetMassMKS();
150 LSL_Integer llGetMemoryLimit(); 152 LSL_Integer llGetMemoryLimit();
151 void llGetNextEmail(string address, string subject); 153 void llGetNextEmail(string address, string subject);
152 LSL_String llGetNotecardLine(string name, int line); 154 LSL_String llGetNotecardLine(string name, int line);
@@ -200,12 +202,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
200 LSL_String llGetTimestamp(); 202 LSL_String llGetTimestamp();
201 LSL_Vector llGetTorque(); 203 LSL_Vector llGetTorque();
202 LSL_Integer llGetUnixTime(); 204 LSL_Integer llGetUnixTime();
203 LSL_Integer llGetUsedMemory();
204 LSL_Vector llGetVel(); 205 LSL_Vector llGetVel();
205 LSL_Float llGetWallclock(); 206 LSL_Float llGetWallclock();
206 void llGiveInventory(string destination, string inventory); 207 void llGiveInventory(string destination, string inventory);
207 void llGiveInventoryList(string destination, string category, LSL_List inventory); 208 void llGiveInventoryList(string destination, string category, LSL_List inventory);
208 LSL_Integer llGiveMoney(string destination, int amount); 209 LSL_Integer llGiveMoney(string destination, int amount);
210 LSL_String llTransferLindenDollars(string destination, int amount);
209 void llGodLikeRezObject(string inventory, LSL_Vector pos); 211 void llGodLikeRezObject(string inventory, LSL_Vector pos);
210 LSL_Float llGround(LSL_Vector offset); 212 LSL_Float llGround(LSL_Vector offset);
211 LSL_Vector llGroundContour(LSL_Vector offset); 213 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -353,6 +355,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
353 void llSetParcelMusicURL(string url); 355 void llSetParcelMusicURL(string url);
354 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 356 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
355 void llSetPos(LSL_Vector pos); 357 void llSetPos(LSL_Vector pos);
358 LSL_Integer llSetRegionPos(LSL_Vector pos);
356 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 359 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
357 void llSetPrimitiveParams(LSL_List rules); 360 void llSetPrimitiveParams(LSL_List rules);
358 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 361 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -401,6 +404,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
401 void llTargetOmega(LSL_Vector axis, double spinrate, double gain); 404 void llTargetOmega(LSL_Vector axis, double spinrate, double gain);
402 void llTargetRemove(int number); 405 void llTargetRemove(int number);
403 void llTeleportAgentHome(string agent); 406 void llTeleportAgentHome(string agent);
407 void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt);
404 void llTextBox(string avatar, string message, int chat_channel); 408 void llTextBox(string avatar, string message, int chat_channel);
405 LSL_String llToLower(string source); 409 LSL_String llToLower(string source);
406 LSL_String llToUpper(string source); 410 LSL_String llToUpper(string source);
@@ -417,9 +421,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
417 LSL_Vector llWind(LSL_Vector offset); 421 LSL_Vector llWind(LSL_Vector offset);
418 LSL_String llXorBase64Strings(string str1, string str2); 422 LSL_String llXorBase64Strings(string str1, string str2);
419 LSL_String llXorBase64StringsCorrect(string str1, string str2); 423 LSL_String llXorBase64StringsCorrect(string str1, string str2);
420 void print(string str); 424 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
425 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
421 426
422 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 427 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
423 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 428 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
429 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
424 } 430 }
425} 431}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 545bbee..2fcc443 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index fd7c41e..23b4336 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
95 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
96 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
97 98
98 //Particle Systems 99 //Particle Systems
99 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -282,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -581,6 +583,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
581 public const int PRIM_MEDIA_PERM_OWNER = 1; 583 public const int PRIM_MEDIA_PERM_OWNER = 1;
582 public const int PRIM_MEDIA_PERM_GROUP = 2; 584 public const int PRIM_MEDIA_PERM_GROUP = 2;
583 public const int PRIM_MEDIA_PERM_ANYONE = 4; 585 public const int PRIM_MEDIA_PERM_ANYONE = 4;
586
587 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
588 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
589 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
590 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
591
592 public const int PRIM_PHYSICS_MATERIAL = 31;
593 public const int DENSITY = 1;
594 public const int FRICTION = 2;
595 public const int RESTITUTION = 4;
596 public const int GRAVITY_MULTIPLIER = 8;
584 597
585 // extra constants for llSetPrimMediaParams 598 // extra constants for llSetPrimMediaParams
586 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 599 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -653,5 +666,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
653 public static readonly LSLInteger RCERR_UNKNOWN = -1; 666 public static readonly LSLInteger RCERR_UNKNOWN = -1;
654 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 667 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
655 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 668 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
669
670 public const int KFM_MODE = 1;
671 public const int KFM_LOOP = 1;
672 public const int KFM_REVERSE = 3;
673 public const int KFM_FORWARD = 0;
674 public const int KFM_PING_PONG = 2;
675 public const int KFM_DATA = 2;
676 public const int KFM_TRANSLATION = 2;
677 public const int KFM_ROTATION = 1;
678 public const int KFM_COMMAND = 0;
679 public const int KFM_CMD_PLAY = 0;
680 public const int KFM_CMD_STOP = 1;
681 public const int KFM_CMD_PAUSE = 2;
656 } 682 }
657} 683}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 3c2f7bd..9446099 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();
@@ -569,6 +581,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
569 return m_LSL_Functions.llGetMass(); 581 return m_LSL_Functions.llGetMass();
570 } 582 }
571 583
584 public LSL_Float llGetMassMKS()
585 {
586 return m_LSL_Functions.llGetMassMKS();
587 }
588
572 public LSL_Integer llGetMemoryLimit() 589 public LSL_Integer llGetMemoryLimit()
573 { 590 {
574 return m_LSL_Functions.llGetMemoryLimit(); 591 return m_LSL_Functions.llGetMemoryLimit();
@@ -834,11 +851,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
834 return m_LSL_Functions.llGetUnixTime(); 851 return m_LSL_Functions.llGetUnixTime();
835 } 852 }
836 853
837 public LSL_Integer llGetUsedMemory()
838 {
839 return m_LSL_Functions.llGetUsedMemory();
840 }
841
842 public LSL_Vector llGetVel() 854 public LSL_Vector llGetVel()
843 { 855 {
844 return m_LSL_Functions.llGetVel(); 856 return m_LSL_Functions.llGetVel();
@@ -864,6 +876,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
864 return m_LSL_Functions.llGiveMoney(destination, amount); 876 return m_LSL_Functions.llGiveMoney(destination, amount);
865 } 877 }
866 878
879 public LSL_String llTransferLindenDollars(string destination, int amount)
880 {
881 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
882 }
883
867 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 884 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
868 { 885 {
869 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 886 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1588,6 +1605,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1588 m_LSL_Functions.llSetPos(pos); 1605 m_LSL_Functions.llSetPos(pos);
1589 } 1606 }
1590 1607
1608 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1609 {
1610 return m_LSL_Functions.llSetRegionPos(pos);
1611 }
1612
1591 public void llSetPrimitiveParams(LSL_List rules) 1613 public void llSetPrimitiveParams(LSL_List rules)
1592 { 1614 {
1593 m_LSL_Functions.llSetPrimitiveParams(rules); 1615 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1823,6 +1845,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1823 m_LSL_Functions.llTargetRemove(number); 1845 m_LSL_Functions.llTargetRemove(number);
1824 } 1846 }
1825 1847
1848 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
1849 {
1850 m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt);
1851 }
1852
1826 public void llTeleportAgentHome(string agent) 1853 public void llTeleportAgentHome(string agent)
1827 { 1854 {
1828 m_LSL_Functions.llTeleportAgentHome(agent); 1855 m_LSL_Functions.llTeleportAgentHome(agent);
@@ -1938,9 +1965,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1938 return m_LSL_Functions.llClearLinkMedia(link, face); 1965 return m_LSL_Functions.llClearLinkMedia(link, face);
1939 } 1966 }
1940 1967
1941 public void print(string str) 1968 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1969 {
1970 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1971 }
1972
1973 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1974 {
1975 m_LSL_Functions.llSetKeyframedMotion(frames, options);
1976 }
1977
1978 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1942 { 1979 {
1943 m_LSL_Functions.print(str); 1980 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1944 } 1981 }
1945 } 1982 }
1946} 1983}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6e36742..ff1f277 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -218,13 +219,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
218 219
219 if (part != null) 220 if (part != null)
220 { 221 {
221 lock (part.TaskInventory) 222 part.TaskInventory.LockItemsForRead(true);
223 if (part.TaskInventory.ContainsKey(ItemID))
222 { 224 {
223 if (part.TaskInventory.ContainsKey(ItemID)) 225 ScriptTask = part.TaskInventory[ItemID];
224 {
225 ScriptTask = part.TaskInventory[ItemID];
226 }
227 } 226 }
227 part.TaskInventory.LockItemsForRead(false);
228 } 228 }
229 229
230 ApiManager am = new ApiManager(); 230 ApiManager am = new ApiManager();
@@ -416,14 +416,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
416 { 416 {
417 int permsMask; 417 int permsMask;
418 UUID permsGranter; 418 UUID permsGranter;
419 lock (part.TaskInventory) 419 part.TaskInventory.LockItemsForRead(true);
420 if (!part.TaskInventory.ContainsKey(ItemID))
420 { 421 {
421 if (!part.TaskInventory.ContainsKey(ItemID)) 422 part.TaskInventory.LockItemsForRead(false);
422 return; 423 return;
423
424 permsGranter = part.TaskInventory[ItemID].PermsGranter;
425 permsMask = part.TaskInventory[ItemID].PermsMask;
426 } 424 }
425 permsGranter = part.TaskInventory[ItemID].PermsGranter;
426 permsMask = part.TaskInventory[ItemID].PermsMask;
427 part.TaskInventory.LockItemsForRead(false);
427 428
428 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 429 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
429 { 430 {
@@ -551,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
551 return true; 552 return true;
552 } 553 }
553 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
554 public void SetState(string state) 556 public void SetState(string state)
555 { 557 {
556 if (state == State) 558 if (state == State)
@@ -562,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
562 new DetectParams[0])); 564 new DetectParams[0]));
563 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
564 new DetectParams[0])); 566 new DetectParams[0]));
565 567
566 throw new EventAbortException(); 568 throw new EventAbortException();
567 } 569 }
568 570
@@ -652,45 +654,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
652 /// <returns></returns> 654 /// <returns></returns>
653 public object EventProcessor() 655 public object EventProcessor()
654 { 656 {
657 EventParams data = null;
655 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 658 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
656 if (!Running) 659 if (!Running)
657 return 0; 660 return 0;
658 661
659 lock (m_Script)
660 {
661// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 662// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
662 663
663 if (Suspended) 664 if (Suspended)
664 return 0; 665 return 0;
665
666 EventParams data = null;
667 666
668 lock (EventQueue) 667 lock (EventQueue)
668 {
669 data = (EventParams) EventQueue.Dequeue();
670 if (data == null) // Shouldn't happen
669 { 671 {
670 data = (EventParams)EventQueue.Dequeue(); 672 if (EventQueue.Count > 0 && Running && !ShuttingDown)
671 if (data == null) // Shouldn't happen
672 { 673 {
673 if (EventQueue.Count > 0 && Running && !ShuttingDown) 674 m_CurrentWorkItem = Engine.QueueEventHandler(this);
674 {
675 m_CurrentWorkItem = Engine.QueueEventHandler(this);
676 }
677 else
678 {
679 m_CurrentWorkItem = null;
680 }
681 return 0;
682 } 675 }
683 676 else
684 if (data.EventName == "timer")
685 m_TimerQueued = false;
686 if (data.EventName == "control")
687 { 677 {
688 if (m_ControlEventsInQueue > 0) 678 m_CurrentWorkItem = null;
689 m_ControlEventsInQueue--;
690 } 679 }
691 if (data.EventName == "collision") 680 return 0;
692 m_CollisionInQueue = false;
693 } 681 }
682
683 if (data.EventName == "timer")
684 m_TimerQueued = false;
685 if (data.EventName == "control")
686 {
687 if (m_ControlEventsInQueue > 0)
688 m_ControlEventsInQueue--;
689 }
690 if (data.EventName == "collision")
691 m_CollisionInQueue = false;
692 }
693
694 lock(m_Script)
695 {
694 696
695// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 697// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
696 698
@@ -859,6 +861,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
859 new Object[0], new DetectParams[0])); 861 new Object[0], new DetectParams[0]));
860 } 862 }
861 863
864 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
862 public void ApiResetScript() 865 public void ApiResetScript()
863 { 866 {
864 // bool running = Running; 867 // bool running = Running;
@@ -890,10 +893,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
890 893
891 public Dictionary<string, object> GetVars() 894 public Dictionary<string, object> GetVars()
892 { 895 {
893 if (m_Script != null) 896 return m_Script.GetVars();
894 return m_Script.GetVars();
895 else
896 return new Dictionary<string, object>();
897 } 897 }
898 898
899 public void SetVars(Dictionary<string, object> vars) 899 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..8adf4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 23a4cf9..5a02d4c 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Reflection; 34using System.Reflection;
@@ -112,6 +113,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
112 private Dictionary<UUID, IScriptInstance> m_Scripts = 113 private Dictionary<UUID, IScriptInstance> m_Scripts =
113 new Dictionary<UUID, IScriptInstance>(); 114 new Dictionary<UUID, IScriptInstance>();
114 115
116 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
117
115 // Maps the asset ID to the assembly 118 // Maps the asset ID to the assembly
116 119
117 private Dictionary<UUID, string> m_Assemblies = 120 private Dictionary<UUID, string> m_Assemblies =
@@ -134,6 +137,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
134 IWorkItemResult m_CurrentCompile = null; 137 IWorkItemResult m_CurrentCompile = null;
135 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 138 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
136 139
140 private void lockScriptsForRead(bool locked)
141 {
142 if (locked)
143 {
144 if (m_scriptsLock.RecursiveReadCount > 0)
145 {
146 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
147 m_scriptsLock.ExitReadLock();
148 }
149 if (m_scriptsLock.RecursiveWriteCount > 0)
150 {
151 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
152 m_scriptsLock.ExitWriteLock();
153 }
154
155 while (!m_scriptsLock.TryEnterReadLock(60000))
156 {
157 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
158 if (m_scriptsLock.IsWriteLockHeld)
159 {
160 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
161 }
162 }
163 }
164 else
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_scriptsLock.ExitReadLock();
169 }
170 }
171 }
172 private void lockScriptsForWrite(bool locked)
173 {
174 if (locked)
175 {
176 if (m_scriptsLock.RecursiveReadCount > 0)
177 {
178 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
179 m_scriptsLock.ExitReadLock();
180 }
181 if (m_scriptsLock.RecursiveWriteCount > 0)
182 {
183 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
184 m_scriptsLock.ExitWriteLock();
185 }
186
187 while (!m_scriptsLock.TryEnterWriteLock(60000))
188 {
189 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
190 if (m_scriptsLock.IsWriteLockHeld)
191 {
192 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
193 }
194 }
195 }
196 else
197 {
198 if (m_scriptsLock.RecursiveWriteCount > 0)
199 {
200 m_scriptsLock.ExitWriteLock();
201 }
202 }
203 }
204
137 public string ScriptEngineName 205 public string ScriptEngineName
138 { 206 {
139 get { return "XEngine"; } 207 get { return "XEngine"; }
@@ -527,44 +595,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine
527 { 595 {
528 if (!m_Enabled) 596 if (!m_Enabled)
529 return; 597 return;
530 598 lockScriptsForRead(true);
531 lock (m_Scripts) 599 foreach (IScriptInstance instance in m_Scripts.Values)
532 { 600 {
533 m_log.InfoFormat( 601 // Force a final state save
534 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 602 //
535 603 if (m_Assemblies.ContainsKey(instance.AssetID))
536 foreach (IScriptInstance instance in m_Scripts.Values)
537 { 604 {
538 // Force a final state save 605 string assembly = m_Assemblies[instance.AssetID];
539 // 606 instance.SaveState(assembly);
540 if (m_Assemblies.ContainsKey(instance.AssetID)) 607 }
541 {
542 string assembly = m_Assemblies[instance.AssetID];
543 instance.SaveState(assembly);
544 }
545 608
546 // Clear the event queue and abort the instance thread 609 // Clear the event queue and abort the instance thread
547 // 610 //
548 instance.ClearQueue(); 611 instance.ClearQueue();
549 instance.Stop(0); 612 instance.Stop(0);
550 613
551 // Release events, timer, etc 614 // Release events, timer, etc
552 // 615 //
553 instance.DestroyScriptInstance(); 616 instance.DestroyScriptInstance();
554 617
555 // Unload scripts and app domains. 618 // Unload scripts and app domains
556 // Must be done explicitly because they have infinite 619 // Must be done explicitly because they have infinite
557 // lifetime. 620 // lifetime
558 // However, don't bother to do this if the simulator is shutting 621 //
559 // down since it takes a long time with many scripts. 622 if (!m_SimulatorShuttingDown)
560 if (!m_SimulatorShuttingDown) 623 {
624 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
625 if (m_DomainScripts[instance.AppDomain].Count == 0)
561 { 626 {
562 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 627 m_DomainScripts.Remove(instance.AppDomain);
563 if (m_DomainScripts[instance.AppDomain].Count == 0) 628 UnloadAppDomain(instance.AppDomain);
564 {
565 m_DomainScripts.Remove(instance.AppDomain);
566 UnloadAppDomain(instance.AppDomain);
567 }
568 } 629 }
569 } 630 }
570 631
@@ -573,6 +634,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
573 m_Assemblies.Clear(); 634 m_Assemblies.Clear();
574 m_DomainScripts.Clear(); 635 m_DomainScripts.Clear();
575 } 636 }
637 lockScriptsForRead(false);
638 lockScriptsForWrite(true);
639 m_Scripts.Clear();
640 lockScriptsForWrite(false);
641 m_PrimObjects.Clear();
642 m_Assemblies.Clear();
643 m_DomainScripts.Clear();
644
576 lock (m_ScriptEngines) 645 lock (m_ScriptEngines)
577 { 646 {
578 m_ScriptEngines.Remove(this); 647 m_ScriptEngines.Remove(this);
@@ -637,22 +706,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
637 706
638 List<IScriptInstance> instances = new List<IScriptInstance>(); 707 List<IScriptInstance> instances = new List<IScriptInstance>();
639 708
640 lock (m_Scripts) 709 lockScriptsForRead(true);
641 { 710 foreach (IScriptInstance instance in m_Scripts.Values)
642 foreach (IScriptInstance instance in m_Scripts.Values)
643 instances.Add(instance); 711 instances.Add(instance);
644 } 712 lockScriptsForRead(false);
645 713
646 foreach (IScriptInstance i in instances) 714 foreach (IScriptInstance i in instances)
647 { 715 {
648 string assembly = String.Empty; 716 string assembly = String.Empty;
649 717
650 lock (m_Scripts) 718
651 {
652 if (!m_Assemblies.ContainsKey(i.AssetID)) 719 if (!m_Assemblies.ContainsKey(i.AssetID))
653 continue; 720 continue;
654 assembly = m_Assemblies[i.AssetID]; 721 assembly = m_Assemblies[i.AssetID];
655 } 722
656 723
657 i.SaveState(assembly); 724 i.SaveState(assembly);
658 } 725 }
@@ -996,95 +1063,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
996 } 1063 }
997 1064
998 ScriptInstance instance = null; 1065 ScriptInstance instance = null;
999 lock (m_Scripts) 1066 // Create the object record
1067 lockScriptsForRead(true);
1068 if ((!m_Scripts.ContainsKey(itemID)) ||
1069 (m_Scripts[itemID].AssetID != assetID))
1000 { 1070 {
1001 // Create the object record 1071 lockScriptsForRead(false);
1002 if ((!m_Scripts.ContainsKey(itemID)) ||
1003 (m_Scripts[itemID].AssetID != assetID))
1004 {
1005 UUID appDomain = assetID;
1006 1072
1007 if (part.ParentGroup.IsAttachment) 1073 UUID appDomain = assetID;
1008 appDomain = part.ParentGroup.RootPart.UUID;
1009 1074
1010 if (!m_AppDomains.ContainsKey(appDomain)) 1075 if (part.ParentGroup.IsAttachment)
1011 { 1076 appDomain = part.ParentGroup.RootPart.UUID;
1012 try
1013 {
1014 AppDomainSetup appSetup = new AppDomainSetup();
1015 appSetup.PrivateBinPath = Path.Combine(
1016 m_ScriptEnginesPath,
1017 m_Scene.RegionInfo.RegionID.ToString());
1018 1077
1019 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1078 if (!m_AppDomains.ContainsKey(appDomain))
1020 Evidence evidence = new Evidence(baseEvidence); 1079 {
1080 try
1081 {
1082 AppDomainSetup appSetup = new AppDomainSetup();
1083 appSetup.PrivateBinPath = Path.Combine(
1084 m_ScriptEnginesPath,
1085 m_Scene.RegionInfo.RegionID.ToString());
1021 1086
1022 AppDomain sandbox; 1087 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1023 if (m_AppDomainLoading) 1088 Evidence evidence = new Evidence(baseEvidence);
1024 {
1025 sandbox = AppDomain.CreateDomain(
1026 m_Scene.RegionInfo.RegionID.ToString(),
1027 evidence, appSetup);
1028 sandbox.AssemblyResolve +=
1029 new ResolveEventHandler(
1030 AssemblyResolver.OnAssemblyResolve);
1031 }
1032 else
1033 {
1034 sandbox = AppDomain.CurrentDomain;
1035 }
1036
1037 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1038 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1039 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1040 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1041 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1042 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1043 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1044
1045 m_AppDomains[appDomain] = sandbox;
1046 1089
1047 m_DomainScripts[appDomain] = new List<UUID>(); 1090 AppDomain sandbox;
1091 if (m_AppDomainLoading)
1092 {
1093 sandbox = AppDomain.CreateDomain(
1094 m_Scene.RegionInfo.RegionID.ToString(),
1095 evidence, appSetup);
1096 m_AppDomains[appDomain].AssemblyResolve +=
1097 new ResolveEventHandler(
1098 AssemblyResolver.OnAssemblyResolve);
1048 } 1099 }
1049 catch (Exception e) 1100 else
1050 { 1101 {
1051 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1102 sandbox = AppDomain.CurrentDomain;
1052 m_ScriptErrorMessage += "Exception creating app domain:\n";
1053 m_ScriptFailCount++;
1054 lock (m_AddingAssemblies)
1055 {
1056 m_AddingAssemblies[assembly]--;
1057 }
1058 return false;
1059 } 1103 }
1060 }
1061 m_DomainScripts[appDomain].Add(itemID);
1062
1063 instance = new ScriptInstance(this, part,
1064 itemID, assetID, assembly,
1065 m_AppDomains[appDomain],
1066 part.ParentGroup.RootPart.Name,
1067 item.Name, startParam, postOnRez,
1068 stateSource, m_MaxScriptQueue);
1069
1070 m_log.DebugFormat(
1071 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1072 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1073 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1074 1104
1075 if (presence != null) 1105 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1106 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1107 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1108 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1109 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1110 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1111 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1112
1113 m_AppDomains[appDomain] = sandbox;
1114
1115 m_DomainScripts[appDomain] = new List<UUID>();
1116 }
1117 catch (Exception e)
1076 { 1118 {
1077 ShowScriptSaveResponse(item.OwnerID, 1119 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1078 assetID, "Compile successful", true); 1120 m_ScriptErrorMessage += "Exception creating app domain:\n";
1121 m_ScriptFailCount++;
1122 lock (m_AddingAssemblies)
1123 {
1124 m_AddingAssemblies[assembly]--;
1125 }
1126 return false;
1079 } 1127 }
1128 }
1129 m_DomainScripts[appDomain].Add(itemID);
1130
1131 instance = new ScriptInstance(this, part,
1132 itemID, assetID, assembly,
1133 m_AppDomains[appDomain],
1134 part.ParentGroup.RootPart.Name,
1135 item.Name, startParam, postOnRez,
1136 stateSource, m_MaxScriptQueue);
1137
1138 m_log.DebugFormat(
1139 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1140 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1141 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1080 1142
1081 instance.AppDomain = appDomain; 1143 if (presence != null)
1082 instance.LineMap = linemap; 1144 {
1083 1145 ShowScriptSaveResponse(item.OwnerID,
1084 m_Scripts[itemID] = instance; 1146 assetID, "Compile successful", true);
1085 } 1147 }
1086 }
1087 1148
1149 instance.AppDomain = appDomain;
1150 instance.LineMap = linemap;
1151 lockScriptsForWrite(true);
1152 m_Scripts[itemID] = instance;
1153 lockScriptsForWrite(false);
1154 }
1155 else
1156 {
1157 lockScriptsForRead(false);
1158 }
1088 lock (m_PrimObjects) 1159 lock (m_PrimObjects)
1089 { 1160 {
1090 if (!m_PrimObjects.ContainsKey(localID)) 1161 if (!m_PrimObjects.ContainsKey(localID))
@@ -1102,9 +1173,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1102 m_AddingAssemblies[assembly]--; 1173 m_AddingAssemblies[assembly]--;
1103 } 1174 }
1104 1175
1105 if (instance != null) 1176 if (instance!=null)
1106 instance.Init(); 1177 instance.Init();
1107 1178
1108 return true; 1179 return true;
1109 } 1180 }
1110 1181
@@ -1117,18 +1188,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1117 m_CompileDict.Remove(itemID); 1188 m_CompileDict.Remove(itemID);
1118 } 1189 }
1119 1190
1120 IScriptInstance instance = null; 1191 lockScriptsForRead(true);
1121 1192 // Do we even have it?
1122 lock (m_Scripts) 1193 if (!m_Scripts.ContainsKey(itemID))
1123 { 1194 {
1124 // Do we even have it? 1195 // Do we even have it?
1125 if (!m_Scripts.ContainsKey(itemID)) 1196 if (!m_Scripts.ContainsKey(itemID))
1126 return; 1197 return;
1127 1198
1128 instance = m_Scripts[itemID]; 1199 lockScriptsForRead(false);
1200 lockScriptsForWrite(true);
1129 m_Scripts.Remove(itemID); 1201 m_Scripts.Remove(itemID);
1202 lockScriptsForWrite(false);
1203
1204 return;
1130 } 1205 }
1206
1131 1207
1208 IScriptInstance instance=m_Scripts[itemID];
1209 lockScriptsForRead(false);
1210 lockScriptsForWrite(true);
1211 m_Scripts.Remove(itemID);
1212 lockScriptsForWrite(false);
1132 instance.ClearQueue(); 1213 instance.ClearQueue();
1133 1214
1134 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1215 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1167,8 +1248,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1167 1248
1168 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1249 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1169 if (handlerObjectRemoved != null) 1250 if (handlerObjectRemoved != null)
1170 handlerObjectRemoved(instance.ObjectID); 1251 {
1252 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1253 handlerObjectRemoved(part.UUID);
1254 }
1171 1255
1256 CleanAssemblies();
1257
1172 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1258 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1173 if (handlerScriptRemoved != null) 1259 if (handlerScriptRemoved != null)
1174 handlerScriptRemoved(itemID); 1260 handlerScriptRemoved(itemID);
@@ -1310,7 +1396,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1310 return false; 1396 return false;
1311 1397
1312 uuids = m_PrimObjects[localID]; 1398 uuids = m_PrimObjects[localID];
1313 } 1399
1314 1400
1315 foreach (UUID itemID in uuids) 1401 foreach (UUID itemID in uuids)
1316 { 1402 {
@@ -1328,6 +1414,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1328 result = true; 1414 result = true;
1329 } 1415 }
1330 } 1416 }
1417 }
1331 1418
1332 return result; 1419 return result;
1333 } 1420 }
@@ -1429,12 +1516,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1429 private IScriptInstance GetInstance(UUID itemID) 1516 private IScriptInstance GetInstance(UUID itemID)
1430 { 1517 {
1431 IScriptInstance instance; 1518 IScriptInstance instance;
1432 lock (m_Scripts) 1519 lockScriptsForRead(true);
1520 if (!m_Scripts.ContainsKey(itemID))
1433 { 1521 {
1434 if (!m_Scripts.ContainsKey(itemID)) 1522 lockScriptsForRead(false);
1435 return null; 1523 return null;
1436 instance = m_Scripts[itemID];
1437 } 1524 }
1525 instance = m_Scripts[itemID];
1526 lockScriptsForRead(false);
1438 return instance; 1527 return instance;
1439 } 1528 }
1440 1529
@@ -1458,6 +1547,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1458 return false; 1547 return false;
1459 } 1548 }
1460 1549
1550 [DebuggerNonUserCode]
1461 public void ApiResetScript(UUID itemID) 1551 public void ApiResetScript(UUID itemID)
1462 { 1552 {
1463 IScriptInstance instance = GetInstance(itemID); 1553 IScriptInstance instance = GetInstance(itemID);
@@ -1509,6 +1599,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1509 return UUID.Zero; 1599 return UUID.Zero;
1510 } 1600 }
1511 1601
1602 [DebuggerNonUserCode]
1512 public void SetState(UUID itemID, string newState) 1603 public void SetState(UUID itemID, string newState)
1513 { 1604 {
1514 IScriptInstance instance = GetInstance(itemID); 1605 IScriptInstance instance = GetInstance(itemID);
@@ -1531,11 +1622,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1531 1622
1532 List<IScriptInstance> instances = new List<IScriptInstance>(); 1623 List<IScriptInstance> instances = new List<IScriptInstance>();
1533 1624
1534 lock (m_Scripts) 1625 lockScriptsForRead(true);
1535 { 1626 foreach (IScriptInstance instance in m_Scripts.Values)
1536 foreach (IScriptInstance instance in m_Scripts.Values)
1537 instances.Add(instance); 1627 instances.Add(instance);
1538 } 1628 lockScriptsForRead(false);
1539 1629
1540 foreach (IScriptInstance i in instances) 1630 foreach (IScriptInstance i in instances)
1541 { 1631 {
@@ -1987,5 +2077,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1987// else 2077// else
1988// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 2078// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
1989 } 2079 }
2080
2081 public bool HasScript(UUID itemID, out bool running)
2082 {
2083 running = true;
2084
2085 IScriptInstance instance = GetInstance(itemID);
2086 if (instance == null)
2087 return false;
2088
2089 running = instance.Running;
2090 return true;
2091 }
1990 } 2092 }
1991} 2093}