aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-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.cs3011
-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, 2719 insertions, 949 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 d4c872c..8637df7 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{
@@ -104,16 +108,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
104 protected int m_notecardLineReadCharsMax = 255; 108 protected int m_notecardLineReadCharsMax = 255;
105 protected int m_scriptConsoleChannel = 0; 109 protected int m_scriptConsoleChannel = 0;
106 protected bool m_scriptConsoleChannelEnabled = false; 110 protected bool m_scriptConsoleChannelEnabled = false;
111 protected bool m_debuggerSafe = false;
107 protected IUrlModule m_UrlModule = null; 112 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 new Dictionary<UUID, UserInfoCacheEntry>(); 114 new Dictionary<UUID, UserInfoCacheEntry>();
110 115
116 protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118
111 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 119 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
112 { 120 {
121 m_ShoutSayTimer = new Timer(1000);
122 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
123 m_ShoutSayTimer.AutoReset = true;
124 m_ShoutSayTimer.Start();
125
113 m_ScriptEngine = ScriptEngine; 126 m_ScriptEngine = ScriptEngine;
114 m_host = host; 127 m_host = host;
115 m_localID = localID; 128 m_localID = localID;
116 m_itemID = itemID; 129 m_itemID = itemID;
130 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
117 131
118 m_ScriptDelayFactor = 132 m_ScriptDelayFactor =
119 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 133 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -161,6 +175,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
161 get { return m_ScriptEngine.World; } 175 get { return m_ScriptEngine.World; }
162 } 176 }
163 177
178 [DebuggerNonUserCode]
164 public void state(string newState) 179 public void state(string newState)
165 { 180 {
166 m_ScriptEngine.SetState(m_itemID, newState); 181 m_ScriptEngine.SetState(m_itemID, newState);
@@ -170,6 +185,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
170 /// Reset the named script. The script must be present 185 /// Reset the named script. The script must be present
171 /// in the same prim. 186 /// in the same prim.
172 /// </summary> 187 /// </summary>
188 [DebuggerNonUserCode]
173 public void llResetScript() 189 public void llResetScript()
174 { 190 {
175 m_host.AddScriptLPS(1); 191 m_host.AddScriptLPS(1);
@@ -226,9 +242,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
226 } 242 }
227 } 243 }
228 244
245 public List<ScenePresence> GetLinkAvatars(int linkType)
246 {
247 List<ScenePresence> ret = new List<ScenePresence>();
248 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
249 return ret;
250
251 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
252
253 switch (linkType)
254 {
255 case ScriptBaseClass.LINK_SET:
256 return avs;
257
258 case ScriptBaseClass.LINK_ROOT:
259 return ret;
260
261 case ScriptBaseClass.LINK_ALL_OTHERS:
262 return avs;
263
264 case ScriptBaseClass.LINK_ALL_CHILDREN:
265 return avs;
266
267 case ScriptBaseClass.LINK_THIS:
268 return ret;
269
270 default:
271 if (linkType < 0)
272 return ret;
273
274 int partCount = m_host.ParentGroup.GetPartCount();
275
276 if (linkType <= partCount)
277 {
278 return ret;
279 }
280 else
281 {
282 linkType = linkType - partCount;
283 if (linkType > avs.Count)
284 {
285 return ret;
286 }
287 else
288 {
289 ret.Add(avs[linkType-1]);
290 return ret;
291 }
292 }
293 }
294 }
295
229 public List<SceneObjectPart> GetLinkParts(int linkType) 296 public List<SceneObjectPart> GetLinkParts(int linkType)
230 { 297 {
231 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 298 List<SceneObjectPart> ret = new List<SceneObjectPart>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
232 ret.Add(m_host); 301 ret.Add(m_host);
233 302
234 switch (linkType) 303 switch (linkType)
@@ -282,28 +351,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 /// <returns></returns> 351 /// <returns></returns>
283 protected TaskInventoryItem GetSelfInventoryItem() 352 protected TaskInventoryItem GetSelfInventoryItem()
284 { 353 {
285 lock (m_host.TaskInventory) 354 TaskInventoryItem invItem = null;
286 return m_host.TaskInventory[m_itemID]; 355
356 bool unlock = false;
357 if (!m_host.TaskInventory.IsReadLockedByMe())
358 {
359 m_host.TaskInventory.LockItemsForRead(true);
360 unlock = true;
361 }
362
363 invItem = m_host.TaskInventory[m_itemID];
364
365 if (unlock)
366 {
367 m_host.TaskInventory.LockItemsForRead(false);
368 }
369
370 return invItem;
287 } 371 }
288 372
289 protected UUID InventoryKey(string name, int type) 373 protected UUID InventoryKey(string name, int type)
290 { 374 {
291 m_host.AddScriptLPS(1); 375 m_host.AddScriptLPS(1);
292 376 m_host.TaskInventory.LockItemsForRead(true);
293 lock (m_host.TaskInventory) 377
378 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
294 { 379 {
295 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 380 if (inv.Value.Name == name)
296 { 381 {
297 if (inv.Value.Name == name) 382 m_host.TaskInventory.LockItemsForRead(false);
383
384 if (inv.Value.Type != type)
298 { 385 {
299 if (inv.Value.Type != type) 386 return UUID.Zero;
300 return UUID.Zero;
301
302 return inv.Value.AssetID;
303 } 387 }
388
389 return inv.Value.AssetID;
304 } 390 }
305 } 391 }
306 392
393 m_host.TaskInventory.LockItemsForRead(false);
307 return UUID.Zero; 394 return UUID.Zero;
308 } 395 }
309 396
@@ -311,17 +398,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
311 { 398 {
312 m_host.AddScriptLPS(1); 399 m_host.AddScriptLPS(1);
313 400
314 lock (m_host.TaskInventory) 401
402 m_host.TaskInventory.LockItemsForRead(true);
403
404 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
315 { 405 {
316 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 406 if (inv.Value.Name == name)
317 { 407 {
318 if (inv.Value.Name == name) 408 m_host.TaskInventory.LockItemsForRead(false);
319 { 409 return inv.Value.AssetID;
320 return inv.Value.AssetID;
321 }
322 } 410 }
323 } 411 }
324 412
413 m_host.TaskInventory.LockItemsForRead(false);
414
415
325 return UUID.Zero; 416 return UUID.Zero;
326 } 417 }
327 418
@@ -463,31 +554,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
463 554
464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 555 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
465 556
466 /// <summary> 557 // Utility function for llRot2Euler
467 /// Convert an LSL rotation to a Euler vector. 558
468 /// </summary> 559 // normalize an angle between -PI and PI (-180 to +180 degrees)
469 /// <remarks> 560 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 { 561 {
477 m_host.AddScriptLPS(1); 562 if (angle > -Math.PI && angle < Math.PI)
563 return angle;
564
565 int numPis = (int)(Math.PI / angle);
566 double remainder = angle - Math.PI * numPis;
567 if (numPis % 2 == 1)
568 return Math.PI - angle;
569 return remainder;
570 }
478 571
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. 572 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. 573 {
481 if (m == 0.0) return new LSL_Vector(); 574 m_host.AddScriptLPS(1);
482 double x = Math.Atan2(-v.y, v.z); 575 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 576
490 return new LSL_Vector(x, y, z); 577 double sqw = q1.s*q1.s;
578 double sqx = q1.x*q1.x;
579 double sqy = q1.z*q1.z;
580 double sqz = q1.y*q1.y;
581 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
582 double test = q1.x*q1.z + q1.y*q1.s;
583 if (test > 0.4999*unit) { // singularity at north pole
584 eul.z = 2 * Math.Atan2(q1.x,q1.s);
585 eul.y = Math.PI/2;
586 eul.x = 0;
587 return eul;
588 }
589 if (test < -0.4999*unit) { // singularity at south pole
590 eul.z = -2 * Math.Atan2(q1.x,q1.s);
591 eul.y = -Math.PI/2;
592 eul.x = 0;
593 return eul;
594 }
595 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
596 eul.y = Math.Asin(2*test/unit);
597 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
598 return eul;
491 } 599 }
492 600
493 /* From wiki: 601 /* From wiki:
@@ -689,77 +797,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 797 {
690 //A and B should both be normalized 798 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 799 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 800 /* 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, 801 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 802
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 803 double dotProduct = LSL_Vector.Dot(a, b);
804 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
805 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
806 double angle = Math.Acos(dotProduct / magProduct);
807 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
808 double s = Math.Sin(angle / 2);
809
810 double x = axis.x * s;
811 double y = axis.y * s;
812 double z = axis.z * s;
813 double w = Math.Cos(angle / 2);
814
815 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
817
818 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
819 */
820
821 // This method mimics the 180 errors found in SL
822 // See www.euclideanspace.com... angleBetween
823 LSL_Vector vec_a = a;
824 LSL_Vector vec_b = b;
825
826 // Eliminate zero length
827 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
828 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
829 if (vec_a_mag < 0.00001 ||
830 vec_b_mag < 0.00001)
696 { 831 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 832 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 833 }
699 else 834
835 // Normalize
836 vec_a = llVecNorm(vec_a);
837 vec_b = llVecNorm(vec_b);
838
839 // Calculate axis and rotation angle
840 LSL_Vector axis = vec_a % vec_b;
841 LSL_Float cos_theta = vec_a * vec_b;
842
843 // Check if parallel
844 if (cos_theta > 0.99999)
700 { 845 {
701 a = LSL_Vector.Norm(a); 846 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 847 }
703 double dotProduct = LSL_Vector.Dot(a, b); 848
704 // There are two degenerate cases possible. These are for vectors 180 or 849 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 850 else if (cos_theta < -0.99999)
706 // 851 {
707 // Check for vectors 180 degrees apart. 852 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. 853 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 854 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 855 }
711 // First assume X axis is orthogonal to the vectors. 856 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 857 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 858 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 859 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 860 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 861 s = Math.Cos(theta);
717 { 862 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 863 x = axis.x * t;
719 } 864 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 865 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 866 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 } 867 }
760 return rotBetween;
761 } 868 }
762 869
763 public void llWhisper(int channelID, string text) 870 public void llWhisper(int channelID, string text)
764 { 871 {
765 m_host.AddScriptLPS(1); 872 m_host.AddScriptLPS(1);
@@ -779,6 +886,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 886 {
780 m_host.AddScriptLPS(1); 887 m_host.AddScriptLPS(1);
781 888
889 if (channelID == 0)
890 m_SayShoutCount++;
891
892 if (m_SayShoutCount >= 11)
893 ScriptSleep(2000);
894
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 895 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 896 {
784 Console.WriteLine(text); 897 Console.WriteLine(text);
@@ -801,6 +914,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 914 {
802 m_host.AddScriptLPS(1); 915 m_host.AddScriptLPS(1);
803 916
917 if (channelID == 0)
918 m_SayShoutCount++;
919
920 if (m_SayShoutCount >= 11)
921 ScriptSleep(2000);
922
804 if (text.Length > 1023) 923 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 924 text = text.Substring(0, 1023);
806 925
@@ -832,8 +951,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
832 951
833 public void llRegionSayTo(string target, int channel, string msg) 952 public void llRegionSayTo(string target, int channel, string msg)
834 { 953 {
835 string error = String.Empty;
836
837 if (msg.Length > 1023) 954 if (msg.Length > 1023)
838 msg = msg.Substring(0, 1023); 955 msg = msg.Substring(0, 1023);
839 956
@@ -1105,10 +1222,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1105 return detectedParams.TouchUV; 1222 return detectedParams.TouchUV;
1106 } 1223 }
1107 1224
1225 [DebuggerNonUserCode]
1108 public virtual void llDie() 1226 public virtual void llDie()
1109 { 1227 {
1110 m_host.AddScriptLPS(1); 1228 m_host.AddScriptLPS(1);
1111 throw new SelfDeleteException(); 1229 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1112 } 1230 }
1113 1231
1114 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
@@ -1181,6 +1299,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1181 1299
1182 public void llSetStatus(int status, int value) 1300 public void llSetStatus(int status, int value)
1183 { 1301 {
1302 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1303 return;
1184 m_host.AddScriptLPS(1); 1304 m_host.AddScriptLPS(1);
1185 1305
1186 int statusrotationaxis = 0; 1306 int statusrotationaxis = 0;
@@ -1412,6 +1532,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1412 { 1532 {
1413 m_host.AddScriptLPS(1); 1533 m_host.AddScriptLPS(1);
1414 1534
1535 SetColor(m_host, color, face);
1536 }
1537
1538 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1539 {
1540 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1541 return;
1542
1543 Primitive.TextureEntry tex = part.Shape.Textures;
1544 Color4 texcolor;
1545 if (face >= 0 && face < GetNumberOfSides(part))
1546 {
1547 texcolor = tex.CreateFace((uint)face).RGBA;
1548 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1549 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1550 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1551 tex.FaceTextures[face].RGBA = texcolor;
1552 part.UpdateTextureEntry(tex.GetBytes());
1553 return;
1554 }
1555 else if (face == ScriptBaseClass.ALL_SIDES)
1556 {
1557 for (uint i = 0; i < GetNumberOfSides(part); i++)
1558 {
1559 if (tex.FaceTextures[i] != null)
1560 {
1561 texcolor = tex.FaceTextures[i].RGBA;
1562 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1563 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1564 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1565 tex.FaceTextures[i].RGBA = texcolor;
1566 }
1567 texcolor = tex.DefaultTexture.RGBA;
1568 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1569 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1570 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1571 tex.DefaultTexture.RGBA = texcolor;
1572 }
1573 part.UpdateTextureEntry(tex.GetBytes());
1574 return;
1575 }
1576
1415 if (face == ScriptBaseClass.ALL_SIDES) 1577 if (face == ScriptBaseClass.ALL_SIDES)
1416 face = SceneObjectPart.ALL_SIDES; 1578 face = SceneObjectPart.ALL_SIDES;
1417 1579
@@ -1420,6 +1582,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1420 1582
1421 public void SetTexGen(SceneObjectPart part, int face,int style) 1583 public void SetTexGen(SceneObjectPart part, int face,int style)
1422 { 1584 {
1585 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1586 return;
1587
1423 Primitive.TextureEntry tex = part.Shape.Textures; 1588 Primitive.TextureEntry tex = part.Shape.Textures;
1424 MappingType textype; 1589 MappingType textype;
1425 textype = MappingType.Default; 1590 textype = MappingType.Default;
@@ -1450,6 +1615,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1450 1615
1451 public void SetGlow(SceneObjectPart part, int face, float glow) 1616 public void SetGlow(SceneObjectPart part, int face, float glow)
1452 { 1617 {
1618 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1619 return;
1620
1453 Primitive.TextureEntry tex = part.Shape.Textures; 1621 Primitive.TextureEntry tex = part.Shape.Textures;
1454 if (face >= 0 && face < GetNumberOfSides(part)) 1622 if (face >= 0 && face < GetNumberOfSides(part))
1455 { 1623 {
@@ -1475,6 +1643,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1475 1643
1476 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1644 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1477 { 1645 {
1646 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1647 return;
1478 1648
1479 Shininess sval = new Shininess(); 1649 Shininess sval = new Shininess();
1480 1650
@@ -1525,6 +1695,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1525 1695
1526 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1696 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1527 { 1697 {
1698 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1699 return;
1700
1528 Primitive.TextureEntry tex = part.Shape.Textures; 1701 Primitive.TextureEntry tex = part.Shape.Textures;
1529 if (face >= 0 && face < GetNumberOfSides(part)) 1702 if (face >= 0 && face < GetNumberOfSides(part))
1530 { 1703 {
@@ -1585,13 +1758,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1585 m_host.AddScriptLPS(1); 1758 m_host.AddScriptLPS(1);
1586 1759
1587 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1760 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1588 1761 if (parts.Count > 0)
1589 foreach (SceneObjectPart part in parts) 1762 {
1590 SetAlpha(part, alpha, face); 1763 try
1764 {
1765 parts[0].ParentGroup.areUpdatesSuspended = true;
1766 foreach (SceneObjectPart part in parts)
1767 SetAlpha(part, alpha, face);
1768 }
1769 finally
1770 {
1771 parts[0].ParentGroup.areUpdatesSuspended = false;
1772 }
1773 }
1591 } 1774 }
1592 1775
1593 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1776 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1594 { 1777 {
1778 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1779 return;
1780
1595 Primitive.TextureEntry tex = part.Shape.Textures; 1781 Primitive.TextureEntry tex = part.Shape.Textures;
1596 Color4 texcolor; 1782 Color4 texcolor;
1597 if (face >= 0 && face < GetNumberOfSides(part)) 1783 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1644,7 +1830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1644 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1830 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1645 float wind, float tension, LSL_Vector Force) 1831 float wind, float tension, LSL_Vector Force)
1646 { 1832 {
1647 if (part == null) 1833 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1648 return; 1834 return;
1649 1835
1650 if (flexi) 1836 if (flexi)
@@ -1678,7 +1864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1678 /// <param name="falloff"></param> 1864 /// <param name="falloff"></param>
1679 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1865 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1680 { 1866 {
1681 if (part == null) 1867 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1682 return; 1868 return;
1683 1869
1684 if (light) 1870 if (light)
@@ -1755,15 +1941,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1755 m_host.AddScriptLPS(1); 1941 m_host.AddScriptLPS(1);
1756 1942
1757 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1943 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1758 1944 if (parts.Count > 0)
1759 foreach (SceneObjectPart part in parts) 1945 {
1760 SetTexture(part, texture, face); 1946 try
1761 1947 {
1948 parts[0].ParentGroup.areUpdatesSuspended = true;
1949 foreach (SceneObjectPart part in parts)
1950 SetTexture(part, texture, face);
1951 }
1952 finally
1953 {
1954 parts[0].ParentGroup.areUpdatesSuspended = false;
1955 }
1956 }
1762 ScriptSleep(200); 1957 ScriptSleep(200);
1763 } 1958 }
1764 1959
1765 protected void SetTexture(SceneObjectPart part, string texture, int face) 1960 protected void SetTexture(SceneObjectPart part, string texture, int face)
1766 { 1961 {
1962 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1963 return;
1964
1767 UUID textureID = new UUID(); 1965 UUID textureID = new UUID();
1768 1966
1769 textureID = InventoryKey(texture, (int)AssetType.Texture); 1967 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1808,6 +2006,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1808 2006
1809 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2007 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1810 { 2008 {
2009 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2010 return;
2011
1811 Primitive.TextureEntry tex = part.Shape.Textures; 2012 Primitive.TextureEntry tex = part.Shape.Textures;
1812 if (face >= 0 && face < GetNumberOfSides(part)) 2013 if (face >= 0 && face < GetNumberOfSides(part))
1813 { 2014 {
@@ -1844,6 +2045,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1844 2045
1845 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2046 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1846 { 2047 {
2048 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2049 return;
2050
1847 Primitive.TextureEntry tex = part.Shape.Textures; 2051 Primitive.TextureEntry tex = part.Shape.Textures;
1848 if (face >= 0 && face < GetNumberOfSides(part)) 2052 if (face >= 0 && face < GetNumberOfSides(part))
1849 { 2053 {
@@ -1880,6 +2084,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1880 2084
1881 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2085 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1882 { 2086 {
2087 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2088 return;
2089
1883 Primitive.TextureEntry tex = part.Shape.Textures; 2090 Primitive.TextureEntry tex = part.Shape.Textures;
1884 if (face >= 0 && face < GetNumberOfSides(part)) 2091 if (face >= 0 && face < GetNumberOfSides(part))
1885 { 2092 {
@@ -1984,26 +2191,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1984 return real_vec; 2191 return real_vec;
1985 } 2192 }
1986 2193
2194 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2195 {
2196 return new LSL_Integer(SetRegionPos(m_host, pos));
2197 }
2198
2199 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2200 {
2201 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2202 return 0;
2203
2204 SceneObjectGroup grp = part.ParentGroup;
2205
2206 if (grp.IsAttachment)
2207 return 0;
2208
2209 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2210 return 0;
2211
2212 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)
2213 return 0;
2214
2215 float constrainedX = (float)targetPos.x;
2216 float constrainedY = (float)targetPos.y;
2217
2218 if (constrainedX < 0.0f)
2219 constrainedX = 0.0f;
2220 if (constrainedY < 0.0f)
2221 constrainedY = 0.0f;
2222 if (constrainedX >= (float)Constants.RegionSize)
2223 constrainedX = (float)Constants.RegionSize - 0.1f;
2224 if (constrainedY >= (float)Constants.RegionSize)
2225 constrainedY = (float)Constants.RegionSize -0.1f;
2226
2227 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2228
2229 if (targetPos.z < ground)
2230 targetPos.z = ground;
2231
2232 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2233
2234 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2235 return 0;
2236
2237 grp.UpdateGroupPosition(dest);
2238
2239 return 1;
2240 }
2241
1987 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2242 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1988 { 2243 {
1989 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2244 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2245 return;
2246
1990 LSL_Vector currentPos = GetPartLocalPos(part); 2247 LSL_Vector currentPos = GetPartLocalPos(part);
2248 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1991 2249
1992 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1993 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1994 2250
1995 if (part.ParentGroup.RootPart == part) 2251 if (part.ParentGroup.RootPart == part)
1996 { 2252 {
1997 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1998 targetPos.z = ground;
1999 SceneObjectGroup parent = part.ParentGroup; 2253 SceneObjectGroup parent = part.ParentGroup;
2000 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2254 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)); 2255 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2256 return;
2257 Util.FireAndForget(delegate(object x) {
2258 parent.UpdateGroupPosition(dest);
2259 });
2002 } 2260 }
2003 else 2261 else
2004 { 2262 {
2005 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2263 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; 2264 SceneObjectGroup parent = part.ParentGroup;
2008 parent.HasGroupChanged = true; 2265 parent.HasGroupChanged = true;
2009 parent.ScheduleGroupForTerseUpdate(); 2266 parent.ScheduleGroupForTerseUpdate();
@@ -2036,17 +2293,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2036 else 2293 else
2037 { 2294 {
2038 if (part.ParentGroup.IsAttachment) 2295 if (part.ParentGroup.IsAttachment)
2039 {
2040 pos = part.AttachedPos; 2296 pos = part.AttachedPos;
2041 }
2042 else 2297 else
2043 {
2044 pos = part.AbsolutePosition; 2298 pos = part.AbsolutePosition;
2045 }
2046 } 2299 }
2047 2300
2048// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2049
2050 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2301 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2051 } 2302 }
2052 2303
@@ -2055,9 +2306,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2055 m_host.AddScriptLPS(1); 2306 m_host.AddScriptLPS(1);
2056 2307
2057 // try to let this work as in SL... 2308 // try to let this work as in SL...
2058 if (m_host.ParentID == 0) 2309 if (m_host.LinkNum < 2)
2059 { 2310 {
2060 // special case: If we are root, rotate complete SOG to new rotation 2311 // Special case: If we are root, rotate complete SOG to new
2312 // rotation.
2313 // We are root if the link number is 0 (single prim) or 1
2314 // (root prim). ParentID may be nonzero in attachments and
2315 // using it would cause attachments and HUDs to rotate
2316 // to the wrong positions.
2061 SetRot(m_host, Rot2Quaternion(rot)); 2317 SetRot(m_host, Rot2Quaternion(rot));
2062 } 2318 }
2063 else 2319 else
@@ -2082,6 +2338,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2082 2338
2083 protected void SetRot(SceneObjectPart part, Quaternion rot) 2339 protected void SetRot(SceneObjectPart part, Quaternion rot)
2084 { 2340 {
2341 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2342 return;
2343
2085 part.UpdateRotation(rot); 2344 part.UpdateRotation(rot);
2086 // Update rotation does not move the object in the physics scene if it's a linkset. 2345 // Update rotation does not move the object in the physics scene if it's a linkset.
2087 2346
@@ -2236,13 +2495,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2236 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2495 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2237 { 2496 {
2238 m_host.AddScriptLPS(1); 2497 m_host.AddScriptLPS(1);
2239 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2498 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2240 } 2499 }
2241 2500
2242 public void llSetTorque(LSL_Vector torque, int local) 2501 public void llSetTorque(LSL_Vector torque, int local)
2243 { 2502 {
2244 m_host.AddScriptLPS(1); 2503 m_host.AddScriptLPS(1);
2245 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2504 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2246 } 2505 }
2247 2506
2248 public LSL_Vector llGetTorque() 2507 public LSL_Vector llGetTorque()
@@ -2846,35 +3105,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2846 public void llLookAt(LSL_Vector target, double strength, double damping) 3105 public void llLookAt(LSL_Vector target, double strength, double damping)
2847 { 3106 {
2848 m_host.AddScriptLPS(1); 3107 m_host.AddScriptLPS(1);
2849 // Determine where we are looking from
2850 LSL_Vector from = llGetPos();
2851 3108
2852 // Work out the normalised vector from the source to the target 3109 // Get the normalized vector to the target
2853 LSL_Vector delta = llVecNorm(target - from); 3110 LSL_Vector d1 = llVecNorm(target - llGetPos());
2854 LSL_Vector angle = new LSL_Vector(0,0,0);
2855 3111
2856 // Calculate the yaw 3112 // Get the bearing (yaw)
2857 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3113 LSL_Vector a1 = new LSL_Vector(0,0,0);
2858 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3114 a1.z = llAtan2(d1.y, d1.x);
2859 3115
2860 // Calculate pitch 3116 // Get the elevation (pitch)
2861 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3117 LSL_Vector a2 = new LSL_Vector(0,0,0);
3118 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2862 3119
2863 // we need to convert from a vector describing 3120 LSL_Rotation r1 = llEuler2Rot(a1);
2864 // the angles of rotation in radians into rotation value 3121 LSL_Rotation r2 = llEuler2Rot(a2);
2865 LSL_Rotation rot = llEuler2Rot(angle); 3122 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2866
2867 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2868 // set the rotation of the object, copy that behavior
2869 PhysicsActor pa = m_host.PhysActor;
2870 3123
2871 if (strength == 0 || pa == null || !pa.IsPhysical) 3124 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2872 { 3125 {
2873 llSetRot(rot); 3126 // Do nothing if either value is 0 (this has been checked in SL)
3127 if (strength <= 0.0 || damping <= 0.0)
3128 return;
3129
3130 llSetRot(r3 * r2 * r1);
2874 } 3131 }
2875 else 3132 else
2876 { 3133 {
2877 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3134 if (strength == 0)
3135 {
3136 llSetRot(r3 * r2 * r1);
3137 return;
3138 }
3139
3140 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2878 } 3141 }
2879 } 3142 }
2880 3143
@@ -2919,17 +3182,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2919 } 3182 }
2920 else 3183 else
2921 { 3184 {
2922 if (m_host.IsRoot) 3185 // new SL always returns object mass
2923 { 3186// if (m_host.IsRoot)
3187// {
2924 return m_host.ParentGroup.GetMass(); 3188 return m_host.ParentGroup.GetMass();
2925 } 3189// }
2926 else 3190// else
2927 { 3191// {
2928 return m_host.GetMass(); 3192// return m_host.GetMass();
2929 } 3193// }
2930 } 3194 }
2931 } 3195 }
2932 3196
3197
3198 public LSL_Float llGetMassMKS()
3199 {
3200 return 100f * llGetMass();
3201 }
3202
2933 public void llCollisionFilter(string name, string id, int accept) 3203 public void llCollisionFilter(string name, string id, int accept)
2934 { 3204 {
2935 m_host.AddScriptLPS(1); 3205 m_host.AddScriptLPS(1);
@@ -3040,11 +3310,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3040 { 3310 {
3041 m_host.AddScriptLPS(1); 3311 m_host.AddScriptLPS(1);
3042 3312
3043// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3044// return;
3045
3046 TaskInventoryItem item = GetSelfInventoryItem(); 3313 TaskInventoryItem item = GetSelfInventoryItem();
3047 3314
3315 m_host.TaskInventory.LockItemsForRead(false);
3316
3048 if (item.PermsGranter != m_host.OwnerID) 3317 if (item.PermsGranter != m_host.OwnerID)
3049 return; 3318 return;
3050 3319
@@ -3089,6 +3358,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3089 3358
3090 public void llInstantMessage(string user, string message) 3359 public void llInstantMessage(string user, string message)
3091 { 3360 {
3361 UUID result;
3362 if (!UUID.TryParse(user, out result))
3363 {
3364 ShoutError("An invalid key was passed to llInstantMessage");
3365 ScriptSleep(2000);
3366 return;
3367 }
3368
3369
3092 m_host.AddScriptLPS(1); 3370 m_host.AddScriptLPS(1);
3093 3371
3094 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3372 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3103,14 +3381,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3103 UUID friendTransactionID = UUID.Random(); 3381 UUID friendTransactionID = UUID.Random();
3104 3382
3105 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3383 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3106 3384
3107 GridInstantMessage msg = new GridInstantMessage(); 3385 GridInstantMessage msg = new GridInstantMessage();
3108 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3386 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3109 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3387 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3110 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3388 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3111// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3389// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3112// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3390// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3113 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3391// DateTime dt = DateTime.UtcNow;
3392//
3393// // Ticks from UtcNow, but make it look like local. Evil, huh?
3394// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3395//
3396// try
3397// {
3398// // Convert that to the PST timezone
3399// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3400// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3401// }
3402// catch
3403// {
3404// // No logging here, as it could be VERY spammy
3405// }
3406//
3407// // And make it look local again to fool the unix time util
3408// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3409
3410 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3411
3114 //if (client != null) 3412 //if (client != null)
3115 //{ 3413 //{
3116 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3414 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3124,12 +3422,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3124 msg.message = message.Substring(0, 1024); 3422 msg.message = message.Substring(0, 1024);
3125 else 3423 else
3126 msg.message = message; 3424 msg.message = message;
3127 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3425 msg.dialog = (byte)19; // MessageFromObject
3128 msg.fromGroup = false;// fromGroup; 3426 msg.fromGroup = false;// fromGroup;
3129 msg.offline = (byte)0; //offline; 3427 msg.offline = (byte)0; //offline;
3130 msg.ParentEstateID = 0; //ParentEstateID; 3428 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3131 msg.Position = new Vector3(m_host.AbsolutePosition); 3429 msg.Position = new Vector3(m_host.AbsolutePosition);
3132 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3430 msg.RegionID = World.RegionInfo.RegionID.Guid;
3133 msg.binaryBucket 3431 msg.binaryBucket
3134 = Util.StringToBytes256( 3432 = Util.StringToBytes256(
3135 "{0}/{1}/{2}/{3}", 3433 "{0}/{1}/{2}/{3}",
@@ -3157,7 +3455,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3157 } 3455 }
3158 3456
3159 emailModule.SendEmail(m_host.UUID, address, subject, message); 3457 emailModule.SendEmail(m_host.UUID, address, subject, message);
3160 ScriptSleep(20000); 3458 ScriptSleep(15000);
3161 } 3459 }
3162 3460
3163 public void llGetNextEmail(string address, string subject) 3461 public void llGetNextEmail(string address, string subject)
@@ -3406,15 +3704,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3406 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3704 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3407 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3705 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3408 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3706 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3707 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3409 ScriptBaseClass.PERMISSION_ATTACH; 3708 ScriptBaseClass.PERMISSION_ATTACH;
3410 3709
3411 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3710 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3412 { 3711 {
3413 lock (m_host.TaskInventory) 3712 m_host.TaskInventory.LockItemsForWrite(true);
3414 { 3713 m_host.TaskInventory[m_itemID].PermsGranter = agentID;
3415 m_host.TaskInventory[m_itemID].PermsGranter = agentID; 3714 m_host.TaskInventory[m_itemID].PermsMask = perm;
3416 m_host.TaskInventory[m_itemID].PermsMask = perm; 3715 m_host.TaskInventory.LockItemsForWrite(false);
3417 }
3418 3716
3419 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3717 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3420 "run_time_permissions", new Object[] { 3718 "run_time_permissions", new Object[] {
@@ -3424,28 +3722,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3424 return; 3722 return;
3425 } 3723 }
3426 } 3724 }
3427 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3725 else
3428 { 3726 {
3429 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3727 bool sitting = false;
3430 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3728 if (m_host.SitTargetAvatar == agentID)
3431 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3729 {
3432 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3730 sitting = true;
3433 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3731 }
3732 else
3733 {
3734 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3735 {
3736 if (p.SitTargetAvatar == agentID)
3737 sitting = true;
3738 }
3739 }
3434 3740
3435 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3741 if (sitting)
3436 { 3742 {
3437 lock (m_host.TaskInventory) 3743 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3744 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3745 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3746 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3747 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3748
3749 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3438 { 3750 {
3751 m_host.TaskInventory.LockItemsForWrite(true);
3439 m_host.TaskInventory[m_itemID].PermsGranter = agentID; 3752 m_host.TaskInventory[m_itemID].PermsGranter = agentID;
3440 m_host.TaskInventory[m_itemID].PermsMask = perm; 3753 m_host.TaskInventory[m_itemID].PermsMask = perm;
3441 } 3754 m_host.TaskInventory.LockItemsForWrite(false);
3442 3755
3443 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3756 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3444 "run_time_permissions", new Object[] { 3757 "run_time_permissions", new Object[] {
3445 new LSL_Integer(perm) }, 3758 new LSL_Integer(perm) },
3446 new DetectParams[0])); 3759 new DetectParams[0]));
3447 3760
3448 return; 3761 return;
3762 }
3449 } 3763 }
3450 } 3764 }
3451 3765
@@ -3459,11 +3773,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3459 3773
3460 if (!m_waitingForScriptAnswer) 3774 if (!m_waitingForScriptAnswer)
3461 { 3775 {
3462 lock (m_host.TaskInventory) 3776 m_host.TaskInventory.LockItemsForWrite(true);
3463 { 3777 m_host.TaskInventory[m_itemID].PermsGranter = agentID;
3464 m_host.TaskInventory[m_itemID].PermsGranter = agentID; 3778 m_host.TaskInventory[m_itemID].PermsMask = 0;
3465 m_host.TaskInventory[m_itemID].PermsMask = 0; 3779 m_host.TaskInventory.LockItemsForWrite(false);
3466 }
3467 3780
3468 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3781 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3469 m_waitingForScriptAnswer=true; 3782 m_waitingForScriptAnswer=true;
@@ -3493,11 +3806,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3493 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3806 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3494 llReleaseControls(); 3807 llReleaseControls();
3495 3808
3496 lock (m_host.TaskInventory) 3809 m_host.TaskInventory.LockItemsForWrite(true);
3497 { 3810 m_host.TaskInventory[m_itemID].PermsMask = answer;
3498 m_host.TaskInventory[m_itemID].PermsMask = answer; 3811 m_host.TaskInventory.LockItemsForWrite(false);
3499 } 3812
3500
3501 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3813 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3502 "run_time_permissions", new Object[] { 3814 "run_time_permissions", new Object[] {
3503 new LSL_Integer(answer) }, 3815 new LSL_Integer(answer) },
@@ -3540,9 +3852,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3540 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3852 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3541 { 3853 {
3542 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3854 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3543 3855 if (parts.Count > 0)
3544 foreach (SceneObjectPart part in parts) 3856 {
3545 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3857 try
3858 {
3859 parts[0].ParentGroup.areUpdatesSuspended = true;
3860 foreach (SceneObjectPart part in parts)
3861 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3862 }
3863 finally
3864 {
3865 parts[0].ParentGroup.areUpdatesSuspended = false;
3866 }
3867 }
3546 } 3868 }
3547 3869
3548 public void llCreateLink(string target, int parent) 3870 public void llCreateLink(string target, int parent)
@@ -3572,11 +3894,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3572 3894
3573 if (targetPart.ParentGroup.AttachmentPoint != 0) 3895 if (targetPart.ParentGroup.AttachmentPoint != 0)
3574 return; // Fail silently if attached 3896 return; // Fail silently if attached
3897
3898 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3899 return;
3900
3575 SceneObjectGroup parentPrim = null, childPrim = null; 3901 SceneObjectGroup parentPrim = null, childPrim = null;
3576 3902
3577 if (targetPart != null) 3903 if (targetPart != null)
3578 { 3904 {
3579 if (parent != 0) { 3905 if (parent != 0)
3906 {
3580 parentPrim = m_host.ParentGroup; 3907 parentPrim = m_host.ParentGroup;
3581 childPrim = targetPart.ParentGroup; 3908 childPrim = targetPart.ParentGroup;
3582 } 3909 }
@@ -3588,7 +3915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3588 3915
3589 // Required for linking 3916 // Required for linking
3590 childPrim.RootPart.ClearUpdateSchedule(); 3917 childPrim.RootPart.ClearUpdateSchedule();
3591 parentPrim.LinkToGroup(childPrim); 3918 parentPrim.LinkToGroup(childPrim, true);
3592 } 3919 }
3593 3920
3594 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3921 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3651,10 +3978,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3651 // Restructuring Multiple Prims. 3978 // Restructuring Multiple Prims.
3652 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3979 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3653 parts.Remove(parentPrim.RootPart); 3980 parts.Remove(parentPrim.RootPart);
3654 foreach (SceneObjectPart part in parts) 3981 if (parts.Count > 0)
3655 { 3982 {
3656 parentPrim.DelinkFromGroup(part.LocalId, true); 3983 try
3984 {
3985 parts[0].ParentGroup.areUpdatesSuspended = true;
3986 foreach (SceneObjectPart part in parts)
3987 {
3988 parentPrim.DelinkFromGroup(part.LocalId, true);
3989 }
3990 }
3991 finally
3992 {
3993 parts[0].ParentGroup.areUpdatesSuspended = false;
3994 }
3657 } 3995 }
3996
3658 parentPrim.HasGroupChanged = true; 3997 parentPrim.HasGroupChanged = true;
3659 parentPrim.ScheduleGroupForFullUpdate(); 3998 parentPrim.ScheduleGroupForFullUpdate();
3660 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3999 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3663,12 +4002,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3663 { 4002 {
3664 SceneObjectPart newRoot = parts[0]; 4003 SceneObjectPart newRoot = parts[0];
3665 parts.Remove(newRoot); 4004 parts.Remove(newRoot);
3666 foreach (SceneObjectPart part in parts) 4005
4006 try
3667 { 4007 {
3668 // Required for linking 4008 parts[0].ParentGroup.areUpdatesSuspended = true;
3669 part.ClearUpdateSchedule(); 4009 foreach (SceneObjectPart part in parts)
3670 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4010 {
4011 part.ClearUpdateSchedule();
4012 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4013 }
3671 } 4014 }
4015 finally
4016 {
4017 parts[0].ParentGroup.areUpdatesSuspended = false;
4018 }
4019
4020
3672 newRoot.ParentGroup.HasGroupChanged = true; 4021 newRoot.ParentGroup.HasGroupChanged = true;
3673 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4022 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3674 } 4023 }
@@ -3688,6 +4037,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3688 public void llBreakAllLinks() 4037 public void llBreakAllLinks()
3689 { 4038 {
3690 m_host.AddScriptLPS(1); 4039 m_host.AddScriptLPS(1);
4040
4041 TaskInventoryItem item = GetSelfInventoryItem();
4042
4043 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4044 && !m_automaticLinkPermission)
4045 {
4046 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4047 return;
4048 }
4049
3691 SceneObjectGroup parentPrim = m_host.ParentGroup; 4050 SceneObjectGroup parentPrim = m_host.ParentGroup;
3692 if (parentPrim.AttachmentPoint != 0) 4051 if (parentPrim.AttachmentPoint != 0)
3693 return; // Fail silently if attached 4052 return; // Fail silently if attached
@@ -3707,25 +4066,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3707 public LSL_String llGetLinkKey(int linknum) 4066 public LSL_String llGetLinkKey(int linknum)
3708 { 4067 {
3709 m_host.AddScriptLPS(1); 4068 m_host.AddScriptLPS(1);
3710 List<UUID> keytable = new List<UUID>();
3711 // parse for sitting avatare-uuids
3712 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3713 {
3714 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3715 keytable.Add(presence.UUID);
3716 });
3717
3718 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3719 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3720 {
3721 return keytable[totalprims - linknum].ToString();
3722 }
3723
3724 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3725 {
3726 return m_host.UUID.ToString();
3727 }
3728
3729 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4069 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3730 if (part != null) 4070 if (part != null)
3731 { 4071 {
@@ -3733,6 +4073,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3733 } 4073 }
3734 else 4074 else
3735 { 4075 {
4076 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4077 {
4078 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4079
4080 if (linknum < 0)
4081 return UUID.Zero.ToString();
4082
4083 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4084 if (avatars.Count > linknum)
4085 {
4086 return avatars[linknum].UUID.ToString();
4087 }
4088 }
3736 return UUID.Zero.ToString(); 4089 return UUID.Zero.ToString();
3737 } 4090 }
3738 } 4091 }
@@ -3832,17 +4185,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3832 m_host.AddScriptLPS(1); 4185 m_host.AddScriptLPS(1);
3833 int count = 0; 4186 int count = 0;
3834 4187
3835 lock (m_host.TaskInventory) 4188 m_host.TaskInventory.LockItemsForRead(true);
4189 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3836 { 4190 {
3837 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4191 if (inv.Value.Type == type || type == -1)
3838 { 4192 {
3839 if (inv.Value.Type == type || type == -1) 4193 count = count + 1;
3840 {
3841 count = count + 1;
3842 }
3843 } 4194 }
3844 } 4195 }
3845 4196
4197 m_host.TaskInventory.LockItemsForRead(false);
3846 return count; 4198 return count;
3847 } 4199 }
3848 4200
@@ -3851,16 +4203,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3851 m_host.AddScriptLPS(1); 4203 m_host.AddScriptLPS(1);
3852 ArrayList keys = new ArrayList(); 4204 ArrayList keys = new ArrayList();
3853 4205
3854 lock (m_host.TaskInventory) 4206 m_host.TaskInventory.LockItemsForRead(true);
4207 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3855 { 4208 {
3856 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4209 if (inv.Value.Type == type || type == -1)
3857 { 4210 {
3858 if (inv.Value.Type == type || type == -1) 4211 keys.Add(inv.Value.Name);
3859 {
3860 keys.Add(inv.Value.Name);
3861 }
3862 } 4212 }
3863 } 4213 }
4214 m_host.TaskInventory.LockItemsForRead(false);
3864 4215
3865 if (keys.Count == 0) 4216 if (keys.Count == 0)
3866 { 4217 {
@@ -3897,25 +4248,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3897 } 4248 }
3898 4249
3899 // move the first object found with this inventory name 4250 // move the first object found with this inventory name
3900 lock (m_host.TaskInventory) 4251 m_host.TaskInventory.LockItemsForRead(true);
4252 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3901 { 4253 {
3902 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4254 if (inv.Value.Name == inventory)
3903 { 4255 {
3904 if (inv.Value.Name == inventory) 4256 found = true;
3905 { 4257 objId = inv.Key;
3906 found = true; 4258 assetType = inv.Value.Type;
3907 objId = inv.Key; 4259 objName = inv.Value.Name;
3908 assetType = inv.Value.Type; 4260 break;
3909 objName = inv.Value.Name;
3910 break;
3911 }
3912 } 4261 }
3913 } 4262 }
4263 m_host.TaskInventory.LockItemsForRead(false);
3914 4264
3915 if (!found) 4265 if (!found)
3916 { 4266 {
3917 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4267 llSay(0, String.Format("Could not find object '{0}'", inventory));
3918 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4268 return;
4269// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3919 } 4270 }
3920 4271
3921 // check if destination is an object 4272 // check if destination is an object
@@ -3941,48 +4292,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3941 return; 4292 return;
3942 } 4293 }
3943 } 4294 }
4295
3944 // destination is an avatar 4296 // destination is an avatar
3945 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4297 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3946 4298
3947 if (agentItem == null) 4299 if (agentItem == null)
3948 return; 4300 return;
3949 4301
3950 byte[] bucket = new byte[17]; 4302 byte[] bucket = new byte[1];
3951 bucket[0] = (byte)assetType; 4303 bucket[0] = (byte)assetType;
3952 byte[] objBytes = agentItem.ID.GetBytes(); 4304 //byte[] objBytes = agentItem.ID.GetBytes();
3953 Array.Copy(objBytes, 0, bucket, 1, 16); 4305 //Array.Copy(objBytes, 0, bucket, 1, 16);
3954 4306
3955 GridInstantMessage msg = new GridInstantMessage(World, 4307 GridInstantMessage msg = new GridInstantMessage(World,
3956 m_host.UUID, m_host.Name+", an object owned by "+ 4308 m_host.OwnerID, m_host.Name, destId,
3957 resolveName(m_host.OwnerID)+",", destId,
3958 (byte)InstantMessageDialog.TaskInventoryOffered, 4309 (byte)InstantMessageDialog.TaskInventoryOffered,
3959 false, objName+"\n"+m_host.Name+" is located at "+ 4310 false, objName+". "+m_host.Name+" is located at "+
3960 World.RegionInfo.RegionName+" "+ 4311 World.RegionInfo.RegionName+" "+
3961 m_host.AbsolutePosition.ToString(), 4312 m_host.AbsolutePosition.ToString(),
3962 agentItem.ID, true, m_host.AbsolutePosition, 4313 agentItem.ID, true, m_host.AbsolutePosition,
3963 bucket); 4314 bucket);
3964 if (m_TransferModule != null) 4315
3965 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4316 ScenePresence sp;
4317
4318 if (World.TryGetScenePresence(destId, out sp))
4319 {
4320 sp.ControllingClient.SendInstantMessage(msg);
4321 }
4322 else
4323 {
4324 if (m_TransferModule != null)
4325 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4326 }
4327
4328 //This delay should only occur when giving inventory to avatars.
3966 ScriptSleep(3000); 4329 ScriptSleep(3000);
3967 } 4330 }
3968 } 4331 }
3969 4332
4333 [DebuggerNonUserCode]
3970 public void llRemoveInventory(string name) 4334 public void llRemoveInventory(string name)
3971 { 4335 {
3972 m_host.AddScriptLPS(1); 4336 m_host.AddScriptLPS(1);
3973 4337
3974 lock (m_host.TaskInventory) 4338 List<TaskInventoryItem> inv;
4339 try
3975 { 4340 {
3976 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4341 m_host.TaskInventory.LockItemsForRead(true);
4342 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4343 }
4344 finally
4345 {
4346 m_host.TaskInventory.LockItemsForRead(false);
4347 }
4348 foreach (TaskInventoryItem item in inv)
4349 {
4350 if (item.Name == name)
3977 { 4351 {
3978 if (item.Name == name) 4352 if (item.ItemID == m_itemID)
3979 { 4353 throw new ScriptDeleteException();
3980 if (item.ItemID == m_itemID) 4354 else
3981 throw new ScriptDeleteException(); 4355 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3982 else 4356 return;
3983 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3984 return;
3985 }
3986 } 4357 }
3987 } 4358 }
3988 } 4359 }
@@ -4017,115 +4388,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4017 { 4388 {
4018 m_host.AddScriptLPS(1); 4389 m_host.AddScriptLPS(1);
4019 4390
4020 UUID uuid = (UUID)id; 4391 UUID uuid;
4021 PresenceInfo pinfo = null; 4392 if (UUID.TryParse(id, out uuid))
4022 UserAccount account;
4023
4024 UserInfoCacheEntry ce;
4025 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4026 { 4393 {
4027 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4394 PresenceInfo pinfo = null;
4028 if (account == null) 4395 UserAccount account;
4396
4397 UserInfoCacheEntry ce;
4398 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4029 { 4399 {
4030 m_userInfoCache[uuid] = null; // Cache negative 4400 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4031 return UUID.Zero.ToString(); 4401 if (account == null)
4032 } 4402 {
4403 m_userInfoCache[uuid] = null; // Cache negative
4404 return UUID.Zero.ToString();
4405 }
4033 4406
4034 4407
4035 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4408 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4036 if (pinfos != null && pinfos.Length > 0) 4409 if (pinfos != null && pinfos.Length > 0)
4037 {
4038 foreach (PresenceInfo p in pinfos)
4039 { 4410 {
4040 if (p.RegionID != UUID.Zero) 4411 foreach (PresenceInfo p in pinfos)
4041 { 4412 {
4042 pinfo = p; 4413 if (p.RegionID != UUID.Zero)
4414 {
4415 pinfo = p;
4416 }
4043 } 4417 }
4044 } 4418 }
4045 }
4046 4419
4047 ce = new UserInfoCacheEntry(); 4420 ce = new UserInfoCacheEntry();
4048 ce.time = Util.EnvironmentTickCount(); 4421 ce.time = Util.EnvironmentTickCount();
4049 ce.account = account; 4422 ce.account = account;
4050 ce.pinfo = pinfo; 4423 ce.pinfo = pinfo;
4051 } 4424 m_userInfoCache[uuid] = ce;
4052 else 4425 }
4053 { 4426 else
4054 if (ce == null) 4427 {
4055 return UUID.Zero.ToString(); 4428 if (ce == null)
4429 return UUID.Zero.ToString();
4056 4430
4057 account = ce.account; 4431 account = ce.account;
4058 pinfo = ce.pinfo; 4432 pinfo = ce.pinfo;
4059 } 4433 }
4060 4434
4061 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4435 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4062 {
4063 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4064 if (pinfos != null && pinfos.Length > 0)
4065 { 4436 {
4066 foreach (PresenceInfo p in pinfos) 4437 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4438 if (pinfos != null && pinfos.Length > 0)
4067 { 4439 {
4068 if (p.RegionID != UUID.Zero) 4440 foreach (PresenceInfo p in pinfos)
4069 { 4441 {
4070 pinfo = p; 4442 if (p.RegionID != UUID.Zero)
4443 {
4444 pinfo = p;
4445 }
4071 } 4446 }
4072 } 4447 }
4073 } 4448 else
4074 else 4449 pinfo = null;
4075 pinfo = null;
4076 4450
4077 ce.time = Util.EnvironmentTickCount(); 4451 ce.time = Util.EnvironmentTickCount();
4078 ce.pinfo = pinfo; 4452 ce.pinfo = pinfo;
4079 } 4453 }
4080 4454
4081 string reply = String.Empty; 4455 string reply = String.Empty;
4082 4456
4083 switch (data) 4457 switch (data)
4084 { 4458 {
4085 case 1: // DATA_ONLINE (0|1) 4459 case 1: // DATA_ONLINE (0|1)
4086 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4460 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4087 reply = "1"; 4461 reply = "1";
4088 else 4462 else
4089 reply = "0"; 4463 reply = "0";
4090 break; 4464 break;
4091 case 2: // DATA_NAME (First Last) 4465 case 2: // DATA_NAME (First Last)
4092 reply = account.FirstName + " " + account.LastName; 4466 reply = account.FirstName + " " + account.LastName;
4093 break; 4467 break;
4094 case 3: // DATA_BORN (YYYY-MM-DD) 4468 case 3: // DATA_BORN (YYYY-MM-DD)
4095 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4469 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4096 born = born.AddSeconds(account.Created); 4470 born = born.AddSeconds(account.Created);
4097 reply = born.ToString("yyyy-MM-dd"); 4471 reply = born.ToString("yyyy-MM-dd");
4098 break; 4472 break;
4099 case 4: // DATA_RATING (0,0,0,0,0,0) 4473 case 4: // DATA_RATING (0,0,0,0,0,0)
4100 reply = "0,0,0,0,0,0"; 4474 reply = "0,0,0,0,0,0";
4101 break; 4475 break;
4102 case 7: // DATA_USERLEVEL (integer) 4476 case 8: // DATA_PAYINFO (0|1|2|3)
4103 reply = account.UserLevel.ToString(); 4477 reply = "0";
4104 break; 4478 break;
4105 case 8: // DATA_PAYINFO (0|1|2|3) 4479 default:
4106 reply = "0"; 4480 return UUID.Zero.ToString(); // Raise no event
4107 break; 4481 }
4108 default:
4109 return UUID.Zero.ToString(); // Raise no event
4110 }
4111 4482
4112 UUID rq = UUID.Random(); 4483 UUID rq = UUID.Random();
4113 4484
4114 UUID tid = AsyncCommands. 4485 UUID tid = AsyncCommands.
4115 DataserverPlugin.RegisterRequest(m_localID, 4486 DataserverPlugin.RegisterRequest(m_localID,
4116 m_itemID, rq.ToString()); 4487 m_itemID, rq.ToString());
4117 4488
4118 AsyncCommands. 4489 AsyncCommands.
4119 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4490 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4120 4491
4121 ScriptSleep(100); 4492 ScriptSleep(100);
4122 return tid.ToString(); 4493 return tid.ToString();
4494 }
4495 else
4496 {
4497 ShoutError("Invalid UUID passed to llRequestAgentData.");
4498 }
4499 return "";
4123 } 4500 }
4124 4501
4125 public LSL_String llRequestInventoryData(string name) 4502 public LSL_String llRequestInventoryData(string name)
4126 { 4503 {
4127 m_host.AddScriptLPS(1); 4504 m_host.AddScriptLPS(1);
4128 4505
4506 //Clone is thread safe
4129 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4507 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4130 4508
4131 foreach (TaskInventoryItem item in itemDictionary.Values) 4509 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4177,19 +4555,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4177 if (UUID.TryParse(agent, out agentId)) 4555 if (UUID.TryParse(agent, out agentId))
4178 { 4556 {
4179 ScenePresence presence = World.GetScenePresence(agentId); 4557 ScenePresence presence = World.GetScenePresence(agentId);
4180 if (presence != null) 4558 if (presence != null && presence.PresenceType != PresenceType.Npc)
4181 { 4559 {
4560 // agent must not be a god
4561 if (presence.UserLevel >= 200) return;
4562
4182 // agent must be over the owners land 4563 // agent must be over the owners land
4183 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4564 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4184 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4565 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4185 { 4566 {
4186 World.TeleportClientHome(agentId, presence.ControllingClient); 4567 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4568 {
4569 // They can't be teleported home for some reason
4570 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4571 if (regionInfo != null)
4572 {
4573 World.RequestTeleportLocation(
4574 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4575 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4576 }
4577 }
4187 } 4578 }
4188 } 4579 }
4189 } 4580 }
4190 ScriptSleep(5000); 4581 ScriptSleep(5000);
4191 } 4582 }
4192 4583
4584 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4585 {
4586 m_host.AddScriptLPS(1);
4587 UUID agentId = new UUID();
4588 if (UUID.TryParse(agent, out agentId))
4589 {
4590 ScenePresence presence = World.GetScenePresence(agentId);
4591 if (presence != null && presence.PresenceType != PresenceType.Npc)
4592 {
4593 // agent must not be a god
4594 if (presence.GodLevel >= 200) return;
4595
4596 if (simname == String.Empty)
4597 simname = World.RegionInfo.RegionName;
4598
4599 // agent must be over the owners land
4600 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4601 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4602 {
4603 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);
4604 }
4605 else // or must be wearing the prim
4606 {
4607 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4608 {
4609 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);
4610 }
4611 }
4612 }
4613 }
4614 }
4615
4193 public void llTextBox(string agent, string message, int chatChannel) 4616 public void llTextBox(string agent, string message, int chatChannel)
4194 { 4617 {
4195 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4618 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4201,7 +4624,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4201 UUID av = new UUID(); 4624 UUID av = new UUID();
4202 if (!UUID.TryParse(agent,out av)) 4625 if (!UUID.TryParse(agent,out av))
4203 { 4626 {
4204 LSLError("First parameter to llDialog needs to be a key"); 4627 //LSLError("First parameter to llDialog needs to be a key");
4205 return; 4628 return;
4206 } 4629 }
4207 4630
@@ -4238,17 +4661,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4238 UUID soundId = UUID.Zero; 4661 UUID soundId = UUID.Zero;
4239 if (!UUID.TryParse(impact_sound, out soundId)) 4662 if (!UUID.TryParse(impact_sound, out soundId))
4240 { 4663 {
4241 lock (m_host.TaskInventory) 4664 m_host.TaskInventory.LockItemsForRead(true);
4665 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4242 { 4666 {
4243 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4667 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4244 { 4668 {
4245 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4669 soundId = item.AssetID;
4246 { 4670 break;
4247 soundId = item.AssetID;
4248 break;
4249 }
4250 } 4671 }
4251 } 4672 }
4673 m_host.TaskInventory.LockItemsForRead(false);
4252 } 4674 }
4253 m_host.CollisionSound = soundId; 4675 m_host.CollisionSound = soundId;
4254 m_host.CollisionSoundVolume = (float)impact_volume; 4676 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4288,6 +4710,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4288 UUID partItemID; 4710 UUID partItemID;
4289 foreach (SceneObjectPart part in parts) 4711 foreach (SceneObjectPart part in parts)
4290 { 4712 {
4713 //Clone is thread safe
4291 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4714 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4292 4715
4293 foreach (TaskInventoryItem item in itemsDictionary.Values) 4716 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4421,7 +4844,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4421 { 4844 {
4422 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4845 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4423 float distance_term = distance * distance * distance; // Script Energy 4846 float distance_term = distance * distance * distance; // Script Energy
4424 float pusher_mass = m_host.GetMass(); 4847 // use total object mass and not part
4848 float pusher_mass = m_host.ParentGroup.GetMass();
4425 4849
4426 float PUSH_ATTENUATION_DISTANCE = 17f; 4850 float PUSH_ATTENUATION_DISTANCE = 17f;
4427 float PUSH_ATTENUATION_SCALE = 5f; 4851 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4662,23 +5086,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4662 { 5086 {
4663 m_host.AddScriptLPS(1); 5087 m_host.AddScriptLPS(1);
4664 5088
4665 lock (m_host.TaskInventory) 5089 m_host.TaskInventory.LockItemsForRead(true);
5090 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4666 { 5091 {
4667 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5092 if (inv.Value.Name == name)
4668 { 5093 {
4669 if (inv.Value.Name == name) 5094 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4670 { 5095 {
4671 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5096 m_host.TaskInventory.LockItemsForRead(false);
4672 { 5097 return inv.Value.AssetID.ToString();
4673 return inv.Value.AssetID.ToString(); 5098 }
4674 } 5099 else
4675 else 5100 {
4676 { 5101 m_host.TaskInventory.LockItemsForRead(false);
4677 return UUID.Zero.ToString(); 5102 return UUID.Zero.ToString();
4678 }
4679 } 5103 }
4680 } 5104 }
4681 } 5105 }
5106 m_host.TaskInventory.LockItemsForRead(false);
4682 5107
4683 return UUID.Zero.ToString(); 5108 return UUID.Zero.ToString();
4684 } 5109 }
@@ -4831,14 +5256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4831 { 5256 {
4832 m_host.AddScriptLPS(1); 5257 m_host.AddScriptLPS(1);
4833 5258
4834 if (src == null) 5259 return src.Length;
4835 {
4836 return 0;
4837 }
4838 else
4839 {
4840 return src.Length;
4841 }
4842 } 5260 }
4843 5261
4844 public LSL_Integer llList2Integer(LSL_List src, int index) 5262 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4884,7 +5302,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4884 else if (src.Data[index] is LSL_Float) 5302 else if (src.Data[index] is LSL_Float)
4885 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5303 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4886 else if (src.Data[index] is LSL_String) 5304 else if (src.Data[index] is LSL_String)
4887 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5305 {
5306 string str = ((LSL_String) src.Data[index]).m_string;
5307 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5308 if (m != Match.Empty)
5309 {
5310 str = m.Value;
5311 double d = 0.0;
5312 if (!Double.TryParse(str, out d))
5313 return 0.0;
5314
5315 return d;
5316 }
5317 return 0.0;
5318 }
4888 return Convert.ToDouble(src.Data[index]); 5319 return Convert.ToDouble(src.Data[index]);
4889 } 5320 }
4890 catch (FormatException) 5321 catch (FormatException)
@@ -5157,7 +5588,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5157 } 5588 }
5158 } 5589 }
5159 } 5590 }
5160 else { 5591 else
5592 {
5161 object[] array = new object[src.Length]; 5593 object[] array = new object[src.Length];
5162 Array.Copy(src.Data, 0, array, 0, src.Length); 5594 Array.Copy(src.Data, 0, array, 0, src.Length);
5163 result = new LSL_List(array); 5595 result = new LSL_List(array);
@@ -5264,7 +5696,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5264 public LSL_Integer llGetRegionAgentCount() 5696 public LSL_Integer llGetRegionAgentCount()
5265 { 5697 {
5266 m_host.AddScriptLPS(1); 5698 m_host.AddScriptLPS(1);
5267 return new LSL_Integer(World.GetRootAgentCount()); 5699
5700 int count = 0;
5701 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5702 count++;
5703 });
5704
5705 return new LSL_Integer(count);
5268 } 5706 }
5269 5707
5270 public LSL_Vector llGetRegionCorner() 5708 public LSL_Vector llGetRegionCorner()
@@ -5544,6 +5982,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5544 flags |= ScriptBaseClass.AGENT_SITTING; 5982 flags |= ScriptBaseClass.AGENT_SITTING;
5545 } 5983 }
5546 5984
5985 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
5986 {
5987 flags |= ScriptBaseClass.AGENT_MALE;
5988 }
5989
5547 return flags; 5990 return flags;
5548 } 5991 }
5549 5992
@@ -5606,10 +6049,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5606 m_host.AddScriptLPS(1); 6049 m_host.AddScriptLPS(1);
5607 6050
5608 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6051 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5609 6052 if (parts.Count > 0)
5610 foreach (var part in parts)
5611 { 6053 {
5612 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6054 try
6055 {
6056 parts[0].ParentGroup.areUpdatesSuspended = true;
6057 foreach (var part in parts)
6058 {
6059 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6060 }
6061 }
6062 finally
6063 {
6064 parts[0].ParentGroup.areUpdatesSuspended = false;
6065 }
5613 } 6066 }
5614 } 6067 }
5615 6068
@@ -5661,13 +6114,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5661 6114
5662 if (m_host.OwnerID == land.LandData.OwnerID) 6115 if (m_host.OwnerID == land.LandData.OwnerID)
5663 { 6116 {
5664 World.TeleportClientHome(agentID, presence.ControllingClient); 6117 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6118 presence.TeleportWithMomentum(pos);
6119 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5665 } 6120 }
5666 } 6121 }
5667 } 6122 }
5668 ScriptSleep(5000); 6123 ScriptSleep(5000);
5669 } 6124 }
5670 6125
6126 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6127 {
6128 return ParseString2List(str, separators, in_spacers, false);
6129 }
6130
5671 public LSL_Integer llOverMyLand(string id) 6131 public LSL_Integer llOverMyLand(string id)
5672 { 6132 {
5673 m_host.AddScriptLPS(1); 6133 m_host.AddScriptLPS(1);
@@ -5732,8 +6192,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5732 UUID agentId = new UUID(); 6192 UUID agentId = new UUID();
5733 if (!UUID.TryParse(agent, out agentId)) 6193 if (!UUID.TryParse(agent, out agentId))
5734 return new LSL_Integer(0); 6194 return new LSL_Integer(0);
6195 if (agentId == m_host.GroupID)
6196 return new LSL_Integer(1);
5735 ScenePresence presence = World.GetScenePresence(agentId); 6197 ScenePresence presence = World.GetScenePresence(agentId);
5736 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6198 if (presence == null || presence.IsChildAgent) // Return false for child agents
5737 return new LSL_Integer(0); 6199 return new LSL_Integer(0);
5738 IClientAPI client = presence.ControllingClient; 6200 IClientAPI client = presence.ControllingClient;
5739 if (m_host.GroupID == client.ActiveGroupId) 6201 if (m_host.GroupID == client.ActiveGroupId)
@@ -5868,7 +6330,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5868 return m_host.ParentGroup.AttachmentPoint; 6330 return m_host.ParentGroup.AttachmentPoint;
5869 } 6331 }
5870 6332
5871 public LSL_Integer llGetFreeMemory() 6333 public virtual LSL_Integer llGetFreeMemory()
5872 { 6334 {
5873 m_host.AddScriptLPS(1); 6335 m_host.AddScriptLPS(1);
5874 // Make scripts designed for LSO happy 6336 // Make scripts designed for LSO happy
@@ -5985,7 +6447,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5985 SetParticleSystem(m_host, rules); 6447 SetParticleSystem(m_host, rules);
5986 } 6448 }
5987 6449
5988 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6450 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6451 {
5989 6452
5990 6453
5991 if (rules.Length == 0) 6454 if (rules.Length == 0)
@@ -6179,14 +6642,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6179 6642
6180 protected UUID GetTaskInventoryItem(string name) 6643 protected UUID GetTaskInventoryItem(string name)
6181 { 6644 {
6182 lock (m_host.TaskInventory) 6645 m_host.TaskInventory.LockItemsForRead(true);
6646 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6183 { 6647 {
6184 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6648 if (inv.Value.Name == name)
6185 { 6649 {
6186 if (inv.Value.Name == name) 6650 m_host.TaskInventory.LockItemsForRead(false);
6187 return inv.Key; 6651 return inv.Key;
6188 } 6652 }
6189 } 6653 }
6654 m_host.TaskInventory.LockItemsForRead(false);
6190 6655
6191 return UUID.Zero; 6656 return UUID.Zero;
6192 } 6657 }
@@ -6224,16 +6689,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6224 if (folderID == UUID.Zero) 6689 if (folderID == UUID.Zero)
6225 return; 6690 return;
6226 6691
6227 byte[] bucket = new byte[17]; 6692 byte[] bucket = new byte[1];
6228 bucket[0] = (byte)AssetType.Folder; 6693 bucket[0] = (byte)AssetType.Folder;
6229 byte[] objBytes = folderID.GetBytes(); 6694 //byte[] objBytes = folderID.GetBytes();
6230 Array.Copy(objBytes, 0, bucket, 1, 16); 6695 //Array.Copy(objBytes, 0, bucket, 1, 16);
6231 6696
6232 GridInstantMessage msg = new GridInstantMessage(World, 6697 GridInstantMessage msg = new GridInstantMessage(World,
6233 m_host.UUID, m_host.Name+", an object owned by "+ 6698 m_host.OwnerID, m_host.Name, destID,
6234 resolveName(m_host.OwnerID)+",", destID, 6699 (byte)InstantMessageDialog.TaskInventoryOffered,
6235 (byte)InstantMessageDialog.InventoryOffered, 6700 false, category+". "+m_host.Name+" is located at "+
6236 false, category+"\n"+m_host.Name+" is located at "+
6237 World.RegionInfo.RegionName+" "+ 6701 World.RegionInfo.RegionName+" "+
6238 m_host.AbsolutePosition.ToString(), 6702 m_host.AbsolutePosition.ToString(),
6239 folderID, true, m_host.AbsolutePosition, 6703 folderID, true, m_host.AbsolutePosition,
@@ -6471,13 +6935,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6471 UUID av = new UUID(); 6935 UUID av = new UUID();
6472 if (!UUID.TryParse(avatar,out av)) 6936 if (!UUID.TryParse(avatar,out av))
6473 { 6937 {
6474 LSLError("First parameter to llDialog needs to be a key"); 6938 //LSLError("First parameter to llDialog needs to be a key");
6475 return; 6939 return;
6476 } 6940 }
6477 if (buttons.Length < 1) 6941 if (buttons.Length < 1)
6478 { 6942 {
6479 LSLError("No less than 1 button can be shown"); 6943 buttons.Add("OK");
6480 return;
6481 } 6944 }
6482 if (buttons.Length > 12) 6945 if (buttons.Length > 12)
6483 { 6946 {
@@ -6494,7 +6957,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6494 } 6957 }
6495 if (buttons.Data[i].ToString().Length > 24) 6958 if (buttons.Data[i].ToString().Length > 24)
6496 { 6959 {
6497 LSLError("button label cannot be longer than 24 characters"); 6960 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6498 return; 6961 return;
6499 } 6962 }
6500 buts[i] = buttons.Data[i].ToString(); 6963 buts[i] = buttons.Data[i].ToString();
@@ -6553,22 +7016,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6553 } 7016 }
6554 7017
6555 // copy the first script found with this inventory name 7018 // copy the first script found with this inventory name
6556 lock (m_host.TaskInventory) 7019 TaskInventoryItem scriptItem = null;
7020 m_host.TaskInventory.LockItemsForRead(true);
7021 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6557 { 7022 {
6558 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7023 if (inv.Value.Name == name)
6559 { 7024 {
6560 if (inv.Value.Name == name) 7025 // make sure the object is a script
7026 if (10 == inv.Value.Type)
6561 { 7027 {
6562 // make sure the object is a script 7028 found = true;
6563 if (10 == inv.Value.Type) 7029 srcId = inv.Key;
6564 { 7030 scriptItem = inv.Value;
6565 found = true; 7031 break;
6566 srcId = inv.Key;
6567 break;
6568 }
6569 } 7032 }
6570 } 7033 }
6571 } 7034 }
7035 m_host.TaskInventory.LockItemsForRead(false);
6572 7036
6573 if (!found) 7037 if (!found)
6574 { 7038 {
@@ -6576,9 +7040,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6576 return; 7040 return;
6577 } 7041 }
6578 7042
6579 // the rest of the permission checks are done in RezScript, so check the pin there as well 7043 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6580 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7044 if (dest != null)
7045 {
7046 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7047 {
7048 // the rest of the permission checks are done in RezScript, so check the pin there as well
7049 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6581 7050
7051 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7052 m_host.Inventory.RemoveInventoryItem(srcId);
7053 }
7054 }
6582 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7055 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6583 ScriptSleep(3000); 7056 ScriptSleep(3000);
6584 } 7057 }
@@ -6641,19 +7114,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6641 public LSL_String llMD5String(string src, int nonce) 7114 public LSL_String llMD5String(string src, int nonce)
6642 { 7115 {
6643 m_host.AddScriptLPS(1); 7116 m_host.AddScriptLPS(1);
6644 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7117 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6645 } 7118 }
6646 7119
6647 public LSL_String llSHA1String(string src) 7120 public LSL_String llSHA1String(string src)
6648 { 7121 {
6649 m_host.AddScriptLPS(1); 7122 m_host.AddScriptLPS(1);
6650 return Util.SHA1Hash(src).ToLower(); 7123 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6651 } 7124 }
6652 7125
6653 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7126 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6654 { 7127 {
6655 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7128 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6656 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7129 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7130 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7131 return shapeBlock;
6657 7132
6658 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7133 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6659 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7134 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6758,6 +7233,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6758 // Prim type box, cylinder and prism. 7233 // Prim type box, cylinder and prism.
6759 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) 7234 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)
6760 { 7235 {
7236 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7237 return;
7238
6761 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7239 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6762 ObjectShapePacket.ObjectDataBlock shapeBlock; 7240 ObjectShapePacket.ObjectDataBlock shapeBlock;
6763 7241
@@ -6811,6 +7289,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6811 // Prim type sphere. 7289 // Prim type sphere.
6812 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7290 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6813 { 7291 {
7292 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7293 return;
7294
6814 ObjectShapePacket.ObjectDataBlock shapeBlock; 7295 ObjectShapePacket.ObjectDataBlock shapeBlock;
6815 7296
6816 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7297 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6852,6 +7333,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6852 // Prim type torus, tube and ring. 7333 // Prim type torus, tube and ring.
6853 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) 7334 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)
6854 { 7335 {
7336 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7337 return;
7338
6855 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7339 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6856 ObjectShapePacket.ObjectDataBlock shapeBlock; 7340 ObjectShapePacket.ObjectDataBlock shapeBlock;
6857 7341
@@ -6987,6 +7471,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6987 // Prim type sculpt. 7471 // Prim type sculpt.
6988 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7472 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6989 { 7473 {
7474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7475 return;
7476
6990 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7477 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6991 UUID sculptId; 7478 UUID sculptId;
6992 7479
@@ -7011,7 +7498,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7011 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7498 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7012 { 7499 {
7013 // default 7500 // default
7014 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7501 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7015 } 7502 }
7016 7503
7017 part.Shape.SetSculptProperties((byte)type, sculptId); 7504 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7027,32 +7514,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7027 ScriptSleep(200); 7514 ScriptSleep(200);
7028 } 7515 }
7029 7516
7030 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7517 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7031 { 7518 {
7032 m_host.AddScriptLPS(1); 7519 m_host.AddScriptLPS(1);
7033 7520
7034 setLinkPrimParams(linknumber, rules); 7521 setLinkPrimParams(linknumber, rules);
7522 }
7035 7523
7036 ScriptSleep(200); 7524 private void setLinkPrimParams(int linknumber, LSL_List rules)
7525 {
7526 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7527 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7528 if (parts.Count>0)
7529 {
7530 try
7531 {
7532 parts[0].ParentGroup.areUpdatesSuspended = true;
7533 foreach (SceneObjectPart part in parts)
7534 SetPrimParams(part, rules);
7535 }
7536 finally
7537 {
7538 parts[0].ParentGroup.areUpdatesSuspended = false;
7539 }
7540 }
7541 if (avatars.Count > 0)
7542 {
7543 foreach (ScenePresence avatar in avatars)
7544 SetPrimParams(avatar, rules);
7545 }
7037 } 7546 }
7038 7547
7039 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7548 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7549 float material_density, float material_friction,
7550 float material_restitution, float material_gravity_modifier)
7040 { 7551 {
7041 m_host.AddScriptLPS(1); 7552 ExtraPhysicsData physdata = new ExtraPhysicsData();
7553 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7554 physdata.Density = part.Density;
7555 physdata.Friction = part.Friction;
7556 physdata.Bounce = part.Bounciness;
7557 physdata.GravitationModifier = part.GravityModifier;
7042 7558
7043 setLinkPrimParams(linknumber, rules); 7559 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7560 physdata.Density = material_density;
7561 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7562 physdata.Friction = material_friction;
7563 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7564 physdata.Bounce = material_restitution;
7565 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7566 physdata.GravitationModifier = material_gravity_modifier;
7567
7568 part.UpdateExtraPhysics(physdata);
7044 } 7569 }
7045 7570
7046 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7571 public void llSetPhysicsMaterial(int material_bits,
7572 float material_gravity_modifier, float material_restitution,
7573 float material_friction, float material_density)
7047 { 7574 {
7048 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7575 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7576 }
7049 7577
7050 foreach (SceneObjectPart part in parts) 7578 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7051 SetPrimParams(part, rules); 7579 {
7580 llSetLinkPrimitiveParamsFast(linknumber, rules);
7581 ScriptSleep(200);
7582 }
7583
7584 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7585 {
7586 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7587 //We only support PRIM_POSITION and PRIM_ROTATION
7588
7589 int idx = 0;
7590
7591 while (idx < rules.Length)
7592 {
7593 int code = rules.GetLSLIntegerItem(idx++);
7594
7595 int remain = rules.Length - idx;
7596
7597 switch (code)
7598 {
7599 case (int)ScriptBaseClass.PRIM_POSITION:
7600 {
7601 if (remain < 1)
7602 return;
7603 LSL_Vector v;
7604 v = rules.GetVector3Item(idx++);
7605
7606 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7607 if (part == null)
7608 break;
7609
7610 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7611 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7612 if (llGetLinkNumber() > 1)
7613 {
7614 localRot = llGetLocalRot();
7615 localPos = llGetLocalPos();
7616 }
7617
7618 v -= localPos;
7619 v /= localRot;
7620
7621 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7622
7623 v = v + 2 * sitOffset;
7624
7625 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7626 av.SendAvatarDataToAllAgents();
7627
7628 }
7629 break;
7630
7631 case (int)ScriptBaseClass.PRIM_ROTATION:
7632 {
7633 if (remain < 1)
7634 return;
7635
7636 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7637 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7638 if (llGetLinkNumber() > 1)
7639 {
7640 localRot = llGetLocalRot();
7641 localPos = llGetLocalPos();
7642 }
7643
7644 LSL_Rotation r;
7645 r = rules.GetQuaternionItem(idx++);
7646 r = r * llGetRootRotation() / localRot;
7647 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7648 av.SendAvatarDataToAllAgents();
7649 }
7650 break;
7651 }
7652 }
7052 } 7653 }
7053 7654
7054 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7655 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7055 { 7656 {
7657 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7658 return;
7659
7056 int idx = 0; 7660 int idx = 0;
7057 7661
7058 bool positionChanged = false; 7662 bool positionChanged = false;
@@ -7374,6 +7978,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7374 part.ScriptSetPhysicsStatus(physics); 7978 part.ScriptSetPhysicsStatus(physics);
7375 break; 7979 break;
7376 7980
7981 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7982 if (remain < 1)
7983 return;
7984
7985 int shape_type = rules.GetLSLIntegerItem(idx++);
7986
7987 ExtraPhysicsData physdata = new ExtraPhysicsData();
7988 physdata.Density = part.Density;
7989 physdata.Bounce = part.Bounciness;
7990 physdata.GravitationModifier = part.GravityModifier;
7991 physdata.PhysShapeType = (PhysShapeType)shape_type;
7992
7993 part.UpdateExtraPhysics(physdata);
7994
7995 break;
7996
7997 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7998 if (remain < 5)
7999 return;
8000
8001 int material_bits = rules.GetLSLIntegerItem(idx++);
8002 float material_density = (float)rules.GetLSLFloatItem(idx++);
8003 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8004 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8005 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8006
8007 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8008
8009 break;
8010
7377 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8011 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7378 if (remain < 1) 8012 if (remain < 1)
7379 return; 8013 return;
@@ -7447,7 +8081,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7447 if (part.ParentGroup.RootPart == part) 8081 if (part.ParentGroup.RootPart == part)
7448 { 8082 {
7449 SceneObjectGroup parent = part.ParentGroup; 8083 SceneObjectGroup parent = part.ParentGroup;
7450 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8084 Util.FireAndForget(delegate(object x) {
8085 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8086 });
7451 } 8087 }
7452 else 8088 else
7453 { 8089 {
@@ -7458,6 +8094,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7458 } 8094 }
7459 } 8095 }
7460 } 8096 }
8097
8098 if (positionChanged)
8099 {
8100 if (part.ParentGroup.RootPart == part)
8101 {
8102 SceneObjectGroup parent = part.ParentGroup;
8103 Util.FireAndForget(delegate(object x) {
8104 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8105 });
8106 }
8107 else
8108 {
8109 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8110 SceneObjectGroup parent = part.ParentGroup;
8111 parent.HasGroupChanged = true;
8112 parent.ScheduleGroupForTerseUpdate();
8113 }
8114 }
7461 } 8115 }
7462 8116
7463 public LSL_String llStringToBase64(string str) 8117 public LSL_String llStringToBase64(string str)
@@ -7618,13 +8272,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7618 public LSL_Integer llGetNumberOfPrims() 8272 public LSL_Integer llGetNumberOfPrims()
7619 { 8273 {
7620 m_host.AddScriptLPS(1); 8274 m_host.AddScriptLPS(1);
7621 int avatarCount = 0; 8275 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7622 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8276
7623 {
7624 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7625 avatarCount++;
7626 });
7627
7628 return m_host.ParentGroup.PrimCount + avatarCount; 8277 return m_host.ParentGroup.PrimCount + avatarCount;
7629 } 8278 }
7630 8279
@@ -7640,55 +8289,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7640 m_host.AddScriptLPS(1); 8289 m_host.AddScriptLPS(1);
7641 UUID objID = UUID.Zero; 8290 UUID objID = UUID.Zero;
7642 LSL_List result = new LSL_List(); 8291 LSL_List result = new LSL_List();
8292
8293 // If the ID is not valid, return null result
7643 if (!UUID.TryParse(obj, out objID)) 8294 if (!UUID.TryParse(obj, out objID))
7644 { 8295 {
7645 result.Add(new LSL_Vector()); 8296 result.Add(new LSL_Vector());
7646 result.Add(new LSL_Vector()); 8297 result.Add(new LSL_Vector());
7647 return result; 8298 return result;
7648 } 8299 }
8300
8301 // Check if this is an attached prim. If so, replace
8302 // the UUID with the avatar UUID and report it's bounding box
8303 SceneObjectPart part = World.GetSceneObjectPart(objID);
8304 if (part != null && part.ParentGroup.IsAttachment)
8305 objID = part.ParentGroup.AttachedAvatar;
8306
8307 // Find out if this is an avatar ID. If so, return it's box
7649 ScenePresence presence = World.GetScenePresence(objID); 8308 ScenePresence presence = World.GetScenePresence(objID);
7650 if (presence != null) 8309 if (presence != null)
7651 { 8310 {
7652 if (presence.ParentID == 0) // not sat on an object 8311 // As per LSL Wiki, there is no difference between sitting
8312 // and standing avatar since server 1.36
8313 LSL_Vector lower;
8314 LSL_Vector upper;
8315 if (presence.Animator.Animations.DefaultAnimation.AnimID
8316 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7653 { 8317 {
7654 LSL_Vector lower; 8318 // This is for ground sitting avatars
7655 LSL_Vector upper; 8319 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7656 if (presence.Animator.Animations.DefaultAnimation.AnimID 8320 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7657 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8321 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7658 {
7659 // This is for ground sitting avatars
7660 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7661 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7662 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7663 }
7664 else
7665 {
7666 // This is for standing/flying avatars
7667 float height = presence.Appearance.AvatarHeight / 2.0f;
7668 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7669 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7670 }
7671 result.Add(lower);
7672 result.Add(upper);
7673 return result;
7674 } 8322 }
7675 else 8323 else
7676 { 8324 {
7677 // sitting on an object so we need the bounding box of that 8325 // This is for standing/flying avatars
7678 // which should include the avatar so set the UUID to the 8326 float height = presence.Appearance.AvatarHeight / 2.0f;
7679 // UUID of the object the avatar is sat on and allow it to fall through 8327 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7680 // to processing an object 8328 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7681 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7682 objID = p.UUID;
7683 } 8329 }
8330
8331 // Adjust to the documented error offsets (see LSL Wiki)
8332 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8333 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8334
8335 if (lower.x > upper.x)
8336 lower.x = upper.x;
8337 if (lower.y > upper.y)
8338 lower.y = upper.y;
8339 if (lower.z > upper.z)
8340 lower.z = upper.z;
8341
8342 result.Add(lower);
8343 result.Add(upper);
8344 return result;
7684 } 8345 }
7685 SceneObjectPart part = World.GetSceneObjectPart(objID); 8346
8347 part = World.GetSceneObjectPart(objID);
7686 // Currently only works for single prims without a sitting avatar 8348 // Currently only works for single prims without a sitting avatar
7687 if (part != null) 8349 if (part != null)
7688 { 8350 {
7689 Vector3 halfSize = part.Scale / 2.0f; 8351 float minX;
7690 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8352 float maxX;
7691 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8353 float minY;
8354 float maxY;
8355 float minZ;
8356 float maxZ;
8357
8358 // This BBox is in sim coordinates, with the offset being
8359 // a contained point.
8360 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8361 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8362
8363 minX -= offsets[0].X;
8364 maxX -= offsets[0].X;
8365 minY -= offsets[0].Y;
8366 maxY -= offsets[0].Y;
8367 minZ -= offsets[0].Z;
8368 maxZ -= offsets[0].Z;
8369
8370 LSL_Vector lower;
8371 LSL_Vector upper;
8372
8373 // Adjust to the documented error offsets (see LSL Wiki)
8374 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8375 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8376
8377 if (lower.x > upper.x)
8378 lower.x = upper.x;
8379 if (lower.y > upper.y)
8380 lower.y = upper.y;
8381 if (lower.z > upper.z)
8382 lower.z = upper.z;
8383
7692 result.Add(lower); 8384 result.Add(lower);
7693 result.Add(upper); 8385 result.Add(upper);
7694 return result; 8386 return result;
@@ -7768,13 +8460,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7768 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8460 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7769 part.AbsolutePosition.Y, 8461 part.AbsolutePosition.Y,
7770 part.AbsolutePosition.Z); 8462 part.AbsolutePosition.Z);
7771 // For some reason, the part.AbsolutePosition.* values do not change if the
7772 // linkset is rotated; they always reflect the child prim's world position
7773 // as though the linkset is unrotated. This is incompatible behavior with SL's
7774 // implementation, so will break scripts imported from there (not to mention it
7775 // makes it more difficult to determine a child prim's actual inworld position).
7776 if (part.ParentID != 0)
7777 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7778 res.Add(v); 8463 res.Add(v);
7779 break; 8464 break;
7780 8465
@@ -7945,56 +8630,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7945 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8630 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7946 if (remain < 1) 8631 if (remain < 1)
7947 return res; 8632 return res;
7948 8633 face = (int)rules.GetLSLIntegerItem(idx++);
7949 face=(int)rules.GetLSLIntegerItem(idx++);
7950 8634
7951 tex = part.Shape.Textures; 8635 tex = part.Shape.Textures;
8636 int shiny;
7952 if (face == ScriptBaseClass.ALL_SIDES) 8637 if (face == ScriptBaseClass.ALL_SIDES)
7953 { 8638 {
7954 for (face = 0; face < GetNumberOfSides(part); face++) 8639 for (face = 0; face < GetNumberOfSides(part); face++)
7955 { 8640 {
7956 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8641 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7957 // Convert Shininess to PRIM_SHINY_* 8642 if (shinyness == Shininess.High)
7958 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8643 {
7959 // PRIM_BUMP_* 8644 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7960 res.Add(new LSL_Integer((int)texface.Bump)); 8645 }
8646 else if (shinyness == Shininess.Medium)
8647 {
8648 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8649 }
8650 else if (shinyness == Shininess.Low)
8651 {
8652 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8653 }
8654 else
8655 {
8656 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8657 }
8658 res.Add(new LSL_Integer(shiny));
8659 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7961 } 8660 }
7962 } 8661 }
7963 else 8662 else
7964 { 8663 {
7965 if (face >= 0 && face < GetNumberOfSides(part)) 8664 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8665 if (shinyness == Shininess.High)
7966 { 8666 {
7967 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8667 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7968 // Convert Shininess to PRIM_SHINY_* 8668 }
7969 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8669 else if (shinyness == Shininess.Medium)
7970 // PRIM_BUMP_* 8670 {
7971 res.Add(new LSL_Integer((int)texface.Bump)); 8671 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8672 }
8673 else if (shinyness == Shininess.Low)
8674 {
8675 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8676 }
8677 else
8678 {
8679 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7972 } 8680 }
8681 res.Add(new LSL_Integer(shiny));
8682 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7973 } 8683 }
7974 break; 8684 break;
7975 8685
7976 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8686 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7977 if (remain < 1) 8687 if (remain < 1)
7978 return res; 8688 return res;
7979 8689 face = (int)rules.GetLSLIntegerItem(idx++);
7980 face=(int)rules.GetLSLIntegerItem(idx++);
7981 8690
7982 tex = part.Shape.Textures; 8691 tex = part.Shape.Textures;
8692 int fullbright;
7983 if (face == ScriptBaseClass.ALL_SIDES) 8693 if (face == ScriptBaseClass.ALL_SIDES)
7984 { 8694 {
7985 for (face = 0; face < GetNumberOfSides(part); face++) 8695 for (face = 0; face < GetNumberOfSides(part); face++)
7986 { 8696 {
7987 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8697 if (tex.GetFace((uint)face).Fullbright == true)
7988 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8698 {
8699 fullbright = ScriptBaseClass.TRUE;
8700 }
8701 else
8702 {
8703 fullbright = ScriptBaseClass.FALSE;
8704 }
8705 res.Add(new LSL_Integer(fullbright));
7989 } 8706 }
7990 } 8707 }
7991 else 8708 else
7992 { 8709 {
7993 if (face >= 0 && face < GetNumberOfSides(part)) 8710 if (tex.GetFace((uint)face).Fullbright == true)
7994 { 8711 {
7995 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8712 fullbright = ScriptBaseClass.TRUE;
7996 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8713 }
8714 else
8715 {
8716 fullbright = ScriptBaseClass.FALSE;
7997 } 8717 }
8718 res.Add(new LSL_Integer(fullbright));
7998 } 8719 }
7999 break; 8720 break;
8000 8721
@@ -8016,27 +8737,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8016 break; 8737 break;
8017 8738
8018 case (int)ScriptBaseClass.PRIM_TEXGEN: 8739 case (int)ScriptBaseClass.PRIM_TEXGEN:
8740 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8019 if (remain < 1) 8741 if (remain < 1)
8020 return res; 8742 return res;
8021 8743 face = (int)rules.GetLSLIntegerItem(idx++);
8022 face=(int)rules.GetLSLIntegerItem(idx++);
8023 8744
8024 tex = part.Shape.Textures; 8745 tex = part.Shape.Textures;
8025 if (face == ScriptBaseClass.ALL_SIDES) 8746 if (face == ScriptBaseClass.ALL_SIDES)
8026 { 8747 {
8027 for (face = 0; face < GetNumberOfSides(part); face++) 8748 for (face = 0; face < GetNumberOfSides(part); face++)
8028 { 8749 {
8029 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8750 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8030 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8751 {
8031 res.Add(new LSL_Integer((uint)texgen >> 1)); 8752 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8753 }
8754 else
8755 {
8756 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8757 }
8032 } 8758 }
8033 } 8759 }
8034 else 8760 else
8035 { 8761 {
8036 if (face >= 0 && face < GetNumberOfSides(part)) 8762 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8037 { 8763 {
8038 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8764 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8039 res.Add(new LSL_Integer((uint)texgen >> 1)); 8765 }
8766 else
8767 {
8768 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8040 } 8769 }
8041 } 8770 }
8042 break; 8771 break;
@@ -8059,28 +8788,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8059 case (int)ScriptBaseClass.PRIM_GLOW: 8788 case (int)ScriptBaseClass.PRIM_GLOW:
8060 if (remain < 1) 8789 if (remain < 1)
8061 return res; 8790 return res;
8062 8791 face = (int)rules.GetLSLIntegerItem(idx++);
8063 face=(int)rules.GetLSLIntegerItem(idx++);
8064 8792
8065 tex = part.Shape.Textures; 8793 tex = part.Shape.Textures;
8794 float primglow;
8066 if (face == ScriptBaseClass.ALL_SIDES) 8795 if (face == ScriptBaseClass.ALL_SIDES)
8067 { 8796 {
8068 for (face = 0; face < GetNumberOfSides(part); face++) 8797 for (face = 0; face < GetNumberOfSides(part); face++)
8069 { 8798 {
8070 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8799 primglow = tex.GetFace((uint)face).Glow;
8071 res.Add(new LSL_Float(texface.Glow)); 8800 res.Add(new LSL_Float(primglow));
8072 } 8801 }
8073 } 8802 }
8074 else 8803 else
8075 { 8804 {
8076 if (face >= 0 && face < GetNumberOfSides(part)) 8805 primglow = tex.GetFace((uint)face).Glow;
8077 { 8806 res.Add(new LSL_Float(primglow));
8078 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8079 res.Add(new LSL_Float(texface.Glow));
8080 }
8081 } 8807 }
8082 break; 8808 break;
8083
8084 case (int)ScriptBaseClass.PRIM_TEXT: 8809 case (int)ScriptBaseClass.PRIM_TEXT:
8085 Color4 textColor = part.GetTextColor(); 8810 Color4 textColor = part.GetTextColor();
8086 res.Add(new LSL_String(part.Text)); 8811 res.Add(new LSL_String(part.Text));
@@ -8692,8 +9417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8692 // The function returns an ordered list 9417 // The function returns an ordered list
8693 // representing the tokens found in the supplied 9418 // representing the tokens found in the supplied
8694 // sources string. If two successive tokenizers 9419 // sources string. If two successive tokenizers
8695 // are encountered, then a NULL entry is added 9420 // are encountered, then a null-string entry is
8696 // to the list. 9421 // added to the list.
8697 // 9422 //
8698 // It is a precondition that the source and 9423 // It is a precondition that the source and
8699 // toekizer lisst are non-null. If they are null, 9424 // toekizer lisst are non-null. If they are null,
@@ -8701,7 +9426,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8701 // while their lengths are being determined. 9426 // while their lengths are being determined.
8702 // 9427 //
8703 // A small amount of working memoryis required 9428 // A small amount of working memoryis required
8704 // of approximately 8*#tokenizers. 9429 // of approximately 8*#tokenizers + 8*srcstrlen.
8705 // 9430 //
8706 // There are many ways in which this function 9431 // There are many ways in which this function
8707 // can be implemented, this implementation is 9432 // can be implemented, this implementation is
@@ -8717,155 +9442,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8717 // and eliminates redundant tokenizers as soon 9442 // and eliminates redundant tokenizers as soon
8718 // as is possible. 9443 // as is possible.
8719 // 9444 //
8720 // The implementation tries to avoid any copying 9445 // The implementation tries to minimize temporary
8721 // of arrays or other objects. 9446 // garbage generation.
8722 // </remarks> 9447 // </remarks>
8723 9448
8724 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9449 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8725 { 9450 {
8726 int beginning = 0; 9451 return ParseString2List(src, separators, spacers, true);
8727 int srclen = src.Length; 9452 }
8728 int seplen = separators.Length;
8729 object[] separray = separators.Data;
8730 int spclen = spacers.Length;
8731 object[] spcarray = spacers.Data;
8732 int mlen = seplen+spclen;
8733
8734 int[] offset = new int[mlen+1];
8735 bool[] active = new bool[mlen];
8736
8737 int best;
8738 int j;
8739
8740 // Initial capacity reduces resize cost
8741 9453
8742 LSL_List tokens = new LSL_List(); 9454 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9455 {
9456 int srclen = src.Length;
9457 int seplen = separators.Length;
9458 object[] separray = separators.Data;
9459 int spclen = spacers.Length;
9460 object[] spcarray = spacers.Data;
9461 int dellen = 0;
9462 string[] delarray = new string[seplen+spclen];
8743 9463
8744 // All entries are initially valid 9464 int outlen = 0;
9465 string[] outarray = new string[srclen*2+1];
8745 9466
8746 for (int i = 0; i < mlen; i++) 9467 int i, j;
8747 active[i] = true; 9468 string d;
8748 9469
8749 offset[mlen] = srclen; 9470 m_host.AddScriptLPS(1);
8750 9471
8751 while (beginning < srclen) 9472 /*
9473 * Convert separator and spacer lists to C# strings.
9474 * Also filter out null strings so we don't hang.
9475 */
9476 for (i = 0; i < seplen; i ++)
8752 { 9477 {
9478 d = separray[i].ToString();
9479 if (d.Length > 0)
9480 {
9481 delarray[dellen++] = d;
9482 }
9483 }
9484 seplen = dellen;
8753 9485
8754 best = mlen; // as bad as it gets 9486 for (i = 0; i < spclen; i ++)
9487 {
9488 d = spcarray[i].ToString();
9489 if (d.Length > 0)
9490 {
9491 delarray[dellen++] = d;
9492 }
9493 }
8755 9494
8756 // Scan for separators 9495 /*
9496 * Scan through source string from beginning to end.
9497 */
9498 for (i = 0;;)
9499 {
8757 9500
8758 for (j = 0; j < seplen; j++) 9501 /*
9502 * Find earliest delimeter in src starting at i (if any).
9503 */
9504 int earliestDel = -1;
9505 int earliestSrc = srclen;
9506 string earliestStr = null;
9507 for (j = 0; j < dellen; j ++)
8759 { 9508 {
8760 if (separray[j].ToString() == String.Empty) 9509 d = delarray[j];
8761 active[j] = false; 9510 if (d != null)
8762
8763 if (active[j])
8764 { 9511 {
8765 // scan all of the markers 9512 int index = src.IndexOf(d, i);
8766 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9513 if (index < 0)
8767 { 9514 {
8768 // not present at all 9515 delarray[j] = null; // delim nowhere in src, don't check it anymore
8769 active[j] = false;
8770 } 9516 }
8771 else 9517 else if (index < earliestSrc)
8772 { 9518 {
8773 // present and correct 9519 earliestSrc = index; // where delimeter starts in source string
8774 if (offset[j] < offset[best]) 9520 earliestDel = j; // where delimeter is in delarray[]
8775 { 9521 earliestStr = d; // the delimeter string from delarray[]
8776 // closest so far 9522 if (index == i) break; // can't do any better than found at beg of string
8777 best = j;
8778 if (offset[best] == beginning)
8779 break;
8780 }
8781 } 9523 }
8782 } 9524 }
8783 } 9525 }
8784 9526
8785 // Scan for spacers 9527 /*
8786 9528 * Output source string starting at i through start of earliest delimeter.
8787 if (offset[best] != beginning) 9529 */
9530 if (keepNulls || (earliestSrc > i))
8788 { 9531 {
8789 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9532 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8790 {
8791 if (spcarray[j-seplen].ToString() == String.Empty)
8792 active[j] = false;
8793
8794 if (active[j])
8795 {
8796 // scan all of the markers
8797 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8798 {
8799 // not present at all
8800 active[j] = false;
8801 }
8802 else
8803 {
8804 // present and correct
8805 if (offset[j] < offset[best])
8806 {
8807 // closest so far
8808 best = j;
8809 }
8810 }
8811 }
8812 }
8813 } 9533 }
8814 9534
8815 // This is the normal exit from the scanning loop 9535 /*
9536 * If no delimeter found at or after i, we're done scanning.
9537 */
9538 if (earliestDel < 0) break;
8816 9539
8817 if (best == mlen) 9540 /*
9541 * If delimeter was a spacer, output the spacer.
9542 */
9543 if (earliestDel >= seplen)
8818 { 9544 {
8819 // no markers were found on this pass 9545 outarray[outlen++] = earliestStr;
8820 // so we're pretty much done
8821 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8822 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8823 break;
8824 } 9546 }
8825 9547
8826 // Otherwise we just add the newly delimited token 9548 /*
8827 // and recalculate where the search should continue. 9549 * Look at rest of src string following delimeter.
8828 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9550 */
8829 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9551 i = earliestSrc + earliestStr.Length;
8830
8831 if (best < seplen)
8832 {
8833 beginning = offset[best] + (separray[best].ToString()).Length;
8834 }
8835 else
8836 {
8837 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8838 string str = spcarray[best - seplen].ToString();
8839 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8840 tokens.Add(new LSL_String(str));
8841 }
8842 } 9552 }
8843 9553
8844 // This an awkward an not very intuitive boundary case. If the 9554 /*
8845 // last substring is a tokenizer, then there is an implied trailing 9555 * Make up an exact-sized output array suitable for an LSL_List object.
8846 // null list entry. Hopefully the single comparison will not be too 9556 */
8847 // arduous. Alternatively the 'break' could be replced with a return 9557 object[] outlist = new object[outlen];
8848 // but that's shabby programming. 9558 for (i = 0; i < outlen; i ++)
8849
8850 if ((beginning == srclen) && (keepNulls))
8851 { 9559 {
8852 if (srclen != 0) 9560 outlist[i] = new LSL_String(outarray[i]);
8853 tokens.Add(new LSL_String(""));
8854 } 9561 }
8855 9562 return new LSL_List(outlist);
8856 return tokens;
8857 }
8858
8859 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8860 {
8861 m_host.AddScriptLPS(1);
8862 return this.ParseString(src, separators, spacers, false);
8863 }
8864
8865 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8866 {
8867 m_host.AddScriptLPS(1);
8868 return this.ParseString(src, separators, spacers, true);
8869 } 9563 }
8870 9564
8871 public LSL_Integer llGetObjectPermMask(int mask) 9565 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8942,28 +9636,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8942 { 9636 {
8943 m_host.AddScriptLPS(1); 9637 m_host.AddScriptLPS(1);
8944 9638
8945 lock (m_host.TaskInventory) 9639 m_host.TaskInventory.LockItemsForRead(true);
9640 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8946 { 9641 {
8947 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9642 if (inv.Value.Name == item)
8948 { 9643 {
8949 if (inv.Value.Name == item) 9644 m_host.TaskInventory.LockItemsForRead(false);
9645 switch (mask)
8950 { 9646 {
8951 switch (mask) 9647 case 0:
8952 { 9648 return (int)inv.Value.BasePermissions;
8953 case 0: 9649 case 1:
8954 return (int)inv.Value.BasePermissions; 9650 return (int)inv.Value.CurrentPermissions;
8955 case 1: 9651 case 2:
8956 return (int)inv.Value.CurrentPermissions; 9652 return (int)inv.Value.GroupPermissions;
8957 case 2: 9653 case 3:
8958 return (int)inv.Value.GroupPermissions; 9654 return (int)inv.Value.EveryonePermissions;
8959 case 3: 9655 case 4:
8960 return (int)inv.Value.EveryonePermissions; 9656 return (int)inv.Value.NextPermissions;
8961 case 4:
8962 return (int)inv.Value.NextPermissions;
8963 }
8964 } 9657 }
8965 } 9658 }
8966 } 9659 }
9660 m_host.TaskInventory.LockItemsForRead(false);
8967 9661
8968 return -1; 9662 return -1;
8969 } 9663 }
@@ -9010,16 +9704,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9010 { 9704 {
9011 m_host.AddScriptLPS(1); 9705 m_host.AddScriptLPS(1);
9012 9706
9013 lock (m_host.TaskInventory) 9707 m_host.TaskInventory.LockItemsForRead(true);
9708 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9014 { 9709 {
9015 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9710 if (inv.Value.Name == item)
9016 { 9711 {
9017 if (inv.Value.Name == item) 9712 m_host.TaskInventory.LockItemsForRead(false);
9018 { 9713 return inv.Value.CreatorID.ToString();
9019 return inv.Value.CreatorID.ToString();
9020 }
9021 } 9714 }
9022 } 9715 }
9716 m_host.TaskInventory.LockItemsForRead(false);
9023 9717
9024 llSay(0, "No item name '" + item + "'"); 9718 llSay(0, "No item name '" + item + "'");
9025 9719
@@ -9145,9 +9839,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9145 { 9839 {
9146 try 9840 try
9147 { 9841 {
9842 /*
9148 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9843 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9149 if (obj != null) 9844 if (obj != null)
9150 return (double)obj.GetMass(); 9845 return (double)obj.GetMass();
9846 */
9847 // return total object mass
9848 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
9849 if (obj != null)
9850 return obj.GetMass();
9851
9151 // the object is null so the key is for an avatar 9852 // the object is null so the key is for an avatar
9152 ScenePresence avatar = World.GetScenePresence(key); 9853 ScenePresence avatar = World.GetScenePresence(key);
9153 if (avatar != null) 9854 if (avatar != null)
@@ -9167,7 +9868,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9167 } 9868 }
9168 9869
9169 /// <summary> 9870 /// <summary>
9170 /// illListReplaceList removes the sub-list defined by the inclusive indices 9871 /// llListReplaceList removes the sub-list defined by the inclusive indices
9171 /// start and end and inserts the src list in its place. The inclusive 9872 /// start and end and inserts the src list in its place. The inclusive
9172 /// nature of the indices means that at least one element must be deleted 9873 /// nature of the indices means that at least one element must be deleted
9173 /// if the indices are within the bounds of the existing list. I.e. 2,2 9874 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9224,16 +9925,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9224 // based upon end. Note that if end exceeds the upper 9925 // based upon end. Note that if end exceeds the upper
9225 // bound in this case, the entire destination list 9926 // bound in this case, the entire destination list
9226 // is removed. 9927 // is removed.
9227 else 9928 else if (start == 0)
9228 { 9929 {
9229 if (end + 1 < dest.Length) 9930 if (end + 1 < dest.Length)
9230 {
9231 return src + dest.GetSublist(end + 1, -1); 9931 return src + dest.GetSublist(end + 1, -1);
9232 }
9233 else 9932 else
9234 {
9235 return src; 9933 return src;
9236 } 9934 }
9935 else // Start < 0
9936 {
9937 if (end + 1 < dest.Length)
9938 return dest.GetSublist(end + 1, -1);
9939 else
9940 return new LSL_List();
9237 } 9941 }
9238 } 9942 }
9239 // Finally, if start > end, we strip away a prefix and 9943 // Finally, if start > end, we strip away a prefix and
@@ -9284,17 +9988,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9284 int width = 0; 9988 int width = 0;
9285 int height = 0; 9989 int height = 0;
9286 9990
9287 ParcelMediaCommandEnum? commandToSend = null; 9991 uint commandToSend = 0;
9288 float time = 0.0f; // default is from start 9992 float time = 0.0f; // default is from start
9289 9993
9290 ScenePresence presence = null; 9994 ScenePresence presence = null;
9291 9995
9292 for (int i = 0; i < commandList.Data.Length; i++) 9996 for (int i = 0; i < commandList.Data.Length; i++)
9293 { 9997 {
9294 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9998 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9295 switch (command) 9999 switch (command)
9296 { 10000 {
9297 case ParcelMediaCommandEnum.Agent: 10001 case (uint)ParcelMediaCommandEnum.Agent:
9298 // we send only to one agent 10002 // we send only to one agent
9299 if ((i + 1) < commandList.Length) 10003 if ((i + 1) < commandList.Length)
9300 { 10004 {
@@ -9311,25 +10015,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9311 } 10015 }
9312 break; 10016 break;
9313 10017
9314 case ParcelMediaCommandEnum.Loop: 10018 case (uint)ParcelMediaCommandEnum.Loop:
9315 loop = 1; 10019 loop = 1;
9316 commandToSend = command; 10020 commandToSend = command;
9317 update = true; //need to send the media update packet to set looping 10021 update = true; //need to send the media update packet to set looping
9318 break; 10022 break;
9319 10023
9320 case ParcelMediaCommandEnum.Play: 10024 case (uint)ParcelMediaCommandEnum.Play:
9321 loop = 0; 10025 loop = 0;
9322 commandToSend = command; 10026 commandToSend = command;
9323 update = true; //need to send the media update packet to make sure it doesn't loop 10027 update = true; //need to send the media update packet to make sure it doesn't loop
9324 break; 10028 break;
9325 10029
9326 case ParcelMediaCommandEnum.Pause: 10030 case (uint)ParcelMediaCommandEnum.Pause:
9327 case ParcelMediaCommandEnum.Stop: 10031 case (uint)ParcelMediaCommandEnum.Stop:
9328 case ParcelMediaCommandEnum.Unload: 10032 case (uint)ParcelMediaCommandEnum.Unload:
9329 commandToSend = command; 10033 commandToSend = command;
9330 break; 10034 break;
9331 10035
9332 case ParcelMediaCommandEnum.Url: 10036 case (uint)ParcelMediaCommandEnum.Url:
9333 if ((i + 1) < commandList.Length) 10037 if ((i + 1) < commandList.Length)
9334 { 10038 {
9335 if (commandList.Data[i + 1] is LSL_String) 10039 if (commandList.Data[i + 1] is LSL_String)
@@ -9342,7 +10046,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9342 } 10046 }
9343 break; 10047 break;
9344 10048
9345 case ParcelMediaCommandEnum.Texture: 10049 case (uint)ParcelMediaCommandEnum.Texture:
9346 if ((i + 1) < commandList.Length) 10050 if ((i + 1) < commandList.Length)
9347 { 10051 {
9348 if (commandList.Data[i + 1] is LSL_String) 10052 if (commandList.Data[i + 1] is LSL_String)
@@ -9355,7 +10059,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9355 } 10059 }
9356 break; 10060 break;
9357 10061
9358 case ParcelMediaCommandEnum.Time: 10062 case (uint)ParcelMediaCommandEnum.Time:
9359 if ((i + 1) < commandList.Length) 10063 if ((i + 1) < commandList.Length)
9360 { 10064 {
9361 if (commandList.Data[i + 1] is LSL_Float) 10065 if (commandList.Data[i + 1] is LSL_Float)
@@ -9367,7 +10071,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9367 } 10071 }
9368 break; 10072 break;
9369 10073
9370 case ParcelMediaCommandEnum.AutoAlign: 10074 case (uint)ParcelMediaCommandEnum.AutoAlign:
9371 if ((i + 1) < commandList.Length) 10075 if ((i + 1) < commandList.Length)
9372 { 10076 {
9373 if (commandList.Data[i + 1] is LSL_Integer) 10077 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9381,7 +10085,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9381 } 10085 }
9382 break; 10086 break;
9383 10087
9384 case ParcelMediaCommandEnum.Type: 10088 case (uint)ParcelMediaCommandEnum.Type:
9385 if ((i + 1) < commandList.Length) 10089 if ((i + 1) < commandList.Length)
9386 { 10090 {
9387 if (commandList.Data[i + 1] is LSL_String) 10091 if (commandList.Data[i + 1] is LSL_String)
@@ -9394,7 +10098,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9394 } 10098 }
9395 break; 10099 break;
9396 10100
9397 case ParcelMediaCommandEnum.Desc: 10101 case (uint)ParcelMediaCommandEnum.Desc:
9398 if ((i + 1) < commandList.Length) 10102 if ((i + 1) < commandList.Length)
9399 { 10103 {
9400 if (commandList.Data[i + 1] is LSL_String) 10104 if (commandList.Data[i + 1] is LSL_String)
@@ -9407,7 +10111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9407 } 10111 }
9408 break; 10112 break;
9409 10113
9410 case ParcelMediaCommandEnum.Size: 10114 case (uint)ParcelMediaCommandEnum.Size:
9411 if ((i + 2) < commandList.Length) 10115 if ((i + 2) < commandList.Length)
9412 { 10116 {
9413 if (commandList.Data[i + 1] is LSL_Integer) 10117 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9477,7 +10181,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9477 } 10181 }
9478 } 10182 }
9479 10183
9480 if (commandToSend != null) 10184 if (commandToSend != 0)
9481 { 10185 {
9482 // the commandList contained a start/stop/... command, too 10186 // the commandList contained a start/stop/... command, too
9483 if (presence == null) 10187 if (presence == null)
@@ -9514,7 +10218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9514 10218
9515 if (aList.Data[i] != null) 10219 if (aList.Data[i] != null)
9516 { 10220 {
9517 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10221 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9518 { 10222 {
9519 case ParcelMediaCommandEnum.Url: 10223 case ParcelMediaCommandEnum.Url:
9520 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10224 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9557,16 +10261,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9557 { 10261 {
9558 m_host.AddScriptLPS(1); 10262 m_host.AddScriptLPS(1);
9559 10263
9560 lock (m_host.TaskInventory) 10264 m_host.TaskInventory.LockItemsForRead(true);
10265 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9561 { 10266 {
9562 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10267 if (inv.Value.Name == name)
9563 { 10268 {
9564 if (inv.Value.Name == name) 10269 m_host.TaskInventory.LockItemsForRead(false);
9565 { 10270 return inv.Value.Type;
9566 return inv.Value.Type;
9567 }
9568 } 10271 }
9569 } 10272 }
10273 m_host.TaskInventory.LockItemsForRead(false);
9570 10274
9571 return -1; 10275 return -1;
9572 } 10276 }
@@ -9577,15 +10281,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9577 10281
9578 if (quick_pay_buttons.Data.Length < 4) 10282 if (quick_pay_buttons.Data.Length < 4)
9579 { 10283 {
9580 LSLError("List must have at least 4 elements"); 10284 int x;
9581 return; 10285 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10286 {
10287 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10288 }
9582 } 10289 }
9583 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10290 int[] nPrice = new int[5];
9584 10291 nPrice[0] = price;
9585 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10292 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9586 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10293 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9587 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10294 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9588 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10295 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10296 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9589 m_host.ParentGroup.HasGroupChanged = true; 10297 m_host.ParentGroup.HasGroupChanged = true;
9590 } 10298 }
9591 10299
@@ -9603,6 +10311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9603 ShoutError("No permissions to track the camera"); 10311 ShoutError("No permissions to track the camera");
9604 return new LSL_Vector(); 10312 return new LSL_Vector();
9605 } 10313 }
10314 m_host.TaskInventory.LockItemsForRead(false);
9606 10315
9607 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10316 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9608 if (presence != null) 10317 if (presence != null)
@@ -9627,6 +10336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9627 ShoutError("No permissions to track the camera"); 10336 ShoutError("No permissions to track the camera");
9628 return new LSL_Rotation(); 10337 return new LSL_Rotation();
9629 } 10338 }
10339 m_host.TaskInventory.LockItemsForRead(false);
9630 10340
9631 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10341 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9632 if (presence != null) 10342 if (presence != null)
@@ -9688,8 +10398,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9688 { 10398 {
9689 m_host.AddScriptLPS(1); 10399 m_host.AddScriptLPS(1);
9690 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10400 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9691 if (detectedParams == null) return; // only works on the first detected avatar 10401 if (detectedParams == null)
9692 10402 {
10403 if (m_host.ParentGroup.IsAttachment == true)
10404 {
10405 detectedParams = new DetectParams();
10406 detectedParams.Key = m_host.OwnerID;
10407 }
10408 else
10409 {
10410 return;
10411 }
10412 }
10413
9693 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10414 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9694 if (avatar != null) 10415 if (avatar != null)
9695 { 10416 {
@@ -9697,6 +10418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9697 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10418 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9698 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10419 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9699 } 10420 }
10421
9700 ScriptSleep(1000); 10422 ScriptSleep(1000);
9701 } 10423 }
9702 10424
@@ -9822,12 +10544,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9822 10544
9823 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10545 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9824 object[] data = rules.Data; 10546 object[] data = rules.Data;
9825 for (int i = 0; i < data.Length; ++i) { 10547 for (int i = 0; i < data.Length; ++i)
10548 {
9826 int type = Convert.ToInt32(data[i++].ToString()); 10549 int type = Convert.ToInt32(data[i++].ToString());
9827 if (i >= data.Length) break; // odd number of entries => ignore the last 10550 if (i >= data.Length) break; // odd number of entries => ignore the last
9828 10551
9829 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10552 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9830 switch (type) { 10553 switch (type)
10554 {
9831 case ScriptBaseClass.CAMERA_FOCUS: 10555 case ScriptBaseClass.CAMERA_FOCUS:
9832 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10556 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9833 case ScriptBaseClass.CAMERA_POSITION: 10557 case ScriptBaseClass.CAMERA_POSITION:
@@ -9935,19 +10659,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9935 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10659 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9936 { 10660 {
9937 m_host.AddScriptLPS(1); 10661 m_host.AddScriptLPS(1);
9938 string ret = String.Empty; 10662
9939 string src1 = llBase64ToString(str1); 10663 if (str1 == String.Empty)
9940 string src2 = llBase64ToString(str2); 10664 return String.Empty;
9941 int c = 0; 10665 if (str2 == String.Empty)
9942 for (int i = 0; i < src1.Length; i++) 10666 return str1;
10667
10668 int len = str2.Length;
10669 if ((len % 4) != 0) // LL is EVIL!!!!
10670 {
10671 while (str2.EndsWith("="))
10672 str2 = str2.Substring(0, str2.Length - 1);
10673
10674 len = str2.Length;
10675 int mod = len % 4;
10676
10677 if (mod == 1)
10678 str2 = str2.Substring(0, str2.Length - 1);
10679 else if (mod == 2)
10680 str2 += "==";
10681 else if (mod == 3)
10682 str2 += "=";
10683 }
10684
10685 byte[] data1;
10686 byte[] data2;
10687 try
10688 {
10689 data1 = Convert.FromBase64String(str1);
10690 data2 = Convert.FromBase64String(str2);
10691 }
10692 catch (Exception)
10693 {
10694 return new LSL_String(String.Empty);
10695 }
10696
10697 byte[] d2 = new Byte[data1.Length];
10698 int pos = 0;
10699
10700 if (data1.Length <= data2.Length)
10701 {
10702 Array.Copy(data2, 0, d2, 0, data1.Length);
10703 }
10704 else
9943 { 10705 {
9944 ret += (char) (src1[i] ^ src2[c]); 10706 while (pos < data1.Length)
10707 {
10708 len = data1.Length - pos;
10709 if (len > data2.Length)
10710 len = data2.Length;
9945 10711
9946 c++; 10712 Array.Copy(data2, 0, d2, pos, len);
9947 if (c >= src2.Length) 10713 pos += len;
9948 c = 0; 10714 }
9949 } 10715 }
9950 return llStringToBase64(ret); 10716
10717 for (pos = 0 ; pos < data1.Length ; pos++ )
10718 data1[pos] ^= d2[pos];
10719
10720 return Convert.ToBase64String(data1);
9951 } 10721 }
9952 10722
9953 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10723 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10004,12 +10774,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10004 Regex r = new Regex(authregex); 10774 Regex r = new Regex(authregex);
10005 int[] gnums = r.GetGroupNumbers(); 10775 int[] gnums = r.GetGroupNumbers();
10006 Match m = r.Match(url); 10776 Match m = r.Match(url);
10007 if (m.Success) { 10777 if (m.Success)
10008 for (int i = 1; i < gnums.Length; i++) { 10778 {
10779 for (int i = 1; i < gnums.Length; i++)
10780 {
10009 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10781 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10010 //CaptureCollection cc = g.Captures; 10782 //CaptureCollection cc = g.Captures;
10011 } 10783 }
10012 if (m.Groups.Count == 5) { 10784 if (m.Groups.Count == 5)
10785 {
10013 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10786 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10014 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10787 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10015 } 10788 }
@@ -10372,15 +11145,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10372 11145
10373 internal UUID ScriptByName(string name) 11146 internal UUID ScriptByName(string name)
10374 { 11147 {
10375 lock (m_host.TaskInventory) 11148 m_host.TaskInventory.LockItemsForRead(true);
11149
11150 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10376 { 11151 {
10377 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11152 if (item.Type == 10 && item.Name == name)
10378 { 11153 {
10379 if (item.Type == 10 && item.Name == name) 11154 m_host.TaskInventory.LockItemsForRead(false);
10380 return item.ItemID; 11155 return item.ItemID;
10381 } 11156 }
10382 } 11157 }
10383 11158
11159 m_host.TaskInventory.LockItemsForRead(false);
11160
10384 return UUID.Zero; 11161 return UUID.Zero;
10385 } 11162 }
10386 11163
@@ -10421,6 +11198,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10421 { 11198 {
10422 m_host.AddScriptLPS(1); 11199 m_host.AddScriptLPS(1);
10423 11200
11201 //Clone is thread safe
10424 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11202 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10425 11203
10426 UUID assetID = UUID.Zero; 11204 UUID assetID = UUID.Zero;
@@ -10483,6 +11261,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10483 { 11261 {
10484 m_host.AddScriptLPS(1); 11262 m_host.AddScriptLPS(1);
10485 11263
11264 //Clone is thread safe
10486 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11265 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10487 11266
10488 UUID assetID = UUID.Zero; 11267 UUID assetID = UUID.Zero;
@@ -10563,15 +11342,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10563 return GetLinkPrimitiveParams(obj, rules); 11342 return GetLinkPrimitiveParams(obj, rules);
10564 } 11343 }
10565 11344
10566 public void print(string str) 11345 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10567 { 11346 {
10568 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11347 List<SceneObjectPart> parts = GetLinkParts(link);
10569 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11348 if (parts.Count < 1)
10570 if (ossl != null) 11349 return 0;
10571 { 11350
10572 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11351 return GetNumberOfSides(parts[0]);
10573 m_log.Info("LSL print():" + str);
10574 }
10575 } 11352 }
10576 11353
10577 private string Name2Username(string name) 11354 private string Name2Username(string name)
@@ -10617,155 +11394,482 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10617 return rq.ToString(); 11394 return rq.ToString();
10618 } 11395 }
10619 11396
11397 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11398 {
11399 m_SayShoutCount = 0;
11400 }
11401
11402 private struct Tri
11403 {
11404 public Vector3 p1;
11405 public Vector3 p2;
11406 public Vector3 p3;
11407 }
11408
11409 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11410 {
11411 float height = avatar.Appearance.AvatarHeight;
11412 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11413 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11414
11415 if (point.X > b1.X && point.X < b2.X &&
11416 point.Y > b1.Y && point.Y < b2.Y &&
11417 point.Z > b1.Z && point.Z < b2.Z)
11418 return true;
11419 return false;
11420 }
11421
11422 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11423 {
11424 List<ContactResult> contacts = new List<ContactResult>();
11425
11426 Vector3 ab = rayEnd - rayStart;
11427
11428 World.ForEachScenePresence(delegate(ScenePresence sp)
11429 {
11430 Vector3 ac = sp.AbsolutePosition - rayStart;
11431 Vector3 bc = sp.AbsolutePosition - rayEnd;
11432
11433 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11434
11435 if (d > 1.5)
11436 return;
11437
11438 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11439
11440 if (d2 > 0)
11441 return;
11442
11443 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11444 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11445
11446 if (!InBoundingBox(sp, p))
11447 return;
11448
11449 ContactResult result = new ContactResult ();
11450 result.ConsumerID = sp.LocalId;
11451 result.Depth = Vector3.Distance(rayStart, p);
11452 result.Normal = Vector3.Zero;
11453 result.Pos = p;
11454
11455 contacts.Add(result);
11456 });
11457
11458 return contacts.ToArray();
11459 }
11460
11461 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11462 {
11463 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11464 List<ContactResult> contacts = new List<ContactResult>();
11465
11466 Vector3 ab = rayEnd - rayStart;
11467
11468 World.ForEachSOG(delegate(SceneObjectGroup group)
11469 {
11470 if (m_host.ParentGroup == group)
11471 return;
11472
11473 if (group.IsAttachment)
11474 return;
11475
11476 if (group.RootPart.PhysActor == null)
11477 {
11478 if (!includePhantom)
11479 return;
11480 }
11481 else
11482 {
11483 if (group.RootPart.PhysActor.IsPhysical)
11484 {
11485 if (!includePhysical)
11486 return;
11487 }
11488 else
11489 {
11490 if (!includeNonPhysical)
11491 return;
11492 }
11493 }
11494
11495 // Find the radius ouside of which we don't even need to hit test
11496 float minX;
11497 float maxX;
11498 float minY;
11499 float maxY;
11500 float minZ;
11501 float maxZ;
11502
11503 float radius = 0.0f;
11504
11505 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11506
11507 if (Math.Abs(minX) > radius)
11508 radius = Math.Abs(minX);
11509 if (Math.Abs(minY) > radius)
11510 radius = Math.Abs(minY);
11511 if (Math.Abs(minZ) > radius)
11512 radius = Math.Abs(minZ);
11513 if (Math.Abs(maxX) > radius)
11514 radius = Math.Abs(maxX);
11515 if (Math.Abs(maxY) > radius)
11516 radius = Math.Abs(maxY);
11517 if (Math.Abs(maxZ) > radius)
11518 radius = Math.Abs(maxZ);
11519
11520 Vector3 ac = group.AbsolutePosition - rayStart;
11521 Vector3 bc = group.AbsolutePosition - rayEnd;
11522
11523 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11524
11525 // Too far off ray, don't bother
11526 if (d > radius)
11527 return;
11528
11529 // Behind ray, drop
11530 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11531 if (d2 > 0)
11532 return;
11533
11534 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11535 // Miss.
11536 if (!intersection.HitTF)
11537 return;
11538
11539 ContactResult result = new ContactResult ();
11540 result.ConsumerID = group.LocalId;
11541 result.Depth = intersection.distance;
11542 result.Normal = intersection.normal;
11543 result.Pos = intersection.ipoint;
11544
11545 contacts.Add(result);
11546 });
11547
11548 return contacts.ToArray();
11549 }
11550
11551 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11552 {
11553 double[,] heightfield = World.Heightmap.GetDoubles();
11554 List<ContactResult> contacts = new List<ContactResult>();
11555
11556 double min = 2048.0;
11557 double max = 0.0;
11558
11559 // Find the min and max of the heightfield
11560 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11561 {
11562 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11563 {
11564 if (heightfield[x, y] > max)
11565 max = heightfield[x, y];
11566 if (heightfield[x, y] < min)
11567 min = heightfield[x, y];
11568 }
11569 }
11570
11571
11572 // A ray extends past rayEnd, but doesn't go back before
11573 // rayStart. If the start is above the highest point of the ground
11574 // and the ray goes up, we can't hit the ground. Ever.
11575 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11576 return null;
11577
11578 // Same for going down
11579 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11580 return null;
11581
11582 List<Tri> trilist = new List<Tri>();
11583
11584 // Create our triangle list
11585 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11586 {
11587 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11588 {
11589 Tri t1 = new Tri();
11590 Tri t2 = new Tri();
11591
11592 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11593 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11594 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11595 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11596
11597 t1.p1 = p1;
11598 t1.p2 = p2;
11599 t1.p3 = p3;
11600
11601 t2.p1 = p3;
11602 t2.p2 = p4;
11603 t2.p3 = p1;
11604
11605 trilist.Add(t1);
11606 trilist.Add(t2);
11607 }
11608 }
11609
11610 // Ray direction
11611 Vector3 rayDirection = rayEnd - rayStart;
11612
11613 foreach (Tri t in trilist)
11614 {
11615 // Compute triangle plane normal and edges
11616 Vector3 u = t.p2 - t.p1;
11617 Vector3 v = t.p3 - t.p1;
11618 Vector3 n = Vector3.Cross(u, v);
11619
11620 if (n == Vector3.Zero)
11621 continue;
11622
11623 Vector3 w0 = rayStart - t.p1;
11624 double a = -Vector3.Dot(n, w0);
11625 double b = Vector3.Dot(n, rayDirection);
11626
11627 // Not intersecting the plane, or in plane (same thing)
11628 // Ignoring this MAY cause the ground to not be detected
11629 // sometimes
11630 if (Math.Abs(b) < 0.000001)
11631 continue;
11632
11633 double r = a / b;
11634
11635 // ray points away from plane
11636 if (r < 0.0)
11637 continue;
11638
11639 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11640
11641 float uu = Vector3.Dot(u, u);
11642 float uv = Vector3.Dot(u, v);
11643 float vv = Vector3.Dot(v, v);
11644 Vector3 w = ip - t.p1;
11645 float wu = Vector3.Dot(w, u);
11646 float wv = Vector3.Dot(w, v);
11647 float d = uv * uv - uu * vv;
11648
11649 float cs = (uv * wv - vv * wu) / d;
11650 if (cs < 0 || cs > 1.0)
11651 continue;
11652 float ct = (uv * wu - uu * wv) / d;
11653 if (ct < 0 || (cs + ct) > 1.0)
11654 continue;
11655
11656 // Add contact point
11657 ContactResult result = new ContactResult ();
11658 result.ConsumerID = 0;
11659 result.Depth = Vector3.Distance(rayStart, ip);
11660 result.Normal = n;
11661 result.Pos = ip;
11662
11663 contacts.Add(result);
11664 }
11665
11666 if (contacts.Count == 0)
11667 return null;
11668
11669 contacts.Sort(delegate(ContactResult a, ContactResult b)
11670 {
11671 return (int)(a.Depth - b.Depth);
11672 });
11673
11674 return contacts[0];
11675 }
11676/*
11677 // not done:
11678 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
11679 {
11680 ContactResult[] contacts = null;
11681 World.ForEachSOG(delegate(SceneObjectGroup group)
11682 {
11683 if (m_host.ParentGroup == group)
11684 return;
11685
11686 if (group.IsAttachment)
11687 return;
11688
11689 if(group.RootPart.PhysActor != null)
11690 return;
11691
11692 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
11693 });
11694 return contacts;
11695 }
11696*/
11697
10620 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11698 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10621 { 11699 {
11700 LSL_List list = new LSL_List();
11701
10622 m_host.AddScriptLPS(1); 11702 m_host.AddScriptLPS(1);
10623 11703
10624 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11704 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10625 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11705 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10626 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11706 Vector3 dir = rayEnd - rayStart;
10627 11707
10628 int count = 0; 11708 float dist = Vector3.Mag(dir);
10629// int detectPhantom = 0; 11709
11710 int count = 1;
11711 bool detectPhantom = false;
10630 int dataFlags = 0; 11712 int dataFlags = 0;
10631 int rejectTypes = 0; 11713 int rejectTypes = 0;
10632 11714
10633 for (int i = 0; i < options.Length; i += 2) 11715 for (int i = 0; i < options.Length; i += 2)
10634 { 11716 {
10635 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11717 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10636 {
10637 count = options.GetLSLIntegerItem(i + 1); 11718 count = options.GetLSLIntegerItem(i + 1);
10638 } 11719 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10639// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11720 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10640// {
10641// detectPhantom = options.GetLSLIntegerItem(i + 1);
10642// }
10643 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11721 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10644 {
10645 dataFlags = options.GetLSLIntegerItem(i + 1); 11722 dataFlags = options.GetLSLIntegerItem(i + 1);
10646 }
10647 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11723 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10648 {
10649 rejectTypes = options.GetLSLIntegerItem(i + 1); 11724 rejectTypes = options.GetLSLIntegerItem(i + 1);
10650 }
10651 } 11725 }
10652 11726
10653 LSL_List list = new LSL_List(); 11727 if (count > 16)
10654 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11728 count = 16;
10655
10656 double distance = Util.GetDistanceTo(startvector, endvector);
10657 11729
10658 if (distance == 0) 11730 List<ContactResult> results = new List<ContactResult>();
10659 distance = 0.001;
10660
10661 Vector3 posToCheck = startvector;
10662 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10663 11731
10664 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11732 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10665 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11733 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10666 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11734 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10667 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11735 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10668 11736
10669 for (float i = 0; i <= distance; i += 0.1f) 11737
11738 if (World.SuportsRayCastFiltered())
10670 { 11739 {
10671 posToCheck = startvector + (dir * (i / (float)distance)); 11740 if (dist == 0)
11741 return list;
10672 11742
10673 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11743 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11744 if (checkTerrain)
11745 rayfilter |= RayFilterFlags.land;
11746// if (checkAgents)
11747// rayfilter |= RayFilterFlags.agent;
11748 if (checkPhysical)
11749 rayfilter |= RayFilterFlags.physical;
11750 if (checkNonPhysical)
11751 rayfilter |= RayFilterFlags.nonphysical;
11752 if (detectPhantom)
11753 rayfilter |= RayFilterFlags.LSLPhanton;
11754
11755 Vector3 direction = dir * ( 1/dist);
11756
11757 if(rayfilter == 0)
10674 { 11758 {
10675 ContactResult result = new ContactResult(); 11759 list.Add(new LSL_Integer(0));
10676 result.ConsumerID = 0; 11760 return list;
10677 result.Depth = 0;
10678 result.Normal = Vector3.Zero;
10679 result.Pos = posToCheck;
10680 results.Add(result);
10681 checkTerrain = false;
10682 } 11761 }
10683 11762
10684 if (checkAgents) 11763 // get some more contacts to sort ???
11764 int physcount = 4 * count;
11765 if (physcount > 20)
11766 physcount = 20;
11767
11768 object physresults;
11769 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11770
11771 if (physresults == null)
10685 { 11772 {
10686 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11773 list.Add(new LSL_Integer(-3)); // timeout error
10687 { 11774 return list;
10688 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
10689 {
10690 ContactResult result = new ContactResult ();
10691 result.ConsumerID = sp.LocalId;
10692 result.Depth = 0;
10693 result.Normal = Vector3.Zero;
10694 result.Pos = posToCheck;
10695 results.Add(result);
10696 }
10697 });
10698 } 11775 }
10699 }
10700 11776
10701 int refcount = 0; 11777 results = (List<ContactResult>)physresults;
10702 foreach (ContactResult result in results) 11778
10703 { 11779 // for now physics doesn't detect sitted avatars so do it outside physics
10704 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11780 if (checkAgents)
10705 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11781 {
10706 continue; 11782 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11783 foreach (ContactResult r in agentHits)
11784 results.Add(r);
11785 }
10707 11786
10708 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11787 // bug: will not detect phantom unless they are physical
11788 // don't use ObjectIntersection because its also bad
10709 11789
10710 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11790 }
10711 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11791 else
11792 {
11793 if (checkTerrain)
11794 {
11795 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11796 if (groundContact != null)
11797 results.Add((ContactResult)groundContact);
11798 }
10712 11799
10713 if (entity == null) 11800 if (checkAgents)
10714 { 11801 {
10715 list.Add(UUID.Zero); 11802 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11803 foreach (ContactResult r in agentHits)
11804 results.Add(r);
11805 }
10716 11806
10717 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11807 if (checkPhysical || checkNonPhysical || detectPhantom)
10718 list.Add(0); 11808 {
11809 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11810 foreach (ContactResult r in objectHits)
11811 results.Add(r);
11812 }
11813 }
10719 11814
10720 list.Add(result.Pos); 11815 results.Sort(delegate(ContactResult a, ContactResult b)
11816 {
11817 return a.Depth.CompareTo(b.Depth);
11818 });
11819
11820 int values = 0;
11821 SceneObjectGroup thisgrp = m_host.ParentGroup;
10721 11822
10722 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11823 foreach (ContactResult result in results)
10723 list.Add(result.Normal); 11824 {
11825 if (result.Depth > dist)
11826 continue;
10724 11827
10725 continue; //Can't find it, so add UUID.Zero 11828 // physics ray can return colisions with host prim
10726 } 11829 if (m_host.LocalId == result.ConsumerID)
11830 continue;
10727 11831
10728 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && 11832 UUID itemID = UUID.Zero;
10729 ((ISceneChildEntity)intersection.obj).PhysActor == null) 11833 int linkNum = 0;
10730 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10731 11834
10732 if (entity is SceneObjectPart) 11835 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11836 // It's a prim!
11837 if (part != null)
10733 { 11838 {
10734 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 11839 // dont detect members of same object ???
11840 if (part.ParentGroup == thisgrp)
11841 continue;
10735 11842
10736 if (pa != null && pa.IsPhysical) 11843 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10737 { 11844 itemID = part.ParentGroup.UUID;
10738 if (!checkPhysical)
10739 continue;
10740 }
10741 else 11845 else
10742 { 11846 itemID = part.UUID;
10743 if (!checkNonPhysical)
10744 continue;
10745 }
10746 }
10747 11847
10748 refcount++; 11848 linkNum = part.LinkNum;
10749 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11849 }
10750 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10751 else 11850 else
10752 list.Add(entity.UUID);
10753
10754 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10755 { 11851 {
10756 if (entity is SceneObjectPart) 11852 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10757 list.Add(((SceneObjectPart)entity).LinkNum); 11853 /// It it a boy? a girl?
10758 else 11854 if (sp != null)
10759 list.Add(0); 11855 itemID = sp.UUID;
10760 } 11856 }
10761 11857
10762 list.Add(result.Pos); 11858 list.Add(new LSL_String(itemID.ToString()));
11859 list.Add(new LSL_String(result.Pos.ToString()));
11860
11861 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11862 list.Add(new LSL_Integer(linkNum));
10763 11863
10764 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11864 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10765 list.Add(result.Normal); 11865 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11866
11867 values++;
11868 if (values >= count)
11869 break;
10766 } 11870 }
10767 11871
10768 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11872 list.Add(new LSL_Integer(values));
10769 11873
10770 return list; 11874 return list;
10771 } 11875 }
@@ -10805,7 +11909,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10805 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11909 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10806 if (!isAccount) return 0; 11910 if (!isAccount) return 0;
10807 if (estate.HasAccess(id)) return 1; 11911 if (estate.HasAccess(id)) return 1;
10808 if (estate.IsBanned(id)) 11912 if (estate.IsBanned(id, World.GetUserFlags(id)))
10809 estate.RemoveBan(id); 11913 estate.RemoveBan(id);
10810 estate.AddEstateUser(id); 11914 estate.AddEstateUser(id);
10811 break; 11915 break;
@@ -10824,14 +11928,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10824 break; 11928 break;
10825 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11929 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10826 if (!isAccount) return 0; 11930 if (!isAccount) return 0;
10827 if (estate.IsBanned(id)) return 1; 11931 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10828 EstateBan ban = new EstateBan(); 11932 EstateBan ban = new EstateBan();
10829 ban.EstateID = estate.EstateID; 11933 ban.EstateID = estate.EstateID;
10830 ban.BannedUserID = id; 11934 ban.BannedUserID = id;
10831 estate.AddBan(ban); 11935 estate.AddBan(ban);
10832 break; 11936 break;
10833 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11937 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10834 if (!isAccount || !estate.IsBanned(id)) return 0; 11938 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10835 estate.RemoveBan(id); 11939 estate.RemoveBan(id);
10836 break; 11940 break;
10837 default: return 0; 11941 default: return 0;
@@ -10860,7 +11964,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10860 return 16384; 11964 return 16384;
10861 } 11965 }
10862 11966
10863 public LSL_Integer llGetUsedMemory() 11967 public virtual LSL_Integer llGetUsedMemory()
10864 { 11968 {
10865 m_host.AddScriptLPS(1); 11969 m_host.AddScriptLPS(1);
10866 // The value returned for LSO scripts in SL 11970 // The value returned for LSO scripts in SL
@@ -10888,7 +11992,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10888 public void llSetSoundQueueing(int queue) 11992 public void llSetSoundQueueing(int queue)
10889 { 11993 {
10890 m_host.AddScriptLPS(1); 11994 m_host.AddScriptLPS(1);
10891 NotImplemented("llSetSoundQueueing");
10892 } 11995 }
10893 11996
10894 public void llCollisionSprite(string impact_sprite) 11997 public void llCollisionSprite(string impact_sprite)
@@ -10900,10 +12003,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10900 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12003 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10901 { 12004 {
10902 m_host.AddScriptLPS(1); 12005 m_host.AddScriptLPS(1);
10903 NotImplemented("llGodLikeRezObject"); 12006
12007 if (!World.Permissions.IsGod(m_host.OwnerID))
12008 NotImplemented("llGodLikeRezObject");
12009
12010 AssetBase rezAsset = World.AssetService.Get(inventory);
12011 if (rezAsset == null)
12012 {
12013 llSay(0, "Asset not found");
12014 return;
12015 }
12016
12017 SceneObjectGroup group = null;
12018
12019 try
12020 {
12021 string xmlData = Utils.BytesToString(rezAsset.Data);
12022 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12023 }
12024 catch
12025 {
12026 llSay(0, "Asset not found");
12027 return;
12028 }
12029
12030 if (group == null)
12031 {
12032 llSay(0, "Asset not found");
12033 return;
12034 }
12035
12036 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12037 group.RootPart.AttachOffset = group.AbsolutePosition;
12038
12039 group.ResetIDs();
12040
12041 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12042 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12043 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12044 group.ScheduleGroupForFullUpdate();
12045
12046 // objects rezzed with this method are die_at_edge by default.
12047 group.RootPart.SetDieAtEdge(true);
12048
12049 group.ResumeScripts();
12050
12051 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12052 "object_rez", new Object[] {
12053 new LSL_String(
12054 group.RootPart.UUID.ToString()) },
12055 new DetectParams[0]));
12056 }
12057
12058 public LSL_String llTransferLindenDollars(string destination, int amount)
12059 {
12060 UUID txn = UUID.Random();
12061
12062 Util.FireAndForget(delegate(object x)
12063 {
12064 int replycode = 0;
12065 string replydata = destination + "," + amount.ToString();
12066
12067 try
12068 {
12069 TaskInventoryItem item = GetSelfInventoryItem();
12070 if (item == null)
12071 {
12072 replydata = "SERVICE_ERROR";
12073 return;
12074 }
12075
12076 m_host.AddScriptLPS(1);
12077
12078 if (item.PermsGranter == UUID.Zero)
12079 {
12080 replydata = "MISSING_PERMISSION_DEBIT";
12081 return;
12082 }
12083
12084 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12085 {
12086 replydata = "MISSING_PERMISSION_DEBIT";
12087 return;
12088 }
12089
12090 UUID toID = new UUID();
12091
12092 if (!UUID.TryParse(destination, out toID))
12093 {
12094 replydata = "INVALID_AGENT";
12095 return;
12096 }
12097
12098 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12099
12100 if (money == null)
12101 {
12102 replydata = "TRANSFERS_DISABLED";
12103 return;
12104 }
12105
12106 bool result = money.ObjectGiveMoney(
12107 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12108
12109 if (result)
12110 {
12111 replycode = 1;
12112 return;
12113 }
12114
12115 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12116 }
12117 finally
12118 {
12119 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12120 "transaction_result", new Object[] {
12121 new LSL_String(txn.ToString()),
12122 new LSL_Integer(replycode),
12123 new LSL_String(replydata) },
12124 new DetectParams[0]));
12125 }
12126 });
12127
12128 return txn.ToString();
10904 } 12129 }
10905 12130
10906 #endregion 12131 #endregion
12132
12133 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12134 {
12135 SceneObjectGroup group = m_host.ParentGroup;
12136
12137 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12138 return;
12139 if (group.IsAttachment)
12140 return;
12141
12142 if (frames.Data.Length > 0) // We are getting a new motion
12143 {
12144 if (group.RootPart.KeyframeMotion != null)
12145 group.RootPart.KeyframeMotion.Stop();
12146 group.RootPart.KeyframeMotion = null;
12147
12148 int idx = 0;
12149
12150 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12151 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12152
12153 while (idx < options.Data.Length)
12154 {
12155 int option = (int)options.GetLSLIntegerItem(idx++);
12156 int remain = options.Data.Length - idx;
12157
12158 switch (option)
12159 {
12160 case ScriptBaseClass.KFM_MODE:
12161 if (remain < 1)
12162 break;
12163 int modeval = (int)options.GetLSLIntegerItem(idx++);
12164 switch(modeval)
12165 {
12166 case ScriptBaseClass.KFM_FORWARD:
12167 mode = KeyframeMotion.PlayMode.Forward;
12168 break;
12169 case ScriptBaseClass.KFM_REVERSE:
12170 mode = KeyframeMotion.PlayMode.Reverse;
12171 break;
12172 case ScriptBaseClass.KFM_LOOP:
12173 mode = KeyframeMotion.PlayMode.Loop;
12174 break;
12175 case ScriptBaseClass.KFM_PING_PONG:
12176 mode = KeyframeMotion.PlayMode.PingPong;
12177 break;
12178 }
12179 break;
12180 case ScriptBaseClass.KFM_DATA:
12181 if (remain < 1)
12182 break;
12183 int dataval = (int)options.GetLSLIntegerItem(idx++);
12184 data = (KeyframeMotion.DataFormat)dataval;
12185 break;
12186 }
12187 }
12188
12189 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12190
12191 idx = 0;
12192
12193 int elemLength = 2;
12194 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12195 elemLength = 3;
12196
12197 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12198 while (idx < frames.Data.Length)
12199 {
12200 int remain = frames.Data.Length - idx;
12201
12202 if (remain < elemLength)
12203 break;
12204
12205 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12206 frame.Position = null;
12207 frame.Rotation = null;
12208
12209 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12210 {
12211 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12212 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12213 }
12214 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12215 {
12216 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12217 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12218 }
12219
12220 float tempf = (float)frames.GetLSLFloatItem(idx++);
12221 frame.TimeMS = (int)(tempf * 1000.0f);
12222
12223 keyframes.Add(frame);
12224 }
12225
12226 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12227 group.RootPart.KeyframeMotion.Start();
12228 }
12229 else
12230 {
12231 if (group.RootPart.KeyframeMotion == null)
12232 return;
12233
12234 if (options.Data.Length == 0)
12235 {
12236 group.RootPart.KeyframeMotion.Stop();
12237 return;
12238 }
12239
12240 int code = (int)options.GetLSLIntegerItem(0);
12241
12242 int idx = 0;
12243
12244 while (idx < options.Data.Length)
12245 {
12246 int option = (int)options.GetLSLIntegerItem(idx++);
12247 int remain = options.Data.Length - idx;
12248
12249 switch (option)
12250 {
12251 case ScriptBaseClass.KFM_COMMAND:
12252 int cmd = (int)options.GetLSLIntegerItem(idx++);
12253 switch (cmd)
12254 {
12255 case ScriptBaseClass.KFM_CMD_PLAY:
12256 group.RootPart.KeyframeMotion.Start();
12257 break;
12258 case ScriptBaseClass.KFM_CMD_STOP:
12259 group.RootPart.KeyframeMotion.Stop();
12260 break;
12261 case ScriptBaseClass.KFM_CMD_PAUSE:
12262 group.RootPart.KeyframeMotion.Pause();
12263 break;
12264 }
12265 break;
12266 }
12267 }
12268 }
12269 }
10907 } 12270 }
10908 12271
10909 public class NotecardCache 12272 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 7fc7337..3f77f38 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 /// <summary> 221 /// <summary>
@@ -925,18 +934,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
925 if (target != null) 934 if (target != null)
926 { 935 {
927 UUID animID=UUID.Zero; 936 UUID animID=UUID.Zero;
928 lock (m_host.TaskInventory) 937 m_host.TaskInventory.LockItemsForRead(true);
938 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
929 { 939 {
930 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 940 if (inv.Value.Name == animation)
931 { 941 {
932 if (inv.Value.Name == animation) 942 if (inv.Value.Type == (int)AssetType.Animation)
933 { 943 animID = inv.Value.AssetID;
934 if (inv.Value.Type == (int)AssetType.Animation) 944 continue;
935 animID = inv.Value.AssetID;
936 continue;
937 }
938 } 945 }
939 } 946 }
947 m_host.TaskInventory.LockItemsForRead(false);
940 if (animID == UUID.Zero) 948 if (animID == UUID.Zero)
941 target.Animator.AddAnimation(animation, m_host.UUID); 949 target.Animator.AddAnimation(animation, m_host.UUID);
942 else 950 else
@@ -963,18 +971,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
963 if (target != null) 971 if (target != null)
964 { 972 {
965 UUID animID = UUID.Zero; 973 UUID animID = UUID.Zero;
966 lock (m_host.TaskInventory) 974 m_host.TaskInventory.LockItemsForRead(true);
975 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
967 { 976 {
968 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 977 if (inv.Value.Name == animation)
969 { 978 {
970 if (inv.Value.Name == animation) 979 if (inv.Value.Type == (int)AssetType.Animation)
971 { 980 animID = inv.Value.AssetID;
972 if (inv.Value.Type == (int)AssetType.Animation) 981 continue;
973 animID = inv.Value.AssetID;
974 continue;
975 }
976 } 982 }
977 } 983 }
984 m_host.TaskInventory.LockItemsForRead(false);
978 985
979 if (animID == UUID.Zero) 986 if (animID == UUID.Zero)
980 target.Animator.RemoveAnimation(animation); 987 target.Animator.RemoveAnimation(animation);
@@ -1795,6 +1802,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1795 1802
1796 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1803 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1797 { 1804 {
1805 m_host.TaskInventory.LockItemsForRead(true);
1798 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1806 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1799 { 1807 {
1800 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1808 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1802,6 +1810,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1802 assetID = item.AssetID; 1810 assetID = item.AssetID;
1803 } 1811 }
1804 } 1812 }
1813 m_host.TaskInventory.LockItemsForRead(false);
1805 } 1814 }
1806 1815
1807 if (assetID == UUID.Zero) 1816 if (assetID == UUID.Zero)
@@ -2269,7 +2278,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2269 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2278 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2270 m_host.AddScriptLPS(1); 2279 m_host.AddScriptLPS(1);
2271 2280
2272 return NpcCreate(firstname, lastname, position, notecard, false, false); 2281 return NpcCreate(firstname, lastname, position, notecard, true, false);
2273 } 2282 }
2274 2283
2275 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2284 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2280,24 +2289,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2280 return NpcCreate( 2289 return NpcCreate(
2281 firstname, lastname, position, notecard, 2290 firstname, lastname, position, notecard,
2282 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2291 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2283 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2292 false);
2293// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2284 } 2294 }
2285 2295
2286 private LSL_Key NpcCreate( 2296 private LSL_Key NpcCreate(
2287 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2297 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2288 { 2298 {
2299 if (!owned)
2300 OSSLError("Unowned NPCs are unsupported");
2301
2302 string groupTitle = String.Empty;
2303
2304 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2305 return new LSL_Key(UUID.Zero.ToString());
2306
2307 if (firstname != String.Empty || lastname != String.Empty)
2308 {
2309 if (firstname != "Shown outfit:")
2310 groupTitle = "- NPC -";
2311 }
2312
2289 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2313 INPCModule module = World.RequestModuleInterface<INPCModule>();
2290 if (module != null) 2314 if (module != null)
2291 { 2315 {
2292 AvatarAppearance appearance = null; 2316 AvatarAppearance appearance = null;
2293 2317
2294 UUID id; 2318// UUID id;
2295 if (UUID.TryParse(notecard, out id)) 2319// if (UUID.TryParse(notecard, out id))
2296 { 2320// {
2297 ScenePresence clonePresence = World.GetScenePresence(id); 2321// ScenePresence clonePresence = World.GetScenePresence(id);
2298 if (clonePresence != null) 2322// if (clonePresence != null)
2299 appearance = clonePresence.Appearance; 2323// appearance = clonePresence.Appearance;
2300 } 2324// }
2301 2325
2302 if (appearance == null) 2326 if (appearance == null)
2303 { 2327 {
@@ -2325,6 +2349,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2325 World, 2349 World,
2326 appearance); 2350 appearance);
2327 2351
2352 ScenePresence sp;
2353 if (World.TryGetScenePresence(x, out sp))
2354 {
2355 sp.Grouptitle = groupTitle;
2356 sp.SendAvatarDataToAllAgents();
2357 }
2328 return new LSL_Key(x.ToString()); 2358 return new LSL_Key(x.ToString());
2329 } 2359 }
2330 2360
@@ -2593,16 +2623,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2593 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2623 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2594 m_host.AddScriptLPS(1); 2624 m_host.AddScriptLPS(1);
2595 2625
2596 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2626 ManualResetEvent ev = new ManualResetEvent(false);
2597 if (module != null)
2598 {
2599 UUID npcId = new UUID(npc.m_string);
2600 2627
2601 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2628 Util.FireAndForget(delegate(object x) {
2602 return; 2629 try
2630 {
2631 INPCModule module = World.RequestModuleInterface<INPCModule>();
2632 if (module != null)
2633 {
2634 UUID npcId = new UUID(npc.m_string);
2603 2635
2604 module.DeleteNPC(npcId, World); 2636 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2605 } 2637 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2638 {
2639 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2640 return;
2641 }
2642
2643 module.DeleteNPC(npcId, World);
2644 }
2645 }
2646 finally
2647 {
2648 ev.Set();
2649 }
2650 });
2651 ev.WaitOne();
2606 } 2652 }
2607 2653
2608 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2654 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3122,4 +3168,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3122 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3168 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3123 } 3169 }
3124 } 3170 }
3125} \ No newline at end of file 3171}
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 d0c852b..fc77d05 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 2c8af81..0f763f1 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 {