aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
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
18 files changed, 2868 insertions, 1043 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 a2176ba..425d2c5 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
@@ -1105,10 +1214,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1105 return detectedParams.TouchUV; 1214 return detectedParams.TouchUV;
1106 } 1215 }
1107 1216
1217 [DebuggerNonUserCode]
1108 public virtual void llDie() 1218 public virtual void llDie()
1109 { 1219 {
1110 m_host.AddScriptLPS(1); 1220 m_host.AddScriptLPS(1);
1111 throw new SelfDeleteException(); 1221 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1112 } 1222 }
1113 1223
1114 public LSL_Float llGround(LSL_Vector offset) 1224 public LSL_Float llGround(LSL_Vector offset)
@@ -1181,6 +1291,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1181 1291
1182 public void llSetStatus(int status, int value) 1292 public void llSetStatus(int status, int value)
1183 { 1293 {
1294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1295 return;
1184 m_host.AddScriptLPS(1); 1296 m_host.AddScriptLPS(1);
1185 1297
1186 int statusrotationaxis = 0; 1298 int statusrotationaxis = 0;
@@ -1412,6 +1524,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1412 { 1524 {
1413 m_host.AddScriptLPS(1); 1525 m_host.AddScriptLPS(1);
1414 1526
1527 SetColor(m_host, color, face);
1528 }
1529
1530 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1531 {
1532 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1533 return;
1534
1535 Primitive.TextureEntry tex = part.Shape.Textures;
1536 Color4 texcolor;
1537 if (face >= 0 && face < GetNumberOfSides(part))
1538 {
1539 texcolor = tex.CreateFace((uint)face).RGBA;
1540 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1541 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1542 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1543 tex.FaceTextures[face].RGBA = texcolor;
1544 part.UpdateTextureEntry(tex.GetBytes());
1545 return;
1546 }
1547 else if (face == ScriptBaseClass.ALL_SIDES)
1548 {
1549 for (uint i = 0; i < GetNumberOfSides(part); i++)
1550 {
1551 if (tex.FaceTextures[i] != null)
1552 {
1553 texcolor = tex.FaceTextures[i].RGBA;
1554 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1555 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1556 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1557 tex.FaceTextures[i].RGBA = texcolor;
1558 }
1559 texcolor = tex.DefaultTexture.RGBA;
1560 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1561 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1562 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1563 tex.DefaultTexture.RGBA = texcolor;
1564 }
1565 part.UpdateTextureEntry(tex.GetBytes());
1566 return;
1567 }
1568
1415 if (face == ScriptBaseClass.ALL_SIDES) 1569 if (face == ScriptBaseClass.ALL_SIDES)
1416 face = SceneObjectPart.ALL_SIDES; 1570 face = SceneObjectPart.ALL_SIDES;
1417 1571
@@ -1420,6 +1574,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1420 1574
1421 public void SetTexGen(SceneObjectPart part, int face,int style) 1575 public void SetTexGen(SceneObjectPart part, int face,int style)
1422 { 1576 {
1577 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1578 return;
1579
1423 Primitive.TextureEntry tex = part.Shape.Textures; 1580 Primitive.TextureEntry tex = part.Shape.Textures;
1424 MappingType textype; 1581 MappingType textype;
1425 textype = MappingType.Default; 1582 textype = MappingType.Default;
@@ -1450,6 +1607,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1450 1607
1451 public void SetGlow(SceneObjectPart part, int face, float glow) 1608 public void SetGlow(SceneObjectPart part, int face, float glow)
1452 { 1609 {
1610 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1611 return;
1612
1453 Primitive.TextureEntry tex = part.Shape.Textures; 1613 Primitive.TextureEntry tex = part.Shape.Textures;
1454 if (face >= 0 && face < GetNumberOfSides(part)) 1614 if (face >= 0 && face < GetNumberOfSides(part))
1455 { 1615 {
@@ -1475,6 +1635,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1475 1635
1476 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1636 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1477 { 1637 {
1638 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1639 return;
1478 1640
1479 Shininess sval = new Shininess(); 1641 Shininess sval = new Shininess();
1480 1642
@@ -1525,6 +1687,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1525 1687
1526 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1688 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1527 { 1689 {
1690 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1691 return;
1692
1528 Primitive.TextureEntry tex = part.Shape.Textures; 1693 Primitive.TextureEntry tex = part.Shape.Textures;
1529 if (face >= 0 && face < GetNumberOfSides(part)) 1694 if (face >= 0 && face < GetNumberOfSides(part))
1530 { 1695 {
@@ -1585,13 +1750,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1585 m_host.AddScriptLPS(1); 1750 m_host.AddScriptLPS(1);
1586 1751
1587 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1752 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1588 1753 if (parts.Count > 0)
1589 foreach (SceneObjectPart part in parts) 1754 {
1590 SetAlpha(part, alpha, face); 1755 try
1756 {
1757 parts[0].ParentGroup.areUpdatesSuspended = true;
1758 foreach (SceneObjectPart part in parts)
1759 SetAlpha(part, alpha, face);
1760 }
1761 finally
1762 {
1763 parts[0].ParentGroup.areUpdatesSuspended = false;
1764 }
1765 }
1591 } 1766 }
1592 1767
1593 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1768 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1594 { 1769 {
1770 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1771 return;
1772
1595 Primitive.TextureEntry tex = part.Shape.Textures; 1773 Primitive.TextureEntry tex = part.Shape.Textures;
1596 Color4 texcolor; 1774 Color4 texcolor;
1597 if (face >= 0 && face < GetNumberOfSides(part)) 1775 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1644,7 +1822,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1644 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1822 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1645 float wind, float tension, LSL_Vector Force) 1823 float wind, float tension, LSL_Vector Force)
1646 { 1824 {
1647 if (part == null) 1825 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1648 return; 1826 return;
1649 1827
1650 if (flexi) 1828 if (flexi)
@@ -1678,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1678 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1679 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1680 { 1858 {
1681 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1682 return; 1860 return;
1683 1861
1684 if (light) 1862 if (light)
@@ -1755,15 +1933,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1755 m_host.AddScriptLPS(1); 1933 m_host.AddScriptLPS(1);
1756 1934
1757 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1935 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1758 1936 if (parts.Count > 0)
1759 foreach (SceneObjectPart part in parts) 1937 {
1760 SetTexture(part, texture, face); 1938 try
1761 1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = true;
1941 foreach (SceneObjectPart part in parts)
1942 SetTexture(part, texture, face);
1943 }
1944 finally
1945 {
1946 parts[0].ParentGroup.areUpdatesSuspended = false;
1947 }
1948 }
1762 ScriptSleep(200); 1949 ScriptSleep(200);
1763 } 1950 }
1764 1951
1765 protected void SetTexture(SceneObjectPart part, string texture, int face) 1952 protected void SetTexture(SceneObjectPart part, string texture, int face)
1766 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1767 UUID textureID = new UUID(); 1957 UUID textureID = new UUID();
1768 1958
1769 textureID = InventoryKey(texture, (int)AssetType.Texture); 1959 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1808,6 +1998,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 1998
1809 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1999 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1810 { 2000 {
2001 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2002 return;
2003
1811 Primitive.TextureEntry tex = part.Shape.Textures; 2004 Primitive.TextureEntry tex = part.Shape.Textures;
1812 if (face >= 0 && face < GetNumberOfSides(part)) 2005 if (face >= 0 && face < GetNumberOfSides(part))
1813 { 2006 {
@@ -1844,6 +2037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1844 2037
1845 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2038 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1846 { 2039 {
2040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2041 return;
2042
1847 Primitive.TextureEntry tex = part.Shape.Textures; 2043 Primitive.TextureEntry tex = part.Shape.Textures;
1848 if (face >= 0 && face < GetNumberOfSides(part)) 2044 if (face >= 0 && face < GetNumberOfSides(part))
1849 { 2045 {
@@ -1880,6 +2076,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1880 2076
1881 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2077 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1882 { 2078 {
2079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2080 return;
2081
1883 Primitive.TextureEntry tex = part.Shape.Textures; 2082 Primitive.TextureEntry tex = part.Shape.Textures;
1884 if (face >= 0 && face < GetNumberOfSides(part)) 2083 if (face >= 0 && face < GetNumberOfSides(part))
1885 { 2084 {
@@ -1984,26 +2183,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1984 return real_vec; 2183 return real_vec;
1985 } 2184 }
1986 2185
2186 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2187 {
2188 return new LSL_Integer(SetRegionPos(m_host, pos));
2189 }
2190
2191 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2192 {
2193 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2194 return 0;
2195
2196 SceneObjectGroup grp = part.ParentGroup;
2197
2198 if (grp.IsAttachment)
2199 return 0;
2200
2201 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2202 return 0;
2203
2204 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)
2205 return 0;
2206
2207 float constrainedX = (float)targetPos.x;
2208 float constrainedY = (float)targetPos.y;
2209
2210 if (constrainedX < 0.0f)
2211 constrainedX = 0.0f;
2212 if (constrainedY < 0.0f)
2213 constrainedY = 0.0f;
2214 if (constrainedX >= (float)Constants.RegionSize)
2215 constrainedX = (float)Constants.RegionSize - 0.1f;
2216 if (constrainedY >= (float)Constants.RegionSize)
2217 constrainedY = (float)Constants.RegionSize -0.1f;
2218
2219 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2220
2221 if (targetPos.z < ground)
2222 targetPos.z = ground;
2223
2224 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2225
2226 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2227 return 0;
2228
2229 grp.UpdateGroupPosition(dest);
2230
2231 return 1;
2232 }
2233
1987 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2234 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1988 { 2235 {
1989 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2236 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2237 return;
2238
1990 LSL_Vector currentPos = GetPartLocalPos(part); 2239 LSL_Vector currentPos = GetPartLocalPos(part);
2240 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1991 2241
1992 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1993 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1994 2242
1995 if (part.ParentGroup.RootPart == part) 2243 if (part.ParentGroup.RootPart == part)
1996 { 2244 {
1997 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1998 targetPos.z = ground;
1999 SceneObjectGroup parent = part.ParentGroup; 2245 SceneObjectGroup parent = part.ParentGroup;
2000 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2246 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2001 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2247 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2248 return;
2249 Util.FireAndForget(delegate(object x) {
2250 parent.UpdateGroupPosition(dest);
2251 });
2002 } 2252 }
2003 else 2253 else
2004 { 2254 {
2005 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2255 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2006 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2007 SceneObjectGroup parent = part.ParentGroup; 2256 SceneObjectGroup parent = part.ParentGroup;
2008 parent.HasGroupChanged = true; 2257 parent.HasGroupChanged = true;
2009 parent.ScheduleGroupForTerseUpdate(); 2258 parent.ScheduleGroupForTerseUpdate();
@@ -2036,17 +2285,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2036 else 2285 else
2037 { 2286 {
2038 if (part.ParentGroup.IsAttachment) 2287 if (part.ParentGroup.IsAttachment)
2039 {
2040 pos = part.AttachedPos; 2288 pos = part.AttachedPos;
2041 }
2042 else 2289 else
2043 {
2044 pos = part.AbsolutePosition; 2290 pos = part.AbsolutePosition;
2045 }
2046 } 2291 }
2047 2292
2048// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2049
2050 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2293 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2051 } 2294 }
2052 2295
@@ -2055,9 +2298,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2055 m_host.AddScriptLPS(1); 2298 m_host.AddScriptLPS(1);
2056 2299
2057 // try to let this work as in SL... 2300 // try to let this work as in SL...
2058 if (m_host.ParentID == 0) 2301 if (m_host.LinkNum < 2)
2059 { 2302 {
2060 // special case: If we are root, rotate complete SOG to new rotation 2303 // Special case: If we are root, rotate complete SOG to new
2304 // rotation.
2305 // We are root if the link number is 0 (single prim) or 1
2306 // (root prim). ParentID may be nonzero in attachments and
2307 // using it would cause attachments and HUDs to rotate
2308 // to the wrong positions.
2061 SetRot(m_host, Rot2Quaternion(rot)); 2309 SetRot(m_host, Rot2Quaternion(rot));
2062 } 2310 }
2063 else 2311 else
@@ -2082,6 +2330,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2082 2330
2083 protected void SetRot(SceneObjectPart part, Quaternion rot) 2331 protected void SetRot(SceneObjectPart part, Quaternion rot)
2084 { 2332 {
2333 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2334 return;
2335
2085 part.UpdateRotation(rot); 2336 part.UpdateRotation(rot);
2086 // Update rotation does not move the object in the physics scene if it's a linkset. 2337 // Update rotation does not move the object in the physics scene if it's a linkset.
2087 2338
@@ -2236,13 +2487,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2236 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2487 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2237 { 2488 {
2238 m_host.AddScriptLPS(1); 2489 m_host.AddScriptLPS(1);
2239 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2490 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2240 } 2491 }
2241 2492
2242 public void llSetTorque(LSL_Vector torque, int local) 2493 public void llSetTorque(LSL_Vector torque, int local)
2243 { 2494 {
2244 m_host.AddScriptLPS(1); 2495 m_host.AddScriptLPS(1);
2245 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2496 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2246 } 2497 }
2247 2498
2248 public LSL_Vector llGetTorque() 2499 public LSL_Vector llGetTorque()
@@ -2707,12 +2958,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2707 2958
2708 m_host.AddScriptLPS(1); 2959 m_host.AddScriptLPS(1);
2709 2960
2961 m_host.TaskInventory.LockItemsForRead(true);
2710 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2962 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2711 2963 m_host.TaskInventory.LockItemsForRead(false);
2712 lock (m_host.TaskInventory)
2713 {
2714 item = m_host.TaskInventory[invItemID];
2715 }
2716 2964
2717 if (item.PermsGranter == UUID.Zero) 2965 if (item.PermsGranter == UUID.Zero)
2718 return 0; 2966 return 0;
@@ -2855,35 +3103,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2855 public void llLookAt(LSL_Vector target, double strength, double damping) 3103 public void llLookAt(LSL_Vector target, double strength, double damping)
2856 { 3104 {
2857 m_host.AddScriptLPS(1); 3105 m_host.AddScriptLPS(1);
2858 // Determine where we are looking from
2859 LSL_Vector from = llGetPos();
2860 3106
2861 // Work out the normalised vector from the source to the target 3107 // Get the normalized vector to the target
2862 LSL_Vector delta = llVecNorm(target - from); 3108 LSL_Vector d1 = llVecNorm(target - llGetPos());
2863 LSL_Vector angle = new LSL_Vector(0,0,0);
2864 3109
2865 // Calculate the yaw 3110 // Get the bearing (yaw)
2866 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3111 LSL_Vector a1 = new LSL_Vector(0,0,0);
2867 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3112 a1.z = llAtan2(d1.y, d1.x);
2868 3113
2869 // Calculate pitch 3114 // Get the elevation (pitch)
2870 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3115 LSL_Vector a2 = new LSL_Vector(0,0,0);
3116 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2871 3117
2872 // we need to convert from a vector describing 3118 LSL_Rotation r1 = llEuler2Rot(a1);
2873 // the angles of rotation in radians into rotation value 3119 LSL_Rotation r2 = llEuler2Rot(a2);
2874 LSL_Rotation rot = llEuler2Rot(angle); 3120 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2875
2876 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2877 // set the rotation of the object, copy that behavior
2878 PhysicsActor pa = m_host.PhysActor;
2879 3121
2880 if (strength == 0 || pa == null || !pa.IsPhysical) 3122 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2881 { 3123 {
2882 llSetRot(rot); 3124 // Do nothing if either value is 0 (this has been checked in SL)
3125 if (strength <= 0.0 || damping <= 0.0)
3126 return;
3127
3128 llSetRot(r3 * r2 * r1);
2883 } 3129 }
2884 else 3130 else
2885 { 3131 {
2886 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3132 if (strength == 0)
3133 {
3134 llSetRot(r3 * r2 * r1);
3135 return;
3136 }
3137
3138 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2887 } 3139 }
2888 } 3140 }
2889 3141
@@ -2928,17 +3180,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2928 } 3180 }
2929 else 3181 else
2930 { 3182 {
2931 if (m_host.IsRoot) 3183 // new SL always returns object mass
2932 { 3184// if (m_host.IsRoot)
3185// {
2933 return m_host.ParentGroup.GetMass(); 3186 return m_host.ParentGroup.GetMass();
2934 } 3187// }
2935 else 3188// else
2936 { 3189// {
2937 return m_host.GetMass(); 3190// return m_host.GetMass();
2938 } 3191// }
2939 } 3192 }
2940 } 3193 }
2941 3194
3195
3196 public LSL_Float llGetMassMKS()
3197 {
3198 return 100f * llGetMass();
3199 }
3200
2942 public void llCollisionFilter(string name, string id, int accept) 3201 public void llCollisionFilter(string name, string id, int accept)
2943 { 3202 {
2944 m_host.AddScriptLPS(1); 3203 m_host.AddScriptLPS(1);
@@ -2957,13 +3216,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2957 { 3216 {
2958 TaskInventoryItem item; 3217 TaskInventoryItem item;
2959 3218
2960 lock (m_host.TaskInventory) 3219 m_host.TaskInventory.LockItemsForRead(true);
3220 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2961 { 3221 {
2962 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3222 m_host.TaskInventory.LockItemsForRead(false);
2963 return; 3223 return;
2964 else
2965 item = m_host.TaskInventory[InventorySelf()];
2966 } 3224 }
3225 else
3226 {
3227 item = m_host.TaskInventory[InventorySelf()];
3228 }
3229 m_host.TaskInventory.LockItemsForRead(false);
2967 3230
2968 if (item.PermsGranter != UUID.Zero) 3231 if (item.PermsGranter != UUID.Zero)
2969 { 3232 {
@@ -2985,13 +3248,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2985 { 3248 {
2986 TaskInventoryItem item; 3249 TaskInventoryItem item;
2987 3250
3251 m_host.TaskInventory.LockItemsForRead(true);
2988 lock (m_host.TaskInventory) 3252 lock (m_host.TaskInventory)
2989 { 3253 {
3254
2990 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3255 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3256 {
3257 m_host.TaskInventory.LockItemsForRead(false);
2991 return; 3258 return;
3259 }
2992 else 3260 else
3261 {
2993 item = m_host.TaskInventory[InventorySelf()]; 3262 item = m_host.TaskInventory[InventorySelf()];
3263 }
2994 } 3264 }
3265 m_host.TaskInventory.LockItemsForRead(false);
2995 3266
2996 m_host.AddScriptLPS(1); 3267 m_host.AddScriptLPS(1);
2997 3268
@@ -3023,19 +3294,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3023 { 3294 {
3024 m_host.AddScriptLPS(1); 3295 m_host.AddScriptLPS(1);
3025 3296
3026// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3027// return;
3028
3029 TaskInventoryItem item; 3297 TaskInventoryItem item;
3030 3298
3031 lock (m_host.TaskInventory) 3299 m_host.TaskInventory.LockItemsForRead(true);
3300
3301 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3032 { 3302 {
3033 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3303 m_host.TaskInventory.LockItemsForRead(false);
3034 return; 3304 return;
3035 else 3305 }
3036 item = m_host.TaskInventory[InventorySelf()]; 3306 else
3307 {
3308 item = m_host.TaskInventory[InventorySelf()];
3037 } 3309 }
3038 3310
3311 m_host.TaskInventory.LockItemsForRead(false);
3312
3039 if (item.PermsGranter != m_host.OwnerID) 3313 if (item.PermsGranter != m_host.OwnerID)
3040 return; 3314 return;
3041 3315
@@ -3060,13 +3334,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3060 3334
3061 TaskInventoryItem item; 3335 TaskInventoryItem item;
3062 3336
3063 lock (m_host.TaskInventory) 3337 m_host.TaskInventory.LockItemsForRead(true);
3338
3339 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3064 { 3340 {
3065 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3341 m_host.TaskInventory.LockItemsForRead(false);
3066 return; 3342 return;
3067 else
3068 item = m_host.TaskInventory[InventorySelf()];
3069 } 3343 }
3344 else
3345 {
3346 item = m_host.TaskInventory[InventorySelf()];
3347 }
3348 m_host.TaskInventory.LockItemsForRead(false);
3349
3070 3350
3071 if (item.PermsGranter != m_host.OwnerID) 3351 if (item.PermsGranter != m_host.OwnerID)
3072 return; 3352 return;
@@ -3113,6 +3393,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3113 3393
3114 public void llInstantMessage(string user, string message) 3394 public void llInstantMessage(string user, string message)
3115 { 3395 {
3396 UUID result;
3397 if (!UUID.TryParse(user, out result))
3398 {
3399 ShoutError("An invalid key was passed to llInstantMessage");
3400 ScriptSleep(2000);
3401 return;
3402 }
3403
3404
3116 m_host.AddScriptLPS(1); 3405 m_host.AddScriptLPS(1);
3117 3406
3118 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3407 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3127,14 +3416,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3127 UUID friendTransactionID = UUID.Random(); 3416 UUID friendTransactionID = UUID.Random();
3128 3417
3129 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3418 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3130 3419
3131 GridInstantMessage msg = new GridInstantMessage(); 3420 GridInstantMessage msg = new GridInstantMessage();
3132 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3421 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3133 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3422 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3134 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3423 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3135// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3424// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3136// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3425// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3137 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3426// DateTime dt = DateTime.UtcNow;
3427//
3428// // Ticks from UtcNow, but make it look like local. Evil, huh?
3429// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3430//
3431// try
3432// {
3433// // Convert that to the PST timezone
3434// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3435// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3436// }
3437// catch
3438// {
3439// // No logging here, as it could be VERY spammy
3440// }
3441//
3442// // And make it look local again to fool the unix time util
3443// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3444
3445 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3446
3138 //if (client != null) 3447 //if (client != null)
3139 //{ 3448 //{
3140 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3449 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3148,12 +3457,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3148 msg.message = message.Substring(0, 1024); 3457 msg.message = message.Substring(0, 1024);
3149 else 3458 else
3150 msg.message = message; 3459 msg.message = message;
3151 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3460 msg.dialog = (byte)19; // MessageFromObject
3152 msg.fromGroup = false;// fromGroup; 3461 msg.fromGroup = false;// fromGroup;
3153 msg.offline = (byte)0; //offline; 3462 msg.offline = (byte)0; //offline;
3154 msg.ParentEstateID = 0; //ParentEstateID; 3463 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3155 msg.Position = new Vector3(m_host.AbsolutePosition); 3464 msg.Position = new Vector3(m_host.AbsolutePosition);
3156 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3465 msg.RegionID = World.RegionInfo.RegionID.Guid;
3157 msg.binaryBucket 3466 msg.binaryBucket
3158 = Util.StringToBytes256( 3467 = Util.StringToBytes256(
3159 "{0}/{1}/{2}/{3}", 3468 "{0}/{1}/{2}/{3}",
@@ -3181,7 +3490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3181 } 3490 }
3182 3491
3183 emailModule.SendEmail(m_host.UUID, address, subject, message); 3492 emailModule.SendEmail(m_host.UUID, address, subject, message);
3184 ScriptSleep(20000); 3493 ScriptSleep(15000);
3185 } 3494 }
3186 3495
3187 public void llGetNextEmail(string address, string subject) 3496 public void llGetNextEmail(string address, string subject)
@@ -3323,14 +3632,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3323 3632
3324 TaskInventoryItem item; 3633 TaskInventoryItem item;
3325 3634
3326 lock (m_host.TaskInventory) 3635 m_host.TaskInventory.LockItemsForRead(true);
3636 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3327 { 3637 {
3328 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3638 m_host.TaskInventory.LockItemsForRead(false);
3329 return; 3639 return;
3330 else
3331 item = m_host.TaskInventory[InventorySelf()];
3332 } 3640 }
3333 3641 else
3642 {
3643 item = m_host.TaskInventory[InventorySelf()];
3644 }
3645 m_host.TaskInventory.LockItemsForRead(false);
3334 if (item.PermsGranter == UUID.Zero) 3646 if (item.PermsGranter == UUID.Zero)
3335 return; 3647 return;
3336 3648
@@ -3360,13 +3672,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3360 3672
3361 TaskInventoryItem item; 3673 TaskInventoryItem item;
3362 3674
3363 lock (m_host.TaskInventory) 3675 m_host.TaskInventory.LockItemsForRead(true);
3676 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3364 { 3677 {
3365 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3678 m_host.TaskInventory.LockItemsForRead(false);
3366 return; 3679 return;
3367 else
3368 item = m_host.TaskInventory[InventorySelf()];
3369 } 3680 }
3681 else
3682 {
3683 item = m_host.TaskInventory[InventorySelf()];
3684 }
3685 m_host.TaskInventory.LockItemsForRead(false);
3686
3370 3687
3371 if (item.PermsGranter == UUID.Zero) 3688 if (item.PermsGranter == UUID.Zero)
3372 return; 3689 return;
@@ -3433,10 +3750,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3433 3750
3434 TaskInventoryItem item; 3751 TaskInventoryItem item;
3435 3752
3436 lock (m_host.TaskInventory) 3753
3754 m_host.TaskInventory.LockItemsForRead(true);
3755 if (!m_host.TaskInventory.ContainsKey(invItemID))
3756 {
3757 m_host.TaskInventory.LockItemsForRead(false);
3758 return;
3759 }
3760 else
3437 { 3761 {
3438 item = m_host.TaskInventory[invItemID]; 3762 item = m_host.TaskInventory[invItemID];
3439 } 3763 }
3764 m_host.TaskInventory.LockItemsForRead(false);
3440 3765
3441 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3766 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3442 { 3767 {
@@ -3464,15 +3789,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3464 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3789 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3465 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3790 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3466 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3791 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3792 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3467 ScriptBaseClass.PERMISSION_ATTACH; 3793 ScriptBaseClass.PERMISSION_ATTACH;
3468 3794
3469 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3795 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3470 { 3796 {
3471 lock (m_host.TaskInventory) 3797 m_host.TaskInventory.LockItemsForWrite(true);
3472 { 3798 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3473 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3799 m_host.TaskInventory[invItemID].PermsMask = perm;
3474 m_host.TaskInventory[invItemID].PermsMask = perm; 3800 m_host.TaskInventory.LockItemsForWrite(false);
3475 }
3476 3801
3477 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3802 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3478 "run_time_permissions", new Object[] { 3803 "run_time_permissions", new Object[] {
@@ -3482,28 +3807,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3482 return; 3807 return;
3483 } 3808 }
3484 } 3809 }
3485 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3810 else
3486 { 3811 {
3487 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3812 bool sitting = false;
3488 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3813 if (m_host.SitTargetAvatar == agentID)
3489 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3814 {
3490 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3815 sitting = true;
3491 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3816 }
3817 else
3818 {
3819 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3820 {
3821 if (p.SitTargetAvatar == agentID)
3822 sitting = true;
3823 }
3824 }
3492 3825
3493 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3826 if (sitting)
3494 { 3827 {
3495 lock (m_host.TaskInventory) 3828 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3829 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3830 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3831 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3832 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3833
3834 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3496 { 3835 {
3836 m_host.TaskInventory.LockItemsForWrite(true);
3497 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3837 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3498 m_host.TaskInventory[invItemID].PermsMask = perm; 3838 m_host.TaskInventory[invItemID].PermsMask = perm;
3499 } 3839 m_host.TaskInventory.LockItemsForWrite(false);
3500 3840
3501 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3841 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3502 "run_time_permissions", new Object[] { 3842 "run_time_permissions", new Object[] {
3503 new LSL_Integer(perm) }, 3843 new LSL_Integer(perm) },
3504 new DetectParams[0])); 3844 new DetectParams[0]));
3505 3845
3506 return; 3846 return;
3847 }
3507 } 3848 }
3508 } 3849 }
3509 3850
@@ -3517,11 +3858,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3517 3858
3518 if (!m_waitingForScriptAnswer) 3859 if (!m_waitingForScriptAnswer)
3519 { 3860 {
3520 lock (m_host.TaskInventory) 3861 m_host.TaskInventory.LockItemsForWrite(true);
3521 { 3862 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3522 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3863 m_host.TaskInventory[invItemID].PermsMask = 0;
3523 m_host.TaskInventory[invItemID].PermsMask = 0; 3864 m_host.TaskInventory.LockItemsForWrite(false);
3524 }
3525 3865
3526 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3866 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3527 m_waitingForScriptAnswer=true; 3867 m_waitingForScriptAnswer=true;
@@ -3556,10 +3896,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3556 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3896 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3557 llReleaseControls(); 3897 llReleaseControls();
3558 3898
3559 lock (m_host.TaskInventory) 3899
3560 { 3900 m_host.TaskInventory.LockItemsForWrite(true);
3561 m_host.TaskInventory[invItemID].PermsMask = answer; 3901 m_host.TaskInventory[invItemID].PermsMask = answer;
3562 } 3902 m_host.TaskInventory.LockItemsForWrite(false);
3903
3563 3904
3564 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3905 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3565 "run_time_permissions", new Object[] { 3906 "run_time_permissions", new Object[] {
@@ -3571,16 +3912,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3571 { 3912 {
3572 m_host.AddScriptLPS(1); 3913 m_host.AddScriptLPS(1);
3573 3914
3574 lock (m_host.TaskInventory) 3915 m_host.TaskInventory.LockItemsForRead(true);
3916
3917 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3575 { 3918 {
3576 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3919 if (item.Type == 10 && item.ItemID == m_itemID)
3577 { 3920 {
3578 if (item.Type == 10 && item.ItemID == m_itemID) 3921 m_host.TaskInventory.LockItemsForRead(false);
3579 { 3922 return item.PermsGranter.ToString();
3580 return item.PermsGranter.ToString();
3581 }
3582 } 3923 }
3583 } 3924 }
3925 m_host.TaskInventory.LockItemsForRead(false);
3584 3926
3585 return UUID.Zero.ToString(); 3927 return UUID.Zero.ToString();
3586 } 3928 }
@@ -3589,19 +3931,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3589 { 3931 {
3590 m_host.AddScriptLPS(1); 3932 m_host.AddScriptLPS(1);
3591 3933
3592 lock (m_host.TaskInventory) 3934 m_host.TaskInventory.LockItemsForRead(true);
3935
3936 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3593 { 3937 {
3594 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3938 if (item.Type == 10 && item.ItemID == m_itemID)
3595 { 3939 {
3596 if (item.Type == 10 && item.ItemID == m_itemID) 3940 int perms = item.PermsMask;
3597 { 3941 if (m_automaticLinkPermission)
3598 int perms = item.PermsMask; 3942 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3599 if (m_automaticLinkPermission) 3943 m_host.TaskInventory.LockItemsForRead(false);
3600 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3944 return perms;
3601 return perms;
3602 }
3603 } 3945 }
3604 } 3946 }
3947 m_host.TaskInventory.LockItemsForRead(false);
3605 3948
3606 return 0; 3949 return 0;
3607 } 3950 }
@@ -3623,9 +3966,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3623 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3966 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3624 { 3967 {
3625 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3968 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3626 3969 if (parts.Count > 0)
3627 foreach (SceneObjectPart part in parts) 3970 {
3628 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3971 try
3972 {
3973 parts[0].ParentGroup.areUpdatesSuspended = true;
3974 foreach (SceneObjectPart part in parts)
3975 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3976 }
3977 finally
3978 {
3979 parts[0].ParentGroup.areUpdatesSuspended = false;
3980 }
3981 }
3629 } 3982 }
3630 3983
3631 public void llCreateLink(string target, int parent) 3984 public void llCreateLink(string target, int parent)
@@ -3638,11 +3991,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3638 return; 3991 return;
3639 3992
3640 TaskInventoryItem item; 3993 TaskInventoryItem item;
3641 lock (m_host.TaskInventory) 3994 m_host.TaskInventory.LockItemsForRead(true);
3642 { 3995 item = m_host.TaskInventory[invItemID];
3643 item = m_host.TaskInventory[invItemID]; 3996 m_host.TaskInventory.LockItemsForRead(false);
3644 } 3997
3645
3646 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3998 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3647 && !m_automaticLinkPermission) 3999 && !m_automaticLinkPermission)
3648 { 4000 {
@@ -3659,11 +4011,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3659 4011
3660 if (targetPart.ParentGroup.AttachmentPoint != 0) 4012 if (targetPart.ParentGroup.AttachmentPoint != 0)
3661 return; // Fail silently if attached 4013 return; // Fail silently if attached
4014
4015 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
4016 return;
4017
3662 SceneObjectGroup parentPrim = null, childPrim = null; 4018 SceneObjectGroup parentPrim = null, childPrim = null;
3663 4019
3664 if (targetPart != null) 4020 if (targetPart != null)
3665 { 4021 {
3666 if (parent != 0) { 4022 if (parent != 0)
4023 {
3667 parentPrim = m_host.ParentGroup; 4024 parentPrim = m_host.ParentGroup;
3668 childPrim = targetPart.ParentGroup; 4025 childPrim = targetPart.ParentGroup;
3669 } 4026 }
@@ -3675,7 +4032,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3675 4032
3676 // Required for linking 4033 // Required for linking
3677 childPrim.RootPart.ClearUpdateSchedule(); 4034 childPrim.RootPart.ClearUpdateSchedule();
3678 parentPrim.LinkToGroup(childPrim); 4035 parentPrim.LinkToGroup(childPrim, true);
3679 } 4036 }
3680 4037
3681 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4038 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3694,16 +4051,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3694 m_host.AddScriptLPS(1); 4051 m_host.AddScriptLPS(1);
3695 UUID invItemID = InventorySelf(); 4052 UUID invItemID = InventorySelf();
3696 4053
3697 lock (m_host.TaskInventory) 4054 m_host.TaskInventory.LockItemsForRead(true);
3698 {
3699 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 4055 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3700 && !m_automaticLinkPermission) 4056 && !m_automaticLinkPermission)
3701 { 4057 {
3702 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 4058 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4059 m_host.TaskInventory.LockItemsForRead(false);
3703 return; 4060 return;
3704 } 4061 }
3705 } 4062 m_host.TaskInventory.LockItemsForRead(false);
3706 4063
3707 if (linknum < ScriptBaseClass.LINK_THIS) 4064 if (linknum < ScriptBaseClass.LINK_THIS)
3708 return; 4065 return;
3709 4066
@@ -3742,10 +4099,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3742 // Restructuring Multiple Prims. 4099 // Restructuring Multiple Prims.
3743 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4100 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3744 parts.Remove(parentPrim.RootPart); 4101 parts.Remove(parentPrim.RootPart);
3745 foreach (SceneObjectPart part in parts) 4102 if (parts.Count > 0)
3746 { 4103 {
3747 parentPrim.DelinkFromGroup(part.LocalId, true); 4104 try
4105 {
4106 parts[0].ParentGroup.areUpdatesSuspended = true;
4107 foreach (SceneObjectPart part in parts)
4108 {
4109 parentPrim.DelinkFromGroup(part.LocalId, true);
4110 }
4111 }
4112 finally
4113 {
4114 parts[0].ParentGroup.areUpdatesSuspended = false;
4115 }
3748 } 4116 }
4117
3749 parentPrim.HasGroupChanged = true; 4118 parentPrim.HasGroupChanged = true;
3750 parentPrim.ScheduleGroupForFullUpdate(); 4119 parentPrim.ScheduleGroupForFullUpdate();
3751 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4120 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3754,12 +4123,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3754 { 4123 {
3755 SceneObjectPart newRoot = parts[0]; 4124 SceneObjectPart newRoot = parts[0];
3756 parts.Remove(newRoot); 4125 parts.Remove(newRoot);
3757 foreach (SceneObjectPart part in parts) 4126
4127 try
3758 { 4128 {
3759 // Required for linking 4129 parts[0].ParentGroup.areUpdatesSuspended = true;
3760 part.ClearUpdateSchedule(); 4130 foreach (SceneObjectPart part in parts)
3761 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4131 {
4132 part.ClearUpdateSchedule();
4133 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4134 }
3762 } 4135 }
4136 finally
4137 {
4138 parts[0].ParentGroup.areUpdatesSuspended = false;
4139 }
4140
4141
3763 newRoot.ParentGroup.HasGroupChanged = true; 4142 newRoot.ParentGroup.HasGroupChanged = true;
3764 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4143 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3765 } 4144 }
@@ -3779,6 +4158,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3779 public void llBreakAllLinks() 4158 public void llBreakAllLinks()
3780 { 4159 {
3781 m_host.AddScriptLPS(1); 4160 m_host.AddScriptLPS(1);
4161
4162 UUID invItemID = InventorySelf();
4163
4164 TaskInventoryItem item;
4165 m_host.TaskInventory.LockItemsForRead(true);
4166 item = m_host.TaskInventory[invItemID];
4167 m_host.TaskInventory.LockItemsForRead(false);
4168
4169 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4170 && !m_automaticLinkPermission)
4171 {
4172 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4173 return;
4174 }
4175
3782 SceneObjectGroup parentPrim = m_host.ParentGroup; 4176 SceneObjectGroup parentPrim = m_host.ParentGroup;
3783 if (parentPrim.AttachmentPoint != 0) 4177 if (parentPrim.AttachmentPoint != 0)
3784 return; // Fail silently if attached 4178 return; // Fail silently if attached
@@ -3798,25 +4192,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3798 public LSL_String llGetLinkKey(int linknum) 4192 public LSL_String llGetLinkKey(int linknum)
3799 { 4193 {
3800 m_host.AddScriptLPS(1); 4194 m_host.AddScriptLPS(1);
3801 List<UUID> keytable = new List<UUID>();
3802 // parse for sitting avatare-uuids
3803 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3804 {
3805 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3806 keytable.Add(presence.UUID);
3807 });
3808
3809 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3810 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3811 {
3812 return keytable[totalprims - linknum].ToString();
3813 }
3814
3815 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3816 {
3817 return m_host.UUID.ToString();
3818 }
3819
3820 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4195 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3821 if (part != null) 4196 if (part != null)
3822 { 4197 {
@@ -3824,6 +4199,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3824 } 4199 }
3825 else 4200 else
3826 { 4201 {
4202 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4203 {
4204 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4205
4206 if (linknum < 0)
4207 return UUID.Zero.ToString();
4208
4209 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4210 if (avatars.Count > linknum)
4211 {
4212 return avatars[linknum].UUID.ToString();
4213 }
4214 }
3827 return UUID.Zero.ToString(); 4215 return UUID.Zero.ToString();
3828 } 4216 }
3829 } 4217 }
@@ -3923,17 +4311,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3923 m_host.AddScriptLPS(1); 4311 m_host.AddScriptLPS(1);
3924 int count = 0; 4312 int count = 0;
3925 4313
3926 lock (m_host.TaskInventory) 4314 m_host.TaskInventory.LockItemsForRead(true);
4315 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3927 { 4316 {
3928 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4317 if (inv.Value.Type == type || type == -1)
3929 { 4318 {
3930 if (inv.Value.Type == type || type == -1) 4319 count = count + 1;
3931 {
3932 count = count + 1;
3933 }
3934 } 4320 }
3935 } 4321 }
3936 4322
4323 m_host.TaskInventory.LockItemsForRead(false);
3937 return count; 4324 return count;
3938 } 4325 }
3939 4326
@@ -3942,16 +4329,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3942 m_host.AddScriptLPS(1); 4329 m_host.AddScriptLPS(1);
3943 ArrayList keys = new ArrayList(); 4330 ArrayList keys = new ArrayList();
3944 4331
3945 lock (m_host.TaskInventory) 4332 m_host.TaskInventory.LockItemsForRead(true);
4333 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3946 { 4334 {
3947 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4335 if (inv.Value.Type == type || type == -1)
3948 { 4336 {
3949 if (inv.Value.Type == type || type == -1) 4337 keys.Add(inv.Value.Name);
3950 {
3951 keys.Add(inv.Value.Name);
3952 }
3953 } 4338 }
3954 } 4339 }
4340 m_host.TaskInventory.LockItemsForRead(false);
3955 4341
3956 if (keys.Count == 0) 4342 if (keys.Count == 0)
3957 { 4343 {
@@ -3988,25 +4374,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3988 } 4374 }
3989 4375
3990 // move the first object found with this inventory name 4376 // move the first object found with this inventory name
3991 lock (m_host.TaskInventory) 4377 m_host.TaskInventory.LockItemsForRead(true);
4378 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3992 { 4379 {
3993 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4380 if (inv.Value.Name == inventory)
3994 { 4381 {
3995 if (inv.Value.Name == inventory) 4382 found = true;
3996 { 4383 objId = inv.Key;
3997 found = true; 4384 assetType = inv.Value.Type;
3998 objId = inv.Key; 4385 objName = inv.Value.Name;
3999 assetType = inv.Value.Type; 4386 break;
4000 objName = inv.Value.Name;
4001 break;
4002 }
4003 } 4387 }
4004 } 4388 }
4389 m_host.TaskInventory.LockItemsForRead(false);
4005 4390
4006 if (!found) 4391 if (!found)
4007 { 4392 {
4008 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4393 llSay(0, String.Format("Could not find object '{0}'", inventory));
4009 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4394 return;
4395// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4010 } 4396 }
4011 4397
4012 // check if destination is an object 4398 // check if destination is an object
@@ -4032,48 +4418,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4032 return; 4418 return;
4033 } 4419 }
4034 } 4420 }
4421
4035 // destination is an avatar 4422 // destination is an avatar
4036 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4423 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4037 4424
4038 if (agentItem == null) 4425 if (agentItem == null)
4039 return; 4426 return;
4040 4427
4041 byte[] bucket = new byte[17]; 4428 byte[] bucket = new byte[1];
4042 bucket[0] = (byte)assetType; 4429 bucket[0] = (byte)assetType;
4043 byte[] objBytes = agentItem.ID.GetBytes(); 4430 //byte[] objBytes = agentItem.ID.GetBytes();
4044 Array.Copy(objBytes, 0, bucket, 1, 16); 4431 //Array.Copy(objBytes, 0, bucket, 1, 16);
4045 4432
4046 GridInstantMessage msg = new GridInstantMessage(World, 4433 GridInstantMessage msg = new GridInstantMessage(World,
4047 m_host.UUID, m_host.Name+", an object owned by "+ 4434 m_host.OwnerID, m_host.Name, destId,
4048 resolveName(m_host.OwnerID)+",", destId,
4049 (byte)InstantMessageDialog.TaskInventoryOffered, 4435 (byte)InstantMessageDialog.TaskInventoryOffered,
4050 false, objName+"\n"+m_host.Name+" is located at "+ 4436 false, objName+". "+m_host.Name+" is located at "+
4051 World.RegionInfo.RegionName+" "+ 4437 World.RegionInfo.RegionName+" "+
4052 m_host.AbsolutePosition.ToString(), 4438 m_host.AbsolutePosition.ToString(),
4053 agentItem.ID, true, m_host.AbsolutePosition, 4439 agentItem.ID, true, m_host.AbsolutePosition,
4054 bucket); 4440 bucket);
4055 if (m_TransferModule != null) 4441
4056 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4442 ScenePresence sp;
4443
4444 if (World.TryGetScenePresence(destId, out sp))
4445 {
4446 sp.ControllingClient.SendInstantMessage(msg);
4447 }
4448 else
4449 {
4450 if (m_TransferModule != null)
4451 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4452 }
4453
4454 //This delay should only occur when giving inventory to avatars.
4057 ScriptSleep(3000); 4455 ScriptSleep(3000);
4058 } 4456 }
4059 } 4457 }
4060 4458
4459 [DebuggerNonUserCode]
4061 public void llRemoveInventory(string name) 4460 public void llRemoveInventory(string name)
4062 { 4461 {
4063 m_host.AddScriptLPS(1); 4462 m_host.AddScriptLPS(1);
4064 4463
4065 lock (m_host.TaskInventory) 4464 List<TaskInventoryItem> inv;
4465 try
4066 { 4466 {
4067 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4467 m_host.TaskInventory.LockItemsForRead(true);
4468 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4469 }
4470 finally
4471 {
4472 m_host.TaskInventory.LockItemsForRead(false);
4473 }
4474 foreach (TaskInventoryItem item in inv)
4475 {
4476 if (item.Name == name)
4068 { 4477 {
4069 if (item.Name == name) 4478 if (item.ItemID == m_itemID)
4070 { 4479 throw new ScriptDeleteException();
4071 if (item.ItemID == m_itemID) 4480 else
4072 throw new ScriptDeleteException(); 4481 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4073 else 4482 return;
4074 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4075 return;
4076 }
4077 } 4483 }
4078 } 4484 }
4079 } 4485 }
@@ -4108,115 +4514,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4108 { 4514 {
4109 m_host.AddScriptLPS(1); 4515 m_host.AddScriptLPS(1);
4110 4516
4111 UUID uuid = (UUID)id; 4517 UUID uuid;
4112 PresenceInfo pinfo = null; 4518 if (UUID.TryParse(id, out uuid))
4113 UserAccount account;
4114
4115 UserInfoCacheEntry ce;
4116 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4117 { 4519 {
4118 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4520 PresenceInfo pinfo = null;
4119 if (account == null) 4521 UserAccount account;
4522
4523 UserInfoCacheEntry ce;
4524 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4120 { 4525 {
4121 m_userInfoCache[uuid] = null; // Cache negative 4526 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4122 return UUID.Zero.ToString(); 4527 if (account == null)
4123 } 4528 {
4529 m_userInfoCache[uuid] = null; // Cache negative
4530 return UUID.Zero.ToString();
4531 }
4124 4532
4125 4533
4126 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4534 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4127 if (pinfos != null && pinfos.Length > 0) 4535 if (pinfos != null && pinfos.Length > 0)
4128 {
4129 foreach (PresenceInfo p in pinfos)
4130 { 4536 {
4131 if (p.RegionID != UUID.Zero) 4537 foreach (PresenceInfo p in pinfos)
4132 { 4538 {
4133 pinfo = p; 4539 if (p.RegionID != UUID.Zero)
4540 {
4541 pinfo = p;
4542 }
4134 } 4543 }
4135 } 4544 }
4136 }
4137 4545
4138 ce = new UserInfoCacheEntry(); 4546 ce = new UserInfoCacheEntry();
4139 ce.time = Util.EnvironmentTickCount(); 4547 ce.time = Util.EnvironmentTickCount();
4140 ce.account = account; 4548 ce.account = account;
4141 ce.pinfo = pinfo; 4549 ce.pinfo = pinfo;
4142 } 4550 m_userInfoCache[uuid] = ce;
4143 else 4551 }
4144 { 4552 else
4145 if (ce == null) 4553 {
4146 return UUID.Zero.ToString(); 4554 if (ce == null)
4555 return UUID.Zero.ToString();
4147 4556
4148 account = ce.account; 4557 account = ce.account;
4149 pinfo = ce.pinfo; 4558 pinfo = ce.pinfo;
4150 } 4559 }
4151 4560
4152 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4561 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4153 {
4154 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4155 if (pinfos != null && pinfos.Length > 0)
4156 { 4562 {
4157 foreach (PresenceInfo p in pinfos) 4563 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4564 if (pinfos != null && pinfos.Length > 0)
4158 { 4565 {
4159 if (p.RegionID != UUID.Zero) 4566 foreach (PresenceInfo p in pinfos)
4160 { 4567 {
4161 pinfo = p; 4568 if (p.RegionID != UUID.Zero)
4569 {
4570 pinfo = p;
4571 }
4162 } 4572 }
4163 } 4573 }
4164 } 4574 else
4165 else 4575 pinfo = null;
4166 pinfo = null;
4167 4576
4168 ce.time = Util.EnvironmentTickCount(); 4577 ce.time = Util.EnvironmentTickCount();
4169 ce.pinfo = pinfo; 4578 ce.pinfo = pinfo;
4170 } 4579 }
4171 4580
4172 string reply = String.Empty; 4581 string reply = String.Empty;
4173 4582
4174 switch (data) 4583 switch (data)
4175 { 4584 {
4176 case 1: // DATA_ONLINE (0|1) 4585 case 1: // DATA_ONLINE (0|1)
4177 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4586 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4178 reply = "1"; 4587 reply = "1";
4179 else 4588 else
4180 reply = "0"; 4589 reply = "0";
4181 break; 4590 break;
4182 case 2: // DATA_NAME (First Last) 4591 case 2: // DATA_NAME (First Last)
4183 reply = account.FirstName + " " + account.LastName; 4592 reply = account.FirstName + " " + account.LastName;
4184 break; 4593 break;
4185 case 3: // DATA_BORN (YYYY-MM-DD) 4594 case 3: // DATA_BORN (YYYY-MM-DD)
4186 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4595 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4187 born = born.AddSeconds(account.Created); 4596 born = born.AddSeconds(account.Created);
4188 reply = born.ToString("yyyy-MM-dd"); 4597 reply = born.ToString("yyyy-MM-dd");
4189 break; 4598 break;
4190 case 4: // DATA_RATING (0,0,0,0,0,0) 4599 case 4: // DATA_RATING (0,0,0,0,0,0)
4191 reply = "0,0,0,0,0,0"; 4600 reply = "0,0,0,0,0,0";
4192 break; 4601 break;
4193 case 7: // DATA_USERLEVEL (integer) 4602 case 8: // DATA_PAYINFO (0|1|2|3)
4194 reply = account.UserLevel.ToString(); 4603 reply = "0";
4195 break; 4604 break;
4196 case 8: // DATA_PAYINFO (0|1|2|3) 4605 default:
4197 reply = "0"; 4606 return UUID.Zero.ToString(); // Raise no event
4198 break; 4607 }
4199 default:
4200 return UUID.Zero.ToString(); // Raise no event
4201 }
4202 4608
4203 UUID rq = UUID.Random(); 4609 UUID rq = UUID.Random();
4204 4610
4205 UUID tid = AsyncCommands. 4611 UUID tid = AsyncCommands.
4206 DataserverPlugin.RegisterRequest(m_localID, 4612 DataserverPlugin.RegisterRequest(m_localID,
4207 m_itemID, rq.ToString()); 4613 m_itemID, rq.ToString());
4208 4614
4209 AsyncCommands. 4615 AsyncCommands.
4210 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4616 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4211 4617
4212 ScriptSleep(100); 4618 ScriptSleep(100);
4213 return tid.ToString(); 4619 return tid.ToString();
4620 }
4621 else
4622 {
4623 ShoutError("Invalid UUID passed to llRequestAgentData.");
4624 }
4625 return "";
4214 } 4626 }
4215 4627
4216 public LSL_String llRequestInventoryData(string name) 4628 public LSL_String llRequestInventoryData(string name)
4217 { 4629 {
4218 m_host.AddScriptLPS(1); 4630 m_host.AddScriptLPS(1);
4219 4631
4632 //Clone is thread safe
4220 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4633 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4221 4634
4222 foreach (TaskInventoryItem item in itemDictionary.Values) 4635 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4268,19 +4681,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4268 if (UUID.TryParse(agent, out agentId)) 4681 if (UUID.TryParse(agent, out agentId))
4269 { 4682 {
4270 ScenePresence presence = World.GetScenePresence(agentId); 4683 ScenePresence presence = World.GetScenePresence(agentId);
4271 if (presence != null) 4684 if (presence != null && presence.PresenceType != PresenceType.Npc)
4272 { 4685 {
4686 // agent must not be a god
4687 if (presence.UserLevel >= 200) return;
4688
4273 // agent must be over the owners land 4689 // agent must be over the owners land
4274 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4690 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4275 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4691 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4276 { 4692 {
4277 World.TeleportClientHome(agentId, presence.ControllingClient); 4693 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4694 {
4695 // They can't be teleported home for some reason
4696 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4697 if (regionInfo != null)
4698 {
4699 World.RequestTeleportLocation(
4700 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4701 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4702 }
4703 }
4278 } 4704 }
4279 } 4705 }
4280 } 4706 }
4281 ScriptSleep(5000); 4707 ScriptSleep(5000);
4282 } 4708 }
4283 4709
4710 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4711 {
4712 m_host.AddScriptLPS(1);
4713 UUID agentId = new UUID();
4714 if (UUID.TryParse(agent, out agentId))
4715 {
4716 ScenePresence presence = World.GetScenePresence(agentId);
4717 if (presence != null && presence.PresenceType != PresenceType.Npc)
4718 {
4719 // agent must not be a god
4720 if (presence.GodLevel >= 200) return;
4721
4722 if (simname == String.Empty)
4723 simname = World.RegionInfo.RegionName;
4724
4725 // agent must be over the owners land
4726 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4727 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4728 {
4729 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);
4730 }
4731 else // or must be wearing the prim
4732 {
4733 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4734 {
4735 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);
4736 }
4737 }
4738 }
4739 }
4740 }
4741
4284 public void llTextBox(string agent, string message, int chatChannel) 4742 public void llTextBox(string agent, string message, int chatChannel)
4285 { 4743 {
4286 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4744 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4292,7 +4750,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4292 UUID av = new UUID(); 4750 UUID av = new UUID();
4293 if (!UUID.TryParse(agent,out av)) 4751 if (!UUID.TryParse(agent,out av))
4294 { 4752 {
4295 LSLError("First parameter to llDialog needs to be a key"); 4753 //LSLError("First parameter to llDialog needs to be a key");
4296 return; 4754 return;
4297 } 4755 }
4298 4756
@@ -4329,17 +4787,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4329 UUID soundId = UUID.Zero; 4787 UUID soundId = UUID.Zero;
4330 if (!UUID.TryParse(impact_sound, out soundId)) 4788 if (!UUID.TryParse(impact_sound, out soundId))
4331 { 4789 {
4332 lock (m_host.TaskInventory) 4790 m_host.TaskInventory.LockItemsForRead(true);
4791 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4333 { 4792 {
4334 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4793 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4335 { 4794 {
4336 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4795 soundId = item.AssetID;
4337 { 4796 break;
4338 soundId = item.AssetID;
4339 break;
4340 }
4341 } 4797 }
4342 } 4798 }
4799 m_host.TaskInventory.LockItemsForRead(false);
4343 } 4800 }
4344 m_host.CollisionSound = soundId; 4801 m_host.CollisionSound = soundId;
4345 m_host.CollisionSoundVolume = (float)impact_volume; 4802 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4379,6 +4836,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4379 UUID partItemID; 4836 UUID partItemID;
4380 foreach (SceneObjectPart part in parts) 4837 foreach (SceneObjectPart part in parts)
4381 { 4838 {
4839 //Clone is thread safe
4382 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4840 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4383 4841
4384 foreach (TaskInventoryItem item in itemsDictionary.Values) 4842 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4512,7 +4970,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4512 { 4970 {
4513 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4971 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4514 float distance_term = distance * distance * distance; // Script Energy 4972 float distance_term = distance * distance * distance; // Script Energy
4515 float pusher_mass = m_host.GetMass(); 4973 // use total object mass and not part
4974 float pusher_mass = m_host.ParentGroup.GetMass();
4516 4975
4517 float PUSH_ATTENUATION_DISTANCE = 17f; 4976 float PUSH_ATTENUATION_DISTANCE = 17f;
4518 float PUSH_ATTENUATION_SCALE = 5f; 4977 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4582,17 +5041,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4582 5041
4583 m_host.AddScriptLPS(1); 5042 m_host.AddScriptLPS(1);
4584 5043
4585 lock (m_host.TaskInventory) 5044 m_host.TaskInventory.LockItemsForRead(true);
5045 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4586 { 5046 {
4587 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 5047 if (item.Type == 10 && item.ItemID == m_itemID)
4588 { 5048 {
4589 if (item.Type == 10 && item.ItemID == m_itemID) 5049 result = item.Name!=null?item.Name:String.Empty;
4590 { 5050 break;
4591 result = item.Name != null ? item.Name : String.Empty;
4592 break;
4593 }
4594 } 5051 }
4595 } 5052 }
5053 m_host.TaskInventory.LockItemsForRead(false);
4596 5054
4597 return result; 5055 return result;
4598 } 5056 }
@@ -4765,23 +5223,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4765 { 5223 {
4766 m_host.AddScriptLPS(1); 5224 m_host.AddScriptLPS(1);
4767 5225
4768 lock (m_host.TaskInventory) 5226 m_host.TaskInventory.LockItemsForRead(true);
5227 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4769 { 5228 {
4770 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5229 if (inv.Value.Name == name)
4771 { 5230 {
4772 if (inv.Value.Name == name) 5231 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4773 { 5232 {
4774 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5233 m_host.TaskInventory.LockItemsForRead(false);
4775 { 5234 return inv.Value.AssetID.ToString();
4776 return inv.Value.AssetID.ToString(); 5235 }
4777 } 5236 else
4778 else 5237 {
4779 { 5238 m_host.TaskInventory.LockItemsForRead(false);
4780 return UUID.Zero.ToString(); 5239 return UUID.Zero.ToString();
4781 }
4782 } 5240 }
4783 } 5241 }
4784 } 5242 }
5243 m_host.TaskInventory.LockItemsForRead(false);
4785 5244
4786 return UUID.Zero.ToString(); 5245 return UUID.Zero.ToString();
4787 } 5246 }
@@ -4934,14 +5393,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4934 { 5393 {
4935 m_host.AddScriptLPS(1); 5394 m_host.AddScriptLPS(1);
4936 5395
4937 if (src == null) 5396 return src.Length;
4938 {
4939 return 0;
4940 }
4941 else
4942 {
4943 return src.Length;
4944 }
4945 } 5397 }
4946 5398
4947 public LSL_Integer llList2Integer(LSL_List src, int index) 5399 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4987,7 +5439,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4987 else if (src.Data[index] is LSL_Float) 5439 else if (src.Data[index] is LSL_Float)
4988 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5440 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4989 else if (src.Data[index] is LSL_String) 5441 else if (src.Data[index] is LSL_String)
4990 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5442 {
5443 string str = ((LSL_String) src.Data[index]).m_string;
5444 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5445 if (m != Match.Empty)
5446 {
5447 str = m.Value;
5448 double d = 0.0;
5449 if (!Double.TryParse(str, out d))
5450 return 0.0;
5451
5452 return d;
5453 }
5454 return 0.0;
5455 }
4991 return Convert.ToDouble(src.Data[index]); 5456 return Convert.ToDouble(src.Data[index]);
4992 } 5457 }
4993 catch (FormatException) 5458 catch (FormatException)
@@ -5260,7 +5725,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5260 } 5725 }
5261 } 5726 }
5262 } 5727 }
5263 else { 5728 else
5729 {
5264 object[] array = new object[src.Length]; 5730 object[] array = new object[src.Length];
5265 Array.Copy(src.Data, 0, array, 0, src.Length); 5731 Array.Copy(src.Data, 0, array, 0, src.Length);
5266 result = new LSL_List(array); 5732 result = new LSL_List(array);
@@ -5367,7 +5833,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5367 public LSL_Integer llGetRegionAgentCount() 5833 public LSL_Integer llGetRegionAgentCount()
5368 { 5834 {
5369 m_host.AddScriptLPS(1); 5835 m_host.AddScriptLPS(1);
5370 return new LSL_Integer(World.GetRootAgentCount()); 5836
5837 int count = 0;
5838 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5839 count++;
5840 });
5841
5842 return new LSL_Integer(count);
5371 } 5843 }
5372 5844
5373 public LSL_Vector llGetRegionCorner() 5845 public LSL_Vector llGetRegionCorner()
@@ -5647,6 +6119,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5647 flags |= ScriptBaseClass.AGENT_SITTING; 6119 flags |= ScriptBaseClass.AGENT_SITTING;
5648 } 6120 }
5649 6121
6122 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6123 {
6124 flags |= ScriptBaseClass.AGENT_MALE;
6125 }
6126
5650 return flags; 6127 return flags;
5651 } 6128 }
5652 6129
@@ -5709,10 +6186,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5709 m_host.AddScriptLPS(1); 6186 m_host.AddScriptLPS(1);
5710 6187
5711 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6188 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5712 6189 if (parts.Count > 0)
5713 foreach (var part in parts)
5714 { 6190 {
5715 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6191 try
6192 {
6193 parts[0].ParentGroup.areUpdatesSuspended = true;
6194 foreach (var part in parts)
6195 {
6196 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6197 }
6198 }
6199 finally
6200 {
6201 parts[0].ParentGroup.areUpdatesSuspended = false;
6202 }
5716 } 6203 }
5717 } 6204 }
5718 6205
@@ -5764,13 +6251,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5764 6251
5765 if (m_host.OwnerID == land.LandData.OwnerID) 6252 if (m_host.OwnerID == land.LandData.OwnerID)
5766 { 6253 {
5767 World.TeleportClientHome(agentID, presence.ControllingClient); 6254 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6255 presence.TeleportWithMomentum(pos);
6256 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5768 } 6257 }
5769 } 6258 }
5770 } 6259 }
5771 ScriptSleep(5000); 6260 ScriptSleep(5000);
5772 } 6261 }
5773 6262
6263 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6264 {
6265 return ParseString2List(str, separators, in_spacers, false);
6266 }
6267
5774 public LSL_Integer llOverMyLand(string id) 6268 public LSL_Integer llOverMyLand(string id)
5775 { 6269 {
5776 m_host.AddScriptLPS(1); 6270 m_host.AddScriptLPS(1);
@@ -5835,8 +6329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5835 UUID agentId = new UUID(); 6329 UUID agentId = new UUID();
5836 if (!UUID.TryParse(agent, out agentId)) 6330 if (!UUID.TryParse(agent, out agentId))
5837 return new LSL_Integer(0); 6331 return new LSL_Integer(0);
6332 if (agentId == m_host.GroupID)
6333 return new LSL_Integer(1);
5838 ScenePresence presence = World.GetScenePresence(agentId); 6334 ScenePresence presence = World.GetScenePresence(agentId);
5839 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6335 if (presence == null || presence.IsChildAgent) // Return false for child agents
5840 return new LSL_Integer(0); 6336 return new LSL_Integer(0);
5841 IClientAPI client = presence.ControllingClient; 6337 IClientAPI client = presence.ControllingClient;
5842 if (m_host.GroupID == client.ActiveGroupId) 6338 if (m_host.GroupID == client.ActiveGroupId)
@@ -5971,7 +6467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5971 return m_host.ParentGroup.AttachmentPoint; 6467 return m_host.ParentGroup.AttachmentPoint;
5972 } 6468 }
5973 6469
5974 public LSL_Integer llGetFreeMemory() 6470 public virtual LSL_Integer llGetFreeMemory()
5975 { 6471 {
5976 m_host.AddScriptLPS(1); 6472 m_host.AddScriptLPS(1);
5977 // Make scripts designed for LSO happy 6473 // Make scripts designed for LSO happy
@@ -6088,7 +6584,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6088 SetParticleSystem(m_host, rules); 6584 SetParticleSystem(m_host, rules);
6089 } 6585 }
6090 6586
6091 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6587 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6588 {
6092 6589
6093 6590
6094 if (rules.Length == 0) 6591 if (rules.Length == 0)
@@ -6282,14 +6779,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6282 6779
6283 protected UUID GetTaskInventoryItem(string name) 6780 protected UUID GetTaskInventoryItem(string name)
6284 { 6781 {
6285 lock (m_host.TaskInventory) 6782 m_host.TaskInventory.LockItemsForRead(true);
6783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6286 { 6784 {
6287 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6785 if (inv.Value.Name == name)
6288 { 6786 {
6289 if (inv.Value.Name == name) 6787 m_host.TaskInventory.LockItemsForRead(false);
6290 return inv.Key; 6788 return inv.Key;
6291 } 6789 }
6292 } 6790 }
6791 m_host.TaskInventory.LockItemsForRead(false);
6293 6792
6294 return UUID.Zero; 6793 return UUID.Zero;
6295 } 6794 }
@@ -6327,16 +6826,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6327 if (folderID == UUID.Zero) 6826 if (folderID == UUID.Zero)
6328 return; 6827 return;
6329 6828
6330 byte[] bucket = new byte[17]; 6829 byte[] bucket = new byte[1];
6331 bucket[0] = (byte)AssetType.Folder; 6830 bucket[0] = (byte)AssetType.Folder;
6332 byte[] objBytes = folderID.GetBytes(); 6831 //byte[] objBytes = folderID.GetBytes();
6333 Array.Copy(objBytes, 0, bucket, 1, 16); 6832 //Array.Copy(objBytes, 0, bucket, 1, 16);
6334 6833
6335 GridInstantMessage msg = new GridInstantMessage(World, 6834 GridInstantMessage msg = new GridInstantMessage(World,
6336 m_host.UUID, m_host.Name+", an object owned by "+ 6835 m_host.OwnerID, m_host.Name, destID,
6337 resolveName(m_host.OwnerID)+",", destID, 6836 (byte)InstantMessageDialog.TaskInventoryOffered,
6338 (byte)InstantMessageDialog.InventoryOffered, 6837 false, category+". "+m_host.Name+" is located at "+
6339 false, category+"\n"+m_host.Name+" is located at "+
6340 World.RegionInfo.RegionName+" "+ 6838 World.RegionInfo.RegionName+" "+
6341 m_host.AbsolutePosition.ToString(), 6839 m_host.AbsolutePosition.ToString(),
6342 folderID, true, m_host.AbsolutePosition, 6840 folderID, true, m_host.AbsolutePosition,
@@ -6574,13 +7072,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6574 UUID av = new UUID(); 7072 UUID av = new UUID();
6575 if (!UUID.TryParse(avatar,out av)) 7073 if (!UUID.TryParse(avatar,out av))
6576 { 7074 {
6577 LSLError("First parameter to llDialog needs to be a key"); 7075 //LSLError("First parameter to llDialog needs to be a key");
6578 return; 7076 return;
6579 } 7077 }
6580 if (buttons.Length < 1) 7078 if (buttons.Length < 1)
6581 { 7079 {
6582 LSLError("No less than 1 button can be shown"); 7080 buttons.Add("OK");
6583 return;
6584 } 7081 }
6585 if (buttons.Length > 12) 7082 if (buttons.Length > 12)
6586 { 7083 {
@@ -6597,7 +7094,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6597 } 7094 }
6598 if (buttons.Data[i].ToString().Length > 24) 7095 if (buttons.Data[i].ToString().Length > 24)
6599 { 7096 {
6600 LSLError("button label cannot be longer than 24 characters"); 7097 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6601 return; 7098 return;
6602 } 7099 }
6603 buts[i] = buttons.Data[i].ToString(); 7100 buts[i] = buttons.Data[i].ToString();
@@ -6656,22 +7153,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6656 } 7153 }
6657 7154
6658 // copy the first script found with this inventory name 7155 // copy the first script found with this inventory name
6659 lock (m_host.TaskInventory) 7156 TaskInventoryItem scriptItem = null;
7157 m_host.TaskInventory.LockItemsForRead(true);
7158 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6660 { 7159 {
6661 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7160 if (inv.Value.Name == name)
6662 { 7161 {
6663 if (inv.Value.Name == name) 7162 // make sure the object is a script
7163 if (10 == inv.Value.Type)
6664 { 7164 {
6665 // make sure the object is a script 7165 found = true;
6666 if (10 == inv.Value.Type) 7166 srcId = inv.Key;
6667 { 7167 scriptItem = inv.Value;
6668 found = true; 7168 break;
6669 srcId = inv.Key;
6670 break;
6671 }
6672 } 7169 }
6673 } 7170 }
6674 } 7171 }
7172 m_host.TaskInventory.LockItemsForRead(false);
6675 7173
6676 if (!found) 7174 if (!found)
6677 { 7175 {
@@ -6679,9 +7177,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6679 return; 7177 return;
6680 } 7178 }
6681 7179
6682 // the rest of the permission checks are done in RezScript, so check the pin there as well 7180 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6683 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7181 if (dest != null)
7182 {
7183 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7184 {
7185 // the rest of the permission checks are done in RezScript, so check the pin there as well
7186 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6684 7187
7188 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7189 m_host.Inventory.RemoveInventoryItem(srcId);
7190 }
7191 }
6685 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7192 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6686 ScriptSleep(3000); 7193 ScriptSleep(3000);
6687 } 7194 }
@@ -6744,19 +7251,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6744 public LSL_String llMD5String(string src, int nonce) 7251 public LSL_String llMD5String(string src, int nonce)
6745 { 7252 {
6746 m_host.AddScriptLPS(1); 7253 m_host.AddScriptLPS(1);
6747 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7254 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6748 } 7255 }
6749 7256
6750 public LSL_String llSHA1String(string src) 7257 public LSL_String llSHA1String(string src)
6751 { 7258 {
6752 m_host.AddScriptLPS(1); 7259 m_host.AddScriptLPS(1);
6753 return Util.SHA1Hash(src).ToLower(); 7260 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6754 } 7261 }
6755 7262
6756 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7263 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6757 { 7264 {
6758 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7265 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6759 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7266 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7267 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7268 return shapeBlock;
6760 7269
6761 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7270 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6762 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7271 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6861,6 +7370,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6861 // Prim type box, cylinder and prism. 7370 // Prim type box, cylinder and prism.
6862 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) 7371 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)
6863 { 7372 {
7373 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7374 return;
7375
6864 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7376 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6865 ObjectShapePacket.ObjectDataBlock shapeBlock; 7377 ObjectShapePacket.ObjectDataBlock shapeBlock;
6866 7378
@@ -6914,6 +7426,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6914 // Prim type sphere. 7426 // Prim type sphere.
6915 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7427 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6916 { 7428 {
7429 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7430 return;
7431
6917 ObjectShapePacket.ObjectDataBlock shapeBlock; 7432 ObjectShapePacket.ObjectDataBlock shapeBlock;
6918 7433
6919 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7434 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6955,6 +7470,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6955 // Prim type torus, tube and ring. 7470 // Prim type torus, tube and ring.
6956 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) 7471 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)
6957 { 7472 {
7473 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7474 return;
7475
6958 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7476 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6959 ObjectShapePacket.ObjectDataBlock shapeBlock; 7477 ObjectShapePacket.ObjectDataBlock shapeBlock;
6960 7478
@@ -7090,6 +7608,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7090 // Prim type sculpt. 7608 // Prim type sculpt.
7091 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7609 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7092 { 7610 {
7611 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7612 return;
7613
7093 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7614 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7094 UUID sculptId; 7615 UUID sculptId;
7095 7616
@@ -7114,7 +7635,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7114 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7635 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7115 { 7636 {
7116 // default 7637 // default
7117 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7638 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7118 } 7639 }
7119 7640
7120 part.Shape.SetSculptProperties((byte)type, sculptId); 7641 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7130,32 +7651,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7130 ScriptSleep(200); 7651 ScriptSleep(200);
7131 } 7652 }
7132 7653
7133 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7654 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7134 { 7655 {
7135 m_host.AddScriptLPS(1); 7656 m_host.AddScriptLPS(1);
7136 7657
7137 setLinkPrimParams(linknumber, rules); 7658 setLinkPrimParams(linknumber, rules);
7659 }
7138 7660
7139 ScriptSleep(200); 7661 private void setLinkPrimParams(int linknumber, LSL_List rules)
7662 {
7663 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7664 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7665 if (parts.Count>0)
7666 {
7667 try
7668 {
7669 parts[0].ParentGroup.areUpdatesSuspended = true;
7670 foreach (SceneObjectPart part in parts)
7671 SetPrimParams(part, rules);
7672 }
7673 finally
7674 {
7675 parts[0].ParentGroup.areUpdatesSuspended = false;
7676 }
7677 }
7678 if (avatars.Count > 0)
7679 {
7680 foreach (ScenePresence avatar in avatars)
7681 SetPrimParams(avatar, rules);
7682 }
7140 } 7683 }
7141 7684
7142 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7685 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7686 float material_density, float material_friction,
7687 float material_restitution, float material_gravity_modifier)
7143 { 7688 {
7144 m_host.AddScriptLPS(1); 7689 ExtraPhysicsData physdata = new ExtraPhysicsData();
7690 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7691 physdata.Density = part.Density;
7692 physdata.Friction = part.Friction;
7693 physdata.Bounce = part.Bounciness;
7694 physdata.GravitationModifier = part.GravityModifier;
7145 7695
7146 setLinkPrimParams(linknumber, rules); 7696 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7697 physdata.Density = material_density;
7698 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7699 physdata.Friction = material_friction;
7700 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7701 physdata.Bounce = material_restitution;
7702 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7703 physdata.GravitationModifier = material_gravity_modifier;
7704
7705 part.UpdateExtraPhysics(physdata);
7147 } 7706 }
7148 7707
7149 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7708 public void llSetPhysicsMaterial(int material_bits,
7709 float material_gravity_modifier, float material_restitution,
7710 float material_friction, float material_density)
7150 { 7711 {
7151 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7712 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7713 }
7152 7714
7153 foreach (SceneObjectPart part in parts) 7715 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7154 SetPrimParams(part, rules); 7716 {
7717 llSetLinkPrimitiveParamsFast(linknumber, rules);
7718 ScriptSleep(200);
7719 }
7720
7721 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7722 {
7723 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7724 //We only support PRIM_POSITION and PRIM_ROTATION
7725
7726 int idx = 0;
7727
7728 while (idx < rules.Length)
7729 {
7730 int code = rules.GetLSLIntegerItem(idx++);
7731
7732 int remain = rules.Length - idx;
7733
7734 switch (code)
7735 {
7736 case (int)ScriptBaseClass.PRIM_POSITION:
7737 {
7738 if (remain < 1)
7739 return;
7740 LSL_Vector v;
7741 v = rules.GetVector3Item(idx++);
7742
7743 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7744 if (part == null)
7745 break;
7746
7747 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7748 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7749 if (llGetLinkNumber() > 1)
7750 {
7751 localRot = llGetLocalRot();
7752 localPos = llGetLocalPos();
7753 }
7754
7755 v -= localPos;
7756 v /= localRot;
7757
7758 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7759
7760 v = v + 2 * sitOffset;
7761
7762 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7763 av.SendAvatarDataToAllAgents();
7764
7765 }
7766 break;
7767
7768 case (int)ScriptBaseClass.PRIM_ROTATION:
7769 {
7770 if (remain < 1)
7771 return;
7772
7773 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7774 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7775 if (llGetLinkNumber() > 1)
7776 {
7777 localRot = llGetLocalRot();
7778 localPos = llGetLocalPos();
7779 }
7780
7781 LSL_Rotation r;
7782 r = rules.GetQuaternionItem(idx++);
7783 r = r * llGetRootRotation() / localRot;
7784 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7785 av.SendAvatarDataToAllAgents();
7786 }
7787 break;
7788 }
7789 }
7155 } 7790 }
7156 7791
7157 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7792 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7158 { 7793 {
7794 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7795 return;
7796
7159 int idx = 0; 7797 int idx = 0;
7160 7798
7161 bool positionChanged = false; 7799 bool positionChanged = false;
@@ -7477,6 +8115,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7477 part.ScriptSetPhysicsStatus(physics); 8115 part.ScriptSetPhysicsStatus(physics);
7478 break; 8116 break;
7479 8117
8118 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8119 if (remain < 1)
8120 return;
8121
8122 int shape_type = rules.GetLSLIntegerItem(idx++);
8123
8124 ExtraPhysicsData physdata = new ExtraPhysicsData();
8125 physdata.Density = part.Density;
8126 physdata.Bounce = part.Bounciness;
8127 physdata.GravitationModifier = part.GravityModifier;
8128 physdata.PhysShapeType = (PhysShapeType)shape_type;
8129
8130 part.UpdateExtraPhysics(physdata);
8131
8132 break;
8133
8134 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8135 if (remain < 5)
8136 return;
8137
8138 int material_bits = rules.GetLSLIntegerItem(idx++);
8139 float material_density = (float)rules.GetLSLFloatItem(idx++);
8140 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8141 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8142 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8143
8144 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8145
8146 break;
8147
7480 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8148 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7481 if (remain < 1) 8149 if (remain < 1)
7482 return; 8150 return;
@@ -7550,7 +8218,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7550 if (part.ParentGroup.RootPart == part) 8218 if (part.ParentGroup.RootPart == part)
7551 { 8219 {
7552 SceneObjectGroup parent = part.ParentGroup; 8220 SceneObjectGroup parent = part.ParentGroup;
7553 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8221 Util.FireAndForget(delegate(object x) {
8222 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8223 });
7554 } 8224 }
7555 else 8225 else
7556 { 8226 {
@@ -7561,6 +8231,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7561 } 8231 }
7562 } 8232 }
7563 } 8233 }
8234
8235 if (positionChanged)
8236 {
8237 if (part.ParentGroup.RootPart == part)
8238 {
8239 SceneObjectGroup parent = part.ParentGroup;
8240 Util.FireAndForget(delegate(object x) {
8241 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8242 });
8243 }
8244 else
8245 {
8246 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8247 SceneObjectGroup parent = part.ParentGroup;
8248 parent.HasGroupChanged = true;
8249 parent.ScheduleGroupForTerseUpdate();
8250 }
8251 }
7564 } 8252 }
7565 8253
7566 public LSL_String llStringToBase64(string str) 8254 public LSL_String llStringToBase64(string str)
@@ -7721,13 +8409,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7721 public LSL_Integer llGetNumberOfPrims() 8409 public LSL_Integer llGetNumberOfPrims()
7722 { 8410 {
7723 m_host.AddScriptLPS(1); 8411 m_host.AddScriptLPS(1);
7724 int avatarCount = 0; 8412 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7725 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8413
7726 {
7727 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7728 avatarCount++;
7729 });
7730
7731 return m_host.ParentGroup.PrimCount + avatarCount; 8414 return m_host.ParentGroup.PrimCount + avatarCount;
7732 } 8415 }
7733 8416
@@ -7743,55 +8426,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7743 m_host.AddScriptLPS(1); 8426 m_host.AddScriptLPS(1);
7744 UUID objID = UUID.Zero; 8427 UUID objID = UUID.Zero;
7745 LSL_List result = new LSL_List(); 8428 LSL_List result = new LSL_List();
8429
8430 // If the ID is not valid, return null result
7746 if (!UUID.TryParse(obj, out objID)) 8431 if (!UUID.TryParse(obj, out objID))
7747 { 8432 {
7748 result.Add(new LSL_Vector()); 8433 result.Add(new LSL_Vector());
7749 result.Add(new LSL_Vector()); 8434 result.Add(new LSL_Vector());
7750 return result; 8435 return result;
7751 } 8436 }
8437
8438 // Check if this is an attached prim. If so, replace
8439 // the UUID with the avatar UUID and report it's bounding box
8440 SceneObjectPart part = World.GetSceneObjectPart(objID);
8441 if (part != null && part.ParentGroup.IsAttachment)
8442 objID = part.ParentGroup.AttachedAvatar;
8443
8444 // Find out if this is an avatar ID. If so, return it's box
7752 ScenePresence presence = World.GetScenePresence(objID); 8445 ScenePresence presence = World.GetScenePresence(objID);
7753 if (presence != null) 8446 if (presence != null)
7754 { 8447 {
7755 if (presence.ParentID == 0) // not sat on an object 8448 // As per LSL Wiki, there is no difference between sitting
8449 // and standing avatar since server 1.36
8450 LSL_Vector lower;
8451 LSL_Vector upper;
8452 if (presence.Animator.Animations.DefaultAnimation.AnimID
8453 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7756 { 8454 {
7757 LSL_Vector lower; 8455 // This is for ground sitting avatars
7758 LSL_Vector upper; 8456 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7759 if (presence.Animator.Animations.DefaultAnimation.AnimID 8457 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7760 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8458 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7761 {
7762 // This is for ground sitting avatars
7763 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7764 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7765 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7766 }
7767 else
7768 {
7769 // This is for standing/flying avatars
7770 float height = presence.Appearance.AvatarHeight / 2.0f;
7771 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7772 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7773 }
7774 result.Add(lower);
7775 result.Add(upper);
7776 return result;
7777 } 8459 }
7778 else 8460 else
7779 { 8461 {
7780 // sitting on an object so we need the bounding box of that 8462 // This is for standing/flying avatars
7781 // which should include the avatar so set the UUID to the 8463 float height = presence.Appearance.AvatarHeight / 2.0f;
7782 // UUID of the object the avatar is sat on and allow it to fall through 8464 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7783 // to processing an object 8465 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7784 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7785 objID = p.UUID;
7786 } 8466 }
8467
8468 // Adjust to the documented error offsets (see LSL Wiki)
8469 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8470 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8471
8472 if (lower.x > upper.x)
8473 lower.x = upper.x;
8474 if (lower.y > upper.y)
8475 lower.y = upper.y;
8476 if (lower.z > upper.z)
8477 lower.z = upper.z;
8478
8479 result.Add(lower);
8480 result.Add(upper);
8481 return result;
7787 } 8482 }
7788 SceneObjectPart part = World.GetSceneObjectPart(objID); 8483
8484 part = World.GetSceneObjectPart(objID);
7789 // Currently only works for single prims without a sitting avatar 8485 // Currently only works for single prims without a sitting avatar
7790 if (part != null) 8486 if (part != null)
7791 { 8487 {
7792 Vector3 halfSize = part.Scale / 2.0f; 8488 float minX;
7793 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8489 float maxX;
7794 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8490 float minY;
8491 float maxY;
8492 float minZ;
8493 float maxZ;
8494
8495 // This BBox is in sim coordinates, with the offset being
8496 // a contained point.
8497 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8498 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8499
8500 minX -= offsets[0].X;
8501 maxX -= offsets[0].X;
8502 minY -= offsets[0].Y;
8503 maxY -= offsets[0].Y;
8504 minZ -= offsets[0].Z;
8505 maxZ -= offsets[0].Z;
8506
8507 LSL_Vector lower;
8508 LSL_Vector upper;
8509
8510 // Adjust to the documented error offsets (see LSL Wiki)
8511 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8512 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8513
8514 if (lower.x > upper.x)
8515 lower.x = upper.x;
8516 if (lower.y > upper.y)
8517 lower.y = upper.y;
8518 if (lower.z > upper.z)
8519 lower.z = upper.z;
8520
7795 result.Add(lower); 8521 result.Add(lower);
7796 result.Add(upper); 8522 result.Add(upper);
7797 return result; 8523 return result;
@@ -7871,13 +8597,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7871 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8597 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7872 part.AbsolutePosition.Y, 8598 part.AbsolutePosition.Y,
7873 part.AbsolutePosition.Z); 8599 part.AbsolutePosition.Z);
7874 // For some reason, the part.AbsolutePosition.* values do not change if the
7875 // linkset is rotated; they always reflect the child prim's world position
7876 // as though the linkset is unrotated. This is incompatible behavior with SL's
7877 // implementation, so will break scripts imported from there (not to mention it
7878 // makes it more difficult to determine a child prim's actual inworld position).
7879 if (part.ParentID != 0)
7880 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7881 res.Add(v); 8600 res.Add(v);
7882 break; 8601 break;
7883 8602
@@ -8048,56 +8767,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8048 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8767 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8049 if (remain < 1) 8768 if (remain < 1)
8050 return res; 8769 return res;
8051 8770 face = (int)rules.GetLSLIntegerItem(idx++);
8052 face=(int)rules.GetLSLIntegerItem(idx++);
8053 8771
8054 tex = part.Shape.Textures; 8772 tex = part.Shape.Textures;
8773 int shiny;
8055 if (face == ScriptBaseClass.ALL_SIDES) 8774 if (face == ScriptBaseClass.ALL_SIDES)
8056 { 8775 {
8057 for (face = 0; face < GetNumberOfSides(part); face++) 8776 for (face = 0; face < GetNumberOfSides(part); face++)
8058 { 8777 {
8059 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8778 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8060 // Convert Shininess to PRIM_SHINY_* 8779 if (shinyness == Shininess.High)
8061 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8780 {
8062 // PRIM_BUMP_* 8781 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8063 res.Add(new LSL_Integer((int)texface.Bump)); 8782 }
8783 else if (shinyness == Shininess.Medium)
8784 {
8785 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8786 }
8787 else if (shinyness == Shininess.Low)
8788 {
8789 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8790 }
8791 else
8792 {
8793 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8794 }
8795 res.Add(new LSL_Integer(shiny));
8796 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8064 } 8797 }
8065 } 8798 }
8066 else 8799 else
8067 { 8800 {
8068 if (face >= 0 && face < GetNumberOfSides(part)) 8801 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8802 if (shinyness == Shininess.High)
8069 { 8803 {
8070 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8804 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8071 // Convert Shininess to PRIM_SHINY_* 8805 }
8072 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8806 else if (shinyness == Shininess.Medium)
8073 // PRIM_BUMP_* 8807 {
8074 res.Add(new LSL_Integer((int)texface.Bump)); 8808 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8809 }
8810 else if (shinyness == Shininess.Low)
8811 {
8812 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8813 }
8814 else
8815 {
8816 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8075 } 8817 }
8818 res.Add(new LSL_Integer(shiny));
8819 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8076 } 8820 }
8077 break; 8821 break;
8078 8822
8079 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8823 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8080 if (remain < 1) 8824 if (remain < 1)
8081 return res; 8825 return res;
8082 8826 face = (int)rules.GetLSLIntegerItem(idx++);
8083 face=(int)rules.GetLSLIntegerItem(idx++);
8084 8827
8085 tex = part.Shape.Textures; 8828 tex = part.Shape.Textures;
8829 int fullbright;
8086 if (face == ScriptBaseClass.ALL_SIDES) 8830 if (face == ScriptBaseClass.ALL_SIDES)
8087 { 8831 {
8088 for (face = 0; face < GetNumberOfSides(part); face++) 8832 for (face = 0; face < GetNumberOfSides(part); face++)
8089 { 8833 {
8090 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8834 if (tex.GetFace((uint)face).Fullbright == true)
8091 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8835 {
8836 fullbright = ScriptBaseClass.TRUE;
8837 }
8838 else
8839 {
8840 fullbright = ScriptBaseClass.FALSE;
8841 }
8842 res.Add(new LSL_Integer(fullbright));
8092 } 8843 }
8093 } 8844 }
8094 else 8845 else
8095 { 8846 {
8096 if (face >= 0 && face < GetNumberOfSides(part)) 8847 if (tex.GetFace((uint)face).Fullbright == true)
8097 { 8848 {
8098 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8849 fullbright = ScriptBaseClass.TRUE;
8099 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8100 } 8850 }
8851 else
8852 {
8853 fullbright = ScriptBaseClass.FALSE;
8854 }
8855 res.Add(new LSL_Integer(fullbright));
8101 } 8856 }
8102 break; 8857 break;
8103 8858
@@ -8119,27 +8874,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8119 break; 8874 break;
8120 8875
8121 case (int)ScriptBaseClass.PRIM_TEXGEN: 8876 case (int)ScriptBaseClass.PRIM_TEXGEN:
8877 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8122 if (remain < 1) 8878 if (remain < 1)
8123 return res; 8879 return res;
8124 8880 face = (int)rules.GetLSLIntegerItem(idx++);
8125 face=(int)rules.GetLSLIntegerItem(idx++);
8126 8881
8127 tex = part.Shape.Textures; 8882 tex = part.Shape.Textures;
8128 if (face == ScriptBaseClass.ALL_SIDES) 8883 if (face == ScriptBaseClass.ALL_SIDES)
8129 { 8884 {
8130 for (face = 0; face < GetNumberOfSides(part); face++) 8885 for (face = 0; face < GetNumberOfSides(part); face++)
8131 { 8886 {
8132 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8887 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8133 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8888 {
8134 res.Add(new LSL_Integer((uint)texgen >> 1)); 8889 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8890 }
8891 else
8892 {
8893 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8894 }
8135 } 8895 }
8136 } 8896 }
8137 else 8897 else
8138 { 8898 {
8139 if (face >= 0 && face < GetNumberOfSides(part)) 8899 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8140 { 8900 {
8141 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8901 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8142 res.Add(new LSL_Integer((uint)texgen >> 1)); 8902 }
8903 else
8904 {
8905 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8143 } 8906 }
8144 } 8907 }
8145 break; 8908 break;
@@ -8162,28 +8925,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8162 case (int)ScriptBaseClass.PRIM_GLOW: 8925 case (int)ScriptBaseClass.PRIM_GLOW:
8163 if (remain < 1) 8926 if (remain < 1)
8164 return res; 8927 return res;
8165 8928 face = (int)rules.GetLSLIntegerItem(idx++);
8166 face=(int)rules.GetLSLIntegerItem(idx++);
8167 8929
8168 tex = part.Shape.Textures; 8930 tex = part.Shape.Textures;
8931 float primglow;
8169 if (face == ScriptBaseClass.ALL_SIDES) 8932 if (face == ScriptBaseClass.ALL_SIDES)
8170 { 8933 {
8171 for (face = 0; face < GetNumberOfSides(part); face++) 8934 for (face = 0; face < GetNumberOfSides(part); face++)
8172 { 8935 {
8173 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8936 primglow = tex.GetFace((uint)face).Glow;
8174 res.Add(new LSL_Float(texface.Glow)); 8937 res.Add(new LSL_Float(primglow));
8175 } 8938 }
8176 } 8939 }
8177 else 8940 else
8178 { 8941 {
8179 if (face >= 0 && face < GetNumberOfSides(part)) 8942 primglow = tex.GetFace((uint)face).Glow;
8180 { 8943 res.Add(new LSL_Float(primglow));
8181 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8182 res.Add(new LSL_Float(texface.Glow));
8183 }
8184 } 8944 }
8185 break; 8945 break;
8186
8187 case (int)ScriptBaseClass.PRIM_TEXT: 8946 case (int)ScriptBaseClass.PRIM_TEXT:
8188 Color4 textColor = part.GetTextColor(); 8947 Color4 textColor = part.GetTextColor();
8189 res.Add(new LSL_String(part.Text)); 8948 res.Add(new LSL_String(part.Text));
@@ -8795,8 +9554,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8795 // The function returns an ordered list 9554 // The function returns an ordered list
8796 // representing the tokens found in the supplied 9555 // representing the tokens found in the supplied
8797 // sources string. If two successive tokenizers 9556 // sources string. If two successive tokenizers
8798 // are encountered, then a NULL entry is added 9557 // are encountered, then a null-string entry is
8799 // to the list. 9558 // added to the list.
8800 // 9559 //
8801 // It is a precondition that the source and 9560 // It is a precondition that the source and
8802 // toekizer lisst are non-null. If they are null, 9561 // toekizer lisst are non-null. If they are null,
@@ -8804,7 +9563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8804 // while their lengths are being determined. 9563 // while their lengths are being determined.
8805 // 9564 //
8806 // A small amount of working memoryis required 9565 // A small amount of working memoryis required
8807 // of approximately 8*#tokenizers. 9566 // of approximately 8*#tokenizers + 8*srcstrlen.
8808 // 9567 //
8809 // There are many ways in which this function 9568 // There are many ways in which this function
8810 // can be implemented, this implementation is 9569 // can be implemented, this implementation is
@@ -8820,155 +9579,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8820 // and eliminates redundant tokenizers as soon 9579 // and eliminates redundant tokenizers as soon
8821 // as is possible. 9580 // as is possible.
8822 // 9581 //
8823 // The implementation tries to avoid any copying 9582 // The implementation tries to minimize temporary
8824 // of arrays or other objects. 9583 // garbage generation.
8825 // </remarks> 9584 // </remarks>
8826 9585
8827 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9586 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8828 { 9587 {
8829 int beginning = 0; 9588 return ParseString2List(src, separators, spacers, true);
8830 int srclen = src.Length; 9589 }
8831 int seplen = separators.Length;
8832 object[] separray = separators.Data;
8833 int spclen = spacers.Length;
8834 object[] spcarray = spacers.Data;
8835 int mlen = seplen+spclen;
8836
8837 int[] offset = new int[mlen+1];
8838 bool[] active = new bool[mlen];
8839
8840 int best;
8841 int j;
8842
8843 // Initial capacity reduces resize cost
8844 9590
8845 LSL_List tokens = new LSL_List(); 9591 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9592 {
9593 int srclen = src.Length;
9594 int seplen = separators.Length;
9595 object[] separray = separators.Data;
9596 int spclen = spacers.Length;
9597 object[] spcarray = spacers.Data;
9598 int dellen = 0;
9599 string[] delarray = new string[seplen+spclen];
8846 9600
8847 // All entries are initially valid 9601 int outlen = 0;
9602 string[] outarray = new string[srclen*2+1];
8848 9603
8849 for (int i = 0; i < mlen; i++) 9604 int i, j;
8850 active[i] = true; 9605 string d;
8851 9606
8852 offset[mlen] = srclen; 9607 m_host.AddScriptLPS(1);
8853 9608
8854 while (beginning < srclen) 9609 /*
9610 * Convert separator and spacer lists to C# strings.
9611 * Also filter out null strings so we don't hang.
9612 */
9613 for (i = 0; i < seplen; i ++)
8855 { 9614 {
9615 d = separray[i].ToString();
9616 if (d.Length > 0)
9617 {
9618 delarray[dellen++] = d;
9619 }
9620 }
9621 seplen = dellen;
8856 9622
8857 best = mlen; // as bad as it gets 9623 for (i = 0; i < spclen; i ++)
9624 {
9625 d = spcarray[i].ToString();
9626 if (d.Length > 0)
9627 {
9628 delarray[dellen++] = d;
9629 }
9630 }
8858 9631
8859 // Scan for separators 9632 /*
9633 * Scan through source string from beginning to end.
9634 */
9635 for (i = 0;;)
9636 {
8860 9637
8861 for (j = 0; j < seplen; j++) 9638 /*
9639 * Find earliest delimeter in src starting at i (if any).
9640 */
9641 int earliestDel = -1;
9642 int earliestSrc = srclen;
9643 string earliestStr = null;
9644 for (j = 0; j < dellen; j ++)
8862 { 9645 {
8863 if (separray[j].ToString() == String.Empty) 9646 d = delarray[j];
8864 active[j] = false; 9647 if (d != null)
8865
8866 if (active[j])
8867 { 9648 {
8868 // scan all of the markers 9649 int index = src.IndexOf(d, i);
8869 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9650 if (index < 0)
8870 { 9651 {
8871 // not present at all 9652 delarray[j] = null; // delim nowhere in src, don't check it anymore
8872 active[j] = false;
8873 } 9653 }
8874 else 9654 else if (index < earliestSrc)
8875 { 9655 {
8876 // present and correct 9656 earliestSrc = index; // where delimeter starts in source string
8877 if (offset[j] < offset[best]) 9657 earliestDel = j; // where delimeter is in delarray[]
8878 { 9658 earliestStr = d; // the delimeter string from delarray[]
8879 // closest so far 9659 if (index == i) break; // can't do any better than found at beg of string
8880 best = j;
8881 if (offset[best] == beginning)
8882 break;
8883 }
8884 } 9660 }
8885 } 9661 }
8886 } 9662 }
8887 9663
8888 // Scan for spacers 9664 /*
8889 9665 * Output source string starting at i through start of earliest delimeter.
8890 if (offset[best] != beginning) 9666 */
9667 if (keepNulls || (earliestSrc > i))
8891 { 9668 {
8892 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9669 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8893 {
8894 if (spcarray[j-seplen].ToString() == String.Empty)
8895 active[j] = false;
8896
8897 if (active[j])
8898 {
8899 // scan all of the markers
8900 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8901 {
8902 // not present at all
8903 active[j] = false;
8904 }
8905 else
8906 {
8907 // present and correct
8908 if (offset[j] < offset[best])
8909 {
8910 // closest so far
8911 best = j;
8912 }
8913 }
8914 }
8915 }
8916 } 9670 }
8917 9671
8918 // This is the normal exit from the scanning loop 9672 /*
9673 * If no delimeter found at or after i, we're done scanning.
9674 */
9675 if (earliestDel < 0) break;
8919 9676
8920 if (best == mlen) 9677 /*
9678 * If delimeter was a spacer, output the spacer.
9679 */
9680 if (earliestDel >= seplen)
8921 { 9681 {
8922 // no markers were found on this pass 9682 outarray[outlen++] = earliestStr;
8923 // so we're pretty much done
8924 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8925 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8926 break;
8927 } 9683 }
8928 9684
8929 // Otherwise we just add the newly delimited token 9685 /*
8930 // and recalculate where the search should continue. 9686 * Look at rest of src string following delimeter.
8931 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9687 */
8932 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9688 i = earliestSrc + earliestStr.Length;
8933
8934 if (best < seplen)
8935 {
8936 beginning = offset[best] + (separray[best].ToString()).Length;
8937 }
8938 else
8939 {
8940 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8941 string str = spcarray[best - seplen].ToString();
8942 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8943 tokens.Add(new LSL_String(str));
8944 }
8945 } 9689 }
8946 9690
8947 // This an awkward an not very intuitive boundary case. If the 9691 /*
8948 // last substring is a tokenizer, then there is an implied trailing 9692 * Make up an exact-sized output array suitable for an LSL_List object.
8949 // null list entry. Hopefully the single comparison will not be too 9693 */
8950 // arduous. Alternatively the 'break' could be replced with a return 9694 object[] outlist = new object[outlen];
8951 // but that's shabby programming. 9695 for (i = 0; i < outlen; i ++)
8952
8953 if ((beginning == srclen) && (keepNulls))
8954 { 9696 {
8955 if (srclen != 0) 9697 outlist[i] = new LSL_String(outarray[i]);
8956 tokens.Add(new LSL_String(""));
8957 } 9698 }
8958 9699 return new LSL_List(outlist);
8959 return tokens;
8960 }
8961
8962 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8963 {
8964 m_host.AddScriptLPS(1);
8965 return this.ParseString(src, separators, spacers, false);
8966 }
8967
8968 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8969 {
8970 m_host.AddScriptLPS(1);
8971 return this.ParseString(src, separators, spacers, true);
8972 } 9700 }
8973 9701
8974 public LSL_Integer llGetObjectPermMask(int mask) 9702 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9045,28 +9773,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9045 { 9773 {
9046 m_host.AddScriptLPS(1); 9774 m_host.AddScriptLPS(1);
9047 9775
9048 lock (m_host.TaskInventory) 9776 m_host.TaskInventory.LockItemsForRead(true);
9777 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9049 { 9778 {
9050 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9779 if (inv.Value.Name == item)
9051 { 9780 {
9052 if (inv.Value.Name == item) 9781 m_host.TaskInventory.LockItemsForRead(false);
9782 switch (mask)
9053 { 9783 {
9054 switch (mask) 9784 case 0:
9055 { 9785 return (int)inv.Value.BasePermissions;
9056 case 0: 9786 case 1:
9057 return (int)inv.Value.BasePermissions; 9787 return (int)inv.Value.CurrentPermissions;
9058 case 1: 9788 case 2:
9059 return (int)inv.Value.CurrentPermissions; 9789 return (int)inv.Value.GroupPermissions;
9060 case 2: 9790 case 3:
9061 return (int)inv.Value.GroupPermissions; 9791 return (int)inv.Value.EveryonePermissions;
9062 case 3: 9792 case 4:
9063 return (int)inv.Value.EveryonePermissions; 9793 return (int)inv.Value.NextPermissions;
9064 case 4:
9065 return (int)inv.Value.NextPermissions;
9066 }
9067 } 9794 }
9068 } 9795 }
9069 } 9796 }
9797 m_host.TaskInventory.LockItemsForRead(false);
9070 9798
9071 return -1; 9799 return -1;
9072 } 9800 }
@@ -9113,16 +9841,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9113 { 9841 {
9114 m_host.AddScriptLPS(1); 9842 m_host.AddScriptLPS(1);
9115 9843
9116 lock (m_host.TaskInventory) 9844 m_host.TaskInventory.LockItemsForRead(true);
9845 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9117 { 9846 {
9118 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9847 if (inv.Value.Name == item)
9119 { 9848 {
9120 if (inv.Value.Name == item) 9849 m_host.TaskInventory.LockItemsForRead(false);
9121 { 9850 return inv.Value.CreatorID.ToString();
9122 return inv.Value.CreatorID.ToString();
9123 }
9124 } 9851 }
9125 } 9852 }
9853 m_host.TaskInventory.LockItemsForRead(false);
9126 9854
9127 llSay(0, "No item name '" + item + "'"); 9855 llSay(0, "No item name '" + item + "'");
9128 9856
@@ -9248,9 +9976,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9248 { 9976 {
9249 try 9977 try
9250 { 9978 {
9979 /*
9251 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9980 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9252 if (obj != null) 9981 if (obj != null)
9253 return (double)obj.GetMass(); 9982 return (double)obj.GetMass();
9983 */
9984 // return total object mass
9985 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
9986 if (obj != null)
9987 return obj.GetMass();
9988
9254 // the object is null so the key is for an avatar 9989 // the object is null so the key is for an avatar
9255 ScenePresence avatar = World.GetScenePresence(key); 9990 ScenePresence avatar = World.GetScenePresence(key);
9256 if (avatar != null) 9991 if (avatar != null)
@@ -9270,7 +10005,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9270 } 10005 }
9271 10006
9272 /// <summary> 10007 /// <summary>
9273 /// illListReplaceList removes the sub-list defined by the inclusive indices 10008 /// llListReplaceList removes the sub-list defined by the inclusive indices
9274 /// start and end and inserts the src list in its place. The inclusive 10009 /// start and end and inserts the src list in its place. The inclusive
9275 /// nature of the indices means that at least one element must be deleted 10010 /// nature of the indices means that at least one element must be deleted
9276 /// if the indices are within the bounds of the existing list. I.e. 2,2 10011 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9327,16 +10062,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9327 // based upon end. Note that if end exceeds the upper 10062 // based upon end. Note that if end exceeds the upper
9328 // bound in this case, the entire destination list 10063 // bound in this case, the entire destination list
9329 // is removed. 10064 // is removed.
9330 else 10065 else if (start == 0)
9331 { 10066 {
9332 if (end + 1 < dest.Length) 10067 if (end + 1 < dest.Length)
9333 {
9334 return src + dest.GetSublist(end + 1, -1); 10068 return src + dest.GetSublist(end + 1, -1);
9335 }
9336 else 10069 else
9337 {
9338 return src; 10070 return src;
9339 } 10071 }
10072 else // Start < 0
10073 {
10074 if (end + 1 < dest.Length)
10075 return dest.GetSublist(end + 1, -1);
10076 else
10077 return new LSL_List();
9340 } 10078 }
9341 } 10079 }
9342 // Finally, if start > end, we strip away a prefix and 10080 // Finally, if start > end, we strip away a prefix and
@@ -9387,17 +10125,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9387 int width = 0; 10125 int width = 0;
9388 int height = 0; 10126 int height = 0;
9389 10127
9390 ParcelMediaCommandEnum? commandToSend = null; 10128 uint commandToSend = 0;
9391 float time = 0.0f; // default is from start 10129 float time = 0.0f; // default is from start
9392 10130
9393 ScenePresence presence = null; 10131 ScenePresence presence = null;
9394 10132
9395 for (int i = 0; i < commandList.Data.Length; i++) 10133 for (int i = 0; i < commandList.Data.Length; i++)
9396 { 10134 {
9397 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10135 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9398 switch (command) 10136 switch (command)
9399 { 10137 {
9400 case ParcelMediaCommandEnum.Agent: 10138 case (uint)ParcelMediaCommandEnum.Agent:
9401 // we send only to one agent 10139 // we send only to one agent
9402 if ((i + 1) < commandList.Length) 10140 if ((i + 1) < commandList.Length)
9403 { 10141 {
@@ -9414,25 +10152,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9414 } 10152 }
9415 break; 10153 break;
9416 10154
9417 case ParcelMediaCommandEnum.Loop: 10155 case (uint)ParcelMediaCommandEnum.Loop:
9418 loop = 1; 10156 loop = 1;
9419 commandToSend = command; 10157 commandToSend = command;
9420 update = true; //need to send the media update packet to set looping 10158 update = true; //need to send the media update packet to set looping
9421 break; 10159 break;
9422 10160
9423 case ParcelMediaCommandEnum.Play: 10161 case (uint)ParcelMediaCommandEnum.Play:
9424 loop = 0; 10162 loop = 0;
9425 commandToSend = command; 10163 commandToSend = command;
9426 update = true; //need to send the media update packet to make sure it doesn't loop 10164 update = true; //need to send the media update packet to make sure it doesn't loop
9427 break; 10165 break;
9428 10166
9429 case ParcelMediaCommandEnum.Pause: 10167 case (uint)ParcelMediaCommandEnum.Pause:
9430 case ParcelMediaCommandEnum.Stop: 10168 case (uint)ParcelMediaCommandEnum.Stop:
9431 case ParcelMediaCommandEnum.Unload: 10169 case (uint)ParcelMediaCommandEnum.Unload:
9432 commandToSend = command; 10170 commandToSend = command;
9433 break; 10171 break;
9434 10172
9435 case ParcelMediaCommandEnum.Url: 10173 case (uint)ParcelMediaCommandEnum.Url:
9436 if ((i + 1) < commandList.Length) 10174 if ((i + 1) < commandList.Length)
9437 { 10175 {
9438 if (commandList.Data[i + 1] is LSL_String) 10176 if (commandList.Data[i + 1] is LSL_String)
@@ -9445,7 +10183,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9445 } 10183 }
9446 break; 10184 break;
9447 10185
9448 case ParcelMediaCommandEnum.Texture: 10186 case (uint)ParcelMediaCommandEnum.Texture:
9449 if ((i + 1) < commandList.Length) 10187 if ((i + 1) < commandList.Length)
9450 { 10188 {
9451 if (commandList.Data[i + 1] is LSL_String) 10189 if (commandList.Data[i + 1] is LSL_String)
@@ -9458,7 +10196,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9458 } 10196 }
9459 break; 10197 break;
9460 10198
9461 case ParcelMediaCommandEnum.Time: 10199 case (uint)ParcelMediaCommandEnum.Time:
9462 if ((i + 1) < commandList.Length) 10200 if ((i + 1) < commandList.Length)
9463 { 10201 {
9464 if (commandList.Data[i + 1] is LSL_Float) 10202 if (commandList.Data[i + 1] is LSL_Float)
@@ -9470,7 +10208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9470 } 10208 }
9471 break; 10209 break;
9472 10210
9473 case ParcelMediaCommandEnum.AutoAlign: 10211 case (uint)ParcelMediaCommandEnum.AutoAlign:
9474 if ((i + 1) < commandList.Length) 10212 if ((i + 1) < commandList.Length)
9475 { 10213 {
9476 if (commandList.Data[i + 1] is LSL_Integer) 10214 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9484,7 +10222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9484 } 10222 }
9485 break; 10223 break;
9486 10224
9487 case ParcelMediaCommandEnum.Type: 10225 case (uint)ParcelMediaCommandEnum.Type:
9488 if ((i + 1) < commandList.Length) 10226 if ((i + 1) < commandList.Length)
9489 { 10227 {
9490 if (commandList.Data[i + 1] is LSL_String) 10228 if (commandList.Data[i + 1] is LSL_String)
@@ -9497,7 +10235,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9497 } 10235 }
9498 break; 10236 break;
9499 10237
9500 case ParcelMediaCommandEnum.Desc: 10238 case (uint)ParcelMediaCommandEnum.Desc:
9501 if ((i + 1) < commandList.Length) 10239 if ((i + 1) < commandList.Length)
9502 { 10240 {
9503 if (commandList.Data[i + 1] is LSL_String) 10241 if (commandList.Data[i + 1] is LSL_String)
@@ -9510,7 +10248,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9510 } 10248 }
9511 break; 10249 break;
9512 10250
9513 case ParcelMediaCommandEnum.Size: 10251 case (uint)ParcelMediaCommandEnum.Size:
9514 if ((i + 2) < commandList.Length) 10252 if ((i + 2) < commandList.Length)
9515 { 10253 {
9516 if (commandList.Data[i + 1] is LSL_Integer) 10254 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9580,7 +10318,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9580 } 10318 }
9581 } 10319 }
9582 10320
9583 if (commandToSend != null) 10321 if (commandToSend != 0)
9584 { 10322 {
9585 // the commandList contained a start/stop/... command, too 10323 // the commandList contained a start/stop/... command, too
9586 if (presence == null) 10324 if (presence == null)
@@ -9617,7 +10355,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9617 10355
9618 if (aList.Data[i] != null) 10356 if (aList.Data[i] != null)
9619 { 10357 {
9620 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10358 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9621 { 10359 {
9622 case ParcelMediaCommandEnum.Url: 10360 case ParcelMediaCommandEnum.Url:
9623 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10361 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9660,16 +10398,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9660 { 10398 {
9661 m_host.AddScriptLPS(1); 10399 m_host.AddScriptLPS(1);
9662 10400
9663 lock (m_host.TaskInventory) 10401 m_host.TaskInventory.LockItemsForRead(true);
10402 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9664 { 10403 {
9665 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10404 if (inv.Value.Name == name)
9666 { 10405 {
9667 if (inv.Value.Name == name) 10406 m_host.TaskInventory.LockItemsForRead(false);
9668 { 10407 return inv.Value.Type;
9669 return inv.Value.Type;
9670 }
9671 } 10408 }
9672 } 10409 }
10410 m_host.TaskInventory.LockItemsForRead(false);
9673 10411
9674 return -1; 10412 return -1;
9675 } 10413 }
@@ -9680,15 +10418,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9680 10418
9681 if (quick_pay_buttons.Data.Length < 4) 10419 if (quick_pay_buttons.Data.Length < 4)
9682 { 10420 {
9683 LSLError("List must have at least 4 elements"); 10421 int x;
9684 return; 10422 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10423 {
10424 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10425 }
9685 } 10426 }
9686 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10427 int[] nPrice = new int[5];
9687 10428 nPrice[0] = price;
9688 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10429 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9689 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10430 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9690 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10431 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9691 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10432 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10433 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9692 m_host.ParentGroup.HasGroupChanged = true; 10434 m_host.ParentGroup.HasGroupChanged = true;
9693 } 10435 }
9694 10436
@@ -9700,17 +10442,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9700 if (invItemID == UUID.Zero) 10442 if (invItemID == UUID.Zero)
9701 return new LSL_Vector(); 10443 return new LSL_Vector();
9702 10444
9703 lock (m_host.TaskInventory) 10445 m_host.TaskInventory.LockItemsForRead(true);
10446 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9704 { 10447 {
9705 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10448 m_host.TaskInventory.LockItemsForRead(false);
9706 return new LSL_Vector(); 10449 return new LSL_Vector();
10450 }
9707 10451
9708 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10452 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9709 { 10453 {
9710 ShoutError("No permissions to track the camera"); 10454 ShoutError("No permissions to track the camera");
9711 return new LSL_Vector(); 10455 m_host.TaskInventory.LockItemsForRead(false);
9712 } 10456 return new LSL_Vector();
9713 } 10457 }
10458 m_host.TaskInventory.LockItemsForRead(false);
9714 10459
9715 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10460 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9716 if (presence != null) 10461 if (presence != null)
@@ -9728,17 +10473,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9728 if (invItemID == UUID.Zero) 10473 if (invItemID == UUID.Zero)
9729 return new LSL_Rotation(); 10474 return new LSL_Rotation();
9730 10475
9731 lock (m_host.TaskInventory) 10476 m_host.TaskInventory.LockItemsForRead(true);
10477 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9732 { 10478 {
9733 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10479 m_host.TaskInventory.LockItemsForRead(false);
9734 return new LSL_Rotation(); 10480 return new LSL_Rotation();
9735
9736 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9737 {
9738 ShoutError("No permissions to track the camera");
9739 return new LSL_Rotation();
9740 }
9741 } 10481 }
10482 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10483 {
10484 ShoutError("No permissions to track the camera");
10485 m_host.TaskInventory.LockItemsForRead(false);
10486 return new LSL_Rotation();
10487 }
10488 m_host.TaskInventory.LockItemsForRead(false);
9742 10489
9743 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10490 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9744 if (presence != null) 10491 if (presence != null)
@@ -9800,8 +10547,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9800 { 10547 {
9801 m_host.AddScriptLPS(1); 10548 m_host.AddScriptLPS(1);
9802 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10549 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9803 if (detectedParams == null) return; // only works on the first detected avatar 10550 if (detectedParams == null)
9804 10551 {
10552 if (m_host.ParentGroup.IsAttachment == true)
10553 {
10554 detectedParams = new DetectParams();
10555 detectedParams.Key = m_host.OwnerID;
10556 }
10557 else
10558 {
10559 return;
10560 }
10561 }
10562
9805 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10563 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9806 if (avatar != null) 10564 if (avatar != null)
9807 { 10565 {
@@ -9809,6 +10567,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9809 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10567 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9810 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10568 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9811 } 10569 }
10570
9812 ScriptSleep(1000); 10571 ScriptSleep(1000);
9813 } 10572 }
9814 10573
@@ -9920,14 +10679,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9920 if (objectID == UUID.Zero) return; 10679 if (objectID == UUID.Zero) return;
9921 10680
9922 UUID agentID; 10681 UUID agentID;
9923 lock (m_host.TaskInventory) 10682 m_host.TaskInventory.LockItemsForRead(true);
9924 { 10683 // we need the permission first, to know which avatar we want to set the camera for
9925 // we need the permission first, to know which avatar we want to set the camera for 10684 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9926 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9927 10685
9928 if (agentID == UUID.Zero) return; 10686 if (agentID == UUID.Zero)
9929 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10687 {
10688 m_host.TaskInventory.LockItemsForRead(false);
10689 return;
9930 } 10690 }
10691 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10692 {
10693 m_host.TaskInventory.LockItemsForRead(false);
10694 return;
10695 }
10696 m_host.TaskInventory.LockItemsForRead(false);
9931 10697
9932 ScenePresence presence = World.GetScenePresence(agentID); 10698 ScenePresence presence = World.GetScenePresence(agentID);
9933 10699
@@ -9936,12 +10702,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9936 10702
9937 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10703 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9938 object[] data = rules.Data; 10704 object[] data = rules.Data;
9939 for (int i = 0; i < data.Length; ++i) { 10705 for (int i = 0; i < data.Length; ++i)
10706 {
9940 int type = Convert.ToInt32(data[i++].ToString()); 10707 int type = Convert.ToInt32(data[i++].ToString());
9941 if (i >= data.Length) break; // odd number of entries => ignore the last 10708 if (i >= data.Length) break; // odd number of entries => ignore the last
9942 10709
9943 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10710 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9944 switch (type) { 10711 switch (type)
10712 {
9945 case ScriptBaseClass.CAMERA_FOCUS: 10713 case ScriptBaseClass.CAMERA_FOCUS:
9946 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10714 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9947 case ScriptBaseClass.CAMERA_POSITION: 10715 case ScriptBaseClass.CAMERA_POSITION:
@@ -9977,12 +10745,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9977 10745
9978 // we need the permission first, to know which avatar we want to clear the camera for 10746 // we need the permission first, to know which avatar we want to clear the camera for
9979 UUID agentID; 10747 UUID agentID;
9980 lock (m_host.TaskInventory) 10748 m_host.TaskInventory.LockItemsForRead(true);
10749 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10750 if (agentID == UUID.Zero)
9981 { 10751 {
9982 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10752 m_host.TaskInventory.LockItemsForRead(false);
9983 if (agentID == UUID.Zero) return; 10753 return;
9984 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10754 }
10755 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10756 {
10757 m_host.TaskInventory.LockItemsForRead(false);
10758 return;
9985 } 10759 }
10760 m_host.TaskInventory.LockItemsForRead(false);
9986 10761
9987 ScenePresence presence = World.GetScenePresence(agentID); 10762 ScenePresence presence = World.GetScenePresence(agentID);
9988 10763
@@ -10049,19 +10824,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10049 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10824 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10050 { 10825 {
10051 m_host.AddScriptLPS(1); 10826 m_host.AddScriptLPS(1);
10052 string ret = String.Empty; 10827
10053 string src1 = llBase64ToString(str1); 10828 if (str1 == String.Empty)
10054 string src2 = llBase64ToString(str2); 10829 return String.Empty;
10055 int c = 0; 10830 if (str2 == String.Empty)
10056 for (int i = 0; i < src1.Length; i++) 10831 return str1;
10832
10833 int len = str2.Length;
10834 if ((len % 4) != 0) // LL is EVIL!!!!
10835 {
10836 while (str2.EndsWith("="))
10837 str2 = str2.Substring(0, str2.Length - 1);
10838
10839 len = str2.Length;
10840 int mod = len % 4;
10841
10842 if (mod == 1)
10843 str2 = str2.Substring(0, str2.Length - 1);
10844 else if (mod == 2)
10845 str2 += "==";
10846 else if (mod == 3)
10847 str2 += "=";
10848 }
10849
10850 byte[] data1;
10851 byte[] data2;
10852 try
10057 { 10853 {
10058 ret += (char) (src1[i] ^ src2[c]); 10854 data1 = Convert.FromBase64String(str1);
10855 data2 = Convert.FromBase64String(str2);
10856 }
10857 catch (Exception)
10858 {
10859 return new LSL_String(String.Empty);
10860 }
10861
10862 byte[] d2 = new Byte[data1.Length];
10863 int pos = 0;
10864
10865 if (data1.Length <= data2.Length)
10866 {
10867 Array.Copy(data2, 0, d2, 0, data1.Length);
10868 }
10869 else
10870 {
10871 while (pos < data1.Length)
10872 {
10873 len = data1.Length - pos;
10874 if (len > data2.Length)
10875 len = data2.Length;
10059 10876
10060 c++; 10877 Array.Copy(data2, 0, d2, pos, len);
10061 if (c >= src2.Length) 10878 pos += len;
10062 c = 0; 10879 }
10063 } 10880 }
10064 return llStringToBase64(ret); 10881
10882 for (pos = 0 ; pos < data1.Length ; pos++ )
10883 data1[pos] ^= d2[pos];
10884
10885 return Convert.ToBase64String(data1);
10065 } 10886 }
10066 10887
10067 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10888 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10118,12 +10939,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10118 Regex r = new Regex(authregex); 10939 Regex r = new Regex(authregex);
10119 int[] gnums = r.GetGroupNumbers(); 10940 int[] gnums = r.GetGroupNumbers();
10120 Match m = r.Match(url); 10941 Match m = r.Match(url);
10121 if (m.Success) { 10942 if (m.Success)
10122 for (int i = 1; i < gnums.Length; i++) { 10943 {
10944 for (int i = 1; i < gnums.Length; i++)
10945 {
10123 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10946 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10124 //CaptureCollection cc = g.Captures; 10947 //CaptureCollection cc = g.Captures;
10125 } 10948 }
10126 if (m.Groups.Count == 5) { 10949 if (m.Groups.Count == 5)
10950 {
10127 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10951 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10128 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10952 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10129 } 10953 }
@@ -10486,15 +11310,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10486 11310
10487 internal UUID ScriptByName(string name) 11311 internal UUID ScriptByName(string name)
10488 { 11312 {
10489 lock (m_host.TaskInventory) 11313 m_host.TaskInventory.LockItemsForRead(true);
11314
11315 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10490 { 11316 {
10491 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11317 if (item.Type == 10 && item.Name == name)
10492 { 11318 {
10493 if (item.Type == 10 && item.Name == name) 11319 m_host.TaskInventory.LockItemsForRead(false);
10494 return item.ItemID; 11320 return item.ItemID;
10495 } 11321 }
10496 } 11322 }
10497 11323
11324 m_host.TaskInventory.LockItemsForRead(false);
11325
10498 return UUID.Zero; 11326 return UUID.Zero;
10499 } 11327 }
10500 11328
@@ -10535,6 +11363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10535 { 11363 {
10536 m_host.AddScriptLPS(1); 11364 m_host.AddScriptLPS(1);
10537 11365
11366 //Clone is thread safe
10538 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11367 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10539 11368
10540 UUID assetID = UUID.Zero; 11369 UUID assetID = UUID.Zero;
@@ -10597,6 +11426,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10597 { 11426 {
10598 m_host.AddScriptLPS(1); 11427 m_host.AddScriptLPS(1);
10599 11428
11429 //Clone is thread safe
10600 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11430 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10601 11431
10602 UUID assetID = UUID.Zero; 11432 UUID assetID = UUID.Zero;
@@ -10677,15 +11507,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10677 return GetLinkPrimitiveParams(obj, rules); 11507 return GetLinkPrimitiveParams(obj, rules);
10678 } 11508 }
10679 11509
10680 public void print(string str) 11510 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10681 { 11511 {
10682 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11512 List<SceneObjectPart> parts = GetLinkParts(link);
10683 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11513 if (parts.Count < 1)
10684 if (ossl != null) 11514 return 0;
10685 { 11515
10686 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11516 return GetNumberOfSides(parts[0]);
10687 m_log.Info("LSL print():" + str);
10688 }
10689 } 11517 }
10690 11518
10691 private string Name2Username(string name) 11519 private string Name2Username(string name)
@@ -10731,155 +11559,482 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10731 return rq.ToString(); 11559 return rq.ToString();
10732 } 11560 }
10733 11561
11562 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11563 {
11564 m_SayShoutCount = 0;
11565 }
11566
11567 private struct Tri
11568 {
11569 public Vector3 p1;
11570 public Vector3 p2;
11571 public Vector3 p3;
11572 }
11573
11574 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11575 {
11576 float height = avatar.Appearance.AvatarHeight;
11577 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11578 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11579
11580 if (point.X > b1.X && point.X < b2.X &&
11581 point.Y > b1.Y && point.Y < b2.Y &&
11582 point.Z > b1.Z && point.Z < b2.Z)
11583 return true;
11584 return false;
11585 }
11586
11587 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11588 {
11589 List<ContactResult> contacts = new List<ContactResult>();
11590
11591 Vector3 ab = rayEnd - rayStart;
11592
11593 World.ForEachScenePresence(delegate(ScenePresence sp)
11594 {
11595 Vector3 ac = sp.AbsolutePosition - rayStart;
11596 Vector3 bc = sp.AbsolutePosition - rayEnd;
11597
11598 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11599
11600 if (d > 1.5)
11601 return;
11602
11603 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11604
11605 if (d2 > 0)
11606 return;
11607
11608 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11609 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11610
11611 if (!InBoundingBox(sp, p))
11612 return;
11613
11614 ContactResult result = new ContactResult ();
11615 result.ConsumerID = sp.LocalId;
11616 result.Depth = Vector3.Distance(rayStart, p);
11617 result.Normal = Vector3.Zero;
11618 result.Pos = p;
11619
11620 contacts.Add(result);
11621 });
11622
11623 return contacts.ToArray();
11624 }
11625
11626 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11627 {
11628 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11629 List<ContactResult> contacts = new List<ContactResult>();
11630
11631 Vector3 ab = rayEnd - rayStart;
11632
11633 World.ForEachSOG(delegate(SceneObjectGroup group)
11634 {
11635 if (m_host.ParentGroup == group)
11636 return;
11637
11638 if (group.IsAttachment)
11639 return;
11640
11641 if (group.RootPart.PhysActor == null)
11642 {
11643 if (!includePhantom)
11644 return;
11645 }
11646 else
11647 {
11648 if (group.RootPart.PhysActor.IsPhysical)
11649 {
11650 if (!includePhysical)
11651 return;
11652 }
11653 else
11654 {
11655 if (!includeNonPhysical)
11656 return;
11657 }
11658 }
11659
11660 // Find the radius ouside of which we don't even need to hit test
11661 float minX;
11662 float maxX;
11663 float minY;
11664 float maxY;
11665 float minZ;
11666 float maxZ;
11667
11668 float radius = 0.0f;
11669
11670 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11671
11672 if (Math.Abs(minX) > radius)
11673 radius = Math.Abs(minX);
11674 if (Math.Abs(minY) > radius)
11675 radius = Math.Abs(minY);
11676 if (Math.Abs(minZ) > radius)
11677 radius = Math.Abs(minZ);
11678 if (Math.Abs(maxX) > radius)
11679 radius = Math.Abs(maxX);
11680 if (Math.Abs(maxY) > radius)
11681 radius = Math.Abs(maxY);
11682 if (Math.Abs(maxZ) > radius)
11683 radius = Math.Abs(maxZ);
11684
11685 Vector3 ac = group.AbsolutePosition - rayStart;
11686 Vector3 bc = group.AbsolutePosition - rayEnd;
11687
11688 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11689
11690 // Too far off ray, don't bother
11691 if (d > radius)
11692 return;
11693
11694 // Behind ray, drop
11695 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11696 if (d2 > 0)
11697 return;
11698
11699 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11700 // Miss.
11701 if (!intersection.HitTF)
11702 return;
11703
11704 ContactResult result = new ContactResult ();
11705 result.ConsumerID = group.LocalId;
11706 result.Depth = intersection.distance;
11707 result.Normal = intersection.normal;
11708 result.Pos = intersection.ipoint;
11709
11710 contacts.Add(result);
11711 });
11712
11713 return contacts.ToArray();
11714 }
11715
11716 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11717 {
11718 double[,] heightfield = World.Heightmap.GetDoubles();
11719 List<ContactResult> contacts = new List<ContactResult>();
11720
11721 double min = 2048.0;
11722 double max = 0.0;
11723
11724 // Find the min and max of the heightfield
11725 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11726 {
11727 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11728 {
11729 if (heightfield[x, y] > max)
11730 max = heightfield[x, y];
11731 if (heightfield[x, y] < min)
11732 min = heightfield[x, y];
11733 }
11734 }
11735
11736
11737 // A ray extends past rayEnd, but doesn't go back before
11738 // rayStart. If the start is above the highest point of the ground
11739 // and the ray goes up, we can't hit the ground. Ever.
11740 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11741 return null;
11742
11743 // Same for going down
11744 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11745 return null;
11746
11747 List<Tri> trilist = new List<Tri>();
11748
11749 // Create our triangle list
11750 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11751 {
11752 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11753 {
11754 Tri t1 = new Tri();
11755 Tri t2 = new Tri();
11756
11757 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11758 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11759 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11760 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11761
11762 t1.p1 = p1;
11763 t1.p2 = p2;
11764 t1.p3 = p3;
11765
11766 t2.p1 = p3;
11767 t2.p2 = p4;
11768 t2.p3 = p1;
11769
11770 trilist.Add(t1);
11771 trilist.Add(t2);
11772 }
11773 }
11774
11775 // Ray direction
11776 Vector3 rayDirection = rayEnd - rayStart;
11777
11778 foreach (Tri t in trilist)
11779 {
11780 // Compute triangle plane normal and edges
11781 Vector3 u = t.p2 - t.p1;
11782 Vector3 v = t.p3 - t.p1;
11783 Vector3 n = Vector3.Cross(u, v);
11784
11785 if (n == Vector3.Zero)
11786 continue;
11787
11788 Vector3 w0 = rayStart - t.p1;
11789 double a = -Vector3.Dot(n, w0);
11790 double b = Vector3.Dot(n, rayDirection);
11791
11792 // Not intersecting the plane, or in plane (same thing)
11793 // Ignoring this MAY cause the ground to not be detected
11794 // sometimes
11795 if (Math.Abs(b) < 0.000001)
11796 continue;
11797
11798 double r = a / b;
11799
11800 // ray points away from plane
11801 if (r < 0.0)
11802 continue;
11803
11804 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11805
11806 float uu = Vector3.Dot(u, u);
11807 float uv = Vector3.Dot(u, v);
11808 float vv = Vector3.Dot(v, v);
11809 Vector3 w = ip - t.p1;
11810 float wu = Vector3.Dot(w, u);
11811 float wv = Vector3.Dot(w, v);
11812 float d = uv * uv - uu * vv;
11813
11814 float cs = (uv * wv - vv * wu) / d;
11815 if (cs < 0 || cs > 1.0)
11816 continue;
11817 float ct = (uv * wu - uu * wv) / d;
11818 if (ct < 0 || (cs + ct) > 1.0)
11819 continue;
11820
11821 // Add contact point
11822 ContactResult result = new ContactResult ();
11823 result.ConsumerID = 0;
11824 result.Depth = Vector3.Distance(rayStart, ip);
11825 result.Normal = n;
11826 result.Pos = ip;
11827
11828 contacts.Add(result);
11829 }
11830
11831 if (contacts.Count == 0)
11832 return null;
11833
11834 contacts.Sort(delegate(ContactResult a, ContactResult b)
11835 {
11836 return (int)(a.Depth - b.Depth);
11837 });
11838
11839 return contacts[0];
11840 }
11841/*
11842 // not done:
11843 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
11844 {
11845 ContactResult[] contacts = null;
11846 World.ForEachSOG(delegate(SceneObjectGroup group)
11847 {
11848 if (m_host.ParentGroup == group)
11849 return;
11850
11851 if (group.IsAttachment)
11852 return;
11853
11854 if(group.RootPart.PhysActor != null)
11855 return;
11856
11857 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
11858 });
11859 return contacts;
11860 }
11861*/
11862
10734 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11863 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10735 { 11864 {
11865 LSL_List list = new LSL_List();
11866
10736 m_host.AddScriptLPS(1); 11867 m_host.AddScriptLPS(1);
10737 11868
10738 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11869 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10739 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11870 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10740 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11871 Vector3 dir = rayEnd - rayStart;
10741 11872
10742 int count = 0; 11873 float dist = Vector3.Mag(dir);
10743// int detectPhantom = 0; 11874
11875 int count = 1;
11876 bool detectPhantom = false;
10744 int dataFlags = 0; 11877 int dataFlags = 0;
10745 int rejectTypes = 0; 11878 int rejectTypes = 0;
10746 11879
10747 for (int i = 0; i < options.Length; i += 2) 11880 for (int i = 0; i < options.Length; i += 2)
10748 { 11881 {
10749 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11882 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10750 {
10751 count = options.GetLSLIntegerItem(i + 1); 11883 count = options.GetLSLIntegerItem(i + 1);
10752 } 11884 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10753// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11885 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10754// {
10755// detectPhantom = options.GetLSLIntegerItem(i + 1);
10756// }
10757 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11886 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10758 {
10759 dataFlags = options.GetLSLIntegerItem(i + 1); 11887 dataFlags = options.GetLSLIntegerItem(i + 1);
10760 }
10761 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11888 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10762 {
10763 rejectTypes = options.GetLSLIntegerItem(i + 1); 11889 rejectTypes = options.GetLSLIntegerItem(i + 1);
10764 }
10765 } 11890 }
10766 11891
10767 LSL_List list = new LSL_List(); 11892 if (count > 16)
10768 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11893 count = 16;
10769
10770 double distance = Util.GetDistanceTo(startvector, endvector);
10771
10772 if (distance == 0)
10773 distance = 0.001;
10774 11894
10775 Vector3 posToCheck = startvector; 11895 List<ContactResult> results = new List<ContactResult>();
10776 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10777 11896
10778 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11897 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10779 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11898 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10780 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11899 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10781 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11900 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10782 11901
10783 for (float i = 0; i <= distance; i += 0.1f) 11902
11903 if (World.SuportsRayCastFiltered())
10784 { 11904 {
10785 posToCheck = startvector + (dir * (i / (float)distance)); 11905 if (dist == 0)
11906 return list;
11907
11908 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11909 if (checkTerrain)
11910 rayfilter |= RayFilterFlags.land;
11911// if (checkAgents)
11912// rayfilter |= RayFilterFlags.agent;
11913 if (checkPhysical)
11914 rayfilter |= RayFilterFlags.physical;
11915 if (checkNonPhysical)
11916 rayfilter |= RayFilterFlags.nonphysical;
11917 if (detectPhantom)
11918 rayfilter |= RayFilterFlags.LSLPhanton;
11919
11920 Vector3 direction = dir * ( 1/dist);
10786 11921
10787 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11922 if(rayfilter == 0)
10788 { 11923 {
10789 ContactResult result = new ContactResult(); 11924 list.Add(new LSL_Integer(0));
10790 result.ConsumerID = 0; 11925 return list;
10791 result.Depth = 0;
10792 result.Normal = Vector3.Zero;
10793 result.Pos = posToCheck;
10794 results.Add(result);
10795 checkTerrain = false;
10796 } 11926 }
10797 11927
10798 if (checkAgents) 11928 // get some more contacts to sort ???
11929 int physcount = 4 * count;
11930 if (physcount > 20)
11931 physcount = 20;
11932
11933 object physresults;
11934 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11935
11936 if (physresults == null)
10799 { 11937 {
10800 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11938 list.Add(new LSL_Integer(-3)); // timeout error
10801 { 11939 return list;
10802 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
10803 {
10804 ContactResult result = new ContactResult ();
10805 result.ConsumerID = sp.LocalId;
10806 result.Depth = 0;
10807 result.Normal = Vector3.Zero;
10808 result.Pos = posToCheck;
10809 results.Add(result);
10810 }
10811 });
10812 } 11940 }
10813 }
10814 11941
10815 int refcount = 0; 11942 results = (List<ContactResult>)physresults;
10816 foreach (ContactResult result in results)
10817 {
10818 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
10819 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10820 continue;
10821 11943
10822 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11944 // for now physics doesn't detect sitted avatars so do it outside physics
11945 if (checkAgents)
11946 {
11947 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11948 foreach (ContactResult r in agentHits)
11949 results.Add(r);
11950 }
10823 11951
10824 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11952 // bug: will not detect phantom unless they are physical
10825 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11953 // don't use ObjectIntersection because its also bad
11954
11955 }
11956 else
11957 {
11958 if (checkTerrain)
11959 {
11960 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11961 if (groundContact != null)
11962 results.Add((ContactResult)groundContact);
11963 }
10826 11964
10827 if (entity == null) 11965 if (checkAgents)
10828 { 11966 {
10829 list.Add(UUID.Zero); 11967 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11968 foreach (ContactResult r in agentHits)
11969 results.Add(r);
11970 }
10830 11971
10831 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11972 if (checkPhysical || checkNonPhysical || detectPhantom)
10832 list.Add(0); 11973 {
11974 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11975 foreach (ContactResult r in objectHits)
11976 results.Add(r);
11977 }
11978 }
10833 11979
10834 list.Add(result.Pos); 11980 results.Sort(delegate(ContactResult a, ContactResult b)
11981 {
11982 return a.Depth.CompareTo(b.Depth);
11983 });
11984
11985 int values = 0;
11986 SceneObjectGroup thisgrp = m_host.ParentGroup;
10835 11987
10836 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11988 foreach (ContactResult result in results)
10837 list.Add(result.Normal); 11989 {
11990 if (result.Depth > dist)
11991 continue;
10838 11992
10839 continue; //Can't find it, so add UUID.Zero 11993 // physics ray can return colisions with host prim
10840 } 11994 if (m_host.LocalId == result.ConsumerID)
11995 continue;
10841 11996
10842 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && 11997 UUID itemID = UUID.Zero;
10843 ((ISceneChildEntity)intersection.obj).PhysActor == null) 11998 int linkNum = 0;
10844 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10845 11999
10846 if (entity is SceneObjectPart) 12000 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
12001 // It's a prim!
12002 if (part != null)
10847 { 12003 {
10848 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 12004 // dont detect members of same object ???
12005 if (part.ParentGroup == thisgrp)
12006 continue;
10849 12007
10850 if (pa != null && pa.IsPhysical) 12008 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10851 { 12009 itemID = part.ParentGroup.UUID;
10852 if (!checkPhysical)
10853 continue;
10854 }
10855 else 12010 else
10856 { 12011 itemID = part.UUID;
10857 if (!checkNonPhysical)
10858 continue;
10859 }
10860 }
10861 12012
10862 refcount++; 12013 linkNum = part.LinkNum;
10863 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 12014 }
10864 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10865 else 12015 else
10866 list.Add(entity.UUID);
10867
10868 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10869 { 12016 {
10870 if (entity is SceneObjectPart) 12017 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10871 list.Add(((SceneObjectPart)entity).LinkNum); 12018 /// It it a boy? a girl?
10872 else 12019 if (sp != null)
10873 list.Add(0); 12020 itemID = sp.UUID;
10874 } 12021 }
10875 12022
10876 list.Add(result.Pos); 12023 list.Add(new LSL_String(itemID.ToString()));
12024 list.Add(new LSL_String(result.Pos.ToString()));
12025
12026 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
12027 list.Add(new LSL_Integer(linkNum));
10877 12028
10878 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 12029 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10879 list.Add(result.Normal); 12030 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
12031
12032 values++;
12033 if (values >= count)
12034 break;
10880 } 12035 }
10881 12036
10882 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 12037 list.Add(new LSL_Integer(values));
10883 12038
10884 return list; 12039 return list;
10885 } 12040 }
@@ -10919,7 +12074,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10919 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12074 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10920 if (!isAccount) return 0; 12075 if (!isAccount) return 0;
10921 if (estate.HasAccess(id)) return 1; 12076 if (estate.HasAccess(id)) return 1;
10922 if (estate.IsBanned(id)) 12077 if (estate.IsBanned(id, World.GetUserFlags(id)))
10923 estate.RemoveBan(id); 12078 estate.RemoveBan(id);
10924 estate.AddEstateUser(id); 12079 estate.AddEstateUser(id);
10925 break; 12080 break;
@@ -10938,14 +12093,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10938 break; 12093 break;
10939 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12094 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10940 if (!isAccount) return 0; 12095 if (!isAccount) return 0;
10941 if (estate.IsBanned(id)) return 1; 12096 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10942 EstateBan ban = new EstateBan(); 12097 EstateBan ban = new EstateBan();
10943 ban.EstateID = estate.EstateID; 12098 ban.EstateID = estate.EstateID;
10944 ban.BannedUserID = id; 12099 ban.BannedUserID = id;
10945 estate.AddBan(ban); 12100 estate.AddBan(ban);
10946 break; 12101 break;
10947 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12102 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10948 if (!isAccount || !estate.IsBanned(id)) return 0; 12103 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10949 estate.RemoveBan(id); 12104 estate.RemoveBan(id);
10950 break; 12105 break;
10951 default: return 0; 12106 default: return 0;
@@ -10974,7 +12129,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10974 return 16384; 12129 return 16384;
10975 } 12130 }
10976 12131
10977 public LSL_Integer llGetUsedMemory() 12132 public virtual LSL_Integer llGetUsedMemory()
10978 { 12133 {
10979 m_host.AddScriptLPS(1); 12134 m_host.AddScriptLPS(1);
10980 // The value returned for LSO scripts in SL 12135 // The value returned for LSO scripts in SL
@@ -11002,7 +12157,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11002 public void llSetSoundQueueing(int queue) 12157 public void llSetSoundQueueing(int queue)
11003 { 12158 {
11004 m_host.AddScriptLPS(1); 12159 m_host.AddScriptLPS(1);
11005 NotImplemented("llSetSoundQueueing");
11006 } 12160 }
11007 12161
11008 public void llCollisionSprite(string impact_sprite) 12162 public void llCollisionSprite(string impact_sprite)
@@ -11014,10 +12168,274 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11014 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12168 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11015 { 12169 {
11016 m_host.AddScriptLPS(1); 12170 m_host.AddScriptLPS(1);
11017 NotImplemented("llGodLikeRezObject"); 12171
12172 if (!World.Permissions.IsGod(m_host.OwnerID))
12173 NotImplemented("llGodLikeRezObject");
12174
12175 AssetBase rezAsset = World.AssetService.Get(inventory);
12176 if (rezAsset == null)
12177 {
12178 llSay(0, "Asset not found");
12179 return;
12180 }
12181
12182 SceneObjectGroup group = null;
12183
12184 try
12185 {
12186 string xmlData = Utils.BytesToString(rezAsset.Data);
12187 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12188 }
12189 catch
12190 {
12191 llSay(0, "Asset not found");
12192 return;
12193 }
12194
12195 if (group == null)
12196 {
12197 llSay(0, "Asset not found");
12198 return;
12199 }
12200
12201 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12202 group.RootPart.AttachOffset = group.AbsolutePosition;
12203
12204 group.ResetIDs();
12205
12206 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12207 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12208 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12209 group.ScheduleGroupForFullUpdate();
12210
12211 // objects rezzed with this method are die_at_edge by default.
12212 group.RootPart.SetDieAtEdge(true);
12213
12214 group.ResumeScripts();
12215
12216 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12217 "object_rez", new Object[] {
12218 new LSL_String(
12219 group.RootPart.UUID.ToString()) },
12220 new DetectParams[0]));
12221 }
12222
12223 public LSL_String llTransferLindenDollars(string destination, int amount)
12224 {
12225 UUID txn = UUID.Random();
12226
12227 Util.FireAndForget(delegate(object x)
12228 {
12229 int replycode = 0;
12230 string replydata = destination + "," + amount.ToString();
12231
12232 try
12233 {
12234 UUID invItemID=InventorySelf();
12235 if (invItemID == UUID.Zero)
12236 {
12237 replydata = "SERVICE_ERROR";
12238 return;
12239 }
12240
12241 m_host.AddScriptLPS(1);
12242
12243 m_host.TaskInventory.LockItemsForRead(true);
12244 TaskInventoryItem item = m_host.TaskInventory[invItemID];
12245 m_host.TaskInventory.LockItemsForRead(false);
12246
12247 if (item.PermsGranter == UUID.Zero)
12248 {
12249 replydata = "MISSING_PERMISSION_DEBIT";
12250 return;
12251 }
12252
12253 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12254 {
12255 replydata = "MISSING_PERMISSION_DEBIT";
12256 return;
12257 }
12258
12259 UUID toID = new UUID();
12260
12261 if (!UUID.TryParse(destination, out toID))
12262 {
12263 replydata = "INVALID_AGENT";
12264 return;
12265 }
12266
12267 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12268
12269 if (money == null)
12270 {
12271 replydata = "TRANSFERS_DISABLED";
12272 return;
12273 }
12274
12275 bool result = money.ObjectGiveMoney(
12276 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12277
12278 if (result)
12279 {
12280 replycode = 1;
12281 return;
12282 }
12283
12284 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12285 }
12286 finally
12287 {
12288 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12289 "transaction_result", new Object[] {
12290 new LSL_String(txn.ToString()),
12291 new LSL_Integer(replycode),
12292 new LSL_String(replydata) },
12293 new DetectParams[0]));
12294 }
12295 });
12296
12297 return txn.ToString();
11018 } 12298 }
11019 12299
11020 #endregion 12300 #endregion
12301
12302 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12303 {
12304 SceneObjectGroup group = m_host.ParentGroup;
12305
12306 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12307 return;
12308 if (group.IsAttachment)
12309 return;
12310
12311 if (frames.Data.Length > 0) // We are getting a new motion
12312 {
12313 if (group.RootPart.KeyframeMotion != null)
12314 group.RootPart.KeyframeMotion.Stop();
12315 group.RootPart.KeyframeMotion = null;
12316
12317 int idx = 0;
12318
12319 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12320 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12321
12322 while (idx < options.Data.Length)
12323 {
12324 int option = (int)options.GetLSLIntegerItem(idx++);
12325 int remain = options.Data.Length - idx;
12326
12327 switch (option)
12328 {
12329 case ScriptBaseClass.KFM_MODE:
12330 if (remain < 1)
12331 break;
12332 int modeval = (int)options.GetLSLIntegerItem(idx++);
12333 switch(modeval)
12334 {
12335 case ScriptBaseClass.KFM_FORWARD:
12336 mode = KeyframeMotion.PlayMode.Forward;
12337 break;
12338 case ScriptBaseClass.KFM_REVERSE:
12339 mode = KeyframeMotion.PlayMode.Reverse;
12340 break;
12341 case ScriptBaseClass.KFM_LOOP:
12342 mode = KeyframeMotion.PlayMode.Loop;
12343 break;
12344 case ScriptBaseClass.KFM_PING_PONG:
12345 mode = KeyframeMotion.PlayMode.PingPong;
12346 break;
12347 }
12348 break;
12349 case ScriptBaseClass.KFM_DATA:
12350 if (remain < 1)
12351 break;
12352 int dataval = (int)options.GetLSLIntegerItem(idx++);
12353 data = (KeyframeMotion.DataFormat)dataval;
12354 break;
12355 }
12356 }
12357
12358 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12359
12360 idx = 0;
12361
12362 int elemLength = 2;
12363 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12364 elemLength = 3;
12365
12366 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12367 while (idx < frames.Data.Length)
12368 {
12369 int remain = frames.Data.Length - idx;
12370
12371 if (remain < elemLength)
12372 break;
12373
12374 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12375 frame.Position = null;
12376 frame.Rotation = null;
12377
12378 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12379 {
12380 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12381 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12382 }
12383 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12384 {
12385 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12386 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12387 }
12388
12389 float tempf = (float)frames.GetLSLFloatItem(idx++);
12390 frame.TimeMS = (int)(tempf * 1000.0f);
12391
12392 keyframes.Add(frame);
12393 }
12394
12395 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12396 group.RootPart.KeyframeMotion.Start();
12397 }
12398 else
12399 {
12400 if (group.RootPart.KeyframeMotion == null)
12401 return;
12402
12403 if (options.Data.Length == 0)
12404 {
12405 group.RootPart.KeyframeMotion.Stop();
12406 return;
12407 }
12408
12409 int code = (int)options.GetLSLIntegerItem(0);
12410
12411 int idx = 0;
12412
12413 while (idx < options.Data.Length)
12414 {
12415 int option = (int)options.GetLSLIntegerItem(idx++);
12416 int remain = options.Data.Length - idx;
12417
12418 switch (option)
12419 {
12420 case ScriptBaseClass.KFM_COMMAND:
12421 int cmd = (int)options.GetLSLIntegerItem(idx++);
12422 switch (cmd)
12423 {
12424 case ScriptBaseClass.KFM_CMD_PLAY:
12425 group.RootPart.KeyframeMotion.Start();
12426 break;
12427 case ScriptBaseClass.KFM_CMD_STOP:
12428 group.RootPart.KeyframeMotion.Stop();
12429 break;
12430 case ScriptBaseClass.KFM_CMD_PAUSE:
12431 group.RootPart.KeyframeMotion.Pause();
12432 break;
12433 }
12434 break;
12435 }
12436 }
12437 }
12438 }
11021 } 12439 }
11022 12440
11023 public class NotecardCache 12441 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 {