aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api')
-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.cs2810
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs12
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs4
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs3
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
15 files changed, 2281 insertions, 929 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index ee32755..61e4934 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -248,6 +248,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
248 248
249 } 249 }
250 250
251 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
252 {
253 // Remove a specific script
254
255 // Remove dataserver events
256 m_Dataserver[engine].RemoveEvents(localID, itemID);
257
258 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
259 if (comms != null)
260 comms.DeleteListener(itemID);
261
262 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
263 xmlrpc.DeleteChannels(itemID);
264 xmlrpc.CancelSRDRequests(itemID);
265
266 // Remove Sensors
267 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
268
269 }
270
251 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 271 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
252 { 272 {
253 List<Object> data = new List<Object>(); 273 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..489c1c6
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,118 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal uint m_localID;
63 internal UUID m_itemID;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_localID = localID;
71 m_itemID = itemID;
72
73 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
74 m_CMFunctionsEnabled = true;
75 }
76
77 public override Object InitializeLifetimeService()
78 {
79 ILease lease = (ILease)base.InitializeLifetimeService();
80
81 if (lease.CurrentState == LeaseState.Initial)
82 {
83 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
84 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
85 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
86 }
87 return lease;
88 }
89
90 public Scene World
91 {
92 get { return m_ScriptEngine.World; }
93 }
94
95 public string cmDetectedCountry(int number)
96 {
97 m_host.AddScriptLPS(1);
98 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, number);
99 if (detectedParams == null)
100 return String.Empty;
101 return detectedParams.Country;
102 }
103
104 public string cmGetAgentCountry(LSL_Key key)
105 {
106 if (!World.Permissions.IsGod(m_host.OwnerID))
107 return String.Empty;
108
109 UUID uuid;
110
111 if (!UUID.TryParse(key, out uuid))
112 return String.Empty;
113
114 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
115 return account.UserCountry;
116 }
117 }
118}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 443e7a5..3bc8750 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -99,16 +103,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
99 protected int m_notecardLineReadCharsMax = 255; 103 protected int m_notecardLineReadCharsMax = 255;
100 protected int m_scriptConsoleChannel = 0; 104 protected int m_scriptConsoleChannel = 0;
101 protected bool m_scriptConsoleChannelEnabled = false; 105 protected bool m_scriptConsoleChannelEnabled = false;
106 protected bool m_debuggerSafe = false;
102 protected IUrlModule m_UrlModule = null; 107 protected IUrlModule m_UrlModule = null;
103 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = 108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
104 new Dictionary<UUID, UserInfoCacheEntry>(); 109 new Dictionary<UUID, UserInfoCacheEntry>();
105 110
111 protected Timer m_ShoutSayTimer;
112 protected int m_SayShoutCount = 0;
113
106 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 114 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
107 { 115 {
116 m_ShoutSayTimer = new Timer(1000);
117 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
118 m_ShoutSayTimer.AutoReset = true;
119 m_ShoutSayTimer.Start();
120
108 m_ScriptEngine = ScriptEngine; 121 m_ScriptEngine = ScriptEngine;
109 m_host = host; 122 m_host = host;
110 m_localID = localID; 123 m_localID = localID;
111 m_itemID = itemID; 124 m_itemID = itemID;
125 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
112 126
113 m_ScriptDelayFactor = 127 m_ScriptDelayFactor =
114 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f); 128 m_ScriptEngine.Config.GetFloat("ScriptDelayFactor", 1.0f);
@@ -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)
@@ -275,40 +344,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
275 protected UUID InventorySelf() 344 protected UUID InventorySelf()
276 { 345 {
277 UUID invItemID = new UUID(); 346 UUID invItemID = new UUID();
278 347 bool unlock = false;
279 lock (m_host.TaskInventory) 348 if (!m_host.TaskInventory.IsReadLockedByMe())
280 { 349 {
281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 350 m_host.TaskInventory.LockItemsForRead(true);
351 unlock = true;
352 }
353 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
354 {
355 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID)
282 { 356 {
283 if (inv.Value.Type == 10 && inv.Value.ItemID == m_itemID) 357 invItemID = inv.Key;
284 { 358 break;
285 invItemID = inv.Key;
286 break;
287 }
288 } 359 }
289 } 360 }
290 361 if (unlock)
362 {
363 m_host.TaskInventory.LockItemsForRead(false);
364 }
291 return invItemID; 365 return invItemID;
292 } 366 }
293 367
294 protected UUID InventoryKey(string name, int type) 368 protected UUID InventoryKey(string name, int type)
295 { 369 {
296 m_host.AddScriptLPS(1); 370 m_host.AddScriptLPS(1);
297 371 m_host.TaskInventory.LockItemsForRead(true);
298 lock (m_host.TaskInventory) 372
373 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
299 { 374 {
300 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 375 if (inv.Value.Name == name)
301 { 376 {
302 if (inv.Value.Name == name) 377 m_host.TaskInventory.LockItemsForRead(false);
378
379 if (inv.Value.Type != type)
303 { 380 {
304 if (inv.Value.Type != type) 381 return UUID.Zero;
305 return UUID.Zero;
306
307 return inv.Value.AssetID;
308 } 382 }
383
384 return inv.Value.AssetID;
309 } 385 }
310 } 386 }
311 387
388 m_host.TaskInventory.LockItemsForRead(false);
312 return UUID.Zero; 389 return UUID.Zero;
313 } 390 }
314 391
@@ -316,17 +393,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
316 { 393 {
317 m_host.AddScriptLPS(1); 394 m_host.AddScriptLPS(1);
318 395
319 lock (m_host.TaskInventory) 396
397 m_host.TaskInventory.LockItemsForRead(true);
398
399 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
320 { 400 {
321 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 401 if (inv.Value.Name == name)
322 { 402 {
323 if (inv.Value.Name == name) 403 m_host.TaskInventory.LockItemsForRead(false);
324 { 404 return inv.Value.AssetID;
325 return inv.Value.AssetID;
326 }
327 } 405 }
328 } 406 }
329 407
408 m_host.TaskInventory.LockItemsForRead(false);
409
410
330 return UUID.Zero; 411 return UUID.Zero;
331 } 412 }
332 413
@@ -468,26 +549,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 549
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 550 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 551
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 552 // Utility function for llRot2Euler
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees).
473 553
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 554 // normalize an angle between -PI and PI (-180 to +180 degrees)
555 protected double NormalizeAngle(double angle)
556 {
557 if (angle > -Math.PI && angle < Math.PI)
558 return angle;
559
560 int numPis = (int)(Math.PI / angle);
561 double remainder = angle - Math.PI * numPis;
562 if (numPis % 2 == 1)
563 return Math.PI - angle;
564 return remainder;
565 }
566
567 public LSL_Vector llRot2Euler(LSL_Rotation q1)
475 { 568 {
476 m_host.AddScriptLPS(1); 569 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 570 LSL_Vector eul = new LSL_Vector();
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 571
479 double m = (t.x + t.y + t.z + t.s); 572 double sqw = q1.s*q1.s;
480 if (m == 0) return new LSL_Vector(); 573 double sqx = q1.x*q1.x;
481 double n = 2 * (r.y * r.s + r.x * r.z); 574 double sqy = q1.z*q1.z;
482 double p = m * m - n * n; 575 double sqz = q1.y*q1.y;
483 if (p > 0) 576 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 577 double test = q1.x*q1.z + q1.y*q1.s;
485 Math.Atan2(n, Math.Sqrt(p)), 578 if (test > 0.4999*unit) { // singularity at north pole
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 579 eul.z = 2 * Math.Atan2(q1.x,q1.s);
487 else if (n > 0) 580 eul.y = Math.PI/2;
488 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 581 eul.x = 0;
489 else 582 return eul;
490 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 583 }
584 if (test < -0.4999*unit) { // singularity at south pole
585 eul.z = -2 * Math.Atan2(q1.x,q1.s);
586 eul.y = -Math.PI/2;
587 eul.x = 0;
588 return eul;
589 }
590 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
591 eul.y = Math.Asin(2*test/unit);
592 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
593 return eul;
491 } 594 }
492 595
493 /* From wiki: 596 /* From wiki:
@@ -689,77 +792,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
689 { 792 {
690 //A and B should both be normalized 793 //A and B should both be normalized
691 m_host.AddScriptLPS(1); 794 m_host.AddScriptLPS(1);
692 LSL_Rotation rotBetween; 795 /* 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, 796 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
694 // continue calculation. 797
695 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 798 double dotProduct = LSL_Vector.Dot(a, b);
799 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
800 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
801 double angle = Math.Acos(dotProduct / magProduct);
802 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
803 double s = Math.Sin(angle / 2);
804
805 double x = axis.x * s;
806 double y = axis.y * s;
807 double z = axis.z * s;
808 double w = Math.Cos(angle / 2);
809
810 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
811 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
812
813 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
814 */
815
816 // This method mimics the 180 errors found in SL
817 // See www.euclideanspace.com... angleBetween
818 LSL_Vector vec_a = a;
819 LSL_Vector vec_b = b;
820
821 // Eliminate zero length
822 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
823 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
824 if (vec_a_mag < 0.00001 ||
825 vec_b_mag < 0.00001)
696 { 826 {
697 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 827 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
698 } 828 }
699 else 829
830 // Normalize
831 vec_a = llVecNorm(vec_a);
832 vec_b = llVecNorm(vec_b);
833
834 // Calculate axis and rotation angle
835 LSL_Vector axis = vec_a % vec_b;
836 LSL_Float cos_theta = vec_a * vec_b;
837
838 // Check if parallel
839 if (cos_theta > 0.99999)
700 { 840 {
701 a = LSL_Vector.Norm(a); 841 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
702 b = LSL_Vector.Norm(b); 842 }
703 double dotProduct = LSL_Vector.Dot(a, b); 843
704 // There are two degenerate cases possible. These are for vectors 180 or 844 // Check if anti-parallel
705 // 0 degrees apart. These have to be detected and handled individually. 845 else if (cos_theta < -0.99999)
706 // 846 {
707 // Check for vectors 180 degrees apart. 847 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. 848 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
709 if (dotProduct < -0.9999999f) 849 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
710 { 850 }
711 // First assume X axis is orthogonal to the vectors. 851 else // other rotation
712 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 852 {
713 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 853 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 854 axis = llVecNorm(axis);
715 // a rotation in an undesired direction. 855 double x, y, z, s, t;
716 if (LSL_Vector.Mag(orthoVector) > 0.0001) 856 s = Math.Cos(theta);
717 { 857 t = Math.Sin(theta);
718 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 858 x = axis.x * t;
719 } 859 y = axis.y * t;
720 // If the magnitude of the vector was near zero, then assume the X axis is not 860 z = axis.z * t;
721 // orthogonal and use the Z axis instead. 861 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 } 862 }
760 return rotBetween;
761 } 863 }
762 864
763 public void llWhisper(int channelID, string text) 865 public void llWhisper(int channelID, string text)
764 { 866 {
765 m_host.AddScriptLPS(1); 867 m_host.AddScriptLPS(1);
@@ -779,6 +881,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
779 { 881 {
780 m_host.AddScriptLPS(1); 882 m_host.AddScriptLPS(1);
781 883
884 if (channelID == 0)
885 m_SayShoutCount++;
886
887 if (m_SayShoutCount >= 11)
888 ScriptSleep(2000);
889
782 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 890 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
783 { 891 {
784 Console.WriteLine(text); 892 Console.WriteLine(text);
@@ -801,6 +909,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 { 909 {
802 m_host.AddScriptLPS(1); 910 m_host.AddScriptLPS(1);
803 911
912 if (channelID == 0)
913 m_SayShoutCount++;
914
915 if (m_SayShoutCount >= 11)
916 ScriptSleep(2000);
917
804 if (text.Length > 1023) 918 if (text.Length > 1023)
805 text = text.Substring(0, 1023); 919 text = text.Substring(0, 1023);
806 920
@@ -1101,10 +1215,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1101 return detectedParams.TouchUV; 1215 return detectedParams.TouchUV;
1102 } 1216 }
1103 1217
1218 [DebuggerNonUserCode]
1104 public virtual void llDie() 1219 public virtual void llDie()
1105 { 1220 {
1106 m_host.AddScriptLPS(1); 1221 m_host.AddScriptLPS(1);
1107 throw new SelfDeleteException(); 1222 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1108 } 1223 }
1109 1224
1110 public LSL_Float llGround(LSL_Vector offset) 1225 public LSL_Float llGround(LSL_Vector offset)
@@ -1177,6 +1292,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 1292
1178 public void llSetStatus(int status, int value) 1293 public void llSetStatus(int status, int value)
1179 { 1294 {
1295 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1296 return;
1180 m_host.AddScriptLPS(1); 1297 m_host.AddScriptLPS(1);
1181 1298
1182 int statusrotationaxis = 0; 1299 int statusrotationaxis = 0;
@@ -1406,6 +1523,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1406 { 1523 {
1407 m_host.AddScriptLPS(1); 1524 m_host.AddScriptLPS(1);
1408 1525
1526 SetColor(m_host, color, face);
1527 }
1528
1529 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1530 {
1531 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1532 return;
1533
1534 Primitive.TextureEntry tex = part.Shape.Textures;
1535 Color4 texcolor;
1536 if (face >= 0 && face < GetNumberOfSides(part))
1537 {
1538 texcolor = tex.CreateFace((uint)face).RGBA;
1539 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1540 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1541 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1542 tex.FaceTextures[face].RGBA = texcolor;
1543 part.UpdateTextureEntry(tex.GetBytes());
1544 return;
1545 }
1546 else if (face == ScriptBaseClass.ALL_SIDES)
1547 {
1548 for (uint i = 0; i < GetNumberOfSides(part); i++)
1549 {
1550 if (tex.FaceTextures[i] != null)
1551 {
1552 texcolor = tex.FaceTextures[i].RGBA;
1553 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1554 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1555 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1556 tex.FaceTextures[i].RGBA = texcolor;
1557 }
1558 texcolor = tex.DefaultTexture.RGBA;
1559 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1560 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1561 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1562 tex.DefaultTexture.RGBA = texcolor;
1563 }
1564 part.UpdateTextureEntry(tex.GetBytes());
1565 return;
1566 }
1567
1409 if (face == ScriptBaseClass.ALL_SIDES) 1568 if (face == ScriptBaseClass.ALL_SIDES)
1410 face = SceneObjectPart.ALL_SIDES; 1569 face = SceneObjectPart.ALL_SIDES;
1411 1570
@@ -1414,6 +1573,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1414 1573
1415 public void SetTexGen(SceneObjectPart part, int face,int style) 1574 public void SetTexGen(SceneObjectPart part, int face,int style)
1416 { 1575 {
1576 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1577 return;
1578
1417 Primitive.TextureEntry tex = part.Shape.Textures; 1579 Primitive.TextureEntry tex = part.Shape.Textures;
1418 MappingType textype; 1580 MappingType textype;
1419 textype = MappingType.Default; 1581 textype = MappingType.Default;
@@ -1444,6 +1606,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1444 1606
1445 public void SetGlow(SceneObjectPart part, int face, float glow) 1607 public void SetGlow(SceneObjectPart part, int face, float glow)
1446 { 1608 {
1609 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1610 return;
1611
1447 Primitive.TextureEntry tex = part.Shape.Textures; 1612 Primitive.TextureEntry tex = part.Shape.Textures;
1448 if (face >= 0 && face < GetNumberOfSides(part)) 1613 if (face >= 0 && face < GetNumberOfSides(part))
1449 { 1614 {
@@ -1469,6 +1634,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1469 1634
1470 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1635 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1471 { 1636 {
1637 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1638 return;
1472 1639
1473 Shininess sval = new Shininess(); 1640 Shininess sval = new Shininess();
1474 1641
@@ -1519,6 +1686,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1519 1686
1520 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1687 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1521 { 1688 {
1689 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1690 return;
1691
1522 Primitive.TextureEntry tex = part.Shape.Textures; 1692 Primitive.TextureEntry tex = part.Shape.Textures;
1523 if (face >= 0 && face < GetNumberOfSides(part)) 1693 if (face >= 0 && face < GetNumberOfSides(part))
1524 { 1694 {
@@ -1579,13 +1749,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 m_host.AddScriptLPS(1); 1749 m_host.AddScriptLPS(1);
1580 1750
1581 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1751 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1582 1752 if (parts.Count > 0)
1583 foreach (SceneObjectPart part in parts) 1753 {
1584 SetAlpha(part, alpha, face); 1754 try
1755 {
1756 parts[0].ParentGroup.areUpdatesSuspended = true;
1757 foreach (SceneObjectPart part in parts)
1758 SetAlpha(part, alpha, face);
1759 }
1760 finally
1761 {
1762 parts[0].ParentGroup.areUpdatesSuspended = false;
1763 }
1764 }
1585 } 1765 }
1586 1766
1587 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1767 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1588 { 1768 {
1769 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1770 return;
1771
1589 Primitive.TextureEntry tex = part.Shape.Textures; 1772 Primitive.TextureEntry tex = part.Shape.Textures;
1590 Color4 texcolor; 1773 Color4 texcolor;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1774 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1638,7 +1821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1638 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1821 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1639 float wind, float tension, LSL_Vector Force) 1822 float wind, float tension, LSL_Vector Force)
1640 { 1823 {
1641 if (part == null) 1824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1642 return; 1825 return;
1643 1826
1644 if (flexi) 1827 if (flexi)
@@ -1672,7 +1855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1672 /// <param name="falloff"></param> 1855 /// <param name="falloff"></param>
1673 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1856 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1674 { 1857 {
1675 if (part == null) 1858 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1676 return; 1859 return;
1677 1860
1678 if (light) 1861 if (light)
@@ -1749,15 +1932,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1749 m_host.AddScriptLPS(1); 1932 m_host.AddScriptLPS(1);
1750 1933
1751 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1934 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1752 1935 if (parts.Count > 0)
1753 foreach (SceneObjectPart part in parts) 1936 {
1754 SetTexture(part, texture, face); 1937 try
1755 1938 {
1939 parts[0].ParentGroup.areUpdatesSuspended = true;
1940 foreach (SceneObjectPart part in parts)
1941 SetTexture(part, texture, face);
1942 }
1943 finally
1944 {
1945 parts[0].ParentGroup.areUpdatesSuspended = false;
1946 }
1947 }
1756 ScriptSleep(200); 1948 ScriptSleep(200);
1757 } 1949 }
1758 1950
1759 protected void SetTexture(SceneObjectPart part, string texture, int face) 1951 protected void SetTexture(SceneObjectPart part, string texture, int face)
1760 { 1952 {
1953 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1954 return;
1955
1761 UUID textureID = new UUID(); 1956 UUID textureID = new UUID();
1762 1957
1763 textureID = InventoryKey(texture, (int)AssetType.Texture); 1958 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1802,6 +1997,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1802 1997
1803 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1998 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1804 { 1999 {
2000 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2001 return;
2002
1805 Primitive.TextureEntry tex = part.Shape.Textures; 2003 Primitive.TextureEntry tex = part.Shape.Textures;
1806 if (face >= 0 && face < GetNumberOfSides(part)) 2004 if (face >= 0 && face < GetNumberOfSides(part))
1807 { 2005 {
@@ -1838,6 +2036,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1838 2036
1839 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2037 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1840 { 2038 {
2039 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2040 return;
2041
1841 Primitive.TextureEntry tex = part.Shape.Textures; 2042 Primitive.TextureEntry tex = part.Shape.Textures;
1842 if (face >= 0 && face < GetNumberOfSides(part)) 2043 if (face >= 0 && face < GetNumberOfSides(part))
1843 { 2044 {
@@ -1874,6 +2075,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 2075
1875 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2076 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1876 { 2077 {
2078 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2079 return;
2080
1877 Primitive.TextureEntry tex = part.Shape.Textures; 2081 Primitive.TextureEntry tex = part.Shape.Textures;
1878 if (face >= 0 && face < GetNumberOfSides(part)) 2082 if (face >= 0 && face < GetNumberOfSides(part))
1879 { 2083 {
@@ -1980,24 +2184,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1980 2184
1981 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2185 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1982 { 2186 {
1983 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2187 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1984 LSL_Vector currentPos = GetPartLocalPos(part); 2188 return;
1985 2189
1986 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2190 LSL_Vector currentPos = GetPartLocalPos(part);
1987 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2191 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1988 2192
1989 if (part.ParentGroup.RootPart == part) 2193 if (part.ParentGroup.RootPart == part)
1990 { 2194 {
1991 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1992 targetPos.z = ground;
1993 SceneObjectGroup parent = part.ParentGroup; 2195 SceneObjectGroup parent = part.ParentGroup;
1994 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2196 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1995 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1996 } 2197 }
1997 else 2198 else
1998 { 2199 {
1999 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2200 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
2000 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
2001 SceneObjectGroup parent = part.ParentGroup; 2201 SceneObjectGroup parent = part.ParentGroup;
2002 parent.HasGroupChanged = true; 2202 parent.HasGroupChanged = true;
2003 parent.ScheduleGroupForTerseUpdate(); 2203 parent.ScheduleGroupForTerseUpdate();
@@ -2048,9 +2248,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2048 m_host.AddScriptLPS(1); 2248 m_host.AddScriptLPS(1);
2049 2249
2050 // try to let this work as in SL... 2250 // try to let this work as in SL...
2051 if (m_host.ParentID == 0) 2251 if (m_host.LinkNum < 2)
2052 { 2252 {
2053 // special case: If we are root, rotate complete SOG to new rotation 2253 // Special case: If we are root, rotate complete SOG to new
2254 // rotation.
2255 // We are root if the link number is 0 (single prim) or 1
2256 // (root prim). ParentID may be nonzero in attachments and
2257 // using it would cause attachments and HUDs to rotate
2258 // to the wrong positions.
2054 SetRot(m_host, Rot2Quaternion(rot)); 2259 SetRot(m_host, Rot2Quaternion(rot));
2055 } 2260 }
2056 else 2261 else
@@ -2075,6 +2280,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2075 2280
2076 protected void SetRot(SceneObjectPart part, Quaternion rot) 2281 protected void SetRot(SceneObjectPart part, Quaternion rot)
2077 { 2282 {
2283 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2284 return;
2285
2078 part.UpdateRotation(rot); 2286 part.UpdateRotation(rot);
2079 // Update rotation does not move the object in the physics scene if it's a linkset. 2287 // Update rotation does not move the object in the physics scene if it's a linkset.
2080 2288
@@ -2698,12 +2906,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2698 2906
2699 m_host.AddScriptLPS(1); 2907 m_host.AddScriptLPS(1);
2700 2908
2909 m_host.TaskInventory.LockItemsForRead(true);
2701 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2910 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2702 2911 m_host.TaskInventory.LockItemsForRead(false);
2703 lock (m_host.TaskInventory)
2704 {
2705 item = m_host.TaskInventory[invItemID];
2706 }
2707 2912
2708 if (item.PermsGranter == UUID.Zero) 2913 if (item.PermsGranter == UUID.Zero)
2709 return 0; 2914 return 0;
@@ -2778,6 +2983,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2778 if (dist > m_ScriptDistanceFactor * 10.0f) 2983 if (dist > m_ScriptDistanceFactor * 10.0f)
2779 return; 2984 return;
2780 2985
2986 //Clone is thread-safe
2781 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2987 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2782 2988
2783 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2989 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2838,6 +3044,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2838 3044
2839 public void llLookAt(LSL_Vector target, double strength, double damping) 3045 public void llLookAt(LSL_Vector target, double strength, double damping)
2840 { 3046 {
3047 /*
2841 m_host.AddScriptLPS(1); 3048 m_host.AddScriptLPS(1);
2842 // Determine where we are looking from 3049 // Determine where we are looking from
2843 LSL_Vector from = llGetPos(); 3050 LSL_Vector from = llGetPos();
@@ -2857,10 +3064,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2857 // the angles of rotation in radians into rotation value 3064 // the angles of rotation in radians into rotation value
2858 3065
2859 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3066 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2860 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3067
2861 m_host.startLookAt(rotation, (float)damping, (float)strength); 3068 // This would only work if your physics system contains an APID controller:
3069 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3070 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3071
2862 // Orient the object to the angle calculated 3072 // Orient the object to the angle calculated
2863 //llSetRot(rot); 3073 llSetRot(rot);
3074 */
3075
3076 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3077 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3078 // http://bugs.meta7.com/view.php?id=28
3079 // - Tom
3080
3081 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3082 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3083 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3084 */
3085 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3086 {
3087 // Part is non-phys, convert this to a llSetRot()
3088 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3089 Vector3 dir = tgt - m_host.GroupPosition;
3090 dir.Normalize();
3091 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3092 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3093 float terot = (float)Math.Atan2(-dir.Z, txy);
3094 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3095 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3096 LSL_Types.Quaternion spin = llEuler2Rot(az);
3097 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3098 llSetRot(rot);
3099 }
3100 else
3101 {
3102 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3103 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3104 m_host.RotLookAt(q, (float)strength, (float)damping);
3105 }
3106
3107 }
3108
3109 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3110 {
3111 m_host.AddScriptLPS(1);
3112// NotImplemented("llRotLookAt");
3113 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3114
2864 } 3115 }
2865 3116
2866 public void llStopLookAt() 3117 public void llStopLookAt()
@@ -2909,13 +3160,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2909 { 3160 {
2910 TaskInventoryItem item; 3161 TaskInventoryItem item;
2911 3162
2912 lock (m_host.TaskInventory) 3163 m_host.TaskInventory.LockItemsForRead(true);
3164 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2913 { 3165 {
2914 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3166 m_host.TaskInventory.LockItemsForRead(false);
2915 return; 3167 return;
2916 else 3168 }
2917 item = m_host.TaskInventory[InventorySelf()]; 3169 else
3170 {
3171 item = m_host.TaskInventory[InventorySelf()];
2918 } 3172 }
3173 m_host.TaskInventory.LockItemsForRead(false);
2919 3174
2920 if (item.PermsGranter != UUID.Zero) 3175 if (item.PermsGranter != UUID.Zero)
2921 { 3176 {
@@ -2937,13 +3192,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2937 { 3192 {
2938 TaskInventoryItem item; 3193 TaskInventoryItem item;
2939 3194
3195 m_host.TaskInventory.LockItemsForRead(true);
2940 lock (m_host.TaskInventory) 3196 lock (m_host.TaskInventory)
2941 { 3197 {
3198
2942 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3199 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3200 {
3201 m_host.TaskInventory.LockItemsForRead(false);
2943 return; 3202 return;
3203 }
2944 else 3204 else
3205 {
2945 item = m_host.TaskInventory[InventorySelf()]; 3206 item = m_host.TaskInventory[InventorySelf()];
3207 }
2946 } 3208 }
3209 m_host.TaskInventory.LockItemsForRead(false);
2947 3210
2948 m_host.AddScriptLPS(1); 3211 m_host.AddScriptLPS(1);
2949 3212
@@ -2975,19 +3238,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2975 { 3238 {
2976 m_host.AddScriptLPS(1); 3239 m_host.AddScriptLPS(1);
2977 3240
2978// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2979// return;
2980
2981 TaskInventoryItem item; 3241 TaskInventoryItem item;
2982 3242
2983 lock (m_host.TaskInventory) 3243 m_host.TaskInventory.LockItemsForRead(true);
3244
3245 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2984 { 3246 {
2985 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3247 m_host.TaskInventory.LockItemsForRead(false);
2986 return; 3248 return;
2987 else 3249 }
2988 item = m_host.TaskInventory[InventorySelf()]; 3250 else
3251 {
3252 item = m_host.TaskInventory[InventorySelf()];
2989 } 3253 }
2990 3254
3255 m_host.TaskInventory.LockItemsForRead(false);
3256
2991 if (item.PermsGranter != m_host.OwnerID) 3257 if (item.PermsGranter != m_host.OwnerID)
2992 return; 3258 return;
2993 3259
@@ -3012,13 +3278,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3012 3278
3013 TaskInventoryItem item; 3279 TaskInventoryItem item;
3014 3280
3015 lock (m_host.TaskInventory) 3281 m_host.TaskInventory.LockItemsForRead(true);
3282
3283 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3016 { 3284 {
3017 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3285 m_host.TaskInventory.LockItemsForRead(false);
3018 return; 3286 return;
3019 else
3020 item = m_host.TaskInventory[InventorySelf()];
3021 } 3287 }
3288 else
3289 {
3290 item = m_host.TaskInventory[InventorySelf()];
3291 }
3292 m_host.TaskInventory.LockItemsForRead(false);
3293
3022 3294
3023 if (item.PermsGranter != m_host.OwnerID) 3295 if (item.PermsGranter != m_host.OwnerID)
3024 return; 3296 return;
@@ -3065,6 +3337,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3065 3337
3066 public void llInstantMessage(string user, string message) 3338 public void llInstantMessage(string user, string message)
3067 { 3339 {
3340 UUID result;
3341 if (!UUID.TryParse(user, out result))
3342 {
3343 ShoutError("An invalid key was passed to llInstantMessage");
3344 ScriptSleep(2000);
3345 return;
3346 }
3347
3348
3068 m_host.AddScriptLPS(1); 3349 m_host.AddScriptLPS(1);
3069 3350
3070 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3351 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3079,14 +3360,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3079 UUID friendTransactionID = UUID.Random(); 3360 UUID friendTransactionID = UUID.Random();
3080 3361
3081 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3362 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3082 3363
3083 GridInstantMessage msg = new GridInstantMessage(); 3364 GridInstantMessage msg = new GridInstantMessage();
3084 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3365 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3085 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3366 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3086 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3367 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3087// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3368// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3088// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3369// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3089 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3370// DateTime dt = DateTime.UtcNow;
3371//
3372// // Ticks from UtcNow, but make it look like local. Evil, huh?
3373// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3374//
3375// try
3376// {
3377// // Convert that to the PST timezone
3378// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3379// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3380// }
3381// catch
3382// {
3383// // No logging here, as it could be VERY spammy
3384// }
3385//
3386// // And make it look local again to fool the unix time util
3387// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3388
3389 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3390
3090 //if (client != null) 3391 //if (client != null)
3091 //{ 3392 //{
3092 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3393 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3100,12 +3401,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3100 msg.message = message.Substring(0, 1024); 3401 msg.message = message.Substring(0, 1024);
3101 else 3402 else
3102 msg.message = message; 3403 msg.message = message;
3103 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3404 msg.dialog = (byte)19; // MessageFromObject
3104 msg.fromGroup = false;// fromGroup; 3405 msg.fromGroup = false;// fromGroup;
3105 msg.offline = (byte)0; //offline; 3406 msg.offline = (byte)0; //offline;
3106 msg.ParentEstateID = 0; //ParentEstateID; 3407 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3107 msg.Position = new Vector3(m_host.AbsolutePosition); 3408 msg.Position = new Vector3(m_host.AbsolutePosition);
3108 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3409 msg.RegionID = World.RegionInfo.RegionID.Guid;
3109 msg.binaryBucket 3410 msg.binaryBucket
3110 = Util.StringToBytes256( 3411 = Util.StringToBytes256(
3111 "{0}/{1}/{2}/{3}", 3412 "{0}/{1}/{2}/{3}",
@@ -3133,7 +3434,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3133 } 3434 }
3134 3435
3135 emailModule.SendEmail(m_host.UUID, address, subject, message); 3436 emailModule.SendEmail(m_host.UUID, address, subject, message);
3136 ScriptSleep(20000); 3437 ScriptSleep(15000);
3137 } 3438 }
3138 3439
3139 public void llGetNextEmail(string address, string subject) 3440 public void llGetNextEmail(string address, string subject)
@@ -3233,13 +3534,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3233 m_host.AddScriptLPS(1); 3534 m_host.AddScriptLPS(1);
3234 } 3535 }
3235 3536
3236 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3237 {
3238 m_host.AddScriptLPS(1);
3239 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3240 m_host.RotLookAt(rot, (float)strength, (float)damping);
3241 }
3242
3243 public LSL_Integer llStringLength(string str) 3537 public LSL_Integer llStringLength(string str)
3244 { 3538 {
3245 m_host.AddScriptLPS(1); 3539 m_host.AddScriptLPS(1);
@@ -3263,14 +3557,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3263 3557
3264 TaskInventoryItem item; 3558 TaskInventoryItem item;
3265 3559
3266 lock (m_host.TaskInventory) 3560 m_host.TaskInventory.LockItemsForRead(true);
3561 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3267 { 3562 {
3268 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3563 m_host.TaskInventory.LockItemsForRead(false);
3269 return; 3564 return;
3270 else
3271 item = m_host.TaskInventory[InventorySelf()];
3272 } 3565 }
3273 3566 else
3567 {
3568 item = m_host.TaskInventory[InventorySelf()];
3569 }
3570 m_host.TaskInventory.LockItemsForRead(false);
3274 if (item.PermsGranter == UUID.Zero) 3571 if (item.PermsGranter == UUID.Zero)
3275 return; 3572 return;
3276 3573
@@ -3300,13 +3597,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3300 3597
3301 TaskInventoryItem item; 3598 TaskInventoryItem item;
3302 3599
3303 lock (m_host.TaskInventory) 3600 m_host.TaskInventory.LockItemsForRead(true);
3601 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3304 { 3602 {
3305 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3603 m_host.TaskInventory.LockItemsForRead(false);
3306 return; 3604 return;
3307 else
3308 item = m_host.TaskInventory[InventorySelf()];
3309 } 3605 }
3606 else
3607 {
3608 item = m_host.TaskInventory[InventorySelf()];
3609 }
3610 m_host.TaskInventory.LockItemsForRead(false);
3611
3310 3612
3311 if (item.PermsGranter == UUID.Zero) 3613 if (item.PermsGranter == UUID.Zero)
3312 return; 3614 return;
@@ -3373,10 +3675,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3373 3675
3374 TaskInventoryItem item; 3676 TaskInventoryItem item;
3375 3677
3376 lock (m_host.TaskInventory) 3678
3679 m_host.TaskInventory.LockItemsForRead(true);
3680 if (!m_host.TaskInventory.ContainsKey(invItemID))
3681 {
3682 m_host.TaskInventory.LockItemsForRead(false);
3683 return;
3684 }
3685 else
3377 { 3686 {
3378 item = m_host.TaskInventory[invItemID]; 3687 item = m_host.TaskInventory[invItemID];
3379 } 3688 }
3689 m_host.TaskInventory.LockItemsForRead(false);
3380 3690
3381 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3691 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3382 { 3692 {
@@ -3404,15 +3714,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3404 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3714 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3405 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3715 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3406 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3716 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3717 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3407 ScriptBaseClass.PERMISSION_ATTACH; 3718 ScriptBaseClass.PERMISSION_ATTACH;
3408 3719
3409 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3720 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3410 { 3721 {
3411 lock (m_host.TaskInventory) 3722 m_host.TaskInventory.LockItemsForWrite(true);
3412 { 3723 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3413 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3724 m_host.TaskInventory[invItemID].PermsMask = perm;
3414 m_host.TaskInventory[invItemID].PermsMask = perm; 3725 m_host.TaskInventory.LockItemsForWrite(false);
3415 }
3416 3726
3417 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3727 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3418 "run_time_permissions", new Object[] { 3728 "run_time_permissions", new Object[] {
@@ -3422,28 +3732,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3422 return; 3732 return;
3423 } 3733 }
3424 } 3734 }
3425 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3735 else
3426 { 3736 {
3427 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3737 bool sitting = false;
3428 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3738 if (m_host.SitTargetAvatar == agentID)
3429 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3739 {
3430 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3740 sitting = true;
3431 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3741 }
3742 else
3743 {
3744 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3745 {
3746 if (p.SitTargetAvatar == agentID)
3747 sitting = true;
3748 }
3749 }
3432 3750
3433 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3751 if (sitting)
3434 { 3752 {
3435 lock (m_host.TaskInventory) 3753 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3754 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3755 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3756 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3757 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3758
3759 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3436 { 3760 {
3761 m_host.TaskInventory.LockItemsForWrite(true);
3437 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3762 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3438 m_host.TaskInventory[invItemID].PermsMask = perm; 3763 m_host.TaskInventory[invItemID].PermsMask = perm;
3439 } 3764 m_host.TaskInventory.LockItemsForWrite(false);
3440 3765
3441 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3766 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3442 "run_time_permissions", new Object[] { 3767 "run_time_permissions", new Object[] {
3443 new LSL_Integer(perm) }, 3768 new LSL_Integer(perm) },
3444 new DetectParams[0])); 3769 new DetectParams[0]));
3445 3770
3446 return; 3771 return;
3772 }
3447 } 3773 }
3448 } 3774 }
3449 3775
@@ -3457,11 +3783,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3457 3783
3458 if (!m_waitingForScriptAnswer) 3784 if (!m_waitingForScriptAnswer)
3459 { 3785 {
3460 lock (m_host.TaskInventory) 3786 m_host.TaskInventory.LockItemsForWrite(true);
3461 { 3787 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3462 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3788 m_host.TaskInventory[invItemID].PermsMask = 0;
3463 m_host.TaskInventory[invItemID].PermsMask = 0; 3789 m_host.TaskInventory.LockItemsForWrite(false);
3464 }
3465 3790
3466 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3791 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3467 m_waitingForScriptAnswer=true; 3792 m_waitingForScriptAnswer=true;
@@ -3496,10 +3821,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3496 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3821 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3497 llReleaseControls(); 3822 llReleaseControls();
3498 3823
3499 lock (m_host.TaskInventory) 3824
3500 { 3825 m_host.TaskInventory.LockItemsForWrite(true);
3501 m_host.TaskInventory[invItemID].PermsMask = answer; 3826 m_host.TaskInventory[invItemID].PermsMask = answer;
3502 } 3827 m_host.TaskInventory.LockItemsForWrite(false);
3828
3503 3829
3504 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3830 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3505 "run_time_permissions", new Object[] { 3831 "run_time_permissions", new Object[] {
@@ -3511,16 +3837,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3511 { 3837 {
3512 m_host.AddScriptLPS(1); 3838 m_host.AddScriptLPS(1);
3513 3839
3514 lock (m_host.TaskInventory) 3840 m_host.TaskInventory.LockItemsForRead(true);
3841
3842 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3515 { 3843 {
3516 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3844 if (item.Type == 10 && item.ItemID == m_itemID)
3517 { 3845 {
3518 if (item.Type == 10 && item.ItemID == m_itemID) 3846 m_host.TaskInventory.LockItemsForRead(false);
3519 { 3847 return item.PermsGranter.ToString();
3520 return item.PermsGranter.ToString();
3521 }
3522 } 3848 }
3523 } 3849 }
3850 m_host.TaskInventory.LockItemsForRead(false);
3524 3851
3525 return UUID.Zero.ToString(); 3852 return UUID.Zero.ToString();
3526 } 3853 }
@@ -3529,19 +3856,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3529 { 3856 {
3530 m_host.AddScriptLPS(1); 3857 m_host.AddScriptLPS(1);
3531 3858
3532 lock (m_host.TaskInventory) 3859 m_host.TaskInventory.LockItemsForRead(true);
3860
3861 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3533 { 3862 {
3534 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3863 if (item.Type == 10 && item.ItemID == m_itemID)
3535 { 3864 {
3536 if (item.Type == 10 && item.ItemID == m_itemID) 3865 int perms = item.PermsMask;
3537 { 3866 if (m_automaticLinkPermission)
3538 int perms = item.PermsMask; 3867 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3539 if (m_automaticLinkPermission) 3868 m_host.TaskInventory.LockItemsForRead(false);
3540 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3869 return perms;
3541 return perms;
3542 }
3543 } 3870 }
3544 } 3871 }
3872 m_host.TaskInventory.LockItemsForRead(false);
3545 3873
3546 return 0; 3874 return 0;
3547 } 3875 }
@@ -3563,9 +3891,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3563 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3891 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3564 { 3892 {
3565 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3893 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3566 3894 if (parts.Count > 0)
3567 foreach (SceneObjectPart part in parts) 3895 {
3568 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3896 try
3897 {
3898 parts[0].ParentGroup.areUpdatesSuspended = true;
3899 foreach (SceneObjectPart part in parts)
3900 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3901 }
3902 finally
3903 {
3904 parts[0].ParentGroup.areUpdatesSuspended = false;
3905 }
3906 }
3569 } 3907 }
3570 3908
3571 public void llCreateLink(string target, int parent) 3909 public void llCreateLink(string target, int parent)
@@ -3578,11 +3916,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3578 return; 3916 return;
3579 3917
3580 TaskInventoryItem item; 3918 TaskInventoryItem item;
3581 lock (m_host.TaskInventory) 3919 m_host.TaskInventory.LockItemsForRead(true);
3582 { 3920 item = m_host.TaskInventory[invItemID];
3583 item = m_host.TaskInventory[invItemID]; 3921 m_host.TaskInventory.LockItemsForRead(false);
3584 } 3922
3585
3586 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3923 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3587 && !m_automaticLinkPermission) 3924 && !m_automaticLinkPermission)
3588 { 3925 {
@@ -3599,11 +3936,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3599 3936
3600 if (targetPart.ParentGroup.AttachmentPoint != 0) 3937 if (targetPart.ParentGroup.AttachmentPoint != 0)
3601 return; // Fail silently if attached 3938 return; // Fail silently if attached
3939
3940 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3941 return;
3942
3602 SceneObjectGroup parentPrim = null, childPrim = null; 3943 SceneObjectGroup parentPrim = null, childPrim = null;
3603 3944
3604 if (targetPart != null) 3945 if (targetPart != null)
3605 { 3946 {
3606 if (parent != 0) { 3947 if (parent != 0)
3948 {
3607 parentPrim = m_host.ParentGroup; 3949 parentPrim = m_host.ParentGroup;
3608 childPrim = targetPart.ParentGroup; 3950 childPrim = targetPart.ParentGroup;
3609 } 3951 }
@@ -3634,16 +3976,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3634 m_host.AddScriptLPS(1); 3976 m_host.AddScriptLPS(1);
3635 UUID invItemID = InventorySelf(); 3977 UUID invItemID = InventorySelf();
3636 3978
3637 lock (m_host.TaskInventory) 3979 m_host.TaskInventory.LockItemsForRead(true);
3638 {
3639 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3980 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3640 && !m_automaticLinkPermission) 3981 && !m_automaticLinkPermission)
3641 { 3982 {
3642 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3983 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3984 m_host.TaskInventory.LockItemsForRead(false);
3643 return; 3985 return;
3644 } 3986 }
3645 } 3987 m_host.TaskInventory.LockItemsForRead(false);
3646 3988
3647 if (linknum < ScriptBaseClass.LINK_THIS) 3989 if (linknum < ScriptBaseClass.LINK_THIS)
3648 return; 3990 return;
3649 3991
@@ -3682,10 +4024,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3682 // Restructuring Multiple Prims. 4024 // Restructuring Multiple Prims.
3683 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4025 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3684 parts.Remove(parentPrim.RootPart); 4026 parts.Remove(parentPrim.RootPart);
3685 foreach (SceneObjectPart part in parts) 4027 if (parts.Count > 0)
3686 { 4028 {
3687 parentPrim.DelinkFromGroup(part.LocalId, true); 4029 try
4030 {
4031 parts[0].ParentGroup.areUpdatesSuspended = true;
4032 foreach (SceneObjectPart part in parts)
4033 {
4034 parentPrim.DelinkFromGroup(part.LocalId, true);
4035 }
4036 }
4037 finally
4038 {
4039 parts[0].ParentGroup.areUpdatesSuspended = false;
4040 }
3688 } 4041 }
4042
3689 parentPrim.HasGroupChanged = true; 4043 parentPrim.HasGroupChanged = true;
3690 parentPrim.ScheduleGroupForFullUpdate(); 4044 parentPrim.ScheduleGroupForFullUpdate();
3691 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4045 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3694,12 +4048,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3694 { 4048 {
3695 SceneObjectPart newRoot = parts[0]; 4049 SceneObjectPart newRoot = parts[0];
3696 parts.Remove(newRoot); 4050 parts.Remove(newRoot);
3697 foreach (SceneObjectPart part in parts) 4051
4052 try
3698 { 4053 {
3699 // Required for linking 4054 parts[0].ParentGroup.areUpdatesSuspended = true;
3700 part.ClearUpdateSchedule(); 4055 foreach (SceneObjectPart part in parts)
3701 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4056 {
4057 part.ClearUpdateSchedule();
4058 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4059 }
3702 } 4060 }
4061 finally
4062 {
4063 parts[0].ParentGroup.areUpdatesSuspended = false;
4064 }
4065
4066
3703 newRoot.ParentGroup.HasGroupChanged = true; 4067 newRoot.ParentGroup.HasGroupChanged = true;
3704 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4068 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3705 } 4069 }
@@ -3719,6 +4083,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3719 public void llBreakAllLinks() 4083 public void llBreakAllLinks()
3720 { 4084 {
3721 m_host.AddScriptLPS(1); 4085 m_host.AddScriptLPS(1);
4086
4087 UUID invItemID = InventorySelf();
4088
4089 TaskInventoryItem item;
4090 m_host.TaskInventory.LockItemsForRead(true);
4091 item = m_host.TaskInventory[invItemID];
4092 m_host.TaskInventory.LockItemsForRead(false);
4093
4094 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4095 && !m_automaticLinkPermission)
4096 {
4097 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4098 return;
4099 }
4100
3722 SceneObjectGroup parentPrim = m_host.ParentGroup; 4101 SceneObjectGroup parentPrim = m_host.ParentGroup;
3723 if (parentPrim.AttachmentPoint != 0) 4102 if (parentPrim.AttachmentPoint != 0)
3724 return; // Fail silently if attached 4103 return; // Fail silently if attached
@@ -3738,25 +4117,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3738 public LSL_String llGetLinkKey(int linknum) 4117 public LSL_String llGetLinkKey(int linknum)
3739 { 4118 {
3740 m_host.AddScriptLPS(1); 4119 m_host.AddScriptLPS(1);
3741 List<UUID> keytable = new List<UUID>();
3742 // parse for sitting avatare-uuids
3743 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3744 {
3745 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
3746 keytable.Add(presence.UUID);
3747 });
3748
3749 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3750 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3751 {
3752 return keytable[totalprims - linknum].ToString();
3753 }
3754
3755 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3756 {
3757 return m_host.UUID.ToString();
3758 }
3759
3760 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4120 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3761 if (part != null) 4121 if (part != null)
3762 { 4122 {
@@ -3764,6 +4124,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3764 } 4124 }
3765 else 4125 else
3766 { 4126 {
4127 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4128 {
4129 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4130
4131 if (linknum < 0)
4132 return UUID.Zero.ToString();
4133
4134 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4135 if (avatars.Count > linknum)
4136 {
4137 return avatars[linknum].UUID.ToString();
4138 }
4139 }
3767 return UUID.Zero.ToString(); 4140 return UUID.Zero.ToString();
3768 } 4141 }
3769 } 4142 }
@@ -3862,17 +4235,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3862 m_host.AddScriptLPS(1); 4235 m_host.AddScriptLPS(1);
3863 int count = 0; 4236 int count = 0;
3864 4237
3865 lock (m_host.TaskInventory) 4238 m_host.TaskInventory.LockItemsForRead(true);
4239 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3866 { 4240 {
3867 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4241 if (inv.Value.Type == type || type == -1)
3868 { 4242 {
3869 if (inv.Value.Type == type || type == -1) 4243 count = count + 1;
3870 {
3871 count = count + 1;
3872 }
3873 } 4244 }
3874 } 4245 }
3875 4246
4247 m_host.TaskInventory.LockItemsForRead(false);
3876 return count; 4248 return count;
3877 } 4249 }
3878 4250
@@ -3881,16 +4253,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3881 m_host.AddScriptLPS(1); 4253 m_host.AddScriptLPS(1);
3882 ArrayList keys = new ArrayList(); 4254 ArrayList keys = new ArrayList();
3883 4255
3884 lock (m_host.TaskInventory) 4256 m_host.TaskInventory.LockItemsForRead(true);
4257 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3885 { 4258 {
3886 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4259 if (inv.Value.Type == type || type == -1)
3887 { 4260 {
3888 if (inv.Value.Type == type || type == -1) 4261 keys.Add(inv.Value.Name);
3889 {
3890 keys.Add(inv.Value.Name);
3891 }
3892 } 4262 }
3893 } 4263 }
4264 m_host.TaskInventory.LockItemsForRead(false);
3894 4265
3895 if (keys.Count == 0) 4266 if (keys.Count == 0)
3896 { 4267 {
@@ -3927,25 +4298,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3927 } 4298 }
3928 4299
3929 // move the first object found with this inventory name 4300 // move the first object found with this inventory name
3930 lock (m_host.TaskInventory) 4301 m_host.TaskInventory.LockItemsForRead(true);
4302 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3931 { 4303 {
3932 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4304 if (inv.Value.Name == inventory)
3933 { 4305 {
3934 if (inv.Value.Name == inventory) 4306 found = true;
3935 { 4307 objId = inv.Key;
3936 found = true; 4308 assetType = inv.Value.Type;
3937 objId = inv.Key; 4309 objName = inv.Value.Name;
3938 assetType = inv.Value.Type; 4310 break;
3939 objName = inv.Value.Name;
3940 break;
3941 }
3942 } 4311 }
3943 } 4312 }
4313 m_host.TaskInventory.LockItemsForRead(false);
3944 4314
3945 if (!found) 4315 if (!found)
3946 { 4316 {
3947 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4317 llSay(0, String.Format("Could not find object '{0}'", inventory));
3948 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4318 return;
4319// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3949 } 4320 }
3950 4321
3951 // check if destination is an object 4322 // check if destination is an object
@@ -3971,48 +4342,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 return; 4342 return;
3972 } 4343 }
3973 } 4344 }
4345
3974 // destination is an avatar 4346 // destination is an avatar
3975 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4347 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3976 4348
3977 if (agentItem == null) 4349 if (agentItem == null)
3978 return; 4350 return;
3979 4351
3980 byte[] bucket = new byte[17]; 4352 byte[] bucket = new byte[1];
3981 bucket[0] = (byte)assetType; 4353 bucket[0] = (byte)assetType;
3982 byte[] objBytes = agentItem.ID.GetBytes(); 4354 //byte[] objBytes = agentItem.ID.GetBytes();
3983 Array.Copy(objBytes, 0, bucket, 1, 16); 4355 //Array.Copy(objBytes, 0, bucket, 1, 16);
3984 4356
3985 GridInstantMessage msg = new GridInstantMessage(World, 4357 GridInstantMessage msg = new GridInstantMessage(World,
3986 m_host.UUID, m_host.Name+", an object owned by "+ 4358 m_host.OwnerID, m_host.Name, destId,
3987 resolveName(m_host.OwnerID)+",", destId,
3988 (byte)InstantMessageDialog.TaskInventoryOffered, 4359 (byte)InstantMessageDialog.TaskInventoryOffered,
3989 false, objName+"\n"+m_host.Name+" is located at "+ 4360 false, objName+". "+m_host.Name+" is located at "+
3990 World.RegionInfo.RegionName+" "+ 4361 World.RegionInfo.RegionName+" "+
3991 m_host.AbsolutePosition.ToString(), 4362 m_host.AbsolutePosition.ToString(),
3992 agentItem.ID, true, m_host.AbsolutePosition, 4363 agentItem.ID, true, m_host.AbsolutePosition,
3993 bucket); 4364 bucket);
3994 if (m_TransferModule != null) 4365
3995 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4366 ScenePresence sp;
4367
4368 if (World.TryGetScenePresence(destId, out sp))
4369 {
4370 sp.ControllingClient.SendInstantMessage(msg);
4371 }
4372 else
4373 {
4374 if (m_TransferModule != null)
4375 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4376 }
4377
4378 //This delay should only occur when giving inventory to avatars.
3996 ScriptSleep(3000); 4379 ScriptSleep(3000);
3997 } 4380 }
3998 } 4381 }
3999 4382
4383 [DebuggerNonUserCode]
4000 public void llRemoveInventory(string name) 4384 public void llRemoveInventory(string name)
4001 { 4385 {
4002 m_host.AddScriptLPS(1); 4386 m_host.AddScriptLPS(1);
4003 4387
4004 lock (m_host.TaskInventory) 4388 List<TaskInventoryItem> inv;
4389 try
4005 { 4390 {
4006 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4391 m_host.TaskInventory.LockItemsForRead(true);
4392 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4393 }
4394 finally
4395 {
4396 m_host.TaskInventory.LockItemsForRead(false);
4397 }
4398 foreach (TaskInventoryItem item in inv)
4399 {
4400 if (item.Name == name)
4007 { 4401 {
4008 if (item.Name == name) 4402 if (item.ItemID == m_itemID)
4009 { 4403 throw new ScriptDeleteException();
4010 if (item.ItemID == m_itemID) 4404 else
4011 throw new ScriptDeleteException(); 4405 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4012 else 4406 return;
4013 m_host.Inventory.RemoveInventoryItem(item.ItemID);
4014 return;
4015 }
4016 } 4407 }
4017 } 4408 }
4018 } 4409 }
@@ -4047,112 +4438,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4047 { 4438 {
4048 m_host.AddScriptLPS(1); 4439 m_host.AddScriptLPS(1);
4049 4440
4050 UUID uuid = (UUID)id; 4441 UUID uuid;
4051 PresenceInfo pinfo = null; 4442 if (UUID.TryParse(id, out uuid))
4052 UserAccount account;
4053
4054 UserInfoCacheEntry ce;
4055 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4056 { 4443 {
4057 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4444 PresenceInfo pinfo = null;
4058 if (account == null) 4445 UserAccount account;
4446
4447 UserInfoCacheEntry ce;
4448 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4059 { 4449 {
4060 m_userInfoCache[uuid] = null; // Cache negative 4450 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4061 return UUID.Zero.ToString(); 4451 if (account == null)
4062 } 4452 {
4453 m_userInfoCache[uuid] = null; // Cache negative
4454 return UUID.Zero.ToString();
4455 }
4063 4456
4064 4457
4065 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4458 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4066 if (pinfos != null && pinfos.Length > 0) 4459 if (pinfos != null && pinfos.Length > 0)
4067 {
4068 foreach (PresenceInfo p in pinfos)
4069 { 4460 {
4070 if (p.RegionID != UUID.Zero) 4461 foreach (PresenceInfo p in pinfos)
4071 { 4462 {
4072 pinfo = p; 4463 if (p.RegionID != UUID.Zero)
4464 {
4465 pinfo = p;
4466 }
4073 } 4467 }
4074 } 4468 }
4075 }
4076 4469
4077 ce = new UserInfoCacheEntry(); 4470 ce = new UserInfoCacheEntry();
4078 ce.time = Util.EnvironmentTickCount(); 4471 ce.time = Util.EnvironmentTickCount();
4079 ce.account = account; 4472 ce.account = account;
4080 ce.pinfo = pinfo; 4473 ce.pinfo = pinfo;
4081 } 4474 m_userInfoCache[uuid] = ce;
4082 else 4475 }
4083 { 4476 else
4084 if (ce == null) 4477 {
4085 return UUID.Zero.ToString(); 4478 if (ce == null)
4479 return UUID.Zero.ToString();
4086 4480
4087 account = ce.account; 4481 account = ce.account;
4088 pinfo = ce.pinfo; 4482 pinfo = ce.pinfo;
4089 } 4483 }
4090 4484
4091 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4485 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4092 {
4093 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4094 if (pinfos != null && pinfos.Length > 0)
4095 { 4486 {
4096 foreach (PresenceInfo p in pinfos) 4487 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4488 if (pinfos != null && pinfos.Length > 0)
4097 { 4489 {
4098 if (p.RegionID != UUID.Zero) 4490 foreach (PresenceInfo p in pinfos)
4099 { 4491 {
4100 pinfo = p; 4492 if (p.RegionID != UUID.Zero)
4493 {
4494 pinfo = p;
4495 }
4101 } 4496 }
4102 } 4497 }
4103 } 4498 else
4104 else 4499 pinfo = null;
4105 pinfo = null;
4106 4500
4107 ce.time = Util.EnvironmentTickCount(); 4501 ce.time = Util.EnvironmentTickCount();
4108 ce.pinfo = pinfo; 4502 ce.pinfo = pinfo;
4109 } 4503 }
4110 4504
4111 string reply = String.Empty; 4505 string reply = String.Empty;
4112 4506
4113 switch (data) 4507 switch (data)
4114 { 4508 {
4115 case 1: // DATA_ONLINE (0|1) 4509 case 1: // DATA_ONLINE (0|1)
4116 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4510 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4117 reply = "1"; 4511 reply = "1";
4118 else 4512 else
4119 reply = "0"; 4513 reply = "0";
4120 break; 4514 break;
4121 case 2: // DATA_NAME (First Last) 4515 case 2: // DATA_NAME (First Last)
4122 reply = account.FirstName + " " + account.LastName; 4516 reply = account.FirstName + " " + account.LastName;
4123 break; 4517 break;
4124 case 3: // DATA_BORN (YYYY-MM-DD) 4518 case 3: // DATA_BORN (YYYY-MM-DD)
4125 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4519 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4126 born = born.AddSeconds(account.Created); 4520 born = born.AddSeconds(account.Created);
4127 reply = born.ToString("yyyy-MM-dd"); 4521 reply = born.ToString("yyyy-MM-dd");
4128 break; 4522 break;
4129 case 4: // DATA_RATING (0,0,0,0,0,0) 4523 case 4: // DATA_RATING (0,0,0,0,0,0)
4130 reply = "0,0,0,0,0,0"; 4524 reply = "0,0,0,0,0,0";
4131 break; 4525 break;
4132 case 8: // DATA_PAYINFO (0|1|2|3) 4526 case 8: // DATA_PAYINFO (0|1|2|3)
4133 reply = "0"; 4527 reply = "0";
4134 break; 4528 break;
4135 default: 4529 default:
4136 return UUID.Zero.ToString(); // Raise no event 4530 return UUID.Zero.ToString(); // Raise no event
4137 } 4531 }
4138 4532
4139 UUID rq = UUID.Random(); 4533 UUID rq = UUID.Random();
4140 4534
4141 UUID tid = AsyncCommands. 4535 UUID tid = AsyncCommands.
4142 DataserverPlugin.RegisterRequest(m_localID, 4536 DataserverPlugin.RegisterRequest(m_localID,
4143 m_itemID, rq.ToString()); 4537 m_itemID, rq.ToString());
4144 4538
4145 AsyncCommands. 4539 AsyncCommands.
4146 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4540 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4147 4541
4148 ScriptSleep(100); 4542 ScriptSleep(100);
4149 return tid.ToString(); 4543 return tid.ToString();
4544 }
4545 else
4546 {
4547 ShoutError("Invalid UUID passed to llRequestAgentData.");
4548 }
4549 return "";
4150 } 4550 }
4151 4551
4152 public LSL_String llRequestInventoryData(string name) 4552 public LSL_String llRequestInventoryData(string name)
4153 { 4553 {
4154 m_host.AddScriptLPS(1); 4554 m_host.AddScriptLPS(1);
4155 4555
4556 //Clone is thread safe
4156 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4557 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4157 4558
4158 foreach (TaskInventoryItem item in itemDictionary.Values) 4559 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4206,6 +4607,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4206 ScenePresence presence = World.GetScenePresence(agentId); 4607 ScenePresence presence = World.GetScenePresence(agentId);
4207 if (presence != null) 4608 if (presence != null)
4208 { 4609 {
4610 // agent must not be a god
4611 if (presence.UserLevel >= 200) return;
4612
4209 // agent must be over the owners land 4613 // agent must be over the owners land
4210 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4614 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4211 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4615 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4228,7 +4632,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4228 UUID av = new UUID(); 4632 UUID av = new UUID();
4229 if (!UUID.TryParse(agent,out av)) 4633 if (!UUID.TryParse(agent,out av))
4230 { 4634 {
4231 LSLError("First parameter to llDialog needs to be a key"); 4635 //LSLError("First parameter to llDialog needs to be a key");
4232 return; 4636 return;
4233 } 4637 }
4234 4638
@@ -4265,17 +4669,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4265 UUID soundId = UUID.Zero; 4669 UUID soundId = UUID.Zero;
4266 if (!UUID.TryParse(impact_sound, out soundId)) 4670 if (!UUID.TryParse(impact_sound, out soundId))
4267 { 4671 {
4268 lock (m_host.TaskInventory) 4672 m_host.TaskInventory.LockItemsForRead(true);
4673 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4269 { 4674 {
4270 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4675 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4271 { 4676 {
4272 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4677 soundId = item.AssetID;
4273 { 4678 break;
4274 soundId = item.AssetID;
4275 break;
4276 }
4277 } 4679 }
4278 } 4680 }
4681 m_host.TaskInventory.LockItemsForRead(false);
4279 } 4682 }
4280 m_host.CollisionSound = soundId; 4683 m_host.CollisionSound = soundId;
4281 m_host.CollisionSoundVolume = (float)impact_volume; 4684 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4315,6 +4718,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4315 UUID partItemID; 4718 UUID partItemID;
4316 foreach (SceneObjectPart part in parts) 4719 foreach (SceneObjectPart part in parts)
4317 { 4720 {
4721 //Clone is thread safe
4318 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4722 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4319 4723
4320 foreach (TaskInventoryItem item in itemsDictionary.Values) 4724 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4529,17 +4933,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4529 4933
4530 m_host.AddScriptLPS(1); 4934 m_host.AddScriptLPS(1);
4531 4935
4532 lock (m_host.TaskInventory) 4936 m_host.TaskInventory.LockItemsForRead(true);
4937 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4533 { 4938 {
4534 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4939 if (item.Type == 10 && item.ItemID == m_itemID)
4535 { 4940 {
4536 if (item.Type == 10 && item.ItemID == m_itemID) 4941 result = item.Name!=null?item.Name:String.Empty;
4537 { 4942 break;
4538 result = item.Name != null ? item.Name : String.Empty;
4539 break;
4540 }
4541 } 4943 }
4542 } 4944 }
4945 m_host.TaskInventory.LockItemsForRead(false);
4543 4946
4544 return result; 4947 return result;
4545 } 4948 }
@@ -4708,23 +5111,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4708 { 5111 {
4709 m_host.AddScriptLPS(1); 5112 m_host.AddScriptLPS(1);
4710 5113
4711 lock (m_host.TaskInventory) 5114 m_host.TaskInventory.LockItemsForRead(true);
5115 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4712 { 5116 {
4713 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5117 if (inv.Value.Name == name)
4714 { 5118 {
4715 if (inv.Value.Name == name) 5119 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4716 { 5120 {
4717 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5121 m_host.TaskInventory.LockItemsForRead(false);
4718 { 5122 return inv.Value.AssetID.ToString();
4719 return inv.Value.AssetID.ToString(); 5123 }
4720 } 5124 else
4721 else 5125 {
4722 { 5126 m_host.TaskInventory.LockItemsForRead(false);
4723 return UUID.Zero.ToString(); 5127 return UUID.Zero.ToString();
4724 }
4725 } 5128 }
4726 } 5129 }
4727 } 5130 }
5131 m_host.TaskInventory.LockItemsForRead(false);
4728 5132
4729 return UUID.Zero.ToString(); 5133 return UUID.Zero.ToString();
4730 } 5134 }
@@ -4877,14 +5281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4877 { 5281 {
4878 m_host.AddScriptLPS(1); 5282 m_host.AddScriptLPS(1);
4879 5283
4880 if (src == null) 5284 return src.Length;
4881 {
4882 return 0;
4883 }
4884 else
4885 {
4886 return src.Length;
4887 }
4888 } 5285 }
4889 5286
4890 public LSL_Integer llList2Integer(LSL_List src, int index) 5287 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4930,7 +5327,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4930 else if (src.Data[index] is LSL_Float) 5327 else if (src.Data[index] is LSL_Float)
4931 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5328 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4932 else if (src.Data[index] is LSL_String) 5329 else if (src.Data[index] is LSL_String)
4933 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5330 {
5331 string str = ((LSL_String) src.Data[index]).m_string;
5332 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5333 if (m != Match.Empty)
5334 {
5335 str = m.Value;
5336 double d = 0.0;
5337 if (!Double.TryParse(str, out d))
5338 return 0.0;
5339
5340 return d;
5341 }
5342 return 0.0;
5343 }
4934 return Convert.ToDouble(src.Data[index]); 5344 return Convert.ToDouble(src.Data[index]);
4935 } 5345 }
4936 catch (FormatException) 5346 catch (FormatException)
@@ -5203,7 +5613,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5203 } 5613 }
5204 } 5614 }
5205 } 5615 }
5206 else { 5616 else
5617 {
5207 object[] array = new object[src.Length]; 5618 object[] array = new object[src.Length];
5208 Array.Copy(src.Data, 0, array, 0, src.Length); 5619 Array.Copy(src.Data, 0, array, 0, src.Length);
5209 result = new LSL_List(array); 5620 result = new LSL_List(array);
@@ -5652,10 +6063,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5652 m_host.AddScriptLPS(1); 6063 m_host.AddScriptLPS(1);
5653 6064
5654 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6065 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5655 6066 if (parts.Count > 0)
5656 foreach (var part in parts)
5657 { 6067 {
5658 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6068 try
6069 {
6070 parts[0].ParentGroup.areUpdatesSuspended = true;
6071 foreach (var part in parts)
6072 {
6073 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6074 }
6075 }
6076 finally
6077 {
6078 parts[0].ParentGroup.areUpdatesSuspended = false;
6079 }
5659 } 6080 }
5660 } 6081 }
5661 6082
@@ -5709,6 +6130,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5709 ScriptSleep(5000); 6130 ScriptSleep(5000);
5710 } 6131 }
5711 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
5712 public LSL_Integer llOverMyLand(string id) 6138 public LSL_Integer llOverMyLand(string id)
5713 { 6139 {
5714 m_host.AddScriptLPS(1); 6140 m_host.AddScriptLPS(1);
@@ -5773,8 +6199,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5773 UUID agentId = new UUID(); 6199 UUID agentId = new UUID();
5774 if (!UUID.TryParse(agent, out agentId)) 6200 if (!UUID.TryParse(agent, out agentId))
5775 return new LSL_Integer(0); 6201 return new LSL_Integer(0);
6202 if (agentId == m_host.GroupID)
6203 return new LSL_Integer(1);
5776 ScenePresence presence = World.GetScenePresence(agentId); 6204 ScenePresence presence = World.GetScenePresence(agentId);
5777 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6205 if (presence == null || presence.IsChildAgent) // Return false for child agents
5778 return new LSL_Integer(0); 6206 return new LSL_Integer(0);
5779 IClientAPI client = presence.ControllingClient; 6207 IClientAPI client = presence.ControllingClient;
5780 if (m_host.GroupID == client.ActiveGroupId) 6208 if (m_host.GroupID == client.ActiveGroupId)
@@ -5909,7 +6337,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5909 return m_host.ParentGroup.AttachmentPoint; 6337 return m_host.ParentGroup.AttachmentPoint;
5910 } 6338 }
5911 6339
5912 public LSL_Integer llGetFreeMemory() 6340 public virtual LSL_Integer llGetFreeMemory()
5913 { 6341 {
5914 m_host.AddScriptLPS(1); 6342 m_host.AddScriptLPS(1);
5915 // Make scripts designed for LSO happy 6343 // Make scripts designed for LSO happy
@@ -6026,7 +6454,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6026 SetParticleSystem(m_host, rules); 6454 SetParticleSystem(m_host, rules);
6027 } 6455 }
6028 6456
6029 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6457 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6458 {
6030 6459
6031 6460
6032 if (rules.Length == 0) 6461 if (rules.Length == 0)
@@ -6220,14 +6649,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6220 6649
6221 protected UUID GetTaskInventoryItem(string name) 6650 protected UUID GetTaskInventoryItem(string name)
6222 { 6651 {
6223 lock (m_host.TaskInventory) 6652 m_host.TaskInventory.LockItemsForRead(true);
6653 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6224 { 6654 {
6225 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6655 if (inv.Value.Name == name)
6226 { 6656 {
6227 if (inv.Value.Name == name) 6657 m_host.TaskInventory.LockItemsForRead(false);
6228 return inv.Key; 6658 return inv.Key;
6229 } 6659 }
6230 } 6660 }
6661 m_host.TaskInventory.LockItemsForRead(false);
6231 6662
6232 return UUID.Zero; 6663 return UUID.Zero;
6233 } 6664 }
@@ -6265,16 +6696,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6265 if (folderID == UUID.Zero) 6696 if (folderID == UUID.Zero)
6266 return; 6697 return;
6267 6698
6268 byte[] bucket = new byte[17]; 6699 byte[] bucket = new byte[1];
6269 bucket[0] = (byte)AssetType.Folder; 6700 bucket[0] = (byte)AssetType.Folder;
6270 byte[] objBytes = folderID.GetBytes(); 6701 //byte[] objBytes = folderID.GetBytes();
6271 Array.Copy(objBytes, 0, bucket, 1, 16); 6702 //Array.Copy(objBytes, 0, bucket, 1, 16);
6272 6703
6273 GridInstantMessage msg = new GridInstantMessage(World, 6704 GridInstantMessage msg = new GridInstantMessage(World,
6274 m_host.UUID, m_host.Name+", an object owned by "+ 6705 m_host.OwnerID, m_host.Name, destID,
6275 resolveName(m_host.OwnerID)+",", destID, 6706 (byte)InstantMessageDialog.TaskInventoryOffered,
6276 (byte)InstantMessageDialog.InventoryOffered, 6707 false, category+". "+m_host.Name+" is located at "+
6277 false, category+"\n"+m_host.Name+" is located at "+
6278 World.RegionInfo.RegionName+" "+ 6708 World.RegionInfo.RegionName+" "+
6279 m_host.AbsolutePosition.ToString(), 6709 m_host.AbsolutePosition.ToString(),
6280 folderID, true, m_host.AbsolutePosition, 6710 folderID, true, m_host.AbsolutePosition,
@@ -6477,13 +6907,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6477 UUID av = new UUID(); 6907 UUID av = new UUID();
6478 if (!UUID.TryParse(avatar,out av)) 6908 if (!UUID.TryParse(avatar,out av))
6479 { 6909 {
6480 LSLError("First parameter to llDialog needs to be a key"); 6910 //LSLError("First parameter to llDialog needs to be a key");
6481 return; 6911 return;
6482 } 6912 }
6483 if (buttons.Length < 1) 6913 if (buttons.Length < 1)
6484 { 6914 {
6485 LSLError("No less than 1 button can be shown"); 6915 buttons.Add("OK");
6486 return;
6487 } 6916 }
6488 if (buttons.Length > 12) 6917 if (buttons.Length > 12)
6489 { 6918 {
@@ -6500,7 +6929,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6500 } 6929 }
6501 if (buttons.Data[i].ToString().Length > 24) 6930 if (buttons.Data[i].ToString().Length > 24)
6502 { 6931 {
6503 LSLError("button label cannot be longer than 24 characters"); 6932 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6504 return; 6933 return;
6505 } 6934 }
6506 buts[i] = buttons.Data[i].ToString(); 6935 buts[i] = buttons.Data[i].ToString();
@@ -6559,22 +6988,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6559 } 6988 }
6560 6989
6561 // copy the first script found with this inventory name 6990 // copy the first script found with this inventory name
6562 lock (m_host.TaskInventory) 6991 TaskInventoryItem scriptItem = null;
6992 m_host.TaskInventory.LockItemsForRead(true);
6993 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6563 { 6994 {
6564 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6995 if (inv.Value.Name == name)
6565 { 6996 {
6566 if (inv.Value.Name == name) 6997 // make sure the object is a script
6998 if (10 == inv.Value.Type)
6567 { 6999 {
6568 // make sure the object is a script 7000 found = true;
6569 if (10 == inv.Value.Type) 7001 srcId = inv.Key;
6570 { 7002 scriptItem = inv.Value;
6571 found = true; 7003 break;
6572 srcId = inv.Key;
6573 break;
6574 }
6575 } 7004 }
6576 } 7005 }
6577 } 7006 }
7007 m_host.TaskInventory.LockItemsForRead(false);
6578 7008
6579 if (!found) 7009 if (!found)
6580 { 7010 {
@@ -6582,8 +7012,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6582 return; 7012 return;
6583 } 7013 }
6584 7014
6585 // the rest of the permission checks are done in RezScript, so check the pin there as well 7015 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6586 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7016 if (dest != null)
7017 {
7018 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7019 {
7020 // the rest of the permission checks are done in RezScript, so check the pin there as well
7021 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7022
7023 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7024 m_host.Inventory.RemoveInventoryItem(srcId);
7025 }
7026 }
6587 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7027 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6588 ScriptSleep(3000); 7028 ScriptSleep(3000);
6589 } 7029 }
@@ -6646,19 +7086,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6646 public LSL_String llMD5String(string src, int nonce) 7086 public LSL_String llMD5String(string src, int nonce)
6647 { 7087 {
6648 m_host.AddScriptLPS(1); 7088 m_host.AddScriptLPS(1);
6649 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7089 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6650 } 7090 }
6651 7091
6652 public LSL_String llSHA1String(string src) 7092 public LSL_String llSHA1String(string src)
6653 { 7093 {
6654 m_host.AddScriptLPS(1); 7094 m_host.AddScriptLPS(1);
6655 return Util.SHA1Hash(src).ToLower(); 7095 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6656 } 7096 }
6657 7097
6658 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7098 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6659 { 7099 {
6660 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7100 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6661 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7101 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7102 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7103 return shapeBlock;
6662 7104
6663 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7105 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6664 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7106 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6763,6 +7205,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6763 // Prim type box, cylinder and prism. 7205 // Prim type box, cylinder and prism.
6764 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) 7206 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)
6765 { 7207 {
7208 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7209 return;
7210
6766 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7211 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6767 ObjectShapePacket.ObjectDataBlock shapeBlock; 7212 ObjectShapePacket.ObjectDataBlock shapeBlock;
6768 7213
@@ -6816,6 +7261,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6816 // Prim type sphere. 7261 // Prim type sphere.
6817 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7262 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6818 { 7263 {
7264 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7265 return;
7266
6819 ObjectShapePacket.ObjectDataBlock shapeBlock; 7267 ObjectShapePacket.ObjectDataBlock shapeBlock;
6820 7268
6821 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7269 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6857,6 +7305,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6857 // Prim type torus, tube and ring. 7305 // Prim type torus, tube and ring.
6858 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) 7306 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)
6859 { 7307 {
7308 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7309 return;
7310
6860 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7311 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6861 ObjectShapePacket.ObjectDataBlock shapeBlock; 7312 ObjectShapePacket.ObjectDataBlock shapeBlock;
6862 7313
@@ -6992,6 +7443,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6992 // Prim type sculpt. 7443 // Prim type sculpt.
6993 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7444 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6994 { 7445 {
7446 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7447 return;
7448
6995 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7449 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6996 UUID sculptId; 7450 UUID sculptId;
6997 7451
@@ -7008,13 +7462,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7008 shapeBlock.PathScaleX = 100; 7462 shapeBlock.PathScaleX = 100;
7009 shapeBlock.PathScaleY = 150; 7463 shapeBlock.PathScaleY = 150;
7010 7464
7011 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7465 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
7012 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7466 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
7013 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7467 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
7014 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7468 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
7015 { 7469 {
7016 // default 7470 // default
7017 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7471 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7018 } 7472 }
7019 7473
7020 part.Shape.SetSculptProperties((byte)type, sculptId); 7474 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7030,32 +7484,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7030 ScriptSleep(200); 7484 ScriptSleep(200);
7031 } 7485 }
7032 7486
7033 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7487 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7034 { 7488 {
7035 m_host.AddScriptLPS(1); 7489 m_host.AddScriptLPS(1);
7036 7490
7037 setLinkPrimParams(linknumber, rules); 7491 setLinkPrimParams(linknumber, rules);
7038
7039 ScriptSleep(200);
7040 } 7492 }
7041 7493
7042 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7494 private void setLinkPrimParams(int linknumber, LSL_List rules)
7043 { 7495 {
7044 m_host.AddScriptLPS(1); 7496 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7497 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7498 if (parts.Count>0)
7499 {
7500 try
7501 {
7502 parts[0].ParentGroup.areUpdatesSuspended = true;
7503 foreach (SceneObjectPart part in parts)
7504 SetPrimParams(part, rules);
7505 }
7506 finally
7507 {
7508 parts[0].ParentGroup.areUpdatesSuspended = false;
7509 }
7510 }
7511 if (avatars.Count > 0)
7512 {
7513 foreach (ScenePresence avatar in avatars)
7514 SetPrimParams(avatar, rules);
7515 }
7516 }
7045 7517
7046 setLinkPrimParams(linknumber, rules); 7518 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7519 {
7520 llSetLinkPrimitiveParamsFast(linknumber, rules);
7521 ScriptSleep(200);
7047 } 7522 }
7048 7523
7049 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7524 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7050 { 7525 {
7051 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7526 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7527 //We only support PRIM_POSITION and PRIM_ROTATION
7052 7528
7053 foreach (SceneObjectPart part in parts) 7529 int idx = 0;
7054 SetPrimParams(part, rules); 7530
7531 while (idx < rules.Length)
7532 {
7533 int code = rules.GetLSLIntegerItem(idx++);
7534
7535 int remain = rules.Length - idx;
7536
7537
7538
7539 switch (code)
7540 {
7541 case (int)ScriptBaseClass.PRIM_POSITION:
7542 if (remain < 1)
7543 return;
7544 LSL_Vector v;
7545 v = rules.GetVector3Item(idx++);
7546 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7547 av.SendAvatarDataToAllAgents();
7548
7549 break;
7550
7551 case (int)ScriptBaseClass.PRIM_ROTATION:
7552 if (remain < 1)
7553 return;
7554 LSL_Rotation r;
7555 r = rules.GetQuaternionItem(idx++);
7556 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7557 av.SendAvatarDataToAllAgents();
7558 break;
7559 }
7560 }
7055 } 7561 }
7056 7562
7057 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7563 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7058 { 7564 {
7565 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7566 return;
7567
7059 int idx = 0; 7568 int idx = 0;
7060 7569
7061 bool positionChanged = false; 7570 bool positionChanged = false;
@@ -7083,6 +7592,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7083 currentPosition = GetSetPosTarget(part, v, currentPosition); 7592 currentPosition = GetSetPosTarget(part, v, currentPosition);
7084 7593
7085 break; 7594 break;
7595 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7596 if (remain < 1)
7597 return;
7598
7599 v=rules.GetVector3Item(idx++);
7600 positionChanged = true;
7601 currentPosition = GetSetPosTarget(part, v, currentPosition);
7602
7603 break;
7086 case (int)ScriptBaseClass.PRIM_SIZE: 7604 case (int)ScriptBaseClass.PRIM_SIZE:
7087 if (remain < 1) 7605 if (remain < 1)
7088 return; 7606 return;
@@ -7460,6 +7978,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7460 } 7978 }
7461 } 7979 }
7462 } 7980 }
7981
7982 if (positionChanged)
7983 {
7984 if (part.ParentGroup.RootPart == part)
7985 {
7986 SceneObjectGroup parent = part.ParentGroup;
7987 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7988 }
7989 else
7990 {
7991 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7992 SceneObjectGroup parent = part.ParentGroup;
7993 parent.HasGroupChanged = true;
7994 parent.ScheduleGroupForTerseUpdate();
7995 }
7996 }
7463 } 7997 }
7464 7998
7465 public LSL_String llStringToBase64(string str) 7999 public LSL_String llStringToBase64(string str)
@@ -7608,13 +8142,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7608 public LSL_Integer llGetNumberOfPrims() 8142 public LSL_Integer llGetNumberOfPrims()
7609 { 8143 {
7610 m_host.AddScriptLPS(1); 8144 m_host.AddScriptLPS(1);
7611 int avatarCount = 0; 8145 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7612 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8146
7613 {
7614 if (presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7615 avatarCount++;
7616 });
7617
7618 return m_host.ParentGroup.PrimCount + avatarCount; 8147 return m_host.ParentGroup.PrimCount + avatarCount;
7619 } 8148 }
7620 8149
@@ -7630,55 +8159,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7630 m_host.AddScriptLPS(1); 8159 m_host.AddScriptLPS(1);
7631 UUID objID = UUID.Zero; 8160 UUID objID = UUID.Zero;
7632 LSL_List result = new LSL_List(); 8161 LSL_List result = new LSL_List();
8162
8163 // If the ID is not valid, return null result
7633 if (!UUID.TryParse(obj, out objID)) 8164 if (!UUID.TryParse(obj, out objID))
7634 { 8165 {
7635 result.Add(new LSL_Vector()); 8166 result.Add(new LSL_Vector());
7636 result.Add(new LSL_Vector()); 8167 result.Add(new LSL_Vector());
7637 return result; 8168 return result;
7638 } 8169 }
8170
8171 // Check if this is an attached prim. If so, replace
8172 // the UUID with the avatar UUID and report it's bounding box
8173 SceneObjectPart part = World.GetSceneObjectPart(objID);
8174 if (part != null && part.ParentGroup.IsAttachment)
8175 objID = part.ParentGroup.AttachedAvatar;
8176
8177 // Find out if this is an avatar ID. If so, return it's box
7639 ScenePresence presence = World.GetScenePresence(objID); 8178 ScenePresence presence = World.GetScenePresence(objID);
7640 if (presence != null) 8179 if (presence != null)
7641 { 8180 {
7642 if (presence.ParentID == 0) // not sat on an object 8181 // As per LSL Wiki, there is no difference between sitting
8182 // and standing avatar since server 1.36
8183 LSL_Vector lower;
8184 LSL_Vector upper;
8185 if (presence.Animator.Animations.DefaultAnimation.AnimID
8186 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7643 { 8187 {
7644 LSL_Vector lower; 8188 // This is for ground sitting avatars
7645 LSL_Vector upper; 8189 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7646 if (presence.Animator.Animations.DefaultAnimation.AnimID 8190 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7647 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8191 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7648 {
7649 // This is for ground sitting avatars
7650 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7651 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7652 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7653 }
7654 else
7655 {
7656 // This is for standing/flying avatars
7657 float height = presence.Appearance.AvatarHeight / 2.0f;
7658 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7659 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7660 }
7661 result.Add(lower);
7662 result.Add(upper);
7663 return result;
7664 } 8192 }
7665 else 8193 else
7666 { 8194 {
7667 // sitting on an object so we need the bounding box of that 8195 // This is for standing/flying avatars
7668 // which should include the avatar so set the UUID to the 8196 float height = presence.Appearance.AvatarHeight / 2.0f;
7669 // UUID of the object the avatar is sat on and allow it to fall through 8197 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7670 // to processing an object 8198 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7671 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7672 objID = p.UUID;
7673 } 8199 }
8200
8201 // Adjust to the documented error offsets (see LSL Wiki)
8202 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8203 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8204
8205 if (lower.x > upper.x)
8206 lower.x = upper.x;
8207 if (lower.y > upper.y)
8208 lower.y = upper.y;
8209 if (lower.z > upper.z)
8210 lower.z = upper.z;
8211
8212 result.Add(lower);
8213 result.Add(upper);
8214 return result;
7674 } 8215 }
7675 SceneObjectPart part = World.GetSceneObjectPart(objID); 8216
8217 part = World.GetSceneObjectPart(objID);
7676 // Currently only works for single prims without a sitting avatar 8218 // Currently only works for single prims without a sitting avatar
7677 if (part != null) 8219 if (part != null)
7678 { 8220 {
7679 Vector3 halfSize = part.Scale / 2.0f; 8221 float minX;
7680 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8222 float maxX;
7681 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8223 float minY;
8224 float maxY;
8225 float minZ;
8226 float maxZ;
8227
8228 // This BBox is in sim coordinates, with the offset being
8229 // a contained point.
8230 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8231 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8232
8233 minX -= offsets[0].X;
8234 maxX -= offsets[0].X;
8235 minY -= offsets[0].Y;
8236 maxY -= offsets[0].Y;
8237 minZ -= offsets[0].Z;
8238 maxZ -= offsets[0].Z;
8239
8240 LSL_Vector lower;
8241 LSL_Vector upper;
8242
8243 // Adjust to the documented error offsets (see LSL Wiki)
8244 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8245 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8246
8247 if (lower.x > upper.x)
8248 lower.x = upper.x;
8249 if (lower.y > upper.y)
8250 lower.y = upper.y;
8251 if (lower.z > upper.z)
8252 lower.z = upper.z;
8253
7682 result.Add(lower); 8254 result.Add(lower);
7683 result.Add(upper); 8255 result.Add(upper);
7684 return result; 8256 return result;
@@ -7758,13 +8330,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7758 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8330 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7759 part.AbsolutePosition.Y, 8331 part.AbsolutePosition.Y,
7760 part.AbsolutePosition.Z); 8332 part.AbsolutePosition.Z);
7761 // For some reason, the part.AbsolutePosition.* values do not change if the
7762 // linkset is rotated; they always reflect the child prim's world position
7763 // as though the linkset is unrotated. This is incompatible behavior with SL's
7764 // implementation, so will break scripts imported from there (not to mention it
7765 // makes it more difficult to determine a child prim's actual inworld position).
7766 if (part.ParentID != 0)
7767 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7768 res.Add(v); 8333 res.Add(v);
7769 break; 8334 break;
7770 8335
@@ -7935,56 +8500,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7935 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8500 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7936 if (remain < 1) 8501 if (remain < 1)
7937 return res; 8502 return res;
7938 8503 face = (int)rules.GetLSLIntegerItem(idx++);
7939 face=(int)rules.GetLSLIntegerItem(idx++);
7940 8504
7941 tex = part.Shape.Textures; 8505 tex = part.Shape.Textures;
8506 int shiny;
7942 if (face == ScriptBaseClass.ALL_SIDES) 8507 if (face == ScriptBaseClass.ALL_SIDES)
7943 { 8508 {
7944 for (face = 0; face < GetNumberOfSides(part); face++) 8509 for (face = 0; face < GetNumberOfSides(part); face++)
7945 { 8510 {
7946 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8511 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7947 // Convert Shininess to PRIM_SHINY_* 8512 if (shinyness == Shininess.High)
7948 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8513 {
7949 // PRIM_BUMP_* 8514 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7950 res.Add(new LSL_Integer((int)texface.Bump)); 8515 }
8516 else if (shinyness == Shininess.Medium)
8517 {
8518 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8519 }
8520 else if (shinyness == Shininess.Low)
8521 {
8522 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8523 }
8524 else
8525 {
8526 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8527 }
8528 res.Add(new LSL_Integer(shiny));
8529 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7951 } 8530 }
7952 } 8531 }
7953 else 8532 else
7954 { 8533 {
7955 if (face >= 0 && face < GetNumberOfSides(part)) 8534 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8535 if (shinyness == Shininess.High)
7956 { 8536 {
7957 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8537 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7958 // Convert Shininess to PRIM_SHINY_* 8538 }
7959 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8539 else if (shinyness == Shininess.Medium)
7960 // PRIM_BUMP_* 8540 {
7961 res.Add(new LSL_Integer((int)texface.Bump)); 8541 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
7962 } 8542 }
8543 else if (shinyness == Shininess.Low)
8544 {
8545 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8546 }
8547 else
8548 {
8549 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8550 }
8551 res.Add(new LSL_Integer(shiny));
8552 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7963 } 8553 }
7964 break; 8554 break;
7965 8555
7966 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8556 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7967 if (remain < 1) 8557 if (remain < 1)
7968 return res; 8558 return res;
7969 8559 face = (int)rules.GetLSLIntegerItem(idx++);
7970 face=(int)rules.GetLSLIntegerItem(idx++);
7971 8560
7972 tex = part.Shape.Textures; 8561 tex = part.Shape.Textures;
8562 int fullbright;
7973 if (face == ScriptBaseClass.ALL_SIDES) 8563 if (face == ScriptBaseClass.ALL_SIDES)
7974 { 8564 {
7975 for (face = 0; face < GetNumberOfSides(part); face++) 8565 for (face = 0; face < GetNumberOfSides(part); face++)
7976 { 8566 {
7977 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8567 if (tex.GetFace((uint)face).Fullbright == true)
7978 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8568 {
8569 fullbright = ScriptBaseClass.TRUE;
8570 }
8571 else
8572 {
8573 fullbright = ScriptBaseClass.FALSE;
8574 }
8575 res.Add(new LSL_Integer(fullbright));
7979 } 8576 }
7980 } 8577 }
7981 else 8578 else
7982 { 8579 {
7983 if (face >= 0 && face < GetNumberOfSides(part)) 8580 if (tex.GetFace((uint)face).Fullbright == true)
7984 { 8581 {
7985 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8582 fullbright = ScriptBaseClass.TRUE;
7986 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8583 }
8584 else
8585 {
8586 fullbright = ScriptBaseClass.FALSE;
7987 } 8587 }
8588 res.Add(new LSL_Integer(fullbright));
7988 } 8589 }
7989 break; 8590 break;
7990 8591
@@ -8006,27 +8607,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8006 break; 8607 break;
8007 8608
8008 case (int)ScriptBaseClass.PRIM_TEXGEN: 8609 case (int)ScriptBaseClass.PRIM_TEXGEN:
8610 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8009 if (remain < 1) 8611 if (remain < 1)
8010 return res; 8612 return res;
8011 8613 face = (int)rules.GetLSLIntegerItem(idx++);
8012 face=(int)rules.GetLSLIntegerItem(idx++);
8013 8614
8014 tex = part.Shape.Textures; 8615 tex = part.Shape.Textures;
8015 if (face == ScriptBaseClass.ALL_SIDES) 8616 if (face == ScriptBaseClass.ALL_SIDES)
8016 { 8617 {
8017 for (face = 0; face < GetNumberOfSides(part); face++) 8618 for (face = 0; face < GetNumberOfSides(part); face++)
8018 { 8619 {
8019 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8620 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8020 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8621 {
8021 res.Add(new LSL_Integer((uint)texgen >> 1)); 8622 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8623 }
8624 else
8625 {
8626 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8627 }
8022 } 8628 }
8023 } 8629 }
8024 else 8630 else
8025 { 8631 {
8026 if (face >= 0 && face < GetNumberOfSides(part)) 8632 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8027 { 8633 {
8028 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8634 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8029 res.Add(new LSL_Integer((uint)texgen >> 1)); 8635 }
8636 else
8637 {
8638 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8030 } 8639 }
8031 } 8640 }
8032 break; 8641 break;
@@ -8049,28 +8658,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8049 case (int)ScriptBaseClass.PRIM_GLOW: 8658 case (int)ScriptBaseClass.PRIM_GLOW:
8050 if (remain < 1) 8659 if (remain < 1)
8051 return res; 8660 return res;
8052 8661 face = (int)rules.GetLSLIntegerItem(idx++);
8053 face=(int)rules.GetLSLIntegerItem(idx++);
8054 8662
8055 tex = part.Shape.Textures; 8663 tex = part.Shape.Textures;
8664 float primglow;
8056 if (face == ScriptBaseClass.ALL_SIDES) 8665 if (face == ScriptBaseClass.ALL_SIDES)
8057 { 8666 {
8058 for (face = 0; face < GetNumberOfSides(part); face++) 8667 for (face = 0; face < GetNumberOfSides(part); face++)
8059 { 8668 {
8060 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8669 primglow = tex.GetFace((uint)face).Glow;
8061 res.Add(new LSL_Float(texface.Glow)); 8670 res.Add(new LSL_Float(primglow));
8062 } 8671 }
8063 } 8672 }
8064 else 8673 else
8065 { 8674 {
8066 if (face >= 0 && face < GetNumberOfSides(part)) 8675 primglow = tex.GetFace((uint)face).Glow;
8067 { 8676 res.Add(new LSL_Float(primglow));
8068 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8069 res.Add(new LSL_Float(texface.Glow));
8070 }
8071 } 8677 }
8072 break; 8678 break;
8073
8074 case (int)ScriptBaseClass.PRIM_TEXT: 8679 case (int)ScriptBaseClass.PRIM_TEXT:
8075 Color4 textColor = part.GetTextColor(); 8680 Color4 textColor = part.GetTextColor();
8076 res.Add(new LSL_String(part.Text)); 8681 res.Add(new LSL_String(part.Text));
@@ -8622,8 +9227,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8622 // The function returns an ordered list 9227 // The function returns an ordered list
8623 // representing the tokens found in the supplied 9228 // representing the tokens found in the supplied
8624 // sources string. If two successive tokenizers 9229 // sources string. If two successive tokenizers
8625 // are encountered, then a NULL entry is added 9230 // are encountered, then a null-string entry is
8626 // to the list. 9231 // added to the list.
8627 // 9232 //
8628 // It is a precondition that the source and 9233 // It is a precondition that the source and
8629 // toekizer lisst are non-null. If they are null, 9234 // toekizer lisst are non-null. If they are null,
@@ -8631,7 +9236,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8631 // while their lengths are being determined. 9236 // while their lengths are being determined.
8632 // 9237 //
8633 // A small amount of working memoryis required 9238 // A small amount of working memoryis required
8634 // of approximately 8*#tokenizers. 9239 // of approximately 8*#tokenizers + 8*srcstrlen.
8635 // 9240 //
8636 // There are many ways in which this function 9241 // There are many ways in which this function
8637 // can be implemented, this implementation is 9242 // can be implemented, this implementation is
@@ -8647,155 +9252,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8647 // and eliminates redundant tokenizers as soon 9252 // and eliminates redundant tokenizers as soon
8648 // as is possible. 9253 // as is possible.
8649 // 9254 //
8650 // The implementation tries to avoid any copying 9255 // The implementation tries to minimize temporary
8651 // of arrays or other objects. 9256 // garbage generation.
8652 // </remarks> 9257 // </remarks>
8653 9258
8654 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9259 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8655 { 9260 {
8656 int beginning = 0; 9261 return ParseString2List(src, separators, spacers, true);
8657 int srclen = src.Length; 9262 }
8658 int seplen = separators.Length;
8659 object[] separray = separators.Data;
8660 int spclen = spacers.Length;
8661 object[] spcarray = spacers.Data;
8662 int mlen = seplen+spclen;
8663
8664 int[] offset = new int[mlen+1];
8665 bool[] active = new bool[mlen];
8666
8667 int best;
8668 int j;
8669
8670 // Initial capacity reduces resize cost
8671 9263
8672 LSL_List tokens = new LSL_List(); 9264 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9265 {
9266 int srclen = src.Length;
9267 int seplen = separators.Length;
9268 object[] separray = separators.Data;
9269 int spclen = spacers.Length;
9270 object[] spcarray = spacers.Data;
9271 int dellen = 0;
9272 string[] delarray = new string[seplen+spclen];
8673 9273
8674 // All entries are initially valid 9274 int outlen = 0;
9275 string[] outarray = new string[srclen*2+1];
8675 9276
8676 for (int i = 0; i < mlen; i++) 9277 int i, j;
8677 active[i] = true; 9278 string d;
8678 9279
8679 offset[mlen] = srclen; 9280 m_host.AddScriptLPS(1);
8680 9281
8681 while (beginning < srclen) 9282 /*
9283 * Convert separator and spacer lists to C# strings.
9284 * Also filter out null strings so we don't hang.
9285 */
9286 for (i = 0; i < seplen; i ++)
8682 { 9287 {
9288 d = separray[i].ToString();
9289 if (d.Length > 0)
9290 {
9291 delarray[dellen++] = d;
9292 }
9293 }
9294 seplen = dellen;
8683 9295
8684 best = mlen; // as bad as it gets 9296 for (i = 0; i < spclen; i ++)
9297 {
9298 d = spcarray[i].ToString();
9299 if (d.Length > 0)
9300 {
9301 delarray[dellen++] = d;
9302 }
9303 }
8685 9304
8686 // Scan for separators 9305 /*
9306 * Scan through source string from beginning to end.
9307 */
9308 for (i = 0;;)
9309 {
8687 9310
8688 for (j = 0; j < seplen; j++) 9311 /*
9312 * Find earliest delimeter in src starting at i (if any).
9313 */
9314 int earliestDel = -1;
9315 int earliestSrc = srclen;
9316 string earliestStr = null;
9317 for (j = 0; j < dellen; j ++)
8689 { 9318 {
8690 if (separray[j].ToString() == String.Empty) 9319 d = delarray[j];
8691 active[j] = false; 9320 if (d != null)
8692
8693 if (active[j])
8694 { 9321 {
8695 // scan all of the markers 9322 int index = src.IndexOf(d, i);
8696 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9323 if (index < 0)
8697 { 9324 {
8698 // not present at all 9325 delarray[j] = null; // delim nowhere in src, don't check it anymore
8699 active[j] = false;
8700 } 9326 }
8701 else 9327 else if (index < earliestSrc)
8702 { 9328 {
8703 // present and correct 9329 earliestSrc = index; // where delimeter starts in source string
8704 if (offset[j] < offset[best]) 9330 earliestDel = j; // where delimeter is in delarray[]
8705 { 9331 earliestStr = d; // the delimeter string from delarray[]
8706 // closest so far 9332 if (index == i) break; // can't do any better than found at beg of string
8707 best = j;
8708 if (offset[best] == beginning)
8709 break;
8710 }
8711 } 9333 }
8712 } 9334 }
8713 } 9335 }
8714 9336
8715 // Scan for spacers 9337 /*
8716 9338 * Output source string starting at i through start of earliest delimeter.
8717 if (offset[best] != beginning) 9339 */
9340 if (keepNulls || (earliestSrc > i))
8718 { 9341 {
8719 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9342 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8720 {
8721 if (spcarray[j-seplen].ToString() == String.Empty)
8722 active[j] = false;
8723
8724 if (active[j])
8725 {
8726 // scan all of the markers
8727 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8728 {
8729 // not present at all
8730 active[j] = false;
8731 }
8732 else
8733 {
8734 // present and correct
8735 if (offset[j] < offset[best])
8736 {
8737 // closest so far
8738 best = j;
8739 }
8740 }
8741 }
8742 }
8743 } 9343 }
8744 9344
8745 // This is the normal exit from the scanning loop 9345 /*
9346 * If no delimeter found at or after i, we're done scanning.
9347 */
9348 if (earliestDel < 0) break;
8746 9349
8747 if (best == mlen) 9350 /*
9351 * If delimeter was a spacer, output the spacer.
9352 */
9353 if (earliestDel >= seplen)
8748 { 9354 {
8749 // no markers were found on this pass 9355 outarray[outlen++] = earliestStr;
8750 // so we're pretty much done
8751 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8752 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8753 break;
8754 } 9356 }
8755 9357
8756 // Otherwise we just add the newly delimited token 9358 /*
8757 // and recalculate where the search should continue. 9359 * Look at rest of src string following delimeter.
8758 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9360 */
8759 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9361 i = earliestSrc + earliestStr.Length;
8760
8761 if (best < seplen)
8762 {
8763 beginning = offset[best] + (separray[best].ToString()).Length;
8764 }
8765 else
8766 {
8767 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8768 string str = spcarray[best - seplen].ToString();
8769 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8770 tokens.Add(new LSL_String(str));
8771 }
8772 } 9362 }
8773 9363
8774 // This an awkward an not very intuitive boundary case. If the 9364 /*
8775 // last substring is a tokenizer, then there is an implied trailing 9365 * Make up an exact-sized output array suitable for an LSL_List object.
8776 // null list entry. Hopefully the single comparison will not be too 9366 */
8777 // arduous. Alternatively the 'break' could be replced with a return 9367 object[] outlist = new object[outlen];
8778 // but that's shabby programming. 9368 for (i = 0; i < outlen; i ++)
8779
8780 if ((beginning == srclen) && (keepNulls))
8781 { 9369 {
8782 if (srclen != 0) 9370 outlist[i] = new LSL_String(outarray[i]);
8783 tokens.Add(new LSL_String(""));
8784 } 9371 }
8785 9372 return new LSL_List(outlist);
8786 return tokens;
8787 }
8788
8789 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8790 {
8791 m_host.AddScriptLPS(1);
8792 return this.ParseString(src, separators, spacers, false);
8793 }
8794
8795 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8796 {
8797 m_host.AddScriptLPS(1);
8798 return this.ParseString(src, separators, spacers, true);
8799 } 9373 }
8800 9374
8801 public LSL_Integer llGetObjectPermMask(int mask) 9375 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8872,28 +9446,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8872 { 9446 {
8873 m_host.AddScriptLPS(1); 9447 m_host.AddScriptLPS(1);
8874 9448
8875 lock (m_host.TaskInventory) 9449 m_host.TaskInventory.LockItemsForRead(true);
9450 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8876 { 9451 {
8877 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9452 if (inv.Value.Name == item)
8878 { 9453 {
8879 if (inv.Value.Name == item) 9454 m_host.TaskInventory.LockItemsForRead(false);
9455 switch (mask)
8880 { 9456 {
8881 switch (mask) 9457 case 0:
8882 { 9458 return (int)inv.Value.BasePermissions;
8883 case 0: 9459 case 1:
8884 return (int)inv.Value.BasePermissions; 9460 return (int)inv.Value.CurrentPermissions;
8885 case 1: 9461 case 2:
8886 return (int)inv.Value.CurrentPermissions; 9462 return (int)inv.Value.GroupPermissions;
8887 case 2: 9463 case 3:
8888 return (int)inv.Value.GroupPermissions; 9464 return (int)inv.Value.EveryonePermissions;
8889 case 3: 9465 case 4:
8890 return (int)inv.Value.EveryonePermissions; 9466 return (int)inv.Value.NextPermissions;
8891 case 4:
8892 return (int)inv.Value.NextPermissions;
8893 }
8894 } 9467 }
8895 } 9468 }
8896 } 9469 }
9470 m_host.TaskInventory.LockItemsForRead(false);
8897 9471
8898 return -1; 9472 return -1;
8899 } 9473 }
@@ -8940,16 +9514,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8940 { 9514 {
8941 m_host.AddScriptLPS(1); 9515 m_host.AddScriptLPS(1);
8942 9516
8943 lock (m_host.TaskInventory) 9517 m_host.TaskInventory.LockItemsForRead(true);
9518 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8944 { 9519 {
8945 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9520 if (inv.Value.Name == item)
8946 { 9521 {
8947 if (inv.Value.Name == item) 9522 m_host.TaskInventory.LockItemsForRead(false);
8948 { 9523 return inv.Value.CreatorID.ToString();
8949 return inv.Value.CreatorID.ToString();
8950 }
8951 } 9524 }
8952 } 9525 }
9526 m_host.TaskInventory.LockItemsForRead(false);
8953 9527
8954 llSay(0, "No item name '" + item + "'"); 9528 llSay(0, "No item name '" + item + "'");
8955 9529
@@ -9097,7 +9671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9097 } 9671 }
9098 9672
9099 /// <summary> 9673 /// <summary>
9100 /// illListReplaceList removes the sub-list defined by the inclusive indices 9674 /// llListReplaceList removes the sub-list defined by the inclusive indices
9101 /// start and end and inserts the src list in its place. The inclusive 9675 /// start and end and inserts the src list in its place. The inclusive
9102 /// nature of the indices means that at least one element must be deleted 9676 /// nature of the indices means that at least one element must be deleted
9103 /// if the indices are within the bounds of the existing list. I.e. 2,2 9677 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9154,16 +9728,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9154 // based upon end. Note that if end exceeds the upper 9728 // based upon end. Note that if end exceeds the upper
9155 // bound in this case, the entire destination list 9729 // bound in this case, the entire destination list
9156 // is removed. 9730 // is removed.
9157 else 9731 else if (start == 0)
9158 { 9732 {
9159 if (end + 1 < dest.Length) 9733 if (end + 1 < dest.Length)
9160 {
9161 return src + dest.GetSublist(end + 1, -1); 9734 return src + dest.GetSublist(end + 1, -1);
9162 }
9163 else 9735 else
9164 {
9165 return src; 9736 return src;
9166 } 9737 }
9738 else // Start < 0
9739 {
9740 if (end + 1 < dest.Length)
9741 return dest.GetSublist(end + 1, -1);
9742 else
9743 return new LSL_List();
9167 } 9744 }
9168 } 9745 }
9169 // Finally, if start > end, we strip away a prefix and 9746 // Finally, if start > end, we strip away a prefix and
@@ -9214,17 +9791,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9214 int width = 0; 9791 int width = 0;
9215 int height = 0; 9792 int height = 0;
9216 9793
9217 ParcelMediaCommandEnum? commandToSend = null; 9794 uint commandToSend = 0;
9218 float time = 0.0f; // default is from start 9795 float time = 0.0f; // default is from start
9219 9796
9220 ScenePresence presence = null; 9797 ScenePresence presence = null;
9221 9798
9222 for (int i = 0; i < commandList.Data.Length; i++) 9799 for (int i = 0; i < commandList.Data.Length; i++)
9223 { 9800 {
9224 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9801 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9225 switch (command) 9802 switch (command)
9226 { 9803 {
9227 case ParcelMediaCommandEnum.Agent: 9804 case (uint)ParcelMediaCommandEnum.Agent:
9228 // we send only to one agent 9805 // we send only to one agent
9229 if ((i + 1) < commandList.Length) 9806 if ((i + 1) < commandList.Length)
9230 { 9807 {
@@ -9241,25 +9818,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9241 } 9818 }
9242 break; 9819 break;
9243 9820
9244 case ParcelMediaCommandEnum.Loop: 9821 case (uint)ParcelMediaCommandEnum.Loop:
9245 loop = 1; 9822 loop = 1;
9246 commandToSend = command; 9823 commandToSend = command;
9247 update = true; //need to send the media update packet to set looping 9824 update = true; //need to send the media update packet to set looping
9248 break; 9825 break;
9249 9826
9250 case ParcelMediaCommandEnum.Play: 9827 case (uint)ParcelMediaCommandEnum.Play:
9251 loop = 0; 9828 loop = 0;
9252 commandToSend = command; 9829 commandToSend = command;
9253 update = true; //need to send the media update packet to make sure it doesn't loop 9830 update = true; //need to send the media update packet to make sure it doesn't loop
9254 break; 9831 break;
9255 9832
9256 case ParcelMediaCommandEnum.Pause: 9833 case (uint)ParcelMediaCommandEnum.Pause:
9257 case ParcelMediaCommandEnum.Stop: 9834 case (uint)ParcelMediaCommandEnum.Stop:
9258 case ParcelMediaCommandEnum.Unload: 9835 case (uint)ParcelMediaCommandEnum.Unload:
9259 commandToSend = command; 9836 commandToSend = command;
9260 break; 9837 break;
9261 9838
9262 case ParcelMediaCommandEnum.Url: 9839 case (uint)ParcelMediaCommandEnum.Url:
9263 if ((i + 1) < commandList.Length) 9840 if ((i + 1) < commandList.Length)
9264 { 9841 {
9265 if (commandList.Data[i + 1] is LSL_String) 9842 if (commandList.Data[i + 1] is LSL_String)
@@ -9272,7 +9849,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9272 } 9849 }
9273 break; 9850 break;
9274 9851
9275 case ParcelMediaCommandEnum.Texture: 9852 case (uint)ParcelMediaCommandEnum.Texture:
9276 if ((i + 1) < commandList.Length) 9853 if ((i + 1) < commandList.Length)
9277 { 9854 {
9278 if (commandList.Data[i + 1] is LSL_String) 9855 if (commandList.Data[i + 1] is LSL_String)
@@ -9285,7 +9862,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9285 } 9862 }
9286 break; 9863 break;
9287 9864
9288 case ParcelMediaCommandEnum.Time: 9865 case (uint)ParcelMediaCommandEnum.Time:
9289 if ((i + 1) < commandList.Length) 9866 if ((i + 1) < commandList.Length)
9290 { 9867 {
9291 if (commandList.Data[i + 1] is LSL_Float) 9868 if (commandList.Data[i + 1] is LSL_Float)
@@ -9297,7 +9874,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9297 } 9874 }
9298 break; 9875 break;
9299 9876
9300 case ParcelMediaCommandEnum.AutoAlign: 9877 case (uint)ParcelMediaCommandEnum.AutoAlign:
9301 if ((i + 1) < commandList.Length) 9878 if ((i + 1) < commandList.Length)
9302 { 9879 {
9303 if (commandList.Data[i + 1] is LSL_Integer) 9880 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9311,7 +9888,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9311 } 9888 }
9312 break; 9889 break;
9313 9890
9314 case ParcelMediaCommandEnum.Type: 9891 case (uint)ParcelMediaCommandEnum.Type:
9315 if ((i + 1) < commandList.Length) 9892 if ((i + 1) < commandList.Length)
9316 { 9893 {
9317 if (commandList.Data[i + 1] is LSL_String) 9894 if (commandList.Data[i + 1] is LSL_String)
@@ -9324,7 +9901,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9324 } 9901 }
9325 break; 9902 break;
9326 9903
9327 case ParcelMediaCommandEnum.Desc: 9904 case (uint)ParcelMediaCommandEnum.Desc:
9328 if ((i + 1) < commandList.Length) 9905 if ((i + 1) < commandList.Length)
9329 { 9906 {
9330 if (commandList.Data[i + 1] is LSL_String) 9907 if (commandList.Data[i + 1] is LSL_String)
@@ -9337,7 +9914,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9337 } 9914 }
9338 break; 9915 break;
9339 9916
9340 case ParcelMediaCommandEnum.Size: 9917 case (uint)ParcelMediaCommandEnum.Size:
9341 if ((i + 2) < commandList.Length) 9918 if ((i + 2) < commandList.Length)
9342 { 9919 {
9343 if (commandList.Data[i + 1] is LSL_Integer) 9920 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9407,7 +9984,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9407 } 9984 }
9408 } 9985 }
9409 9986
9410 if (commandToSend != null) 9987 if (commandToSend != 0)
9411 { 9988 {
9412 // the commandList contained a start/stop/... command, too 9989 // the commandList contained a start/stop/... command, too
9413 if (presence == null) 9990 if (presence == null)
@@ -9444,7 +10021,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9444 10021
9445 if (aList.Data[i] != null) 10022 if (aList.Data[i] != null)
9446 { 10023 {
9447 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10024 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9448 { 10025 {
9449 case ParcelMediaCommandEnum.Url: 10026 case ParcelMediaCommandEnum.Url:
9450 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10027 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9487,16 +10064,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9487 { 10064 {
9488 m_host.AddScriptLPS(1); 10065 m_host.AddScriptLPS(1);
9489 10066
9490 lock (m_host.TaskInventory) 10067 m_host.TaskInventory.LockItemsForRead(true);
10068 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9491 { 10069 {
9492 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10070 if (inv.Value.Name == name)
9493 { 10071 {
9494 if (inv.Value.Name == name) 10072 m_host.TaskInventory.LockItemsForRead(false);
9495 { 10073 return inv.Value.Type;
9496 return inv.Value.Type;
9497 }
9498 } 10074 }
9499 } 10075 }
10076 m_host.TaskInventory.LockItemsForRead(false);
9500 10077
9501 return -1; 10078 return -1;
9502 } 10079 }
@@ -9507,15 +10084,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9507 10084
9508 if (quick_pay_buttons.Data.Length < 4) 10085 if (quick_pay_buttons.Data.Length < 4)
9509 { 10086 {
9510 LSLError("List must have at least 4 elements"); 10087 int x;
9511 return; 10088 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10089 {
10090 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10091 }
9512 } 10092 }
9513 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10093 int[] nPrice = new int[5];
9514 10094 nPrice[0] = price;
9515 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10095 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9516 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10096 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9517 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10097 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9518 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10098 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10099 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9519 m_host.ParentGroup.HasGroupChanged = true; 10100 m_host.ParentGroup.HasGroupChanged = true;
9520 } 10101 }
9521 10102
@@ -9527,17 +10108,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9527 if (invItemID == UUID.Zero) 10108 if (invItemID == UUID.Zero)
9528 return new LSL_Vector(); 10109 return new LSL_Vector();
9529 10110
9530 lock (m_host.TaskInventory) 10111 m_host.TaskInventory.LockItemsForRead(true);
10112 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9531 { 10113 {
9532 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10114 m_host.TaskInventory.LockItemsForRead(false);
9533 return new LSL_Vector(); 10115 return new LSL_Vector();
10116 }
9534 10117
9535 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10118 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9536 { 10119 {
9537 ShoutError("No permissions to track the camera"); 10120 ShoutError("No permissions to track the camera");
9538 return new LSL_Vector(); 10121 m_host.TaskInventory.LockItemsForRead(false);
9539 } 10122 return new LSL_Vector();
9540 } 10123 }
10124 m_host.TaskInventory.LockItemsForRead(false);
9541 10125
9542 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10126 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9543 if (presence != null) 10127 if (presence != null)
@@ -9555,17 +10139,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9555 if (invItemID == UUID.Zero) 10139 if (invItemID == UUID.Zero)
9556 return new LSL_Rotation(); 10140 return new LSL_Rotation();
9557 10141
9558 lock (m_host.TaskInventory) 10142 m_host.TaskInventory.LockItemsForRead(true);
10143 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9559 { 10144 {
9560 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10145 m_host.TaskInventory.LockItemsForRead(false);
9561 return new LSL_Rotation(); 10146 return new LSL_Rotation();
9562
9563 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9564 {
9565 ShoutError("No permissions to track the camera");
9566 return new LSL_Rotation();
9567 }
9568 } 10147 }
10148 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10149 {
10150 ShoutError("No permissions to track the camera");
10151 m_host.TaskInventory.LockItemsForRead(false);
10152 return new LSL_Rotation();
10153 }
10154 m_host.TaskInventory.LockItemsForRead(false);
9569 10155
9570 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10156 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9571 if (presence != null) 10157 if (presence != null)
@@ -9627,8 +10213,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9627 { 10213 {
9628 m_host.AddScriptLPS(1); 10214 m_host.AddScriptLPS(1);
9629 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10215 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9630 if (detectedParams == null) return; // only works on the first detected avatar 10216 if (detectedParams == null)
9631 10217 {
10218 if (m_host.ParentGroup.IsAttachment == true)
10219 {
10220 detectedParams = new DetectParams();
10221 detectedParams.Key = m_host.OwnerID;
10222 }
10223 else
10224 {
10225 return;
10226 }
10227 }
10228
9632 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10229 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9633 if (avatar != null) 10230 if (avatar != null)
9634 { 10231 {
@@ -9636,6 +10233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9636 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10233 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9637 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10234 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9638 } 10235 }
10236
9639 ScriptSleep(1000); 10237 ScriptSleep(1000);
9640 } 10238 }
9641 10239
@@ -9728,14 +10326,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9728 if (objectID == UUID.Zero) return; 10326 if (objectID == UUID.Zero) return;
9729 10327
9730 UUID agentID; 10328 UUID agentID;
9731 lock (m_host.TaskInventory) 10329 m_host.TaskInventory.LockItemsForRead(true);
9732 { 10330 // we need the permission first, to know which avatar we want to set the camera for
9733 // we need the permission first, to know which avatar we want to set the camera for 10331 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9734 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9735 10332
9736 if (agentID == UUID.Zero) return; 10333 if (agentID == UUID.Zero)
9737 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10334 {
10335 m_host.TaskInventory.LockItemsForRead(false);
10336 return;
10337 }
10338 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10339 {
10340 m_host.TaskInventory.LockItemsForRead(false);
10341 return;
9738 } 10342 }
10343 m_host.TaskInventory.LockItemsForRead(false);
9739 10344
9740 ScenePresence presence = World.GetScenePresence(agentID); 10345 ScenePresence presence = World.GetScenePresence(agentID);
9741 10346
@@ -9744,12 +10349,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9744 10349
9745 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10350 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9746 object[] data = rules.Data; 10351 object[] data = rules.Data;
9747 for (int i = 0; i < data.Length; ++i) { 10352 for (int i = 0; i < data.Length; ++i)
10353 {
9748 int type = Convert.ToInt32(data[i++].ToString()); 10354 int type = Convert.ToInt32(data[i++].ToString());
9749 if (i >= data.Length) break; // odd number of entries => ignore the last 10355 if (i >= data.Length) break; // odd number of entries => ignore the last
9750 10356
9751 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10357 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9752 switch (type) { 10358 switch (type)
10359 {
9753 case ScriptBaseClass.CAMERA_FOCUS: 10360 case ScriptBaseClass.CAMERA_FOCUS:
9754 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10361 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9755 case ScriptBaseClass.CAMERA_POSITION: 10362 case ScriptBaseClass.CAMERA_POSITION:
@@ -9785,12 +10392,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9785 10392
9786 // we need the permission first, to know which avatar we want to clear the camera for 10393 // we need the permission first, to know which avatar we want to clear the camera for
9787 UUID agentID; 10394 UUID agentID;
9788 lock (m_host.TaskInventory) 10395 m_host.TaskInventory.LockItemsForRead(true);
10396 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10397 if (agentID == UUID.Zero)
9789 { 10398 {
9790 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10399 m_host.TaskInventory.LockItemsForRead(false);
9791 if (agentID == UUID.Zero) return; 10400 return;
9792 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return;
9793 } 10401 }
10402 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10403 {
10404 m_host.TaskInventory.LockItemsForRead(false);
10405 return;
10406 }
10407 m_host.TaskInventory.LockItemsForRead(false);
9794 10408
9795 ScenePresence presence = World.GetScenePresence(agentID); 10409 ScenePresence presence = World.GetScenePresence(agentID);
9796 10410
@@ -9857,19 +10471,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9857 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10471 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9858 { 10472 {
9859 m_host.AddScriptLPS(1); 10473 m_host.AddScriptLPS(1);
9860 string ret = String.Empty; 10474
9861 string src1 = llBase64ToString(str1); 10475 if (str1 == String.Empty)
9862 string src2 = llBase64ToString(str2); 10476 return String.Empty;
9863 int c = 0; 10477 if (str2 == String.Empty)
9864 for (int i = 0; i < src1.Length; i++) 10478 return str1;
10479
10480 int len = str2.Length;
10481 if ((len % 4) != 0) // LL is EVIL!!!!
9865 { 10482 {
9866 ret += (char) (src1[i] ^ src2[c]); 10483 while (str2.EndsWith("="))
10484 str2 = str2.Substring(0, str2.Length - 1);
10485
10486 len = str2.Length;
10487 int mod = len % 4;
9867 10488
9868 c++; 10489 if (mod == 1)
9869 if (c >= src2.Length) 10490 str2 = str2.Substring(0, str2.Length - 1);
9870 c = 0; 10491 else if (mod == 2)
10492 str2 += "==";
10493 else if (mod == 3)
10494 str2 += "=";
9871 } 10495 }
9872 return llStringToBase64(ret); 10496
10497 byte[] data1;
10498 byte[] data2;
10499 try
10500 {
10501 data1 = Convert.FromBase64String(str1);
10502 data2 = Convert.FromBase64String(str2);
10503 }
10504 catch (Exception)
10505 {
10506 return new LSL_String(String.Empty);
10507 }
10508
10509 byte[] d2 = new Byte[data1.Length];
10510 int pos = 0;
10511
10512 if (data1.Length <= data2.Length)
10513 {
10514 Array.Copy(data2, 0, d2, 0, data1.Length);
10515 }
10516 else
10517 {
10518 while (pos < data1.Length)
10519 {
10520 len = data1.Length - pos;
10521 if (len > data2.Length)
10522 len = data2.Length;
10523
10524 Array.Copy(data2, 0, d2, pos, len);
10525 pos += len;
10526 }
10527 }
10528
10529 for (pos = 0 ; pos < data1.Length ; pos++ )
10530 data1[pos] ^= d2[pos];
10531
10532 return Convert.ToBase64String(data1);
9873 } 10533 }
9874 10534
9875 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10535 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9926,12 +10586,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9926 Regex r = new Regex(authregex); 10586 Regex r = new Regex(authregex);
9927 int[] gnums = r.GetGroupNumbers(); 10587 int[] gnums = r.GetGroupNumbers();
9928 Match m = r.Match(url); 10588 Match m = r.Match(url);
9929 if (m.Success) { 10589 if (m.Success)
9930 for (int i = 1; i < gnums.Length; i++) { 10590 {
10591 for (int i = 1; i < gnums.Length; i++)
10592 {
9931 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10593 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9932 //CaptureCollection cc = g.Captures; 10594 //CaptureCollection cc = g.Captures;
9933 } 10595 }
9934 if (m.Groups.Count == 5) { 10596 if (m.Groups.Count == 5)
10597 {
9935 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10598 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9936 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10599 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9937 } 10600 }
@@ -10217,15 +10880,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10217 10880
10218 internal UUID ScriptByName(string name) 10881 internal UUID ScriptByName(string name)
10219 { 10882 {
10220 lock (m_host.TaskInventory) 10883 m_host.TaskInventory.LockItemsForRead(true);
10884
10885 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10221 { 10886 {
10222 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10887 if (item.Type == 10 && item.Name == name)
10223 { 10888 {
10224 if (item.Type == 10 && item.Name == name) 10889 m_host.TaskInventory.LockItemsForRead(false);
10225 return item.ItemID; 10890 return item.ItemID;
10226 } 10891 }
10227 } 10892 }
10228 10893
10894 m_host.TaskInventory.LockItemsForRead(false);
10895
10229 return UUID.Zero; 10896 return UUID.Zero;
10230 } 10897 }
10231 10898
@@ -10266,6 +10933,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10266 { 10933 {
10267 m_host.AddScriptLPS(1); 10934 m_host.AddScriptLPS(1);
10268 10935
10936 //Clone is thread safe
10269 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10937 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10270 10938
10271 UUID assetID = UUID.Zero; 10939 UUID assetID = UUID.Zero;
@@ -10328,6 +10996,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10328 { 10996 {
10329 m_host.AddScriptLPS(1); 10997 m_host.AddScriptLPS(1);
10330 10998
10999 //Clone is thread safe
10331 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11000 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10332 11001
10333 UUID assetID = UUID.Zero; 11002 UUID assetID = UUID.Zero;
@@ -10408,15 +11077,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10408 return GetLinkPrimitiveParams(obj, rules); 11077 return GetLinkPrimitiveParams(obj, rules);
10409 } 11078 }
10410 11079
10411 public void print(string str) 11080 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10412 { 11081 {
10413 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11082 List<SceneObjectPart> parts = GetLinkParts(link);
10414 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11083 if (parts.Count < 1)
10415 if (ossl != null) 11084 return 0;
10416 { 11085
10417 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11086 return GetNumberOfSides(parts[0]);
10418 m_log.Info("LSL print():" + str);
10419 }
10420 } 11087 }
10421 11088
10422 private string Name2Username(string name) 11089 private string Name2Username(string name)
@@ -10462,153 +11129,392 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10462 return rq.ToString(); 11129 return rq.ToString();
10463 } 11130 }
10464 11131
11132 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11133 {
11134 m_SayShoutCount = 0;
11135 }
11136
11137 private struct Tri
11138 {
11139 public Vector3 p1;
11140 public Vector3 p2;
11141 public Vector3 p3;
11142 }
11143
11144 private bool InBoundingBox(ScenePresence avatar, Vector3 point)
11145 {
11146 float height = avatar.Appearance.AvatarHeight;
11147 Vector3 b1 = avatar.AbsolutePosition + new Vector3(-0.22f, -0.22f, -height/2);
11148 Vector3 b2 = avatar.AbsolutePosition + new Vector3(0.22f, 0.22f, height/2);
11149
11150 if (point.X > b1.X && point.X < b2.X &&
11151 point.Y > b1.Y && point.Y < b2.Y &&
11152 point.Z > b1.Z && point.Z < b2.Z)
11153 return true;
11154 return false;
11155 }
11156
11157 private ContactResult[] AvatarIntersection(Vector3 rayStart, Vector3 rayEnd)
11158 {
11159 List<ContactResult> contacts = new List<ContactResult>();
11160
11161 Vector3 ab = rayEnd - rayStart;
11162
11163 World.ForEachScenePresence(delegate(ScenePresence sp)
11164 {
11165 Vector3 ac = sp.AbsolutePosition - rayStart;
11166 Vector3 bc = sp.AbsolutePosition - rayEnd;
11167
11168 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11169
11170 if (d > 1.5)
11171 return;
11172
11173 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11174
11175 if (d2 > 0)
11176 return;
11177
11178 double dp = Math.Sqrt(Vector3.Mag(ac) * Vector3.Mag(ac) - d * d);
11179 Vector3 p = rayStart + Vector3.Divide(Vector3.Multiply(ab, (float)dp), (float)Vector3.Mag(ab));
11180
11181 if (!InBoundingBox(sp, p))
11182 return;
11183
11184 ContactResult result = new ContactResult ();
11185 result.ConsumerID = sp.LocalId;
11186 result.Depth = Vector3.Distance(rayStart, p);
11187 result.Normal = Vector3.Zero;
11188 result.Pos = p;
11189
11190 contacts.Add(result);
11191 });
11192
11193 return contacts.ToArray();
11194 }
11195
11196 private ContactResult[] ObjectIntersection(Vector3 rayStart, Vector3 rayEnd, bool includePhysical, bool includeNonPhysical, bool includePhantom)
11197 {
11198 Ray ray = new Ray(rayStart, Vector3.Normalize(rayEnd - rayStart));
11199 List<ContactResult> contacts = new List<ContactResult>();
11200
11201 Vector3 ab = rayEnd - rayStart;
11202
11203 World.ForEachSOG(delegate(SceneObjectGroup group)
11204 {
11205 if (m_host.ParentGroup == group)
11206 return;
11207
11208 if (group.IsAttachment)
11209 return;
11210
11211 if (group.RootPart.PhysActor == null)
11212 {
11213 if (!includePhantom)
11214 return;
11215 }
11216 else
11217 {
11218 if (group.RootPart.PhysActor.IsPhysical)
11219 {
11220 if (!includePhysical)
11221 return;
11222 }
11223 else
11224 {
11225 if (!includeNonPhysical)
11226 return;
11227 }
11228 }
11229
11230 // Find the radius ouside of which we don't even need to hit test
11231 float minX;
11232 float maxX;
11233 float minY;
11234 float maxY;
11235 float minZ;
11236 float maxZ;
11237
11238 float radius = 0.0f;
11239
11240 group.GetAxisAlignedBoundingBoxRaw(out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
11241
11242 if (Math.Abs(minX) > radius)
11243 radius = Math.Abs(minX);
11244 if (Math.Abs(minY) > radius)
11245 radius = Math.Abs(minY);
11246 if (Math.Abs(minZ) > radius)
11247 radius = Math.Abs(minZ);
11248 if (Math.Abs(maxX) > radius)
11249 radius = Math.Abs(maxX);
11250 if (Math.Abs(maxY) > radius)
11251 radius = Math.Abs(maxY);
11252 if (Math.Abs(maxZ) > radius)
11253 radius = Math.Abs(maxZ);
11254
11255 Vector3 ac = group.AbsolutePosition - rayStart;
11256 Vector3 bc = group.AbsolutePosition - rayEnd;
11257
11258 double d = Math.Abs(Vector3.Mag(Vector3.Cross(ab, ac)) / Vector3.Distance(rayStart, rayEnd));
11259
11260 // Too far off ray, don't bother
11261 if (d > radius)
11262 return;
11263
11264 // Behind ray, drop
11265 double d2 = Vector3.Dot(Vector3.Negate(ab), ac);
11266 if (d2 > 0)
11267 return;
11268
11269 EntityIntersection intersection = group.TestIntersection(ray, true, false);
11270 // Miss.
11271 if (!intersection.HitTF)
11272 return;
11273
11274 ContactResult result = new ContactResult ();
11275 result.ConsumerID = group.LocalId;
11276 result.Depth = intersection.distance;
11277 result.Normal = intersection.normal;
11278 result.Pos = intersection.ipoint;
11279
11280 contacts.Add(result);
11281 });
11282
11283 return contacts.ToArray();
11284 }
11285
11286 private ContactResult? GroundIntersection(Vector3 rayStart, Vector3 rayEnd)
11287 {
11288 double[,] heightfield = World.Heightmap.GetDoubles();
11289 List<ContactResult> contacts = new List<ContactResult>();
11290
11291 double min = 2048.0;
11292 double max = 0.0;
11293
11294 // Find the min and max of the heightfield
11295 for (int x = 0 ; x < World.Heightmap.Width ; x++)
11296 {
11297 for (int y = 0 ; y < World.Heightmap.Height ; y++)
11298 {
11299 if (heightfield[x, y] > max)
11300 max = heightfield[x, y];
11301 if (heightfield[x, y] < min)
11302 min = heightfield[x, y];
11303 }
11304 }
11305
11306
11307 // A ray extends past rayEnd, but doesn't go back before
11308 // rayStart. If the start is above the highest point of the ground
11309 // and the ray goes up, we can't hit the ground. Ever.
11310 if (rayStart.Z > max && rayEnd.Z >= rayStart.Z)
11311 return null;
11312
11313 // Same for going down
11314 if (rayStart.Z < min && rayEnd.Z <= rayStart.Z)
11315 return null;
11316
11317 List<Tri> trilist = new List<Tri>();
11318
11319 // Create our triangle list
11320 for (int x = 1 ; x < World.Heightmap.Width ; x++)
11321 {
11322 for (int y = 1 ; y < World.Heightmap.Height ; y++)
11323 {
11324 Tri t1 = new Tri();
11325 Tri t2 = new Tri();
11326
11327 Vector3 p1 = new Vector3(x-1, y-1, (float)heightfield[x-1, y-1]);
11328 Vector3 p2 = new Vector3(x, y-1, (float)heightfield[x, y-1]);
11329 Vector3 p3 = new Vector3(x, y, (float)heightfield[x, y]);
11330 Vector3 p4 = new Vector3(x-1, y, (float)heightfield[x-1, y]);
11331
11332 t1.p1 = p1;
11333 t1.p2 = p2;
11334 t1.p3 = p3;
11335
11336 t2.p1 = p3;
11337 t2.p2 = p4;
11338 t2.p3 = p1;
11339
11340 trilist.Add(t1);
11341 trilist.Add(t2);
11342 }
11343 }
11344
11345 // Ray direction
11346 Vector3 rayDirection = rayEnd - rayStart;
11347
11348 foreach (Tri t in trilist)
11349 {
11350 // Compute triangle plane normal and edges
11351 Vector3 u = t.p2 - t.p1;
11352 Vector3 v = t.p3 - t.p1;
11353 Vector3 n = Vector3.Cross(u, v);
11354
11355 if (n == Vector3.Zero)
11356 continue;
11357
11358 Vector3 w0 = rayStart - t.p1;
11359 double a = -Vector3.Dot(n, w0);
11360 double b = Vector3.Dot(n, rayDirection);
11361
11362 // Not intersecting the plane, or in plane (same thing)
11363 // Ignoring this MAY cause the ground to not be detected
11364 // sometimes
11365 if (Math.Abs(b) < 0.000001)
11366 continue;
11367
11368 double r = a / b;
11369
11370 // ray points away from plane
11371 if (r < 0.0)
11372 continue;
11373
11374 Vector3 ip = rayStart + Vector3.Multiply(rayDirection, (float)r);
11375
11376 float uu = Vector3.Dot(u, u);
11377 float uv = Vector3.Dot(u, v);
11378 float vv = Vector3.Dot(v, v);
11379 Vector3 w = ip - t.p1;
11380 float wu = Vector3.Dot(w, u);
11381 float wv = Vector3.Dot(w, v);
11382 float d = uv * uv - uu * vv;
11383
11384 float cs = (uv * wv - vv * wu) / d;
11385 if (cs < 0 || cs > 1.0)
11386 continue;
11387 float ct = (uv * wu - uu * wv) / d;
11388 if (ct < 0 || (cs + ct) > 1.0)
11389 continue;
11390
11391 // Add contact point
11392 ContactResult result = new ContactResult ();
11393 result.ConsumerID = 0;
11394 result.Depth = Vector3.Distance(rayStart, ip);
11395 result.Normal = n;
11396 result.Pos = ip;
11397
11398 contacts.Add(result);
11399 }
11400
11401 if (contacts.Count == 0)
11402 return null;
11403
11404 contacts.Sort(delegate(ContactResult a, ContactResult b)
11405 {
11406 return (int)(a.Depth - b.Depth);
11407 });
11408
11409 return contacts[0];
11410 }
11411
10465 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11412 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10466 { 11413 {
11414 LSL_List list = new LSL_List();
11415
10467 m_host.AddScriptLPS(1); 11416 m_host.AddScriptLPS(1);
10468 11417
10469 Vector3 dir = new Vector3((float)(end-start).x, (float)(end-start).y, (float)(end-start).z); 11418 Vector3 rayStart = new Vector3((float)start.x, (float)start.y, (float)start.z);
10470 Vector3 startvector = new Vector3((float)start.x, (float)start.y, (float)start.z); 11419 Vector3 rayEnd = new Vector3((float)end.x, (float)end.y, (float)end.z);
10471 Vector3 endvector = new Vector3((float)end.x, (float)end.y, (float)end.z); 11420 Vector3 dir = rayEnd - rayStart;
10472 11421
10473 int count = 0; 11422 int count = 1;
10474// int detectPhantom = 0; 11423 bool detectPhantom = false;
10475 int dataFlags = 0; 11424 int dataFlags = 0;
10476 int rejectTypes = 0; 11425 int rejectTypes = 0;
10477 11426
10478 for (int i = 0; i < options.Length; i += 2) 11427 for (int i = 0; i < options.Length; i += 2)
10479 { 11428 {
10480 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS) 11429 if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
10481 {
10482 count = options.GetLSLIntegerItem(i + 1); 11430 count = options.GetLSLIntegerItem(i + 1);
10483 } 11431 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
10484// else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM) 11432 detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
10485// {
10486// detectPhantom = options.GetLSLIntegerItem(i + 1);
10487// }
10488 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS) 11433 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
10489 {
10490 dataFlags = options.GetLSLIntegerItem(i + 1); 11434 dataFlags = options.GetLSLIntegerItem(i + 1);
10491 }
10492 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES) 11435 else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
10493 {
10494 rejectTypes = options.GetLSLIntegerItem(i + 1); 11436 rejectTypes = options.GetLSLIntegerItem(i + 1);
10495 }
10496 } 11437 }
10497 11438
10498 LSL_List list = new LSL_List(); 11439 if (count > 16)
10499 List<ContactResult> results = World.PhysicsScene.RaycastWorld(startvector, dir, dir.Length(), count); 11440 count = 16;
10500
10501 double distance = Util.GetDistanceTo(startvector, endvector);
10502 11441
10503 if (distance == 0) 11442 List<ContactResult> results = new List<ContactResult>();
10504 distance = 0.001;
10505
10506 Vector3 posToCheck = startvector;
10507 ITerrainChannel channel = World.RequestModuleInterface<ITerrainChannel>();
10508 11443
10509 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND); 11444 bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
10510 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS); 11445 bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
10511 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL); 11446 bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
10512 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 11447 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10513 11448
10514 for (float i = 0; i <= distance; i += 0.1f) 11449 if (checkTerrain)
10515 { 11450 {
10516 posToCheck = startvector + (dir * (i / (float)distance)); 11451 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
11452 if (groundContact != null)
11453 results.Add((ContactResult)groundContact);
11454 }
10517 11455
10518 if (checkTerrain && channel[(int)(posToCheck.X + startvector.X), (int)(posToCheck.Y + startvector.Y)] < posToCheck.Z) 11456 if (checkAgents)
10519 { 11457 {
10520 ContactResult result = new ContactResult(); 11458 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
10521 result.ConsumerID = 0; 11459 foreach (ContactResult r in agentHits)
10522 result.Depth = 0; 11460 results.Add(r);
10523 result.Normal = Vector3.Zero; 11461 }
10524 result.Pos = posToCheck;
10525 results.Add(result);
10526 checkTerrain = false;
10527 }
10528 11462
10529 if (checkAgents) 11463 if (checkPhysical || checkNonPhysical)
10530 { 11464 {
10531 World.ForEachRootScenePresence(delegate(ScenePresence sp) 11465 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
10532 { 11466 foreach (ContactResult r in objectHits)
10533 if (sp.AbsolutePosition.ApproxEquals(posToCheck, sp.PhysicsActor.Size.X)) 11467 results.Add(r);
10534 {
10535 ContactResult result = new ContactResult ();
10536 result.ConsumerID = sp.LocalId;
10537 result.Depth = 0;
10538 result.Normal = Vector3.Zero;
10539 result.Pos = posToCheck;
10540 results.Add(result);
10541 }
10542 });
10543 }
10544 } 11468 }
10545 11469
10546 int refcount = 0; 11470 results.Sort(delegate(ContactResult a, ContactResult b)
11471 {
11472 return (int)(a.Depth - b.Depth);
11473 });
11474
11475 int values = 0;
10547 foreach (ContactResult result in results) 11476 foreach (ContactResult result in results)
10548 { 11477 {
10549 if ((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) 11478 UUID itemID = UUID.Zero;
10550 == ScriptBaseClass.RC_REJECT_LAND && result.ConsumerID == 0) 11479 int linkNum = 0;
10551 continue;
10552
10553 ISceneEntity entity = World.GetSceneObjectPart(result.ConsumerID);
10554 11480
10555 if (entity == null && (rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) != ScriptBaseClass.RC_REJECT_AGENTS) 11481 SceneObjectPart part = World.GetSceneObjectPart(result.ConsumerID);
10556 entity = World.GetScenePresence(result.ConsumerID); //Only check if we should be looking for agents 11482 // It's a prim!
10557 11483 if (part != null)
10558 if (entity == null)
10559 { 11484 {
10560 list.Add(UUID.Zero); 11485 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
10561 11486 itemID = part.ParentGroup.UUID;
10562 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11487 else
10563 list.Add(0); 11488 itemID = part.UUID;
10564
10565 list.Add(result.Pos);
10566
10567 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10568 list.Add(result.Normal);
10569 11489
10570 continue; //Can't find it, so add UUID.Zero 11490 linkNum = part.LinkNum;
10571 } 11491 }
10572 11492 else
10573 /*if (detectPhantom == 0 && intersection.obj is ISceneChildEntity &&
10574 ((ISceneChildEntity)intersection.obj).PhysActor == null)
10575 continue;*/ //Can't do this ATM, physics engine knows only of non phantom objects
10576
10577 if (entity is SceneObjectPart)
10578 { 11493 {
10579 if (((SceneObjectPart)entity).PhysActor != null && ((SceneObjectPart)entity).PhysActor.IsPhysical) 11494 ScenePresence sp = World.GetScenePresence(result.ConsumerID);
10580 { 11495 /// It it a boy? a girl?
10581 if (!checkPhysical) 11496 if (sp != null)
10582 continue; 11497 itemID = sp.UUID;
10583 }
10584 else
10585 {
10586 if (!checkNonPhysical)
10587 continue;
10588 }
10589 } 11498 }
10590 11499
10591 refcount++; 11500 list.Add(new LSL_String(itemID.ToString()));
10592 if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY && entity is SceneObjectPart) 11501 list.Add(new LSL_String(result.Pos.ToString()));
10593 list.Add(((SceneObjectPart)entity).ParentGroup.UUID);
10594 else
10595 list.Add(entity.UUID);
10596 11502
10597 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM) 11503 if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
10598 { 11504 list.Add(new LSL_Integer(linkNum));
10599 if (entity is SceneObjectPart)
10600 list.Add(((SceneObjectPart)entity).LinkNum);
10601 else
10602 list.Add(0);
10603 }
10604 11505
10605 list.Add(result.Pos);
10606 11506
10607 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL) 11507 if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
10608 list.Add(result.Normal); 11508 list.Add(new LSL_Vector(result.Normal.X, result.Normal.Y, result.Normal.Z));
11509
11510 values++;
11511 count--;
11512
11513 if (count == 0)
11514 break;
10609 } 11515 }
10610 11516
10611 list.Add(refcount); //The status code, either the # of contacts, RCERR_SIM_PERF_LOW, or RCERR_CAST_TIME_EXCEEDED 11517 list.Add(new LSL_Integer(values));
10612 11518
10613 return list; 11519 return list;
10614 } 11520 }
@@ -10631,22 +11537,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10631 NotImplemented("llGetSPMaxMemory"); 11537 NotImplemented("llGetSPMaxMemory");
10632 } 11538 }
10633 11539
10634 public void llGetUsedMemory() 11540 public virtual LSL_Integer llGetUsedMemory()
10635 { 11541 {
10636 m_host.AddScriptLPS(1); 11542 m_host.AddScriptLPS(1);
10637 NotImplemented("llGetUsedMemory"); 11543 NotImplemented("llGetUsedMemory");
11544 return 0;
10638 } 11545 }
10639 11546
10640 public void llScriptProfiler(LSL_Integer flags) 11547 public void llScriptProfiler(LSL_Integer flags)
10641 { 11548 {
10642 m_host.AddScriptLPS(1); 11549 m_host.AddScriptLPS(1);
10643 NotImplemented("llScriptProfiler"); 11550 //NotImplemented("llScriptProfiler");
10644 } 11551 }
10645 11552
10646 public void llSetSoundQueueing(int queue) 11553 public void llSetSoundQueueing(int queue)
10647 { 11554 {
10648 m_host.AddScriptLPS(1); 11555 m_host.AddScriptLPS(1);
10649 NotImplemented("llSetSoundQueueing");
10650 } 11556 }
10651 11557
10652 public void llCollisionSprite(string impact_sprite) 11558 public void llCollisionSprite(string impact_sprite)
@@ -10658,7 +11564,133 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10658 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11564 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10659 { 11565 {
10660 m_host.AddScriptLPS(1); 11566 m_host.AddScriptLPS(1);
10661 NotImplemented("llGodLikeRezObject"); 11567
11568 if (!World.Permissions.IsGod(m_host.OwnerID))
11569 NotImplemented("llGodLikeRezObject");
11570
11571 AssetBase rezAsset = World.AssetService.Get(inventory);
11572 if (rezAsset == null)
11573 {
11574 llSay(0, "Asset not found");
11575 return;
11576 }
11577
11578 SceneObjectGroup group = null;
11579
11580 try
11581 {
11582 string xmlData = Utils.BytesToString(rezAsset.Data);
11583 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11584 }
11585 catch
11586 {
11587 llSay(0, "Asset not found");
11588 return;
11589 }
11590
11591 if (group == null)
11592 {
11593 llSay(0, "Asset not found");
11594 return;
11595 }
11596
11597 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11598 group.RootPart.AttachOffset = group.AbsolutePosition;
11599
11600 group.ResetIDs();
11601
11602 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11603 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11604 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11605 group.ScheduleGroupForFullUpdate();
11606
11607 // objects rezzed with this method are die_at_edge by default.
11608 group.RootPart.SetDieAtEdge(true);
11609
11610 group.ResumeScripts();
11611
11612 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11613 "object_rez", new Object[] {
11614 new LSL_String(
11615 group.RootPart.UUID.ToString()) },
11616 new DetectParams[0]));
11617 }
11618
11619 public LSL_String llTransferLindenDollars(string destination, int amount)
11620 {
11621 UUID txn = UUID.Random();
11622
11623 Util.FireAndForget(delegate(object x)
11624 {
11625 int replycode = 0;
11626 string replydata = destination + "," + amount.ToString();
11627
11628 try
11629 {
11630 UUID invItemID=InventorySelf();
11631 if (invItemID == UUID.Zero)
11632 {
11633 replydata = "SERVICE_ERROR";
11634 return;
11635 }
11636
11637 m_host.AddScriptLPS(1);
11638
11639 m_host.TaskInventory.LockItemsForRead(true);
11640 TaskInventoryItem item = m_host.TaskInventory[invItemID];
11641 m_host.TaskInventory.LockItemsForRead(false);
11642
11643 if (item.PermsGranter == UUID.Zero)
11644 {
11645 replydata = "MISSING_PERMISSION_DEBIT";
11646 return;
11647 }
11648
11649 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
11650 {
11651 replydata = "MISSING_PERMISSION_DEBIT";
11652 return;
11653 }
11654
11655 UUID toID = new UUID();
11656
11657 if (!UUID.TryParse(destination, out toID))
11658 {
11659 replydata = "INVALID_AGENT";
11660 return;
11661 }
11662
11663 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
11664
11665 if (money == null)
11666 {
11667 replydata = "TRANSFERS_DISABLED";
11668 return;
11669 }
11670
11671 bool result = money.ObjectGiveMoney(
11672 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
11673
11674 if (result)
11675 {
11676 replycode = 1;
11677 return;
11678 }
11679
11680 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
11681 }
11682 finally
11683 {
11684 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
11685 "transaction_result", new Object[] {
11686 new LSL_String(txn.ToString()),
11687 new LSL_Integer(replycode),
11688 new LSL_String(replydata) },
11689 new DetectParams[0]));
11690 }
11691 });
11692
11693 return txn.ToString();
10662 } 11694 }
10663 11695
10664 #endregion 11696 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index bb0ba3d..8cc6554 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -137,6 +137,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 137 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
138 internal float m_ScriptDelayFactor = 1.0f; 138 internal float m_ScriptDelayFactor = 1.0f;
139 internal float m_ScriptDistanceFactor = 1.0f; 139 internal float m_ScriptDistanceFactor = 1.0f;
140 internal bool m_debuggerSafe = false;
140 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
141 142
142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_host = host; 146 m_host = host;
146 m_localID = localID; 147 m_localID = localID;
147 m_itemID = itemID; 148 m_itemID = itemID;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 private void InitLSL() 221 private void InitLSL()
@@ -897,18 +906,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
897 if (target != null) 906 if (target != null)
898 { 907 {
899 UUID animID=UUID.Zero; 908 UUID animID=UUID.Zero;
900 lock (m_host.TaskInventory) 909 m_host.TaskInventory.LockItemsForRead(true);
910 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
901 { 911 {
902 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 912 if (inv.Value.Name == animation)
903 { 913 {
904 if (inv.Value.Name == animation) 914 if (inv.Value.Type == (int)AssetType.Animation)
905 { 915 animID = inv.Value.AssetID;
906 if (inv.Value.Type == (int)AssetType.Animation) 916 continue;
907 animID = inv.Value.AssetID;
908 continue;
909 }
910 } 917 }
911 } 918 }
919 m_host.TaskInventory.LockItemsForRead(false);
912 if (animID == UUID.Zero) 920 if (animID == UUID.Zero)
913 target.Animator.AddAnimation(animation, m_host.UUID); 921 target.Animator.AddAnimation(animation, m_host.UUID);
914 else 922 else
@@ -930,18 +938,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
930 if (target != null) 938 if (target != null)
931 { 939 {
932 UUID animID = UUID.Zero; 940 UUID animID = UUID.Zero;
933 lock (m_host.TaskInventory) 941 m_host.TaskInventory.LockItemsForRead(true);
942 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
934 { 943 {
935 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 944 if (inv.Value.Name == animation)
936 { 945 {
937 if (inv.Value.Name == animation) 946 if (inv.Value.Type == (int)AssetType.Animation)
938 { 947 animID = inv.Value.AssetID;
939 if (inv.Value.Type == (int)AssetType.Animation) 948 continue;
940 animID = inv.Value.AssetID;
941 continue;
942 }
943 } 949 }
944 } 950 }
951 m_host.TaskInventory.LockItemsForRead(false);
945 952
946 if (animID == UUID.Zero) 953 if (animID == UUID.Zero)
947 target.Animator.RemoveAnimation(animation); 954 target.Animator.RemoveAnimation(animation);
@@ -1772,6 +1779,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1772 1779
1773 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1780 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1774 { 1781 {
1782 m_host.TaskInventory.LockItemsForRead(true);
1775 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1783 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1776 { 1784 {
1777 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1785 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1779,6 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1779 assetID = item.AssetID; 1787 assetID = item.AssetID;
1780 } 1788 }
1781 } 1789 }
1790 m_host.TaskInventory.LockItemsForRead(false);
1782 } 1791 }
1783 1792
1784 if (assetID == UUID.Zero) 1793 if (assetID == UUID.Zero)
@@ -2102,8 +2111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2102 UUID x = module.CreateNPC(firstname, 2111 UUID x = module.CreateNPC(firstname,
2103 lastname, 2112 lastname,
2104 new Vector3((float) position.x, (float) position.y, (float) position.z), 2113 new Vector3((float) position.x, (float) position.y, (float) position.z),
2105 World, 2114 World,appearance);
2106 appearance);
2107 2115
2108 return new LSL_Key(x.ToString()); 2116 return new LSL_Key(x.ToString());
2109 } 2117 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3eeb23d..91a7b87 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -205,7 +205,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 205 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 207 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 208 sensedEntities.AddRange(doAgentSensor(ts));
209 } 209 }
210 210
211 // If SCRIPTED or PASSIVE or ACTIVE check objects 211 // If SCRIPTED or PASSIVE or ACTIVE check objects
@@ -302,13 +302,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
302 float dy; 302 float dy;
303 float dz; 303 float dz;
304 304
305 Quaternion q = SensePoint.RotationOffset; 305// Quaternion q = SensePoint.RotationOffset;
306 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
306 if (SensePoint.ParentGroup.IsAttachment) 307 if (SensePoint.ParentGroup.IsAttachment)
307 { 308 {
308 // In attachments, the sensor cone always orients with the 309 // In attachments, the sensor cone always orients with the
309 // avatar rotation. This may include a nonzero elevation if 310 // avatar rotation. This may include a nonzero elevation if
310 // in mouselook. 311 // in mouselook.
311 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 312 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
313 fromRegionPos = avatar.AbsolutePosition;
312 q = avatar.Rotation; 314 q = avatar.Rotation;
313 } 315 }
314 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 316 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -429,6 +431,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
429 // avatar rotation. This may include a nonzero elevation if 431 // avatar rotation. This may include a nonzero elevation if
430 // in mouselook. 432 // in mouselook.
431 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 433 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
434 if (avatar == null)
435 return sensedEntities;
436 fromRegionPos = avatar.AbsolutePosition;
432 q = avatar.Rotation; 437 q = avatar.Rotation;
433 } 438 }
434 439
@@ -441,6 +446,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
441 446
442 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence) 447 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence)
443 { 448 {
449 if (presence.PresenceType == PresenceType.Npc)
450 return;
451
444 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) 452 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
445 return; 453 return;
446 454
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index eeb59d9..2fd33fe 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -109,25 +109,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
109 if (Timers.Count == 0) 109 if (Timers.Count == 0)
110 return; 110 return;
111 111
112 Dictionary<string, TimerClass>.ValueCollection tvals;
112 lock (TimerListLock) 113 lock (TimerListLock)
113 { 114 {
114 // Go through all timers 115 // Go through all timers
115 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 116 tvals = Timers.Values;
116 foreach (TimerClass ts in tvals) 117 }
118
119 foreach (TimerClass ts in tvals)
120 {
121 // Time has passed?
122 if (ts.next < DateTime.Now.Ticks)
117 { 123 {
118 // Time has passed? 124 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
119 if (ts.next < DateTime.Now.Ticks) 125 // Add it to queue
120 { 126 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
121 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 127 new EventParams("timer", new Object[0],
122 // Add it to queue 128 new DetectParams[0]));
123 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 129 // set next interval
124 new EventParams("timer", new Object[0], 130
125 new DetectParams[0])); 131 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
126 // set next interval 132 ts.next = DateTime.Now.Ticks + ts.interval;
127
128 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
129 ts.next = DateTime.Now.Ticks + ts.interval;
130 }
131 } 133 }
132 } 134 }
133 } 135 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 62e2854..e0027b2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -123,6 +123,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
123 LSL_Float llGetEnergy(); 123 LSL_Float llGetEnergy();
124 LSL_Vector llGetForce(); 124 LSL_Vector llGetForce();
125 LSL_Integer llGetFreeMemory(); 125 LSL_Integer llGetFreeMemory();
126 LSL_Integer llGetUsedMemory();
126 LSL_Integer llGetFreeURLs(); 127 LSL_Integer llGetFreeURLs();
127 LSL_Vector llGetGeometricCenter(); 128 LSL_Vector llGetGeometricCenter();
128 LSL_Float llGetGMTclock(); 129 LSL_Float llGetGMTclock();
@@ -199,6 +200,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
199 void llGiveInventory(string destination, string inventory); 200 void llGiveInventory(string destination, string inventory);
200 void llGiveInventoryList(string destination, string category, LSL_List inventory); 201 void llGiveInventoryList(string destination, string category, LSL_List inventory);
201 LSL_Integer llGiveMoney(string destination, int amount); 202 LSL_Integer llGiveMoney(string destination, int amount);
203 LSL_String llTransferLindenDollars(string destination, int amount);
202 void llGodLikeRezObject(string inventory, LSL_Vector pos); 204 void llGodLikeRezObject(string inventory, LSL_Vector pos);
203 LSL_Float llGround(LSL_Vector offset); 205 LSL_Float llGround(LSL_Vector offset);
204 LSL_Vector llGroundContour(LSL_Vector offset); 206 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -405,7 +407,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_Vector llWind(LSL_Vector offset); 407 LSL_Vector llWind(LSL_Vector offset);
406 LSL_String llXorBase64Strings(string str1, string str2); 408 LSL_String llXorBase64Strings(string str1, string str2);
407 LSL_String llXorBase64StringsCorrect(string str1, string str2); 409 LSL_String llXorBase64StringsCorrect(string str1, string str2);
408 void print(string str); 410 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
409 411
410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 412 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 413 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index f5ee733..a49feb0 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 fd08373..0ad3f78 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -281,6 +281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 281 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
282 public const int CHANGED_MEDIA = 2048; 282 public const int CHANGED_MEDIA = 2048;
283 public const int CHANGED_ANIMATION = 16384; 283 public const int CHANGED_ANIMATION = 16384;
284 public const int CHANGED_POSITION = 32768;
284 public const int TYPE_INVALID = 0; 285 public const int TYPE_INVALID = 0;
285 public const int TYPE_INTEGER = 1; 286 public const int TYPE_INTEGER = 1;
286 public const int TYPE_FLOAT = 2; 287 public const int TYPE_FLOAT = 2;
@@ -377,6 +378,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
377 public const int PRIM_SCULPT_TYPE_TORUS = 2; 378 public const int PRIM_SCULPT_TYPE_TORUS = 2;
378 public const int PRIM_SCULPT_TYPE_PLANE = 3; 379 public const int PRIM_SCULPT_TYPE_PLANE = 3;
379 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 380 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
381 public const int PRIM_SCULPT_FLAG_INVERT = 64;
382 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
380 383
381 public const int MASK_BASE = 0; 384 public const int MASK_BASE = 0;
382 public const int MASK_OWNER = 1; 385 public const int MASK_OWNER = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..231cd7e 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -164,6 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
164 m_LSL_Functions.llBreakLink(linknum); 165 m_LSL_Functions.llBreakLink(linknum);
165 } 166 }
166 167
168 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
169 {
170 return m_LSL_Functions.llCastRay(start, end, options);
171 }
172
167 public LSL_Integer llCeil(double f) 173 public LSL_Integer llCeil(double f)
168 { 174 {
169 return m_LSL_Functions.llCeil(f); 175 return m_LSL_Functions.llCeil(f);
@@ -314,6 +320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 320 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 321 }
316 322
323 [DebuggerNonUserCode]
317 public void llDie() 324 public void llDie()
318 { 325 {
319 m_LSL_Functions.llDie(); 326 m_LSL_Functions.llDie();
@@ -464,6 +471,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 471 return m_LSL_Functions.llGetFreeMemory();
465 } 472 }
466 473
474 public LSL_Integer llGetUsedMemory()
475 {
476 return m_LSL_Functions.llGetUsedMemory();
477 }
478
467 public LSL_Integer llGetFreeURLs() 479 public LSL_Integer llGetFreeURLs()
468 { 480 {
469 return m_LSL_Functions.llGetFreeURLs(); 481 return m_LSL_Functions.llGetFreeURLs();
@@ -839,6 +851,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
839 return m_LSL_Functions.llGiveMoney(destination, amount); 851 return m_LSL_Functions.llGiveMoney(destination, amount);
840 } 852 }
841 853
854 public LSL_String llTransferLindenDollars(string destination, int amount)
855 {
856 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
857 }
858
842 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 859 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
843 { 860 {
844 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 861 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1878,9 +1895,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1878 return m_LSL_Functions.llClearPrimMedia(face); 1895 return m_LSL_Functions.llClearPrimMedia(face);
1879 } 1896 }
1880 1897
1881 public void print(string str) 1898 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1882 { 1899 {
1883 m_LSL_Functions.print(str); 1900 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1884 } 1901 }
1885 } 1902 }
1886} 1903}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);