aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine')
-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.cs2252
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs7
-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.cs3
-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.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs52
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs353
19 files changed, 2112 insertions, 969 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 f8327b9..b968bdc 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{
@@ -81,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
81 /// </summary> 85 /// </summary>
82 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi 86 public class LSL_Api : MarshalByRefObject, ILSL_Api, IScriptApi
83 { 87 {
84 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 88// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
85 protected IScriptEngine m_ScriptEngine; 89 protected IScriptEngine m_ScriptEngine;
86 protected SceneObjectPart m_host; 90 protected SceneObjectPart m_host;
87 protected uint m_localID; 91 protected uint m_localID;
@@ -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())
349 {
350 m_host.TaskInventory.LockItemsForRead(true);
351 unlock = true;
352 }
353 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
280 { 354 {
281 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 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). 553
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 }
473 566
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 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.UpdateTexture(tex);
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.UpdateTexture(tex);
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)
@@ -1673,7 +1856,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1673 /// <param name="falloff"></param> 1856 /// <param name="falloff"></param>
1674 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1857 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1675 { 1858 {
1676 if (part == null) 1859 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1677 return; 1860 return;
1678 1861
1679 if (light) 1862 if (light)
@@ -1750,15 +1933,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1750 m_host.AddScriptLPS(1); 1933 m_host.AddScriptLPS(1);
1751 1934
1752 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1935 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1753 1936 if (parts.Count > 0)
1754 foreach (SceneObjectPart part in parts) 1937 {
1755 SetTexture(part, texture, face); 1938 try
1756 1939 {
1940 parts[0].ParentGroup.areUpdatesSuspended = true;
1941 foreach (SceneObjectPart part in parts)
1942 SetTexture(part, texture, face);
1943 }
1944 finally
1945 {
1946 parts[0].ParentGroup.areUpdatesSuspended = false;
1947 }
1948 }
1757 ScriptSleep(200); 1949 ScriptSleep(200);
1758 } 1950 }
1759 1951
1760 protected void SetTexture(SceneObjectPart part, string texture, int face) 1952 protected void SetTexture(SceneObjectPart part, string texture, int face)
1761 { 1953 {
1954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1955 return;
1956
1762 UUID textureID = new UUID(); 1957 UUID textureID = new UUID();
1763 1958
1764 textureID = InventoryKey(texture, (int)AssetType.Texture); 1959 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1803,6 +1998,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1803 1998
1804 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1999 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1805 { 2000 {
2001 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2002 return;
2003
1806 Primitive.TextureEntry tex = part.Shape.Textures; 2004 Primitive.TextureEntry tex = part.Shape.Textures;
1807 if (face >= 0 && face < GetNumberOfSides(part)) 2005 if (face >= 0 && face < GetNumberOfSides(part))
1808 { 2006 {
@@ -1839,6 +2037,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1839 2037
1840 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2038 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1841 { 2039 {
2040 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2041 return;
2042
1842 Primitive.TextureEntry tex = part.Shape.Textures; 2043 Primitive.TextureEntry tex = part.Shape.Textures;
1843 if (face >= 0 && face < GetNumberOfSides(part)) 2044 if (face >= 0 && face < GetNumberOfSides(part))
1844 { 2045 {
@@ -1875,6 +2076,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1875 2076
1876 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2077 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1877 { 2078 {
2079 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2080 return;
2081
1878 Primitive.TextureEntry tex = part.Shape.Textures; 2082 Primitive.TextureEntry tex = part.Shape.Textures;
1879 if (face >= 0 && face < GetNumberOfSides(part)) 2083 if (face >= 0 && face < GetNumberOfSides(part))
1880 { 2084 {
@@ -1958,10 +2162,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1958 return end; 2162 return end;
1959 } 2163 }
1960 2164
1961 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2165 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos)
1962 { 2166 {
2167 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2168 return fromPos;
2169
1963 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2170 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos)
1964 LSL_Vector currentPos = GetPartLocalPos(part); 2171
1965 2172
1966 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y); 2173 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1967 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true); 2174 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
@@ -1970,14 +2177,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1970 { 2177 {
1971 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2178 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1972 targetPos.z = ground; 2179 targetPos.z = ground;
2180 }
2181 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos);
2182
2183 return real_vec;
2184 }
2185
2186 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
2187 {
2188 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2189 return;
2190
2191 LSL_Vector currentPos = GetPartLocalPos(part);
2192 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2193
2194 if (part.ParentGroup.RootPart == part)
2195 {
1973 SceneObjectGroup parent = part.ParentGroup; 2196 SceneObjectGroup parent = part.ParentGroup;
1974 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2197 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
1975 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z));
1976 } 2198 }
1977 else 2199 else
1978 { 2200 {
1979 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2201 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1980 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1981 SceneObjectGroup parent = part.ParentGroup; 2202 SceneObjectGroup parent = part.ParentGroup;
1982 parent.HasGroupChanged = true; 2203 parent.HasGroupChanged = true;
1983 parent.ScheduleGroupForTerseUpdate(); 2204 parent.ScheduleGroupForTerseUpdate();
@@ -2028,9 +2249,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2028 m_host.AddScriptLPS(1); 2249 m_host.AddScriptLPS(1);
2029 2250
2030 // try to let this work as in SL... 2251 // try to let this work as in SL...
2031 if (m_host.ParentID == 0) 2252 if (m_host.LinkNum < 2)
2032 { 2253 {
2033 // special case: If we are root, rotate complete SOG to new rotation 2254 // Special case: If we are root, rotate complete SOG to new
2255 // rotation.
2256 // We are root if the link number is 0 (single prim) or 1
2257 // (root prim). ParentID may be nonzero in attachments and
2258 // using it would cause attachments and HUDs to rotate
2259 // to the wrong positions.
2034 SetRot(m_host, Rot2Quaternion(rot)); 2260 SetRot(m_host, Rot2Quaternion(rot));
2035 } 2261 }
2036 else 2262 else
@@ -2055,6 +2281,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2055 2281
2056 protected void SetRot(SceneObjectPart part, Quaternion rot) 2282 protected void SetRot(SceneObjectPart part, Quaternion rot)
2057 { 2283 {
2284 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2285 return;
2286
2058 part.UpdateRotation(rot); 2287 part.UpdateRotation(rot);
2059 // Update rotation does not move the object in the physics scene if it's a linkset. 2288 // Update rotation does not move the object in the physics scene if it's a linkset.
2060 2289
@@ -2680,12 +2909,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2680 2909
2681 m_host.AddScriptLPS(1); 2910 m_host.AddScriptLPS(1);
2682 2911
2912 m_host.TaskInventory.LockItemsForRead(true);
2683 TaskInventoryItem item = m_host.TaskInventory[invItemID]; 2913 TaskInventoryItem item = m_host.TaskInventory[invItemID];
2684 2914 m_host.TaskInventory.LockItemsForRead(false);
2685 lock (m_host.TaskInventory)
2686 {
2687 item = m_host.TaskInventory[invItemID];
2688 }
2689 2915
2690 if (item.PermsGranter == UUID.Zero) 2916 if (item.PermsGranter == UUID.Zero)
2691 return 0; 2917 return 0;
@@ -2760,6 +2986,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2760 if (dist > m_ScriptDistanceFactor * 10.0f) 2986 if (dist > m_ScriptDistanceFactor * 10.0f)
2761 return; 2987 return;
2762 2988
2989 //Clone is thread-safe
2763 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 2990 TaskInventoryDictionary partInventory = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
2764 2991
2765 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory) 2992 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in partInventory)
@@ -2820,6 +3047,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2820 3047
2821 public void llLookAt(LSL_Vector target, double strength, double damping) 3048 public void llLookAt(LSL_Vector target, double strength, double damping)
2822 { 3049 {
3050 /*
2823 m_host.AddScriptLPS(1); 3051 m_host.AddScriptLPS(1);
2824 // Determine where we are looking from 3052 // Determine where we are looking from
2825 LSL_Vector from = llGetPos(); 3053 LSL_Vector from = llGetPos();
@@ -2839,10 +3067,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2839 // the angles of rotation in radians into rotation value 3067 // the angles of rotation in radians into rotation value
2840 3068
2841 LSL_Types.Quaternion rot = llEuler2Rot(angle); 3069 LSL_Types.Quaternion rot = llEuler2Rot(angle);
2842 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 3070
2843 m_host.startLookAt(rotation, (float)damping, (float)strength); 3071 // This would only work if your physics system contains an APID controller:
3072 // Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s);
3073 // m_host.startLookAt(rotation, (float)damping, (float)strength);
3074
2844 // Orient the object to the angle calculated 3075 // Orient the object to the angle calculated
2845 //llSetRot(rot); 3076 llSetRot(rot);
3077 */
3078
3079 //The above code, while nice, doesn't replicate the behaviour of SL and tends to "roll" the object.
3080 //There's probably a smarter way of doing this, my rotation math-fu is weak.
3081 // http://bugs.meta7.com/view.php?id=28
3082 // - Tom
3083
3084 /* And the following does not do the job either. It has to be performed inside the ODE glue-code. -.- .._.
3085 LSL_Rotation newrot = llGetRot() * llRotBetween(new LSL_Vector(1.0d, 0.0d, 0.0d) * llGetRot(), new LSL_Vector(0.0d, 0.0d, -1.0d));
3086 llSetRot(newrot * llRotBetween(new LSL_Vector(0.0d,0.0d,1.0d) * newrot, target - llGetPos()));
3087 */
3088 if (m_host.PhysActor != null && !m_host.PhysActor.IsPhysical)
3089 {
3090 // Part is non-phys, convert this to a llSetRot()
3091 Vector3 tgt = new Vector3((float)target.x, (float)target.y, (float)target.z);
3092 Vector3 dir = tgt - m_host.GroupPosition;
3093 dir.Normalize();
3094 float tzrot = (float)Math.Atan2(dir.Y, dir.X);
3095 float txy = (float)Math.Sqrt((dir.X * dir.X) + (dir.Y * dir.Y));
3096 float terot = (float)Math.Atan2(-dir.Z, txy);
3097 LSL_Vector az = new LSL_Vector(0.0f, 0.0f, tzrot);
3098 LSL_Vector ae = new LSL_Vector(0.0f, terot, 0.0f);
3099 LSL_Types.Quaternion spin = llEuler2Rot(az);
3100 LSL_Types.Quaternion rot = llEuler2Rot(ae) * spin;
3101 llSetRot(rot);
3102 }
3103 else
3104 {
3105 // Physical, send the target vector to RotLookAt method inside a 'rotation', the .w -99.9 value indicates it is really a LookAt.
3106 Quaternion q = new Quaternion((float)target.x, (float)target.y, (float)target.z, -99.9f);
3107 m_host.RotLookAt(q, (float)strength, (float)damping);
3108 }
3109
3110 }
3111
3112 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3113 {
3114 m_host.AddScriptLPS(1);
3115// NotImplemented("llRotLookAt");
3116 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3117
2846 } 3118 }
2847 3119
2848 public void llStopLookAt() 3120 public void llStopLookAt()
@@ -2891,13 +3163,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2891 { 3163 {
2892 TaskInventoryItem item; 3164 TaskInventoryItem item;
2893 3165
2894 lock (m_host.TaskInventory) 3166 m_host.TaskInventory.LockItemsForRead(true);
3167 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2895 { 3168 {
2896 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3169 m_host.TaskInventory.LockItemsForRead(false);
2897 return; 3170 return;
2898 else 3171 }
2899 item = m_host.TaskInventory[InventorySelf()]; 3172 else
3173 {
3174 item = m_host.TaskInventory[InventorySelf()];
2900 } 3175 }
3176 m_host.TaskInventory.LockItemsForRead(false);
2901 3177
2902 if (item.PermsGranter != UUID.Zero) 3178 if (item.PermsGranter != UUID.Zero)
2903 { 3179 {
@@ -2919,13 +3195,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2919 { 3195 {
2920 TaskInventoryItem item; 3196 TaskInventoryItem item;
2921 3197
3198 m_host.TaskInventory.LockItemsForRead(true);
2922 lock (m_host.TaskInventory) 3199 lock (m_host.TaskInventory)
2923 { 3200 {
3201
2924 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3202 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3203 {
3204 m_host.TaskInventory.LockItemsForRead(false);
2925 return; 3205 return;
3206 }
2926 else 3207 else
3208 {
2927 item = m_host.TaskInventory[InventorySelf()]; 3209 item = m_host.TaskInventory[InventorySelf()];
3210 }
2928 } 3211 }
3212 m_host.TaskInventory.LockItemsForRead(false);
2929 3213
2930 m_host.AddScriptLPS(1); 3214 m_host.AddScriptLPS(1);
2931 3215
@@ -2957,19 +3241,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2957 { 3241 {
2958 m_host.AddScriptLPS(1); 3242 m_host.AddScriptLPS(1);
2959 3243
2960// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
2961// return;
2962
2963 TaskInventoryItem item; 3244 TaskInventoryItem item;
2964 3245
2965 lock (m_host.TaskInventory) 3246 m_host.TaskInventory.LockItemsForRead(true);
3247
3248 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2966 { 3249 {
2967 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3250 m_host.TaskInventory.LockItemsForRead(false);
2968 return; 3251 return;
2969 else 3252 }
2970 item = m_host.TaskInventory[InventorySelf()]; 3253 else
3254 {
3255 item = m_host.TaskInventory[InventorySelf()];
2971 } 3256 }
2972 3257
3258 m_host.TaskInventory.LockItemsForRead(false);
3259
2973 if (item.PermsGranter != m_host.OwnerID) 3260 if (item.PermsGranter != m_host.OwnerID)
2974 return; 3261 return;
2975 3262
@@ -2978,11 +3265,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2978 SceneObjectGroup grp = m_host.ParentGroup; 3265 SceneObjectGroup grp = m_host.ParentGroup;
2979 3266
2980 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 3267 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
2981 3268 if (presence.Scene.AttachmentsModule != null)
2982 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3269 {
2983 if (attachmentsModule != null) 3270 presence.Scene.AttachmentsModule.AttachObject(presence.ControllingClient, grp, (uint)attachment, false);
2984 attachmentsModule.AttachObject(presence.ControllingClient, 3271 }
2985 grp, (uint)attachment, false);
2986 } 3272 }
2987 } 3273 }
2988 3274
@@ -2995,13 +3281,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2995 3281
2996 TaskInventoryItem item; 3282 TaskInventoryItem item;
2997 3283
2998 lock (m_host.TaskInventory) 3284 m_host.TaskInventory.LockItemsForRead(true);
3285
3286 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
2999 { 3287 {
3000 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3288 m_host.TaskInventory.LockItemsForRead(false);
3001 return; 3289 return;
3002 else 3290 }
3003 item = m_host.TaskInventory[InventorySelf()]; 3291 else
3292 {
3293 item = m_host.TaskInventory[InventorySelf()];
3004 } 3294 }
3295 m_host.TaskInventory.LockItemsForRead(false);
3296
3005 3297
3006 if (item.PermsGranter != m_host.OwnerID) 3298 if (item.PermsGranter != m_host.OwnerID)
3007 return; 3299 return;
@@ -3048,6 +3340,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3048 3340
3049 public void llInstantMessage(string user, string message) 3341 public void llInstantMessage(string user, string message)
3050 { 3342 {
3343 UUID result;
3344 if (!UUID.TryParse(user, out result))
3345 {
3346 ShoutError("An invalid key was passed to llInstantMessage");
3347 ScriptSleep(2000);
3348 return;
3349 }
3350
3351
3051 m_host.AddScriptLPS(1); 3352 m_host.AddScriptLPS(1);
3052 3353
3053 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3354 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3062,14 +3363,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3062 UUID friendTransactionID = UUID.Random(); 3363 UUID friendTransactionID = UUID.Random();
3063 3364
3064 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3365 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3065 3366
3066 GridInstantMessage msg = new GridInstantMessage(); 3367 GridInstantMessage msg = new GridInstantMessage();
3067 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3368 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3068 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3369 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3069 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3370 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3070// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3371// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3071// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3372// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3072 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3373// DateTime dt = DateTime.UtcNow;
3374//
3375// // Ticks from UtcNow, but make it look like local. Evil, huh?
3376// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3377//
3378// try
3379// {
3380// // Convert that to the PST timezone
3381// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3382// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3383// }
3384// catch
3385// {
3386// // No logging here, as it could be VERY spammy
3387// }
3388//
3389// // And make it look local again to fool the unix time util
3390// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3391
3392 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3393
3073 //if (client != null) 3394 //if (client != null)
3074 //{ 3395 //{
3075 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3396 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3083,12 +3404,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3083 msg.message = message.Substring(0, 1024); 3404 msg.message = message.Substring(0, 1024);
3084 else 3405 else
3085 msg.message = message; 3406 msg.message = message;
3086 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3407 msg.dialog = (byte)19; // MessageFromObject
3087 msg.fromGroup = false;// fromGroup; 3408 msg.fromGroup = false;// fromGroup;
3088 msg.offline = (byte)0; //offline; 3409 msg.offline = (byte)0; //offline;
3089 msg.ParentEstateID = 0; //ParentEstateID; 3410 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3090 msg.Position = new Vector3(m_host.AbsolutePosition); 3411 msg.Position = new Vector3(m_host.AbsolutePosition);
3091 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3412 msg.RegionID = World.RegionInfo.RegionID.Guid;
3092 msg.binaryBucket 3413 msg.binaryBucket
3093 = Util.StringToBytes256( 3414 = Util.StringToBytes256(
3094 "{0}/{1}/{2}/{3}", 3415 "{0}/{1}/{2}/{3}",
@@ -3116,7 +3437,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3116 } 3437 }
3117 3438
3118 emailModule.SendEmail(m_host.UUID, address, subject, message); 3439 emailModule.SendEmail(m_host.UUID, address, subject, message);
3119 ScriptSleep(20000); 3440 ScriptSleep(15000);
3120 } 3441 }
3121 3442
3122 public void llGetNextEmail(string address, string subject) 3443 public void llGetNextEmail(string address, string subject)
@@ -3216,13 +3537,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3216 m_host.AddScriptLPS(1); 3537 m_host.AddScriptLPS(1);
3217 } 3538 }
3218 3539
3219 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3220 {
3221 m_host.AddScriptLPS(1);
3222 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s);
3223 m_host.RotLookAt(rot, (float)strength, (float)damping);
3224 }
3225
3226 public LSL_Integer llStringLength(string str) 3540 public LSL_Integer llStringLength(string str)
3227 { 3541 {
3228 m_host.AddScriptLPS(1); 3542 m_host.AddScriptLPS(1);
@@ -3246,14 +3560,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3246 3560
3247 TaskInventoryItem item; 3561 TaskInventoryItem item;
3248 3562
3249 lock (m_host.TaskInventory) 3563 m_host.TaskInventory.LockItemsForRead(true);
3564 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3250 { 3565 {
3251 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3566 m_host.TaskInventory.LockItemsForRead(false);
3252 return; 3567 return;
3253 else
3254 item = m_host.TaskInventory[InventorySelf()];
3255 } 3568 }
3256 3569 else
3570 {
3571 item = m_host.TaskInventory[InventorySelf()];
3572 }
3573 m_host.TaskInventory.LockItemsForRead(false);
3257 if (item.PermsGranter == UUID.Zero) 3574 if (item.PermsGranter == UUID.Zero)
3258 return; 3575 return;
3259 3576
@@ -3283,13 +3600,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3283 3600
3284 TaskInventoryItem item; 3601 TaskInventoryItem item;
3285 3602
3286 lock (m_host.TaskInventory) 3603 m_host.TaskInventory.LockItemsForRead(true);
3604 if (!m_host.TaskInventory.ContainsKey(InventorySelf()))
3287 { 3605 {
3288 if (!m_host.TaskInventory.ContainsKey(InventorySelf())) 3606 m_host.TaskInventory.LockItemsForRead(false);
3289 return; 3607 return;
3290 else 3608 }
3291 item = m_host.TaskInventory[InventorySelf()]; 3609 else
3610 {
3611 item = m_host.TaskInventory[InventorySelf()];
3292 } 3612 }
3613 m_host.TaskInventory.LockItemsForRead(false);
3614
3293 3615
3294 if (item.PermsGranter == UUID.Zero) 3616 if (item.PermsGranter == UUID.Zero)
3295 return; 3617 return;
@@ -3354,10 +3676,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3354 3676
3355 TaskInventoryItem item; 3677 TaskInventoryItem item;
3356 3678
3357 lock (m_host.TaskInventory) 3679
3680 m_host.TaskInventory.LockItemsForRead(true);
3681 if (!m_host.TaskInventory.ContainsKey(invItemID))
3682 {
3683 m_host.TaskInventory.LockItemsForRead(false);
3684 return;
3685 }
3686 else
3358 { 3687 {
3359 item = m_host.TaskInventory[invItemID]; 3688 item = m_host.TaskInventory[invItemID];
3360 } 3689 }
3690 m_host.TaskInventory.LockItemsForRead(false);
3361 3691
3362 if (agentID == UUID.Zero || perm == 0) // Releasing permissions 3692 if (agentID == UUID.Zero || perm == 0) // Releasing permissions
3363 { 3693 {
@@ -3385,15 +3715,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3385 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3715 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3386 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3716 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3387 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3717 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3718 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3388 ScriptBaseClass.PERMISSION_ATTACH; 3719 ScriptBaseClass.PERMISSION_ATTACH;
3389 3720
3390 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3721 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3391 { 3722 {
3392 lock (m_host.TaskInventory) 3723 m_host.TaskInventory.LockItemsForWrite(true);
3393 { 3724 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3394 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3725 m_host.TaskInventory[invItemID].PermsMask = perm;
3395 m_host.TaskInventory[invItemID].PermsMask = perm; 3726 m_host.TaskInventory.LockItemsForWrite(false);
3396 }
3397 3727
3398 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3728 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3399 "run_time_permissions", new Object[] { 3729 "run_time_permissions", new Object[] {
@@ -3403,28 +3733,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3403 return; 3733 return;
3404 } 3734 }
3405 } 3735 }
3406 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3736 else
3407 { 3737 {
3408 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3738 bool sitting = false;
3409 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3739 if (m_host.SitTargetAvatar == agentID)
3410 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3740 {
3411 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3741 sitting = true;
3412 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3742 }
3743 else
3744 {
3745 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3746 {
3747 if (p.SitTargetAvatar == agentID)
3748 sitting = true;
3749 }
3750 }
3413 3751
3414 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3752 if (sitting)
3415 { 3753 {
3416 lock (m_host.TaskInventory) 3754 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3755 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3756 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3757 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3758 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3759
3760 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3417 { 3761 {
3762 m_host.TaskInventory.LockItemsForWrite(true);
3418 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3763 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3419 m_host.TaskInventory[invItemID].PermsMask = perm; 3764 m_host.TaskInventory[invItemID].PermsMask = perm;
3420 } 3765 m_host.TaskInventory.LockItemsForWrite(false);
3421 3766
3422 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3767 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3423 "run_time_permissions", new Object[] { 3768 "run_time_permissions", new Object[] {
3424 new LSL_Integer(perm) }, 3769 new LSL_Integer(perm) },
3425 new DetectParams[0])); 3770 new DetectParams[0]));
3426 3771
3427 return; 3772 return;
3773 }
3428 } 3774 }
3429 } 3775 }
3430 3776
@@ -3438,11 +3784,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 3784
3439 if (!m_waitingForScriptAnswer) 3785 if (!m_waitingForScriptAnswer)
3440 { 3786 {
3441 lock (m_host.TaskInventory) 3787 m_host.TaskInventory.LockItemsForWrite(true);
3442 { 3788 m_host.TaskInventory[invItemID].PermsGranter = agentID;
3443 m_host.TaskInventory[invItemID].PermsGranter = agentID; 3789 m_host.TaskInventory[invItemID].PermsMask = 0;
3444 m_host.TaskInventory[invItemID].PermsMask = 0; 3790 m_host.TaskInventory.LockItemsForWrite(false);
3445 }
3446 3791
3447 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3792 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3448 m_waitingForScriptAnswer=true; 3793 m_waitingForScriptAnswer=true;
@@ -3477,10 +3822,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3477 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3822 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3478 llReleaseControls(); 3823 llReleaseControls();
3479 3824
3480 lock (m_host.TaskInventory) 3825
3481 { 3826 m_host.TaskInventory.LockItemsForWrite(true);
3482 m_host.TaskInventory[invItemID].PermsMask = answer; 3827 m_host.TaskInventory[invItemID].PermsMask = answer;
3483 } 3828 m_host.TaskInventory.LockItemsForWrite(false);
3829
3484 3830
3485 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams( 3831 m_ScriptEngine.PostScriptEvent(m_itemID, new EventParams(
3486 "run_time_permissions", new Object[] { 3832 "run_time_permissions", new Object[] {
@@ -3492,16 +3838,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3492 { 3838 {
3493 m_host.AddScriptLPS(1); 3839 m_host.AddScriptLPS(1);
3494 3840
3495 lock (m_host.TaskInventory) 3841 m_host.TaskInventory.LockItemsForRead(true);
3842
3843 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3496 { 3844 {
3497 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3845 if (item.Type == 10 && item.ItemID == m_itemID)
3498 { 3846 {
3499 if (item.Type == 10 && item.ItemID == m_itemID) 3847 m_host.TaskInventory.LockItemsForRead(false);
3500 { 3848 return item.PermsGranter.ToString();
3501 return item.PermsGranter.ToString();
3502 }
3503 } 3849 }
3504 } 3850 }
3851 m_host.TaskInventory.LockItemsForRead(false);
3505 3852
3506 return UUID.Zero.ToString(); 3853 return UUID.Zero.ToString();
3507 } 3854 }
@@ -3510,19 +3857,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3510 { 3857 {
3511 m_host.AddScriptLPS(1); 3858 m_host.AddScriptLPS(1);
3512 3859
3513 lock (m_host.TaskInventory) 3860 m_host.TaskInventory.LockItemsForRead(true);
3861
3862 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
3514 { 3863 {
3515 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 3864 if (item.Type == 10 && item.ItemID == m_itemID)
3516 { 3865 {
3517 if (item.Type == 10 && item.ItemID == m_itemID) 3866 int perms = item.PermsMask;
3518 { 3867 if (m_automaticLinkPermission)
3519 int perms = item.PermsMask; 3868 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS;
3520 if (m_automaticLinkPermission) 3869 m_host.TaskInventory.LockItemsForRead(false);
3521 perms |= ScriptBaseClass.PERMISSION_CHANGE_LINKS; 3870 return perms;
3522 return perms;
3523 }
3524 } 3871 }
3525 } 3872 }
3873 m_host.TaskInventory.LockItemsForRead(false);
3526 3874
3527 return 0; 3875 return 0;
3528 } 3876 }
@@ -3544,9 +3892,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3544 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3892 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3545 { 3893 {
3546 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3894 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3547 3895 if (parts.Count > 0)
3548 foreach (SceneObjectPart part in parts) 3896 {
3549 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3897 try
3898 {
3899 parts[0].ParentGroup.areUpdatesSuspended = true;
3900 foreach (SceneObjectPart part in parts)
3901 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3902 }
3903 finally
3904 {
3905 parts[0].ParentGroup.areUpdatesSuspended = false;
3906 }
3907 }
3550 } 3908 }
3551 3909
3552 public void llCreateLink(string target, int parent) 3910 public void llCreateLink(string target, int parent)
@@ -3559,11 +3917,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3559 return; 3917 return;
3560 3918
3561 TaskInventoryItem item; 3919 TaskInventoryItem item;
3562 lock (m_host.TaskInventory) 3920 m_host.TaskInventory.LockItemsForRead(true);
3563 { 3921 item = m_host.TaskInventory[invItemID];
3564 item = m_host.TaskInventory[invItemID]; 3922 m_host.TaskInventory.LockItemsForRead(false);
3565 } 3923
3566
3567 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3924 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3568 && !m_automaticLinkPermission) 3925 && !m_automaticLinkPermission)
3569 { 3926 {
@@ -3580,11 +3937,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3580 3937
3581 if (targetPart.ParentGroup.AttachmentPoint != 0) 3938 if (targetPart.ParentGroup.AttachmentPoint != 0)
3582 return; // Fail silently if attached 3939 return; // Fail silently if attached
3940
3941 if (targetPart.ParentGroup.RootPart.OwnerID != m_host.ParentGroup.RootPart.OwnerID)
3942 return;
3943
3583 SceneObjectGroup parentPrim = null, childPrim = null; 3944 SceneObjectGroup parentPrim = null, childPrim = null;
3584 3945
3585 if (targetPart != null) 3946 if (targetPart != null)
3586 { 3947 {
3587 if (parent != 0) { 3948 if (parent != 0)
3949 {
3588 parentPrim = m_host.ParentGroup; 3950 parentPrim = m_host.ParentGroup;
3589 childPrim = targetPart.ParentGroup; 3951 childPrim = targetPart.ParentGroup;
3590 } 3952 }
@@ -3616,16 +3978,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3616 m_host.AddScriptLPS(1); 3978 m_host.AddScriptLPS(1);
3617 UUID invItemID = InventorySelf(); 3979 UUID invItemID = InventorySelf();
3618 3980
3619 lock (m_host.TaskInventory) 3981 m_host.TaskInventory.LockItemsForRead(true);
3620 {
3621 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0 3982 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
3622 && !m_automaticLinkPermission) 3983 && !m_automaticLinkPermission)
3623 { 3984 {
3624 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!"); 3985 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
3986 m_host.TaskInventory.LockItemsForRead(false);
3625 return; 3987 return;
3626 } 3988 }
3627 } 3989 m_host.TaskInventory.LockItemsForRead(false);
3628 3990
3629 if (linknum < ScriptBaseClass.LINK_THIS) 3991 if (linknum < ScriptBaseClass.LINK_THIS)
3630 return; 3992 return;
3631 3993
@@ -3664,10 +4026,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3664 // Restructuring Multiple Prims. 4026 // Restructuring Multiple Prims.
3665 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4027 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3666 parts.Remove(parentPrim.RootPart); 4028 parts.Remove(parentPrim.RootPart);
3667 foreach (SceneObjectPart part in parts) 4029 if (parts.Count > 0)
3668 { 4030 {
3669 parentPrim.DelinkFromGroup(part.LocalId, true); 4031 try
4032 {
4033 parts[0].ParentGroup.areUpdatesSuspended = true;
4034 foreach (SceneObjectPart part in parts)
4035 {
4036 parentPrim.DelinkFromGroup(part.LocalId, true);
4037 }
4038 }
4039 finally
4040 {
4041 parts[0].ParentGroup.areUpdatesSuspended = false;
4042 }
3670 } 4043 }
4044
3671 parentPrim.HasGroupChanged = true; 4045 parentPrim.HasGroupChanged = true;
3672 parentPrim.ScheduleGroupForFullUpdate(); 4046 parentPrim.ScheduleGroupForFullUpdate();
3673 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4047 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3676,11 +4050,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3676 { 4050 {
3677 SceneObjectPart newRoot = parts[0]; 4051 SceneObjectPart newRoot = parts[0];
3678 parts.Remove(newRoot); 4052 parts.Remove(newRoot);
3679 foreach (SceneObjectPart part in parts) 4053
4054 try
3680 { 4055 {
3681 part.UpdateFlag = 0; 4056 parts[0].ParentGroup.areUpdatesSuspended = true;
3682 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4057 foreach (SceneObjectPart part in parts)
4058 {
4059 part.UpdateFlag = 0;
4060 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4061 }
3683 } 4062 }
4063 finally
4064 {
4065 parts[0].ParentGroup.areUpdatesSuspended = false;
4066 }
4067
4068
3684 newRoot.ParentGroup.HasGroupChanged = true; 4069 newRoot.ParentGroup.HasGroupChanged = true;
3685 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4070 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3686 } 4071 }
@@ -3700,6 +4085,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3700 public void llBreakAllLinks() 4085 public void llBreakAllLinks()
3701 { 4086 {
3702 m_host.AddScriptLPS(1); 4087 m_host.AddScriptLPS(1);
4088
4089 UUID invItemID = InventorySelf();
4090
4091 TaskInventoryItem item;
4092 m_host.TaskInventory.LockItemsForRead(true);
4093 item = m_host.TaskInventory[invItemID];
4094 m_host.TaskInventory.LockItemsForRead(false);
4095
4096 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4097 && !m_automaticLinkPermission)
4098 {
4099 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4100 return;
4101 }
4102
3703 SceneObjectGroup parentPrim = m_host.ParentGroup; 4103 SceneObjectGroup parentPrim = m_host.ParentGroup;
3704 if (parentPrim.AttachmentPoint != 0) 4104 if (parentPrim.AttachmentPoint != 0)
3705 return; // Fail silently if attached 4105 return; // Fail silently if attached
@@ -3745,6 +4145,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3745 } 4145 }
3746 else 4146 else
3747 { 4147 {
4148 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4149 {
4150 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4151
4152 if (linknum < 0)
4153 return UUID.Zero.ToString();
4154
4155 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4156 if (avatars.Count > linknum)
4157 {
4158 return avatars[linknum].UUID.ToString();
4159 }
4160 }
3748 return UUID.Zero.ToString(); 4161 return UUID.Zero.ToString();
3749 } 4162 }
3750 } 4163 }
@@ -3843,17 +4256,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 m_host.AddScriptLPS(1); 4256 m_host.AddScriptLPS(1);
3844 int count = 0; 4257 int count = 0;
3845 4258
3846 lock (m_host.TaskInventory) 4259 m_host.TaskInventory.LockItemsForRead(true);
4260 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3847 { 4261 {
3848 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4262 if (inv.Value.Type == type || type == -1)
3849 { 4263 {
3850 if (inv.Value.Type == type || type == -1) 4264 count = count + 1;
3851 {
3852 count = count + 1;
3853 }
3854 } 4265 }
3855 } 4266 }
3856 4267
4268 m_host.TaskInventory.LockItemsForRead(false);
3857 return count; 4269 return count;
3858 } 4270 }
3859 4271
@@ -3862,16 +4274,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3862 m_host.AddScriptLPS(1); 4274 m_host.AddScriptLPS(1);
3863 ArrayList keys = new ArrayList(); 4275 ArrayList keys = new ArrayList();
3864 4276
3865 lock (m_host.TaskInventory) 4277 m_host.TaskInventory.LockItemsForRead(true);
4278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3866 { 4279 {
3867 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4280 if (inv.Value.Type == type || type == -1)
3868 { 4281 {
3869 if (inv.Value.Type == type || type == -1) 4282 keys.Add(inv.Value.Name);
3870 {
3871 keys.Add(inv.Value.Name);
3872 }
3873 } 4283 }
3874 } 4284 }
4285 m_host.TaskInventory.LockItemsForRead(false);
3875 4286
3876 if (keys.Count == 0) 4287 if (keys.Count == 0)
3877 { 4288 {
@@ -3908,25 +4319,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3908 } 4319 }
3909 4320
3910 // move the first object found with this inventory name 4321 // move the first object found with this inventory name
3911 lock (m_host.TaskInventory) 4322 m_host.TaskInventory.LockItemsForRead(true);
4323 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3912 { 4324 {
3913 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4325 if (inv.Value.Name == inventory)
3914 { 4326 {
3915 if (inv.Value.Name == inventory) 4327 found = true;
3916 { 4328 objId = inv.Key;
3917 found = true; 4329 assetType = inv.Value.Type;
3918 objId = inv.Key; 4330 objName = inv.Value.Name;
3919 assetType = inv.Value.Type; 4331 break;
3920 objName = inv.Value.Name;
3921 break;
3922 }
3923 } 4332 }
3924 } 4333 }
4334 m_host.TaskInventory.LockItemsForRead(false);
3925 4335
3926 if (!found) 4336 if (!found)
3927 { 4337 {
3928 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4338 llSay(0, String.Format("Could not find object '{0}'", inventory));
3929 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4339 return;
4340// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3930 } 4341 }
3931 4342
3932 // check if destination is an object 4343 // check if destination is an object
@@ -3952,6 +4363,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3952 return; 4363 return;
3953 } 4364 }
3954 } 4365 }
4366
3955 // destination is an avatar 4367 // destination is an avatar
3956 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4368 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3957 4369
@@ -3974,26 +4386,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3974 bucket); 4386 bucket);
3975 if (m_TransferModule != null) 4387 if (m_TransferModule != null)
3976 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4388 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4389
4390 //This delay should only occur when giving inventory to avatars.
3977 ScriptSleep(3000); 4391 ScriptSleep(3000);
3978 } 4392 }
3979 } 4393 }
3980 4394
4395 [DebuggerNonUserCode]
3981 public void llRemoveInventory(string name) 4396 public void llRemoveInventory(string name)
3982 { 4397 {
3983 m_host.AddScriptLPS(1); 4398 m_host.AddScriptLPS(1);
3984 4399
3985 lock (m_host.TaskInventory) 4400 List<TaskInventoryItem> inv;
4401 try
3986 { 4402 {
3987 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4403 m_host.TaskInventory.LockItemsForRead(true);
4404 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4405 }
4406 finally
4407 {
4408 m_host.TaskInventory.LockItemsForRead(false);
4409 }
4410 foreach (TaskInventoryItem item in inv)
4411 {
4412 if (item.Name == name)
3988 { 4413 {
3989 if (item.Name == name) 4414 if (item.ItemID == m_itemID)
3990 { 4415 throw new ScriptDeleteException();
3991 if (item.ItemID == m_itemID) 4416 else
3992 throw new ScriptDeleteException(); 4417 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3993 else 4418 return;
3994 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3995 return;
3996 }
3997 } 4419 }
3998 } 4420 }
3999 } 4421 }
@@ -4028,112 +4450,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4028 { 4450 {
4029 m_host.AddScriptLPS(1); 4451 m_host.AddScriptLPS(1);
4030 4452
4031 UUID uuid = (UUID)id; 4453 UUID uuid;
4032 PresenceInfo pinfo = null; 4454 if (UUID.TryParse(id, out uuid))
4033 UserAccount account;
4034
4035 UserInfoCacheEntry ce;
4036 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4037 { 4455 {
4038 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4456 PresenceInfo pinfo = null;
4039 if (account == null) 4457 UserAccount account;
4458
4459 UserInfoCacheEntry ce;
4460 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4040 { 4461 {
4041 m_userInfoCache[uuid] = null; // Cache negative 4462 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4042 return UUID.Zero.ToString(); 4463 if (account == null)
4043 } 4464 {
4465 m_userInfoCache[uuid] = null; // Cache negative
4466 return UUID.Zero.ToString();
4467 }
4044 4468
4045 4469
4046 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4470 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4047 if (pinfos != null && pinfos.Length > 0) 4471 if (pinfos != null && pinfos.Length > 0)
4048 {
4049 foreach (PresenceInfo p in pinfos)
4050 { 4472 {
4051 if (p.RegionID != UUID.Zero) 4473 foreach (PresenceInfo p in pinfos)
4052 { 4474 {
4053 pinfo = p; 4475 if (p.RegionID != UUID.Zero)
4476 {
4477 pinfo = p;
4478 }
4054 } 4479 }
4055 } 4480 }
4056 }
4057 4481
4058 ce = new UserInfoCacheEntry(); 4482 ce = new UserInfoCacheEntry();
4059 ce.time = Util.EnvironmentTickCount(); 4483 ce.time = Util.EnvironmentTickCount();
4060 ce.account = account; 4484 ce.account = account;
4061 ce.pinfo = pinfo; 4485 ce.pinfo = pinfo;
4062 } 4486 m_userInfoCache[uuid] = ce;
4063 else 4487 }
4064 { 4488 else
4065 if (ce == null) 4489 {
4066 return UUID.Zero.ToString(); 4490 if (ce == null)
4491 return UUID.Zero.ToString();
4067 4492
4068 account = ce.account; 4493 account = ce.account;
4069 pinfo = ce.pinfo; 4494 pinfo = ce.pinfo;
4070 } 4495 }
4071 4496
4072 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4497 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4073 {
4074 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4075 if (pinfos != null && pinfos.Length > 0)
4076 { 4498 {
4077 foreach (PresenceInfo p in pinfos) 4499 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4500 if (pinfos != null && pinfos.Length > 0)
4078 { 4501 {
4079 if (p.RegionID != UUID.Zero) 4502 foreach (PresenceInfo p in pinfos)
4080 { 4503 {
4081 pinfo = p; 4504 if (p.RegionID != UUID.Zero)
4505 {
4506 pinfo = p;
4507 }
4082 } 4508 }
4083 } 4509 }
4084 } 4510 else
4085 else 4511 pinfo = null;
4086 pinfo = null;
4087 4512
4088 ce.time = Util.EnvironmentTickCount(); 4513 ce.time = Util.EnvironmentTickCount();
4089 ce.pinfo = pinfo; 4514 ce.pinfo = pinfo;
4090 } 4515 }
4091 4516
4092 string reply = String.Empty; 4517 string reply = String.Empty;
4093 4518
4094 switch (data) 4519 switch (data)
4095 { 4520 {
4096 case 1: // DATA_ONLINE (0|1) 4521 case 1: // DATA_ONLINE (0|1)
4097 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4522 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4098 reply = "1"; 4523 reply = "1";
4099 else 4524 else
4100 reply = "0"; 4525 reply = "0";
4101 break; 4526 break;
4102 case 2: // DATA_NAME (First Last) 4527 case 2: // DATA_NAME (First Last)
4103 reply = account.FirstName + " " + account.LastName; 4528 reply = account.FirstName + " " + account.LastName;
4104 break; 4529 break;
4105 case 3: // DATA_BORN (YYYY-MM-DD) 4530 case 3: // DATA_BORN (YYYY-MM-DD)
4106 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4531 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4107 born = born.AddSeconds(account.Created); 4532 born = born.AddSeconds(account.Created);
4108 reply = born.ToString("yyyy-MM-dd"); 4533 reply = born.ToString("yyyy-MM-dd");
4109 break; 4534 break;
4110 case 4: // DATA_RATING (0,0,0,0,0,0) 4535 case 4: // DATA_RATING (0,0,0,0,0,0)
4111 reply = "0,0,0,0,0,0"; 4536 reply = "0,0,0,0,0,0";
4112 break; 4537 break;
4113 case 8: // DATA_PAYINFO (0|1|2|3) 4538 case 8: // DATA_PAYINFO (0|1|2|3)
4114 reply = "0"; 4539 reply = "0";
4115 break; 4540 break;
4116 default: 4541 default:
4117 return UUID.Zero.ToString(); // Raise no event 4542 return UUID.Zero.ToString(); // Raise no event
4118 } 4543 }
4119 4544
4120 UUID rq = UUID.Random(); 4545 UUID rq = UUID.Random();
4121 4546
4122 UUID tid = AsyncCommands. 4547 UUID tid = AsyncCommands.
4123 DataserverPlugin.RegisterRequest(m_localID, 4548 DataserverPlugin.RegisterRequest(m_localID,
4124 m_itemID, rq.ToString()); 4549 m_itemID, rq.ToString());
4125 4550
4126 AsyncCommands. 4551 AsyncCommands.
4127 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4552 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4128 4553
4129 ScriptSleep(100); 4554 ScriptSleep(100);
4130 return tid.ToString(); 4555 return tid.ToString();
4556 }
4557 else
4558 {
4559 ShoutError("Invalid UUID passed to llRequestAgentData.");
4560 }
4561 return "";
4131 } 4562 }
4132 4563
4133 public LSL_String llRequestInventoryData(string name) 4564 public LSL_String llRequestInventoryData(string name)
4134 { 4565 {
4135 m_host.AddScriptLPS(1); 4566 m_host.AddScriptLPS(1);
4136 4567
4568 //Clone is thread safe
4137 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4569 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4138 4570
4139 foreach (TaskInventoryItem item in itemDictionary.Values) 4571 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4187,6 +4619,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4187 ScenePresence presence = World.GetScenePresence(agentId); 4619 ScenePresence presence = World.GetScenePresence(agentId);
4188 if (presence != null) 4620 if (presence != null)
4189 { 4621 {
4622 // agent must not be a god
4623 if (presence.UserLevel >= 200) return;
4624
4190 // agent must be over the owners land 4625 // agent must be over the owners land
4191 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4626 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4192 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4627 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
@@ -4209,7 +4644,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4209 UUID av = new UUID(); 4644 UUID av = new UUID();
4210 if (!UUID.TryParse(agent,out av)) 4645 if (!UUID.TryParse(agent,out av))
4211 { 4646 {
4212 LSLError("First parameter to llDialog needs to be a key"); 4647 //LSLError("First parameter to llDialog needs to be a key");
4213 return; 4648 return;
4214 } 4649 }
4215 4650
@@ -4246,17 +4681,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4246 UUID soundId = UUID.Zero; 4681 UUID soundId = UUID.Zero;
4247 if (!UUID.TryParse(impact_sound, out soundId)) 4682 if (!UUID.TryParse(impact_sound, out soundId))
4248 { 4683 {
4249 lock (m_host.TaskInventory) 4684 m_host.TaskInventory.LockItemsForRead(true);
4685 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4250 { 4686 {
4251 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4687 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4252 { 4688 {
4253 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4689 soundId = item.AssetID;
4254 { 4690 break;
4255 soundId = item.AssetID;
4256 break;
4257 }
4258 } 4691 }
4259 } 4692 }
4693 m_host.TaskInventory.LockItemsForRead(false);
4260 } 4694 }
4261 m_host.CollisionSound = soundId; 4695 m_host.CollisionSound = soundId;
4262 m_host.CollisionSoundVolume = (float)impact_volume; 4696 m_host.CollisionSoundVolume = (float)impact_volume;
@@ -4296,6 +4730,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4296 UUID partItemID; 4730 UUID partItemID;
4297 foreach (SceneObjectPart part in parts) 4731 foreach (SceneObjectPart part in parts)
4298 { 4732 {
4733 //Clone is thread safe
4299 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4734 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4300 4735
4301 foreach (TaskInventoryItem item in itemsDictionary.Values) 4736 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4510,17 +4945,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4510 4945
4511 m_host.AddScriptLPS(1); 4946 m_host.AddScriptLPS(1);
4512 4947
4513 lock (m_host.TaskInventory) 4948 m_host.TaskInventory.LockItemsForRead(true);
4949 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4514 { 4950 {
4515 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4951 if (item.Type == 10 && item.ItemID == m_itemID)
4516 { 4952 {
4517 if (item.Type == 10 && item.ItemID == m_itemID) 4953 result = item.Name!=null?item.Name:String.Empty;
4518 { 4954 break;
4519 result = item.Name != null ? item.Name : String.Empty;
4520 break;
4521 }
4522 } 4955 }
4523 } 4956 }
4957 m_host.TaskInventory.LockItemsForRead(false);
4524 4958
4525 return result; 4959 return result;
4526 } 4960 }
@@ -4689,23 +5123,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4689 { 5123 {
4690 m_host.AddScriptLPS(1); 5124 m_host.AddScriptLPS(1);
4691 5125
4692 lock (m_host.TaskInventory) 5126 m_host.TaskInventory.LockItemsForRead(true);
5127 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4693 { 5128 {
4694 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5129 if (inv.Value.Name == name)
4695 { 5130 {
4696 if (inv.Value.Name == name) 5131 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4697 { 5132 {
4698 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5133 m_host.TaskInventory.LockItemsForRead(false);
4699 { 5134 return inv.Value.AssetID.ToString();
4700 return inv.Value.AssetID.ToString(); 5135 }
4701 } 5136 else
4702 else 5137 {
4703 { 5138 m_host.TaskInventory.LockItemsForRead(false);
4704 return UUID.Zero.ToString(); 5139 return UUID.Zero.ToString();
4705 }
4706 } 5140 }
4707 } 5141 }
4708 } 5142 }
5143 m_host.TaskInventory.LockItemsForRead(false);
4709 5144
4710 return UUID.Zero.ToString(); 5145 return UUID.Zero.ToString();
4711 } 5146 }
@@ -4858,14 +5293,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4858 { 5293 {
4859 m_host.AddScriptLPS(1); 5294 m_host.AddScriptLPS(1);
4860 5295
4861 if (src == null) 5296 return src.Length;
4862 {
4863 return 0;
4864 }
4865 else
4866 {
4867 return src.Length;
4868 }
4869 } 5297 }
4870 5298
4871 public LSL_Integer llList2Integer(LSL_List src, int index) 5299 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4911,7 +5339,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4911 else if (src.Data[index] is LSL_Float) 5339 else if (src.Data[index] is LSL_Float)
4912 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5340 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4913 else if (src.Data[index] is LSL_String) 5341 else if (src.Data[index] is LSL_String)
4914 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5342 {
5343 string str = ((LSL_String) src.Data[index]).m_string;
5344 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5345 if (m != Match.Empty)
5346 {
5347 str = m.Value;
5348 double d = 0.0;
5349 if (!Double.TryParse(str, out d))
5350 return 0.0;
5351
5352 return d;
5353 }
5354 return 0.0;
5355 }
4915 return Convert.ToDouble(src.Data[index]); 5356 return Convert.ToDouble(src.Data[index]);
4916 } 5357 }
4917 catch (FormatException) 5358 catch (FormatException)
@@ -5184,7 +5625,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5184 } 5625 }
5185 } 5626 }
5186 } 5627 }
5187 else { 5628 else
5629 {
5188 object[] array = new object[src.Length]; 5630 object[] array = new object[src.Length];
5189 Array.Copy(src.Data, 0, array, 0, src.Length); 5631 Array.Copy(src.Data, 0, array, 0, src.Length);
5190 result = new LSL_List(array); 5632 result = new LSL_List(array);
@@ -5635,10 +6077,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5635 m_host.AddScriptLPS(1); 6077 m_host.AddScriptLPS(1);
5636 6078
5637 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6079 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5638 6080 if (parts.Count > 0)
5639 foreach (var part in parts)
5640 { 6081 {
5641 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6082 try
6083 {
6084 parts[0].ParentGroup.areUpdatesSuspended = true;
6085 foreach (var part in parts)
6086 {
6087 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6088 }
6089 }
6090 finally
6091 {
6092 parts[0].ParentGroup.areUpdatesSuspended = false;
6093 }
5642 } 6094 }
5643 } 6095 }
5644 6096
@@ -5692,6 +6144,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5692 ScriptSleep(5000); 6144 ScriptSleep(5000);
5693 } 6145 }
5694 6146
6147 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6148 {
6149 return ParseString2List(str, separators, in_spacers, false);
6150 }
6151
5695 public LSL_Integer llOverMyLand(string id) 6152 public LSL_Integer llOverMyLand(string id)
5696 { 6153 {
5697 m_host.AddScriptLPS(1); 6154 m_host.AddScriptLPS(1);
@@ -5892,7 +6349,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5892 return m_host.ParentGroup.AttachmentPoint; 6349 return m_host.ParentGroup.AttachmentPoint;
5893 } 6350 }
5894 6351
5895 public LSL_Integer llGetFreeMemory() 6352 public virtual LSL_Integer llGetFreeMemory()
5896 { 6353 {
5897 m_host.AddScriptLPS(1); 6354 m_host.AddScriptLPS(1);
5898 // Make scripts designed for LSO happy 6355 // Make scripts designed for LSO happy
@@ -6009,7 +6466,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6009 SetParticleSystem(m_host, rules); 6466 SetParticleSystem(m_host, rules);
6010 } 6467 }
6011 6468
6012 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6469 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6470 {
6013 6471
6014 6472
6015 if (rules.Length == 0) 6473 if (rules.Length == 0)
@@ -6203,14 +6661,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6203 6661
6204 protected UUID GetTaskInventoryItem(string name) 6662 protected UUID GetTaskInventoryItem(string name)
6205 { 6663 {
6206 lock (m_host.TaskInventory) 6664 m_host.TaskInventory.LockItemsForRead(true);
6665 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6207 { 6666 {
6208 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6667 if (inv.Value.Name == name)
6209 { 6668 {
6210 if (inv.Value.Name == name) 6669 m_host.TaskInventory.LockItemsForRead(false);
6211 return inv.Key; 6670 return inv.Key;
6212 } 6671 }
6213 } 6672 }
6673 m_host.TaskInventory.LockItemsForRead(false);
6214 6674
6215 return UUID.Zero; 6675 return UUID.Zero;
6216 } 6676 }
@@ -6460,13 +6920,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6460 UUID av = new UUID(); 6920 UUID av = new UUID();
6461 if (!UUID.TryParse(avatar,out av)) 6921 if (!UUID.TryParse(avatar,out av))
6462 { 6922 {
6463 LSLError("First parameter to llDialog needs to be a key"); 6923 //LSLError("First parameter to llDialog needs to be a key");
6464 return; 6924 return;
6465 } 6925 }
6466 if (buttons.Length < 1) 6926 if (buttons.Length < 1)
6467 { 6927 {
6468 LSLError("No less than 1 button can be shown"); 6928 buttons.Add("OK");
6469 return;
6470 } 6929 }
6471 if (buttons.Length > 12) 6930 if (buttons.Length > 12)
6472 { 6931 {
@@ -6483,7 +6942,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6483 } 6942 }
6484 if (buttons.Data[i].ToString().Length > 24) 6943 if (buttons.Data[i].ToString().Length > 24)
6485 { 6944 {
6486 LSLError("button label cannot be longer than 24 characters"); 6945 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6487 return; 6946 return;
6488 } 6947 }
6489 buts[i] = buttons.Data[i].ToString(); 6948 buts[i] = buttons.Data[i].ToString();
@@ -6542,22 +7001,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6542 } 7001 }
6543 7002
6544 // copy the first script found with this inventory name 7003 // copy the first script found with this inventory name
6545 lock (m_host.TaskInventory) 7004 TaskInventoryItem scriptItem = null;
7005 m_host.TaskInventory.LockItemsForRead(true);
7006 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6546 { 7007 {
6547 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7008 if (inv.Value.Name == name)
6548 { 7009 {
6549 if (inv.Value.Name == name) 7010 // make sure the object is a script
7011 if (10 == inv.Value.Type)
6550 { 7012 {
6551 // make sure the object is a script 7013 found = true;
6552 if (10 == inv.Value.Type) 7014 srcId = inv.Key;
6553 { 7015 scriptItem = inv.Value;
6554 found = true; 7016 break;
6555 srcId = inv.Key;
6556 break;
6557 }
6558 } 7017 }
6559 } 7018 }
6560 } 7019 }
7020 m_host.TaskInventory.LockItemsForRead(false);
6561 7021
6562 if (!found) 7022 if (!found)
6563 { 7023 {
@@ -6565,8 +7025,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6565 return; 7025 return;
6566 } 7026 }
6567 7027
6568 // the rest of the permission checks are done in RezScript, so check the pin there as well 7028 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6569 World.RezScript(srcId, m_host, destId, pin, running, start_param); 7029 if (dest != null)
7030 {
7031 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7032 {
7033 // the rest of the permission checks are done in RezScript, so check the pin there as well
7034 World.RezScript(srcId, m_host, destId, pin, running, start_param);
7035
7036 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7037 m_host.Inventory.RemoveInventoryItem(srcId);
7038 }
7039 }
6570 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7040 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6571 ScriptSleep(3000); 7041 ScriptSleep(3000);
6572 } 7042 }
@@ -6629,19 +7099,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6629 public LSL_String llMD5String(string src, int nonce) 7099 public LSL_String llMD5String(string src, int nonce)
6630 { 7100 {
6631 m_host.AddScriptLPS(1); 7101 m_host.AddScriptLPS(1);
6632 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7102 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6633 } 7103 }
6634 7104
6635 public LSL_String llSHA1String(string src) 7105 public LSL_String llSHA1String(string src)
6636 { 7106 {
6637 m_host.AddScriptLPS(1); 7107 m_host.AddScriptLPS(1);
6638 return Util.SHA1Hash(src).ToLower(); 7108 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6639 } 7109 }
6640 7110
6641 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7111 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6642 { 7112 {
6643 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7113 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6644 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7114 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7115 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7116 return shapeBlock;
6645 7117
6646 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7118 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6647 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7119 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6746,6 +7218,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6746 // Prim type box, cylinder and prism. 7218 // Prim type box, cylinder and prism.
6747 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) 7219 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)
6748 { 7220 {
7221 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7222 return;
7223
6749 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7224 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6750 ObjectShapePacket.ObjectDataBlock shapeBlock; 7225 ObjectShapePacket.ObjectDataBlock shapeBlock;
6751 7226
@@ -6799,6 +7274,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6799 // Prim type sphere. 7274 // Prim type sphere.
6800 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7275 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6801 { 7276 {
7277 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7278 return;
7279
6802 ObjectShapePacket.ObjectDataBlock shapeBlock; 7280 ObjectShapePacket.ObjectDataBlock shapeBlock;
6803 7281
6804 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7282 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6840,6 +7318,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6840 // Prim type torus, tube and ring. 7318 // Prim type torus, tube and ring.
6841 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) 7319 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)
6842 { 7320 {
7321 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7322 return;
7323
6843 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7324 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6844 ObjectShapePacket.ObjectDataBlock shapeBlock; 7325 ObjectShapePacket.ObjectDataBlock shapeBlock;
6845 7326
@@ -6975,6 +7456,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6975 // Prim type sculpt. 7456 // Prim type sculpt.
6976 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7457 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
6977 { 7458 {
7459 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7460 return;
7461
6978 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7462 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
6979 UUID sculptId; 7463 UUID sculptId;
6980 7464
@@ -6991,13 +7475,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6991 shapeBlock.PathScaleX = 100; 7475 shapeBlock.PathScaleX = 100;
6992 shapeBlock.PathScaleY = 150; 7476 shapeBlock.PathScaleY = 150;
6993 7477
6994 if (type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER && 7478 if ((type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_CYLINDER) == 0 &&
6995 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE && 7479 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_PLANE) == 0 &&
6996 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE && 7480 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE) == 0 &&
6997 type != (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) 7481 (type & (int)ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS) == 0)
6998 { 7482 {
6999 // default 7483 // default
7000 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7484 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7001 } 7485 }
7002 7486
7003 part.Shape.SetSculptProperties((byte)type, sculptId); 7487 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7013,32 +7497,87 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7013 ScriptSleep(200); 7497 ScriptSleep(200);
7014 } 7498 }
7015 7499
7016 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7500 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7017 { 7501 {
7018 m_host.AddScriptLPS(1); 7502 m_host.AddScriptLPS(1);
7019 7503
7020 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7504 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7505 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7506 if (parts.Count>0)
7507 {
7508 try
7509 {
7510 parts[0].ParentGroup.areUpdatesSuspended = true;
7511 foreach (SceneObjectPart part in parts)
7512 SetPrimParams(part, rules);
7513 }
7514 finally
7515 {
7516 parts[0].ParentGroup.areUpdatesSuspended = false;
7517 }
7518 }
7519 if (avatars.Count > 0)
7520 {
7521 foreach (ScenePresence avatar in avatars)
7522 SetPrimParams(avatar, rules);
7523 }
7524 }
7021 7525
7022 foreach (SceneObjectPart part in parts) 7526 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7023 SetPrimParams(part, rules); 7527 {
7024 7528 llSetLinkPrimitiveParamsFast(linknumber, rules);
7025 ScriptSleep(200); 7529 ScriptSleep(200);
7026 } 7530 }
7027 7531
7028 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7532 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7029 { 7533 {
7030 m_host.AddScriptLPS(1); 7534 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7535 //We only support PRIM_POSITION and PRIM_ROTATION
7031 7536
7032 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7537 int idx = 0;
7033 7538
7034 foreach (SceneObjectPart part in parts) 7539 while (idx < rules.Length)
7035 SetPrimParams(part, rules); 7540 {
7541 int code = rules.GetLSLIntegerItem(idx++);
7542
7543 int remain = rules.Length - idx;
7544
7545
7546
7547 switch (code)
7548 {
7549 case (int)ScriptBaseClass.PRIM_POSITION:
7550 if (remain < 1)
7551 return;
7552 LSL_Vector v;
7553 v = rules.GetVector3Item(idx++);
7554 av.AbsolutePosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
7555 av.SendAvatarDataToAllAgents();
7556
7557 break;
7558
7559 case (int)ScriptBaseClass.PRIM_ROTATION:
7560 if (remain < 1)
7561 return;
7562 LSL_Rotation r;
7563 r = rules.GetQuaternionItem(idx++);
7564 av.OffsetRotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
7565 av.SendAvatarDataToAllAgents();
7566 break;
7567 }
7568 }
7036 } 7569 }
7037 7570
7038 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7571 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7039 { 7572 {
7573 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7574 return;
7575
7040 int idx = 0; 7576 int idx = 0;
7041 7577
7578 bool positionChanged = false;
7579 LSL_Vector currentPosition = GetPartLocalPos(part);
7580
7042 while (idx < rules.Length) 7581 while (idx < rules.Length)
7043 { 7582 {
7044 int code = rules.GetLSLIntegerItem(idx++); 7583 int code = rules.GetLSLIntegerItem(idx++);
@@ -7047,7 +7586,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7047 7586
7048 int face; 7587 int face;
7049 LSL_Vector v; 7588 LSL_Vector v;
7050 7589
7051 switch (code) 7590 switch (code)
7052 { 7591 {
7053 case (int)ScriptBaseClass.PRIM_POSITION: 7592 case (int)ScriptBaseClass.PRIM_POSITION:
@@ -7055,7 +7594,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7055 return; 7594 return;
7056 7595
7057 v=rules.GetVector3Item(idx++); 7596 v=rules.GetVector3Item(idx++);
7058 SetPos(part, v); 7597 positionChanged = true;
7598 currentPosition = GetSetPosTarget(part, v, currentPosition);
7059 7599
7060 break; 7600 break;
7061 case (int)ScriptBaseClass.PRIM_SIZE: 7601 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7400,6 +7940,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7400 break; 7940 break;
7401 } 7941 }
7402 } 7942 }
7943
7944 if (positionChanged)
7945 {
7946 if (part.ParentGroup.RootPart == part)
7947 {
7948 SceneObjectGroup parent = part.ParentGroup;
7949 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7950 }
7951 else
7952 {
7953 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
7954 SceneObjectGroup parent = part.ParentGroup;
7955 parent.HasGroupChanged = true;
7956 parent.ScheduleGroupForTerseUpdate();
7957 }
7958 }
7403 } 7959 }
7404 7960
7405 public LSL_String llStringToBase64(string str) 7961 public LSL_String llStringToBase64(string str)
@@ -7548,13 +8104,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7548 public LSL_Integer llGetNumberOfPrims() 8104 public LSL_Integer llGetNumberOfPrims()
7549 { 8105 {
7550 m_host.AddScriptLPS(1); 8106 m_host.AddScriptLPS(1);
7551 int avatarCount = 0; 8107 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7552 World.ForEachScenePresence(delegate(ScenePresence presence) 8108
7553 {
7554 if (!presence.IsChildAgent && presence.ParentID != 0 && m_host.ParentGroup.HasChildPrim(presence.ParentID))
7555 avatarCount++;
7556 });
7557
7558 return m_host.ParentGroup.PrimCount + avatarCount; 8109 return m_host.ParentGroup.PrimCount + avatarCount;
7559 } 8110 }
7560 8111
@@ -7570,55 +8121,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7570 m_host.AddScriptLPS(1); 8121 m_host.AddScriptLPS(1);
7571 UUID objID = UUID.Zero; 8122 UUID objID = UUID.Zero;
7572 LSL_List result = new LSL_List(); 8123 LSL_List result = new LSL_List();
8124
8125 // If the ID is not valid, return null result
7573 if (!UUID.TryParse(obj, out objID)) 8126 if (!UUID.TryParse(obj, out objID))
7574 { 8127 {
7575 result.Add(new LSL_Vector()); 8128 result.Add(new LSL_Vector());
7576 result.Add(new LSL_Vector()); 8129 result.Add(new LSL_Vector());
7577 return result; 8130 return result;
7578 } 8131 }
8132
8133 // Check if this is an attached prim. If so, replace
8134 // the UUID with the avatar UUID and report it's bounding box
8135 SceneObjectPart part = World.GetSceneObjectPart(objID);
8136 if (part != null && part.ParentGroup.IsAttachment)
8137 objID = part.ParentGroup.AttachedAvatar;
8138
8139 // Find out if this is an avatar ID. If so, return it's box
7579 ScenePresence presence = World.GetScenePresence(objID); 8140 ScenePresence presence = World.GetScenePresence(objID);
7580 if (presence != null) 8141 if (presence != null)
7581 { 8142 {
7582 if (presence.ParentID == 0) // not sat on an object 8143 // As per LSL Wiki, there is no difference between sitting
8144 // and standing avatar since server 1.36
8145 LSL_Vector lower;
8146 LSL_Vector upper;
8147 if (presence.Animator.Animations.DefaultAnimation.AnimID
8148 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7583 { 8149 {
7584 LSL_Vector lower; 8150 // This is for ground sitting avatars
7585 LSL_Vector upper; 8151 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7586 if (presence.Animator.Animations.DefaultAnimation.AnimID 8152 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7587 == AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8153 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7588 {
7589 // This is for ground sitting avatars
7590 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7591 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7592 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7593 }
7594 else
7595 {
7596 // This is for standing/flying avatars
7597 float height = presence.Appearance.AvatarHeight / 2.0f;
7598 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7599 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7600 }
7601 result.Add(lower);
7602 result.Add(upper);
7603 return result;
7604 } 8154 }
7605 else 8155 else
7606 { 8156 {
7607 // sitting on an object so we need the bounding box of that 8157 // This is for standing/flying avatars
7608 // which should include the avatar so set the UUID to the 8158 float height = presence.Appearance.AvatarHeight / 2.0f;
7609 // UUID of the object the avatar is sat on and allow it to fall through 8159 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7610 // to processing an object 8160 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7611 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7612 objID = p.UUID;
7613 } 8161 }
8162
8163 // Adjust to the documented error offsets (see LSL Wiki)
8164 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8165 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8166
8167 if (lower.x > upper.x)
8168 lower.x = upper.x;
8169 if (lower.y > upper.y)
8170 lower.y = upper.y;
8171 if (lower.z > upper.z)
8172 lower.z = upper.z;
8173
8174 result.Add(lower);
8175 result.Add(upper);
8176 return result;
7614 } 8177 }
7615 SceneObjectPart part = World.GetSceneObjectPart(objID); 8178
8179 part = World.GetSceneObjectPart(objID);
7616 // Currently only works for single prims without a sitting avatar 8180 // Currently only works for single prims without a sitting avatar
7617 if (part != null) 8181 if (part != null)
7618 { 8182 {
7619 Vector3 halfSize = part.Scale / 2.0f; 8183 float minX;
7620 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8184 float maxX;
7621 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8185 float minY;
8186 float maxY;
8187 float minZ;
8188 float maxZ;
8189
8190 // This BBox is in sim coordinates, with the offset being
8191 // a contained point.
8192 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8193 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8194
8195 minX -= offsets[0].X;
8196 maxX -= offsets[0].X;
8197 minY -= offsets[0].Y;
8198 maxY -= offsets[0].Y;
8199 minZ -= offsets[0].Z;
8200 maxZ -= offsets[0].Z;
8201
8202 LSL_Vector lower;
8203 LSL_Vector upper;
8204
8205 // Adjust to the documented error offsets (see LSL Wiki)
8206 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8207 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8208
8209 if (lower.x > upper.x)
8210 lower.x = upper.x;
8211 if (lower.y > upper.y)
8212 lower.y = upper.y;
8213 if (lower.z > upper.z)
8214 lower.z = upper.z;
8215
7622 result.Add(lower); 8216 result.Add(lower);
7623 result.Add(upper); 8217 result.Add(upper);
7624 return result; 8218 return result;
@@ -7698,13 +8292,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7698 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8292 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7699 part.AbsolutePosition.Y, 8293 part.AbsolutePosition.Y,
7700 part.AbsolutePosition.Z); 8294 part.AbsolutePosition.Z);
7701 // For some reason, the part.AbsolutePosition.* values do not change if the
7702 // linkset is rotated; they always reflect the child prim's world position
7703 // as though the linkset is unrotated. This is incompatible behavior with SL's
7704 // implementation, so will break scripts imported from there (not to mention it
7705 // makes it more difficult to determine a child prim's actual inworld position).
7706 if (part.ParentID != 0)
7707 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7708 res.Add(v); 8295 res.Add(v);
7709 break; 8296 break;
7710 8297
@@ -7875,56 +8462,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7875 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 8462 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7876 if (remain < 1) 8463 if (remain < 1)
7877 return res; 8464 return res;
7878 8465 face = (int)rules.GetLSLIntegerItem(idx++);
7879 face=(int)rules.GetLSLIntegerItem(idx++);
7880 8466
7881 tex = part.Shape.Textures; 8467 tex = part.Shape.Textures;
8468 int shiny;
7882 if (face == ScriptBaseClass.ALL_SIDES) 8469 if (face == ScriptBaseClass.ALL_SIDES)
7883 { 8470 {
7884 for (face = 0; face < GetNumberOfSides(part); face++) 8471 for (face = 0; face < GetNumberOfSides(part); face++)
7885 { 8472 {
7886 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8473 Shininess shinyness = tex.GetFace((uint)face).Shiny;
7887 // Convert Shininess to PRIM_SHINY_* 8474 if (shinyness == Shininess.High)
7888 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8475 {
7889 // PRIM_BUMP_* 8476 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7890 res.Add(new LSL_Integer((int)texface.Bump)); 8477 }
8478 else if (shinyness == Shininess.Medium)
8479 {
8480 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8481 }
8482 else if (shinyness == Shininess.Low)
8483 {
8484 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8485 }
8486 else
8487 {
8488 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8489 }
8490 res.Add(new LSL_Integer(shiny));
8491 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7891 } 8492 }
7892 } 8493 }
7893 else 8494 else
7894 { 8495 {
7895 if (face >= 0 && face < GetNumberOfSides(part)) 8496 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8497 if (shinyness == Shininess.High)
7896 { 8498 {
7897 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8499 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
7898 // Convert Shininess to PRIM_SHINY_*
7899 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
7900 // PRIM_BUMP_*
7901 res.Add(new LSL_Integer((int)texface.Bump));
7902 } 8500 }
8501 else if (shinyness == Shininess.Medium)
8502 {
8503 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8504 }
8505 else if (shinyness == Shininess.Low)
8506 {
8507 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8508 }
8509 else
8510 {
8511 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8512 }
8513 res.Add(new LSL_Integer(shiny));
8514 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
7903 } 8515 }
7904 break; 8516 break;
7905 8517
7906 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 8518 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7907 if (remain < 1) 8519 if (remain < 1)
7908 return res; 8520 return res;
7909 8521 face = (int)rules.GetLSLIntegerItem(idx++);
7910 face=(int)rules.GetLSLIntegerItem(idx++);
7911 8522
7912 tex = part.Shape.Textures; 8523 tex = part.Shape.Textures;
8524 int fullbright;
7913 if (face == ScriptBaseClass.ALL_SIDES) 8525 if (face == ScriptBaseClass.ALL_SIDES)
7914 { 8526 {
7915 for (face = 0; face < GetNumberOfSides(part); face++) 8527 for (face = 0; face < GetNumberOfSides(part); face++)
7916 { 8528 {
7917 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8529 if (tex.GetFace((uint)face).Fullbright == true)
7918 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 8530 {
8531 fullbright = ScriptBaseClass.TRUE;
8532 }
8533 else
8534 {
8535 fullbright = ScriptBaseClass.FALSE;
8536 }
8537 res.Add(new LSL_Integer(fullbright));
7919 } 8538 }
7920 } 8539 }
7921 else 8540 else
7922 { 8541 {
7923 if (face >= 0 && face < GetNumberOfSides(part)) 8542 if (tex.GetFace((uint)face).Fullbright == true)
7924 { 8543 {
7925 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8544 fullbright = ScriptBaseClass.TRUE;
7926 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
7927 } 8545 }
8546 else
8547 {
8548 fullbright = ScriptBaseClass.FALSE;
8549 }
8550 res.Add(new LSL_Integer(fullbright));
7928 } 8551 }
7929 break; 8552 break;
7930 8553
@@ -7946,27 +8569,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7946 break; 8569 break;
7947 8570
7948 case (int)ScriptBaseClass.PRIM_TEXGEN: 8571 case (int)ScriptBaseClass.PRIM_TEXGEN:
8572 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
7949 if (remain < 1) 8573 if (remain < 1)
7950 return res; 8574 return res;
7951 8575 face = (int)rules.GetLSLIntegerItem(idx++);
7952 face=(int)rules.GetLSLIntegerItem(idx++);
7953 8576
7954 tex = part.Shape.Textures; 8577 tex = part.Shape.Textures;
7955 if (face == ScriptBaseClass.ALL_SIDES) 8578 if (face == ScriptBaseClass.ALL_SIDES)
7956 { 8579 {
7957 for (face = 0; face < GetNumberOfSides(part); face++) 8580 for (face = 0; face < GetNumberOfSides(part); face++)
7958 { 8581 {
7959 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8582 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
7960 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 8583 {
7961 res.Add(new LSL_Integer((uint)texgen >> 1)); 8584 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8585 }
8586 else
8587 {
8588 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8589 }
7962 } 8590 }
7963 } 8591 }
7964 else 8592 else
7965 { 8593 {
7966 if (face >= 0 && face < GetNumberOfSides(part)) 8594 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8595 {
8596 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8597 }
8598 else
7967 { 8599 {
7968 MappingType texgen = tex.GetFace((uint)face).TexMapType; 8600 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
7969 res.Add(new LSL_Integer((uint)texgen >> 1));
7970 } 8601 }
7971 } 8602 }
7972 break; 8603 break;
@@ -7989,28 +8620,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7989 case (int)ScriptBaseClass.PRIM_GLOW: 8620 case (int)ScriptBaseClass.PRIM_GLOW:
7990 if (remain < 1) 8621 if (remain < 1)
7991 return res; 8622 return res;
7992 8623 face = (int)rules.GetLSLIntegerItem(idx++);
7993 face=(int)rules.GetLSLIntegerItem(idx++);
7994 8624
7995 tex = part.Shape.Textures; 8625 tex = part.Shape.Textures;
8626 float primglow;
7996 if (face == ScriptBaseClass.ALL_SIDES) 8627 if (face == ScriptBaseClass.ALL_SIDES)
7997 { 8628 {
7998 for (face = 0; face < GetNumberOfSides(part); face++) 8629 for (face = 0; face < GetNumberOfSides(part); face++)
7999 { 8630 {
8000 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8631 primglow = tex.GetFace((uint)face).Glow;
8001 res.Add(new LSL_Float(texface.Glow)); 8632 res.Add(new LSL_Float(primglow));
8002 } 8633 }
8003 } 8634 }
8004 else 8635 else
8005 { 8636 {
8006 if (face >= 0 && face < GetNumberOfSides(part)) 8637 primglow = tex.GetFace((uint)face).Glow;
8007 { 8638 res.Add(new LSL_Float(primglow));
8008 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8009 res.Add(new LSL_Float(texface.Glow));
8010 }
8011 } 8639 }
8012 break; 8640 break;
8013
8014 case (int)ScriptBaseClass.PRIM_TEXT: 8641 case (int)ScriptBaseClass.PRIM_TEXT:
8015 Color4 textColor = part.GetTextColor(); 8642 Color4 textColor = part.GetTextColor();
8016 res.Add(new LSL_String(part.Text)); 8643 res.Add(new LSL_String(part.Text));
@@ -8559,8 +9186,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8559 // The function returns an ordered list 9186 // The function returns an ordered list
8560 // representing the tokens found in the supplied 9187 // representing the tokens found in the supplied
8561 // sources string. If two successive tokenizers 9188 // sources string. If two successive tokenizers
8562 // are encountered, then a NULL entry is added 9189 // are encountered, then a null-string entry is
8563 // to the list. 9190 // added to the list.
8564 // 9191 //
8565 // It is a precondition that the source and 9192 // It is a precondition that the source and
8566 // toekizer lisst are non-null. If they are null, 9193 // toekizer lisst are non-null. If they are null,
@@ -8568,7 +9195,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8568 // while their lengths are being determined. 9195 // while their lengths are being determined.
8569 // 9196 //
8570 // A small amount of working memoryis required 9197 // A small amount of working memoryis required
8571 // of approximately 8*#tokenizers. 9198 // of approximately 8*#tokenizers + 8*srcstrlen.
8572 // 9199 //
8573 // There are many ways in which this function 9200 // There are many ways in which this function
8574 // can be implemented, this implementation is 9201 // can be implemented, this implementation is
@@ -8584,155 +9211,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8584 // and eliminates redundant tokenizers as soon 9211 // and eliminates redundant tokenizers as soon
8585 // as is possible. 9212 // as is possible.
8586 // 9213 //
8587 // The implementation tries to avoid any copying 9214 // The implementation tries to minimize temporary
8588 // of arrays or other objects. 9215 // garbage generation.
8589 // </remarks> 9216 // </remarks>
8590 9217
8591 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9218 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8592 { 9219 {
8593 int beginning = 0; 9220 return ParseString2List(src, separators, spacers, true);
8594 int srclen = src.Length; 9221 }
8595 int seplen = separators.Length;
8596 object[] separray = separators.Data;
8597 int spclen = spacers.Length;
8598 object[] spcarray = spacers.Data;
8599 int mlen = seplen+spclen;
8600
8601 int[] offset = new int[mlen+1];
8602 bool[] active = new bool[mlen];
8603
8604 int best;
8605 int j;
8606
8607 // Initial capacity reduces resize cost
8608 9222
8609 LSL_List tokens = new LSL_List(); 9223 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9224 {
9225 int srclen = src.Length;
9226 int seplen = separators.Length;
9227 object[] separray = separators.Data;
9228 int spclen = spacers.Length;
9229 object[] spcarray = spacers.Data;
9230 int dellen = 0;
9231 string[] delarray = new string[seplen+spclen];
8610 9232
8611 // All entries are initially valid 9233 int outlen = 0;
9234 string[] outarray = new string[srclen*2+1];
8612 9235
8613 for (int i = 0; i < mlen; i++) 9236 int i, j;
8614 active[i] = true; 9237 string d;
8615 9238
8616 offset[mlen] = srclen; 9239 m_host.AddScriptLPS(1);
8617 9240
8618 while (beginning < srclen) 9241 /*
9242 * Convert separator and spacer lists to C# strings.
9243 * Also filter out null strings so we don't hang.
9244 */
9245 for (i = 0; i < seplen; i ++)
8619 { 9246 {
9247 d = separray[i].ToString();
9248 if (d.Length > 0)
9249 {
9250 delarray[dellen++] = d;
9251 }
9252 }
9253 seplen = dellen;
8620 9254
8621 best = mlen; // as bad as it gets 9255 for (i = 0; i < spclen; i ++)
9256 {
9257 d = spcarray[i].ToString();
9258 if (d.Length > 0)
9259 {
9260 delarray[dellen++] = d;
9261 }
9262 }
8622 9263
8623 // Scan for separators 9264 /*
9265 * Scan through source string from beginning to end.
9266 */
9267 for (i = 0;;)
9268 {
8624 9269
8625 for (j = 0; j < seplen; j++) 9270 /*
9271 * Find earliest delimeter in src starting at i (if any).
9272 */
9273 int earliestDel = -1;
9274 int earliestSrc = srclen;
9275 string earliestStr = null;
9276 for (j = 0; j < dellen; j ++)
8626 { 9277 {
8627 if (separray[j].ToString() == String.Empty) 9278 d = delarray[j];
8628 active[j] = false; 9279 if (d != null)
8629
8630 if (active[j])
8631 { 9280 {
8632 // scan all of the markers 9281 int index = src.IndexOf(d, i);
8633 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9282 if (index < 0)
8634 { 9283 {
8635 // not present at all 9284 delarray[j] = null; // delim nowhere in src, don't check it anymore
8636 active[j] = false;
8637 } 9285 }
8638 else 9286 else if (index < earliestSrc)
8639 { 9287 {
8640 // present and correct 9288 earliestSrc = index; // where delimeter starts in source string
8641 if (offset[j] < offset[best]) 9289 earliestDel = j; // where delimeter is in delarray[]
8642 { 9290 earliestStr = d; // the delimeter string from delarray[]
8643 // closest so far 9291 if (index == i) break; // can't do any better than found at beg of string
8644 best = j;
8645 if (offset[best] == beginning)
8646 break;
8647 }
8648 } 9292 }
8649 } 9293 }
8650 } 9294 }
8651 9295
8652 // Scan for spacers 9296 /*
8653 9297 * Output source string starting at i through start of earliest delimeter.
8654 if (offset[best] != beginning) 9298 */
9299 if (keepNulls || (earliestSrc > i))
8655 { 9300 {
8656 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9301 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8657 {
8658 if (spcarray[j-seplen].ToString() == String.Empty)
8659 active[j] = false;
8660
8661 if (active[j])
8662 {
8663 // scan all of the markers
8664 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8665 {
8666 // not present at all
8667 active[j] = false;
8668 }
8669 else
8670 {
8671 // present and correct
8672 if (offset[j] < offset[best])
8673 {
8674 // closest so far
8675 best = j;
8676 }
8677 }
8678 }
8679 }
8680 } 9302 }
8681 9303
8682 // This is the normal exit from the scanning loop 9304 /*
9305 * If no delimeter found at or after i, we're done scanning.
9306 */
9307 if (earliestDel < 0) break;
8683 9308
8684 if (best == mlen) 9309 /*
9310 * If delimeter was a spacer, output the spacer.
9311 */
9312 if (earliestDel >= seplen)
8685 { 9313 {
8686 // no markers were found on this pass 9314 outarray[outlen++] = earliestStr;
8687 // so we're pretty much done
8688 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8689 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8690 break;
8691 } 9315 }
8692 9316
8693 // Otherwise we just add the newly delimited token 9317 /*
8694 // and recalculate where the search should continue. 9318 * Look at rest of src string following delimeter.
8695 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9319 */
8696 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9320 i = earliestSrc + earliestStr.Length;
8697
8698 if (best < seplen)
8699 {
8700 beginning = offset[best] + (separray[best].ToString()).Length;
8701 }
8702 else
8703 {
8704 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8705 string str = spcarray[best - seplen].ToString();
8706 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8707 tokens.Add(new LSL_String(str));
8708 }
8709 } 9321 }
8710 9322
8711 // This an awkward an not very intuitive boundary case. If the 9323 /*
8712 // last substring is a tokenizer, then there is an implied trailing 9324 * Make up an exact-sized output array suitable for an LSL_List object.
8713 // null list entry. Hopefully the single comparison will not be too 9325 */
8714 // arduous. Alternatively the 'break' could be replced with a return 9326 object[] outlist = new object[outlen];
8715 // but that's shabby programming. 9327 for (i = 0; i < outlen; i ++)
8716
8717 if ((beginning == srclen) && (keepNulls))
8718 { 9328 {
8719 if (srclen != 0) 9329 outlist[i] = new LSL_String(outarray[i]);
8720 tokens.Add(new LSL_String(""));
8721 } 9330 }
8722 9331 return new LSL_List(outlist);
8723 return tokens;
8724 }
8725
8726 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8727 {
8728 m_host.AddScriptLPS(1);
8729 return this.ParseString(src, separators, spacers, false);
8730 }
8731
8732 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8733 {
8734 m_host.AddScriptLPS(1);
8735 return this.ParseString(src, separators, spacers, true);
8736 } 9332 }
8737 9333
8738 public LSL_Integer llGetObjectPermMask(int mask) 9334 public LSL_Integer llGetObjectPermMask(int mask)
@@ -8809,28 +9405,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8809 { 9405 {
8810 m_host.AddScriptLPS(1); 9406 m_host.AddScriptLPS(1);
8811 9407
8812 lock (m_host.TaskInventory) 9408 m_host.TaskInventory.LockItemsForRead(true);
9409 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8813 { 9410 {
8814 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9411 if (inv.Value.Name == item)
8815 { 9412 {
8816 if (inv.Value.Name == item) 9413 m_host.TaskInventory.LockItemsForRead(false);
9414 switch (mask)
8817 { 9415 {
8818 switch (mask) 9416 case 0:
8819 { 9417 return (int)inv.Value.BasePermissions;
8820 case 0: 9418 case 1:
8821 return (int)inv.Value.BasePermissions; 9419 return (int)inv.Value.CurrentPermissions;
8822 case 1: 9420 case 2:
8823 return (int)inv.Value.CurrentPermissions; 9421 return (int)inv.Value.GroupPermissions;
8824 case 2: 9422 case 3:
8825 return (int)inv.Value.GroupPermissions; 9423 return (int)inv.Value.EveryonePermissions;
8826 case 3: 9424 case 4:
8827 return (int)inv.Value.EveryonePermissions; 9425 return (int)inv.Value.NextPermissions;
8828 case 4:
8829 return (int)inv.Value.NextPermissions;
8830 }
8831 } 9426 }
8832 } 9427 }
8833 } 9428 }
9429 m_host.TaskInventory.LockItemsForRead(false);
8834 9430
8835 return -1; 9431 return -1;
8836 } 9432 }
@@ -8877,16 +9473,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8877 { 9473 {
8878 m_host.AddScriptLPS(1); 9474 m_host.AddScriptLPS(1);
8879 9475
8880 lock (m_host.TaskInventory) 9476 m_host.TaskInventory.LockItemsForRead(true);
9477 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
8881 { 9478 {
8882 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 9479 if (inv.Value.Name == item)
8883 { 9480 {
8884 if (inv.Value.Name == item) 9481 m_host.TaskInventory.LockItemsForRead(false);
8885 { 9482 return inv.Value.CreatorID.ToString();
8886 return inv.Value.CreatorID.ToString();
8887 }
8888 } 9483 }
8889 } 9484 }
9485 m_host.TaskInventory.LockItemsForRead(false);
8890 9486
8891 llSay(0, "No item name '" + item + "'"); 9487 llSay(0, "No item name '" + item + "'");
8892 9488
@@ -9034,7 +9630,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9034 } 9630 }
9035 9631
9036 /// <summary> 9632 /// <summary>
9037 /// illListReplaceList removes the sub-list defined by the inclusive indices 9633 /// llListReplaceList removes the sub-list defined by the inclusive indices
9038 /// start and end and inserts the src list in its place. The inclusive 9634 /// start and end and inserts the src list in its place. The inclusive
9039 /// nature of the indices means that at least one element must be deleted 9635 /// nature of the indices means that at least one element must be deleted
9040 /// if the indices are within the bounds of the existing list. I.e. 2,2 9636 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9091,16 +9687,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9091 // based upon end. Note that if end exceeds the upper 9687 // based upon end. Note that if end exceeds the upper
9092 // bound in this case, the entire destination list 9688 // bound in this case, the entire destination list
9093 // is removed. 9689 // is removed.
9094 else 9690 else if (start == 0)
9095 { 9691 {
9096 if (end + 1 < dest.Length) 9692 if (end + 1 < dest.Length)
9097 {
9098 return src + dest.GetSublist(end + 1, -1); 9693 return src + dest.GetSublist(end + 1, -1);
9099 }
9100 else 9694 else
9101 {
9102 return src; 9695 return src;
9103 } 9696 }
9697 else // Start < 0
9698 {
9699 if (end + 1 < dest.Length)
9700 return dest.GetSublist(end + 1, -1);
9701 else
9702 return new LSL_List();
9104 } 9703 }
9105 } 9704 }
9106 // Finally, if start > end, we strip away a prefix and 9705 // Finally, if start > end, we strip away a prefix and
@@ -9151,17 +9750,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9151 int width = 0; 9750 int width = 0;
9152 int height = 0; 9751 int height = 0;
9153 9752
9154 ParcelMediaCommandEnum? commandToSend = null; 9753 uint commandToSend = 0;
9155 float time = 0.0f; // default is from start 9754 float time = 0.0f; // default is from start
9156 9755
9157 ScenePresence presence = null; 9756 ScenePresence presence = null;
9158 9757
9159 for (int i = 0; i < commandList.Data.Length; i++) 9758 for (int i = 0; i < commandList.Data.Length; i++)
9160 { 9759 {
9161 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 9760 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9162 switch (command) 9761 switch (command)
9163 { 9762 {
9164 case ParcelMediaCommandEnum.Agent: 9763 case (uint)ParcelMediaCommandEnum.Agent:
9165 // we send only to one agent 9764 // we send only to one agent
9166 if ((i + 1) < commandList.Length) 9765 if ((i + 1) < commandList.Length)
9167 { 9766 {
@@ -9178,25 +9777,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9178 } 9777 }
9179 break; 9778 break;
9180 9779
9181 case ParcelMediaCommandEnum.Loop: 9780 case (uint)ParcelMediaCommandEnum.Loop:
9182 loop = 1; 9781 loop = 1;
9183 commandToSend = command; 9782 commandToSend = command;
9184 update = true; //need to send the media update packet to set looping 9783 update = true; //need to send the media update packet to set looping
9185 break; 9784 break;
9186 9785
9187 case ParcelMediaCommandEnum.Play: 9786 case (uint)ParcelMediaCommandEnum.Play:
9188 loop = 0; 9787 loop = 0;
9189 commandToSend = command; 9788 commandToSend = command;
9190 update = true; //need to send the media update packet to make sure it doesn't loop 9789 update = true; //need to send the media update packet to make sure it doesn't loop
9191 break; 9790 break;
9192 9791
9193 case ParcelMediaCommandEnum.Pause: 9792 case (uint)ParcelMediaCommandEnum.Pause:
9194 case ParcelMediaCommandEnum.Stop: 9793 case (uint)ParcelMediaCommandEnum.Stop:
9195 case ParcelMediaCommandEnum.Unload: 9794 case (uint)ParcelMediaCommandEnum.Unload:
9196 commandToSend = command; 9795 commandToSend = command;
9197 break; 9796 break;
9198 9797
9199 case ParcelMediaCommandEnum.Url: 9798 case (uint)ParcelMediaCommandEnum.Url:
9200 if ((i + 1) < commandList.Length) 9799 if ((i + 1) < commandList.Length)
9201 { 9800 {
9202 if (commandList.Data[i + 1] is LSL_String) 9801 if (commandList.Data[i + 1] is LSL_String)
@@ -9209,7 +9808,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9209 } 9808 }
9210 break; 9809 break;
9211 9810
9212 case ParcelMediaCommandEnum.Texture: 9811 case (uint)ParcelMediaCommandEnum.Texture:
9213 if ((i + 1) < commandList.Length) 9812 if ((i + 1) < commandList.Length)
9214 { 9813 {
9215 if (commandList.Data[i + 1] is LSL_String) 9814 if (commandList.Data[i + 1] is LSL_String)
@@ -9222,7 +9821,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9222 } 9821 }
9223 break; 9822 break;
9224 9823
9225 case ParcelMediaCommandEnum.Time: 9824 case (uint)ParcelMediaCommandEnum.Time:
9226 if ((i + 1) < commandList.Length) 9825 if ((i + 1) < commandList.Length)
9227 { 9826 {
9228 if (commandList.Data[i + 1] is LSL_Float) 9827 if (commandList.Data[i + 1] is LSL_Float)
@@ -9234,7 +9833,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9234 } 9833 }
9235 break; 9834 break;
9236 9835
9237 case ParcelMediaCommandEnum.AutoAlign: 9836 case (uint)ParcelMediaCommandEnum.AutoAlign:
9238 if ((i + 1) < commandList.Length) 9837 if ((i + 1) < commandList.Length)
9239 { 9838 {
9240 if (commandList.Data[i + 1] is LSL_Integer) 9839 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9248,7 +9847,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9248 } 9847 }
9249 break; 9848 break;
9250 9849
9251 case ParcelMediaCommandEnum.Type: 9850 case (uint)ParcelMediaCommandEnum.Type:
9252 if ((i + 1) < commandList.Length) 9851 if ((i + 1) < commandList.Length)
9253 { 9852 {
9254 if (commandList.Data[i + 1] is LSL_String) 9853 if (commandList.Data[i + 1] is LSL_String)
@@ -9261,7 +9860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9261 } 9860 }
9262 break; 9861 break;
9263 9862
9264 case ParcelMediaCommandEnum.Desc: 9863 case (uint)ParcelMediaCommandEnum.Desc:
9265 if ((i + 1) < commandList.Length) 9864 if ((i + 1) < commandList.Length)
9266 { 9865 {
9267 if (commandList.Data[i + 1] is LSL_String) 9866 if (commandList.Data[i + 1] is LSL_String)
@@ -9274,7 +9873,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9274 } 9873 }
9275 break; 9874 break;
9276 9875
9277 case ParcelMediaCommandEnum.Size: 9876 case (uint)ParcelMediaCommandEnum.Size:
9278 if ((i + 2) < commandList.Length) 9877 if ((i + 2) < commandList.Length)
9279 { 9878 {
9280 if (commandList.Data[i + 1] is LSL_Integer) 9879 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9344,7 +9943,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9344 } 9943 }
9345 } 9944 }
9346 9945
9347 if (commandToSend != null) 9946 if (commandToSend != 0)
9348 { 9947 {
9349 // the commandList contained a start/stop/... command, too 9948 // the commandList contained a start/stop/... command, too
9350 if (presence == null) 9949 if (presence == null)
@@ -9381,7 +9980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9381 9980
9382 if (aList.Data[i] != null) 9981 if (aList.Data[i] != null)
9383 { 9982 {
9384 switch ((ParcelMediaCommandEnum) aList.Data[i]) 9983 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9385 { 9984 {
9386 case ParcelMediaCommandEnum.Url: 9985 case ParcelMediaCommandEnum.Url:
9387 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 9986 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9424,16 +10023,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9424 { 10023 {
9425 m_host.AddScriptLPS(1); 10024 m_host.AddScriptLPS(1);
9426 10025
9427 lock (m_host.TaskInventory) 10026 m_host.TaskInventory.LockItemsForRead(true);
10027 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9428 { 10028 {
9429 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10029 if (inv.Value.Name == name)
9430 { 10030 {
9431 if (inv.Value.Name == name) 10031 m_host.TaskInventory.LockItemsForRead(false);
9432 { 10032 return inv.Value.Type;
9433 return inv.Value.Type;
9434 }
9435 } 10033 }
9436 } 10034 }
10035 m_host.TaskInventory.LockItemsForRead(false);
9437 10036
9438 return -1; 10037 return -1;
9439 } 10038 }
@@ -9444,15 +10043,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9444 10043
9445 if (quick_pay_buttons.Data.Length < 4) 10044 if (quick_pay_buttons.Data.Length < 4)
9446 { 10045 {
9447 LSLError("List must have at least 4 elements"); 10046 int x;
9448 return; 10047 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10048 {
10049 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10050 }
9449 } 10051 }
9450 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10052 int[] nPrice = new int[5];
9451 10053 nPrice[0] = price;
9452 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10054 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9453 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10055 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9454 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10056 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9455 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10057 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10058 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9456 m_host.ParentGroup.HasGroupChanged = true; 10059 m_host.ParentGroup.HasGroupChanged = true;
9457 } 10060 }
9458 10061
@@ -9464,17 +10067,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9464 if (invItemID == UUID.Zero) 10067 if (invItemID == UUID.Zero)
9465 return new LSL_Vector(); 10068 return new LSL_Vector();
9466 10069
9467 lock (m_host.TaskInventory) 10070 m_host.TaskInventory.LockItemsForRead(true);
10071 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9468 { 10072 {
9469 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10073 m_host.TaskInventory.LockItemsForRead(false);
9470 return new LSL_Vector(); 10074 return new LSL_Vector();
10075 }
9471 10076
9472 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0) 10077 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9473 { 10078 {
9474 ShoutError("No permissions to track the camera"); 10079 ShoutError("No permissions to track the camera");
9475 return new LSL_Vector(); 10080 m_host.TaskInventory.LockItemsForRead(false);
9476 } 10081 return new LSL_Vector();
9477 } 10082 }
10083 m_host.TaskInventory.LockItemsForRead(false);
9478 10084
9479 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10085 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9480 if (presence != null) 10086 if (presence != null)
@@ -9492,17 +10098,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9492 if (invItemID == UUID.Zero) 10098 if (invItemID == UUID.Zero)
9493 return new LSL_Rotation(); 10099 return new LSL_Rotation();
9494 10100
9495 lock (m_host.TaskInventory) 10101 m_host.TaskInventory.LockItemsForRead(true);
10102 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
9496 { 10103 {
9497 if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero) 10104 m_host.TaskInventory.LockItemsForRead(false);
9498 return new LSL_Rotation(); 10105 return new LSL_Rotation();
9499
9500 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
9501 {
9502 ShoutError("No permissions to track the camera");
9503 return new LSL_Rotation();
9504 }
9505 } 10106 }
10107 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TRACK_CAMERA) == 0)
10108 {
10109 ShoutError("No permissions to track the camera");
10110 m_host.TaskInventory.LockItemsForRead(false);
10111 return new LSL_Rotation();
10112 }
10113 m_host.TaskInventory.LockItemsForRead(false);
9506 10114
9507 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10115 ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
9508 if (presence != null) 10116 if (presence != null)
@@ -9564,8 +10172,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9564 { 10172 {
9565 m_host.AddScriptLPS(1); 10173 m_host.AddScriptLPS(1);
9566 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0); 10174 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_itemID, 0);
9567 if (detectedParams == null) return; // only works on the first detected avatar 10175 if (detectedParams == null)
9568 10176 {
10177 if (m_host.ParentGroup.IsAttachment == true)
10178 {
10179 detectedParams = new DetectParams();
10180 detectedParams.Key = m_host.OwnerID;
10181 }
10182 else
10183 {
10184 return;
10185 }
10186 }
10187
9569 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10188 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9570 if (avatar != null) 10189 if (avatar != null)
9571 { 10190 {
@@ -9573,6 +10192,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9573 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 10192 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9574 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 10193 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9575 } 10194 }
10195
9576 ScriptSleep(1000); 10196 ScriptSleep(1000);
9577 } 10197 }
9578 10198
@@ -9665,14 +10285,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9665 if (objectID == UUID.Zero) return; 10285 if (objectID == UUID.Zero) return;
9666 10286
9667 UUID agentID; 10287 UUID agentID;
9668 lock (m_host.TaskInventory) 10288 m_host.TaskInventory.LockItemsForRead(true);
9669 { 10289 // we need the permission first, to know which avatar we want to set the camera for
9670 // we need the permission first, to know which avatar we want to set the camera for 10290 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9671 agentID = m_host.TaskInventory[invItemID].PermsGranter;
9672 10291
9673 if (agentID == UUID.Zero) return; 10292 if (agentID == UUID.Zero)
9674 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10293 {
10294 m_host.TaskInventory.LockItemsForRead(false);
10295 return;
10296 }
10297 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10298 {
10299 m_host.TaskInventory.LockItemsForRead(false);
10300 return;
9675 } 10301 }
10302 m_host.TaskInventory.LockItemsForRead(false);
9676 10303
9677 ScenePresence presence = World.GetScenePresence(agentID); 10304 ScenePresence presence = World.GetScenePresence(agentID);
9678 10305
@@ -9681,12 +10308,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9681 10308
9682 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10309 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9683 object[] data = rules.Data; 10310 object[] data = rules.Data;
9684 for (int i = 0; i < data.Length; ++i) { 10311 for (int i = 0; i < data.Length; ++i)
10312 {
9685 int type = Convert.ToInt32(data[i++].ToString()); 10313 int type = Convert.ToInt32(data[i++].ToString());
9686 if (i >= data.Length) break; // odd number of entries => ignore the last 10314 if (i >= data.Length) break; // odd number of entries => ignore the last
9687 10315
9688 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10316 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9689 switch (type) { 10317 switch (type)
10318 {
9690 case ScriptBaseClass.CAMERA_FOCUS: 10319 case ScriptBaseClass.CAMERA_FOCUS:
9691 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10320 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9692 case ScriptBaseClass.CAMERA_POSITION: 10321 case ScriptBaseClass.CAMERA_POSITION:
@@ -9722,12 +10351,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9722 10351
9723 // we need the permission first, to know which avatar we want to clear the camera for 10352 // we need the permission first, to know which avatar we want to clear the camera for
9724 UUID agentID; 10353 UUID agentID;
9725 lock (m_host.TaskInventory) 10354 m_host.TaskInventory.LockItemsForRead(true);
10355 agentID = m_host.TaskInventory[invItemID].PermsGranter;
10356 if (agentID == UUID.Zero)
9726 { 10357 {
9727 agentID = m_host.TaskInventory[invItemID].PermsGranter; 10358 m_host.TaskInventory.LockItemsForRead(false);
9728 if (agentID == UUID.Zero) return; 10359 return;
9729 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0) return; 10360 }
10361 if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_CONTROL_CAMERA) == 0)
10362 {
10363 m_host.TaskInventory.LockItemsForRead(false);
10364 return;
9730 } 10365 }
10366 m_host.TaskInventory.LockItemsForRead(false);
9731 10367
9732 ScenePresence presence = World.GetScenePresence(agentID); 10368 ScenePresence presence = World.GetScenePresence(agentID);
9733 10369
@@ -9794,19 +10430,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9794 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10430 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
9795 { 10431 {
9796 m_host.AddScriptLPS(1); 10432 m_host.AddScriptLPS(1);
9797 string ret = String.Empty; 10433
9798 string src1 = llBase64ToString(str1); 10434 if (str1 == String.Empty)
9799 string src2 = llBase64ToString(str2); 10435 return String.Empty;
9800 int c = 0; 10436 if (str2 == String.Empty)
9801 for (int i = 0; i < src1.Length; i++) 10437 return str1;
10438
10439 int len = str2.Length;
10440 if ((len % 4) != 0) // LL is EVIL!!!!
9802 { 10441 {
9803 ret += (char) (src1[i] ^ src2[c]); 10442 while (str2.EndsWith("="))
10443 str2 = str2.Substring(0, str2.Length - 1);
10444
10445 len = str2.Length;
10446 int mod = len % 4;
10447
10448 if (mod == 1)
10449 str2 = str2.Substring(0, str2.Length - 1);
10450 else if (mod == 2)
10451 str2 += "==";
10452 else if (mod == 3)
10453 str2 += "=";
10454 }
9804 10455
9805 c++; 10456 byte[] data1;
9806 if (c >= src2.Length) 10457 byte[] data2;
9807 c = 0; 10458 try
10459 {
10460 data1 = Convert.FromBase64String(str1);
10461 data2 = Convert.FromBase64String(str2);
9808 } 10462 }
9809 return llStringToBase64(ret); 10463 catch (Exception)
10464 {
10465 return new LSL_String(String.Empty);
10466 }
10467
10468 byte[] d2 = new Byte[data1.Length];
10469 int pos = 0;
10470
10471 if (data1.Length <= data2.Length)
10472 {
10473 Array.Copy(data2, 0, d2, 0, data1.Length);
10474 }
10475 else
10476 {
10477 while (pos < data1.Length)
10478 {
10479 len = data1.Length - pos;
10480 if (len > data2.Length)
10481 len = data2.Length;
10482
10483 Array.Copy(data2, 0, d2, pos, len);
10484 pos += len;
10485 }
10486 }
10487
10488 for (pos = 0 ; pos < data1.Length ; pos++ )
10489 data1[pos] ^= d2[pos];
10490
10491 return Convert.ToBase64String(data1);
9810 } 10492 }
9811 10493
9812 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 10494 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -9865,12 +10547,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9865 Regex r = new Regex(authregex); 10547 Regex r = new Regex(authregex);
9866 int[] gnums = r.GetGroupNumbers(); 10548 int[] gnums = r.GetGroupNumbers();
9867 Match m = r.Match(url); 10549 Match m = r.Match(url);
9868 if (m.Success) { 10550 if (m.Success)
9869 for (int i = 1; i < gnums.Length; i++) { 10551 {
10552 for (int i = 1; i < gnums.Length; i++)
10553 {
9870 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 10554 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
9871 //CaptureCollection cc = g.Captures; 10555 //CaptureCollection cc = g.Captures;
9872 } 10556 }
9873 if (m.Groups.Count == 5) { 10557 if (m.Groups.Count == 5)
10558 {
9874 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 10559 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
9875 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 10560 url = m.Groups[1].ToString() + m.Groups[4].ToString();
9876 } 10561 }
@@ -10156,15 +10841,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10156 10841
10157 internal UUID ScriptByName(string name) 10842 internal UUID ScriptByName(string name)
10158 { 10843 {
10159 lock (m_host.TaskInventory) 10844 m_host.TaskInventory.LockItemsForRead(true);
10845
10846 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10160 { 10847 {
10161 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 10848 if (item.Type == 10 && item.Name == name)
10162 { 10849 {
10163 if (item.Type == 10 && item.Name == name) 10850 m_host.TaskInventory.LockItemsForRead(false);
10164 return item.ItemID; 10851 return item.ItemID;
10165 } 10852 }
10166 } 10853 }
10167 10854
10855 m_host.TaskInventory.LockItemsForRead(false);
10856
10168 return UUID.Zero; 10857 return UUID.Zero;
10169 } 10858 }
10170 10859
@@ -10205,6 +10894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10205 { 10894 {
10206 m_host.AddScriptLPS(1); 10895 m_host.AddScriptLPS(1);
10207 10896
10897 //Clone is thread safe
10208 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10898 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10209 10899
10210 UUID assetID = UUID.Zero; 10900 UUID assetID = UUID.Zero;
@@ -10267,6 +10957,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10267 { 10957 {
10268 m_host.AddScriptLPS(1); 10958 m_host.AddScriptLPS(1);
10269 10959
10960 //Clone is thread safe
10270 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 10961 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10271 10962
10272 UUID assetID = UUID.Zero; 10963 UUID assetID = UUID.Zero;
@@ -10347,15 +11038,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10347 return GetLinkPrimitiveParams(obj, rules); 11038 return GetLinkPrimitiveParams(obj, rules);
10348 } 11039 }
10349 11040
10350 public void print(string str) 11041 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10351 { 11042 {
10352 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11043 List<SceneObjectPart> parts = GetLinkParts(link);
10353 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_itemID, "OSSL"); 11044 if (parts.Count < 1)
10354 if (ossl != null) 11045 return 0;
10355 { 11046
10356 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11047 return GetNumberOfSides(parts[0]);
10357 m_log.Info("LSL print():" + str);
10358 }
10359 } 11048 }
10360 11049
10361 private string Name2Username(string name) 11050 private string Name2Username(string name)
@@ -10401,6 +11090,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10401 return rq.ToString(); 11090 return rq.ToString();
10402 } 11091 }
10403 11092
11093 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11094 {
11095 m_SayShoutCount = 0;
11096 }
10404 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 11097 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10405 { 11098 {
10406 m_host.AddScriptLPS(1); 11099 m_host.AddScriptLPS(1);
@@ -10570,22 +11263,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10570 NotImplemented("llGetSPMaxMemory"); 11263 NotImplemented("llGetSPMaxMemory");
10571 } 11264 }
10572 11265
10573 public void llGetUsedMemory() 11266 public virtual LSL_Integer llGetUsedMemory()
10574 { 11267 {
10575 m_host.AddScriptLPS(1); 11268 m_host.AddScriptLPS(1);
10576 NotImplemented("llGetUsedMemory"); 11269 NotImplemented("llGetUsedMemory");
11270 return 0;
10577 } 11271 }
10578 11272
10579 public void llScriptProfiler(LSL_Integer flags) 11273 public void llScriptProfiler(LSL_Integer flags)
10580 { 11274 {
10581 m_host.AddScriptLPS(1); 11275 m_host.AddScriptLPS(1);
10582 NotImplemented("llScriptProfiler"); 11276 //NotImplemented("llScriptProfiler");
10583 } 11277 }
10584 11278
10585 public void llSetSoundQueueing(int queue) 11279 public void llSetSoundQueueing(int queue)
10586 { 11280 {
10587 m_host.AddScriptLPS(1); 11281 m_host.AddScriptLPS(1);
10588 NotImplemented("llSetSoundQueueing");
10589 } 11282 }
10590 11283
10591 public void llCollisionSprite(string impact_sprite) 11284 public void llCollisionSprite(string impact_sprite)
@@ -10597,7 +11290,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10597 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 11290 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
10598 { 11291 {
10599 m_host.AddScriptLPS(1); 11292 m_host.AddScriptLPS(1);
10600 NotImplemented("llGodLikeRezObject"); 11293
11294 if (!World.Permissions.IsGod(m_host.OwnerID))
11295 NotImplemented("llGodLikeRezObject");
11296
11297 AssetBase rezAsset = World.AssetService.Get(inventory);
11298 if (rezAsset == null)
11299 {
11300 llSay(0, "Asset not found");
11301 return;
11302 }
11303
11304 SceneObjectGroup group = null;
11305
11306 try
11307 {
11308 string xmlData = Utils.BytesToString(rezAsset.Data);
11309 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
11310 }
11311 catch
11312 {
11313 llSay(0, "Asset not found");
11314 return;
11315 }
11316
11317 if (group == null)
11318 {
11319 llSay(0, "Asset not found");
11320 return;
11321 }
11322
11323 group.RootPart.AttachPoint = group.RootPart.Shape.State;
11324 group.RootPart.AttachOffset = group.AbsolutePosition;
11325
11326 group.ResetIDs();
11327
11328 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
11329 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
11330 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
11331 group.ScheduleGroupForFullUpdate();
11332
11333 // objects rezzed with this method are die_at_edge by default.
11334 group.RootPart.SetDieAtEdge(true);
11335
11336 group.ResumeScripts();
11337
11338 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
11339 "object_rez", new Object[] {
11340 new LSL_String(
11341 group.RootPart.UUID.ToString()) },
11342 new DetectParams[0]));
10601 } 11343 }
10602 11344
10603 #endregion 11345 #endregion
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index e1c837e..8f450f8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -135,6 +135,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 135 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
136 internal float m_ScriptDelayFactor = 1.0f; 136 internal float m_ScriptDelayFactor = 1.0f;
137 internal float m_ScriptDistanceFactor = 1.0f; 137 internal float m_ScriptDistanceFactor = 1.0f;
138 internal bool m_debuggerSafe = false;
138 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 139 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
139 140
140 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID) 141 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, uint localID, UUID itemID)
@@ -143,6 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
143 m_host = host; 144 m_host = host;
144 m_localID = localID; 145 m_localID = localID;
145 m_itemID = itemID; 146 m_itemID = itemID;
147 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 148
147 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
148 m_OSFunctionsEnabled = true; 150 m_OSFunctionsEnabled = true;
@@ -201,7 +203,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
201 203
202 internal void OSSLError(string msg) 204 internal void OSSLError(string msg)
203 { 205 {
204 throw new Exception("OSSL Runtime Error: " + msg); 206 if (m_debuggerSafe)
207 {
208 OSSLShoutError(msg);
209 }
210 else
211 {
212 throw new Exception("OSSL Runtime Error: " + msg);
213 }
205 } 214 }
206 215
207 private void InitLSL() 216 private void InitLSL()
@@ -840,18 +849,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
840 if (target != null) 849 if (target != null)
841 { 850 {
842 UUID animID=UUID.Zero; 851 UUID animID=UUID.Zero;
843 lock (m_host.TaskInventory) 852 m_host.TaskInventory.LockItemsForRead(true);
853 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
844 { 854 {
845 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 855 if (inv.Value.Name == animation)
846 { 856 {
847 if (inv.Value.Name == animation) 857 if (inv.Value.Type == (int)AssetType.Animation)
848 { 858 animID = inv.Value.AssetID;
849 if (inv.Value.Type == (int)AssetType.Animation) 859 continue;
850 animID = inv.Value.AssetID;
851 continue;
852 }
853 } 860 }
854 } 861 }
862 m_host.TaskInventory.LockItemsForRead(false);
855 if (animID == UUID.Zero) 863 if (animID == UUID.Zero)
856 target.Animator.AddAnimation(animation, m_host.UUID); 864 target.Animator.AddAnimation(animation, m_host.UUID);
857 else 865 else
@@ -873,18 +881,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
873 if (target != null) 881 if (target != null)
874 { 882 {
875 UUID animID = UUID.Zero; 883 UUID animID = UUID.Zero;
876 lock (m_host.TaskInventory) 884 m_host.TaskInventory.LockItemsForRead(true);
885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
877 { 886 {
878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 887 if (inv.Value.Name == animation)
879 { 888 {
880 if (inv.Value.Name == animation) 889 if (inv.Value.Type == (int)AssetType.Animation)
881 { 890 animID = inv.Value.AssetID;
882 if (inv.Value.Type == (int)AssetType.Animation) 891 continue;
883 animID = inv.Value.AssetID;
884 continue;
885 }
886 } 892 }
887 } 893 }
894 m_host.TaskInventory.LockItemsForRead(false);
888 895
889 if (animID == UUID.Zero) 896 if (animID == UUID.Zero)
890 target.Animator.RemoveAnimation(animation); 897 target.Animator.RemoveAnimation(animation);
@@ -1834,6 +1841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1834 1841
1835 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1842 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1836 { 1843 {
1844 m_host.TaskInventory.LockItemsForRead(true);
1837 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1845 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1838 { 1846 {
1839 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1847 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1841,6 +1849,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1841 assetID = item.AssetID; 1849 assetID = item.AssetID;
1842 } 1850 }
1843 } 1851 }
1852 m_host.TaskInventory.LockItemsForRead(false);
1844 } 1853 }
1845 1854
1846 if (assetID == UUID.Zero) 1855 if (assetID == UUID.Zero)
@@ -2164,8 +2173,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2164 UUID x = module.CreateNPC(firstname, 2173 UUID x = module.CreateNPC(firstname,
2165 lastname, 2174 lastname,
2166 new Vector3((float) position.x, (float) position.y, (float) position.z), 2175 new Vector3((float) position.x, (float) position.y, (float) position.z),
2167 World, 2176 World,appearance);
2168 appearance);
2169 2177
2170 return new LSL_Key(x.ToString()); 2178 return new LSL_Key(x.ToString());
2171 } 2179 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 4ac7f8b..6de0773 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,7 @@ 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 fromRegionPos = avatar.AbsolutePosition;
432 q = avatar.Rotation; 435 q = avatar.Rotation;
433 } 436 }
434 437
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..4ad4123 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();
@@ -405,7 +406,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
405 LSL_Vector llWind(LSL_Vector offset); 406 LSL_Vector llWind(LSL_Vector offset);
406 LSL_String llXorBase64Strings(string str1, string str2); 407 LSL_String llXorBase64Strings(string str1, string str2);
407 LSL_String llXorBase64StringsCorrect(string str1, string str2); 408 LSL_String llXorBase64StringsCorrect(string str1, string str2);
408 void print(string str); 409 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
409 410
410 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 411 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
411 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 412 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 87cfe1a..5ddba60 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -83,7 +83,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
83 // Avatar Info Commands 83 // Avatar Info Commands
84 string osGetAgentIP(string agent); 84 string osGetAgentIP(string agent);
85 LSL_List osGetAgents(); 85 LSL_List osGetAgents();
86 86
87 // Teleport commands 87 // Teleport commands
88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 88 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
89 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 89 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 e82c281..59eaccb 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;
@@ -374,6 +375,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
374 public const int PRIM_SCULPT_TYPE_TORUS = 2; 375 public const int PRIM_SCULPT_TYPE_TORUS = 2;
375 public const int PRIM_SCULPT_TYPE_PLANE = 3; 376 public const int PRIM_SCULPT_TYPE_PLANE = 3;
376 public const int PRIM_SCULPT_TYPE_CYLINDER = 4; 377 public const int PRIM_SCULPT_TYPE_CYLINDER = 4;
378 public const int PRIM_SCULPT_FLAG_INVERT = 64;
379 public const int PRIM_SCULPT_FLAG_MIRROR = 128;
377 380
378 public const int MASK_BASE = 0; 381 public const int MASK_BASE = 0;
379 public const int MASK_OWNER = 1; 382 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..a88a1f4 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;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -464,6 +466,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
464 return m_LSL_Functions.llGetFreeMemory(); 466 return m_LSL_Functions.llGetFreeMemory();
465 } 467 }
466 468
469 public LSL_Integer llGetUsedMemory()
470 {
471 return m_LSL_Functions.llGetUsedMemory();
472 }
473
467 public LSL_Integer llGetFreeURLs() 474 public LSL_Integer llGetFreeURLs()
468 { 475 {
469 return m_LSL_Functions.llGetFreeURLs(); 476 return m_LSL_Functions.llGetFreeURLs();
@@ -1878,9 +1885,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1878 return m_LSL_Functions.llClearPrimMedia(face); 1885 return m_LSL_Functions.llClearPrimMedia(face);
1879 } 1886 }
1880 1887
1881 public void print(string str) 1888 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1882 { 1889 {
1883 m_LSL_Functions.print(str); 1890 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1884 } 1891 }
1885 } 1892 }
1886} 1893}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 6e9f3ec..cf25189 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -55,7 +56,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 56{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 57 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 58 {
58 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 59 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 60
60 private IScriptEngine m_Engine; 61 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 62 private IScriptWorkItem m_CurrentResult = null;
@@ -238,13 +239,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
238 239
239 if (part != null) 240 if (part != null)
240 { 241 {
241 lock (part.TaskInventory) 242 part.TaskInventory.LockItemsForRead(true);
243 if (part.TaskInventory.ContainsKey(m_ItemID))
242 { 244 {
243 if (part.TaskInventory.ContainsKey(m_ItemID)) 245 m_thisScriptTask = part.TaskInventory[m_ItemID];
244 {
245 m_thisScriptTask = part.TaskInventory[m_ItemID];
246 }
247 } 246 }
247 part.TaskInventory.LockItemsForRead(false);
248 } 248 }
249 249
250 ApiManager am = new ApiManager(); 250 ApiManager am = new ApiManager();
@@ -271,9 +271,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 271 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
272// lease.Register(this); 272// lease.Register(this);
273 } 273 }
274 catch (Exception) 274 catch (Exception e)
275 { 275 {
276 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 276 m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly);
277 throw;
277 } 278 }
278 279
279 try 280 try
@@ -434,14 +435,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
434 { 435 {
435 int permsMask; 436 int permsMask;
436 UUID permsGranter; 437 UUID permsGranter;
437 lock (part.TaskInventory) 438 part.TaskInventory.LockItemsForRead(true);
439 if (!part.TaskInventory.ContainsKey(m_ItemID))
438 { 440 {
439 if (!part.TaskInventory.ContainsKey(m_ItemID)) 441 part.TaskInventory.LockItemsForRead(false);
440 return; 442 return;
441
442 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
443 permsMask = part.TaskInventory[m_ItemID].PermsMask;
444 } 443 }
444 permsGranter = part.TaskInventory[m_ItemID].PermsGranter;
445 permsMask = part.TaskInventory[m_ItemID].PermsMask;
446 part.TaskInventory.LockItemsForRead(false);
445 447
446 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 448 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
447 { 449 {
@@ -550,6 +552,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
550 return true; 552 return true;
551 } 553 }
552 554
555 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
553 public void SetState(string state) 556 public void SetState(string state)
554 { 557 {
555 if (state == State) 558 if (state == State)
@@ -561,7 +564,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 new DetectParams[0])); 564 new DetectParams[0]));
562 PostEvent(new EventParams("state_entry", new Object[0], 565 PostEvent(new EventParams("state_entry", new Object[0],
563 new DetectParams[0])); 566 new DetectParams[0]));
564 567
565 throw new EventAbortException(); 568 throw new EventAbortException();
566 } 569 }
567 570
@@ -644,14 +647,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
644 /// <returns></returns> 647 /// <returns></returns>
645 public object EventProcessor() 648 public object EventProcessor()
646 { 649 {
647 if (m_Suspended) 650 EventParams data = null;
648 return 0;
649 651
650 lock (m_Script) 652 lock (m_EventQueue)
651 { 653 {
652 EventParams data = null; 654 if (m_Suspended)
655 return 0;
653 656
654 lock (m_EventQueue) 657 lock (m_Script)
655 { 658 {
656 data = (EventParams) m_EventQueue.Dequeue(); 659 data = (EventParams) m_EventQueue.Dequeue();
657 if (data == null) // Shouldn't happen 660 if (data == null) // Shouldn't happen
@@ -677,6 +680,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
677 if (data.EventName == "collision") 680 if (data.EventName == "collision")
678 m_CollisionInQueue = false; 681 m_CollisionInQueue = false;
679 } 682 }
683 }
684 lock(m_Script)
685 {
680 686
681 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this); 687 //m_log.DebugFormat("[XENGINE]: Processing event {0} for {1}", data.EventName, this);
682 688
@@ -833,6 +839,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
833 new Object[0], new DetectParams[0])); 839 new Object[0], new DetectParams[0]));
834 } 840 }
835 841
842 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
836 public void ApiResetScript() 843 public void ApiResetScript()
837 { 844 {
838 // bool running = Running; 845 // bool running = Running;
@@ -864,10 +871,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
864 871
865 public Dictionary<string, object> GetVars() 872 public Dictionary<string, object> GetVars()
866 { 873 {
867 if (m_Script != null) 874 return m_Script.GetVars();
868 return m_Script.GetVars();
869 else
870 return new Dictionary<string, object>();
871 } 875 }
872 876
873 public void SetVars(Dictionary<string, object> vars) 877 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..9e6752c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -1064,7 +1058,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1058 {
1065 list ret = new list(); 1059 list ret = new list();
1066 double entry; 1060 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1061 for (int i = 0; i < src.Data.Length; i++)
1068 { 1062 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1063 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1064 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 156fd57..975e9cc 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -30,6 +30,7 @@ using System.IO;
30using System.Threading; 30using System.Threading;
31using System.Collections; 31using System.Collections;
32using System.Collections.Generic; 32using System.Collections.Generic;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Security; 34using System.Security;
34using System.Security.Policy; 35using System.Security.Policy;
35using System.Reflection; 36using System.Reflection;
@@ -102,6 +103,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
102 private Dictionary<UUID, IScriptInstance> m_Scripts = 103 private Dictionary<UUID, IScriptInstance> m_Scripts =
103 new Dictionary<UUID, IScriptInstance>(); 104 new Dictionary<UUID, IScriptInstance>();
104 105
106 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
107
105 // Maps the asset ID to the assembly 108 // Maps the asset ID to the assembly
106 109
107 private Dictionary<UUID, string> m_Assemblies = 110 private Dictionary<UUID, string> m_Assemblies =
@@ -124,6 +127,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
124 IWorkItemResult m_CurrentCompile = null; 127 IWorkItemResult m_CurrentCompile = null;
125 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 128 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
126 129
130 private void lockScriptsForRead(bool locked)
131 {
132 if (locked)
133 {
134 if (m_scriptsLock.RecursiveReadCount > 0)
135 {
136 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
137 m_scriptsLock.ExitReadLock();
138 }
139 if (m_scriptsLock.RecursiveWriteCount > 0)
140 {
141 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
142 m_scriptsLock.ExitWriteLock();
143 }
144
145 while (!m_scriptsLock.TryEnterReadLock(60000))
146 {
147 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire READ lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
148 if (m_scriptsLock.IsWriteLockHeld)
149 {
150 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
151 }
152 }
153 }
154 else
155 {
156 if (m_scriptsLock.RecursiveReadCount > 0)
157 {
158 m_scriptsLock.ExitReadLock();
159 }
160 }
161 }
162 private void lockScriptsForWrite(bool locked)
163 {
164 if (locked)
165 {
166 if (m_scriptsLock.RecursiveReadCount > 0)
167 {
168 m_log.Error("[XEngine.m_Scripts] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue.");
169 m_scriptsLock.ExitReadLock();
170 }
171 if (m_scriptsLock.RecursiveWriteCount > 0)
172 {
173 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
174 m_scriptsLock.ExitWriteLock();
175 }
176
177 while (!m_scriptsLock.TryEnterWriteLock(60000))
178 {
179 m_log.Error("[XEngine.m_Scripts] Thread lock detected while trying to aquire WRITE lock of m_scripts in XEngine. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed.");
180 if (m_scriptsLock.IsWriteLockHeld)
181 {
182 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
183 }
184 }
185 }
186 else
187 {
188 if (m_scriptsLock.RecursiveWriteCount > 0)
189 {
190 m_scriptsLock.ExitWriteLock();
191 }
192 }
193 }
194
127 public string ScriptEngineName 195 public string ScriptEngineName
128 { 196 {
129 get { return "XEngine"; } 197 get { return "XEngine"; }
@@ -269,43 +337,45 @@ namespace OpenSim.Region.ScriptEngine.XEngine
269 337
270 public void RemoveRegion(Scene scene) 338 public void RemoveRegion(Scene scene)
271 { 339 {
272 lock (m_Scripts) 340 lockScriptsForRead(true);
341 foreach (IScriptInstance instance in m_Scripts.Values)
273 { 342 {
274 foreach (IScriptInstance instance in m_Scripts.Values) 343 // Force a final state save
344 //
345 if (m_Assemblies.ContainsKey(instance.AssetID))
275 { 346 {
276 // Force a final state save 347 string assembly = m_Assemblies[instance.AssetID];
277 // 348 instance.SaveState(assembly);
278 if (m_Assemblies.ContainsKey(instance.AssetID)) 349 }
279 {
280 string assembly = m_Assemblies[instance.AssetID];
281 instance.SaveState(assembly);
282 }
283 350
284 // Clear the event queue and abort the instance thread 351 // Clear the event queue and abort the instance thread
285 // 352 //
286 instance.ClearQueue(); 353 instance.ClearQueue();
287 instance.Stop(0); 354 instance.Stop(0);
288 355
289 // Release events, timer, etc 356 // Release events, timer, etc
290 // 357 //
291 instance.DestroyScriptInstance(); 358 instance.DestroyScriptInstance();
292 359
293 // Unload scripts and app domains 360 // Unload scripts and app domains
294 // Must be done explicitly because they have infinite 361 // Must be done explicitly because they have infinite
295 // lifetime 362 // lifetime
296 // 363 //
297 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 364 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
298 if (m_DomainScripts[instance.AppDomain].Count == 0) 365 if (m_DomainScripts[instance.AppDomain].Count == 0)
299 { 366 {
300 m_DomainScripts.Remove(instance.AppDomain); 367 m_DomainScripts.Remove(instance.AppDomain);
301 UnloadAppDomain(instance.AppDomain); 368 UnloadAppDomain(instance.AppDomain);
302 }
303 } 369 }
304 m_Scripts.Clear();
305 m_PrimObjects.Clear();
306 m_Assemblies.Clear();
307 m_DomainScripts.Clear();
308 } 370 }
371 lockScriptsForRead(false);
372 lockScriptsForWrite(true);
373 m_Scripts.Clear();
374 lockScriptsForWrite(false);
375 m_PrimObjects.Clear();
376 m_Assemblies.Clear();
377 m_DomainScripts.Clear();
378
309 lock (m_ScriptEngines) 379 lock (m_ScriptEngines)
310 { 380 {
311 m_ScriptEngines.Remove(this); 381 m_ScriptEngines.Remove(this);
@@ -367,22 +437,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
367 437
368 List<IScriptInstance> instances = new List<IScriptInstance>(); 438 List<IScriptInstance> instances = new List<IScriptInstance>();
369 439
370 lock (m_Scripts) 440 lockScriptsForRead(true);
371 { 441 foreach (IScriptInstance instance in m_Scripts.Values)
372 foreach (IScriptInstance instance in m_Scripts.Values)
373 instances.Add(instance); 442 instances.Add(instance);
374 } 443 lockScriptsForRead(false);
375 444
376 foreach (IScriptInstance i in instances) 445 foreach (IScriptInstance i in instances)
377 { 446 {
378 string assembly = String.Empty; 447 string assembly = String.Empty;
379 448
380 lock (m_Scripts) 449
381 {
382 if (!m_Assemblies.ContainsKey(i.AssetID)) 450 if (!m_Assemblies.ContainsKey(i.AssetID))
383 continue; 451 continue;
384 assembly = m_Assemblies[i.AssetID]; 452 assembly = m_Assemblies[i.AssetID];
385 } 453
386 454
387 i.SaveState(assembly); 455 i.SaveState(assembly);
388 } 456 }
@@ -716,92 +784,95 @@ namespace OpenSim.Region.ScriptEngine.XEngine
716 } 784 }
717 785
718 ScriptInstance instance = null; 786 ScriptInstance instance = null;
719 lock (m_Scripts) 787 // Create the object record
788 lockScriptsForRead(true);
789 if ((!m_Scripts.ContainsKey(itemID)) ||
790 (m_Scripts[itemID].AssetID != assetID))
720 { 791 {
721 // Create the object record 792 lockScriptsForRead(false);
722 793
723 if ((!m_Scripts.ContainsKey(itemID)) || 794 UUID appDomain = assetID;
724 (m_Scripts[itemID].AssetID != assetID))
725 {
726 UUID appDomain = assetID;
727 795
728 if (part.ParentGroup.IsAttachment) 796 if (part.ParentGroup.IsAttachment)
729 appDomain = part.ParentGroup.RootPart.UUID; 797 appDomain = part.ParentGroup.RootPart.UUID;
730 798
731 if (!m_AppDomains.ContainsKey(appDomain)) 799 if (!m_AppDomains.ContainsKey(appDomain))
800 {
801 try
732 { 802 {
733 try 803 AppDomainSetup appSetup = new AppDomainSetup();
734 { 804 appSetup.PrivateBinPath = Path.Combine(
735 AppDomainSetup appSetup = new AppDomainSetup(); 805 m_ScriptEnginesPath,
736 appSetup.PrivateBinPath = Path.Combine( 806 m_Scene.RegionInfo.RegionID.ToString());
737 m_ScriptEnginesPath, 807
738 m_Scene.RegionInfo.RegionID.ToString()); 808 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
739 809 Evidence evidence = new Evidence(baseEvidence);
740 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 810
741 Evidence evidence = new Evidence(baseEvidence); 811 AppDomain sandbox;
742 812 if (m_AppDomainLoading)
743 AppDomain sandbox; 813 sandbox = AppDomain.CreateDomain(
744 if (m_AppDomainLoading) 814 m_Scene.RegionInfo.RegionID.ToString(),
745 sandbox = AppDomain.CreateDomain( 815 evidence, appSetup);
746 m_Scene.RegionInfo.RegionID.ToString(), 816 else
747 evidence, appSetup); 817 sandbox = AppDomain.CurrentDomain;
748 else 818
749 sandbox = AppDomain.CurrentDomain; 819 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
750 820 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
751 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel(); 821 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
752 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition(); 822 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
753 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet"); 823 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
754 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet); 824 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
755 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement); 825 //sandbox.SetAppDomainPolicy(sandboxPolicy);
756 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup; 826
757 //sandbox.SetAppDomainPolicy(sandboxPolicy); 827 m_AppDomains[appDomain] = sandbox;
758 828
759 m_AppDomains[appDomain] = sandbox; 829 m_AppDomains[appDomain].AssemblyResolve +=
760 830 new ResolveEventHandler(
761 m_AppDomains[appDomain].AssemblyResolve += 831 AssemblyResolver.OnAssemblyResolve);
762 new ResolveEventHandler( 832 m_DomainScripts[appDomain] = new List<UUID>();
763 AssemblyResolver.OnAssemblyResolve); 833 }
764 m_DomainScripts[appDomain] = new List<UUID>(); 834 catch (Exception e)
765 } 835 {
766 catch (Exception e) 836 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
837 m_ScriptErrorMessage += "Exception creating app domain:\n";
838 m_ScriptFailCount++;
839 lock (m_AddingAssemblies)
767 { 840 {
768 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 841 m_AddingAssemblies[assembly]--;
769 m_ScriptErrorMessage += "Exception creating app domain:\n";
770 m_ScriptFailCount++;
771 lock (m_AddingAssemblies)
772 {
773 m_AddingAssemblies[assembly]--;
774 }
775 return false;
776 } 842 }
843 return false;
777 } 844 }
778 m_DomainScripts[appDomain].Add(itemID); 845 }
779 846 m_DomainScripts[appDomain].Add(itemID);
780 instance = new ScriptInstance(this, part, 847
781 itemID, assetID, assembly, 848 instance = new ScriptInstance(this, part,
782 m_AppDomains[appDomain], 849 itemID, assetID, assembly,
783 part.ParentGroup.RootPart.Name, 850 m_AppDomains[appDomain],
784 item.Name, startParam, postOnRez, 851 part.ParentGroup.RootPart.Name,
785 stateSource, m_MaxScriptQueue); 852 item.Name, startParam, postOnRez,
786 853 stateSource, m_MaxScriptQueue);
787 m_log.DebugFormat( 854
855 m_log.DebugFormat(
788 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}", 856 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
789 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID, 857 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
790 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName); 858 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
791 859
792 if (presence != null) 860 if (presence != null)
793 { 861 {
794 ShowScriptSaveResponse(item.OwnerID, 862 ShowScriptSaveResponse(item.OwnerID,
795 assetID, "Compile successful", true); 863 assetID, "Compile successful", true);
796 }
797
798 instance.AppDomain = appDomain;
799 instance.LineMap = linemap;
800
801 m_Scripts[itemID] = instance;
802 } 864 }
803 }
804 865
866 instance.AppDomain = appDomain;
867 instance.LineMap = linemap;
868 lockScriptsForWrite(true);
869 m_Scripts[itemID] = instance;
870 lockScriptsForWrite(false);
871 }
872 else
873 {
874 lockScriptsForRead(false);
875 }
805 lock (m_PrimObjects) 876 lock (m_PrimObjects)
806 { 877 {
807 if (!m_PrimObjects.ContainsKey(localID)) 878 if (!m_PrimObjects.ContainsKey(localID))
@@ -820,9 +891,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
820 m_AddingAssemblies[assembly]--; 891 m_AddingAssemblies[assembly]--;
821 } 892 }
822 893
823 if (instance != null) 894 if (instance!=null)
824 instance.Init(); 895 instance.Init();
825 896
826 return true; 897 return true;
827 } 898 }
828 899
@@ -835,20 +906,23 @@ namespace OpenSim.Region.ScriptEngine.XEngine
835 m_CompileDict.Remove(itemID); 906 m_CompileDict.Remove(itemID);
836 } 907 }
837 908
838 IScriptInstance instance = null; 909 lockScriptsForRead(true);
839 910 // Do we even have it?
840 lock (m_Scripts) 911 if (!m_Scripts.ContainsKey(itemID))
841 { 912 {
842 // Do we even have it? 913 lockScriptsForRead(false);
843 if (!m_Scripts.ContainsKey(itemID)) 914 return;
844 return;
845
846 instance=m_Scripts[itemID];
847 m_Scripts.Remove(itemID);
848 } 915 }
916
849 917
918 IScriptInstance instance=m_Scripts[itemID];
919 lockScriptsForRead(false);
920 lockScriptsForWrite(true);
921 m_Scripts.Remove(itemID);
922 lockScriptsForWrite(false);
850 instance.ClearQueue(); 923 instance.ClearQueue();
851 instance.Stop(0); 924 instance.Stop(0);
925
852// bool objectRemoved = false; 926// bool objectRemoved = false;
853 927
854 lock (m_PrimObjects) 928 lock (m_PrimObjects)
@@ -884,11 +958,12 @@ namespace OpenSim.Region.ScriptEngine.XEngine
884 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 958 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
885 if (handlerObjectRemoved != null) 959 if (handlerObjectRemoved != null)
886 { 960 {
887 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID); 961 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
888 handlerObjectRemoved(part.UUID); 962 handlerObjectRemoved(part.UUID);
889 } 963 }
890 964
891 965 CleanAssemblies();
966
892 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 967 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
893 if (handlerScriptRemoved != null) 968 if (handlerScriptRemoved != null)
894 handlerScriptRemoved(itemID); 969 handlerScriptRemoved(itemID);
@@ -1030,7 +1105,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1030 return false; 1105 return false;
1031 1106
1032 uuids = m_PrimObjects[localID]; 1107 uuids = m_PrimObjects[localID];
1033 } 1108
1034 1109
1035 foreach (UUID itemID in uuids) 1110 foreach (UUID itemID in uuids)
1036 { 1111 {
@@ -1048,6 +1123,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1048 result = true; 1123 result = true;
1049 } 1124 }
1050 } 1125 }
1126 }
1051 1127
1052 return result; 1128 return result;
1053 } 1129 }
@@ -1147,12 +1223,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1147 private IScriptInstance GetInstance(UUID itemID) 1223 private IScriptInstance GetInstance(UUID itemID)
1148 { 1224 {
1149 IScriptInstance instance; 1225 IScriptInstance instance;
1150 lock (m_Scripts) 1226 lockScriptsForRead(true);
1227 if (!m_Scripts.ContainsKey(itemID))
1151 { 1228 {
1152 if (!m_Scripts.ContainsKey(itemID)) 1229 lockScriptsForRead(false);
1153 return null; 1230 return null;
1154 instance = m_Scripts[itemID];
1155 } 1231 }
1232 instance = m_Scripts[itemID];
1233 lockScriptsForRead(false);
1156 return instance; 1234 return instance;
1157 } 1235 }
1158 1236
@@ -1176,6 +1254,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1176 return false; 1254 return false;
1177 } 1255 }
1178 1256
1257 [DebuggerNonUserCode]
1179 public void ApiResetScript(UUID itemID) 1258 public void ApiResetScript(UUID itemID)
1180 { 1259 {
1181 IScriptInstance instance = GetInstance(itemID); 1260 IScriptInstance instance = GetInstance(itemID);
@@ -1227,6 +1306,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1227 return UUID.Zero; 1306 return UUID.Zero;
1228 } 1307 }
1229 1308
1309 [DebuggerNonUserCode]
1230 public void SetState(UUID itemID, string newState) 1310 public void SetState(UUID itemID, string newState)
1231 { 1311 {
1232 IScriptInstance instance = GetInstance(itemID); 1312 IScriptInstance instance = GetInstance(itemID);
@@ -1247,11 +1327,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1247 { 1327 {
1248 List<IScriptInstance> instances = new List<IScriptInstance>(); 1328 List<IScriptInstance> instances = new List<IScriptInstance>();
1249 1329
1250 lock (m_Scripts) 1330 lockScriptsForRead(true);
1251 { 1331 foreach (IScriptInstance instance in m_Scripts.Values)
1252 foreach (IScriptInstance instance in m_Scripts.Values)
1253 instances.Add(instance); 1332 instances.Add(instance);
1254 } 1333 lockScriptsForRead(false);
1255 1334
1256 foreach (IScriptInstance i in instances) 1335 foreach (IScriptInstance i in instances)
1257 { 1336 {
@@ -1632,5 +1711,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1632 1711
1633 instance.Resume(); 1712 instance.Resume();
1634 } 1713 }
1714
1715 public bool HasScript(UUID itemID, out bool running)
1716 {
1717 running = true;
1718
1719 IScriptInstance instance = GetInstance(itemID);
1720 if (instance == null)
1721 return false;
1722
1723 running = instance.Running;
1724 return true;
1725 }
1635 } 1726 }
1636} 1727}