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.cs3003
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs11
-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, 2715 insertions, 947 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 62b5c0f..a067868 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
@@ -1103,10 +1222,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1103 return detectedParams.TouchUV; 1222 return detectedParams.TouchUV;
1104 } 1223 }
1105 1224
1225 [DebuggerNonUserCode]
1106 public virtual void llDie() 1226 public virtual void llDie()
1107 { 1227 {
1108 m_host.AddScriptLPS(1); 1228 m_host.AddScriptLPS(1);
1109 throw new SelfDeleteException(); 1229 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1110 } 1230 }
1111 1231
1112 public LSL_Float llGround(LSL_Vector offset) 1232 public LSL_Float llGround(LSL_Vector offset)
@@ -1179,6 +1299,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1179 1299
1180 public void llSetStatus(int status, int value) 1300 public void llSetStatus(int status, int value)
1181 { 1301 {
1302 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1303 return;
1182 m_host.AddScriptLPS(1); 1304 m_host.AddScriptLPS(1);
1183 1305
1184 int statusrotationaxis = 0; 1306 int statusrotationaxis = 0;
@@ -1410,6 +1532,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1410 { 1532 {
1411 m_host.AddScriptLPS(1); 1533 m_host.AddScriptLPS(1);
1412 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
1413 if (face == ScriptBaseClass.ALL_SIDES) 1577 if (face == ScriptBaseClass.ALL_SIDES)
1414 face = SceneObjectPart.ALL_SIDES; 1578 face = SceneObjectPart.ALL_SIDES;
1415 1579
@@ -1418,6 +1582,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1418 1582
1419 public void SetTexGen(SceneObjectPart part, int face,int style) 1583 public void SetTexGen(SceneObjectPart part, int face,int style)
1420 { 1584 {
1585 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1586 return;
1587
1421 Primitive.TextureEntry tex = part.Shape.Textures; 1588 Primitive.TextureEntry tex = part.Shape.Textures;
1422 MappingType textype; 1589 MappingType textype;
1423 textype = MappingType.Default; 1590 textype = MappingType.Default;
@@ -1448,6 +1615,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1448 1615
1449 public void SetGlow(SceneObjectPart part, int face, float glow) 1616 public void SetGlow(SceneObjectPart part, int face, float glow)
1450 { 1617 {
1618 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1619 return;
1620
1451 Primitive.TextureEntry tex = part.Shape.Textures; 1621 Primitive.TextureEntry tex = part.Shape.Textures;
1452 if (face >= 0 && face < GetNumberOfSides(part)) 1622 if (face >= 0 && face < GetNumberOfSides(part))
1453 { 1623 {
@@ -1473,6 +1643,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1473 1643
1474 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1644 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1475 { 1645 {
1646 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1647 return;
1476 1648
1477 Shininess sval = new Shininess(); 1649 Shininess sval = new Shininess();
1478 1650
@@ -1523,6 +1695,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1523 1695
1524 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1696 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1525 { 1697 {
1698 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1699 return;
1700
1526 Primitive.TextureEntry tex = part.Shape.Textures; 1701 Primitive.TextureEntry tex = part.Shape.Textures;
1527 if (face >= 0 && face < GetNumberOfSides(part)) 1702 if (face >= 0 && face < GetNumberOfSides(part))
1528 { 1703 {
@@ -1583,13 +1758,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1583 m_host.AddScriptLPS(1); 1758 m_host.AddScriptLPS(1);
1584 1759
1585 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1760 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1586 1761 if (parts.Count > 0)
1587 foreach (SceneObjectPart part in parts) 1762 {
1588 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 }
1589 } 1774 }
1590 1775
1591 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1776 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1592 { 1777 {
1778 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1779 return;
1780
1593 Primitive.TextureEntry tex = part.Shape.Textures; 1781 Primitive.TextureEntry tex = part.Shape.Textures;
1594 Color4 texcolor; 1782 Color4 texcolor;
1595 if (face >= 0 && face < GetNumberOfSides(part)) 1783 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1642,7 +1830,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1642 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,
1643 float wind, float tension, LSL_Vector Force) 1831 float wind, float tension, LSL_Vector Force)
1644 { 1832 {
1645 if (part == null) 1833 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1646 return; 1834 return;
1647 1835
1648 if (flexi) 1836 if (flexi)
@@ -1676,7 +1864,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1676 /// <param name="falloff"></param> 1864 /// <param name="falloff"></param>
1677 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)
1678 { 1866 {
1679 if (part == null) 1867 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1680 return; 1868 return;
1681 1869
1682 if (light) 1870 if (light)
@@ -1754,15 +1942,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1754 m_host.AddScriptLPS(1); 1942 m_host.AddScriptLPS(1);
1755 1943
1756 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1944 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1757 1945 if (parts.Count > 0)
1758 foreach (SceneObjectPart part in parts) 1946 {
1759 SetTexture(part, texture, face); 1947 try
1760 1948 {
1949 parts[0].ParentGroup.areUpdatesSuspended = true;
1950 foreach (SceneObjectPart part in parts)
1951 SetTexture(part, texture, face);
1952 }
1953 finally
1954 {
1955 parts[0].ParentGroup.areUpdatesSuspended = false;
1956 }
1957 }
1761 ScriptSleep(200); 1958 ScriptSleep(200);
1762 } 1959 }
1763 1960
1764 protected void SetTexture(SceneObjectPart part, string texture, int face) 1961 protected void SetTexture(SceneObjectPart part, string texture, int face)
1765 { 1962 {
1963 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1964 return;
1965
1766 UUID textureID = new UUID(); 1966 UUID textureID = new UUID();
1767 1967
1768 textureID = InventoryKey(texture, (int)AssetType.Texture); 1968 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1807,6 +2007,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1807 2007
1808 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2008 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1809 { 2009 {
2010 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2011 return;
2012
1810 Primitive.TextureEntry tex = part.Shape.Textures; 2013 Primitive.TextureEntry tex = part.Shape.Textures;
1811 if (face >= 0 && face < GetNumberOfSides(part)) 2014 if (face >= 0 && face < GetNumberOfSides(part))
1812 { 2015 {
@@ -1843,6 +2046,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1843 2046
1844 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2047 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1845 { 2048 {
2049 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2050 return;
2051
1846 Primitive.TextureEntry tex = part.Shape.Textures; 2052 Primitive.TextureEntry tex = part.Shape.Textures;
1847 if (face >= 0 && face < GetNumberOfSides(part)) 2053 if (face >= 0 && face < GetNumberOfSides(part))
1848 { 2054 {
@@ -1879,6 +2085,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1879 2085
1880 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2086 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1881 { 2087 {
2088 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2089 return;
2090
1882 Primitive.TextureEntry tex = part.Shape.Textures; 2091 Primitive.TextureEntry tex = part.Shape.Textures;
1883 if (face >= 0 && face < GetNumberOfSides(part)) 2092 if (face >= 0 && face < GetNumberOfSides(part))
1884 { 2093 {
@@ -1983,26 +2192,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1983 return real_vec; 2192 return real_vec;
1984 } 2193 }
1985 2194
2195 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2196 {
2197 return new LSL_Integer(SetRegionPos(m_host, pos));
2198 }
2199
2200 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2201 {
2202 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2203 return 0;
2204
2205 SceneObjectGroup grp = part.ParentGroup;
2206
2207 if (grp.IsAttachment)
2208 return 0;
2209
2210 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2211 return 0;
2212
2213 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)
2214 return 0;
2215
2216 float constrainedX = (float)targetPos.x;
2217 float constrainedY = (float)targetPos.y;
2218
2219 if (constrainedX < 0.0f)
2220 constrainedX = 0.0f;
2221 if (constrainedY < 0.0f)
2222 constrainedY = 0.0f;
2223 if (constrainedX >= (float)Constants.RegionSize)
2224 constrainedX = (float)Constants.RegionSize - 0.1f;
2225 if (constrainedY >= (float)Constants.RegionSize)
2226 constrainedY = (float)Constants.RegionSize -0.1f;
2227
2228 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2229
2230 if (targetPos.z < ground)
2231 targetPos.z = ground;
2232
2233 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2234
2235 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2236 return 0;
2237
2238 grp.UpdateGroupPosition(dest);
2239
2240 return 1;
2241 }
2242
1986 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2243 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1987 { 2244 {
1988 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2245 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2246 return;
2247
1989 LSL_Vector currentPos = GetPartLocalPos(part); 2248 LSL_Vector currentPos = GetPartLocalPos(part);
2249 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1990 2250
1991 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1992 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1993 2251
1994 if (part.ParentGroup.RootPart == part) 2252 if (part.ParentGroup.RootPart == part)
1995 { 2253 {
1996 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1997 targetPos.z = ground;
1998 SceneObjectGroup parent = part.ParentGroup; 2254 SceneObjectGroup parent = part.ParentGroup;
1999 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2255 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2000 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2256 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2257 return;
2258 Util.FireAndForget(delegate(object x) {
2259 parent.UpdateGroupPosition(dest);
2260 });
2001 } 2261 }
2002 else 2262 else
2003 { 2263 {
2004 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2264 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2005 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2006 SceneObjectGroup parent = part.ParentGroup; 2265 SceneObjectGroup parent = part.ParentGroup;
2007 parent.HasGroupChanged = true; 2266 parent.HasGroupChanged = true;
2008 parent.ScheduleGroupForTerseUpdate(); 2267 parent.ScheduleGroupForTerseUpdate();
@@ -2035,17 +2294,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2035 else 2294 else
2036 { 2295 {
2037 if (part.ParentGroup.IsAttachment) 2296 if (part.ParentGroup.IsAttachment)
2038 {
2039 pos = part.AttachedPos; 2297 pos = part.AttachedPos;
2040 }
2041 else 2298 else
2042 {
2043 pos = part.AbsolutePosition; 2299 pos = part.AbsolutePosition;
2044 }
2045 } 2300 }
2046 2301
2047// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2048
2049 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2302 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2050 } 2303 }
2051 2304
@@ -2054,9 +2307,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2054 m_host.AddScriptLPS(1); 2307 m_host.AddScriptLPS(1);
2055 2308
2056 // try to let this work as in SL... 2309 // try to let this work as in SL...
2057 if (m_host.ParentID == 0) 2310 if (m_host.LinkNum < 2)
2058 { 2311 {
2059 // special case: If we are root, rotate complete SOG to new rotation 2312 // Special case: If we are root, rotate complete SOG to new
2313 // rotation.
2314 // We are root if the link number is 0 (single prim) or 1
2315 // (root prim). ParentID may be nonzero in attachments and
2316 // using it would cause attachments and HUDs to rotate
2317 // to the wrong positions.
2060 SetRot(m_host, Rot2Quaternion(rot)); 2318 SetRot(m_host, Rot2Quaternion(rot));
2061 } 2319 }
2062 else 2320 else
@@ -2081,6 +2339,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2081 2339
2082 protected void SetRot(SceneObjectPart part, Quaternion rot) 2340 protected void SetRot(SceneObjectPart part, Quaternion rot)
2083 { 2341 {
2342 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2343 return;
2344
2084 part.UpdateRotation(rot); 2345 part.UpdateRotation(rot);
2085 // Update rotation does not move the object in the physics scene if it's a linkset. 2346 // Update rotation does not move the object in the physics scene if it's a linkset.
2086 2347
@@ -2235,13 +2496,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2235 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2496 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2236 { 2497 {
2237 m_host.AddScriptLPS(1); 2498 m_host.AddScriptLPS(1);
2238 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2499 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2239 } 2500 }
2240 2501
2241 public void llSetTorque(LSL_Vector torque, int local) 2502 public void llSetTorque(LSL_Vector torque, int local)
2242 { 2503 {
2243 m_host.AddScriptLPS(1); 2504 m_host.AddScriptLPS(1);
2244 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2505 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2245 } 2506 }
2246 2507
2247 public LSL_Vector llGetTorque() 2508 public LSL_Vector llGetTorque()
@@ -2845,35 +3106,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2845 public void llLookAt(LSL_Vector target, double strength, double damping) 3106 public void llLookAt(LSL_Vector target, double strength, double damping)
2846 { 3107 {
2847 m_host.AddScriptLPS(1); 3108 m_host.AddScriptLPS(1);
2848 // Determine where we are looking from
2849 LSL_Vector from = llGetPos();
2850 3109
2851 // Work out the normalised vector from the source to the target 3110 // Get the normalized vector to the target
2852 LSL_Vector delta = llVecNorm(target - from); 3111 LSL_Vector d1 = llVecNorm(target - llGetPos());
2853 LSL_Vector angle = new LSL_Vector(0,0,0);
2854 3112
2855 // Calculate the yaw 3113 // Get the bearing (yaw)
2856 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3114 LSL_Vector a1 = new LSL_Vector(0,0,0);
2857 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3115 a1.z = llAtan2(d1.y, d1.x);
2858 3116
2859 // Calculate pitch 3117 // Get the elevation (pitch)
2860 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3118 LSL_Vector a2 = new LSL_Vector(0,0,0);
3119 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2861 3120
2862 // we need to convert from a vector describing 3121 LSL_Rotation r1 = llEuler2Rot(a1);
2863 // the angles of rotation in radians into rotation value 3122 LSL_Rotation r2 = llEuler2Rot(a2);
2864 LSL_Rotation rot = llEuler2Rot(angle); 3123 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2865
2866 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2867 // set the rotation of the object, copy that behavior
2868 PhysicsActor pa = m_host.PhysActor;
2869 3124
2870 if (strength == 0 || pa == null || !pa.IsPhysical) 3125 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2871 { 3126 {
2872 llSetRot(rot); 3127 // Do nothing if either value is 0 (this has been checked in SL)
3128 if (strength <= 0.0 || damping <= 0.0)
3129 return;
3130
3131 llSetRot(r3 * r2 * r1);
2873 } 3132 }
2874 else 3133 else
2875 { 3134 {
2876 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3135 if (strength == 0)
3136 {
3137 llSetRot(r3 * r2 * r1);
3138 return;
3139 }
3140
3141 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2877 } 3142 }
2878 } 3143 }
2879 3144
@@ -2918,17 +3183,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2918 } 3183 }
2919 else 3184 else
2920 { 3185 {
2921 if (m_host.IsRoot) 3186 // new SL always returns object mass
2922 { 3187// if (m_host.IsRoot)
3188// {
2923 return m_host.ParentGroup.GetMass(); 3189 return m_host.ParentGroup.GetMass();
2924 } 3190// }
2925 else 3191// else
2926 { 3192// {
2927 return m_host.GetMass(); 3193// return m_host.GetMass();
2928 } 3194// }
2929 } 3195 }
2930 } 3196 }
2931 3197
3198
3199 public LSL_Float llGetMassMKS()
3200 {
3201 return 100f * llGetMass();
3202 }
3203
2932 public void llCollisionFilter(string name, string id, int accept) 3204 public void llCollisionFilter(string name, string id, int accept)
2933 { 3205 {
2934 m_host.AddScriptLPS(1); 3206 m_host.AddScriptLPS(1);
@@ -3039,11 +3311,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3039 { 3311 {
3040 m_host.AddScriptLPS(1); 3312 m_host.AddScriptLPS(1);
3041 3313
3042// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3043// return;
3044
3045 TaskInventoryItem item = GetSelfInventoryItem(); 3314 TaskInventoryItem item = GetSelfInventoryItem();
3046 3315
3316 m_host.TaskInventory.LockItemsForRead(false);
3317
3047 if (item.PermsGranter != m_host.OwnerID) 3318 if (item.PermsGranter != m_host.OwnerID)
3048 return; 3319 return;
3049 3320
@@ -3088,6 +3359,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3088 3359
3089 public void llInstantMessage(string user, string message) 3360 public void llInstantMessage(string user, string message)
3090 { 3361 {
3362 UUID result;
3363 if (!UUID.TryParse(user, out result))
3364 {
3365 ShoutError("An invalid key was passed to llInstantMessage");
3366 ScriptSleep(2000);
3367 return;
3368 }
3369
3370
3091 m_host.AddScriptLPS(1); 3371 m_host.AddScriptLPS(1);
3092 3372
3093 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3373 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3102,14 +3382,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3102 UUID friendTransactionID = UUID.Random(); 3382 UUID friendTransactionID = UUID.Random();
3103 3383
3104 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3384 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3105 3385
3106 GridInstantMessage msg = new GridInstantMessage(); 3386 GridInstantMessage msg = new GridInstantMessage();
3107 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3387 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3108 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3388 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3109 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3389 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3110// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3390// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3111// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3391// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3112 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3392// DateTime dt = DateTime.UtcNow;
3393//
3394// // Ticks from UtcNow, but make it look like local. Evil, huh?
3395// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3396//
3397// try
3398// {
3399// // Convert that to the PST timezone
3400// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3401// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3402// }
3403// catch
3404// {
3405// // No logging here, as it could be VERY spammy
3406// }
3407//
3408// // And make it look local again to fool the unix time util
3409// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3410
3411 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3412
3113 //if (client != null) 3413 //if (client != null)
3114 //{ 3414 //{
3115 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3415 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3123,12 +3423,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3123 msg.message = message.Substring(0, 1024); 3423 msg.message = message.Substring(0, 1024);
3124 else 3424 else
3125 msg.message = message; 3425 msg.message = message;
3126 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3426 msg.dialog = (byte)19; // MessageFromObject
3127 msg.fromGroup = false;// fromGroup; 3427 msg.fromGroup = false;// fromGroup;
3128 msg.offline = (byte)0; //offline; 3428 msg.offline = (byte)0; //offline;
3129 msg.ParentEstateID = 0; //ParentEstateID; 3429 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3130 msg.Position = new Vector3(m_host.AbsolutePosition); 3430 msg.Position = new Vector3(m_host.AbsolutePosition);
3131 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3431 msg.RegionID = World.RegionInfo.RegionID.Guid;
3132 msg.binaryBucket 3432 msg.binaryBucket
3133 = Util.StringToBytes256( 3433 = Util.StringToBytes256(
3134 "{0}/{1}/{2}/{3}", 3434 "{0}/{1}/{2}/{3}",
@@ -3156,7 +3456,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3156 } 3456 }
3157 3457
3158 emailModule.SendEmail(m_host.UUID, address, subject, message); 3458 emailModule.SendEmail(m_host.UUID, address, subject, message);
3159 ScriptSleep(20000); 3459 ScriptSleep(15000);
3160 } 3460 }
3161 3461
3162 public void llGetNextEmail(string address, string subject) 3462 public void llGetNextEmail(string address, string subject)
@@ -3411,15 +3711,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3411 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3711 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3412 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3712 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3413 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3713 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3714 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3414 ScriptBaseClass.PERMISSION_ATTACH; 3715 ScriptBaseClass.PERMISSION_ATTACH;
3415 3716
3416 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3717 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3417 { 3718 {
3418 lock (m_host.TaskInventory) 3719 m_host.TaskInventory.LockItemsForWrite(true);
3419 { 3720 m_host.TaskInventory[m_itemID].PermsGranter = agentID;
3420 m_host.TaskInventory[m_itemID].PermsGranter = agentID; 3721 m_host.TaskInventory[m_itemID].PermsMask = perm;
3421 m_host.TaskInventory[m_itemID].PermsMask = perm; 3722 m_host.TaskInventory.LockItemsForWrite(false);
3422 }
3423 3723
3424 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3724 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3425 "run_time_permissions", new Object[] { 3725 "run_time_permissions", new Object[] {
@@ -3429,28 +3729,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3429 return; 3729 return;
3430 } 3730 }
3431 } 3731 }
3432 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3732 else
3433 { 3733 {
3434 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3734 bool sitting = false;
3435 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3735 if (m_host.SitTargetAvatar == agentID)
3436 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3736 {
3437 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3737 sitting = true;
3438 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3738 }
3739 else
3740 {
3741 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3742 {
3743 if (p.SitTargetAvatar == agentID)
3744 sitting = true;
3745 }
3746 }
3439 3747
3440 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3748 if (sitting)
3441 { 3749 {
3442 lock (m_host.TaskInventory) 3750 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3751 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3752 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3753 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3754 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3755
3756 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3443 { 3757 {
3758 m_host.TaskInventory.LockItemsForWrite(true);
3444 m_host.TaskInventory[m_itemID].PermsGranter = agentID; 3759 m_host.TaskInventory[m_itemID].PermsGranter = agentID;
3445 m_host.TaskInventory[m_itemID].PermsMask = perm; 3760 m_host.TaskInventory[m_itemID].PermsMask = perm;
3446 } 3761 m_host.TaskInventory.LockItemsForWrite(false);
3447 3762
3448 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3763 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3449 "run_time_permissions", new Object[] { 3764 "run_time_permissions", new Object[] {
3450 new LSL_Integer(perm) }, 3765 new LSL_Integer(perm) },
3451 new DetectParams[0])); 3766 new DetectParams[0]));
3452 3767
3453 return; 3768 return;
3769 }
3454 } 3770 }
3455 } 3771 }
3456 3772
@@ -3464,11 +3780,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3464 3780
3465 if (!m_waitingForScriptAnswer) 3781 if (!m_waitingForScriptAnswer)
3466 { 3782 {
3467 lock (m_host.TaskInventory) 3783 m_host.TaskInventory.LockItemsForWrite(true);
3468 { 3784 m_host.TaskInventory[m_itemID].PermsGranter = agentID;
3469 m_host.TaskInventory[m_itemID].PermsGranter = agentID; 3785 m_host.TaskInventory[m_itemID].PermsMask = 0;
3470 m_host.TaskInventory[m_itemID].PermsMask = 0; 3786 m_host.TaskInventory.LockItemsForWrite(false);
3471 }
3472 3787
3473 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3788 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3474 m_waitingForScriptAnswer=true; 3789 m_waitingForScriptAnswer=true;
@@ -3498,11 +3813,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3498 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3813 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3499 llReleaseControls(); 3814 llReleaseControls();
3500 3815
3501 lock (m_host.TaskInventory) 3816 m_host.TaskInventory.LockItemsForWrite(true);
3502 { 3817 m_host.TaskInventory[m_itemID].PermsMask = answer;
3503 m_host.TaskInventory[m_itemID].PermsMask = answer; 3818 m_host.TaskInventory.LockItemsForWrite(false);
3504 } 3819
3505
3506 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3820 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3507 "run_time_permissions", new Object[] { 3821 "run_time_permissions", new Object[] {
3508 new LSL_Integer(answer) }, 3822 new LSL_Integer(answer) },
@@ -3545,14 +3859,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3545 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3859 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3546 { 3860 {
3547 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3861 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3548 3862 if (parts.Count > 0)
3549 foreach (SceneObjectPart part in parts) 3863 {
3550 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3864 try
3865 {
3866 parts[0].ParentGroup.areUpdatesSuspended = true;
3867 foreach (SceneObjectPart part in parts)
3868 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3869 }
3870 finally
3871 {
3872 parts[0].ParentGroup.areUpdatesSuspended = false;
3873 }
3874 }
3551 } 3875 }
3552 3876
3553 public void llCreateLink(string target, int parent) 3877 public void llCreateLink(string target, int parent)
3554 { 3878 {
3555 m_host.AddScriptLPS(1); 3879 m_host.AddScriptLPS(1);
3880
3556 UUID targetID; 3881 UUID targetID;
3557 3882
3558 if (!UUID.TryParse(target, out targetID)) 3883 if (!UUID.TryParse(target, out targetID))
@@ -3660,10 +3985,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3660 // Restructuring Multiple Prims. 3985 // Restructuring Multiple Prims.
3661 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3986 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3662 parts.Remove(parentPrim.RootPart); 3987 parts.Remove(parentPrim.RootPart);
3663 foreach (SceneObjectPart part in parts) 3988 if (parts.Count > 0)
3664 { 3989 {
3665 parentPrim.DelinkFromGroup(part.LocalId, true); 3990 try
3991 {
3992 parts[0].ParentGroup.areUpdatesSuspended = true;
3993 foreach (SceneObjectPart part in parts)
3994 {
3995 parentPrim.DelinkFromGroup(part.LocalId, true);
3996 }
3997 }
3998 finally
3999 {
4000 parts[0].ParentGroup.areUpdatesSuspended = false;
4001 }
3666 } 4002 }
4003
3667 parentPrim.HasGroupChanged = true; 4004 parentPrim.HasGroupChanged = true;
3668 parentPrim.ScheduleGroupForFullUpdate(); 4005 parentPrim.ScheduleGroupForFullUpdate();
3669 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4006 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3672,12 +4009,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3672 { 4009 {
3673 SceneObjectPart newRoot = parts[0]; 4010 SceneObjectPart newRoot = parts[0];
3674 parts.Remove(newRoot); 4011 parts.Remove(newRoot);
3675 foreach (SceneObjectPart part in parts) 4012
4013 try
3676 { 4014 {
3677 // Required for linking 4015 parts[0].ParentGroup.areUpdatesSuspended = true;
3678 part.ClearUpdateSchedule(); 4016 foreach (SceneObjectPart part in parts)
3679 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4017 {
4018 part.ClearUpdateSchedule();
4019 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4020 }
3680 } 4021 }
4022 finally
4023 {
4024 parts[0].ParentGroup.areUpdatesSuspended = false;
4025 }
4026
4027
3681 newRoot.ParentGroup.HasGroupChanged = true; 4028 newRoot.ParentGroup.HasGroupChanged = true;
3682 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4029 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3683 } 4030 }
@@ -3697,6 +4044,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3697 public void llBreakAllLinks() 4044 public void llBreakAllLinks()
3698 { 4045 {
3699 m_host.AddScriptLPS(1); 4046 m_host.AddScriptLPS(1);
4047
4048 TaskInventoryItem item = GetSelfInventoryItem();
4049
4050 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4051 && !m_automaticLinkPermission)
4052 {
4053 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4054 return;
4055 }
4056
3700 SceneObjectGroup parentPrim = m_host.ParentGroup; 4057 SceneObjectGroup parentPrim = m_host.ParentGroup;
3701 if (parentPrim.AttachmentPoint != 0) 4058 if (parentPrim.AttachmentPoint != 0)
3702 return; // Fail silently if attached 4059 return; // Fail silently if attached
@@ -3716,25 +4073,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3716 public LSL_String llGetLinkKey(int linknum) 4073 public LSL_String llGetLinkKey(int linknum)
3717 { 4074 {
3718 m_host.AddScriptLPS(1); 4075 m_host.AddScriptLPS(1);
3719 List<UUID> keytable = new List<UUID>();
3720 // parse for sitting avatare-uuids
3721 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3722 {
3723 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3724 keytable.Add(presence.UUID);
3725 });
3726
3727 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3728 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3729 {
3730 return keytable[totalprims - linknum].ToString();
3731 }
3732
3733 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3734 {
3735 return m_host.UUID.ToString();
3736 }
3737
3738 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4076 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3739 if (part != null) 4077 if (part != null)
3740 { 4078 {
@@ -3742,6 +4080,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3742 } 4080 }
3743 else 4081 else
3744 { 4082 {
4083 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4084 {
4085 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4086
4087 if (linknum < 0)
4088 return UUID.Zero.ToString();
4089
4090 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4091 if (avatars.Count > linknum)
4092 {
4093 return avatars[linknum].UUID.ToString();
4094 }
4095 }
3745 return UUID.Zero.ToString(); 4096 return UUID.Zero.ToString();
3746 } 4097 }
3747 } 4098 }
@@ -3841,17 +4192,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3841 m_host.AddScriptLPS(1); 4192 m_host.AddScriptLPS(1);
3842 int count = 0; 4193 int count = 0;
3843 4194
3844 lock (m_host.TaskInventory) 4195 m_host.TaskInventory.LockItemsForRead(true);
4196 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3845 { 4197 {
3846 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4198 if (inv.Value.Type == type || type == -1)
3847 { 4199 {
3848 if (inv.Value.Type == type || type == -1) 4200 count = count + 1;
3849 {
3850 count = count + 1;
3851 }
3852 } 4201 }
3853 } 4202 }
3854 4203
4204 m_host.TaskInventory.LockItemsForRead(false);
3855 return count; 4205 return count;
3856 } 4206 }
3857 4207
@@ -3860,16 +4210,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3860 m_host.AddScriptLPS(1); 4210 m_host.AddScriptLPS(1);
3861 ArrayList keys = new ArrayList(); 4211 ArrayList keys = new ArrayList();
3862 4212
3863 lock (m_host.TaskInventory) 4213 m_host.TaskInventory.LockItemsForRead(true);
4214 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3864 { 4215 {
3865 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4216 if (inv.Value.Type == type || type == -1)
3866 { 4217 {
3867 if (inv.Value.Type == type || type == -1) 4218 keys.Add(inv.Value.Name);
3868 {
3869 keys.Add(inv.Value.Name);
3870 }
3871 } 4219 }
3872 } 4220 }
4221 m_host.TaskInventory.LockItemsForRead(false);
3873 4222
3874 if (keys.Count == 0) 4223 if (keys.Count == 0)
3875 { 4224 {
@@ -3906,25 +4255,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3906 } 4255 }
3907 4256
3908 // move the first object found with this inventory name 4257 // move the first object found with this inventory name
3909 lock (m_host.TaskInventory) 4258 m_host.TaskInventory.LockItemsForRead(true);
4259 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3910 { 4260 {
3911 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4261 if (inv.Value.Name == inventory)
3912 { 4262 {
3913 if (inv.Value.Name == inventory) 4263 found = true;
3914 { 4264 objId = inv.Key;
3915 found = true; 4265 assetType = inv.Value.Type;
3916 objId = inv.Key; 4266 objName = inv.Value.Name;
3917 assetType = inv.Value.Type; 4267 break;
3918 objName = inv.Value.Name;
3919 break;
3920 }
3921 } 4268 }
3922 } 4269 }
4270 m_host.TaskInventory.LockItemsForRead(false);
3923 4271
3924 if (!found) 4272 if (!found)
3925 { 4273 {
3926 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4274 llSay(0, String.Format("Could not find object '{0}'", inventory));
3927 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4275 return;
4276// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3928 } 4277 }
3929 4278
3930 // check if destination is an object 4279 // check if destination is an object
@@ -3950,48 +4299,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3950 return; 4299 return;
3951 } 4300 }
3952 } 4301 }
4302
3953 // destination is an avatar 4303 // destination is an avatar
3954 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4304 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3955 4305
3956 if (agentItem == null) 4306 if (agentItem == null)
3957 return; 4307 return;
3958 4308
3959 byte[] bucket = new byte[17]; 4309 byte[] bucket = new byte[1];
3960 bucket[0] = (byte)assetType; 4310 bucket[0] = (byte)assetType;
3961 byte[] objBytes = agentItem.ID.GetBytes(); 4311 //byte[] objBytes = agentItem.ID.GetBytes();
3962 Array.Copy(objBytes, 0, bucket, 1, 16); 4312 //Array.Copy(objBytes, 0, bucket, 1, 16);
3963 4313
3964 GridInstantMessage msg = new GridInstantMessage(World, 4314 GridInstantMessage msg = new GridInstantMessage(World,
3965 m_host.UUID, m_host.Name+", an object owned by "+ 4315 m_host.OwnerID, m_host.Name, destId,
3966 resolveName(m_host.OwnerID)+",", destId,
3967 (byte)InstantMessageDialog.TaskInventoryOffered, 4316 (byte)InstantMessageDialog.TaskInventoryOffered,
3968 false, objName+"\n"+m_host.Name+" is located at "+ 4317 false, objName+". "+m_host.Name+" is located at "+
3969 World.RegionInfo.RegionName+" "+ 4318 World.RegionInfo.RegionName+" "+
3970 m_host.AbsolutePosition.ToString(), 4319 m_host.AbsolutePosition.ToString(),
3971 agentItem.ID, true, m_host.AbsolutePosition, 4320 agentItem.ID, true, m_host.AbsolutePosition,
3972 bucket); 4321 bucket);
3973 if (m_TransferModule != null) 4322
3974 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4323 ScenePresence sp;
4324
4325 if (World.TryGetScenePresence(destId, out sp))
4326 {
4327 sp.ControllingClient.SendInstantMessage(msg);
4328 }
4329 else
4330 {
4331 if (m_TransferModule != null)
4332 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4333 }
4334
4335 //This delay should only occur when giving inventory to avatars.
3975 ScriptSleep(3000); 4336 ScriptSleep(3000);
3976 } 4337 }
3977 } 4338 }
3978 4339
4340 [DebuggerNonUserCode]
3979 public void llRemoveInventory(string name) 4341 public void llRemoveInventory(string name)
3980 { 4342 {
3981 m_host.AddScriptLPS(1); 4343 m_host.AddScriptLPS(1);
3982 4344
3983 lock (m_host.TaskInventory) 4345 List<TaskInventoryItem> inv;
4346 try
3984 { 4347 {
3985 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4348 m_host.TaskInventory.LockItemsForRead(true);
4349 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4350 }
4351 finally
4352 {
4353 m_host.TaskInventory.LockItemsForRead(false);
4354 }
4355 foreach (TaskInventoryItem item in inv)
4356 {
4357 if (item.Name == name)
3986 { 4358 {
3987 if (item.Name == name) 4359 if (item.ItemID == m_itemID)
3988 { 4360 throw new ScriptDeleteException();
3989 if (item.ItemID == m_itemID) 4361 else
3990 throw new ScriptDeleteException(); 4362 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3991 else 4363 return;
3992 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3993 return;
3994 }
3995 } 4364 }
3996 } 4365 }
3997 } 4366 }
@@ -4026,115 +4395,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4026 { 4395 {
4027 m_host.AddScriptLPS(1); 4396 m_host.AddScriptLPS(1);
4028 4397
4029 UUID uuid = (UUID)id; 4398 UUID uuid;
4030 PresenceInfo pinfo = null; 4399 if (UUID.TryParse(id, out uuid))
4031 UserAccount account;
4032
4033 UserInfoCacheEntry ce;
4034 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4035 { 4400 {
4036 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4401 PresenceInfo pinfo = null;
4037 if (account == null) 4402 UserAccount account;
4403
4404 UserInfoCacheEntry ce;
4405 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4038 { 4406 {
4039 m_userInfoCache[uuid] = null; // Cache negative 4407 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4040 return UUID.Zero.ToString(); 4408 if (account == null)
4041 } 4409 {
4410 m_userInfoCache[uuid] = null; // Cache negative
4411 return UUID.Zero.ToString();
4412 }
4042 4413
4043 4414
4044 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4415 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4045 if (pinfos != null && pinfos.Length > 0) 4416 if (pinfos != null && pinfos.Length > 0)
4046 {
4047 foreach (PresenceInfo p in pinfos)
4048 { 4417 {
4049 if (p.RegionID != UUID.Zero) 4418 foreach (PresenceInfo p in pinfos)
4050 { 4419 {
4051 pinfo = p; 4420 if (p.RegionID != UUID.Zero)
4421 {
4422 pinfo = p;
4423 }
4052 } 4424 }
4053 } 4425 }
4054 }
4055 4426
4056 ce = new UserInfoCacheEntry(); 4427 ce = new UserInfoCacheEntry();
4057 ce.time = Util.EnvironmentTickCount(); 4428 ce.time = Util.EnvironmentTickCount();
4058 ce.account = account; 4429 ce.account = account;
4059 ce.pinfo = pinfo; 4430 ce.pinfo = pinfo;
4060 } 4431 m_userInfoCache[uuid] = ce;
4061 else 4432 }
4062 { 4433 else
4063 if (ce == null) 4434 {
4064 return UUID.Zero.ToString(); 4435 if (ce == null)
4436 return UUID.Zero.ToString();
4065 4437
4066 account = ce.account; 4438 account = ce.account;
4067 pinfo = ce.pinfo; 4439 pinfo = ce.pinfo;
4068 } 4440 }
4069 4441
4070 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4442 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4071 {
4072 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4073 if (pinfos != null && pinfos.Length > 0)
4074 { 4443 {
4075 foreach (PresenceInfo p in pinfos) 4444 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4445 if (pinfos != null && pinfos.Length > 0)
4076 { 4446 {
4077 if (p.RegionID != UUID.Zero) 4447 foreach (PresenceInfo p in pinfos)
4078 { 4448 {
4079 pinfo = p; 4449 if (p.RegionID != UUID.Zero)
4450 {
4451 pinfo = p;
4452 }
4080 } 4453 }
4081 } 4454 }
4082 } 4455 else
4083 else 4456 pinfo = null;
4084 pinfo = null;
4085 4457
4086 ce.time = Util.EnvironmentTickCount(); 4458 ce.time = Util.EnvironmentTickCount();
4087 ce.pinfo = pinfo; 4459 ce.pinfo = pinfo;
4088 } 4460 }
4089 4461
4090 string reply = String.Empty; 4462 string reply = String.Empty;
4091 4463
4092 switch (data) 4464 switch (data)
4093 { 4465 {
4094 case 1: // DATA_ONLINE (0|1) 4466 case 1: // DATA_ONLINE (0|1)
4095 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4467 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4096 reply = "1"; 4468 reply = "1";
4097 else 4469 else
4098 reply = "0"; 4470 reply = "0";
4099 break; 4471 break;
4100 case 2: // DATA_NAME (First Last) 4472 case 2: // DATA_NAME (First Last)
4101 reply = account.FirstName + " " + account.LastName; 4473 reply = account.FirstName + " " + account.LastName;
4102 break; 4474 break;
4103 case 3: // DATA_BORN (YYYY-MM-DD) 4475 case 3: // DATA_BORN (YYYY-MM-DD)
4104 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4476 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4105 born = born.AddSeconds(account.Created); 4477 born = born.AddSeconds(account.Created);
4106 reply = born.ToString("yyyy-MM-dd"); 4478 reply = born.ToString("yyyy-MM-dd");
4107 break; 4479 break;
4108 case 4: // DATA_RATING (0,0,0,0,0,0) 4480 case 4: // DATA_RATING (0,0,0,0,0,0)
4109 reply = "0,0,0,0,0,0"; 4481 reply = "0,0,0,0,0,0";
4110 break; 4482 break;
4111 case 7: // DATA_USERLEVEL (integer) 4483 case 8: // DATA_PAYINFO (0|1|2|3)
4112 reply = account.UserLevel.ToString(); 4484 reply = "0";
4113 break; 4485 break;
4114 case 8: // DATA_PAYINFO (0|1|2|3) 4486 default:
4115 reply = "0"; 4487 return UUID.Zero.ToString(); // Raise no event
4116 break; 4488 }
4117 default:
4118 return UUID.Zero.ToString(); // Raise no event
4119 }
4120 4489
4121 UUID rq = UUID.Random(); 4490 UUID rq = UUID.Random();
4122 4491
4123 UUID tid = AsyncCommands. 4492 UUID tid = AsyncCommands.
4124 DataserverPlugin.RegisterRequest(m_localID, 4493 DataserverPlugin.RegisterRequest(m_localID,
4125 m_itemID, rq.ToString()); 4494 m_itemID, rq.ToString());
4126 4495
4127 AsyncCommands. 4496 AsyncCommands.
4128 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4497 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4129 4498
4130 ScriptSleep(100); 4499 ScriptSleep(100);
4131 return tid.ToString(); 4500 return tid.ToString();
4501 }
4502 else
4503 {
4504 ShoutError("Invalid UUID passed to llRequestAgentData.");
4505 }
4506 return "";
4132 } 4507 }
4133 4508
4134 public LSL_String llRequestInventoryData(string name) 4509 public LSL_String llRequestInventoryData(string name)
4135 { 4510 {
4136 m_host.AddScriptLPS(1); 4511 m_host.AddScriptLPS(1);
4137 4512
4513 //Clone is thread safe
4138 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4514 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4139 4515
4140 foreach (TaskInventoryItem item in itemDictionary.Values) 4516 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4186,19 +4562,64 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4186 if (UUID.TryParse(agent, out agentId)) 4562 if (UUID.TryParse(agent, out agentId))
4187 { 4563 {
4188 ScenePresence presence = World.GetScenePresence(agentId); 4564 ScenePresence presence = World.GetScenePresence(agentId);
4189 if (presence != null) 4565 if (presence != null && presence.PresenceType != PresenceType.Npc)
4190 { 4566 {
4567 // agent must not be a god
4568 if (presence.UserLevel >= 200) return;
4569
4191 // agent must be over the owners land 4570 // agent must be over the owners land
4192 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4571 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4193 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4572 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4194 { 4573 {
4195 World.TeleportClientHome(agentId, presence.ControllingClient); 4574 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4575 {
4576 // They can't be teleported home for some reason
4577 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4578 if (regionInfo != null)
4579 {
4580 World.RequestTeleportLocation(
4581 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4582 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4583 }
4584 }
4196 } 4585 }
4197 } 4586 }
4198 } 4587 }
4199 ScriptSleep(5000); 4588 ScriptSleep(5000);
4200 } 4589 }
4201 4590
4591 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
4592 {
4593 m_host.AddScriptLPS(1);
4594 UUID agentId = new UUID();
4595 if (UUID.TryParse(agent, out agentId))
4596 {
4597 ScenePresence presence = World.GetScenePresence(agentId);
4598 if (presence != null && presence.PresenceType != PresenceType.Npc)
4599 {
4600 // agent must not be a god
4601 if (presence.GodLevel >= 200) return;
4602
4603 if (simname == String.Empty)
4604 simname = World.RegionInfo.RegionName;
4605
4606 // agent must be over the owners land
4607 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4608 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4609 {
4610 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);
4611 }
4612 else // or must be wearing the prim
4613 {
4614 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4615 {
4616 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);
4617 }
4618 }
4619 }
4620 }
4621 }
4622
4202 public void llTextBox(string agent, string message, int chatChannel) 4623 public void llTextBox(string agent, string message, int chatChannel)
4203 { 4624 {
4204 IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); 4625 IDialogModule dm = World.RequestModuleInterface<IDialogModule>();
@@ -4210,7 +4631,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4210 UUID av = new UUID(); 4631 UUID av = new UUID();
4211 if (!UUID.TryParse(agent,out av)) 4632 if (!UUID.TryParse(agent,out av))
4212 { 4633 {
4213 LSLError("First parameter to llDialog needs to be a key"); 4634 //LSLError("First parameter to llDialog needs to be a key");
4214 return; 4635 return;
4215 } 4636 }
4216 4637
@@ -4247,17 +4668,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4247 UUID soundId = UUID.Zero; 4668 UUID soundId = UUID.Zero;
4248 if (!UUID.TryParse(impact_sound, out soundId)) 4669 if (!UUID.TryParse(impact_sound, out soundId))
4249 { 4670 {
4250 lock (m_host.TaskInventory) 4671 m_host.TaskInventory.LockItemsForRead(true);
4672 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4251 { 4673 {
4252 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4674 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4253 { 4675 {
4254 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4676 soundId = item.AssetID;
4255 { 4677 break;
4256 soundId = item.AssetID;
4257 break;
4258 }
4259 } 4678 }
4260 } 4679 }
4680 m_host.TaskInventory.LockItemsForRead(false);
4261 } 4681 }
4262 m_host.CollisionSound = soundId; 4682 m_host.CollisionSound = soundId;
4263 m_host.CollisionSoundVolume = (float)impact_volume; 4683 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4297,6 +4717,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4297 UUID partItemID; 4717 UUID partItemID;
4298 foreach (SceneObjectPart part in parts) 4718 foreach (SceneObjectPart part in parts)
4299 { 4719 {
4720 //Clone is thread safe
4300 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4721 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4301 4722
4302 foreach (TaskInventoryItem item in itemsDictionary.Values) 4723 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4430,7 +4851,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4430 { 4851 {
4431 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4852 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4432 float distance_term = distance * distance * distance; // Script Energy 4853 float distance_term = distance * distance * distance; // Script Energy
4433 float pusher_mass = m_host.GetMass(); 4854 // use total object mass and not part
4855 float pusher_mass = m_host.ParentGroup.GetMass();
4434 4856
4435 float PUSH_ATTENUATION_DISTANCE = 17f; 4857 float PUSH_ATTENUATION_DISTANCE = 17f;
4436 float PUSH_ATTENUATION_SCALE = 5f; 4858 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4671,23 +5093,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4671 { 5093 {
4672 m_host.AddScriptLPS(1); 5094 m_host.AddScriptLPS(1);
4673 5095
4674 lock (m_host.TaskInventory) 5096 m_host.TaskInventory.LockItemsForRead(true);
5097 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4675 { 5098 {
4676 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5099 if (inv.Value.Name == name)
4677 { 5100 {
4678 if (inv.Value.Name == name) 5101 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4679 { 5102 {
4680 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5103 m_host.TaskInventory.LockItemsForRead(false);
4681 { 5104 return inv.Value.AssetID.ToString();
4682 return inv.Value.AssetID.ToString(); 5105 }
4683 } 5106 else
4684 else 5107 {
4685 { 5108 m_host.TaskInventory.LockItemsForRead(false);
4686 return UUID.Zero.ToString(); 5109 return UUID.Zero.ToString();
4687 }
4688 } 5110 }
4689 } 5111 }
4690 } 5112 }
5113 m_host.TaskInventory.LockItemsForRead(false);
4691 5114
4692 return UUID.Zero.ToString(); 5115 return UUID.Zero.ToString();
4693 } 5116 }
@@ -4821,7 +5244,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4821 public LSL_Vector llGetCenterOfMass() 5244 public LSL_Vector llGetCenterOfMass()
4822 { 5245 {
4823 m_host.AddScriptLPS(1); 5246 m_host.AddScriptLPS(1);
4824 Vector3 center = m_host.GetGeometricCenter(); 5247 Vector3 center = m_host.GetCenterOfMass();
4825 return new LSL_Vector(center.X,center.Y,center.Z); 5248 return new LSL_Vector(center.X,center.Y,center.Z);
4826 } 5249 }
4827 5250
@@ -4840,14 +5263,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4840 { 5263 {
4841 m_host.AddScriptLPS(1); 5264 m_host.AddScriptLPS(1);
4842 5265
4843 if (src == null) 5266 return src.Length;
4844 {
4845 return 0;
4846 }
4847 else
4848 {
4849 return src.Length;
4850 }
4851 } 5267 }
4852 5268
4853 public LSL_Integer llList2Integer(LSL_List src, int index) 5269 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4893,7 +5309,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4893 else if (src.Data[index] is LSL_Float) 5309 else if (src.Data[index] is LSL_Float)
4894 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5310 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4895 else if (src.Data[index] is LSL_String) 5311 else if (src.Data[index] is LSL_String)
4896 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5312 {
5313 string str = ((LSL_String) src.Data[index]).m_string;
5314 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5315 if (m != Match.Empty)
5316 {
5317 str = m.Value;
5318 double d = 0.0;
5319 if (!Double.TryParse(str, out d))
5320 return 0.0;
5321
5322 return d;
5323 }
5324 return 0.0;
5325 }
4897 return Convert.ToDouble(src.Data[index]); 5326 return Convert.ToDouble(src.Data[index]);
4898 } 5327 }
4899 catch (FormatException) 5328 catch (FormatException)
@@ -5166,7 +5595,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5166 } 5595 }
5167 } 5596 }
5168 } 5597 }
5169 else { 5598 else
5599 {
5170 object[] array = new object[src.Length]; 5600 object[] array = new object[src.Length];
5171 Array.Copy(src.Data, 0, array, 0, src.Length); 5601 Array.Copy(src.Data, 0, array, 0, src.Length);
5172 result = new LSL_List(array); 5602 result = new LSL_List(array);
@@ -5273,7 +5703,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5273 public LSL_Integer llGetRegionAgentCount() 5703 public LSL_Integer llGetRegionAgentCount()
5274 { 5704 {
5275 m_host.AddScriptLPS(1); 5705 m_host.AddScriptLPS(1);
5276 return new LSL_Integer(World.GetRootAgentCount()); 5706
5707 int count = 0;
5708 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5709 count++;
5710 });
5711
5712 return new LSL_Integer(count);
5277 } 5713 }
5278 5714
5279 public LSL_Vector llGetRegionCorner() 5715 public LSL_Vector llGetRegionCorner()
@@ -5553,6 +5989,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5553 flags |= ScriptBaseClass.AGENT_SITTING; 5989 flags |= ScriptBaseClass.AGENT_SITTING;
5554 } 5990 }
5555 5991
5992 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
5993 {
5994 flags |= ScriptBaseClass.AGENT_MALE;
5995 }
5996
5556 return flags; 5997 return flags;
5557 } 5998 }
5558 5999
@@ -5615,10 +6056,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5615 m_host.AddScriptLPS(1); 6056 m_host.AddScriptLPS(1);
5616 6057
5617 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6058 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5618 6059 if (parts.Count > 0)
5619 foreach (var part in parts)
5620 { 6060 {
5621 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6061 try
6062 {
6063 parts[0].ParentGroup.areUpdatesSuspended = true;
6064 foreach (var part in parts)
6065 {
6066 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6067 }
6068 }
6069 finally
6070 {
6071 parts[0].ParentGroup.areUpdatesSuspended = false;
6072 }
5622 } 6073 }
5623 } 6074 }
5624 6075
@@ -5670,13 +6121,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5670 6121
5671 if (m_host.OwnerID == land.LandData.OwnerID) 6122 if (m_host.OwnerID == land.LandData.OwnerID)
5672 { 6123 {
5673 World.TeleportClientHome(agentID, presence.ControllingClient); 6124 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6125 presence.TeleportWithMomentum(pos, null);
6126 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5674 } 6127 }
5675 } 6128 }
5676 } 6129 }
5677 ScriptSleep(5000); 6130 ScriptSleep(5000);
5678 } 6131 }
5679 6132
6133 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6134 {
6135 return ParseString2List(str, separators, in_spacers, false);
6136 }
6137
5680 public LSL_Integer llOverMyLand(string id) 6138 public LSL_Integer llOverMyLand(string id)
5681 { 6139 {
5682 m_host.AddScriptLPS(1); 6140 m_host.AddScriptLPS(1);
@@ -5741,8 +6199,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5741 UUID agentId = new UUID(); 6199 UUID agentId = new UUID();
5742 if (!UUID.TryParse(agent, out agentId)) 6200 if (!UUID.TryParse(agent, out agentId))
5743 return new LSL_Integer(0); 6201 return new LSL_Integer(0);
6202 if (agentId == m_host.GroupID)
6203 return new LSL_Integer(1);
5744 ScenePresence presence = World.GetScenePresence(agentId); 6204 ScenePresence presence = World.GetScenePresence(agentId);
5745 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6205 if (presence == null || presence.IsChildAgent) // Return false for child agents
5746 return new LSL_Integer(0); 6206 return new LSL_Integer(0);
5747 IClientAPI client = presence.ControllingClient; 6207 IClientAPI client = presence.ControllingClient;
5748 if (m_host.GroupID == client.ActiveGroupId) 6208 if (m_host.GroupID == client.ActiveGroupId)
@@ -5877,7 +6337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5877 return m_host.ParentGroup.AttachmentPoint; 6337 return m_host.ParentGroup.AttachmentPoint;
5878 } 6338 }
5879 6339
5880 public LSL_Integer llGetFreeMemory() 6340 public virtual LSL_Integer llGetFreeMemory()
5881 { 6341 {
5882 m_host.AddScriptLPS(1); 6342 m_host.AddScriptLPS(1);
5883 // Make scripts designed for LSO happy 6343 // Make scripts designed for LSO happy
@@ -5994,7 +6454,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5994 SetParticleSystem(m_host, rules); 6454 SetParticleSystem(m_host, rules);
5995 } 6455 }
5996 6456
5997 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6457 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6458 {
5998 6459
5999 6460
6000 if (rules.Length == 0) 6461 if (rules.Length == 0)
@@ -6188,14 +6649,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6188 6649
6189 protected UUID GetTaskInventoryItem(string name) 6650 protected UUID GetTaskInventoryItem(string name)
6190 { 6651 {
6191 lock (m_host.TaskInventory) 6652 m_host.TaskInventory.LockItemsForRead(true);
6653 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6192 { 6654 {
6193 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6655 if (inv.Value.Name == name)
6194 { 6656 {
6195 if (inv.Value.Name == name) 6657 m_host.TaskInventory.LockItemsForRead(false);
6196 return inv.Key; 6658 return inv.Key;
6197 } 6659 }
6198 } 6660 }
6661 m_host.TaskInventory.LockItemsForRead(false);
6199 6662
6200 return UUID.Zero; 6663 return UUID.Zero;
6201 } 6664 }
@@ -6233,16 +6696,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6233 if (folderID == UUID.Zero) 6696 if (folderID == UUID.Zero)
6234 return; 6697 return;
6235 6698
6236 byte[] bucket = new byte[17]; 6699 byte[] bucket = new byte[1];
6237 bucket[0] = (byte)AssetType.Folder; 6700 bucket[0] = (byte)AssetType.Folder;
6238 byte[] objBytes = folderID.GetBytes(); 6701 //byte[] objBytes = folderID.GetBytes();
6239 Array.Copy(objBytes, 0, bucket, 1, 16); 6702 //Array.Copy(objBytes, 0, bucket, 1, 16);
6240 6703
6241 GridInstantMessage msg = new GridInstantMessage(World, 6704 GridInstantMessage msg = new GridInstantMessage(World,
6242 m_host.UUID, m_host.Name+", an object owned by "+ 6705 m_host.OwnerID, m_host.Name, destID,
6243 resolveName(m_host.OwnerID)+",", destID, 6706 (byte)InstantMessageDialog.TaskInventoryOffered,
6244 (byte)InstantMessageDialog.InventoryOffered, 6707 false, category+". "+m_host.Name+" is located at "+
6245 false, category+"\n"+m_host.Name+" is located at "+
6246 World.RegionInfo.RegionName+" "+ 6708 World.RegionInfo.RegionName+" "+
6247 m_host.AbsolutePosition.ToString(), 6709 m_host.AbsolutePosition.ToString(),
6248 folderID, true, m_host.AbsolutePosition, 6710 folderID, true, m_host.AbsolutePosition,
@@ -6480,13 +6942,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6480 UUID av = new UUID(); 6942 UUID av = new UUID();
6481 if (!UUID.TryParse(avatar,out av)) 6943 if (!UUID.TryParse(avatar,out av))
6482 { 6944 {
6483 LSLError("First parameter to llDialog needs to be a key"); 6945 //LSLError("First parameter to llDialog needs to be a key");
6484 return; 6946 return;
6485 } 6947 }
6486 if (buttons.Length < 1) 6948 if (buttons.Length < 1)
6487 { 6949 {
6488 LSLError("No less than 1 button can be shown"); 6950 buttons.Add("OK");
6489 return;
6490 } 6951 }
6491 if (buttons.Length > 12) 6952 if (buttons.Length > 12)
6492 { 6953 {
@@ -6503,7 +6964,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6503 } 6964 }
6504 if (buttons.Data[i].ToString().Length > 24) 6965 if (buttons.Data[i].ToString().Length > 24)
6505 { 6966 {
6506 LSLError("button label cannot be longer than 24 characters"); 6967 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6507 return; 6968 return;
6508 } 6969 }
6509 buts[i] = buttons.Data[i].ToString(); 6970 buts[i] = buttons.Data[i].ToString();
@@ -6562,22 +7023,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6562 } 7023 }
6563 7024
6564 // copy the first script found with this inventory name 7025 // copy the first script found with this inventory name
6565 lock (m_host.TaskInventory) 7026 TaskInventoryItem scriptItem = null;
7027 m_host.TaskInventory.LockItemsForRead(true);
7028 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6566 { 7029 {
6567 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7030 if (inv.Value.Name == name)
6568 { 7031 {
6569 if (inv.Value.Name == name) 7032 // make sure the object is a script
7033 if (10 == inv.Value.Type)
6570 { 7034 {
6571 // make sure the object is a script 7035 found = true;
6572 if (10 == inv.Value.Type) 7036 srcId = inv.Key;
6573 { 7037 scriptItem = inv.Value;
6574 found = true; 7038 break;
6575 srcId = inv.Key;
6576 break;
6577 }
6578 } 7039 }
6579 } 7040 }
6580 } 7041 }
7042 m_host.TaskInventory.LockItemsForRead(false);
6581 7043
6582 if (!found) 7044 if (!found)
6583 { 7045 {
@@ -6585,9 +7047,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6585 return; 7047 return;
6586 } 7048 }
6587 7049
6588 // the rest of the permission checks are done in RezScript, so check the pin there as well 7050 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6589 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7051 if (dest != null)
7052 {
7053 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7054 {
7055 // the rest of the permission checks are done in RezScript, so check the pin there as well
7056 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6590 7057
7058 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7059 m_host.Inventory.RemoveInventoryItem(srcId);
7060 }
7061 }
6591 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7062 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6592 ScriptSleep(3000); 7063 ScriptSleep(3000);
6593 } 7064 }
@@ -6650,19 +7121,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6650 public LSL_String llMD5String(string src, int nonce) 7121 public LSL_String llMD5String(string src, int nonce)
6651 { 7122 {
6652 m_host.AddScriptLPS(1); 7123 m_host.AddScriptLPS(1);
6653 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7124 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6654 } 7125 }
6655 7126
6656 public LSL_String llSHA1String(string src) 7127 public LSL_String llSHA1String(string src)
6657 { 7128 {
6658 m_host.AddScriptLPS(1); 7129 m_host.AddScriptLPS(1);
6659 return Util.SHA1Hash(src).ToLower(); 7130 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6660 } 7131 }
6661 7132
6662 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7133 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6663 { 7134 {
6664 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7135 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6665 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7136 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7137 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7138 return shapeBlock;
6666 7139
6667 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7140 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6668 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7141 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6767,6 +7240,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6767 // Prim type box, cylinder and prism. 7240 // Prim type box, cylinder and prism.
6768 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) 7241 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)
6769 { 7242 {
7243 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7244 return;
7245
6770 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7246 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6771 ObjectShapePacket.ObjectDataBlock shapeBlock; 7247 ObjectShapePacket.ObjectDataBlock shapeBlock;
6772 7248
@@ -6820,6 +7296,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6820 // Prim type sphere. 7296 // Prim type sphere.
6821 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7297 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6822 { 7298 {
7299 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7300 return;
7301
6823 ObjectShapePacket.ObjectDataBlock shapeBlock; 7302 ObjectShapePacket.ObjectDataBlock shapeBlock;
6824 7303
6825 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7304 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6861,6 +7340,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6861 // Prim type torus, tube and ring. 7340 // Prim type torus, tube and ring.
6862 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) 7341 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)
6863 { 7342 {
7343 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7344 return;
7345
6864 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7346 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6865 ObjectShapePacket.ObjectDataBlock shapeBlock; 7347 ObjectShapePacket.ObjectDataBlock shapeBlock;
6866 7348
@@ -6996,6 +7478,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6996 // Prim type sculpt. 7478 // Prim type sculpt.
6997 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7479 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6998 { 7480 {
7481 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7482 return;
7483
6999 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7484 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7000 UUID sculptId; 7485 UUID sculptId;
7001 7486
@@ -7020,7 +7505,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7020 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7505 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7021 { 7506 {
7022 // default 7507 // default
7023 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7508 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7024 } 7509 }
7025 7510
7026 part.Shape.SetSculptProperties((byte)type, sculptId); 7511 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7036,32 +7521,149 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7036 ScriptSleep(200); 7521 ScriptSleep(200);
7037 } 7522 }
7038 7523
7039 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7524 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7040 { 7525 {
7041 m_host.AddScriptLPS(1); 7526 m_host.AddScriptLPS(1);
7042 7527
7043 setLinkPrimParams(linknumber, rules); 7528 setLinkPrimParams(linknumber, rules);
7529 }
7044 7530
7045 ScriptSleep(200); 7531 private void setLinkPrimParams(int linknumber, LSL_List rules)
7532 {
7533 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7534 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7535 if (parts.Count>0)
7536 {
7537 try
7538 {
7539 parts[0].ParentGroup.areUpdatesSuspended = true;
7540 foreach (SceneObjectPart part in parts)
7541 SetPrimParams(part, rules);
7542 }
7543 finally
7544 {
7545 parts[0].ParentGroup.areUpdatesSuspended = false;
7546 }
7547 }
7548 if (avatars.Count > 0)
7549 {
7550 foreach (ScenePresence avatar in avatars)
7551 SetPrimParams(avatar, rules);
7552 }
7046 } 7553 }
7047 7554
7048 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7555 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7556 float material_density, float material_friction,
7557 float material_restitution, float material_gravity_modifier)
7049 { 7558 {
7050 m_host.AddScriptLPS(1); 7559 ExtraPhysicsData physdata = new ExtraPhysicsData();
7560 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7561 physdata.Density = part.Density;
7562 physdata.Friction = part.Friction;
7563 physdata.Bounce = part.Bounciness;
7564 physdata.GravitationModifier = part.GravityModifier;
7051 7565
7052 setLinkPrimParams(linknumber, rules); 7566 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7567 physdata.Density = material_density;
7568 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7569 physdata.Friction = material_friction;
7570 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7571 physdata.Bounce = material_restitution;
7572 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7573 physdata.GravitationModifier = material_gravity_modifier;
7574
7575 part.UpdateExtraPhysics(physdata);
7053 } 7576 }
7054 7577
7055 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7578 public void llSetPhysicsMaterial(int material_bits,
7579 float material_gravity_modifier, float material_restitution,
7580 float material_friction, float material_density)
7056 { 7581 {
7057 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7582 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7583 }
7058 7584
7059 foreach (SceneObjectPart part in parts) 7585 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7060 SetPrimParams(part, rules); 7586 {
7587 llSetLinkPrimitiveParamsFast(linknumber, rules);
7588 ScriptSleep(200);
7589 }
7590
7591 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7592 {
7593 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7594 //We only support PRIM_POSITION and PRIM_ROTATION
7595
7596 int idx = 0;
7597
7598 while (idx < rules.Length)
7599 {
7600 int code = rules.GetLSLIntegerItem(idx++);
7601
7602 int remain = rules.Length - idx;
7603
7604 switch (code)
7605 {
7606 case (int)ScriptBaseClass.PRIM_POSITION:
7607 {
7608 if (remain < 1)
7609 return;
7610 LSL_Vector v;
7611 v = rules.GetVector3Item(idx++);
7612
7613 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
7614 if (part == null)
7615 break;
7616
7617 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7618 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7619 if (llGetLinkNumber() > 1)
7620 {
7621 localRot = llGetLocalRot();
7622 localPos = llGetLocalPos();
7623 }
7624
7625 v -= localPos;
7626 v /= localRot;
7627
7628 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
7629
7630 v = v + 2 * sitOffset;
7631
7632 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7633 av.SendAvatarDataToAllAgents();
7634
7635 }
7636 break;
7637
7638 case (int)ScriptBaseClass.PRIM_ROTATION:
7639 {
7640 if (remain < 1)
7641 return;
7642
7643 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
7644 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
7645 if (llGetLinkNumber() > 1)
7646 {
7647 localRot = llGetLocalRot();
7648 localPos = llGetLocalPos();
7649 }
7650
7651 LSL_Rotation r;
7652 r = rules.GetQuaternionItem(idx++);
7653 r = r * llGetRootRotation() / localRot;
7654 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7655 av.SendAvatarDataToAllAgents();
7656 }
7657 break;
7658 }
7659 }
7061 } 7660 }
7062 7661
7063 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7662 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7064 { 7663 {
7664 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7665 return;
7666
7065 int idx = 0; 7667 int idx = 0;
7066 7668
7067 bool positionChanged = false; 7669 bool positionChanged = false;
@@ -7383,6 +7985,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7383 part.ScriptSetPhysicsStatus(physics); 7985 part.ScriptSetPhysicsStatus(physics);
7384 break; 7986 break;
7385 7987
7988 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7989 if (remain < 1)
7990 return;
7991
7992 int shape_type = rules.GetLSLIntegerItem(idx++);
7993
7994 ExtraPhysicsData physdata = new ExtraPhysicsData();
7995 physdata.Density = part.Density;
7996 physdata.Bounce = part.Bounciness;
7997 physdata.GravitationModifier = part.GravityModifier;
7998 physdata.PhysShapeType = (PhysShapeType)shape_type;
7999
8000 part.UpdateExtraPhysics(physdata);
8001
8002 break;
8003
8004 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8005 if (remain < 5)
8006 return;
8007
8008 int material_bits = rules.GetLSLIntegerItem(idx++);
8009 float material_density = (float)rules.GetLSLFloatItem(idx++);
8010 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8011 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8012 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8013
8014 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8015
8016 break;
8017
7386 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8018 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7387 if (remain < 1) 8019 if (remain < 1)
7388 return; 8020 return;
@@ -7456,7 +8088,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7456 if (part.ParentGroup.RootPart == part) 8088 if (part.ParentGroup.RootPart == part)
7457 { 8089 {
7458 SceneObjectGroup parent = part.ParentGroup; 8090 SceneObjectGroup parent = part.ParentGroup;
7459 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8091 Util.FireAndForget(delegate(object x) {
8092 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8093 });
7460 } 8094 }
7461 else 8095 else
7462 { 8096 {
@@ -7467,6 +8101,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7467 } 8101 }
7468 } 8102 }
7469 } 8103 }
8104
8105 if (positionChanged)
8106 {
8107 if (part.ParentGroup.RootPart == part)
8108 {
8109 SceneObjectGroup parent = part.ParentGroup;
8110 Util.FireAndForget(delegate(object x) {
8111 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8112 });
8113 }
8114 else
8115 {
8116 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8117 SceneObjectGroup parent = part.ParentGroup;
8118 parent.HasGroupChanged = true;
8119 parent.ScheduleGroupForTerseUpdate();
8120 }
8121 }
7470 } 8122 }
7471 8123
7472 public LSL_String llStringToBase64(string str) 8124 public LSL_String llStringToBase64(string str)
@@ -7627,13 +8279,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7627 public LSL_Integer llGetNumberOfPrims() 8279 public LSL_Integer llGetNumberOfPrims()
7628 { 8280 {
7629 m_host.AddScriptLPS(1); 8281 m_host.AddScriptLPS(1);
7630 int avatarCount = 0; 8282 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7631 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8283
7632 {
7633 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7634 avatarCount++;
7635 });
7636
7637 return m_host.ParentGroup.PrimCount + avatarCount; 8284 return m_host.ParentGroup.PrimCount + avatarCount;
7638 } 8285 }
7639 8286
@@ -7649,55 +8296,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7649 m_host.AddScriptLPS(1); 8296 m_host.AddScriptLPS(1);
7650 UUID objID = UUID.Zero; 8297 UUID objID = UUID.Zero;
7651 LSL_List result = new LSL_List(); 8298 LSL_List result = new LSL_List();
8299
8300 // If the ID is not valid, return null result
7652 if (!UUID.TryParse(obj, out objID)) 8301 if (!UUID.TryParse(obj, out objID))
7653 { 8302 {
7654 result.Add(new LSL_Vector()); 8303 result.Add(new LSL_Vector());
7655 result.Add(new LSL_Vector()); 8304 result.Add(new LSL_Vector());
7656 return result; 8305 return result;
7657 } 8306 }
8307
8308 // Check if this is an attached prim. If so, replace
8309 // the UUID with the avatar UUID and report it's bounding box
8310 SceneObjectPart part = World.GetSceneObjectPart(objID);
8311 if (part != null && part.ParentGroup.IsAttachment)
8312 objID = part.ParentGroup.AttachedAvatar;
8313
8314 // Find out if this is an avatar ID. If so, return it's box
7658 ScenePresence presence = World.GetScenePresence(objID); 8315 ScenePresence presence = World.GetScenePresence(objID);
7659 if (presence != null) 8316 if (presence != null)
7660 { 8317 {
7661 if (presence.ParentID == 0) // not sat on an object 8318 // As per LSL Wiki, there is no difference between sitting
8319 // and standing avatar since server 1.36
8320 LSL_Vector lower;
8321 LSL_Vector upper;
8322 if (presence.Animator.Animations.DefaultAnimation.AnimID
8323 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7662 { 8324 {
7663 LSL_Vector lower; 8325 // This is for ground sitting avatars
7664 LSL_Vector upper; 8326 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7665 if (presence.Animator.Animations.DefaultAnimation.AnimID 8327 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7666 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8328 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7667 {
7668 // This is for ground sitting avatars
7669 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7670 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7671 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7672 }
7673 else
7674 {
7675 // This is for standing/flying avatars
7676 float height = presence.Appearance.AvatarHeight / 2.0f;
7677 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7678 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7679 }
7680 result.Add(lower);
7681 result.Add(upper);
7682 return result;
7683 } 8329 }
7684 else 8330 else
7685 { 8331 {
7686 // sitting on an object so we need the bounding box of that 8332 // This is for standing/flying avatars
7687 // which should include the avatar so set the UUID to the 8333 float height = presence.Appearance.AvatarHeight / 2.0f;
7688 // UUID of the object the avatar is sat on and allow it to fall through 8334 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7689 // to processing an object 8335 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7690 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7691 objID = p.UUID;
7692 } 8336 }
8337
8338 // Adjust to the documented error offsets (see LSL Wiki)
8339 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8340 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8341
8342 if (lower.x > upper.x)
8343 lower.x = upper.x;
8344 if (lower.y > upper.y)
8345 lower.y = upper.y;
8346 if (lower.z > upper.z)
8347 lower.z = upper.z;
8348
8349 result.Add(lower);
8350 result.Add(upper);
8351 return result;
7693 } 8352 }
7694 SceneObjectPart part = World.GetSceneObjectPart(objID); 8353
8354 part = World.GetSceneObjectPart(objID);
7695 // Currently only works for single prims without a sitting avatar 8355 // Currently only works for single prims without a sitting avatar
7696 if (part != null) 8356 if (part != null)
7697 { 8357 {
7698 Vector3 halfSize = part.Scale / 2.0f; 8358 float minX;
7699 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8359 float maxX;
7700 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8360 float minY;
8361 float maxY;
8362 float minZ;
8363 float maxZ;
8364
8365 // This BBox is in sim coordinates, with the offset being
8366 // a contained point.
8367 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8368 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8369
8370 minX -= offsets[0].X;
8371 maxX -= offsets[0].X;
8372 minY -= offsets[0].Y;
8373 maxY -= offsets[0].Y;
8374 minZ -= offsets[0].Z;
8375 maxZ -= offsets[0].Z;
8376
8377 LSL_Vector lower;
8378 LSL_Vector upper;
8379
8380 // Adjust to the documented error offsets (see LSL Wiki)
8381 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8382 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8383
8384 if (lower.x > upper.x)
8385 lower.x = upper.x;
8386 if (lower.y > upper.y)
8387 lower.y = upper.y;
8388 if (lower.z > upper.z)
8389 lower.z = upper.z;
8390
7701 result.Add(lower); 8391 result.Add(lower);
7702 result.Add(upper); 8392 result.Add(upper);
7703 return result; 8393 return result;
@@ -7777,13 +8467,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7777 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8467 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7778 part.AbsolutePosition.Y, 8468 part.AbsolutePosition.Y,
7779 part.AbsolutePosition.Z); 8469 part.AbsolutePosition.Z);
7780 // For some reason, the part.AbsolutePosition.* values do not change if the
7781 // linkset is rotated; they always reflect the child prim's world position
7782 // as though the linkset is unrotated. This is incompatible behavior with SL's
7783 // implementation, so will break scripts imported from there (not to mention it
7784 // makes it more difficult to determine a child prim's actual inworld position).
7785 if (part.ParentID != 0)
7786 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7787 res.Add(v); 8470 res.Add(v);
7788 break; 8471 break;
7789 8472
@@ -7954,56 +8637,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7954 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8637 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7955 if (remain < 1) 8638 if (remain < 1)
7956 return res; 8639 return res;
7957 8640 face = (int)rules.GetLSLIntegerItem(idx++);
7958 face=(int)rules.GetLSLIntegerItem(idx++);
7959 8641
7960 tex = part.Shape.Textures; 8642 tex = part.Shape.Textures;
8643 int shiny;
7961 if (face == ScriptBaseClass.ALL_SIDES) 8644 if (face == ScriptBaseClass.ALL_SIDES)
7962 { 8645 {
7963 for (face = 0; face < GetNumberOfSides(part); face++) 8646 for (face = 0; face < GetNumberOfSides(part); face++)
7964 { 8647 {
7965 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8648 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7966 // Convert Shininess to PRIM_SHINY_* 8649 if (shinyness == Shininess.High)
7967 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8650 {
7968 // PRIM_BUMP_* 8651 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7969 res.Add(new LSL_Integer((int)texface.Bump)); 8652 }
8653 else if (shinyness == Shininess.Medium)
8654 {
8655 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8656 }
8657 else if (shinyness == Shininess.Low)
8658 {
8659 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8660 }
8661 else
8662 {
8663 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8664 }
8665 res.Add(new LSL_Integer(shiny));
8666 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7970 } 8667 }
7971 } 8668 }
7972 else 8669 else
7973 { 8670 {
7974 if (face >= 0 && face < GetNumberOfSides(part)) 8671 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8672 if (shinyness == Shininess.High)
7975 { 8673 {
7976 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8674 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7977 // Convert Shininess to PRIM_SHINY_* 8675 }
7978 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8676 else if (shinyness == Shininess.Medium)
7979 // PRIM_BUMP_* 8677 {
7980 res.Add(new LSL_Integer((int)texface.Bump)); 8678 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8679 }
8680 else if (shinyness == Shininess.Low)
8681 {
8682 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8683 }
8684 else
8685 {
8686 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
7981 } 8687 }
8688 res.Add(new LSL_Integer(shiny));
8689 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7982 } 8690 }
7983 break; 8691 break;
7984 8692
7985 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8693 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7986 if (remain < 1) 8694 if (remain < 1)
7987 return res; 8695 return res;
7988 8696 face = (int)rules.GetLSLIntegerItem(idx++);
7989 face=(int)rules.GetLSLIntegerItem(idx++);
7990 8697
7991 tex = part.Shape.Textures; 8698 tex = part.Shape.Textures;
8699 int fullbright;
7992 if (face == ScriptBaseClass.ALL_SIDES) 8700 if (face == ScriptBaseClass.ALL_SIDES)
7993 { 8701 {
7994 for (face = 0; face < GetNumberOfSides(part); face++) 8702 for (face = 0; face < GetNumberOfSides(part); face++)
7995 { 8703 {
7996 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8704 if (tex.GetFace((uint)face).Fullbright == true)
7997 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8705 {
8706 fullbright = ScriptBaseClass.TRUE;
8707 }
8708 else
8709 {
8710 fullbright = ScriptBaseClass.FALSE;
8711 }
8712 res.Add(new LSL_Integer(fullbright));
7998 } 8713 }
7999 } 8714 }
8000 else 8715 else
8001 { 8716 {
8002 if (face >= 0 && face < GetNumberOfSides(part)) 8717 if (tex.GetFace((uint)face).Fullbright == true)
8003 { 8718 {
8004 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8719 fullbright = ScriptBaseClass.TRUE;
8005 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8006 } 8720 }
8721 else
8722 {
8723 fullbright = ScriptBaseClass.FALSE;
8724 }
8725 res.Add(new LSL_Integer(fullbright));
8007 } 8726 }
8008 break; 8727 break;
8009 8728
@@ -8025,27 +8744,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8025 break; 8744 break;
8026 8745
8027 case (int)ScriptBaseClass.PRIM_TEXGEN: 8746 case (int)ScriptBaseClass.PRIM_TEXGEN:
8747 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8028 if (remain < 1) 8748 if (remain < 1)
8029 return res; 8749 return res;
8030 8750 face = (int)rules.GetLSLIntegerItem(idx++);
8031 face=(int)rules.GetLSLIntegerItem(idx++);
8032 8751
8033 tex = part.Shape.Textures; 8752 tex = part.Shape.Textures;
8034 if (face == ScriptBaseClass.ALL_SIDES) 8753 if (face == ScriptBaseClass.ALL_SIDES)
8035 { 8754 {
8036 for (face = 0; face < GetNumberOfSides(part); face++) 8755 for (face = 0; face < GetNumberOfSides(part); face++)
8037 { 8756 {
8038 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8757 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8039 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8758 {
8040 res.Add(new LSL_Integer((uint)texgen >> 1)); 8759 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8760 }
8761 else
8762 {
8763 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8764 }
8041 } 8765 }
8042 } 8766 }
8043 else 8767 else
8044 { 8768 {
8045 if (face >= 0 && face < GetNumberOfSides(part)) 8769 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8046 { 8770 {
8047 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8771 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8048 res.Add(new LSL_Integer((uint)texgen >> 1)); 8772 }
8773 else
8774 {
8775 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8049 } 8776 }
8050 } 8777 }
8051 break; 8778 break;
@@ -8068,28 +8795,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8068 case (int)ScriptBaseClass.PRIM_GLOW: 8795 case (int)ScriptBaseClass.PRIM_GLOW:
8069 if (remain < 1) 8796 if (remain < 1)
8070 return res; 8797 return res;
8071 8798 face = (int)rules.GetLSLIntegerItem(idx++);
8072 face=(int)rules.GetLSLIntegerItem(idx++);
8073 8799
8074 tex = part.Shape.Textures; 8800 tex = part.Shape.Textures;
8801 float primglow;
8075 if (face == ScriptBaseClass.ALL_SIDES) 8802 if (face == ScriptBaseClass.ALL_SIDES)
8076 { 8803 {
8077 for (face = 0; face < GetNumberOfSides(part); face++) 8804 for (face = 0; face < GetNumberOfSides(part); face++)
8078 { 8805 {
8079 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8806 primglow = tex.GetFace((uint)face).Glow;
8080 res.Add(new LSL_Float(texface.Glow)); 8807 res.Add(new LSL_Float(primglow));
8081 } 8808 }
8082 } 8809 }
8083 else 8810 else
8084 { 8811 {
8085 if (face >= 0 && face < GetNumberOfSides(part)) 8812 primglow = tex.GetFace((uint)face).Glow;
8086 { 8813 res.Add(new LSL_Float(primglow));
8087 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8088 res.Add(new LSL_Float(texface.Glow));
8089 }
8090 } 8814 }
8091 break; 8815 break;
8092
8093 case (int)ScriptBaseClass.PRIM_TEXT: 8816 case (int)ScriptBaseClass.PRIM_TEXT:
8094 Color4 textColor = part.GetTextColor(); 8817 Color4 textColor = part.GetTextColor();
8095 res.Add(new LSL_String(part.Text)); 8818 res.Add(new LSL_String(part.Text));
@@ -8701,8 +9424,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8701 // The function returns an ordered list 9424 // The function returns an ordered list
8702 // representing the tokens found in the supplied 9425 // representing the tokens found in the supplied
8703 // sources string. If two successive tokenizers 9426 // sources string. If two successive tokenizers
8704 // are encountered, then a NULL entry is added 9427 // are encountered, then a null-string entry is
8705 // to the list. 9428 // added to the list.
8706 // 9429 //
8707 // It is a precondition that the source and 9430 // It is a precondition that the source and
8708 // toekizer lisst are non-null. If they are null, 9431 // toekizer lisst are non-null. If they are null,
@@ -8710,7 +9433,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8710 // while their lengths are being determined. 9433 // while their lengths are being determined.
8711 // 9434 //
8712 // A small amount of working memoryis required 9435 // A small amount of working memoryis required
8713 // of approximately 8*#tokenizers. 9436 // of approximately 8*#tokenizers + 8*srcstrlen.
8714 // 9437 //
8715 // There are many ways in which this function 9438 // There are many ways in which this function
8716 // can be implemented, this implementation is 9439 // can be implemented, this implementation is
@@ -8726,155 +9449,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8726 // and eliminates redundant tokenizers as soon 9449 // and eliminates redundant tokenizers as soon
8727 // as is possible. 9450 // as is possible.
8728 // 9451 //
8729 // The implementation tries to avoid any copying 9452 // The implementation tries to minimize temporary
8730 // of arrays or other objects. 9453 // garbage generation.
8731 // </remarks> 9454 // </remarks>
8732 9455
8733 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9456 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8734 { 9457 {
8735 int beginning = 0; 9458 return ParseString2List(src, separators, spacers, true);
8736 int srclen = src.Length; 9459 }
8737 int seplen = separators.Length;
8738 object[] separray = separators.Data;
8739 int spclen = spacers.Length;
8740 object[] spcarray = spacers.Data;
8741 int mlen = seplen+spclen;
8742
8743 int[] offset = new int[mlen+1];
8744 bool[] active = new bool[mlen];
8745
8746 int best;
8747 int j;
8748
8749 // Initial capacity reduces resize cost
8750 9460
8751 LSL_List tokens = new LSL_List(); 9461 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9462 {
9463 int srclen = src.Length;
9464 int seplen = separators.Length;
9465 object[] separray = separators.Data;
9466 int spclen = spacers.Length;
9467 object[] spcarray = spacers.Data;
9468 int dellen = 0;
9469 string[] delarray = new string[seplen+spclen];
8752 9470
8753 // All entries are initially valid 9471 int outlen = 0;
9472 string[] outarray = new string[srclen*2+1];
8754 9473
8755 for (int i = 0; i < mlen; i++) 9474 int i, j;
8756 active[i] = true; 9475 string d;
8757 9476
8758 offset[mlen] = srclen; 9477 m_host.AddScriptLPS(1);
8759 9478
8760 while (beginning < srclen) 9479 /*
9480 * Convert separator and spacer lists to C# strings.
9481 * Also filter out null strings so we don't hang.
9482 */
9483 for (i = 0; i < seplen; i ++)
8761 { 9484 {
9485 d = separray[i].ToString();
9486 if (d.Length > 0)
9487 {
9488 delarray[dellen++] = d;
9489 }
9490 }
9491 seplen = dellen;
8762 9492
8763 best = mlen; // as bad as it gets 9493 for (i = 0; i < spclen; i ++)
9494 {
9495 d = spcarray[i].ToString();
9496 if (d.Length > 0)
9497 {
9498 delarray[dellen++] = d;
9499 }
9500 }
8764 9501
8765 // Scan for separators 9502 /*
9503 * Scan through source string from beginning to end.
9504 */
9505 for (i = 0;;)
9506 {
8766 9507
8767 for (j = 0; j < seplen; j++) 9508 /*
9509 * Find earliest delimeter in src starting at i (if any).
9510 */
9511 int earliestDel = -1;
9512 int earliestSrc = srclen;
9513 string earliestStr = null;
9514 for (j = 0; j < dellen; j ++)
8768 { 9515 {
8769 if (separray[j].ToString() == String.Empty) 9516 d = delarray[j];
8770 active[j] = false; 9517 if (d != null)
8771
8772 if (active[j])
8773 { 9518 {
8774 // scan all of the markers 9519 int index = src.IndexOf(d, i);
8775 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9520 if (index < 0)
8776 { 9521 {
8777 // not present at all 9522 delarray[j] = null; // delim nowhere in src, don't check it anymore
8778 active[j] = false;
8779 } 9523 }
8780 else 9524 else if (index < earliestSrc)
8781 { 9525 {
8782 // present and correct 9526 earliestSrc = index; // where delimeter starts in source string
8783 if (offset[j] < offset[best]) 9527 earliestDel = j; // where delimeter is in delarray[]
8784 { 9528 earliestStr = d; // the delimeter string from delarray[]
8785 // closest so far 9529 if (index == i) break; // can't do any better than found at beg of string
8786 best = j;
8787 if (offset[best] == beginning)
8788 break;
8789 }
8790 } 9530 }
8791 } 9531 }
8792 } 9532 }
8793 9533
8794 // Scan for spacers 9534 /*
8795 9535 * Output source string starting at i through start of earliest delimeter.
8796 if (offset[best] != beginning) 9536 */
9537 if (keepNulls || (earliestSrc > i))
8797 { 9538 {
8798 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9539 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8799 {
8800 if (spcarray[j-seplen].ToString() == String.Empty)
8801 active[j] = false;
8802
8803 if (active[j])
8804 {
8805 // scan all of the markers
8806 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8807 {
8808 // not present at all
8809 active[j] = false;
8810 }
8811 else
8812 {
8813 // present and correct
8814 if (offset[j] < offset[best])
8815 {
8816 // closest so far
8817 best = j;
8818 }
8819 }
8820 }
8821 }
8822 } 9540 }
8823 9541
8824 // This is the normal exit from the scanning loop 9542 /*
9543 * If no delimeter found at or after i, we're done scanning.
9544 */
9545 if (earliestDel < 0) break;
8825 9546
8826 if (best == mlen) 9547 /*
9548 * If delimeter was a spacer, output the spacer.
9549 */
9550 if (earliestDel >= seplen)
8827 { 9551 {
8828 // no markers were found on this pass 9552 outarray[outlen++] = earliestStr;
8829 // so we're pretty much done
8830 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8831 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8832 break;
8833 } 9553 }
8834 9554
8835 // Otherwise we just add the newly delimited token 9555 /*
8836 // and recalculate where the search should continue. 9556 * Look at rest of src string following delimeter.
8837 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9557 */
8838 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9558 i = earliestSrc + earliestStr.Length;
8839
8840 if (best < seplen)
8841 {
8842 beginning = offset[best] + (separray[best].ToString()).Length;
8843 }
8844 else
8845 {
8846 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8847 string str = spcarray[best - seplen].ToString();
8848 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8849 tokens.Add(new LSL_String(str));
8850 }
8851 } 9559 }
8852 9560
8853 // This an awkward an not very intuitive boundary case. If the 9561 /*
8854 // last substring is a tokenizer, then there is an implied trailing 9562 * Make up an exact-sized output array suitable for an LSL_List object.
8855 // null list entry. Hopefully the single comparison will not be too 9563 */
8856 // arduous. Alternatively the 'break' could be replced with a return 9564 object[] outlist = new object[outlen];
8857 // but that's shabby programming. 9565 for (i = 0; i < outlen; i ++)
8858
8859 if ((beginning == srclen) && (keepNulls))
8860 { 9566 {
8861 if (srclen != 0) 9567 outlist[i] = new LSL_String(outarray[i]);
8862 tokens.Add(new LSL_String(""));
8863 } 9568 }
8864 9569 return new LSL_List(outlist);
8865 return tokens;
8866 }
8867
8868 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8869 {
8870 m_host.AddScriptLPS(1);
8871 return this.ParseString(src, separators, spacers, false);
8872 }
8873
8874 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8875 {
8876 m_host.AddScriptLPS(1);
8877 return this.ParseString(src, separators, spacers, true);
8878 } 9570 }
8879 9571
8880 public LSL_Integer llGetObjectPermMask(int mask) 9572 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8951,28 +9643,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8951 { 9643 {
8952 m_host.AddScriptLPS(1); 9644 m_host.AddScriptLPS(1);
8953 9645
8954 lock (m_host.TaskInventory) 9646 m_host.TaskInventory.LockItemsForRead(true);
9647 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8955 { 9648 {
8956 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9649 if (inv.Value.Name == item)
8957 { 9650 {
8958 if (inv.Value.Name == item) 9651 m_host.TaskInventory.LockItemsForRead(false);
9652 switch (mask)
8959 { 9653 {
8960 switch (mask) 9654 case 0:
8961 { 9655 return (int)inv.Value.BasePermissions;
8962 case 0: 9656 case 1:
8963 return (int)inv.Value.BasePermissions; 9657 return (int)inv.Value.CurrentPermissions;
8964 case 1: 9658 case 2:
8965 return (int)inv.Value.CurrentPermissions; 9659 return (int)inv.Value.GroupPermissions;
8966 case 2: 9660 case 3:
8967 return (int)inv.Value.GroupPermissions; 9661 return (int)inv.Value.EveryonePermissions;
8968 case 3: 9662 case 4:
8969 return (int)inv.Value.EveryonePermissions; 9663 return (int)inv.Value.NextPermissions;
8970 case 4:
8971 return (int)inv.Value.NextPermissions;
8972 }
8973 } 9664 }
8974 } 9665 }
8975 } 9666 }
9667 m_host.TaskInventory.LockItemsForRead(false);
8976 9668
8977 return -1; 9669 return -1;
8978 } 9670 }
@@ -9019,16 +9711,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9019 { 9711 {
9020 m_host.AddScriptLPS(1); 9712 m_host.AddScriptLPS(1);
9021 9713
9022 lock (m_host.TaskInventory) 9714 m_host.TaskInventory.LockItemsForRead(true);
9715 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9023 { 9716 {
9024 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9717 if (inv.Value.Name == item)
9025 { 9718 {
9026 if (inv.Value.Name == item) 9719 m_host.TaskInventory.LockItemsForRead(false);
9027 { 9720 return inv.Value.CreatorID.ToString();
9028 return inv.Value.CreatorID.ToString();
9029 }
9030 } 9721 }
9031 } 9722 }
9723 m_host.TaskInventory.LockItemsForRead(false);
9032 9724
9033 llSay(0, "No item name '" + item + "'"); 9725 llSay(0, "No item name '" + item + "'");
9034 9726
@@ -9154,9 +9846,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9154 { 9846 {
9155 try 9847 try
9156 { 9848 {
9849 /*
9157 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 9850 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9158 if (obj != null) 9851 if (obj != null)
9159 return (double)obj.GetMass(); 9852 return (double)obj.GetMass();
9853 */
9854 // return total object mass
9855 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
9856 if (obj != null)
9857 return obj.GetMass();
9858
9160 // the object is null so the key is for an avatar 9859 // the object is null so the key is for an avatar
9161 ScenePresence avatar = World.GetScenePresence(key); 9860 ScenePresence avatar = World.GetScenePresence(key);
9162 if (avatar != null) 9861 if (avatar != null)
@@ -9176,7 +9875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9176 } 9875 }
9177 9876
9178 /// <summary> 9877 /// <summary>
9179 /// illListReplaceList removes the sub-list defined by the inclusive indices 9878 /// llListReplaceList removes the sub-list defined by the inclusive indices
9180 /// start and end and inserts the src list in its place. The inclusive 9879 /// start and end and inserts the src list in its place. The inclusive
9181 /// nature of the indices means that at least one element must be deleted 9880 /// nature of the indices means that at least one element must be deleted
9182 /// if the indices are within the bounds of the existing list. I.e. 2,2 9881 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9233,16 +9932,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9233 // based upon end. Note that if end exceeds the upper 9932 // based upon end. Note that if end exceeds the upper
9234 // bound in this case, the entire destination list 9933 // bound in this case, the entire destination list
9235 // is removed. 9934 // is removed.
9236 else 9935 else if (start == 0)
9237 { 9936 {
9238 if (end + 1 < dest.Length) 9937 if (end + 1 < dest.Length)
9239 {
9240 return src + dest.GetSublist(end + 1, -1); 9938 return src + dest.GetSublist(end + 1, -1);
9241 }
9242 else 9939 else
9243 {
9244 return src; 9940 return src;
9245 } 9941 }
9942 else // Start < 0
9943 {
9944 if (end + 1 < dest.Length)
9945 return dest.GetSublist(end + 1, -1);
9946 else
9947 return new LSL_List();
9246 } 9948 }
9247 } 9949 }
9248 // Finally, if start > end, we strip away a prefix and 9950 // Finally, if start > end, we strip away a prefix and
@@ -9293,17 +9995,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9293 int width = 0; 9995 int width = 0;
9294 int height = 0; 9996 int height = 0;
9295 9997
9296 ParcelMediaCommandEnum? commandToSend = null; 9998 uint commandToSend = 0;
9297 float time = 0.0f; // default is from start 9999 float time = 0.0f; // default is from start
9298 10000
9299 ScenePresence presence = null; 10001 ScenePresence presence = null;
9300 10002
9301 for (int i = 0; i < commandList.Data.Length; i++) 10003 for (int i = 0; i < commandList.Data.Length; i++)
9302 { 10004 {
9303 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10005 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9304 switch (command) 10006 switch (command)
9305 { 10007 {
9306 case ParcelMediaCommandEnum.Agent: 10008 case (uint)ParcelMediaCommandEnum.Agent:
9307 // we send only to one agent 10009 // we send only to one agent
9308 if ((i + 1) < commandList.Length) 10010 if ((i + 1) < commandList.Length)
9309 { 10011 {
@@ -9320,25 +10022,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9320 } 10022 }
9321 break; 10023 break;
9322 10024
9323 case ParcelMediaCommandEnum.Loop: 10025 case (uint)ParcelMediaCommandEnum.Loop:
9324 loop = 1; 10026 loop = 1;
9325 commandToSend = command; 10027 commandToSend = command;
9326 update = true; //need to send the media update packet to set looping 10028 update = true; //need to send the media update packet to set looping
9327 break; 10029 break;
9328 10030
9329 case ParcelMediaCommandEnum.Play: 10031 case (uint)ParcelMediaCommandEnum.Play:
9330 loop = 0; 10032 loop = 0;
9331 commandToSend = command; 10033 commandToSend = command;
9332 update = true; //need to send the media update packet to make sure it doesn't loop 10034 update = true; //need to send the media update packet to make sure it doesn't loop
9333 break; 10035 break;
9334 10036
9335 case ParcelMediaCommandEnum.Pause: 10037 case (uint)ParcelMediaCommandEnum.Pause:
9336 case ParcelMediaCommandEnum.Stop: 10038 case (uint)ParcelMediaCommandEnum.Stop:
9337 case ParcelMediaCommandEnum.Unload: 10039 case (uint)ParcelMediaCommandEnum.Unload:
9338 commandToSend = command; 10040 commandToSend = command;
9339 break; 10041 break;
9340 10042
9341 case ParcelMediaCommandEnum.Url: 10043 case (uint)ParcelMediaCommandEnum.Url:
9342 if ((i + 1) < commandList.Length) 10044 if ((i + 1) < commandList.Length)
9343 { 10045 {
9344 if (commandList.Data[i + 1] is LSL_String) 10046 if (commandList.Data[i + 1] is LSL_String)
@@ -9351,7 +10053,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9351 } 10053 }
9352 break; 10054 break;
9353 10055
9354 case ParcelMediaCommandEnum.Texture: 10056 case (uint)ParcelMediaCommandEnum.Texture:
9355 if ((i + 1) < commandList.Length) 10057 if ((i + 1) < commandList.Length)
9356 { 10058 {
9357 if (commandList.Data[i + 1] is LSL_String) 10059 if (commandList.Data[i + 1] is LSL_String)
@@ -9364,7 +10066,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9364 } 10066 }
9365 break; 10067 break;
9366 10068
9367 case ParcelMediaCommandEnum.Time: 10069 case (uint)ParcelMediaCommandEnum.Time:
9368 if ((i + 1) < commandList.Length) 10070 if ((i + 1) < commandList.Length)
9369 { 10071 {
9370 if (commandList.Data[i + 1] is LSL_Float) 10072 if (commandList.Data[i + 1] is LSL_Float)
@@ -9376,7 +10078,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9376 } 10078 }
9377 break; 10079 break;
9378 10080
9379 case ParcelMediaCommandEnum.AutoAlign: 10081 case (uint)ParcelMediaCommandEnum.AutoAlign:
9380 if ((i + 1) < commandList.Length) 10082 if ((i + 1) < commandList.Length)
9381 { 10083 {
9382 if (commandList.Data[i + 1] is LSL_Integer) 10084 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9390,7 +10092,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9390 } 10092 }
9391 break; 10093 break;
9392 10094
9393 case ParcelMediaCommandEnum.Type: 10095 case (uint)ParcelMediaCommandEnum.Type:
9394 if ((i + 1) < commandList.Length) 10096 if ((i + 1) < commandList.Length)
9395 { 10097 {
9396 if (commandList.Data[i + 1] is LSL_String) 10098 if (commandList.Data[i + 1] is LSL_String)
@@ -9403,7 +10105,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9403 } 10105 }
9404 break; 10106 break;
9405 10107
9406 case ParcelMediaCommandEnum.Desc: 10108 case (uint)ParcelMediaCommandEnum.Desc:
9407 if ((i + 1) < commandList.Length) 10109 if ((i + 1) < commandList.Length)
9408 { 10110 {
9409 if (commandList.Data[i + 1] is LSL_String) 10111 if (commandList.Data[i + 1] is LSL_String)
@@ -9416,7 +10118,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9416 } 10118 }
9417 break; 10119 break;
9418 10120
9419 case ParcelMediaCommandEnum.Size: 10121 case (uint)ParcelMediaCommandEnum.Size:
9420 if ((i + 2) < commandList.Length) 10122 if ((i + 2) < commandList.Length)
9421 { 10123 {
9422 if (commandList.Data[i + 1] is LSL_Integer) 10124 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9486,7 +10188,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9486 } 10188 }
9487 } 10189 }
9488 10190
9489 if (commandToSend != null) 10191 if (commandToSend != 0)
9490 { 10192 {
9491 // the commandList contained a start/stop/... command, too 10193 // the commandList contained a start/stop/... command, too
9492 if (presence == null) 10194 if (presence == null)
@@ -9523,7 +10225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9523 10225
9524 if (aList.Data[i] != null) 10226 if (aList.Data[i] != null)
9525 { 10227 {
9526 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10228 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9527 { 10229 {
9528 case ParcelMediaCommandEnum.Url: 10230 case ParcelMediaCommandEnum.Url:
9529 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10231 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9566,16 +10268,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9566 { 10268 {
9567 m_host.AddScriptLPS(1); 10269 m_host.AddScriptLPS(1);
9568 10270
9569 lock (m_host.TaskInventory) 10271 m_host.TaskInventory.LockItemsForRead(true);
10272 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9570 { 10273 {
9571 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10274 if (inv.Value.Name == name)
9572 { 10275 {
9573 if (inv.Value.Name == name) 10276 m_host.TaskInventory.LockItemsForRead(false);
9574 { 10277 return inv.Value.Type;
9575 return inv.Value.Type;
9576 }
9577 } 10278 }
9578 } 10279 }
10280 m_host.TaskInventory.LockItemsForRead(false);
9579 10281
9580 return -1; 10282 return -1;
9581 } 10283 }
@@ -9586,15 +10288,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9586 10288
9587 if (quick_pay_buttons.Data.Length < 4) 10289 if (quick_pay_buttons.Data.Length < 4)
9588 { 10290 {
9589 LSLError("List must have at least 4 elements"); 10291 int x;
9590 return; 10292 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10293 {
10294 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10295 }
9591 } 10296 }
9592 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10297 int[] nPrice = new int[5];
9593 10298 nPrice[0] = price;
9594 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10299 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9595 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10300 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9596 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10301 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9597 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10302 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10303 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9598 m_host.ParentGroup.HasGroupChanged = true; 10304 m_host.ParentGroup.HasGroupChanged = true;
9599 } 10305 }
9600 10306
@@ -9612,6 +10318,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9612 ShoutError("No permissions to track the camera"); 10318 ShoutError("No permissions to track the camera");
9613 return new LSL_Vector(); 10319 return new LSL_Vector();
9614 } 10320 }
10321 m_host.TaskInventory.LockItemsForRead(false);
9615 10322
9616 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10323 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9617 if (presence != null) 10324 if (presence != null)
@@ -9636,6 +10343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9636 ShoutError("No permissions to track the camera"); 10343 ShoutError("No permissions to track the camera");
9637 return new LSL_Rotation(); 10344 return new LSL_Rotation();
9638 } 10345 }
10346 m_host.TaskInventory.LockItemsForRead(false);
9639 10347
9640 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10348 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9641 if (presence != null) 10349 if (presence != null)
@@ -9697,8 +10405,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9697 { 10405 {
9698 m_host.AddScriptLPS(1); 10406 m_host.AddScriptLPS(1);
9699 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10407 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9700 if (detectedParams == null) return; // only works on the first detected avatar 10408 if (detectedParams == null)
9701 10409 {
10410 if (m_host.ParentGroup.IsAttachment == true)
10411 {
10412 detectedParams = new DetectParams();
10413 detectedParams.Key = m_host.OwnerID;
10414 }
10415 else
10416 {
10417 return;
10418 }
10419 }
10420
9702 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10421 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9703 if (avatar != null) 10422 if (avatar != null)
9704 { 10423 {
@@ -9706,6 +10425,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9706 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10425 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9707 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10426 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9708 } 10427 }
10428
9709 ScriptSleep(1000); 10429 ScriptSleep(1000);
9710 } 10430 }
9711 10431
@@ -9831,12 +10551,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9831 10551
9832 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10552 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9833 object[] data = rules.Data; 10553 object[] data = rules.Data;
9834 for (int i = 0; i < data.Length; ++i) { 10554 for (int i = 0; i < data.Length; ++i)
10555 {
9835 int type = Convert.ToInt32(data[i++].ToString()); 10556 int type = Convert.ToInt32(data[i++].ToString());
9836 if (i >= data.Length) break; // odd number of entries => ignore the last 10557 if (i >= data.Length) break; // odd number of entries => ignore the last
9837 10558
9838 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10559 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9839 switch (type) { 10560 switch (type)
10561 {
9840 case ScriptBaseClass.CAMERA_FOCUS: 10562 case ScriptBaseClass.CAMERA_FOCUS:
9841 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10563 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9842 case ScriptBaseClass.CAMERA_POSITION: 10564 case ScriptBaseClass.CAMERA_POSITION:
@@ -9944,19 +10666,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9944 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10666 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9945 { 10667 {
9946 m_host.AddScriptLPS(1); 10668 m_host.AddScriptLPS(1);
9947 string ret = String.Empty; 10669
9948 string src1 = llBase64ToString(str1); 10670 if (str1 == String.Empty)
9949 string src2 = llBase64ToString(str2); 10671 return String.Empty;
9950 int c = 0; 10672 if (str2 == String.Empty)
9951 for (int i = 0; i < src1.Length; i++) 10673 return str1;
10674
10675 int len = str2.Length;
10676 if ((len % 4) != 0) // LL is EVIL!!!!
10677 {
10678 while (str2.EndsWith("="))
10679 str2 = str2.Substring(0, str2.Length - 1);
10680
10681 len = str2.Length;
10682 int mod = len % 4;
10683
10684 if (mod == 1)
10685 str2 = str2.Substring(0, str2.Length - 1);
10686 else if (mod == 2)
10687 str2 += "==";
10688 else if (mod == 3)
10689 str2 += "=";
10690 }
10691
10692 byte[] data1;
10693 byte[] data2;
10694 try
10695 {
10696 data1 = Convert.FromBase64String(str1);
10697 data2 = Convert.FromBase64String(str2);
10698 }
10699 catch (Exception)
10700 {
10701 return new LSL_String(String.Empty);
10702 }
10703
10704 byte[] d2 = new Byte[data1.Length];
10705 int pos = 0;
10706
10707 if (data1.Length <= data2.Length)
10708 {
10709 Array.Copy(data2, 0, d2, 0, data1.Length);
10710 }
10711 else
9952 { 10712 {
9953 ret += (char) (src1[i] ^ src2[c]); 10713 while (pos < data1.Length)
10714 {
10715 len = data1.Length - pos;
10716 if (len > data2.Length)
10717 len = data2.Length;
9954 10718
9955 c++; 10719 Array.Copy(data2, 0, d2, pos, len);
9956 if (c >= src2.Length) 10720 pos += len;
9957 c = 0; 10721 }
9958 } 10722 }
9959 return llStringToBase64(ret); 10723
10724 for (pos = 0 ; pos < data1.Length ; pos++ )
10725 data1[pos] ^= d2[pos];
10726
10727 return Convert.ToBase64String(data1);
9960 } 10728 }
9961 10729
9962 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10730 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10013,12 +10781,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10013 Regex r = new Regex(authregex); 10781 Regex r = new Regex(authregex);
10014 int[] gnums = r.GetGroupNumbers(); 10782 int[] gnums = r.GetGroupNumbers();
10015 Match m = r.Match(url); 10783 Match m = r.Match(url);
10016 if (m.Success) { 10784 if (m.Success)
10017 for (int i = 1; i < gnums.Length; i++) { 10785 {
10786 for (int i = 1; i < gnums.Length; i++)
10787 {
10018 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10788 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10019 //CaptureCollection cc = g.Captures; 10789 //CaptureCollection cc = g.Captures;
10020 } 10790 }
10021 if (m.Groups.Count == 5) { 10791 if (m.Groups.Count == 5)
10792 {
10022 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10793 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10023 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10794 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10024 } 10795 }
@@ -10381,15 +11152,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10381 11152
10382 internal UUID ScriptByName(string name) 11153 internal UUID ScriptByName(string name)
10383 { 11154 {
10384 lock (m_host.TaskInventory) 11155 m_host.TaskInventory.LockItemsForRead(true);
11156
11157 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10385 { 11158 {
10386 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11159 if (item.Type == 10 && item.Name == name)
10387 { 11160 {
10388 if (item.Type == 10 && item.Name == name) 11161 m_host.TaskInventory.LockItemsForRead(false);
10389 return item.ItemID; 11162 return item.ItemID;
10390 } 11163 }
10391 } 11164 }
10392 11165
11166 m_host.TaskInventory.LockItemsForRead(false);
11167
10393 return UUID.Zero; 11168 return UUID.Zero;
10394 } 11169 }
10395 11170
@@ -10430,6 +11205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10430 { 11205 {
10431 m_host.AddScriptLPS(1); 11206 m_host.AddScriptLPS(1);
10432 11207
11208 //Clone is thread safe
10433 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11209 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10434 11210
10435 UUID assetID = UUID.Zero; 11211 UUID assetID = UUID.Zero;
@@ -10492,6 +11268,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10492 { 11268 {
10493 m_host.AddScriptLPS(1); 11269 m_host.AddScriptLPS(1);
10494 11270
11271 //Clone is thread safe
10495 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11272 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10496 11273
10497 UUID assetID = UUID.Zero; 11274 UUID assetID = UUID.Zero;
@@ -10572,15 +11349,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10572 return GetLinkPrimitiveParams(obj, rules); 11349 return GetLinkPrimitiveParams(obj, rules);
10573 } 11350 }
10574 11351
10575 public void print(string str) 11352 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10576 { 11353 {
10577 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11354 List<SceneObjectPart> parts = GetLinkParts(link);
10578 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11355 if (parts.Count < 1)
10579 if (ossl != null) 11356 return 0;
10580 { 11357
10581 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11358 return GetNumberOfSides(parts[0]);
10582 m_log.Info("LSL print():" + str);
10583 }
10584 } 11359 }
10585 11360
10586 private string Name2Username(string name) 11361 private string Name2Username(string name)
@@ -10626,155 +11401,482 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10626 return rq.ToString(); 11401 return rq.ToString();
10627 } 11402 }
10628 11403
11404 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11405 {
11406 m_SayShoutCount = 0;
11407 }
11408
11409 private struct Tri
11410 {
11411 public Vector3 p1;
11412 public Vector3 p2;
11413 public Vector3 p3;
11414 }
11415
11416 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11417 {
11418 float height = avatar.Appearance.AvatarHeight;
11419 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11420 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11421
11422 if (point.X > b1.X && point.X < b2.X &&
11423 point.Y > b1.Y && point.Y < b2.Y &&
11424 point.Z > b1.Z && point.Z < b2.Z)
11425 return true;
11426 return false;
11427 }
11428
11429 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11430 {
11431 List<ContactResult> contacts = new List<ContactResult>();
11432
11433 Vector3 ab = rayEnd - rayStart;
11434
11435 World.ForEachScenePresence(delegate(ScenePresence sp)
11436 {
11437 Vector3 ac = sp.AbsolutePosition - rayStart;
11438 Vector3 bc = sp.AbsolutePosition - rayEnd;
11439
11440 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11441
11442 if (d > 1.5)
11443 return;
11444
11445 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11446
11447 if (d2 > 0)
11448 return;
11449
11450 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11451 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11452
11453 if (!InBoundingBox(sp, p))
11454 return;
11455
11456 ContactResult result = new ContactResult ();
11457 result.ConsumerID = sp.LocalId;
11458 result.Depth = Vector3.Distance(rayStart, p);
11459 result.Normal = Vector3.Zero;
11460 result.Pos = p;
11461
11462 contacts.Add(result);
11463 });
11464
11465 return contacts.ToArray();
11466 }
11467
11468 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11469 {
11470 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11471 List<ContactResult> contacts = new List<ContactResult>();
11472
11473 Vector3 ab = rayEnd - rayStart;
11474
11475 World.ForEachSOG(delegate(SceneObjectGroup group)
11476 {
11477 if (m_host.ParentGroup == group)
11478 return;
11479
11480 if (group.IsAttachment)
11481 return;
11482
11483 if (group.RootPart.PhysActor == null)
11484 {
11485 if (!includePhantom)
11486 return;
11487 }
11488 else
11489 {
11490 if (group.RootPart.PhysActor.IsPhysical)
11491 {
11492 if (!includePhysical)
11493 return;
11494 }
11495 else
11496 {
11497 if (!includeNonPhysical)
11498 return;
11499 }
11500 }
11501
11502 // Find the radius ouside of which we don't even need to hit test
11503 float minX;
11504 float maxX;
11505 float minY;
11506 float maxY;
11507 float minZ;
11508 float maxZ;
11509
11510 float radius = 0.0f;
11511
11512 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11513
11514 if (Math.Abs(minX) > radius)
11515 radius = Math.Abs(minX);
11516 if (Math.Abs(minY) > radius)
11517 radius = Math.Abs(minY);
11518 if (Math.Abs(minZ) > radius)
11519 radius = Math.Abs(minZ);
11520 if (Math.Abs(maxX) > radius)
11521 radius = Math.Abs(maxX);
11522 if (Math.Abs(maxY) > radius)
11523 radius = Math.Abs(maxY);
11524 if (Math.Abs(maxZ) > radius)
11525 radius = Math.Abs(maxZ);
11526
11527 Vector3 ac = group.AbsolutePosition - rayStart;
11528 Vector3 bc = group.AbsolutePosition - rayEnd;
11529
11530 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11531
11532 // Too far off ray, don't bother
11533 if (d > radius)
11534 return;
11535
11536 // Behind ray, drop
11537 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11538 if (d2 > 0)
11539 return;
11540
11541 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11542 // Miss.
11543 if (!intersection.HitTF)
11544 return;
11545
11546 ContactResult result = new ContactResult ();
11547 result.ConsumerID = group.LocalId;
11548 result.Depth = intersection.distance;
11549 result.Normal = intersection.normal;
11550 result.Pos = intersection.ipoint;
11551
11552 contacts.Add(result);
11553 });
11554
11555 return contacts.ToArray();
11556 }
11557
11558 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11559 {
11560 double[,] heightfield = World.Heightmap.GetDoubles();
11561 List<ContactResult> contacts = new List<ContactResult>();
11562
11563 double min = 2048.0;
11564 double max = 0.0;
11565
11566 // Find the min and max of the heightfield
11567 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11568 {
11569 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11570 {
11571 if (heightfield[x, y] > max)
11572 max = heightfield[x, y];
11573 if (heightfield[x, y] < min)
11574 min = heightfield[x, y];
11575 }
11576 }
11577
11578
11579 // A ray extends past rayEnd, but doesn't go back before
11580 // rayStart. If the start is above the highest point of the ground
11581 // and the ray goes up, we can't hit the ground. Ever.
11582 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11583 return null;
11584
11585 // Same for going down
11586 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11587 return null;
11588
11589 List<Tri> trilist = new List<Tri>();
11590
11591 // Create our triangle list
11592 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11593 {
11594 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11595 {
11596 Tri t1 = new Tri();
11597 Tri t2 = new Tri();
11598
11599 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11600 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11601 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11602 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11603
11604 t1.p1 = p1;
11605 t1.p2 = p2;
11606 t1.p3 = p3;
11607
11608 t2.p1 = p3;
11609 t2.p2 = p4;
11610 t2.p3 = p1;
11611
11612 trilist.Add(t1);
11613 trilist.Add(t2);
11614 }
11615 }
11616
11617 // Ray direction
11618 Vector3 rayDirection = rayEnd - rayStart;
11619
11620 foreach (Tri t in trilist)
11621 {
11622 // Compute triangle plane normal and edges
11623 Vector3 u = t.p2 - t.p1;
11624 Vector3 v = t.p3 - t.p1;
11625 Vector3 n = Vector3.Cross(u, v);
11626
11627 if (n == Vector3.Zero)
11628 continue;
11629
11630 Vector3 w0 = rayStart - t.p1;
11631 double a = -Vector3.Dot(n, w0);
11632 double b = Vector3.Dot(n, rayDirection);
11633
11634 // Not intersecting the plane, or in plane (same thing)
11635 // Ignoring this MAY cause the ground to not be detected
11636 // sometimes
11637 if (Math.Abs(b) < 0.000001)
11638 continue;
11639
11640 double r = a / b;
11641
11642 // ray points away from plane
11643 if (r < 0.0)
11644 continue;
11645
11646 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11647
11648 float uu = Vector3.Dot(u, u);
11649 float uv = Vector3.Dot(u, v);
11650 float vv = Vector3.Dot(v, v);
11651 Vector3 w = ip - t.p1;
11652 float wu = Vector3.Dot(w, u);
11653 float wv = Vector3.Dot(w, v);
11654 float d = uv * uv - uu * vv;
11655
11656 float cs = (uv * wv - vv * wu) / d;
11657 if (cs < 0 || cs > 1.0)
11658 continue;
11659 float ct = (uv * wu - uu * wv) / d;
11660 if (ct < 0 || (cs + ct) > 1.0)
11661 continue;
11662
11663 // Add contact point
11664 ContactResult result = new ContactResult ();
11665 result.ConsumerID = 0;
11666 result.Depth = Vector3.Distance(rayStart, ip);
11667 result.Normal = n;
11668 result.Pos = ip;
11669
11670 contacts.Add(result);
11671 }
11672
11673 if (contacts.Count == 0)
11674 return null;
11675
11676 contacts.Sort(delegate(ContactResult a, ContactResult b)
11677 {
11678 return (int)(a.Depth - b.Depth);
11679 });
11680
11681 return contacts[0];
11682 }
11683/*
11684 // not done:
11685 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
11686 {
11687 ContactResult[] contacts = null;
11688 World.ForEachSOG(delegate(SceneObjectGroup group)
11689 {
11690 if (m_host.ParentGroup == group)
11691 return;
11692
11693 if (group.IsAttachment)
11694 return;
11695
11696 if(group.RootPart.PhysActor != null)
11697 return;
11698
11699 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
11700 });
11701 return contacts;
11702 }
11703*/
11704
10629 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11705 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10630 { 11706 {
11707 LSL_List list = new LSL_List();
11708
10631 m_host.AddScriptLPS(1); 11709 m_host.AddScriptLPS(1);
10632 11710
10633 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11711 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10634 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11712 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10635 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11713 Vector3 dir = rayEnd - rayStart;
10636 11714
10637 int count = 0; 11715 float dist = Vector3.Mag(dir);
10638// int detectPhantom = 0; 11716
11717 int count = 1;
11718 bool detectPhantom = false;
10639 int dataFlags = 0; 11719 int dataFlags = 0;
10640 int rejectTypes = 0; 11720 int rejectTypes = 0;
10641 11721
10642 for (int i = 0; i < options.Length; i += 2) 11722 for (int i = 0; i < options.Length; i += 2)
10643 { 11723 {
10644 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11724 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10645 {
10646 count = options.GetLSLIntegerItem(i + 1); 11725 count = options.GetLSLIntegerItem(i + 1);
10647 } 11726 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10648// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11727 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10649// {
10650// detectPhantom = options.GetLSLIntegerItem(i + 1);
10651// }
10652 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11728 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10653 {
10654 dataFlags = options.GetLSLIntegerItem(i + 1); 11729 dataFlags = options.GetLSLIntegerItem(i + 1);
10655 }
10656 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11730 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10657 {
10658 rejectTypes = options.GetLSLIntegerItem(i + 1); 11731 rejectTypes = options.GetLSLIntegerItem(i + 1);
10659 }
10660 } 11732 }
10661 11733
10662 LSL_List list = new LSL_List(); 11734 if (count > 16)
10663 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11735 count = 16;
10664
10665 double distance = Util.GetDistanceTo(startvector, endvector);
10666
10667 if (distance == 0)
10668 distance = 0.001;
10669 11736
10670 Vector3 posToCheck = startvector; 11737 List<ContactResult> results = new List<ContactResult>();
10671 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10672 11738
10673 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11739 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10674 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11740 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10675 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11741 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10676 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11742 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10677 11743
10678 for (float i = 0; i <= distance; i += 0.1f) 11744
11745 if (World.SuportsRayCastFiltered())
10679 { 11746 {
10680 posToCheck = startvector + (dir * (i / (float)distance)); 11747 if (dist == 0)
11748 return list;
11749
11750 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11751 if (checkTerrain)
11752 rayfilter |= RayFilterFlags.land;
11753// if (checkAgents)
11754// rayfilter |= RayFilterFlags.agent;
11755 if (checkPhysical)
11756 rayfilter |= RayFilterFlags.physical;
11757 if (checkNonPhysical)
11758 rayfilter |= RayFilterFlags.nonphysical;
11759 if (detectPhantom)
11760 rayfilter |= RayFilterFlags.LSLPhanton;
10681 11761
10682 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11762 Vector3 direction = dir * ( 1/dist);
11763
11764 if(rayfilter == 0)
10683 { 11765 {
10684 ContactResult result = new ContactResult(); 11766 list.Add(new LSL_Integer(0));
10685 result.ConsumerID = 0; 11767 return list;
10686 result.Depth = 0;
10687 result.Normal = Vector3.Zero;
10688 result.Pos = posToCheck;
10689 results.Add(result);
10690 checkTerrain = false;
10691 } 11768 }
10692 11769
10693 if (checkAgents) 11770 // get some more contacts to sort ???
11771 int physcount = 4 * count;
11772 if (physcount > 20)
11773 physcount = 20;
11774
11775 object physresults;
11776 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11777
11778 if (physresults == null)
10694 { 11779 {
10695 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11780 list.Add(new LSL_Integer(-3)); // timeout error
10696 { 11781 return list;
10697 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X))
10698 {
10699 ContactResult result = new ContactResult ();
10700 result.ConsumerID = sp.LocalId;
10701 result.Depth = 0;
10702 result.Normal = Vector3.Zero;
10703 result.Pos = posToCheck;
10704 results.Add(result);
10705 }
10706 });
10707 } 11782 }
10708 }
10709 11783
10710 int refcount = 0; 11784 results = (List<ContactResult>)physresults;
10711 foreach (ContactResult result in results)
10712 {
10713 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND)
10714 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0)
10715 continue;
10716 11785
10717 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID); 11786 // for now physics doesn't detect sitted avatars so do it outside physics
11787 if (checkAgents)
11788 {
11789 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11790 foreach (ContactResult r in agentHits)
11791 results.Add(r);
11792 }
10718 11793
10719 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11794 // bug: will not detect phantom unless they are physical
10720 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11795 // don't use ObjectIntersection because its also bad
11796
11797 }
11798 else
11799 {
11800 if (checkTerrain)
11801 {
11802 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11803 if (groundContact != null)
11804 results.Add((ContactResult)groundContact);
11805 }
10721 11806
10722 if (entity == null) 11807 if (checkAgents)
10723 { 11808 {
10724 list.Add(UUID.Zero); 11809 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
11810 foreach (ContactResult r in agentHits)
11811 results.Add(r);
11812 }
10725 11813
10726 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11814 if (checkPhysical || checkNonPhysical || detectPhantom)
10727 list.Add(0); 11815 {
11816 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
11817 foreach (ContactResult r in objectHits)
11818 results.Add(r);
11819 }
11820 }
10728 11821
10729 list.Add(result.Pos); 11822 results.Sort(delegate(ContactResult a, ContactResult b)
11823 {
11824 return a.Depth.CompareTo(b.Depth);
11825 });
11826
11827 int values = 0;
11828 SceneObjectGroup thisgrp = m_host.ParentGroup;
10730 11829
10731 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11830 foreach (ContactResult result in results)
10732 list.Add(result.Normal); 11831 {
11832 if (result.Depth > dist)
11833 continue;
10733 11834
10734 continue; //Can't find it, so add UUID.Zero 11835 // physics ray can return colisions with host prim
10735 } 11836 if (m_host.LocalId == result.ConsumerID)
11837 continue;
10736 11838
10737 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity && 11839 UUID itemID = UUID.Zero;
10738 ((ISceneChildEntity)intersection.obj).PhysActor == null) 11840 int linkNum = 0;
10739 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10740 11841
10741 if (entity is SceneObjectPart) 11842 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
11843 // It's a prim!
11844 if (part != null)
10742 { 11845 {
10743 PhysicsActor pa = ((SceneObjectPart)entity).PhysActor; 11846 // dont detect members of same object ???
11847 if (part.ParentGroup == thisgrp)
11848 continue;
10744 11849
10745 if (pa != null && pa.IsPhysical) 11850 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10746 { 11851 itemID = part.ParentGroup.UUID;
10747 if (!checkPhysical)
10748 continue;
10749 }
10750 else 11852 else
10751 { 11853 itemID = part.UUID;
10752 if (!checkNonPhysical)
10753 continue;
10754 }
10755 }
10756 11854
10757 refcount++; 11855 linkNum = part.LinkNum;
10758 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11856 }
10759 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10760 else 11857 else
10761 list.Add(entity.UUID);
10762
10763 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10764 { 11858 {
10765 if (entity is SceneObjectPart) 11859 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10766 list.Add(((SceneObjectPart)entity).LinkNum); 11860 /// It it a boy? a girl?
10767 else 11861 if (sp != null)
10768 list.Add(0); 11862 itemID = sp.UUID;
10769 } 11863 }
10770 11864
10771 list.Add(result.Pos); 11865 list.Add(new LSL_String(itemID.ToString()));
11866 list.Add(new LSL_String(result.Pos.ToString()));
11867
11868 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
11869 list.Add(new LSL_Integer(linkNum));
10772 11870
10773 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11871 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10774 list.Add(result.Normal); 11872 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11873
11874 values++;
11875 if (values >= count)
11876 break;
10775 } 11877 }
10776 11878
10777 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11879 list.Add(new LSL_Integer(values));
10778 11880
10779 return list; 11881 return list;
10780 } 11882 }
@@ -10814,7 +11916,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10814 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 11916 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10815 if (!isAccount) return 0; 11917 if (!isAccount) return 0;
10816 if (estate.HasAccess(id)) return 1; 11918 if (estate.HasAccess(id)) return 1;
10817 if (estate.IsBanned(id)) 11919 if (estate.IsBanned(id, World.GetUserFlags(id)))
10818 estate.RemoveBan(id); 11920 estate.RemoveBan(id);
10819 estate.AddEstateUser(id); 11921 estate.AddEstateUser(id);
10820 break; 11922 break;
@@ -10833,14 +11935,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10833 break; 11935 break;
10834 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 11936 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10835 if (!isAccount) return 0; 11937 if (!isAccount) return 0;
10836 if (estate.IsBanned(id)) return 1; 11938 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
10837 EstateBan ban = new EstateBan(); 11939 EstateBan ban = new EstateBan();
10838 ban.EstateID = estate.EstateID; 11940 ban.EstateID = estate.EstateID;
10839 ban.BannedUserID = id; 11941 ban.BannedUserID = id;
10840 estate.AddBan(ban); 11942 estate.AddBan(ban);
10841 break; 11943 break;
10842 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 11944 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10843 if (!isAccount || !estate.IsBanned(id)) return 0; 11945 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
10844 estate.RemoveBan(id); 11946 estate.RemoveBan(id);
10845 break; 11947 break;
10846 default: return 0; 11948 default: return 0;
@@ -10869,7 +11971,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10869 return 16384; 11971 return 16384;
10870 } 11972 }
10871 11973
10872 public LSL_Integer llGetUsedMemory() 11974 public virtual LSL_Integer llGetUsedMemory()
10873 { 11975 {
10874 m_host.AddScriptLPS(1); 11976 m_host.AddScriptLPS(1);
10875 // The value returned for LSO scripts in SL 11977 // The value returned for LSO scripts in SL
@@ -10897,7 +11999,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10897 public void llSetSoundQueueing(int queue) 11999 public void llSetSoundQueueing(int queue)
10898 { 12000 {
10899 m_host.AddScriptLPS(1); 12001 m_host.AddScriptLPS(1);
10900 NotImplemented("llSetSoundQueueing");
10901 } 12002 }
10902 12003
10903 public void llCollisionSprite(string impact_sprite) 12004 public void llCollisionSprite(string impact_sprite)
@@ -10909,10 +12010,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10909 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12010 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10910 { 12011 {
10911 m_host.AddScriptLPS(1); 12012 m_host.AddScriptLPS(1);
10912 NotImplemented("llGodLikeRezObject"); 12013
12014 if (!World.Permissions.IsGod(m_host.OwnerID))
12015 NotImplemented("llGodLikeRezObject");
12016
12017 AssetBase rezAsset = World.AssetService.Get(inventory);
12018 if (rezAsset == null)
12019 {
12020 llSay(0, "Asset not found");
12021 return;
12022 }
12023
12024 SceneObjectGroup group = null;
12025
12026 try
12027 {
12028 string xmlData = Utils.BytesToString(rezAsset.Data);
12029 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12030 }
12031 catch
12032 {
12033 llSay(0, "Asset not found");
12034 return;
12035 }
12036
12037 if (group == null)
12038 {
12039 llSay(0, "Asset not found");
12040 return;
12041 }
12042
12043 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12044 group.RootPart.AttachOffset = group.AbsolutePosition;
12045
12046 group.ResetIDs();
12047
12048 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12049 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12050 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12051 group.ScheduleGroupForFullUpdate();
12052
12053 // objects rezzed with this method are die_at_edge by default.
12054 group.RootPart.SetDieAtEdge(true);
12055
12056 group.ResumeScripts();
12057
12058 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12059 "object_rez", new Object[] {
12060 new LSL_String(
12061 group.RootPart.UUID.ToString()) },
12062 new DetectParams[0]));
12063 }
12064
12065 public LSL_String llTransferLindenDollars(string destination, int amount)
12066 {
12067 UUID txn = UUID.Random();
12068
12069 Util.FireAndForget(delegate(object x)
12070 {
12071 int replycode = 0;
12072 string replydata = destination + "," + amount.ToString();
12073
12074 try
12075 {
12076 TaskInventoryItem item = GetSelfInventoryItem();
12077 if (item == null)
12078 {
12079 replydata = "SERVICE_ERROR";
12080 return;
12081 }
12082
12083 m_host.AddScriptLPS(1);
12084
12085 if (item.PermsGranter == UUID.Zero)
12086 {
12087 replydata = "MISSING_PERMISSION_DEBIT";
12088 return;
12089 }
12090
12091 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12092 {
12093 replydata = "MISSING_PERMISSION_DEBIT";
12094 return;
12095 }
12096
12097 UUID toID = new UUID();
12098
12099 if (!UUID.TryParse(destination, out toID))
12100 {
12101 replydata = "INVALID_AGENT";
12102 return;
12103 }
12104
12105 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12106
12107 if (money == null)
12108 {
12109 replydata = "TRANSFERS_DISABLED";
12110 return;
12111 }
12112
12113 bool result = money.ObjectGiveMoney(
12114 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12115
12116 if (result)
12117 {
12118 replycode = 1;
12119 return;
12120 }
12121
12122 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12123 }
12124 finally
12125 {
12126 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
12127 "transaction_result", new Object[] {
12128 new LSL_String(txn.ToString()),
12129 new LSL_Integer(replycode),
12130 new LSL_String(replydata) },
12131 new DetectParams[0]));
12132 }
12133 });
12134
12135 return txn.ToString();
10913 } 12136 }
10914 12137
10915 #endregion 12138 #endregion
12139
12140 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12141 {
12142 SceneObjectGroup group = m_host.ParentGroup;
12143
12144 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12145 return;
12146 if (group.IsAttachment)
12147 return;
12148
12149 if (frames.Data.Length > 0) // We are getting a new motion
12150 {
12151 if (group.RootPart.KeyframeMotion != null)
12152 group.RootPart.KeyframeMotion.Stop();
12153 group.RootPart.KeyframeMotion = null;
12154
12155 int idx = 0;
12156
12157 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12158 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12159
12160 while (idx < options.Data.Length)
12161 {
12162 int option = (int)options.GetLSLIntegerItem(idx++);
12163 int remain = options.Data.Length - idx;
12164
12165 switch (option)
12166 {
12167 case ScriptBaseClass.KFM_MODE:
12168 if (remain < 1)
12169 break;
12170 int modeval = (int)options.GetLSLIntegerItem(idx++);
12171 switch(modeval)
12172 {
12173 case ScriptBaseClass.KFM_FORWARD:
12174 mode = KeyframeMotion.PlayMode.Forward;
12175 break;
12176 case ScriptBaseClass.KFM_REVERSE:
12177 mode = KeyframeMotion.PlayMode.Reverse;
12178 break;
12179 case ScriptBaseClass.KFM_LOOP:
12180 mode = KeyframeMotion.PlayMode.Loop;
12181 break;
12182 case ScriptBaseClass.KFM_PING_PONG:
12183 mode = KeyframeMotion.PlayMode.PingPong;
12184 break;
12185 }
12186 break;
12187 case ScriptBaseClass.KFM_DATA:
12188 if (remain < 1)
12189 break;
12190 int dataval = (int)options.GetLSLIntegerItem(idx++);
12191 data = (KeyframeMotion.DataFormat)dataval;
12192 break;
12193 }
12194 }
12195
12196 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12197
12198 idx = 0;
12199
12200 int elemLength = 2;
12201 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12202 elemLength = 3;
12203
12204 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12205 while (idx < frames.Data.Length)
12206 {
12207 int remain = frames.Data.Length - idx;
12208
12209 if (remain < elemLength)
12210 break;
12211
12212 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12213 frame.Position = null;
12214 frame.Rotation = null;
12215
12216 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12217 {
12218 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12219 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12220 }
12221 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12222 {
12223 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12224 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12225 }
12226
12227 float tempf = (float)frames.GetLSLFloatItem(idx++);
12228 frame.TimeMS = (int)(tempf * 1000.0f);
12229
12230 keyframes.Add(frame);
12231 }
12232
12233 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12234 group.RootPart.KeyframeMotion.Start();
12235 }
12236 else
12237 {
12238 if (group.RootPart.KeyframeMotion == null)
12239 return;
12240
12241 if (options.Data.Length == 0)
12242 {
12243 group.RootPart.KeyframeMotion.Stop();
12244 return;
12245 }
12246
12247 int code = (int)options.GetLSLIntegerItem(0);
12248
12249 int idx = 0;
12250
12251 while (idx < options.Data.Length)
12252 {
12253 int option = (int)options.GetLSLIntegerItem(idx++);
12254 int remain = options.Data.Length - idx;
12255
12256 switch (option)
12257 {
12258 case ScriptBaseClass.KFM_COMMAND:
12259 int cmd = (int)options.GetLSLIntegerItem(idx++);
12260 switch (cmd)
12261 {
12262 case ScriptBaseClass.KFM_CMD_PLAY:
12263 group.RootPart.KeyframeMotion.Start();
12264 break;
12265 case ScriptBaseClass.KFM_CMD_STOP:
12266 group.RootPart.KeyframeMotion.Stop();
12267 break;
12268 case ScriptBaseClass.KFM_CMD_PAUSE:
12269 group.RootPart.KeyframeMotion.Pause();
12270 break;
12271 }
12272 break;
12273 }
12274 }
12275 }
12276 }
10916 } 12277 }
10917 12278
10918 public class NotecardCache 12279 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 0d4ea19..60568a8 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>
@@ -927,18 +936,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
927 if (target != null) 936 if (target != null)
928 { 937 {
929 UUID animID=UUID.Zero; 938 UUID animID=UUID.Zero;
930 lock (m_host.TaskInventory) 939 m_host.TaskInventory.LockItemsForRead(true);
940 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
931 { 941 {
932 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 942 if (inv.Value.Name == animation)
933 { 943 {
934 if (inv.Value.Name == animation) 944 if (inv.Value.Type == (int)AssetType.Animation)
935 { 945 animID = inv.Value.AssetID;
936 if (inv.Value.Type == (int)AssetType.Animation) 946 continue;
937 animID = inv.Value.AssetID;
938 continue;
939 }
940 } 947 }
941 } 948 }
949 m_host.TaskInventory.LockItemsForRead(false);
942 if (animID == UUID.Zero) 950 if (animID == UUID.Zero)
943 target.Animator.AddAnimation(animation, m_host.UUID); 951 target.Animator.AddAnimation(animation, m_host.UUID);
944 else 952 else
@@ -965,18 +973,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
965 if (target != null) 973 if (target != null)
966 { 974 {
967 UUID animID = UUID.Zero; 975 UUID animID = UUID.Zero;
968 lock (m_host.TaskInventory) 976 m_host.TaskInventory.LockItemsForRead(true);
977 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
969 { 978 {
970 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 979 if (inv.Value.Name == animation)
971 { 980 {
972 if (inv.Value.Name == animation) 981 if (inv.Value.Type == (int)AssetType.Animation)
973 { 982 animID = inv.Value.AssetID;
974 if (inv.Value.Type == (int)AssetType.Animation) 983 continue;
975 animID = inv.Value.AssetID;
976 continue;
977 }
978 } 984 }
979 } 985 }
986 m_host.TaskInventory.LockItemsForRead(false);
980 987
981 if (animID == UUID.Zero) 988 if (animID == UUID.Zero)
982 target.Animator.RemoveAnimation(animation); 989 target.Animator.RemoveAnimation(animation);
@@ -1797,6 +1804,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1797 1804
1798 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1805 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1799 { 1806 {
1807 m_host.TaskInventory.LockItemsForRead(true);
1800 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1808 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1801 { 1809 {
1802 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1810 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1804,6 +1812,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1804 assetID = item.AssetID; 1812 assetID = item.AssetID;
1805 } 1813 }
1806 } 1814 }
1815 m_host.TaskInventory.LockItemsForRead(false);
1807 } 1816 }
1808 1817
1809 if (assetID == UUID.Zero) 1818 if (assetID == UUID.Zero)
@@ -2271,7 +2280,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2271 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2280 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2272 m_host.AddScriptLPS(1); 2281 m_host.AddScriptLPS(1);
2273 2282
2274 return NpcCreate(firstname, lastname, position, notecard, false, false); 2283 return NpcCreate(firstname, lastname, position, notecard, true, false);
2275 } 2284 }
2276 2285
2277 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2286 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2282,24 +2291,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2282 return NpcCreate( 2291 return NpcCreate(
2283 firstname, lastname, position, notecard, 2292 firstname, lastname, position, notecard,
2284 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2293 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2285 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2294 false);
2295// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2286 } 2296 }
2287 2297
2288 private LSL_Key NpcCreate( 2298 private LSL_Key NpcCreate(
2289 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2299 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2290 { 2300 {
2301 if (!owned)
2302 OSSLError("Unowned NPCs are unsupported");
2303
2304 string groupTitle = String.Empty;
2305
2306 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2307 return new LSL_Key(UUID.Zero.ToString());
2308
2309 if (firstname != String.Empty || lastname != String.Empty)
2310 {
2311 if (firstname != "Shown outfit:")
2312 groupTitle = "- NPC -";
2313 }
2314
2291 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2315 INPCModule module = World.RequestModuleInterface<INPCModule>();
2292 if (module != null) 2316 if (module != null)
2293 { 2317 {
2294 AvatarAppearance appearance = null; 2318 AvatarAppearance appearance = null;
2295 2319
2296 UUID id; 2320// UUID id;
2297 if (UUID.TryParse(notecard, out id)) 2321// if (UUID.TryParse(notecard, out id))
2298 { 2322// {
2299 ScenePresence clonePresence = World.GetScenePresence(id); 2323// ScenePresence clonePresence = World.GetScenePresence(id);
2300 if (clonePresence != null) 2324// if (clonePresence != null)
2301 appearance = clonePresence.Appearance; 2325// appearance = clonePresence.Appearance;
2302 } 2326// }
2303 2327
2304 if (appearance == null) 2328 if (appearance == null)
2305 { 2329 {
@@ -2327,6 +2351,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2327 World, 2351 World,
2328 appearance); 2352 appearance);
2329 2353
2354 ScenePresence sp;
2355 if (World.TryGetScenePresence(x, out sp))
2356 {
2357 sp.Grouptitle = groupTitle;
2358 sp.SendAvatarDataToAllAgents();
2359 }
2330 return new LSL_Key(x.ToString()); 2360 return new LSL_Key(x.ToString());
2331 } 2361 }
2332 2362
@@ -2617,16 +2647,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2617 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2647 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2618 m_host.AddScriptLPS(1); 2648 m_host.AddScriptLPS(1);
2619 2649
2620 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2650 ManualResetEvent ev = new ManualResetEvent(false);
2621 if (module != null)
2622 {
2623 UUID npcId = new UUID(npc.m_string);
2624 2651
2625 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2652 Util.FireAndForget(delegate(object x) {
2626 return; 2653 try
2654 {
2655 INPCModule module = World.RequestModuleInterface<INPCModule>();
2656 if (module != null)
2657 {
2658 UUID npcId = new UUID(npc.m_string);
2627 2659
2628 module.DeleteNPC(npcId, World); 2660 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2629 } 2661 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2662 {
2663 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2664 return;
2665 }
2666
2667 module.DeleteNPC(npcId, World);
2668 }
2669 }
2670 finally
2671 {
2672 ev.Set();
2673 }
2674 });
2675 ev.WaitOne();
2630 } 2676 }
2631 2677
2632 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2678 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3160,4 +3206,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3160 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3206 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3161 } 3207 }
3162 } 3208 }
3163} \ No newline at end of file 3209}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3844753..19f3ce1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -319,7 +319,8 @@ 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.GetWorldRotation(); 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, rotate the sensor cone with the 326 // In attachments, rotate the sensor cone with the
@@ -333,7 +334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
333 // Position of a sensor in a child prim attached to an avatar 334 // Position of a sensor in a child prim attached to an avatar
334 // will be still wrong. 335 // will be still wrong.
335 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 336 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
336 q = avatar.Rotation * q; 337 fromRegionPos = avatar.AbsolutePosition;
338 q = avatar.Rotation;
337 } 339 }
338 340
339 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 341 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -463,7 +465,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
463 // Position of a sensor in a child prim attached to an avatar 465 // Position of a sensor in a child prim attached to an avatar
464 // will be still wrong. 466 // will be still wrong.
465 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 467 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
466 q = avatar.Rotation * q; 468 if (avatar == null)
469 return sensedEntities;
470 fromRegionPos = avatar.AbsolutePosition;
471 q = avatar.Rotation;
467 } 472 }
468 473
469 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 474 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
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 7a797ac..2ecc455 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -125,6 +125,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
125 LSL_Float llGetEnergy(); 125 LSL_Float llGetEnergy();
126 LSL_Vector llGetForce(); 126 LSL_Vector llGetForce();
127 LSL_Integer llGetFreeMemory(); 127 LSL_Integer llGetFreeMemory();
128 LSL_Integer llGetUsedMemory();
128 LSL_Integer llGetFreeURLs(); 129 LSL_Integer llGetFreeURLs();
129 LSL_Vector llGetGeometricCenter(); 130 LSL_Vector llGetGeometricCenter();
130 LSL_Float llGetGMTclock(); 131 LSL_Float llGetGMTclock();
@@ -148,6 +149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
148 LSL_Vector llGetLocalPos(); 149 LSL_Vector llGetLocalPos();
149 LSL_Rotation llGetLocalRot(); 150 LSL_Rotation llGetLocalRot();
150 LSL_Float llGetMass(); 151 LSL_Float llGetMass();
152 LSL_Float llGetMassMKS();
151 LSL_Integer llGetMemoryLimit(); 153 LSL_Integer llGetMemoryLimit();
152 void llGetNextEmail(string address, string subject); 154 void llGetNextEmail(string address, string subject);
153 LSL_String llGetNotecardLine(string name, int line); 155 LSL_String llGetNotecardLine(string name, int line);
@@ -201,12 +203,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
201 LSL_String llGetTimestamp(); 203 LSL_String llGetTimestamp();
202 LSL_Vector llGetTorque(); 204 LSL_Vector llGetTorque();
203 LSL_Integer llGetUnixTime(); 205 LSL_Integer llGetUnixTime();
204 LSL_Integer llGetUsedMemory();
205 LSL_Vector llGetVel(); 206 LSL_Vector llGetVel();
206 LSL_Float llGetWallclock(); 207 LSL_Float llGetWallclock();
207 void llGiveInventory(string destination, string inventory); 208 void llGiveInventory(string destination, string inventory);
208 void llGiveInventoryList(string destination, string category, LSL_List inventory); 209 void llGiveInventoryList(string destination, string category, LSL_List inventory);
209 LSL_Integer llGiveMoney(string destination, int amount); 210 LSL_Integer llGiveMoney(string destination, int amount);
211 LSL_String llTransferLindenDollars(string destination, int amount);
210 void llGodLikeRezObject(string inventory, LSL_Vector pos); 212 void llGodLikeRezObject(string inventory, LSL_Vector pos);
211 LSL_Float llGround(LSL_Vector offset); 213 LSL_Float llGround(LSL_Vector offset);
212 LSL_Vector llGroundContour(LSL_Vector offset); 214 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -354,6 +356,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
354 void llSetParcelMusicURL(string url); 356 void llSetParcelMusicURL(string url);
355 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 357 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
356 void llSetPos(LSL_Vector pos); 358 void llSetPos(LSL_Vector pos);
359 LSL_Integer llSetRegionPos(LSL_Vector pos);
357 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 360 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
358 void llSetPrimitiveParams(LSL_List rules); 361 void llSetPrimitiveParams(LSL_List rules);
359 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 362 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -402,6 +405,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
402 void llTargetOmega(LSL_Vector axis, double spinrate, double gain); 405 void llTargetOmega(LSL_Vector axis, double spinrate, double gain);
403 void llTargetRemove(int number); 406 void llTargetRemove(int number);
404 void llTeleportAgentHome(string agent); 407 void llTeleportAgentHome(string agent);
408 void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt);
405 void llTextBox(string avatar, string message, int chat_channel); 409 void llTextBox(string avatar, string message, int chat_channel);
406 LSL_String llToLower(string source); 410 LSL_String llToLower(string source);
407 LSL_String llToUpper(string source); 411 LSL_String llToUpper(string source);
@@ -418,9 +422,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
418 LSL_Vector llWind(LSL_Vector offset); 422 LSL_Vector llWind(LSL_Vector offset);
419 LSL_String llXorBase64Strings(string str1, string str2); 423 LSL_String llXorBase64Strings(string str1, string str2);
420 LSL_String llXorBase64StringsCorrect(string str1, string str2); 424 LSL_String llXorBase64StringsCorrect(string str1, string str2);
421 void print(string str); 425 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
426 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
422 427
423 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 428 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
424 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 429 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
430 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
425 } 431 }
426} 432}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index e92518d..7382495 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 80fa530..8db4006 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();
@@ -469,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
469 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
470 } 477 }
471 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
472 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
473 { 485 {
474 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -574,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
574 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
575 } 587 }
576 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
577 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
578 { 595 {
579 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -839,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
839 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
840 } 857 }
841 858
842 public LSL_Integer llGetUsedMemory()
843 {
844 return m_LSL_Functions.llGetUsedMemory();
845 }
846
847 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
848 { 860 {
849 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -869,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
869 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
870 } 882 }
871 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
872 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
873 { 890 {
874 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1593,6 +1610,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1593 m_LSL_Functions.llSetPos(pos); 1610 m_LSL_Functions.llSetPos(pos);
1594 } 1611 }
1595 1612
1613 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1614 {
1615 return m_LSL_Functions.llSetRegionPos(pos);
1616 }
1617
1596 public void llSetPrimitiveParams(LSL_List rules) 1618 public void llSetPrimitiveParams(LSL_List rules)
1597 { 1619 {
1598 m_LSL_Functions.llSetPrimitiveParams(rules); 1620 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1828,6 +1850,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1828 m_LSL_Functions.llTargetRemove(number); 1850 m_LSL_Functions.llTargetRemove(number);
1829 } 1851 }
1830 1852
1853 public void llTeleportAgent(string agent, string simname, LSL_Vector pos, LSL_Vector lookAt)
1854 {
1855 m_LSL_Functions.llTeleportAgent(agent, simname, pos, lookAt);
1856 }
1857
1831 public void llTeleportAgentHome(string agent) 1858 public void llTeleportAgentHome(string agent)
1832 { 1859 {
1833 m_LSL_Functions.llTeleportAgentHome(agent); 1860 m_LSL_Functions.llTeleportAgentHome(agent);
@@ -1943,9 +1970,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1943 return m_LSL_Functions.llClearLinkMedia(link, face); 1970 return m_LSL_Functions.llClearLinkMedia(link, face);
1944 } 1971 }
1945 1972
1946 public void print(string str) 1973 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1974 {
1975 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1976 }
1977
1978 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1979 {
1980 m_LSL_Functions.llSetKeyframedMotion(frames, options);
1981 }
1982
1983 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1947 { 1984 {
1948 m_LSL_Functions.print(str); 1985 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1949 } 1986 }
1950 } 1987 }
1951} 1988}
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 {