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.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs117
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3502
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs6
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs157
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs22
-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.cs14
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs3
-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.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs70
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs5
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs45
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs172
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs363
21 files changed, 3311 insertions, 1421 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 998f40b..1e19032 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -28,9 +28,7 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Reflection;
32using System.Threading; 31using System.Threading;
33using log4net;
34using OpenMetaverse; 32using OpenMetaverse;
35using OpenSim.Framework; 33using OpenSim.Framework;
36using OpenSim.Framework.Monitoring; 34using OpenSim.Framework.Monitoring;
@@ -39,6 +37,8 @@ using OpenSim.Region.ScriptEngine.Interfaces;
39using OpenSim.Region.ScriptEngine.Shared; 37using OpenSim.Region.ScriptEngine.Shared;
40using OpenSim.Region.ScriptEngine.Shared.Api.Plugins; 38using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
41using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer; 39using Timer=OpenSim.Region.ScriptEngine.Shared.Api.Plugins.Timer;
40using System.Reflection;
41using log4net;
42 42
43namespace OpenSim.Region.ScriptEngine.Shared.Api 43namespace OpenSim.Region.ScriptEngine.Shared.Api
44{ 44{
@@ -269,6 +269,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
269 /// <param name="itemID"></param> 269 /// <param name="itemID"></param>
270 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID) 270 public static void RemoveScript(IScriptEngine engine, uint localID, UUID itemID)
271 { 271 {
272 // Remove a specific script
272// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID); 273// m_log.DebugFormat("[ASYNC COMMAND MANAGER]: Removing facilities for script {0}", itemID);
273 274
274 lock (staticLock) 275 lock (staticLock)
@@ -282,7 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
282 // Remove from: HttpRequest 283 // Remove from: HttpRequest
283 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>(); 284 IHttpRequestModule iHttpReq = engine.World.RequestModuleInterface<IHttpRequestModule>();
284 if (iHttpReq != null) 285 if (iHttpReq != null)
285 iHttpReq.StopHttpRequestsForScript(itemID); 286 iHttpReq.StopHttpRequest(localID, itemID);
286 287
287 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>(); 288 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
288 if (comms != null) 289 if (comms != null)
@@ -364,6 +365,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
364 } 365 }
365 } 366 }
366 367
368 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
369 {
370 // Remove a specific script
371
372 // Remove dataserver events
373 m_Dataserver[engine].RemoveEvents(localID, itemID);
374
375 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
376 if (comms != null)
377 comms.DeleteListener(itemID);
378
379 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
380 if (xmlrpc != null)
381 {
382 xmlrpc.DeleteChannels(itemID);
383 xmlrpc.CancelSRDRequests(itemID);
384 }
385
386 // Remove Sensors
387 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
388
389 }
390
367 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 391 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
368 { 392 {
369 List<Object> data = new List<Object>(); 393 List<Object> data = new List<Object>();
@@ -439,4 +463,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
439 } 463 }
440 } 464 }
441 } 465 }
442} \ No newline at end of file 466}
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..fce8ff8
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,117 @@
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.Threading;
30using System.Reflection;
31using System.Collections;
32using System.Collections.Generic;
33using System.Runtime.Remoting.Lifetime;
34using OpenMetaverse;
35using Nini.Config;
36using OpenSim;
37using OpenSim.Framework;
38using OpenSim.Region.CoreModules.World.LightShare;
39using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes;
41using OpenSim.Region.ScriptEngine.Shared;
42using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
43using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
44using OpenSim.Region.ScriptEngine.Interfaces;
45using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
46using OpenSim.Services.Interfaces;
47
48using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
49using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
50using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
51using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
52using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
53using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
54using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
55
56namespace OpenSim.Region.ScriptEngine.Shared.Api
57{
58 [Serializable]
59 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
60 {
61 internal IScriptEngine m_ScriptEngine;
62 internal SceneObjectPart m_host;
63 internal TaskInventoryItem m_item;
64 internal bool m_CMFunctionsEnabled = false;
65
66 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
67 {
68 m_ScriptEngine = ScriptEngine;
69 m_host = host;
70 m_item = item;
71
72 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
73 m_CMFunctionsEnabled = true;
74 }
75
76 public override Object InitializeLifetimeService()
77 {
78 ILease lease = (ILease)base.InitializeLifetimeService();
79
80 if (lease.CurrentState == LeaseState.Initial)
81 {
82 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
83 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
84 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
85 }
86 return lease;
87 }
88
89 public Scene World
90 {
91 get { return m_ScriptEngine.World; }
92 }
93
94 public string cmDetectedCountry(int number)
95 {
96 m_host.AddScriptLPS(1);
97 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
98 if (detectedParams == null)
99 return String.Empty;
100 return detectedParams.Country;
101 }
102
103 public string cmGetAgentCountry(LSL_Key key)
104 {
105 if (!World.Permissions.IsGod(m_host.OwnerID))
106 return String.Empty;
107
108 UUID uuid;
109
110 if (!UUID.TryParse(key, out uuid))
111 return String.Empty;
112
113 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
114 return account.UserCountry;
115 }
116 }
117}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 9427061..f5d5bc6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 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. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
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.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70using System.Linq; 74using System.Linq;
71using PermissionMask = OpenSim.Framework.PermissionMask; 75using PermissionMask = OpenSim.Framework.PermissionMask;
72 76
@@ -115,11 +119,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
115 protected int m_notecardLineReadCharsMax = 255; 119 protected int m_notecardLineReadCharsMax = 255;
116 protected int m_scriptConsoleChannel = 0; 120 protected int m_scriptConsoleChannel = 0;
117 protected bool m_scriptConsoleChannelEnabled = false; 121 protected bool m_scriptConsoleChannelEnabled = false;
122 protected bool m_debuggerSafe = false;
118 protected IUrlModule m_UrlModule = null; 123 protected IUrlModule m_UrlModule = null;
119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 124 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 125 new Dictionary<UUID, UserInfoCacheEntry>();
126 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
121 protected ISoundModule m_SoundModule = null; 127 protected ISoundModule m_SoundModule = null;
122 128
129// protected Timer m_ShoutSayTimer;
130 protected int m_SayShoutCount = 0;
131 DateTime m_lastSayShoutCheck;
132
133 private Dictionary<string, string> MovementAnimationsForLSL =
134 new Dictionary<string, string> {
135 {"FLY", "Flying"},
136 {"FLYSLOW", "FlyingSlow"},
137 {"HOVER_UP", "Hovering Up"},
138 {"HOVER_DOWN", "Hovering Down"},
139 {"HOVER", "Hovering"},
140 {"LAND", "Landing"},
141 {"FALLDOWN", "Falling Down"},
142 {"PREJUMP", "PreJumping"},
143 {"JUMP", "Jumping"},
144 {"STANDUP", "Standing Up"},
145 {"SOFT_LAND", "Soft Landing"},
146 {"STAND", "Standing"},
147 {"CROUCHWALK", "CrouchWalking"},
148 {"RUN", "Running"},
149 {"WALK", "Walking"},
150 {"CROUCH", "Crouching"},
151 {"TURNLEFT", "Turning Left"},
152 {"TURNRIGHT", "Turning Right"}
153 };
123 //An array of HTTP/1.1 headers that are not allowed to be used 154 //An array of HTTP/1.1 headers that are not allowed to be used
124 //as custom headers by llHTTPRequest. 155 //as custom headers by llHTTPRequest.
125 private string[] HttpStandardHeaders = 156 private string[] HttpStandardHeaders =
@@ -140,9 +171,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 public void Initialize( 171 public void Initialize(
141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
142 { 173 {
174 m_lastSayShoutCheck = DateTime.UtcNow;
175
143 m_ScriptEngine = scriptEngine; 176 m_ScriptEngine = scriptEngine;
144 m_host = host; 177 m_host = host;
145 m_item = item; 178 m_item = item;
179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 m_coopSleepHandle = coopSleepHandle; 180 m_coopSleepHandle = coopSleepHandle;
147 181
148 LoadConfig(); 182 LoadConfig();
@@ -231,6 +265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
231 get { return m_ScriptEngine.World; } 265 get { return m_ScriptEngine.World; }
232 } 266 }
233 267
268 [DebuggerNonUserCode]
234 public void state(string newState) 269 public void state(string newState)
235 { 270 {
236 m_ScriptEngine.SetState(m_item.ItemID, newState); 271 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -240,6 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
240 /// Reset the named script. The script must be present 275 /// Reset the named script. The script must be present
241 /// in the same prim. 276 /// in the same prim.
242 /// </summary> 277 /// </summary>
278 [DebuggerNonUserCode]
243 public void llResetScript() 279 public void llResetScript()
244 { 280 {
245 m_host.AddScriptLPS(1); 281 m_host.AddScriptLPS(1);
@@ -302,6 +338,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
302 } 338 }
303 } 339 }
304 340
341 public List<ScenePresence> GetLinkAvatars(int linkType)
342 {
343 List<ScenePresence> ret = new List<ScenePresence>();
344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
345 return ret;
346
347 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
348
349 switch (linkType)
350 {
351 case ScriptBaseClass.LINK_SET:
352 return avs;
353
354 case ScriptBaseClass.LINK_ROOT:
355 return ret;
356
357 case ScriptBaseClass.LINK_ALL_OTHERS:
358 return avs;
359
360 case ScriptBaseClass.LINK_ALL_CHILDREN:
361 return avs;
362
363 case ScriptBaseClass.LINK_THIS:
364 return ret;
365
366 default:
367 if (linkType < 0)
368 return ret;
369
370 int partCount = m_host.ParentGroup.GetPartCount();
371
372 if (linkType <= partCount)
373 {
374 return ret;
375 }
376 else
377 {
378 linkType = linkType - partCount;
379 if (linkType > avs.Count)
380 {
381 return ret;
382 }
383 else
384 {
385 ret.Add(avs[linkType-1]);
386 return ret;
387 }
388 }
389 }
390 }
391
305 /// <summary> 392 /// <summary>
306 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
307 /// </summary> 394 /// </summary>
@@ -384,6 +471,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 471 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
385 { 472 {
386 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 473 List<SceneObjectPart> ret = new List<SceneObjectPart>();
474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
475 return ret;
387 ret.Add(part); 476 ret.Add(part);
388 477
389 switch (linkType) 478 switch (linkType)
@@ -537,31 +626,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
537 626
538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 627 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
539 628
540 /// <summary> 629 // Utility function for llRot2Euler
541 /// Convert an LSL rotation to a Euler vector. 630
542 /// </summary> 631 // normalize an angle between -PI and PI (-180 to +180 degrees)
543 /// <remarks> 632 protected double NormalizeAngle(double angle)
544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
546 /// </remarks>
547 /// <param name="r"></param>
548 /// <returns></returns>
549 public LSL_Vector llRot2Euler(LSL_Rotation r)
550 { 633 {
551 m_host.AddScriptLPS(1); 634 if (angle > -Math.PI && angle < Math.PI)
635 return angle;
552 636
553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 637 int numPis = (int)(Math.PI / angle);
554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 638 double remainder = angle - Math.PI * numPis;
555 if (m == 0.0) return new LSL_Vector(); 639 if (numPis % 2 == 1)
556 double x = Math.Atan2(-v.y, v.z); 640 return Math.PI - angle;
557 double sin = v.x / m; 641 return remainder;
558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 642 }
559 double y = Math.Asin(sin);
560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
561 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
562 double z = Math.Atan2(v.y, v.x);
563 643
564 return new LSL_Vector(x, y, z); 644 public LSL_Vector llRot2Euler(LSL_Rotation q1)
645 {
646 m_host.AddScriptLPS(1);
647 LSL_Vector eul = new LSL_Vector();
648
649 double sqw = q1.s*q1.s;
650 double sqx = q1.x*q1.x;
651 double sqy = q1.z*q1.z;
652 double sqz = q1.y*q1.y;
653 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
654 double test = q1.x*q1.z + q1.y*q1.s;
655 if (test > 0.4999*unit) { // singularity at north pole
656 eul.z = 2 * Math.Atan2(q1.x,q1.s);
657 eul.y = Math.PI/2;
658 eul.x = 0;
659 return eul;
660 }
661 if (test < -0.4999*unit) { // singularity at south pole
662 eul.z = -2 * Math.Atan2(q1.x,q1.s);
663 eul.y = -Math.PI/2;
664 eul.x = 0;
665 return eul;
666 }
667 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
668 eul.y = Math.Asin(2*test/unit);
669 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
670 return eul;
565 } 671 }
566 672
567 /* From wiki: 673 /* From wiki:
@@ -614,18 +720,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
614 m_host.AddScriptLPS(1); 720 m_host.AddScriptLPS(1);
615 721
616 double x,y,z,s; 722 double x,y,z,s;
617 723 v.x *= 0.5;
618 double c1 = Math.Cos(v.x * 0.5); 724 v.y *= 0.5;
619 double c2 = Math.Cos(v.y * 0.5); 725 v.z *= 0.5;
620 double c3 = Math.Cos(v.z * 0.5); 726 double c1 = Math.Cos(v.x);
621 double s1 = Math.Sin(v.x * 0.5); 727 double c2 = Math.Cos(v.y);
622 double s2 = Math.Sin(v.y * 0.5); 728 double c1c2 = c1 * c2;
623 double s3 = Math.Sin(v.z * 0.5); 729 double s1 = Math.Sin(v.x);
624 730 double s2 = Math.Sin(v.y);
625 x = s1 * c2 * c3 + c1 * s2 * s3; 731 double s1s2 = s1 * s2;
626 y = c1 * s2 * c3 - s1 * c2 * s3; 732 double c1s2 = c1 * s2;
627 z = s1 * s2 * c3 + c1 * c2 * s3; 733 double s1c2 = s1 * c2;
628 s = c1 * c2 * c3 - s1 * s2 * s3; 734 double c3 = Math.Cos(v.z);
735 double s3 = Math.Sin(v.z);
736
737 x = s1c2 * c3 + c1s2 * s3;
738 y = c1s2 * c3 - s1c2 * s3;
739 z = s1s2 * c3 + c1c2 * s3;
740 s = c1c2 * c3 - s1s2 * s3;
629 741
630 return new LSL_Rotation(x, y, z, s); 742 return new LSL_Rotation(x, y, z, s);
631 } 743 }
@@ -763,77 +875,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
763 { 875 {
764 //A and B should both be normalized 876 //A and B should both be normalized
765 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
766 LSL_Rotation rotBetween; 878 /* This method is more accurate than the SL one, and thus causes problems
767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 879 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
768 // continue calculation. 880
769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 881 double dotProduct = LSL_Vector.Dot(a, b);
770 { 882 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 883 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
772 } 884 double angle = Math.Acos(dotProduct / magProduct);
773 else 885 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
774 { 886 double s = Math.Sin(angle / 2);
775 a = LSL_Vector.Norm(a); 887
776 b = LSL_Vector.Norm(b); 888 double x = axis.x * s;
777 double dotProduct = LSL_Vector.Dot(a, b); 889 double y = axis.y * s;
778 // There are two degenerate cases possible. These are for vectors 180 or 890 double z = axis.z * s;
779 // 0 degrees apart. These have to be detected and handled individually. 891 double w = Math.Cos(angle / 2);
780 // 892
781 // Check for vectors 180 degrees apart. 893 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
782 // A dot product of -1 would mean the angle between vectors is 180 degrees. 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
783 if (dotProduct < -0.9999999f) 895
784 { 896 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
785 // First assume X axis is orthogonal to the vectors. 897 */
786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 898
787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 899 // This method mimics the 180 errors found in SL
788 // Check for near zero vector. A very small non-zero number here will create 900 // See www.euclideanspace.com... angleBetween
789 // a rotation in an undesired direction. 901 LSL_Vector vec_a = a;
790 if (LSL_Vector.Mag(orthoVector) > 0.0001) 902 LSL_Vector vec_b = b;
791 { 903
792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 904 // Eliminate zero length
793 } 905 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
794 // If the magnitude of the vector was near zero, then assume the X axis is not 906 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
795 // orthogonal and use the Z axis instead. 907 if (vec_a_mag < 0.00001 ||
796 else 908 vec_b_mag < 0.00001)
797 { 909 {
798 // Set 180 z rotation. 910 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 911 }
800 } 912
801 } 913 // Normalize
802 // Check for parallel vectors. 914 vec_a = llVecNorm(vec_a);
803 // A dot product of 1 would mean the angle between vectors is 0 degrees. 915 vec_b = llVecNorm(vec_b);
804 else if (dotProduct > 0.9999999f) 916
805 { 917 // Calculate axis and rotation angle
806 // Set zero rotation. 918 LSL_Vector axis = vec_a % vec_b;
807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 919 LSL_Float cos_theta = vec_a * vec_b;
808 } 920
809 else 921 // Check if parallel
810 { 922 if (cos_theta > 0.99999)
811 // All special checks have been performed so get the axis of rotation. 923 {
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 924 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813 // Quarternion s value is the length of the unit vector + dot product. 925 }
814 double qs = 1.0 + dotProduct; 926
815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 927 // Check if anti-parallel
816 // Normalize the rotation. 928 else if (cos_theta < -0.99999)
817 double mag = LSL_Rotation.Mag(rotBetween); 929 {
818 // We shouldn't have to worry about a divide by zero here. The qs value will be 930 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
819 // non-zero because we already know if we're here, then the dotProduct is not -1 so 931 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
820 // qs will not be zero. Also, we've already handled the input vectors being zero so the 932 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
821 // crossProduct vector should also not be zero. 933 }
822 rotBetween.x = rotBetween.x / mag; 934 else // other rotation
823 rotBetween.y = rotBetween.y / mag; 935 {
824 rotBetween.z = rotBetween.z / mag; 936 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
825 rotBetween.s = rotBetween.s / mag; 937 axis = llVecNorm(axis);
826 // Check for undefined values and set zero rotation if any found. This code might not actually be required 938 double x, y, z, s, t;
827 // any longer since zero vectors are checked for at the top. 939 s = Math.Cos(theta);
828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 940 t = Math.Sin(theta);
829 { 941 x = axis.x * t;
830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 942 y = axis.y * t;
831 } 943 z = axis.z * t;
832 } 944 return new LSL_Rotation(x,y,z,s);
833 } 945 }
834 return rotBetween; 946 }
835 } 947
836
837 public void llWhisper(int channelID, string text) 948 public void llWhisper(int channelID, string text)
838 { 949 {
839 m_host.AddScriptLPS(1); 950 m_host.AddScriptLPS(1);
@@ -849,10 +960,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 960 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
850 } 961 }
851 962
963 private void CheckSayShoutTime()
964 {
965 DateTime now = DateTime.UtcNow;
966 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
967 {
968 m_lastSayShoutCheck = now;
969 m_SayShoutCount = 0;
970 }
971 else
972 m_SayShoutCount++;
973 }
974
852 public void llSay(int channelID, string text) 975 public void llSay(int channelID, string text)
853 { 976 {
854 m_host.AddScriptLPS(1); 977 m_host.AddScriptLPS(1);
855 978
979 if (channelID == 0)
980// m_SayShoutCount++;
981 CheckSayShoutTime();
982
983 if (m_SayShoutCount >= 11)
984 ScriptSleep(2000);
985
856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 986 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
857 { 987 {
858 Console.WriteLine(text); 988 Console.WriteLine(text);
@@ -875,6 +1005,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 { 1005 {
876 m_host.AddScriptLPS(1); 1006 m_host.AddScriptLPS(1);
877 1007
1008 if (channelID == 0)
1009// m_SayShoutCount++;
1010 CheckSayShoutTime();
1011
1012 if (m_SayShoutCount >= 11)
1013 ScriptSleep(2000);
1014
878 if (text.Length > 1023) 1015 if (text.Length > 1023)
879 text = text.Substring(0, 1023); 1016 text = text.Substring(0, 1023);
880 1017
@@ -906,22 +1043,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
906 1043
907 public void llRegionSayTo(string target, int channel, string msg) 1044 public void llRegionSayTo(string target, int channel, string msg)
908 { 1045 {
1046 string error = String.Empty;
1047
909 if (msg.Length > 1023) 1048 if (msg.Length > 1023)
910 msg = msg.Substring(0, 1023); 1049 msg = msg.Substring(0, 1023);
911 1050
912 m_host.AddScriptLPS(1); 1051 m_host.AddScriptLPS(1);
913 1052
914 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
915 {
916 return;
917 }
918
919 UUID TargetID; 1053 UUID TargetID;
920 UUID.TryParse(target, out TargetID); 1054 UUID.TryParse(target, out TargetID);
921 1055
922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1056 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
923 if (wComm != null) 1057 if (wComm != null)
924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1058 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1059 LSLError(error);
925 } 1060 }
926 1061
927 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1062 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1177,10 +1312,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 return detectedParams.TouchUV; 1312 return detectedParams.TouchUV;
1178 } 1313 }
1179 1314
1315 [DebuggerNonUserCode]
1180 public virtual void llDie() 1316 public virtual void llDie()
1181 { 1317 {
1182 m_host.AddScriptLPS(1); 1318 m_host.AddScriptLPS(1);
1183 throw new SelfDeleteException(); 1319 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1184 } 1320 }
1185 1321
1186 public LSL_Float llGround(LSL_Vector offset) 1322 public LSL_Float llGround(LSL_Vector offset)
@@ -1251,6 +1387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1251 1387
1252 public void llSetStatus(int status, int value) 1388 public void llSetStatus(int status, int value)
1253 { 1389 {
1390 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1391 return;
1254 m_host.AddScriptLPS(1); 1392 m_host.AddScriptLPS(1);
1255 1393
1256 int statusrotationaxis = 0; 1394 int statusrotationaxis = 0;
@@ -1274,6 +1412,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1274 if (!allow) 1412 if (!allow)
1275 return; 1413 return;
1276 1414
1415 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1416 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1417 return;
1418
1277 m_host.ScriptSetPhysicsStatus(true); 1419 m_host.ScriptSetPhysicsStatus(true);
1278 } 1420 }
1279 else 1421 else
@@ -1474,6 +1616,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1474 { 1616 {
1475 m_host.AddScriptLPS(1); 1617 m_host.AddScriptLPS(1);
1476 1618
1619 SetColor(m_host, color, face);
1620 }
1621
1622 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1623 {
1624 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1625 return;
1626
1627 Primitive.TextureEntry tex = part.Shape.Textures;
1628 Color4 texcolor;
1629 if (face >= 0 && face < GetNumberOfSides(part))
1630 {
1631 texcolor = tex.CreateFace((uint)face).RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.FaceTextures[face].RGBA = texcolor;
1636 part.UpdateTextureEntry(tex.GetBytes());
1637 return;
1638 }
1639 else if (face == ScriptBaseClass.ALL_SIDES)
1640 {
1641 for (uint i = 0; i < GetNumberOfSides(part); i++)
1642 {
1643 if (tex.FaceTextures[i] != null)
1644 {
1645 texcolor = tex.FaceTextures[i].RGBA;
1646 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1647 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1648 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1649 tex.FaceTextures[i].RGBA = texcolor;
1650 }
1651 texcolor = tex.DefaultTexture.RGBA;
1652 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1653 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1654 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1655 tex.DefaultTexture.RGBA = texcolor;
1656 }
1657 part.UpdateTextureEntry(tex.GetBytes());
1658 return;
1659 }
1660
1477 if (face == ScriptBaseClass.ALL_SIDES) 1661 if (face == ScriptBaseClass.ALL_SIDES)
1478 face = SceneObjectPart.ALL_SIDES; 1662 face = SceneObjectPart.ALL_SIDES;
1479 1663
@@ -1482,6 +1666,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1482 1666
1483 public void SetTexGen(SceneObjectPart part, int face,int style) 1667 public void SetTexGen(SceneObjectPart part, int face,int style)
1484 { 1668 {
1669 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1670 return;
1671
1485 Primitive.TextureEntry tex = part.Shape.Textures; 1672 Primitive.TextureEntry tex = part.Shape.Textures;
1486 MappingType textype; 1673 MappingType textype;
1487 textype = MappingType.Default; 1674 textype = MappingType.Default;
@@ -1512,6 +1699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1512 1699
1513 public void SetGlow(SceneObjectPart part, int face, float glow) 1700 public void SetGlow(SceneObjectPart part, int face, float glow)
1514 { 1701 {
1702 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1703 return;
1704
1515 Primitive.TextureEntry tex = part.Shape.Textures; 1705 Primitive.TextureEntry tex = part.Shape.Textures;
1516 if (face >= 0 && face < GetNumberOfSides(part)) 1706 if (face >= 0 && face < GetNumberOfSides(part))
1517 { 1707 {
@@ -1537,6 +1727,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1537 1727
1538 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1728 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1539 { 1729 {
1730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1731 return;
1540 1732
1541 Shininess sval = new Shininess(); 1733 Shininess sval = new Shininess();
1542 1734
@@ -1587,6 +1779,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1587 1779
1588 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1780 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1589 { 1781 {
1782 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1783 return;
1784
1590 Primitive.TextureEntry tex = part.Shape.Textures; 1785 Primitive.TextureEntry tex = part.Shape.Textures;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1786 if (face >= 0 && face < GetNumberOfSides(part))
1592 { 1787 {
@@ -1647,13 +1842,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1647 m_host.AddScriptLPS(1); 1842 m_host.AddScriptLPS(1);
1648 1843
1649 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1844 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1650 1845 if (parts.Count > 0)
1651 foreach (SceneObjectPart part in parts) 1846 {
1652 SetAlpha(part, alpha, face); 1847 try
1848 {
1849 foreach (SceneObjectPart part in parts)
1850 SetAlpha(part, alpha, face);
1851 }
1852 finally
1853 {
1854 }
1855 }
1653 } 1856 }
1654 1857
1655 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1858 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1656 { 1859 {
1860 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1861 return;
1862
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1863 Primitive.TextureEntry tex = part.Shape.Textures;
1658 Color4 texcolor; 1864 Color4 texcolor;
1659 if (face >= 0 && face < GetNumberOfSides(part)) 1865 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1706,7 +1912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1706 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1912 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1707 float wind, float tension, LSL_Vector Force) 1913 float wind, float tension, LSL_Vector Force)
1708 { 1914 {
1709 if (part == null) 1915 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1710 return; 1916 return;
1711 1917
1712 if (flexi) 1918 if (flexi)
@@ -1747,7 +1953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1747 /// <param name="falloff"></param> 1953 /// <param name="falloff"></param>
1748 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1954 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1749 { 1955 {
1750 if (part == null) 1956 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1751 return; 1957 return;
1752 1958
1753 if (light) 1959 if (light)
@@ -1780,11 +1986,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1780 Primitive.TextureEntry tex = part.Shape.Textures; 1986 Primitive.TextureEntry tex = part.Shape.Textures;
1781 Color4 texcolor; 1987 Color4 texcolor;
1782 LSL_Vector rgb = new LSL_Vector(); 1988 LSL_Vector rgb = new LSL_Vector();
1989 int nsides = GetNumberOfSides(part);
1990
1783 if (face == ScriptBaseClass.ALL_SIDES) 1991 if (face == ScriptBaseClass.ALL_SIDES)
1784 { 1992 {
1785 int i; 1993 int i;
1786 1994 for (i = 0; i < nsides; i++)
1787 for (i = 0 ; i < GetNumberOfSides(part); i++)
1788 { 1995 {
1789 texcolor = tex.GetFace((uint)i).RGBA; 1996 texcolor = tex.GetFace((uint)i).RGBA;
1790 rgb.x += texcolor.R; 1997 rgb.x += texcolor.R;
@@ -1792,14 +1999,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 rgb.z += texcolor.B; 1999 rgb.z += texcolor.B;
1793 } 2000 }
1794 2001
1795 rgb.x /= (float)GetNumberOfSides(part); 2002 float invnsides = 1.0f / (float)nsides;
1796 rgb.y /= (float)GetNumberOfSides(part); 2003
1797 rgb.z /= (float)GetNumberOfSides(part); 2004 rgb.x *= invnsides;
2005 rgb.y *= invnsides;
2006 rgb.z *= invnsides;
1798 2007
1799 return rgb; 2008 return rgb;
1800 } 2009 }
1801 2010 if (face >= 0 && face < nsides)
1802 if (face >= 0 && face < GetNumberOfSides(part))
1803 { 2011 {
1804 texcolor = tex.GetFace((uint)face).RGBA; 2012 texcolor = tex.GetFace((uint)face).RGBA;
1805 rgb.x = texcolor.R; 2013 rgb.x = texcolor.R;
@@ -1826,15 +2034,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1826 m_host.AddScriptLPS(1); 2034 m_host.AddScriptLPS(1);
1827 2035
1828 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2036 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1829 2037 if (parts.Count > 0)
1830 foreach (SceneObjectPart part in parts) 2038 {
1831 SetTexture(part, texture, face); 2039 try
1832 2040 {
2041 foreach (SceneObjectPart part in parts)
2042 SetTexture(part, texture, face);
2043 }
2044 finally
2045 {
2046 }
2047 }
1833 ScriptSleep(200); 2048 ScriptSleep(200);
1834 } 2049 }
1835 2050
1836 protected void SetTexture(SceneObjectPart part, string texture, int face) 2051 protected void SetTexture(SceneObjectPart part, string texture, int face)
1837 { 2052 {
2053 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2054 return;
2055
1838 UUID textureID = new UUID(); 2056 UUID textureID = new UUID();
1839 2057
1840 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2058 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1879,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1879 2097
1880 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2098 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1881 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1882 Primitive.TextureEntry tex = part.Shape.Textures; 2103 Primitive.TextureEntry tex = part.Shape.Textures;
1883 if (face >= 0 && face < GetNumberOfSides(part)) 2104 if (face >= 0 && face < GetNumberOfSides(part))
1884 { 2105 {
@@ -1915,6 +2136,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1915 2136
1916 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2137 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1917 { 2138 {
2139 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2140 return;
2141
1918 Primitive.TextureEntry tex = part.Shape.Textures; 2142 Primitive.TextureEntry tex = part.Shape.Textures;
1919 if (face >= 0 && face < GetNumberOfSides(part)) 2143 if (face >= 0 && face < GetNumberOfSides(part))
1920 { 2144 {
@@ -1951,6 +2175,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1951 2175
1952 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2176 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1953 { 2177 {
2178 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2179 return;
2180
1954 Primitive.TextureEntry tex = part.Shape.Textures; 2181 Primitive.TextureEntry tex = part.Shape.Textures;
1955 if (face >= 0 && face < GetNumberOfSides(part)) 2182 if (face >= 0 && face < GetNumberOfSides(part))
1956 { 2183 {
@@ -2092,7 +2319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2092 return end; 2319 return end;
2093 } 2320 }
2094 2321
2095 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2322 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2096 { 2323 {
2097 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2324 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2098 return fromPos; 2325 return fromPos;
@@ -2108,9 +2335,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2108 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2335 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2109 targetPos.z = ground; 2336 targetPos.z = ground;
2110 } 2337 }
2111 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2338 if (adjust)
2339 return SetPosAdjust(fromPos, targetPos);
2112 2340
2113 return real_vec; 2341 return targetPos;
2114 } 2342 }
2115 2343
2116 /// <summary> 2344 /// <summary>
@@ -2121,27 +2349,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2121 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2349 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2122 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2350 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2123 { 2351 {
2124 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2352 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2353 return;
2354
2125 LSL_Vector currentPos = GetPartLocalPos(part); 2355 LSL_Vector currentPos = GetPartLocalPos(part);
2356 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2126 2357
2127 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2128 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2129 2358
2130 if (part.ParentGroup.RootPart == part) 2359 if (part.ParentGroup.RootPart == part)
2131 { 2360 {
2132 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2133 targetPos.z = ground;
2134 SceneObjectGroup parent = part.ParentGroup; 2361 SceneObjectGroup parent = part.ParentGroup;
2135 parent.UpdateGroupPosition(!adjust ? targetPos : 2362 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2136 SetPosAdjust(currentPos, targetPos)); 2363 return;
2364 Util.FireAndForget(delegate(object x) {
2365 parent.UpdateGroupPosition((Vector3)toPos);
2366 });
2137 } 2367 }
2138 else 2368 else
2139 { 2369 {
2140 part.OffsetPosition = !adjust ? targetPos : 2370 part.OffsetPosition = (Vector3)toPos;
2141 SetPosAdjust(currentPos, targetPos); 2371// SceneObjectGroup parent = part.ParentGroup;
2142 SceneObjectGroup parent = part.ParentGroup; 2372// parent.HasGroupChanged = true;
2143 parent.HasGroupChanged = true; 2373// parent.ScheduleGroupForTerseUpdate();
2144 parent.ScheduleGroupForTerseUpdate(); 2374 part.ScheduleTerseUpdate();
2145 } 2375 }
2146 } 2376 }
2147 2377
@@ -2170,13 +2400,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2170 else 2400 else
2171 { 2401 {
2172 if (part.ParentGroup.IsAttachment) 2402 if (part.ParentGroup.IsAttachment)
2173 {
2174 pos = part.AttachedPos; 2403 pos = part.AttachedPos;
2175 }
2176 else 2404 else
2177 {
2178 pos = part.AbsolutePosition; 2405 pos = part.AbsolutePosition;
2179 }
2180 } 2406 }
2181 2407
2182// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2408// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2188,8 +2414,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 { 2414 {
2189 m_host.AddScriptLPS(1); 2415 m_host.AddScriptLPS(1);
2190 2416
2417
2418 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2419 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2420 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2421 // RootPart != null should shortcircuit
2422
2191 // try to let this work as in SL... 2423 // try to let this work as in SL...
2192 if (m_host.ParentID == 0) 2424 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2193 { 2425 {
2194 // special case: If we are root, rotate complete SOG to new rotation 2426 // special case: If we are root, rotate complete SOG to new rotation
2195 SetRot(m_host, rot); 2427 SetRot(m_host, rot);
@@ -2216,25 +2448,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 2448
2217 protected void SetRot(SceneObjectPart part, Quaternion rot) 2449 protected void SetRot(SceneObjectPart part, Quaternion rot)
2218 { 2450 {
2219 part.UpdateRotation(rot); 2451 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2220 // Update rotation does not move the object in the physics scene if it's a linkset. 2452 return;
2221 2453
2222//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2454 bool isroot = (part == part.ParentGroup.RootPart);
2223// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2455 bool isphys;
2224 2456
2225 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2226 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2227 // It's perfectly okay when the object is not an active physical body though.
2228 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2229 // but only if the object is not physial and active. This is important for rotating doors.
2230 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2231 // scene
2232 PhysicsActor pa = part.PhysActor; 2457 PhysicsActor pa = part.PhysActor;
2233 2458
2234 if (pa != null && !pa.IsPhysical) 2459 // keep using physactor ideia of isphysical
2460 // it should be SOP ideia of that
2461 // not much of a issue with ubitODE
2462 if (pa != null && pa.IsPhysical)
2463 isphys = true;
2464 else
2465 isphys = false;
2466
2467 // SL doesn't let scripts rotate root of physical linksets
2468 if (isroot && isphys)
2469 return;
2470
2471 part.UpdateRotation(rot);
2472
2473 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2474 // so do a nasty update of parts positions if is a root part rotation
2475 if (isroot && pa != null) // with if above implies non physical root part
2235 { 2476 {
2236 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2477 part.ParentGroup.ResetChildPrimPhysicsPositions();
2237 } 2478 }
2479 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2480 {
2481 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2482 if (sittingavas.Count > 0)
2483 {
2484 foreach (ScenePresence av in sittingavas)
2485 {
2486 if (isroot || part.LocalId == av.ParentID)
2487 av.SendTerseUpdateToAllClients();
2488 }
2489 }
2490 }
2238 } 2491 }
2239 2492
2240 /// <summary> 2493 /// <summary>
@@ -2251,6 +2504,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2251 2504
2252 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
2253 Quaternion q = m_host.GetWorldRotation(); 2506 Quaternion q = m_host.GetWorldRotation();
2507
2508 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2509 {
2510 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2511 if (avatar != null)
2512 {
2513 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2514 q = avatar.CameraRotation * q; // Mouselook
2515 else
2516 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2517 }
2518 }
2519
2254 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2520 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2255 } 2521 }
2256 2522
@@ -2278,14 +2544,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2278 return new LSL_Rotation(q); 2544 return new LSL_Rotation(q);
2279 } 2545 }
2280 2546
2281 return new LSL_Rotation(part.GetWorldRotation()); 2547 q = part.GetWorldRotation();
2548 if (part.ParentGroup.AttachmentPoint != 0)
2549 {
2550 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2551 if (avatar != null)
2552 {
2553 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2554 q = avatar.CameraRotation * q; // Mouselook
2555 else
2556 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2557 }
2558 }
2559
2560 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2282 } 2561 }
2283 2562
2284 public LSL_Rotation llGetLocalRot() 2563 public LSL_Rotation llGetLocalRot()
2285 { 2564 {
2286 m_host.AddScriptLPS(1); 2565 return GetPartLocalRot(m_host);
2566 }
2287 2567
2288 return new LSL_Rotation(m_host.RotationOffset); 2568 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2569 {
2570 m_host.AddScriptLPS(1);
2571 Quaternion rot = part.RotationOffset;
2572 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2289 } 2573 }
2290 2574
2291 public void llSetForce(LSL_Vector force, int local) 2575 public void llSetForce(LSL_Vector force, int local)
@@ -2365,16 +2649,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2365 m_host.ApplyImpulse(v, local != 0); 2649 m_host.ApplyImpulse(v, local != 0);
2366 } 2650 }
2367 2651
2652
2368 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2653 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2369 { 2654 {
2370 m_host.AddScriptLPS(1); 2655 m_host.AddScriptLPS(1);
2371 m_host.ApplyAngularImpulse(force, local != 0); 2656 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2372 } 2657 }
2373 2658
2374 public void llSetTorque(LSL_Vector torque, int local) 2659 public void llSetTorque(LSL_Vector torque, int local)
2375 { 2660 {
2376 m_host.AddScriptLPS(1); 2661 m_host.AddScriptLPS(1);
2377 m_host.SetAngularImpulse(torque, local != 0); 2662 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2378 } 2663 }
2379 2664
2380 public LSL_Vector llGetTorque() 2665 public LSL_Vector llGetTorque()
@@ -2391,20 +2676,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2391 llSetTorque(torque, local); 2676 llSetTorque(torque, local);
2392 } 2677 }
2393 2678
2679 public void llSetVelocity(LSL_Vector vel, int local)
2680 {
2681 m_host.AddScriptLPS(1);
2682 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2683 }
2684
2394 public LSL_Vector llGetVel() 2685 public LSL_Vector llGetVel()
2395 { 2686 {
2396 m_host.AddScriptLPS(1); 2687 m_host.AddScriptLPS(1);
2397 2688
2398 Vector3 vel; 2689 Vector3 vel = Vector3.Zero;
2399 2690
2400 if (m_host.ParentGroup.IsAttachment) 2691 if (m_host.ParentGroup.IsAttachment)
2401 { 2692 {
2402 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2693 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2403 vel = avatar.Velocity; 2694 if (avatar != null)
2695 vel = avatar.Velocity;
2404 } 2696 }
2405 else 2697 else
2406 { 2698 {
2407 vel = m_host.Velocity; 2699 vel = m_host.ParentGroup.RootPart.Velocity;
2408 } 2700 }
2409 2701
2410 return new LSL_Vector(vel); 2702 return new LSL_Vector(vel);
@@ -2417,11 +2709,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2417 return new LSL_Vector(m_host.Acceleration); 2709 return new LSL_Vector(m_host.Acceleration);
2418 } 2710 }
2419 2711
2420 public LSL_Vector llGetOmega() 2712 public void llSetAngularVelocity(LSL_Vector avel, int local)
2421 { 2713 {
2422 m_host.AddScriptLPS(1); 2714 m_host.AddScriptLPS(1);
2715 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2716 }
2423 2717
2424 return new LSL_Vector(m_host.AngularVelocity); 2718 public LSL_Vector llGetOmega()
2719 {
2720 m_host.AddScriptLPS(1);
2721 Vector3 avel = m_host.AngularVelocity;
2722 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2425 } 2723 }
2426 2724
2427 public LSL_Float llGetTimeOfDay() 2725 public LSL_Float llGetTimeOfDay()
@@ -2782,7 +3080,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2782 return src.ToLower(); 3080 return src.ToLower();
2783 } 3081 }
2784 3082
2785 public void llGiveMoney(string destination, int amount) 3083 public LSL_Integer llGiveMoney(string destination, int amount)
2786 { 3084 {
2787 Util.FireAndForget(x => 3085 Util.FireAndForget(x =>
2788 { 3086 {
@@ -2814,8 +3112,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2814 } 3112 }
2815 3113
2816 money.ObjectGiveMoney( 3114 money.ObjectGiveMoney(
2817 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3115 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2818 }); 3116 });
3117
3118 return 0;
2819 } 3119 }
2820 3120
2821 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3121 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2894,13 +3194,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2894 new_group.RootPart.UUID.ToString()) }, 3194 new_group.RootPart.UUID.ToString()) },
2895 new DetectParams[0])); 3195 new DetectParams[0]));
2896 3196
2897 float groupmass = new_group.GetMass(); 3197 // do recoil
3198 SceneObjectGroup hostgrp = m_host.ParentGroup;
3199 if (hostgrp == null)
3200 return;
3201
3202 if (hostgrp.IsAttachment) // don't recoil avatars
3203 return;
2898 3204
2899 PhysicsActor pa = new_group.RootPart.PhysActor; 3205 PhysicsActor pa = new_group.RootPart.PhysActor;
2900 3206
2901 //Recoil. 3207 //Recoil.
2902 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3208 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2903 { 3209 {
3210 float groupmass = new_group.GetMass();
2904 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3211 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2905 if (recoil != Vector3.Zero) 3212 if (recoil != Vector3.Zero)
2906 { 3213 {
@@ -2908,6 +3215,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2908 } 3215 }
2909 } 3216 }
2910 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3217 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3218 return;
3219
2911 }); 3220 });
2912 3221
2913 //ScriptSleep((int)((groupmass * velmag) / 10)); 3222 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2922,35 +3231,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2922 public void llLookAt(LSL_Vector target, double strength, double damping) 3231 public void llLookAt(LSL_Vector target, double strength, double damping)
2923 { 3232 {
2924 m_host.AddScriptLPS(1); 3233 m_host.AddScriptLPS(1);
2925 // Determine where we are looking from
2926 LSL_Vector from = llGetPos();
2927 3234
2928 // Work out the normalised vector from the source to the target 3235 // Get the normalized vector to the target
2929 LSL_Vector delta = llVecNorm(target - from); 3236 LSL_Vector d1 = llVecNorm(target - llGetPos());
2930 LSL_Vector angle = new LSL_Vector(0,0,0);
2931 3237
2932 // Calculate the yaw 3238 // Get the bearing (yaw)
2933 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3239 LSL_Vector a1 = new LSL_Vector(0,0,0);
2934 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3240 a1.z = llAtan2(d1.y, d1.x);
2935 3241
2936 // Calculate pitch 3242 // Get the elevation (pitch)
2937 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3243 LSL_Vector a2 = new LSL_Vector(0,0,0);
3244 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2938 3245
2939 // we need to convert from a vector describing 3246 LSL_Rotation r1 = llEuler2Rot(a1);
2940 // the angles of rotation in radians into rotation value 3247 LSL_Rotation r2 = llEuler2Rot(a2);
2941 LSL_Rotation rot = llEuler2Rot(angle); 3248 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2942
2943 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2944 // set the rotation of the object, copy that behavior
2945 PhysicsActor pa = m_host.PhysActor;
2946 3249
2947 if (strength == 0 || pa == null || !pa.IsPhysical) 3250 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2948 { 3251 {
2949 llSetRot(rot); 3252 // Do nothing if either value is 0 (this has been checked in SL)
3253 if (strength <= 0.0 || damping <= 0.0)
3254 return;
3255
3256 llSetRot(r3 * r2 * r1);
2950 } 3257 }
2951 else 3258 else
2952 { 3259 {
2953 m_host.StartLookAt(rot, (float)strength, (float)damping); 3260 if (strength == 0)
3261 {
3262 llSetRot(r3 * r2 * r1);
3263 return;
3264 }
3265
3266 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2954 } 3267 }
2955 } 3268 }
2956 3269
@@ -2997,17 +3310,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2997 } 3310 }
2998 else 3311 else
2999 { 3312 {
3000 if (m_host.IsRoot) 3313 // new SL always returns object mass
3001 { 3314// if (m_host.IsRoot)
3315// {
3002 return m_host.ParentGroup.GetMass(); 3316 return m_host.ParentGroup.GetMass();
3003 } 3317// }
3004 else 3318// else
3005 { 3319// {
3006 return m_host.GetMass(); 3320// return m_host.GetMass();
3007 } 3321// }
3008 } 3322 }
3009 } 3323 }
3010 3324
3325
3326 public LSL_Float llGetMassMKS()
3327 {
3328 return 100f * llGetMass();
3329 }
3330
3011 public void llCollisionFilter(string name, string id, int accept) 3331 public void llCollisionFilter(string name, string id, int accept)
3012 { 3332 {
3013 m_host.AddScriptLPS(1); 3333 m_host.AddScriptLPS(1);
@@ -3055,8 +3375,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3055 { 3375 {
3056 // Unregister controls from Presence 3376 // Unregister controls from Presence
3057 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3377 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3058 // Remove Take Control permission.
3059 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3060 } 3378 }
3061 } 3379 }
3062 } 3380 }
@@ -3084,7 +3402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3084 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3402 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3085 3403
3086 if (attachmentsModule != null) 3404 if (attachmentsModule != null)
3087 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3405 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3088 else 3406 else
3089 return false; 3407 return false;
3090 } 3408 }
@@ -3114,9 +3432,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3114 { 3432 {
3115 m_host.AddScriptLPS(1); 3433 m_host.AddScriptLPS(1);
3116 3434
3117// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3118// return;
3119
3120 if (m_item.PermsGranter != m_host.OwnerID) 3435 if (m_item.PermsGranter != m_host.OwnerID)
3121 return; 3436 return;
3122 3437
@@ -3159,6 +3474,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3159 3474
3160 public void llInstantMessage(string user, string message) 3475 public void llInstantMessage(string user, string message)
3161 { 3476 {
3477 UUID result;
3478 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3479 {
3480 ShoutError("An invalid key was passed to llInstantMessage");
3481 ScriptSleep(2000);
3482 return;
3483 }
3484
3485
3162 m_host.AddScriptLPS(1); 3486 m_host.AddScriptLPS(1);
3163 3487
3164 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3488 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3173,14 +3497,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3173 UUID friendTransactionID = UUID.Random(); 3497 UUID friendTransactionID = UUID.Random();
3174 3498
3175 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3499 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3176 3500
3177 GridInstantMessage msg = new GridInstantMessage(); 3501 GridInstantMessage msg = new GridInstantMessage();
3178 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3502 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3179 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3503 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3180 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3504 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3181// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3505// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3182// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3506// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3183 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3507// DateTime dt = DateTime.UtcNow;
3508//
3509// // Ticks from UtcNow, but make it look like local. Evil, huh?
3510// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3511//
3512// try
3513// {
3514// // Convert that to the PST timezone
3515// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3516// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3517// }
3518// catch
3519// {
3520// // No logging here, as it could be VERY spammy
3521// }
3522//
3523// // And make it look local again to fool the unix time util
3524// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3525
3526 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3527
3184 //if (client != null) 3528 //if (client != null)
3185 //{ 3529 //{
3186 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3530 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3194,10 +3538,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3194 msg.message = message.Substring(0, 1024); 3538 msg.message = message.Substring(0, 1024);
3195 else 3539 else
3196 msg.message = message; 3540 msg.message = message;
3197 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3541 msg.dialog = (byte)19; // MessageFromObject
3198 msg.fromGroup = false;// fromGroup; 3542 msg.fromGroup = false;// fromGroup;
3199 msg.offline = (byte)0; //offline; 3543 msg.offline = (byte)0; //offline;
3200 msg.ParentEstateID = 0; //ParentEstateID; 3544 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3201 msg.Position = new Vector3(m_host.AbsolutePosition); 3545 msg.Position = new Vector3(m_host.AbsolutePosition);
3202 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3546 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3203 3547
@@ -3229,7 +3573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3229 } 3573 }
3230 3574
3231 emailModule.SendEmail(m_host.UUID, address, subject, message); 3575 emailModule.SendEmail(m_host.UUID, address, subject, message);
3232 llSleep(EMAIL_PAUSE_TIME); 3576 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3233 } 3577 }
3234 3578
3235 public void llGetNextEmail(string address, string subject) 3579 public void llGetNextEmail(string address, string subject)
@@ -3475,7 +3819,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3475 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3819 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3476 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3820 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3477 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3821 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3822 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3478 ScriptBaseClass.PERMISSION_ATTACH; 3823 ScriptBaseClass.PERMISSION_ATTACH;
3824
3479 } 3825 }
3480 else 3826 else
3481 { 3827 {
@@ -3492,15 +3838,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3492 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3838 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3493 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3839 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3494 } 3840 }
3841 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3842 {
3843 implicitPerms = perm;
3844 }
3495 } 3845 }
3496 3846
3497 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3847 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3498 { 3848 {
3499 lock (m_host.TaskInventory) 3849 m_host.TaskInventory.LockItemsForWrite(true);
3500 { 3850 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3501 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3851 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3502 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3852 m_host.TaskInventory.LockItemsForWrite(false);
3503 }
3504 3853
3505 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3854 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3506 "run_time_permissions", new Object[] { 3855 "run_time_permissions", new Object[] {
@@ -3543,11 +3892,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3543 3892
3544 if (!m_waitingForScriptAnswer) 3893 if (!m_waitingForScriptAnswer)
3545 { 3894 {
3546 lock (m_host.TaskInventory) 3895 m_host.TaskInventory.LockItemsForWrite(true);
3547 { 3896 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3548 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3897 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3549 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3898 m_host.TaskInventory.LockItemsForWrite(false);
3550 }
3551 3899
3552 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3900 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3553 m_waitingForScriptAnswer=true; 3901 m_waitingForScriptAnswer=true;
@@ -3576,14 +3924,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3576 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3924 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3577 llReleaseControls(); 3925 llReleaseControls();
3578 3926
3579 lock (m_host.TaskInventory) 3927 m_host.TaskInventory.LockItemsForWrite(true);
3580 { 3928 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3581 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3929 m_host.TaskInventory.LockItemsForWrite(false);
3582 } 3930
3583 3931 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3584 m_ScriptEngine.PostScriptEvent( 3932 "run_time_permissions", new Object[] {
3585 m_item.ItemID, 3933 new LSL_Integer(answer) },
3586 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3934 new DetectParams[0]));
3587 } 3935 }
3588 3936
3589 public LSL_String llGetPermissionsKey() 3937 public LSL_String llGetPermissionsKey()
@@ -3622,14 +3970,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3622 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3970 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3623 { 3971 {
3624 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3972 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3625 3973 if (parts.Count > 0)
3626 foreach (SceneObjectPart part in parts) 3974 {
3627 part.SetFaceColorAlpha(face, color, null); 3975 try
3976 {
3977 foreach (SceneObjectPart part in parts)
3978 part.SetFaceColorAlpha(face, color, null);
3979 }
3980 finally
3981 {
3982 }
3983 }
3628 } 3984 }
3629 3985
3630 public void llCreateLink(string target, int parent) 3986 public void llCreateLink(string target, int parent)
3631 { 3987 {
3632 m_host.AddScriptLPS(1); 3988 m_host.AddScriptLPS(1);
3989
3633 UUID targetID; 3990 UUID targetID;
3634 3991
3635 if (!UUID.TryParse(target, out targetID)) 3992 if (!UUID.TryParse(target, out targetID))
@@ -3735,10 +4092,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 // Restructuring Multiple Prims. 4092 // Restructuring Multiple Prims.
3736 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4093 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3737 parts.Remove(parentPrim.RootPart); 4094 parts.Remove(parentPrim.RootPart);
3738 foreach (SceneObjectPart part in parts) 4095 if (parts.Count > 0)
3739 { 4096 {
3740 parentPrim.DelinkFromGroup(part.LocalId, true); 4097 try
4098 {
4099 foreach (SceneObjectPart part in parts)
4100 {
4101 parentPrim.DelinkFromGroup(part.LocalId, true);
4102 }
4103 }
4104 finally
4105 {
4106 }
3741 } 4107 }
4108
3742 parentPrim.HasGroupChanged = true; 4109 parentPrim.HasGroupChanged = true;
3743 parentPrim.ScheduleGroupForFullUpdate(); 4110 parentPrim.ScheduleGroupForFullUpdate();
3744 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4111 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3747,12 +4114,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3747 { 4114 {
3748 SceneObjectPart newRoot = parts[0]; 4115 SceneObjectPart newRoot = parts[0];
3749 parts.Remove(newRoot); 4116 parts.Remove(newRoot);
3750 foreach (SceneObjectPart part in parts) 4117
4118 try
3751 { 4119 {
3752 // Required for linking 4120 foreach (SceneObjectPart part in parts)
3753 part.ClearUpdateSchedule(); 4121 {
3754 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4122 part.ClearUpdateSchedule();
4123 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4124 }
3755 } 4125 }
4126 finally
4127 {
4128 }
4129
4130
3756 newRoot.ParentGroup.HasGroupChanged = true; 4131 newRoot.ParentGroup.HasGroupChanged = true;
3757 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4132 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3758 } 4133 }
@@ -3772,6 +4147,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3772 public void llBreakAllLinks() 4147 public void llBreakAllLinks()
3773 { 4148 {
3774 m_host.AddScriptLPS(1); 4149 m_host.AddScriptLPS(1);
4150
4151 TaskInventoryItem item = m_item;
4152
4153 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4154 && !m_automaticLinkPermission)
4155 {
4156 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4157 return;
4158 }
4159
3775 SceneObjectGroup parentPrim = m_host.ParentGroup; 4160 SceneObjectGroup parentPrim = m_host.ParentGroup;
3776 if (parentPrim.AttachmentPoint != 0) 4161 if (parentPrim.AttachmentPoint != 0)
3777 return; // Fail silently if attached 4162 return; // Fail silently if attached
@@ -3791,13 +4176,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3791 public LSL_String llGetLinkKey(int linknum) 4176 public LSL_String llGetLinkKey(int linknum)
3792 { 4177 {
3793 m_host.AddScriptLPS(1); 4178 m_host.AddScriptLPS(1);
4179 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4180 if (part != null)
4181 {
4182 return part.UUID.ToString();
4183 }
4184 else
4185 {
4186 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4187 {
4188 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3794 4189
3795 ISceneEntity entity = GetLinkEntity(linknum); 4190 if (linknum < 0)
4191 return UUID.Zero.ToString();
3796 4192
3797 if (entity != null) 4193 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3798 return entity.UUID.ToString(); 4194 if (avatars.Count > linknum)
3799 else 4195 {
3800 return ScriptBaseClass.NULL_KEY; 4196 return avatars[linknum].UUID.ToString();
4197 }
4198 }
4199 return UUID.Zero.ToString();
4200 }
3801 } 4201 }
3802 4202
3803 /// <summary> 4203 /// <summary>
@@ -3856,17 +4256,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3856 m_host.AddScriptLPS(1); 4256 m_host.AddScriptLPS(1);
3857 int count = 0; 4257 int count = 0;
3858 4258
3859 lock (m_host.TaskInventory) 4259 m_host.TaskInventory.LockItemsForRead(true);
4260 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3860 { 4261 {
3861 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4262 if (inv.Value.Type == type || type == -1)
3862 { 4263 {
3863 if (inv.Value.Type == type || type == -1) 4264 count = count + 1;
3864 {
3865 count = count + 1;
3866 }
3867 } 4265 }
3868 } 4266 }
3869 4267
4268 m_host.TaskInventory.LockItemsForRead(false);
3870 return count; 4269 return count;
3871 } 4270 }
3872 4271
@@ -3875,16 +4274,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3875 m_host.AddScriptLPS(1); 4274 m_host.AddScriptLPS(1);
3876 ArrayList keys = new ArrayList(); 4275 ArrayList keys = new ArrayList();
3877 4276
3878 lock (m_host.TaskInventory) 4277 m_host.TaskInventory.LockItemsForRead(true);
4278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3879 { 4279 {
3880 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4280 if (inv.Value.Type == type || type == -1)
3881 { 4281 {
3882 if (inv.Value.Type == type || type == -1) 4282 keys.Add(inv.Value.Name);
3883 {
3884 keys.Add(inv.Value.Name);
3885 }
3886 } 4283 }
3887 } 4284 }
4285 m_host.TaskInventory.LockItemsForRead(false);
3888 4286
3889 if (keys.Count == 0) 4287 if (keys.Count == 0)
3890 { 4288 {
@@ -3922,7 +4320,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3922 if (item == null) 4320 if (item == null)
3923 { 4321 {
3924 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4322 llSay(0, String.Format("Could not find object '{0}'", inventory));
3925 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4323 return;
4324// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3926 } 4325 }
3927 4326
3928 UUID objId = item.ItemID; 4327 UUID objId = item.ItemID;
@@ -3950,33 +4349,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3950 return; 4349 return;
3951 } 4350 }
3952 } 4351 }
4352
3953 // destination is an avatar 4353 // destination is an avatar
3954 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4354 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3955 4355
3956 if (agentItem == null) 4356 if (agentItem == null)
3957 return; 4357 return;
3958 4358
3959 if (m_TransferModule != null) 4359 byte[] bucket = new byte[1];
3960 { 4360 bucket[0] = (byte)item.Type;
3961 byte[] bucket = new byte[1]; 4361 //byte[] objBytes = agentItem.ID.GetBytes();
3962 bucket[0] = (byte)item.Type; 4362 //Array.Copy(objBytes, 0, bucket, 1, 16);
3963 4363
3964 GridInstantMessage msg = new GridInstantMessage(World, 4364 GridInstantMessage msg = new GridInstantMessage(World,
3965 m_host.OwnerID, m_host.Name, destId, 4365 m_host.OwnerID, m_host.Name, destId,
3966 (byte)InstantMessageDialog.TaskInventoryOffered, 4366 (byte)InstantMessageDialog.TaskInventoryOffered,
3967 false, item.Name+". "+m_host.Name+" is located at "+ 4367 false, item.Name+". "+m_host.Name+" is located at "+
3968 World.RegionInfo.RegionName+" "+ 4368 World.RegionInfo.RegionName+" "+
3969 m_host.AbsolutePosition.ToString(), 4369 m_host.AbsolutePosition.ToString(),
3970 agentItem.ID, true, m_host.AbsolutePosition, 4370 agentItem.ID, true, m_host.AbsolutePosition,
3971 bucket, true); 4371 bucket, true);
3972 4372
3973 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4373 ScenePresence sp;
3974 }
3975 4374
4375 if (World.TryGetScenePresence(destId, out sp))
4376 {
4377 sp.ControllingClient.SendInstantMessage(msg);
4378 }
4379 else
4380 {
4381 if (m_TransferModule != null)
4382 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4383 }
4384
4385 //This delay should only occur when giving inventory to avatars.
3976 ScriptSleep(3000); 4386 ScriptSleep(3000);
3977 } 4387 }
3978 } 4388 }
3979 4389
4390 [DebuggerNonUserCode]
3980 public void llRemoveInventory(string name) 4391 public void llRemoveInventory(string name)
3981 { 4392 {
3982 m_host.AddScriptLPS(1); 4393 m_host.AddScriptLPS(1);
@@ -4031,109 +4442,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4031 { 4442 {
4032 m_host.AddScriptLPS(1); 4443 m_host.AddScriptLPS(1);
4033 4444
4034 UUID uuid = (UUID)id; 4445 UUID uuid;
4035 PresenceInfo pinfo = null; 4446 if (UUID.TryParse(id, out uuid))
4036 UserAccount account;
4037
4038 UserInfoCacheEntry ce;
4039 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4040 { 4447 {
4041 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4448 PresenceInfo pinfo = null;
4042 if (account == null) 4449 UserAccount account;
4450
4451 UserInfoCacheEntry ce;
4452 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4043 { 4453 {
4044 m_userInfoCache[uuid] = null; // Cache negative 4454 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4045 return UUID.Zero.ToString(); 4455 if (account == null)
4046 } 4456 {
4457 m_userInfoCache[uuid] = null; // Cache negative
4458 return UUID.Zero.ToString();
4459 }
4047 4460
4048 4461
4049 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4462 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4050 if (pinfos != null && pinfos.Length > 0) 4463 if (pinfos != null && pinfos.Length > 0)
4051 {
4052 foreach (PresenceInfo p in pinfos)
4053 { 4464 {
4054 if (p.RegionID != UUID.Zero) 4465 foreach (PresenceInfo p in pinfos)
4055 { 4466 {
4056 pinfo = p; 4467 if (p.RegionID != UUID.Zero)
4468 {
4469 pinfo = p;
4470 }
4057 } 4471 }
4058 } 4472 }
4059 }
4060 4473
4061 ce = new UserInfoCacheEntry(); 4474 ce = new UserInfoCacheEntry();
4062 ce.time = Util.EnvironmentTickCount(); 4475 ce.time = Util.EnvironmentTickCount();
4063 ce.account = account; 4476 ce.account = account;
4064 ce.pinfo = pinfo; 4477 ce.pinfo = pinfo;
4065 } 4478 m_userInfoCache[uuid] = ce;
4066 else 4479 }
4067 { 4480 else
4068 if (ce == null) 4481 {
4069 return UUID.Zero.ToString(); 4482 if (ce == null)
4483 return UUID.Zero.ToString();
4070 4484
4071 account = ce.account; 4485 account = ce.account;
4072 pinfo = ce.pinfo; 4486 pinfo = ce.pinfo;
4073 } 4487 }
4074 4488
4075 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4489 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4076 {
4077 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4078 if (pinfos != null && pinfos.Length > 0)
4079 { 4490 {
4080 foreach (PresenceInfo p in pinfos) 4491 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4492 if (pinfos != null && pinfos.Length > 0)
4081 { 4493 {
4082 if (p.RegionID != UUID.Zero) 4494 foreach (PresenceInfo p in pinfos)
4083 { 4495 {
4084 pinfo = p; 4496 if (p.RegionID != UUID.Zero)
4497 {
4498 pinfo = p;
4499 }
4085 } 4500 }
4086 } 4501 }
4087 } 4502 else
4088 else 4503 pinfo = null;
4089 pinfo = null;
4090 4504
4091 ce.time = Util.EnvironmentTickCount(); 4505 ce.time = Util.EnvironmentTickCount();
4092 ce.pinfo = pinfo; 4506 ce.pinfo = pinfo;
4093 } 4507 }
4094 4508
4095 string reply = String.Empty; 4509 string reply = String.Empty;
4096 4510
4097 switch (data) 4511 switch (data)
4098 { 4512 {
4099 case 1: // DATA_ONLINE (0|1) 4513 case 1: // DATA_ONLINE (0|1)
4100 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4514 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4101 reply = "1"; 4515 reply = "1";
4102 else 4516 else
4103 reply = "0"; 4517 reply = "0";
4104 break; 4518 break;
4105 case 2: // DATA_NAME (First Last) 4519 case 2: // DATA_NAME (First Last)
4106 reply = account.FirstName + " " + account.LastName; 4520 reply = account.FirstName + " " + account.LastName;
4107 break; 4521 break;
4108 case 3: // DATA_BORN (YYYY-MM-DD) 4522 case 3: // DATA_BORN (YYYY-MM-DD)
4109 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4523 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4110 born = born.AddSeconds(account.Created); 4524 born = born.AddSeconds(account.Created);
4111 reply = born.ToString("yyyy-MM-dd"); 4525 reply = born.ToString("yyyy-MM-dd");
4112 break; 4526 break;
4113 case 4: // DATA_RATING (0,0,0,0,0,0) 4527 case 4: // DATA_RATING (0,0,0,0,0,0)
4114 reply = "0,0,0,0,0,0"; 4528 reply = "0,0,0,0,0,0";
4115 break; 4529 break;
4116 case 7: // DATA_USERLEVEL (integer) 4530 case 8: // DATA_PAYINFO (0|1|2|3)
4117 reply = account.UserLevel.ToString(); 4531 reply = "0";
4118 break; 4532 break;
4119 case 8: // DATA_PAYINFO (0|1|2|3) 4533 default:
4120 reply = "0"; 4534 return UUID.Zero.ToString(); // Raise no event
4121 break; 4535 }
4122 default:
4123 return UUID.Zero.ToString(); // Raise no event
4124 }
4125 4536
4126 UUID rq = UUID.Random(); 4537 UUID rq = UUID.Random();
4127 4538
4128 UUID tid = AsyncCommands. 4539 UUID tid = AsyncCommands.
4129 DataserverPlugin.RegisterRequest(m_host.LocalId, 4540 DataserverPlugin.RegisterRequest(m_host.LocalId,
4130 m_item.ItemID, rq.ToString()); 4541 m_item.ItemID, rq.ToString());
4131 4542
4132 AsyncCommands. 4543 AsyncCommands.
4133 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4544 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4134 4545
4135 ScriptSleep(100); 4546 ScriptSleep(100);
4136 return tid.ToString(); 4547 return tid.ToString();
4548 }
4549 else
4550 {
4551 ShoutError("Invalid UUID passed to llRequestAgentData.");
4552 }
4553 return "";
4137 } 4554 }
4138 4555
4139 public LSL_String llRequestInventoryData(string name) 4556 public LSL_String llRequestInventoryData(string name)
@@ -4190,12 +4607,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4190 if (UUID.TryParse(agent, out agentId)) 4607 if (UUID.TryParse(agent, out agentId))
4191 { 4608 {
4192 ScenePresence presence = World.GetScenePresence(agentId); 4609 ScenePresence presence = World.GetScenePresence(agentId);
4193 if (presence != null) 4610 if (presence != null && presence.PresenceType != PresenceType.Npc)
4194 { 4611 {
4612 // agent must not be a god
4613 if (presence.UserLevel >= 200) return;
4614
4195 // agent must be over the owners land 4615 // agent must be over the owners land
4196 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4616 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4197 { 4617 {
4198 World.TeleportClientHome(agentId, presence.ControllingClient); 4618 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4619 {
4620 // They can't be teleported home for some reason
4621 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4622 if (regionInfo != null)
4623 {
4624 World.RequestTeleportLocation(
4625 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4626 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4627 }
4628 }
4199 } 4629 }
4200 } 4630 }
4201 } 4631 }
@@ -4213,20 +4643,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4213 ScenePresence presence = World.GetScenePresence(agentId); 4643 ScenePresence presence = World.GetScenePresence(agentId);
4214 if (presence != null && presence.PresenceType != PresenceType.Npc) 4644 if (presence != null && presence.PresenceType != PresenceType.Npc)
4215 { 4645 {
4216 // agent must not be a god
4217 if (presence.GodLevel >= 200) return;
4218
4219 if (destination == String.Empty) 4646 if (destination == String.Empty)
4220 destination = World.RegionInfo.RegionName; 4647 destination = World.RegionInfo.RegionName;
4221 4648
4222 // agent must be over the owners land 4649 if (m_item.PermsGranter == agentId)
4223 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4650 {
4651 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4652 {
4653 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4654 }
4655 }
4656
4657 // agent must be wearing the object
4658 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4224 { 4659 {
4225 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4660 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4226 } 4661 }
4227 else // or must be wearing the prim 4662 else
4228 { 4663 {
4229 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4664 // agent must not be a god
4665 if (presence.GodLevel >= 200) return;
4666
4667 // agent must be over the owners land
4668 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
4669 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
4670 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4230 { 4671 {
4231 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4672 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4232 } 4673 }
@@ -4240,24 +4681,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4240 m_host.AddScriptLPS(1); 4681 m_host.AddScriptLPS(1);
4241 UUID agentId = new UUID(); 4682 UUID agentId = new UUID();
4242 4683
4243 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4684 ulong regionHandle = Utils.UIntsToLong((uint)(global_coords.x / 256) * 256, (uint)(global_coords.y / 256) * 256);
4244 4685
4245 if (UUID.TryParse(agent, out agentId)) 4686 if (UUID.TryParse(agent, out agentId))
4246 { 4687 {
4688 // This function is owner only!
4689 if (m_host.OwnerID != agentId)
4690 return;
4691
4247 ScenePresence presence = World.GetScenePresence(agentId); 4692 ScenePresence presence = World.GetScenePresence(agentId);
4693
4694 // Can't TP sitting avatars
4695 if (presence.ParentID != 0) // Sitting
4696 return;
4697
4248 if (presence != null && presence.PresenceType != PresenceType.Npc) 4698 if (presence != null && presence.PresenceType != PresenceType.Npc)
4249 { 4699 {
4250 // agent must not be a god 4700 if (m_item.PermsGranter == agentId)
4251 if (presence.GodLevel >= 200) return;
4252
4253 // agent must be over the owners land
4254 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4255 { 4701 {
4256 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4702 // If attached using llAttachToAvatarTemp, cowardly refuse
4257 } 4703 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
4258 else // or must be wearing the prim 4704 return;
4259 { 4705
4260 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4706 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4261 { 4707 {
4262 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4708 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4263 } 4709 }
@@ -4301,7 +4747,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4301 UUID av = new UUID(); 4747 UUID av = new UUID();
4302 if (!UUID.TryParse(agent,out av)) 4748 if (!UUID.TryParse(agent,out av))
4303 { 4749 {
4304 LSLError("First parameter to llDialog needs to be a key");
4305 return; 4750 return;
4306 } 4751 }
4307 4752
@@ -4334,9 +4779,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4334 { 4779 {
4335 m_host.AddScriptLPS(1); 4780 m_host.AddScriptLPS(1);
4336 4781
4782 if(impact_sound == "")
4783 {
4784 m_host.CollisionSoundVolume = (float)impact_volume;
4785 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4786 m_host.CollisionSoundType = 0;
4787 return;
4788 }
4337 // TODO: Parameter check logic required. 4789 // TODO: Parameter check logic required.
4338 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4790 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4339 m_host.CollisionSoundVolume = (float)impact_volume; 4791 m_host.CollisionSoundVolume = (float)impact_volume;
4792 m_host.CollisionSoundType = 1;
4340 } 4793 }
4341 4794
4342 public LSL_String llGetAnimation(string id) 4795 public LSL_String llGetAnimation(string id)
@@ -4350,14 +4803,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4350 4803
4351 if (m_host.RegionHandle == presence.RegionHandle) 4804 if (m_host.RegionHandle == presence.RegionHandle)
4352 { 4805 {
4353 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4354
4355 if (presence != null) 4806 if (presence != null)
4356 { 4807 {
4357 AnimationSet currentAnims = presence.Animator.Animations; 4808 if (presence.SitGround)
4358 string currentAnimationState = String.Empty; 4809 return "Sitting on Ground";
4359 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4810 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4360 return currentAnimationState; 4811 return "Sitting";
4812
4813 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4814 string lslMovementAnimation;
4815
4816 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4817 return lslMovementAnimation;
4361 } 4818 }
4362 } 4819 }
4363 4820
@@ -4505,7 +4962,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4505 { 4962 {
4506 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4963 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4507 float distance_term = distance * distance * distance; // Script Energy 4964 float distance_term = distance * distance * distance; // Script Energy
4508 float pusher_mass = m_host.GetMass(); 4965 // use total object mass and not part
4966 float pusher_mass = m_host.ParentGroup.GetMass();
4509 4967
4510 float PUSH_ATTENUATION_DISTANCE = 17f; 4968 float PUSH_ATTENUATION_DISTANCE = 17f;
4511 float PUSH_ATTENUATION_SCALE = 5f; 4969 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4762,6 +5220,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4762 { 5220 {
4763 return item.AssetID.ToString(); 5221 return item.AssetID.ToString();
4764 } 5222 }
5223 m_host.TaskInventory.LockItemsForRead(false);
4765 5224
4766 return UUID.Zero.ToString(); 5225 return UUID.Zero.ToString();
4767 } 5226 }
@@ -4914,14 +5373,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4914 { 5373 {
4915 m_host.AddScriptLPS(1); 5374 m_host.AddScriptLPS(1);
4916 5375
4917 if (src == null) 5376 return src.Length;
4918 {
4919 return 0;
4920 }
4921 else
4922 {
4923 return src.Length;
4924 }
4925 } 5377 }
4926 5378
4927 public LSL_Integer llList2Integer(LSL_List src, int index) 5379 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4992,7 +5444,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4992 else if (src.Data[index] is LSL_Float) 5444 else if (src.Data[index] is LSL_Float)
4993 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5445 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4994 else if (src.Data[index] is LSL_String) 5446 else if (src.Data[index] is LSL_String)
4995 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5447 {
5448 string str = ((LSL_String) src.Data[index]).m_string;
5449 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5450 if (m != Match.Empty)
5451 {
5452 str = m.Value;
5453 double d = 0.0;
5454 if (!Double.TryParse(str, out d))
5455 return 0.0;
5456
5457 return d;
5458 }
5459 return 0.0;
5460 }
4996 return Convert.ToDouble(src.Data[index]); 5461 return Convert.ToDouble(src.Data[index]);
4997 } 5462 }
4998 catch (FormatException) 5463 catch (FormatException)
@@ -5034,7 +5499,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5034 // for completion and should LSL_Key ever be implemented 5499 // for completion and should LSL_Key ever be implemented
5035 // as it's own struct 5500 // as it's own struct
5036 else if (!(src.Data[index] is LSL_String || 5501 else if (!(src.Data[index] is LSL_String ||
5037 src.Data[index] is LSL_Key)) 5502 src.Data[index] is LSL_Key ||
5503 src.Data[index] is String))
5038 { 5504 {
5039 return ""; 5505 return "";
5040 } 5506 }
@@ -5292,7 +5758,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5292 } 5758 }
5293 } 5759 }
5294 } 5760 }
5295 else { 5761 else
5762 {
5296 object[] array = new object[src.Length]; 5763 object[] array = new object[src.Length];
5297 Array.Copy(src.Data, 0, array, 0, src.Length); 5764 Array.Copy(src.Data, 0, array, 0, src.Length);
5298 result = new LSL_List(array); 5765 result = new LSL_List(array);
@@ -5399,7 +5866,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5399 public LSL_Integer llGetRegionAgentCount() 5866 public LSL_Integer llGetRegionAgentCount()
5400 { 5867 {
5401 m_host.AddScriptLPS(1); 5868 m_host.AddScriptLPS(1);
5402 return new LSL_Integer(World.GetRootAgentCount()); 5869
5870 int count = 0;
5871 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5872 count++;
5873 });
5874
5875 return new LSL_Integer(count);
5403 } 5876 }
5404 5877
5405 public LSL_Vector llGetRegionCorner() 5878 public LSL_Vector llGetRegionCorner()
@@ -5640,6 +6113,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5640 flags |= ScriptBaseClass.AGENT_AWAY; 6113 flags |= ScriptBaseClass.AGENT_AWAY;
5641 } 6114 }
5642 6115
6116 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6117 UUID[] anims = agent.Animator.GetAnimationArray();
6118 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6119 {
6120 flags |= ScriptBaseClass.AGENT_BUSY;
6121 }
6122
5643 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6123 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5644 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6124 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5645 { 6125 {
@@ -5687,6 +6167,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5687 flags |= ScriptBaseClass.AGENT_SITTING; 6167 flags |= ScriptBaseClass.AGENT_SITTING;
5688 } 6168 }
5689 6169
6170 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6171 {
6172 flags |= ScriptBaseClass.AGENT_MALE;
6173 }
6174
5690 return flags; 6175 return flags;
5691 } 6176 }
5692 6177
@@ -5832,9 +6317,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5832 6317
5833 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6318 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5834 6319
5835 foreach (SceneObjectPart part in parts) 6320 try
6321 {
6322 foreach (SceneObjectPart part in parts)
6323 {
6324 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6325 }
6326 }
6327 finally
5836 { 6328 {
5837 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5838 } 6329 }
5839 } 6330 }
5840 6331
@@ -5888,13 +6379,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5888 6379
5889 if (m_host.OwnerID == land.LandData.OwnerID) 6380 if (m_host.OwnerID == land.LandData.OwnerID)
5890 { 6381 {
5891 World.TeleportClientHome(agentID, presence.ControllingClient); 6382 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6383 presence.TeleportWithMomentum(p, null);
6384 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5892 } 6385 }
5893 } 6386 }
5894 } 6387 }
5895 ScriptSleep(5000); 6388 ScriptSleep(5000);
5896 } 6389 }
5897 6390
6391 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6392 {
6393 return ParseString2List(str, separators, in_spacers, false);
6394 }
6395
5898 public LSL_Integer llOverMyLand(string id) 6396 public LSL_Integer llOverMyLand(string id)
5899 { 6397 {
5900 m_host.AddScriptLPS(1); 6398 m_host.AddScriptLPS(1);
@@ -5947,26 +6445,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5947 } 6445 }
5948 else 6446 else
5949 { 6447 {
5950 agentSize = GetAgentSize(avatar); 6448// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6449 Vector3 s = avatar.Appearance.AvatarSize;
6450 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5951 } 6451 }
5952
5953 return agentSize; 6452 return agentSize;
5954 } 6453 }
5955 6454
5956 public LSL_Integer llSameGroup(string agent) 6455 public LSL_Integer llSameGroup(string id)
5957 { 6456 {
5958 m_host.AddScriptLPS(1); 6457 m_host.AddScriptLPS(1);
5959 UUID agentId = new UUID(); 6458 UUID uuid = new UUID();
5960 if (!UUID.TryParse(agent, out agentId)) 6459 if (!UUID.TryParse(id, out uuid))
5961 return new LSL_Integer(0); 6460 return new LSL_Integer(0);
5962 ScenePresence presence = World.GetScenePresence(agentId); 6461
5963 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6462 // Check if it's a group key
5964 return new LSL_Integer(0); 6463 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5965 IClientAPI client = presence.ControllingClient;
5966 if (m_host.GroupID == client.ActiveGroupId)
5967 return new LSL_Integer(1); 6464 return new LSL_Integer(1);
5968 else 6465
6466 // We got passed a UUID.Zero
6467 if (uuid == UUID.Zero)
6468 return new LSL_Integer(0);
6469
6470 // Handle the case where id names an avatar
6471 ScenePresence presence = World.GetScenePresence(uuid);
6472 if (presence != null)
6473 {
6474 if (presence.IsChildAgent)
6475 return new LSL_Integer(0);
6476
6477 IClientAPI client = presence.ControllingClient;
6478 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6479 return new LSL_Integer(1);
6480
6481 return new LSL_Integer(0);
6482 }
6483
6484 // Handle object case
6485 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6486 if (part != null)
6487 {
6488 // This will handle both deed and non-deed and also the no
6489 // group case
6490 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6491 return new LSL_Integer(1);
6492
5969 return new LSL_Integer(0); 6493 return new LSL_Integer(0);
6494 }
6495
6496 return new LSL_Integer(0);
5970 } 6497 }
5971 6498
5972 public void llUnSit(string id) 6499 public void llUnSit(string id)
@@ -6525,6 +7052,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6525 7052
6526 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7053 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6527 { 7054 {
7055 // LSL quaternions can normalize to 0, normal Quaternions can't.
7056 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7057 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7058
6528 part.SitTargetPosition = offset; 7059 part.SitTargetPosition = offset;
6529 part.SitTargetOrientation = rot; 7060 part.SitTargetOrientation = rot;
6530 part.ParentGroup.HasGroupChanged = true; 7061 part.ParentGroup.HasGroupChanged = true;
@@ -6711,30 +7242,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6711 UUID av = new UUID(); 7242 UUID av = new UUID();
6712 if (!UUID.TryParse(avatar,out av)) 7243 if (!UUID.TryParse(avatar,out av))
6713 { 7244 {
6714 LSLError("First parameter to llDialog needs to be a key"); 7245 //LSLError("First parameter to llDialog needs to be a key");
6715 return; 7246 return;
6716 } 7247 }
6717 if (buttons.Length < 1) 7248 if (buttons.Length < 1)
6718 { 7249 {
6719 LSLError("No less than 1 button can be shown"); 7250 buttons.Add("OK");
6720 return;
6721 } 7251 }
6722 if (buttons.Length > 12) 7252 if (buttons.Length > 12)
6723 { 7253 {
6724 LSLError("No more than 12 buttons can be shown"); 7254 ShoutError("button list too long, must be 12 or fewer entries");
6725 return;
6726 } 7255 }
6727 string[] buts = new string[buttons.Length]; 7256 int length = buttons.Length;
6728 for (int i = 0; i < buttons.Length; i++) 7257 if (length > 12)
7258 length = 12;
7259
7260 string[] buts = new string[length];
7261 for (int i = 0; i < length; i++)
6729 { 7262 {
6730 if (buttons.Data[i].ToString() == String.Empty) 7263 if (buttons.Data[i].ToString() == String.Empty)
6731 { 7264 {
6732 LSLError("button label cannot be blank"); 7265 ShoutError("button label cannot be blank");
6733 return; 7266 return;
6734 } 7267 }
6735 if (buttons.Data[i].ToString().Length > 24) 7268 if (buttons.Data[i].ToString().Length > 24)
6736 { 7269 {
6737 LSLError("button label cannot be longer than 24 characters"); 7270 ShoutError("button label cannot be longer than 24 characters");
6738 return; 7271 return;
6739 } 7272 }
6740 buts[i] = buttons.Data[i].ToString(); 7273 buts[i] = buttons.Data[i].ToString();
@@ -6801,9 +7334,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6801 return; 7334 return;
6802 } 7335 }
6803 7336
6804 // the rest of the permission checks are done in RezScript, so check the pin there as well 7337 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6805 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7338 if (dest != null)
7339 {
7340 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7341 {
7342 // the rest of the permission checks are done in RezScript, so check the pin there as well
7343 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6806 7344
7345 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7346 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7347 }
7348 }
6807 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7349 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6808 ScriptSleep(3000); 7350 ScriptSleep(3000);
6809 } 7351 }
@@ -6877,19 +7419,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 public LSL_String llMD5String(string src, int nonce) 7419 public LSL_String llMD5String(string src, int nonce)
6878 { 7420 {
6879 m_host.AddScriptLPS(1); 7421 m_host.AddScriptLPS(1);
6880 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7422 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6881 } 7423 }
6882 7424
6883 public LSL_String llSHA1String(string src) 7425 public LSL_String llSHA1String(string src)
6884 { 7426 {
6885 m_host.AddScriptLPS(1); 7427 m_host.AddScriptLPS(1);
6886 return Util.SHA1Hash(src).ToLower(); 7428 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6887 } 7429 }
6888 7430
6889 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7431 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6890 { 7432 {
6891 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7433 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6892 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7434 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7435 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7436 return shapeBlock;
6893 7437
6894 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7438 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6895 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7439 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6994,6 +7538,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6994 // Prim type box, cylinder and prism. 7538 // Prim type box, cylinder and prism.
6995 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) 7539 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)
6996 { 7540 {
7541 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7542 return;
7543
6997 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7544 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6998 ObjectShapePacket.ObjectDataBlock shapeBlock; 7545 ObjectShapePacket.ObjectDataBlock shapeBlock;
6999 7546
@@ -7047,6 +7594,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7047 // Prim type sphere. 7594 // Prim type sphere.
7048 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7595 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7049 { 7596 {
7597 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7598 return;
7599
7050 ObjectShapePacket.ObjectDataBlock shapeBlock; 7600 ObjectShapePacket.ObjectDataBlock shapeBlock;
7051 7601
7052 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7602 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7088,6 +7638,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7088 // Prim type torus, tube and ring. 7638 // Prim type torus, tube and ring.
7089 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) 7639 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)
7090 { 7640 {
7641 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7642 return;
7643
7091 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7644 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7092 ObjectShapePacket.ObjectDataBlock shapeBlock; 7645 ObjectShapePacket.ObjectDataBlock shapeBlock;
7093 7646
@@ -7223,6 +7776,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7223 // Prim type sculpt. 7776 // Prim type sculpt.
7224 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7777 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7225 { 7778 {
7779 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7780 return;
7781
7226 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7782 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7227 UUID sculptId; 7783 UUID sculptId;
7228 7784
@@ -7245,7 +7801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7245 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7801 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7246 { 7802 {
7247 // default 7803 // default
7248 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7804 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7249 } 7805 }
7250 7806
7251 part.Shape.SetSculptProperties((byte)type, sculptId); 7807 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7262,15 +7818,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7262 ScriptSleep(200); 7818 ScriptSleep(200);
7263 } 7819 }
7264 7820
7265 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7266 {
7267 m_host.AddScriptLPS(1);
7268
7269 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7270
7271 ScriptSleep(200);
7272 }
7273
7274 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7821 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7275 { 7822 {
7276 m_host.AddScriptLPS(1); 7823 m_host.AddScriptLPS(1);
@@ -7278,172 +7825,135 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7278 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7825 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7279 } 7826 }
7280 7827
7281 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7828 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7282 { 7829 {
7283 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7830 List<object> parts = new List<object>();
7831 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7832 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7833 foreach (SceneObjectPart p in prims)
7834 parts.Add(p);
7835 foreach (ScenePresence p in avatars)
7836 parts.Add(p);
7284 7837
7285 LSL_List remaining = null; 7838 LSL_List remaining = null;
7286 uint rulesParsed = 0; 7839 uint rulesParsed = 0;
7287 7840
7288 foreach (SceneObjectPart part in parts) 7841 if (parts.Count > 0)
7289 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7290
7291 while (remaining != null && remaining.Length > 2)
7292 {
7293 linknumber = remaining.GetLSLIntegerItem(0);
7294 rules = remaining.GetSublist(1, -1);
7295 parts = GetLinkParts(linknumber);
7296
7297 foreach (SceneObjectPart part in parts)
7298 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7299 }
7300 }
7301
7302 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7303 {
7304 SceneObjectGroup group = m_host.ParentGroup;
7305
7306 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7307 return;
7308 if (group.IsAttachment)
7309 return;
7310
7311 if (frames.Data.Length > 0) // We are getting a new motion
7312 { 7842 {
7313 if (group.RootPart.KeyframeMotion != null) 7843 foreach (object part in parts)
7314 group.RootPart.KeyframeMotion.Delete();
7315 group.RootPart.KeyframeMotion = null;
7316
7317 int idx = 0;
7318
7319 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7320 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7321
7322 while (idx < options.Data.Length)
7323 { 7844 {
7324 int option = (int)options.GetLSLIntegerItem(idx++); 7845 if (part is SceneObjectPart)
7325 int remain = options.Data.Length - idx; 7846 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7847 else
7848 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7849 }
7326 7850
7327 switch (option) 7851 while ((object)remaining != null && remaining.Length > 2)
7852 {
7853 linknumber = remaining.GetLSLIntegerItem(0);
7854 rules = remaining.GetSublist(1, -1);
7855 parts.Clear();
7856 prims = GetLinkParts(linknumber);
7857 avatars = GetLinkAvatars(linknumber);
7858 foreach (SceneObjectPart p in prims)
7859 parts.Add(p);
7860 foreach (ScenePresence p in avatars)
7861 parts.Add(p);
7862
7863 remaining = null;
7864 foreach (object part in parts)
7328 { 7865 {
7329 case ScriptBaseClass.KFM_MODE: 7866 if (part is SceneObjectPart)
7330 if (remain < 1) 7867 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7331 break; 7868 else
7332 int modeval = (int)options.GetLSLIntegerItem(idx++); 7869 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7333 switch(modeval)
7334 {
7335 case ScriptBaseClass.KFM_FORWARD:
7336 mode = KeyframeMotion.PlayMode.Forward;
7337 break;
7338 case ScriptBaseClass.KFM_REVERSE:
7339 mode = KeyframeMotion.PlayMode.Reverse;
7340 break;
7341 case ScriptBaseClass.KFM_LOOP:
7342 mode = KeyframeMotion.PlayMode.Loop;
7343 break;
7344 case ScriptBaseClass.KFM_PING_PONG:
7345 mode = KeyframeMotion.PlayMode.PingPong;
7346 break;
7347 }
7348 break;
7349 case ScriptBaseClass.KFM_DATA:
7350 if (remain < 1)
7351 break;
7352 int dataval = (int)options.GetLSLIntegerItem(idx++);
7353 data = (KeyframeMotion.DataFormat)dataval;
7354 break;
7355 } 7870 }
7356 } 7871 }
7872 }
7873 }
7357 7874
7358 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); 7875 public LSL_List llGetPhysicsMaterial()
7876 {
7877 LSL_List result = new LSL_List();
7359 7878
7360 idx = 0; 7879 result.Add(new LSL_Float(m_host.GravityModifier));
7880 result.Add(new LSL_Float(m_host.Restitution));
7881 result.Add(new LSL_Float(m_host.Friction));
7882 result.Add(new LSL_Float(m_host.Density));
7361 7883
7362 int elemLength = 2; 7884 return result;
7363 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 7885 }
7364 elemLength = 3;
7365 7886
7366 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 7887 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7367 while (idx < frames.Data.Length) 7888 float material_density, float material_friction,
7368 { 7889 float material_restitution, float material_gravity_modifier)
7369 int remain = frames.Data.Length - idx; 7890 {
7891 ExtraPhysicsData physdata = new ExtraPhysicsData();
7892 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7893 physdata.Density = part.Density;
7894 physdata.Friction = part.Friction;
7895 physdata.Bounce = part.Restitution;
7896 physdata.GravitationModifier = part.GravityModifier;
7370 7897
7371 if (remain < elemLength) 7898 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7372 break; 7899 physdata.Density = material_density;
7900 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7901 physdata.Friction = material_friction;
7902 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7903 physdata.Bounce = material_restitution;
7904 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7905 physdata.GravitationModifier = material_gravity_modifier;
7373 7906
7374 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 7907 part.UpdateExtraPhysics(physdata);
7375 frame.Position = null; 7908 }
7376 frame.Rotation = null;
7377 7909
7378 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 7910 public void llSetPhysicsMaterial(int material_bits,
7379 { 7911 float material_gravity_modifier, float material_restitution,
7380 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); 7912 float material_friction, float material_density)
7381 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); 7913 {
7382 } 7914 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7383 if ((data & KeyframeMotion.DataFormat.Rotation) != 0) 7915 }
7384 {
7385 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7386 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7387 q.Normalize();
7388 frame.Rotation = q;
7389 }
7390 7916
7391 float tempf = (float)frames.GetLSLFloatItem(idx++); 7917 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7392 frame.TimeMS = (int)(tempf * 1000.0f); 7918 {
7919 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7920 llSetLinkPrimitiveParamsFast(linknumber, rules);
7921 ScriptSleep(200);
7922 }
7393 7923
7394 keyframes.Add(frame); 7924 // vector up using libomv (c&p from sop )
7395 } 7925 // vector up rotated by r
7926 private Vector3 Zrot(Quaternion r)
7927 {
7928 double x, y, z, m;
7396 7929
7397 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 7930 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7398 group.RootPart.KeyframeMotion.Start(); 7931 if (Math.Abs(1.0 - m) > 0.000001)
7399 }
7400 else
7401 { 7932 {
7402 if (group.RootPart.KeyframeMotion == null) 7933 m = 1.0 / Math.Sqrt(m);
7403 return; 7934 r.X *= (float)m;
7404 7935 r.Y *= (float)m;
7405 if (options.Data.Length == 0) 7936 r.Z *= (float)m;
7406 { 7937 r.W *= (float)m;
7407 group.RootPart.KeyframeMotion.Stop(); 7938 }
7408 return;
7409 }
7410
7411 int code = (int)options.GetLSLIntegerItem(0);
7412
7413 int idx = 0;
7414 7939
7415 while (idx < options.Data.Length) 7940 x = 2 * (r.X * r.Z + r.Y * r.W);
7416 { 7941 y = 2 * (-r.X * r.W + r.Y * r.Z);
7417 int option = (int)options.GetLSLIntegerItem(idx++); 7942 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7418 int remain = options.Data.Length - idx;
7419 7943
7420 switch (option) 7944 return new Vector3((float)x, (float)y, (float)z);
7421 {
7422 case ScriptBaseClass.KFM_COMMAND:
7423 int cmd = (int)options.GetLSLIntegerItem(idx++);
7424 switch (cmd)
7425 {
7426 case ScriptBaseClass.KFM_CMD_PLAY:
7427 group.RootPart.KeyframeMotion.Start();
7428 break;
7429 case ScriptBaseClass.KFM_CMD_STOP:
7430 group.RootPart.KeyframeMotion.Stop();
7431 break;
7432 case ScriptBaseClass.KFM_CMD_PAUSE:
7433 group.RootPart.KeyframeMotion.Pause();
7434 break;
7435 }
7436 break;
7437 }
7438 }
7439 }
7440 } 7945 }
7441 7946
7442 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7947 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7443 { 7948 {
7949 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7950 return null;
7951
7444 int idx = 0; 7952 int idx = 0;
7445 int idxStart = 0; 7953 int idxStart = 0;
7446 7954
7955 SceneObjectGroup parentgrp = part.ParentGroup;
7956
7447 bool positionChanged = false; 7957 bool positionChanged = false;
7448 LSL_Vector currentPosition = GetPartLocalPos(part); 7958 LSL_Vector currentPosition = GetPartLocalPos(part);
7449 7959
@@ -7468,8 +7978,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7468 return null; 7978 return null;
7469 7979
7470 v=rules.GetVector3Item(idx++); 7980 v=rules.GetVector3Item(idx++);
7981 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7982 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7983 else
7984 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7471 positionChanged = true; 7985 positionChanged = true;
7472 currentPosition = GetSetPosTarget(part, v, currentPosition);
7473 7986
7474 break; 7987 break;
7475 case (int)ScriptBaseClass.PRIM_SIZE: 7988 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7486,7 +7999,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7486 7999
7487 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8000 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7488 // try to let this work as in SL... 8001 // try to let this work as in SL...
7489 if (part.ParentID == 0) 8002 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7490 { 8003 {
7491 // special case: If we are root, rotate complete SOG to new rotation 8004 // special case: If we are root, rotate complete SOG to new rotation
7492 SetRot(part, q); 8005 SetRot(part, q);
@@ -7746,7 +8259,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7746 return null; 8259 return null;
7747 8260
7748 string ph = rules.Data[idx++].ToString(); 8261 string ph = rules.Data[idx++].ToString();
7749 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8262 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7750 8263
7751 break; 8264 break;
7752 8265
@@ -7780,12 +8293,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7780 8293
7781 break; 8294 break;
7782 8295
8296 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8297 if (remain < 5)
8298 return null;
8299
8300 int material_bits = rules.GetLSLIntegerItem(idx++);
8301 float material_density = (float)rules.GetLSLFloatItem(idx++);
8302 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8303 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8304 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8305
8306 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8307
8308 break;
8309
7783 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8310 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7784 if (remain < 1) 8311 if (remain < 1)
7785 return null; 8312 return null;
7786 string temp = rules.Data[idx++].ToString(); 8313 string temp = rules.Data[idx++].ToString();
7787 8314
7788 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8315 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7789 8316
7790 break; 8317 break;
7791 8318
@@ -7859,14 +8386,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7859 if (part.ParentGroup.RootPart == part) 8386 if (part.ParentGroup.RootPart == part)
7860 { 8387 {
7861 SceneObjectGroup parent = part.ParentGroup; 8388 SceneObjectGroup parent = part.ParentGroup;
7862 parent.UpdateGroupPosition(currentPosition); 8389 Util.FireAndForget(delegate(object x) {
8390 parent.UpdateGroupPosition(currentPosition);
8391 });
7863 } 8392 }
7864 else 8393 else
7865 { 8394 {
7866 part.OffsetPosition = currentPosition; 8395 part.OffsetPosition = currentPosition;
7867 SceneObjectGroup parent = part.ParentGroup; 8396// SceneObjectGroup parent = part.ParentGroup;
7868 parent.HasGroupChanged = true; 8397// parent.HasGroupChanged = true;
7869 parent.ScheduleGroupForTerseUpdate(); 8398// parent.ScheduleGroupForTerseUpdate();
8399 part.ScheduleTerseUpdate();
7870 } 8400 }
7871 } 8401 }
7872 } 8402 }
@@ -7904,10 +8434,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7904 8434
7905 public LSL_String llXorBase64Strings(string str1, string str2) 8435 public LSL_String llXorBase64Strings(string str1, string str2)
7906 { 8436 {
7907 m_host.AddScriptLPS(1); 8437 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7908 Deprecated("llXorBase64Strings"); 8438
7909 ScriptSleep(300); 8439 ScriptSleep(300);
7910 return String.Empty; 8440 m_host.AddScriptLPS(1);
8441
8442 if (str1 == String.Empty)
8443 return String.Empty;
8444 if (str2 == String.Empty)
8445 return str1;
8446
8447 int len = str2.Length;
8448 if ((len % 4) != 0) // LL is EVIL!!!!
8449 {
8450 while (str2.EndsWith("="))
8451 str2 = str2.Substring(0, str2.Length - 1);
8452
8453 len = str2.Length;
8454 int mod = len % 4;
8455
8456 if (mod == 1)
8457 str2 = str2.Substring(0, str2.Length - 1);
8458 else if (mod == 2)
8459 str2 += "==";
8460 else if (mod == 3)
8461 str2 += "=";
8462 }
8463
8464 byte[] data1;
8465 byte[] data2;
8466 try
8467 {
8468 data1 = Convert.FromBase64String(str1);
8469 data2 = Convert.FromBase64String(str2);
8470 }
8471 catch (Exception)
8472 {
8473 return new LSL_String(String.Empty);
8474 }
8475
8476 // For cases where the decoded length of s2 is greater
8477 // than the decoded length of s1, simply perform a normal
8478 // decode and XOR
8479 //
8480 if (data2.Length >= data1.Length)
8481 {
8482 for (int pos = 0 ; pos < data1.Length ; pos++ )
8483 data1[pos] ^= data2[pos];
8484
8485 return Convert.ToBase64String(data1);
8486 }
8487
8488 // Remove padding
8489 while (str1.EndsWith("="))
8490 str1 = str1.Substring(0, str1.Length - 1);
8491 while (str2.EndsWith("="))
8492 str2 = str2.Substring(0, str2.Length - 1);
8493
8494 byte[] d1 = new byte[str1.Length];
8495 byte[] d2 = new byte[str2.Length];
8496
8497 for (int i = 0 ; i < str1.Length ; i++)
8498 {
8499 int idx = b64.IndexOf(str1.Substring(i, 1));
8500 if (idx == -1)
8501 idx = 0;
8502 d1[i] = (byte)idx;
8503 }
8504
8505 for (int i = 0 ; i < str2.Length ; i++)
8506 {
8507 int idx = b64.IndexOf(str2.Substring(i, 1));
8508 if (idx == -1)
8509 idx = 0;
8510 d2[i] = (byte)idx;
8511 }
8512
8513 string output = String.Empty;
8514
8515 for (int pos = 0 ; pos < d1.Length ; pos++)
8516 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8517
8518 while (output.Length % 3 > 0)
8519 output += "=";
8520
8521 return output;
7911 } 8522 }
7912 8523
7913 public void llRemoteDataSetRegion() 8524 public void llRemoteDataSetRegion()
@@ -8032,8 +8643,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8032 public LSL_Integer llGetNumberOfPrims() 8643 public LSL_Integer llGetNumberOfPrims()
8033 { 8644 {
8034 m_host.AddScriptLPS(1); 8645 m_host.AddScriptLPS(1);
8035 8646 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
8036 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8647
8648 return m_host.ParentGroup.PrimCount + avatarCount;
8037 } 8649 }
8038 8650
8039 /// <summary> 8651 /// <summary>
@@ -8048,55 +8660,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8048 m_host.AddScriptLPS(1); 8660 m_host.AddScriptLPS(1);
8049 UUID objID = UUID.Zero; 8661 UUID objID = UUID.Zero;
8050 LSL_List result = new LSL_List(); 8662 LSL_List result = new LSL_List();
8663
8664 // If the ID is not valid, return null result
8051 if (!UUID.TryParse(obj, out objID)) 8665 if (!UUID.TryParse(obj, out objID))
8052 { 8666 {
8053 result.Add(new LSL_Vector()); 8667 result.Add(new LSL_Vector());
8054 result.Add(new LSL_Vector()); 8668 result.Add(new LSL_Vector());
8055 return result; 8669 return result;
8056 } 8670 }
8671
8672 // Check if this is an attached prim. If so, replace
8673 // the UUID with the avatar UUID and report it's bounding box
8674 SceneObjectPart part = World.GetSceneObjectPart(objID);
8675 if (part != null && part.ParentGroup.IsAttachment)
8676 objID = part.ParentGroup.AttachedAvatar;
8677
8678 // Find out if this is an avatar ID. If so, return it's box
8057 ScenePresence presence = World.GetScenePresence(objID); 8679 ScenePresence presence = World.GetScenePresence(objID);
8058 if (presence != null) 8680 if (presence != null)
8059 { 8681 {
8060 if (presence.ParentID == 0) // not sat on an object 8682 // As per LSL Wiki, there is no difference between sitting
8683 // and standing avatar since server 1.36
8684 LSL_Vector lower;
8685 LSL_Vector upper;
8686
8687 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8688
8689 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8690 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8691/*
8061 { 8692 {
8062 LSL_Vector lower; 8693 // This is for ground sitting avatars
8063 LSL_Vector upper; 8694 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8064 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8695 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8065 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8696 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8066 { 8697 }
8067 // This is for ground sitting avatars 8698 else
8068 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8699 {
8069 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8700 // This is for standing/flying avatars
8070 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8701 float height = presence.Appearance.AvatarHeight / 2.0f;
8071 } 8702 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8072 else 8703 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8073 { 8704 }
8074 // This is for standing/flying avatars 8705
8075 float height = presence.Appearance.AvatarHeight / 2.0f; 8706 // Adjust to the documented error offsets (see LSL Wiki)
8076 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8707 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8077 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8708 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8078 } 8709*/
8079 result.Add(lower); 8710 {
8080 result.Add(upper); 8711 // This is for ground sitting avatars TODO!
8081 return result; 8712 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8713 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8082 } 8714 }
8083 else 8715 else
8084 { 8716 {
8085 // sitting on an object so we need the bounding box of that 8717 // This is for standing/flying avatars
8086 // which should include the avatar so set the UUID to the 8718 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8087 // UUID of the object the avatar is sat on and allow it to fall through 8719 upper = new LSL_Vector(box.X, box.Y, box.Z);
8088 // to processing an object
8089 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
8090 objID = p.UUID;
8091 } 8720 }
8721
8722 if (lower.x > upper.x)
8723 lower.x = upper.x;
8724 if (lower.y > upper.y)
8725 lower.y = upper.y;
8726 if (lower.z > upper.z)
8727 lower.z = upper.z;
8728
8729 result.Add(lower);
8730 result.Add(upper);
8731 return result;
8092 } 8732 }
8093 SceneObjectPart part = World.GetSceneObjectPart(objID); 8733
8734 part = World.GetSceneObjectPart(objID);
8094 // Currently only works for single prims without a sitting avatar 8735 // Currently only works for single prims without a sitting avatar
8095 if (part != null) 8736 if (part != null)
8096 { 8737 {
8097 Vector3 halfSize = part.Scale / 2.0f; 8738 float minX;
8098 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8739 float maxX;
8099 LSL_Vector upper = new LSL_Vector(halfSize); 8740 float minY;
8741 float maxY;
8742 float minZ;
8743 float maxZ;
8744
8745 // This BBox is in sim coordinates, with the offset being
8746 // a contained point.
8747 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8748 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8749
8750 minX -= offsets[0].X;
8751 maxX -= offsets[0].X;
8752 minY -= offsets[0].Y;
8753 maxY -= offsets[0].Y;
8754 minZ -= offsets[0].Z;
8755 maxZ -= offsets[0].Z;
8756
8757 LSL_Vector lower;
8758 LSL_Vector upper;
8759
8760 // Adjust to the documented error offsets (see LSL Wiki)
8761 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8762 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8763
8764 if (lower.x > upper.x)
8765 lower.x = upper.x;
8766 if (lower.y > upper.y)
8767 lower.y = upper.y;
8768 if (lower.z > upper.z)
8769 lower.z = upper.z;
8770
8100 result.Add(lower); 8771 result.Add(lower);
8101 result.Add(upper); 8772 result.Add(upper);
8102 return result; 8773 return result;
@@ -8113,224 +8784,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8113 return new LSL_Vector(m_host.GetGeometricCenter()); 8784 return new LSL_Vector(m_host.GetGeometricCenter());
8114 } 8785 }
8115 8786
8116 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8787 public LSL_List llGetPrimitiveParams(LSL_List rules)
8117 { 8788 {
8118 LSL_List result = new LSL_List(); 8789 m_host.AddScriptLPS(1);
8119 LSL_List remaining = null;
8120 8790
8121 while (true) 8791 LSL_List result = new LSL_List();
8122 {
8123 if (entity is SceneObjectPart)
8124 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
8125 else
8126 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
8127 8792
8128 if (remaining == null || remaining.Length <= 2) 8793 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8129 return result;
8130 8794
8795 while ((object)remaining != null && remaining.Length > 2)
8796 {
8131 int linknumber = remaining.GetLSLIntegerItem(0); 8797 int linknumber = remaining.GetLSLIntegerItem(0);
8132 rules = remaining.GetSublist(1, -1); 8798 rules = remaining.GetSublist(1, -1);
8133 entity = GetLinkEntity(linknumber); 8799 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8134 }
8135 }
8136 8800
8137 public LSL_List llGetPrimitiveParams(LSL_List rules) 8801 foreach (SceneObjectPart part in parts)
8138 { 8802 remaining = GetPrimParams(part, rules, ref result);
8139 m_host.AddScriptLPS(1); 8803 }
8140 8804
8141 return GetEntityParams(m_host, rules); 8805 return result;
8142 } 8806 }
8143 8807
8144 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8808 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8145 { 8809 {
8146 m_host.AddScriptLPS(1); 8810 m_host.AddScriptLPS(1);
8147 8811
8148 return GetEntityParams(GetLinkEntity(linknumber), rules); 8812 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8149 } 8813 // keep other options as before
8150 8814
8151 public LSL_Vector GetAgentSize(ScenePresence sp) 8815 List<SceneObjectPart> parts;
8152 { 8816 List<ScenePresence> avatars;
8153 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8817
8154 } 8818 LSL_List res = new LSL_List();
8819 LSL_List remaining = null;
8155 8820
8156 /// <summary> 8821 while (rules.Length > 0)
8157 /// Gets params for a seated avatar in a linkset.
8158 /// </summary>
8159 /// <returns></returns>
8160 /// <param name='sp'></param>
8161 /// <param name='rules'></param>
8162 /// <param name='res'></param>
8163 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8164 {
8165 int idx = 0;
8166 while (idx < rules.Length)
8167 { 8822 {
8168 int code = (int)rules.GetLSLIntegerItem(idx++); 8823 parts = GetLinkParts(linknumber);
8169 int remain = rules.Length-idx; 8824 avatars = GetLinkAvatars(linknumber);
8170 8825
8171 switch (code) 8826 remaining = null;
8827 foreach (SceneObjectPart part in parts)
8172 { 8828 {
8173 case (int)ScriptBaseClass.PRIM_MATERIAL: 8829 remaining = GetPrimParams(part, rules, ref res);
8174 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8830 }
8175 break; 8831 foreach (ScenePresence avatar in avatars)
8176 8832 {
8177 case (int)ScriptBaseClass.PRIM_PHYSICS: 8833 remaining = GetPrimParams(avatar, rules, ref res);
8178 res.Add(ScriptBaseClass.FALSE); 8834 }
8179 break;
8180
8181 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8182 res.Add(ScriptBaseClass.FALSE);
8183 break;
8184
8185 case (int)ScriptBaseClass.PRIM_PHANTOM:
8186 res.Add(ScriptBaseClass.FALSE);
8187 break;
8188
8189 case (int)ScriptBaseClass.PRIM_POSITION:
8190 res.Add(new LSL_Vector(sp.AbsolutePosition));
8191 break;
8192
8193 case (int)ScriptBaseClass.PRIM_SIZE:
8194 res.Add(GetAgentSize(sp));
8195 break;
8196
8197 case (int)ScriptBaseClass.PRIM_ROTATION:
8198 res.Add(sp.GetWorldRotation());
8199 break;
8200
8201 case (int)ScriptBaseClass.PRIM_TYPE:
8202 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8203 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8204 res.Add(new LSL_Vector(0, 1, 0));
8205 res.Add(new LSL_Float(0));
8206 res.Add(new LSL_Vector(0, 0, 0));
8207 res.Add(new LSL_Vector(1, 1, 0));
8208 res.Add(new LSL_Vector(0, 0, 0));
8209 break;
8210
8211 case (int)ScriptBaseClass.PRIM_TEXTURE:
8212 if (remain < 1)
8213 return null;
8214
8215 int face = (int)rules.GetLSLIntegerItem(idx++);
8216 if (face > 21)
8217 break;
8218
8219 res.Add(new LSL_String(""));
8220 res.Add(ScriptBaseClass.ZERO_VECTOR);
8221 res.Add(ScriptBaseClass.ZERO_VECTOR);
8222 res.Add(new LSL_Float(0));
8223 break;
8224
8225 case (int)ScriptBaseClass.PRIM_COLOR:
8226 if (remain < 1)
8227 return null;
8228
8229 face = (int)rules.GetLSLIntegerItem(idx++);
8230 if (face > 21)
8231 break;
8232
8233 res.Add(ScriptBaseClass.ZERO_VECTOR);
8234 res.Add(new LSL_Float(0));
8235 break;
8236
8237 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8238 if (remain < 1)
8239 return null;
8240
8241 face = (int)rules.GetLSLIntegerItem(idx++);
8242 if (face > 21)
8243 break;
8244
8245 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8246 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8247 break;
8248
8249 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8250 if (remain < 1)
8251 return null;
8252
8253 face = (int)rules.GetLSLIntegerItem(idx++);
8254 if (face > 21)
8255 break;
8256
8257 res.Add(ScriptBaseClass.FALSE);
8258 break;
8259
8260 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8261 res.Add(ScriptBaseClass.FALSE);
8262 res.Add(new LSL_Integer(0));
8263 res.Add(new LSL_Float(0));
8264 res.Add(new LSL_Float(0));
8265 res.Add(new LSL_Float(0));
8266 res.Add(new LSL_Float(0));
8267 res.Add(ScriptBaseClass.ZERO_VECTOR);
8268 break;
8269
8270 case (int)ScriptBaseClass.PRIM_TEXGEN:
8271 if (remain < 1)
8272 return null;
8273
8274 face = (int)rules.GetLSLIntegerItem(idx++);
8275 if (face > 21)
8276 break;
8277
8278 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8279 break;
8280
8281 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8282 res.Add(ScriptBaseClass.FALSE);
8283 res.Add(ScriptBaseClass.ZERO_VECTOR);
8284 res.Add(ScriptBaseClass.ZERO_VECTOR);
8285 break;
8286
8287 case (int)ScriptBaseClass.PRIM_GLOW:
8288 if (remain < 1)
8289 return null;
8290
8291 face = (int)rules.GetLSLIntegerItem(idx++);
8292 if (face > 21)
8293 break;
8294
8295 res.Add(new LSL_Float(0));
8296 break;
8297
8298 case (int)ScriptBaseClass.PRIM_TEXT:
8299 res.Add(new LSL_String(""));
8300 res.Add(ScriptBaseClass.ZERO_VECTOR);
8301 res.Add(new LSL_Float(1));
8302 break;
8303
8304 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8305 res.Add(new LSL_Rotation(sp.Rotation));
8306 break;
8307
8308 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8309 res.Add(new LSL_Vector(sp.OffsetPosition));
8310 break;
8311
8312 case (int)ScriptBaseClass.PRIM_SLICE:
8313 res.Add(new LSL_Vector(0, 1, 0));
8314 break;
8315
8316 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8317 if(remain < 3)
8318 return null;
8319 8835
8320 return rules.GetSublist(idx, -1); 8836 if ((object)remaining != null && remaining.Length > 0)
8837 {
8838 linknumber = remaining.GetLSLIntegerItem(0);
8839 rules = remaining.GetSublist(1, -1);
8321 } 8840 }
8841 else
8842 break;
8322 } 8843 }
8323 8844
8324 return null; 8845 return res;
8325 } 8846 }
8326 8847
8327 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8848 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8328 { 8849 {
8329 int idx = 0; 8850 int idx=0;
8330 while (idx < rules.Length) 8851 while (idx < rules.Length)
8331 { 8852 {
8332 int code = (int)rules.GetLSLIntegerItem(idx++); 8853 int code=(int)rules.GetLSLIntegerItem(idx++);
8333 int remain = rules.Length-idx; 8854 int remain=rules.Length-idx;
8334 8855
8335 switch (code) 8856 switch (code)
8336 { 8857 {
@@ -8360,19 +8881,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8360 break; 8881 break;
8361 8882
8362 case (int)ScriptBaseClass.PRIM_POSITION: 8883 case (int)ScriptBaseClass.PRIM_POSITION:
8363 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8884 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8364 8885 part.AbsolutePosition.Y,
8365 // For some reason, the part.AbsolutePosition.* values do not change if the 8886 part.AbsolutePosition.Z);
8366 // linkset is rotated; they always reflect the child prim's world position
8367 // as though the linkset is unrotated. This is incompatible behavior with SL's
8368 // implementation, so will break scripts imported from there (not to mention it
8369 // makes it more difficult to determine a child prim's actual inworld position).
8370 if (!part.IsRoot)
8371 {
8372 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8373 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8374 }
8375
8376 res.Add(v); 8887 res.Add(v);
8377 break; 8888 break;
8378 8889
@@ -8542,30 +9053,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8542 if (remain < 1) 9053 if (remain < 1)
8543 return null; 9054 return null;
8544 9055
8545 face=(int)rules.GetLSLIntegerItem(idx++); 9056 face = (int)rules.GetLSLIntegerItem(idx++);
8546 9057
8547 tex = part.Shape.Textures; 9058 tex = part.Shape.Textures;
9059 int shiny;
8548 if (face == ScriptBaseClass.ALL_SIDES) 9060 if (face == ScriptBaseClass.ALL_SIDES)
8549 { 9061 {
8550 for (face = 0; face < GetNumberOfSides(part); face++) 9062 for (face = 0; face < GetNumberOfSides(part); face++)
8551 { 9063 {
8552 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9064 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8553 // Convert Shininess to PRIM_SHINY_* 9065 if (shinyness == Shininess.High)
8554 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9066 {
8555 // PRIM_BUMP_* 9067 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8556 res.Add(new LSL_Integer((int)texface.Bump)); 9068 }
9069 else if (shinyness == Shininess.Medium)
9070 {
9071 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9072 }
9073 else if (shinyness == Shininess.Low)
9074 {
9075 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9076 }
9077 else
9078 {
9079 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9080 }
9081 res.Add(new LSL_Integer(shiny));
9082 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8557 } 9083 }
8558 } 9084 }
8559 else 9085 else
8560 { 9086 {
8561 if (face >= 0 && face < GetNumberOfSides(part)) 9087 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9088 if (shinyness == Shininess.High)
8562 { 9089 {
8563 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9090 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8564 // Convert Shininess to PRIM_SHINY_* 9091 }
8565 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9092 else if (shinyness == Shininess.Medium)
8566 // PRIM_BUMP_* 9093 {
8567 res.Add(new LSL_Integer((int)texface.Bump)); 9094 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8568 } 9095 }
9096 else if (shinyness == Shininess.Low)
9097 {
9098 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9099 }
9100 else
9101 {
9102 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9103 }
9104 res.Add(new LSL_Integer(shiny));
9105 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8569 } 9106 }
8570 break; 9107 break;
8571 9108
@@ -8576,21 +9113,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8576 face = (int)rules.GetLSLIntegerItem(idx++); 9113 face = (int)rules.GetLSLIntegerItem(idx++);
8577 9114
8578 tex = part.Shape.Textures; 9115 tex = part.Shape.Textures;
9116 int fullbright;
8579 if (face == ScriptBaseClass.ALL_SIDES) 9117 if (face == ScriptBaseClass.ALL_SIDES)
8580 { 9118 {
8581 for (face = 0; face < GetNumberOfSides(part); face++) 9119 for (face = 0; face < GetNumberOfSides(part); face++)
8582 { 9120 {
8583 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9121 if (tex.GetFace((uint)face).Fullbright == true)
8584 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9122 {
9123 fullbright = ScriptBaseClass.TRUE;
9124 }
9125 else
9126 {
9127 fullbright = ScriptBaseClass.FALSE;
9128 }
9129 res.Add(new LSL_Integer(fullbright));
8585 } 9130 }
8586 } 9131 }
8587 else 9132 else
8588 { 9133 {
8589 if (face >= 0 && face < GetNumberOfSides(part)) 9134 if (tex.GetFace((uint)face).Fullbright == true)
8590 { 9135 {
8591 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9136 fullbright = ScriptBaseClass.TRUE;
8592 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0));
8593 } 9137 }
9138 else
9139 {
9140 fullbright = ScriptBaseClass.FALSE;
9141 }
9142 res.Add(new LSL_Integer(fullbright));
8594 } 9143 }
8595 break; 9144 break;
8596 9145
@@ -8612,27 +9161,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8612 break; 9161 break;
8613 9162
8614 case (int)ScriptBaseClass.PRIM_TEXGEN: 9163 case (int)ScriptBaseClass.PRIM_TEXGEN:
9164 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8615 if (remain < 1) 9165 if (remain < 1)
8616 return null; 9166 return null;
8617 9167
8618 face=(int)rules.GetLSLIntegerItem(idx++); 9168 face = (int)rules.GetLSLIntegerItem(idx++);
8619 9169
8620 tex = part.Shape.Textures; 9170 tex = part.Shape.Textures;
8621 if (face == ScriptBaseClass.ALL_SIDES) 9171 if (face == ScriptBaseClass.ALL_SIDES)
8622 { 9172 {
8623 for (face = 0; face < GetNumberOfSides(part); face++) 9173 for (face = 0; face < GetNumberOfSides(part); face++)
8624 { 9174 {
8625 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9175 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8626 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9176 {
8627 res.Add(new LSL_Integer((uint)texgen >> 1)); 9177 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9178 }
9179 else
9180 {
9181 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9182 }
8628 } 9183 }
8629 } 9184 }
8630 else 9185 else
8631 { 9186 {
8632 if (face >= 0 && face < GetNumberOfSides(part)) 9187 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8633 { 9188 {
8634 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9189 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8635 res.Add(new LSL_Integer((uint)texgen >> 1)); 9190 }
9191 else
9192 {
9193 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8636 } 9194 }
8637 } 9195 }
8638 break; 9196 break;
@@ -8656,24 +9214,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8656 if (remain < 1) 9214 if (remain < 1)
8657 return null; 9215 return null;
8658 9216
8659 face=(int)rules.GetLSLIntegerItem(idx++); 9217 face = (int)rules.GetLSLIntegerItem(idx++);
8660 9218
8661 tex = part.Shape.Textures; 9219 tex = part.Shape.Textures;
9220 float primglow;
8662 if (face == ScriptBaseClass.ALL_SIDES) 9221 if (face == ScriptBaseClass.ALL_SIDES)
8663 { 9222 {
8664 for (face = 0; face < GetNumberOfSides(part); face++) 9223 for (face = 0; face < GetNumberOfSides(part); face++)
8665 { 9224 {
8666 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9225 primglow = tex.GetFace((uint)face).Glow;
8667 res.Add(new LSL_Float(texface.Glow)); 9226 res.Add(new LSL_Float(primglow));
8668 } 9227 }
8669 } 9228 }
8670 else 9229 else
8671 { 9230 {
8672 if (face >= 0 && face < GetNumberOfSides(part)) 9231 primglow = tex.GetFace((uint)face).Glow;
8673 { 9232 res.Add(new LSL_Float(primglow));
8674 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8675 res.Add(new LSL_Float(texface.Glow));
8676 }
8677 } 9233 }
8678 break; 9234 break;
8679 9235
@@ -8685,15 +9241,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8685 textColor.B)); 9241 textColor.B));
8686 res.Add(new LSL_Float(textColor.A)); 9242 res.Add(new LSL_Float(textColor.A));
8687 break; 9243 break;
9244
8688 case (int)ScriptBaseClass.PRIM_NAME: 9245 case (int)ScriptBaseClass.PRIM_NAME:
8689 res.Add(new LSL_String(part.Name)); 9246 res.Add(new LSL_String(part.Name));
8690 break; 9247 break;
9248
8691 case (int)ScriptBaseClass.PRIM_DESC: 9249 case (int)ScriptBaseClass.PRIM_DESC:
8692 res.Add(new LSL_String(part.Description)); 9250 res.Add(new LSL_String(part.Description));
8693 break; 9251 break;
8694 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9252 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8695 res.Add(new LSL_Rotation(part.RotationOffset)); 9253 res.Add(new LSL_Rotation(part.RotationOffset));
8696 break; 9254 break;
9255
8697 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9256 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8698 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9257 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8699 break; 9258 break;
@@ -9304,8 +9863,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9304 // The function returns an ordered list 9863 // The function returns an ordered list
9305 // representing the tokens found in the supplied 9864 // representing the tokens found in the supplied
9306 // sources string. If two successive tokenizers 9865 // sources string. If two successive tokenizers
9307 // are encountered, then a NULL entry is added 9866 // are encountered, then a null-string entry is
9308 // to the list. 9867 // added to the list.
9309 // 9868 //
9310 // It is a precondition that the source and 9869 // It is a precondition that the source and
9311 // toekizer lisst are non-null. If they are null, 9870 // toekizer lisst are non-null. If they are null,
@@ -9313,7 +9872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9313 // while their lengths are being determined. 9872 // while their lengths are being determined.
9314 // 9873 //
9315 // A small amount of working memoryis required 9874 // A small amount of working memoryis required
9316 // of approximately 8*#tokenizers. 9875 // of approximately 8*#tokenizers + 8*srcstrlen.
9317 // 9876 //
9318 // There are many ways in which this function 9877 // There are many ways in which this function
9319 // can be implemented, this implementation is 9878 // can be implemented, this implementation is
@@ -9329,155 +9888,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9329 // and eliminates redundant tokenizers as soon 9888 // and eliminates redundant tokenizers as soon
9330 // as is possible. 9889 // as is possible.
9331 // 9890 //
9332 // The implementation tries to avoid any copying 9891 // The implementation tries to minimize temporary
9333 // of arrays or other objects. 9892 // garbage generation.
9334 // </remarks> 9893 // </remarks>
9335 9894
9336 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9895 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9337 { 9896 {
9338 int beginning = 0; 9897 return ParseString2List(src, separators, spacers, true);
9339 int srclen = src.Length; 9898 }
9340 int seplen = separators.Length;
9341 object[] separray = separators.Data;
9342 int spclen = spacers.Length;
9343 object[] spcarray = spacers.Data;
9344 int mlen = seplen+spclen;
9345
9346 int[] offset = new int[mlen+1];
9347 bool[] active = new bool[mlen];
9348
9349 int best;
9350 int j;
9351
9352 // Initial capacity reduces resize cost
9353 9899
9354 LSL_List tokens = new LSL_List(); 9900 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9901 {
9902 int srclen = src.Length;
9903 int seplen = separators.Length;
9904 object[] separray = separators.Data;
9905 int spclen = spacers.Length;
9906 object[] spcarray = spacers.Data;
9907 int dellen = 0;
9908 string[] delarray = new string[seplen+spclen];
9355 9909
9356 // All entries are initially valid 9910 int outlen = 0;
9911 string[] outarray = new string[srclen*2+1];
9357 9912
9358 for (int i = 0; i < mlen; i++) 9913 int i, j;
9359 active[i] = true; 9914 string d;
9360 9915
9361 offset[mlen] = srclen; 9916 m_host.AddScriptLPS(1);
9362 9917
9363 while (beginning < srclen) 9918 /*
9919 * Convert separator and spacer lists to C# strings.
9920 * Also filter out null strings so we don't hang.
9921 */
9922 for (i = 0; i < seplen; i ++)
9364 { 9923 {
9924 d = separray[i].ToString();
9925 if (d.Length > 0)
9926 {
9927 delarray[dellen++] = d;
9928 }
9929 }
9930 seplen = dellen;
9365 9931
9366 best = mlen; // as bad as it gets 9932 for (i = 0; i < spclen; i ++)
9933 {
9934 d = spcarray[i].ToString();
9935 if (d.Length > 0)
9936 {
9937 delarray[dellen++] = d;
9938 }
9939 }
9367 9940
9368 // Scan for separators 9941 /*
9942 * Scan through source string from beginning to end.
9943 */
9944 for (i = 0;;)
9945 {
9369 9946
9370 for (j = 0; j < seplen; j++) 9947 /*
9948 * Find earliest delimeter in src starting at i (if any).
9949 */
9950 int earliestDel = -1;
9951 int earliestSrc = srclen;
9952 string earliestStr = null;
9953 for (j = 0; j < dellen; j ++)
9371 { 9954 {
9372 if (separray[j].ToString() == String.Empty) 9955 d = delarray[j];
9373 active[j] = false; 9956 if (d != null)
9374
9375 if (active[j])
9376 { 9957 {
9377 // scan all of the markers 9958 int index = src.IndexOf(d, i);
9378 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9959 if (index < 0)
9379 { 9960 {
9380 // not present at all 9961 delarray[j] = null; // delim nowhere in src, don't check it anymore
9381 active[j] = false;
9382 } 9962 }
9383 else 9963 else if (index < earliestSrc)
9384 { 9964 {
9385 // present and correct 9965 earliestSrc = index; // where delimeter starts in source string
9386 if (offset[j] < offset[best]) 9966 earliestDel = j; // where delimeter is in delarray[]
9387 { 9967 earliestStr = d; // the delimeter string from delarray[]
9388 // closest so far 9968 if (index == i) break; // can't do any better than found at beg of string
9389 best = j;
9390 if (offset[best] == beginning)
9391 break;
9392 }
9393 } 9969 }
9394 } 9970 }
9395 } 9971 }
9396 9972
9397 // Scan for spacers 9973 /*
9398 9974 * Output source string starting at i through start of earliest delimeter.
9399 if (offset[best] != beginning) 9975 */
9976 if (keepNulls || (earliestSrc > i))
9400 { 9977 {
9401 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9978 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9402 {
9403 if (spcarray[j-seplen].ToString() == String.Empty)
9404 active[j] = false;
9405
9406 if (active[j])
9407 {
9408 // scan all of the markers
9409 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9410 {
9411 // not present at all
9412 active[j] = false;
9413 }
9414 else
9415 {
9416 // present and correct
9417 if (offset[j] < offset[best])
9418 {
9419 // closest so far
9420 best = j;
9421 }
9422 }
9423 }
9424 }
9425 } 9979 }
9426 9980
9427 // This is the normal exit from the scanning loop 9981 /*
9982 * If no delimeter found at or after i, we're done scanning.
9983 */
9984 if (earliestDel < 0) break;
9428 9985
9429 if (best == mlen) 9986 /*
9987 * If delimeter was a spacer, output the spacer.
9988 */
9989 if (earliestDel >= seplen)
9430 { 9990 {
9431 // no markers were found on this pass 9991 outarray[outlen++] = earliestStr;
9432 // so we're pretty much done
9433 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9434 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9435 break;
9436 } 9992 }
9437 9993
9438 // Otherwise we just add the newly delimited token 9994 /*
9439 // and recalculate where the search should continue. 9995 * Look at rest of src string following delimeter.
9440 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9996 */
9441 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9997 i = earliestSrc + earliestStr.Length;
9442
9443 if (best < seplen)
9444 {
9445 beginning = offset[best] + (separray[best].ToString()).Length;
9446 }
9447 else
9448 {
9449 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9450 string str = spcarray[best - seplen].ToString();
9451 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9452 tokens.Add(new LSL_String(str));
9453 }
9454 } 9998 }
9455 9999
9456 // This an awkward an not very intuitive boundary case. If the 10000 /*
9457 // last substring is a tokenizer, then there is an implied trailing 10001 * Make up an exact-sized output array suitable for an LSL_List object.
9458 // null list entry. Hopefully the single comparison will not be too 10002 */
9459 // arduous. Alternatively the 'break' could be replced with a return 10003 object[] outlist = new object[outlen];
9460 // but that's shabby programming. 10004 for (i = 0; i < outlen; i ++)
9461
9462 if ((beginning == srclen) && (keepNulls))
9463 { 10005 {
9464 if (srclen != 0) 10006 outlist[i] = new LSL_String(outarray[i]);
9465 tokens.Add(new LSL_String(""));
9466 } 10007 }
9467 10008 return new LSL_List(outlist);
9468 return tokens;
9469 }
9470
9471 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9472 {
9473 m_host.AddScriptLPS(1);
9474 return this.ParseString(src, separators, spacers, false);
9475 }
9476
9477 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9478 {
9479 m_host.AddScriptLPS(1);
9480 return this.ParseString(src, separators, spacers, true);
9481 } 10009 }
9482 10010
9483 public LSL_Integer llGetObjectPermMask(int mask) 10011 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9572,6 +10100,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 case 4: 10100 case 4:
9573 return (int)item.NextPermissions; 10101 return (int)item.NextPermissions;
9574 } 10102 }
10103 m_host.TaskInventory.LockItemsForRead(false);
9575 10104
9576 return -1; 10105 return -1;
9577 } 10106 }
@@ -9775,31 +10304,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9775 UUID key = new UUID(); 10304 UUID key = new UUID();
9776 if (UUID.TryParse(id, out key)) 10305 if (UUID.TryParse(id, out key))
9777 { 10306 {
9778 try 10307 // return total object mass
9779 { 10308 SceneObjectPart part = World.GetSceneObjectPart(key);
9780 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10309 if (part != null)
9781 if (obj != null) 10310 return part.ParentGroup.GetMass();
9782 return (double)obj.GetMass(); 10311
9783 // the object is null so the key is for an avatar 10312 // the object is null so the key is for an avatar
9784 ScenePresence avatar = World.GetScenePresence(key); 10313 ScenePresence avatar = World.GetScenePresence(key);
9785 if (avatar != null) 10314 if (avatar != null)
9786 if (avatar.IsChildAgent)
9787 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9788 // child agents have a mass of 1.0
9789 return 1;
9790 else
9791 return (double)avatar.GetMass();
9792 }
9793 catch (KeyNotFoundException)
9794 { 10315 {
9795 return 0; // The Object/Agent not in the region so just return zero 10316 if (avatar.IsChildAgent)
10317 {
10318 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10319 // child agents have a mass of 1.0
10320 return 1;
10321 }
10322 else
10323 {
10324 return (double)avatar.GetMass();
10325 }
9796 } 10326 }
9797 } 10327 }
9798 return 0; 10328 return 0;
9799 } 10329 }
9800 10330
9801 /// <summary> 10331 /// <summary>
9802 /// illListReplaceList removes the sub-list defined by the inclusive indices 10332 /// llListReplaceList removes the sub-list defined by the inclusive indices
9803 /// start and end and inserts the src list in its place. The inclusive 10333 /// start and end and inserts the src list in its place. The inclusive
9804 /// nature of the indices means that at least one element must be deleted 10334 /// nature of the indices means that at least one element must be deleted
9805 /// if the indices are within the bounds of the existing list. I.e. 2,2 10335 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9856,16 +10386,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9856 // based upon end. Note that if end exceeds the upper 10386 // based upon end. Note that if end exceeds the upper
9857 // bound in this case, the entire destination list 10387 // bound in this case, the entire destination list
9858 // is removed. 10388 // is removed.
9859 else 10389 else if (start == 0)
9860 { 10390 {
9861 if (end + 1 < dest.Length) 10391 if (end + 1 < dest.Length)
9862 {
9863 return src + dest.GetSublist(end + 1, -1); 10392 return src + dest.GetSublist(end + 1, -1);
9864 }
9865 else 10393 else
9866 {
9867 return src; 10394 return src;
9868 } 10395 }
10396 else // Start < 0
10397 {
10398 if (end + 1 < dest.Length)
10399 return dest.GetSublist(end + 1, -1);
10400 else
10401 return new LSL_List();
9869 } 10402 }
9870 } 10403 }
9871 // Finally, if start > end, we strip away a prefix and 10404 // Finally, if start > end, we strip away a prefix and
@@ -9916,17 +10449,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9916 int width = 0; 10449 int width = 0;
9917 int height = 0; 10450 int height = 0;
9918 10451
9919 ParcelMediaCommandEnum? commandToSend = null; 10452 uint commandToSend = 0;
9920 float time = 0.0f; // default is from start 10453 float time = 0.0f; // default is from start
9921 10454
9922 ScenePresence presence = null; 10455 ScenePresence presence = null;
9923 10456
9924 for (int i = 0; i < commandList.Data.Length; i++) 10457 for (int i = 0; i < commandList.Data.Length; i++)
9925 { 10458 {
9926 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10459 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9927 switch (command) 10460 switch (command)
9928 { 10461 {
9929 case ParcelMediaCommandEnum.Agent: 10462 case (uint)ParcelMediaCommandEnum.Agent:
9930 // we send only to one agent 10463 // we send only to one agent
9931 if ((i + 1) < commandList.Length) 10464 if ((i + 1) < commandList.Length)
9932 { 10465 {
@@ -9943,25 +10476,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9943 } 10476 }
9944 break; 10477 break;
9945 10478
9946 case ParcelMediaCommandEnum.Loop: 10479 case (uint)ParcelMediaCommandEnum.Loop:
9947 loop = 1; 10480 loop = 1;
9948 commandToSend = command; 10481 commandToSend = command;
9949 update = true; //need to send the media update packet to set looping 10482 update = true; //need to send the media update packet to set looping
9950 break; 10483 break;
9951 10484
9952 case ParcelMediaCommandEnum.Play: 10485 case (uint)ParcelMediaCommandEnum.Play:
9953 loop = 0; 10486 loop = 0;
9954 commandToSend = command; 10487 commandToSend = command;
9955 update = true; //need to send the media update packet to make sure it doesn't loop 10488 update = true; //need to send the media update packet to make sure it doesn't loop
9956 break; 10489 break;
9957 10490
9958 case ParcelMediaCommandEnum.Pause: 10491 case (uint)ParcelMediaCommandEnum.Pause:
9959 case ParcelMediaCommandEnum.Stop: 10492 case (uint)ParcelMediaCommandEnum.Stop:
9960 case ParcelMediaCommandEnum.Unload: 10493 case (uint)ParcelMediaCommandEnum.Unload:
9961 commandToSend = command; 10494 commandToSend = command;
9962 break; 10495 break;
9963 10496
9964 case ParcelMediaCommandEnum.Url: 10497 case (uint)ParcelMediaCommandEnum.Url:
9965 if ((i + 1) < commandList.Length) 10498 if ((i + 1) < commandList.Length)
9966 { 10499 {
9967 if (commandList.Data[i + 1] is LSL_String) 10500 if (commandList.Data[i + 1] is LSL_String)
@@ -9974,7 +10507,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9974 } 10507 }
9975 break; 10508 break;
9976 10509
9977 case ParcelMediaCommandEnum.Texture: 10510 case (uint)ParcelMediaCommandEnum.Texture:
9978 if ((i + 1) < commandList.Length) 10511 if ((i + 1) < commandList.Length)
9979 { 10512 {
9980 if (commandList.Data[i + 1] is LSL_String) 10513 if (commandList.Data[i + 1] is LSL_String)
@@ -9987,7 +10520,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9987 } 10520 }
9988 break; 10521 break;
9989 10522
9990 case ParcelMediaCommandEnum.Time: 10523 case (uint)ParcelMediaCommandEnum.Time:
9991 if ((i + 1) < commandList.Length) 10524 if ((i + 1) < commandList.Length)
9992 { 10525 {
9993 if (commandList.Data[i + 1] is LSL_Float) 10526 if (commandList.Data[i + 1] is LSL_Float)
@@ -9999,7 +10532,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9999 } 10532 }
10000 break; 10533 break;
10001 10534
10002 case ParcelMediaCommandEnum.AutoAlign: 10535 case (uint)ParcelMediaCommandEnum.AutoAlign:
10003 if ((i + 1) < commandList.Length) 10536 if ((i + 1) < commandList.Length)
10004 { 10537 {
10005 if (commandList.Data[i + 1] is LSL_Integer) 10538 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10013,7 +10546,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10013 } 10546 }
10014 break; 10547 break;
10015 10548
10016 case ParcelMediaCommandEnum.Type: 10549 case (uint)ParcelMediaCommandEnum.Type:
10017 if ((i + 1) < commandList.Length) 10550 if ((i + 1) < commandList.Length)
10018 { 10551 {
10019 if (commandList.Data[i + 1] is LSL_String) 10552 if (commandList.Data[i + 1] is LSL_String)
@@ -10026,7 +10559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10026 } 10559 }
10027 break; 10560 break;
10028 10561
10029 case ParcelMediaCommandEnum.Desc: 10562 case (uint)ParcelMediaCommandEnum.Desc:
10030 if ((i + 1) < commandList.Length) 10563 if ((i + 1) < commandList.Length)
10031 { 10564 {
10032 if (commandList.Data[i + 1] is LSL_String) 10565 if (commandList.Data[i + 1] is LSL_String)
@@ -10039,7 +10572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10039 } 10572 }
10040 break; 10573 break;
10041 10574
10042 case ParcelMediaCommandEnum.Size: 10575 case (uint)ParcelMediaCommandEnum.Size:
10043 if ((i + 2) < commandList.Length) 10576 if ((i + 2) < commandList.Length)
10044 { 10577 {
10045 if (commandList.Data[i + 1] is LSL_Integer) 10578 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10109,7 +10642,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10109 } 10642 }
10110 } 10643 }
10111 10644
10112 if (commandToSend != null) 10645 if (commandToSend != 0)
10113 { 10646 {
10114 // the commandList contained a start/stop/... command, too 10647 // the commandList contained a start/stop/... command, too
10115 if (presence == null) 10648 if (presence == null)
@@ -10146,7 +10679,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10146 10679
10147 if (aList.Data[i] != null) 10680 if (aList.Data[i] != null)
10148 { 10681 {
10149 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10682 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10150 { 10683 {
10151 case ParcelMediaCommandEnum.Url: 10684 case ParcelMediaCommandEnum.Url:
10152 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10685 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10203,15 +10736,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10203 10736
10204 if (quick_pay_buttons.Data.Length < 4) 10737 if (quick_pay_buttons.Data.Length < 4)
10205 { 10738 {
10206 LSLError("List must have at least 4 elements"); 10739 int x;
10207 return; 10740 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10741 {
10742 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10743 }
10208 } 10744 }
10209 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10745 int[] nPrice = new int[5];
10210 10746 nPrice[0] = price;
10211 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10747 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10212 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10748 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10213 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10749 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10214 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10750 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10751 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10215 m_host.ParentGroup.HasGroupChanged = true; 10752 m_host.ParentGroup.HasGroupChanged = true;
10216 } 10753 }
10217 10754
@@ -10228,7 +10765,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10228 return Vector3.Zero; 10765 return Vector3.Zero;
10229 } 10766 }
10230 10767
10231 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10768// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10769 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10232 if (presence != null) 10770 if (presence != null)
10233 { 10771 {
10234 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10772 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10251,7 +10789,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10251 return Quaternion.Identity; 10789 return Quaternion.Identity;
10252 } 10790 }
10253 10791
10254 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10792// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10793 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10255 if (presence != null) 10794 if (presence != null)
10256 { 10795 {
10257 return new LSL_Rotation(presence.CameraRotation); 10796 return new LSL_Rotation(presence.CameraRotation);
@@ -10311,14 +10850,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10311 { 10850 {
10312 m_host.AddScriptLPS(1); 10851 m_host.AddScriptLPS(1);
10313 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10852 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10314 if (detectedParams == null) return; // only works on the first detected avatar 10853 if (detectedParams == null)
10315 10854 {
10855 if (m_host.ParentGroup.IsAttachment == true)
10856 {
10857 detectedParams = new DetectParams();
10858 detectedParams.Key = m_host.OwnerID;
10859 }
10860 else
10861 {
10862 return;
10863 }
10864 }
10865
10316 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10866 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10317 if (avatar != null) 10867 if (avatar != null)
10318 { 10868 {
10319 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10869 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10320 simname, pos, lookAt); 10870 simname, pos, lookAt);
10321 } 10871 }
10872
10322 ScriptSleep(1000); 10873 ScriptSleep(1000);
10323 } 10874 }
10324 10875
@@ -10442,12 +10993,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10442 10993
10443 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10994 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10444 object[] data = rules.Data; 10995 object[] data = rules.Data;
10445 for (int i = 0; i < data.Length; ++i) { 10996 for (int i = 0; i < data.Length; ++i)
10997 {
10446 int type = Convert.ToInt32(data[i++].ToString()); 10998 int type = Convert.ToInt32(data[i++].ToString());
10447 if (i >= data.Length) break; // odd number of entries => ignore the last 10999 if (i >= data.Length) break; // odd number of entries => ignore the last
10448 11000
10449 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11001 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10450 switch (type) { 11002 switch (type)
11003 {
10451 case ScriptBaseClass.CAMERA_FOCUS: 11004 case ScriptBaseClass.CAMERA_FOCUS:
10452 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11005 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10453 case ScriptBaseClass.CAMERA_POSITION: 11006 case ScriptBaseClass.CAMERA_POSITION:
@@ -10552,19 +11105,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10552 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11105 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10553 { 11106 {
10554 m_host.AddScriptLPS(1); 11107 m_host.AddScriptLPS(1);
10555 string ret = String.Empty; 11108
10556 string src1 = llBase64ToString(str1); 11109 if (str1 == String.Empty)
10557 string src2 = llBase64ToString(str2); 11110 return String.Empty;
10558 int c = 0; 11111 if (str2 == String.Empty)
10559 for (int i = 0; i < src1.Length; i++) 11112 return str1;
11113
11114 int len = str2.Length;
11115 if ((len % 4) != 0) // LL is EVIL!!!!
10560 { 11116 {
10561 ret += (char) (src1[i] ^ src2[c]); 11117 while (str2.EndsWith("="))
11118 str2 = str2.Substring(0, str2.Length - 1);
10562 11119
10563 c++; 11120 len = str2.Length;
10564 if (c >= src2.Length) 11121 int mod = len % 4;
10565 c = 0; 11122
11123 if (mod == 1)
11124 str2 = str2.Substring(0, str2.Length - 1);
11125 else if (mod == 2)
11126 str2 += "==";
11127 else if (mod == 3)
11128 str2 += "=";
11129 }
11130
11131 byte[] data1;
11132 byte[] data2;
11133 try
11134 {
11135 data1 = Convert.FromBase64String(str1);
11136 data2 = Convert.FromBase64String(str2);
11137 }
11138 catch (Exception)
11139 {
11140 return new LSL_String(String.Empty);
11141 }
11142
11143 byte[] d2 = new Byte[data1.Length];
11144 int pos = 0;
11145
11146 if (data1.Length <= data2.Length)
11147 {
11148 Array.Copy(data2, 0, d2, 0, data1.Length);
11149 }
11150 else
11151 {
11152 while (pos < data1.Length)
11153 {
11154 len = data1.Length - pos;
11155 if (len > data2.Length)
11156 len = data2.Length;
11157
11158 Array.Copy(data2, 0, d2, pos, len);
11159 pos += len;
11160 }
10566 } 11161 }
10567 return llStringToBase64(ret); 11162
11163 for (pos = 0 ; pos < data1.Length ; pos++ )
11164 data1[pos] ^= d2[pos];
11165
11166 return Convert.ToBase64String(data1);
10568 } 11167 }
10569 11168
10570 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11169 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10668,16 +11267,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10668 if (userAgent != null) 11267 if (userAgent != null)
10669 httpHeaders["User-Agent"] = userAgent; 11268 httpHeaders["User-Agent"] = userAgent;
10670 11269
11270 // See if the URL contains any header hacks
11271 string[] urlParts = url.Split(new char[] {'\n'});
11272 if (urlParts.Length > 1)
11273 {
11274 // Iterate the passed headers and parse them
11275 for (int i = 1 ; i < urlParts.Length ; i++ )
11276 {
11277 // The rest of those would be added to the body in SL.
11278 // Let's not do that.
11279 if (urlParts[i] == String.Empty)
11280 break;
11281
11282 // See if this could be a valid header
11283 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11284 if (headerParts.Length != 2)
11285 continue;
11286
11287 string headerName = headerParts[0].Trim();
11288 string headerValue = headerParts[1].Trim();
11289
11290 // Filter out headers that could be used to abuse
11291 // another system or cloak the request
11292 if (headerName.ToLower() == "x-secondlife-shard" ||
11293 headerName.ToLower() == "x-secondlife-object-name" ||
11294 headerName.ToLower() == "x-secondlife-object-key" ||
11295 headerName.ToLower() == "x-secondlife-region" ||
11296 headerName.ToLower() == "x-secondlife-local-position" ||
11297 headerName.ToLower() == "x-secondlife-local-velocity" ||
11298 headerName.ToLower() == "x-secondlife-local-rotation" ||
11299 headerName.ToLower() == "x-secondlife-owner-name" ||
11300 headerName.ToLower() == "x-secondlife-owner-key" ||
11301 headerName.ToLower() == "connection" ||
11302 headerName.ToLower() == "content-length" ||
11303 headerName.ToLower() == "from" ||
11304 headerName.ToLower() == "host" ||
11305 headerName.ToLower() == "proxy-authorization" ||
11306 headerName.ToLower() == "referer" ||
11307 headerName.ToLower() == "trailer" ||
11308 headerName.ToLower() == "transfer-encoding" ||
11309 headerName.ToLower() == "via" ||
11310 headerName.ToLower() == "authorization")
11311 continue;
11312
11313 httpHeaders[headerName] = headerValue;
11314 }
11315
11316 // Finally, strip any protocol specifier from the URL
11317 url = urlParts[0].Trim();
11318 int idx = url.IndexOf(" HTTP/");
11319 if (idx != -1)
11320 url = url.Substring(0, idx);
11321 }
11322
10671 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11323 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10672 Regex r = new Regex(authregex); 11324 Regex r = new Regex(authregex);
10673 int[] gnums = r.GetGroupNumbers(); 11325 int[] gnums = r.GetGroupNumbers();
10674 Match m = r.Match(url); 11326 Match m = r.Match(url);
10675 if (m.Success) { 11327 if (m.Success)
10676 for (int i = 1; i < gnums.Length; i++) { 11328 {
11329 for (int i = 1; i < gnums.Length; i++)
11330 {
10677 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11331 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10678 //CaptureCollection cc = g.Captures; 11332 //CaptureCollection cc = g.Captures;
10679 } 11333 }
10680 if (m.Groups.Count == 5) { 11334 if (m.Groups.Count == 5)
11335 {
10681 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11336 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10682 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11337 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10683 } 11338 }
@@ -10880,6 +11535,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10880 11535
10881 LSL_List ret = new LSL_List(); 11536 LSL_List ret = new LSL_List();
10882 UUID key = new UUID(); 11537 UUID key = new UUID();
11538
11539
10883 if (UUID.TryParse(id, out key)) 11540 if (UUID.TryParse(id, out key))
10884 { 11541 {
10885 ScenePresence av = World.GetScenePresence(key); 11542 ScenePresence av = World.GetScenePresence(key);
@@ -10897,13 +11554,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10897 ret.Add(new LSL_String("")); 11554 ret.Add(new LSL_String(""));
10898 break; 11555 break;
10899 case ScriptBaseClass.OBJECT_POS: 11556 case ScriptBaseClass.OBJECT_POS:
10900 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11557 Vector3 avpos;
11558
11559 if (av.ParentID != 0 && av.ParentPart != null)
11560 {
11561 avpos = av.OffsetPosition;
11562
11563 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11564 avpos -= sitOffset;
11565
11566 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11567 }
11568 else
11569 avpos = av.AbsolutePosition;
11570
11571 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10901 break; 11572 break;
10902 case ScriptBaseClass.OBJECT_ROT: 11573 case ScriptBaseClass.OBJECT_ROT:
10903 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11574 Quaternion avrot = av.Rotation;
11575 if (av.ParentID != 0 && av.ParentPart != null)
11576 {
11577 avrot = av.ParentPart.GetWorldRotation() * avrot;
11578 }
11579 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10904 break; 11580 break;
10905 case ScriptBaseClass.OBJECT_VELOCITY: 11581 case ScriptBaseClass.OBJECT_VELOCITY:
10906 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11582 Vector3 avvel = av.Velocity;
11583 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10907 break; 11584 break;
10908 case ScriptBaseClass.OBJECT_OWNER: 11585 case ScriptBaseClass.OBJECT_OWNER:
10909 ret.Add(new LSL_String(id)); 11586 ret.Add(new LSL_String(id));
@@ -10988,11 +11665,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10988 case ScriptBaseClass.OBJECT_NAME: 11665 case ScriptBaseClass.OBJECT_NAME:
10989 ret.Add(new LSL_String(obj.Name)); 11666 ret.Add(new LSL_String(obj.Name));
10990 break; 11667 break;
10991 case ScriptBaseClass.OBJECT_DESC: 11668 case ScriptBaseClass.OBJECT_DESC:
10992 ret.Add(new LSL_String(obj.Description)); 11669 ret.Add(new LSL_String(obj.Description));
10993 break; 11670 break;
10994 case ScriptBaseClass.OBJECT_POS: 11671 case ScriptBaseClass.OBJECT_POS:
10995 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11672 Vector3 opos = obj.AbsolutePosition;
11673 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10996 break; 11674 break;
10997 case ScriptBaseClass.OBJECT_ROT: 11675 case ScriptBaseClass.OBJECT_ROT:
10998 { 11676 {
@@ -11042,9 +11720,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11042 // The value returned in SL for normal prims is prim count 11720 // The value returned in SL for normal prims is prim count
11043 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11721 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11044 break; 11722 break;
11045 // The following 3 costs I have intentionaly coded to return zero. They are part of 11723
11046 // "Land Impact" calculations. These calculations are probably not applicable 11724 // costs below may need to be diferent for root parts, need to check
11047 // to OpenSim and are not yet complete in SL
11048 case ScriptBaseClass.OBJECT_SERVER_COST: 11725 case ScriptBaseClass.OBJECT_SERVER_COST:
11049 // The linden calculation is here 11726 // The linden calculation is here
11050 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11727 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -11052,16 +11729,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11052 ret.Add(new LSL_Float(0)); 11729 ret.Add(new LSL_Float(0));
11053 break; 11730 break;
11054 case ScriptBaseClass.OBJECT_STREAMING_COST: 11731 case ScriptBaseClass.OBJECT_STREAMING_COST:
11055 // The linden calculation is here 11732 // The value returned in SL for normal prims is prim count * 0.06
11056 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11733 ret.Add(new LSL_Float(obj.StreamingCost));
11057 // The value returned in SL for normal prims looks like the prim count * 0.06
11058 ret.Add(new LSL_Float(0));
11059 break; 11734 break;
11060 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11735 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11061 // The linden calculation is here 11736 // The value returned in SL for normal prims is prim count
11062 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11737 ret.Add(new LSL_Float(obj.PhysicsCost));
11063 // The value returned in SL for normal prims looks like the prim count
11064 ret.Add(new LSL_Float(0));
11065 break; 11738 break;
11066 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11739 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11067 ret.Add(new LSL_Float(0)); 11740 ret.Add(new LSL_Float(0));
@@ -11320,15 +11993,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11320 return result; 11993 return result;
11321 } 11994 }
11322 11995
11323 public void print(string str) 11996 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11324 { 11997 {
11325 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11998 List<SceneObjectPart> parts = GetLinkParts(link);
11326 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11999 if (parts.Count < 1)
11327 if (ossl != null) 12000 return 0;
11328 { 12001
11329 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12002 return GetNumberOfSides(parts[0]);
11330 m_log.Info("LSL print():" + str);
11331 }
11332 } 12003 }
11333 12004
11334 private string Name2Username(string name) 12005 private string Name2Username(string name)
@@ -11373,7 +12044,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11373 12044
11374 return rq.ToString(); 12045 return rq.ToString();
11375 } 12046 }
11376 12047/*
12048 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12049 {
12050 m_SayShoutCount = 0;
12051 }
12052*/
11377 private struct Tri 12053 private struct Tri
11378 { 12054 {
11379 public Vector3 p1; 12055 public Vector3 p1;
@@ -11522,9 +12198,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11522 12198
11523 ContactResult result = new ContactResult (); 12199 ContactResult result = new ContactResult ();
11524 result.ConsumerID = group.LocalId; 12200 result.ConsumerID = group.LocalId;
11525 result.Depth = intersection.distance; 12201// result.Depth = intersection.distance;
11526 result.Normal = intersection.normal; 12202 result.Normal = intersection.normal;
11527 result.Pos = intersection.ipoint; 12203 result.Pos = intersection.ipoint;
12204 result.Depth = Vector3.Mag(rayStart - result.Pos);
11528 12205
11529 contacts.Add(result); 12206 contacts.Add(result);
11530 }); 12207 });
@@ -11657,6 +12334,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11657 12334
11658 return contacts[0]; 12335 return contacts[0];
11659 } 12336 }
12337/*
12338 // not done:
12339 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12340 {
12341 ContactResult[] contacts = null;
12342 World.ForEachSOG(delegate(SceneObjectGroup group)
12343 {
12344 if (m_host.ParentGroup == group)
12345 return;
12346
12347 if (group.IsAttachment)
12348 return;
12349
12350 if(group.RootPart.PhysActor != null)
12351 return;
12352
12353 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12354 });
12355 return contacts;
12356 }
12357*/
11660 12358
11661 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12359 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11662 { 12360 {
@@ -11780,18 +12478,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11780 } 12478 }
11781 } 12479 }
11782 12480
12481 // Double check this
11783 if (checkTerrain) 12482 if (checkTerrain)
11784 { 12483 {
11785 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12484 bool skipGroundCheck = false;
11786 if (groundContact != null) 12485
11787 results.Add((ContactResult)groundContact); 12486 foreach (ContactResult c in results)
12487 {
12488 if (c.ConsumerID == 0) // Physics gave us a ground collision
12489 skipGroundCheck = true;
12490 }
12491
12492 if (!skipGroundCheck)
12493 {
12494 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12495 if (groundContact != null)
12496 results.Add((ContactResult)groundContact);
12497 }
11788 } 12498 }
11789 12499
11790 results.Sort(delegate(ContactResult a, ContactResult b) 12500 results.Sort(delegate(ContactResult a, ContactResult b)
11791 { 12501 {
11792 return a.Depth.CompareTo(b.Depth); 12502 return a.Depth.CompareTo(b.Depth);
11793 }); 12503 });
11794 12504
11795 int values = 0; 12505 int values = 0;
11796 SceneObjectGroup thisgrp = m_host.ParentGroup; 12506 SceneObjectGroup thisgrp = m_host.ParentGroup;
11797 12507
@@ -11884,7 +12594,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11884 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12594 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11885 if (!isAccount) return 0; 12595 if (!isAccount) return 0;
11886 if (estate.HasAccess(id)) return 1; 12596 if (estate.HasAccess(id)) return 1;
11887 if (estate.IsBanned(id)) 12597 if (estate.IsBanned(id, World.GetUserFlags(id)))
11888 estate.RemoveBan(id); 12598 estate.RemoveBan(id);
11889 estate.AddEstateUser(id); 12599 estate.AddEstateUser(id);
11890 break; 12600 break;
@@ -11903,14 +12613,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11903 break; 12613 break;
11904 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12614 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11905 if (!isAccount) return 0; 12615 if (!isAccount) return 0;
11906 if (estate.IsBanned(id)) return 1; 12616 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11907 EstateBan ban = new EstateBan(); 12617 EstateBan ban = new EstateBan();
11908 ban.EstateID = estate.EstateID; 12618 ban.EstateID = estate.EstateID;
11909 ban.BannedUserID = id; 12619 ban.BannedUserID = id;
11910 estate.AddBan(ban); 12620 estate.AddBan(ban);
11911 break; 12621 break;
11912 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12622 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11913 if (!isAccount || !estate.IsBanned(id)) return 0; 12623 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11914 estate.RemoveBan(id); 12624 estate.RemoveBan(id);
11915 break; 12625 break;
11916 default: return 0; 12626 default: return 0;
@@ -11975,13 +12685,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11975 public void llCollisionSprite(string impact_sprite) 12685 public void llCollisionSprite(string impact_sprite)
11976 { 12686 {
11977 m_host.AddScriptLPS(1); 12687 m_host.AddScriptLPS(1);
11978 NotImplemented("llCollisionSprite"); 12688 // Viewer 2.0 broke this and it's likely LL has no intention
12689 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11979 } 12690 }
11980 12691
11981 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12692 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11982 { 12693 {
11983 m_host.AddScriptLPS(1); 12694 m_host.AddScriptLPS(1);
11984 NotImplemented("llGodLikeRezObject"); 12695
12696 if (!World.Permissions.IsGod(m_host.OwnerID))
12697 NotImplemented("llGodLikeRezObject");
12698
12699 AssetBase rezAsset = World.AssetService.Get(inventory);
12700 if (rezAsset == null)
12701 {
12702 llSay(0, "Asset not found");
12703 return;
12704 }
12705
12706 SceneObjectGroup group = null;
12707
12708 try
12709 {
12710 string xmlData = Utils.BytesToString(rezAsset.Data);
12711 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12712 }
12713 catch
12714 {
12715 llSay(0, "Asset not found");
12716 return;
12717 }
12718
12719 if (group == null)
12720 {
12721 llSay(0, "Asset not found");
12722 return;
12723 }
12724
12725 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12726 group.RootPart.AttachOffset = group.AbsolutePosition;
12727
12728 group.ResetIDs();
12729
12730 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12731 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12732 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12733 group.ScheduleGroupForFullUpdate();
12734
12735 // objects rezzed with this method are die_at_edge by default.
12736 group.RootPart.SetDieAtEdge(true);
12737
12738 group.ResumeScripts();
12739
12740 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12741 "object_rez", new Object[] {
12742 new LSL_String(
12743 group.RootPart.UUID.ToString()) },
12744 new DetectParams[0]));
11985 } 12745 }
11986 12746
11987 public LSL_String llTransferLindenDollars(string destination, int amount) 12747 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -12033,7 +12793,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12033 } 12793 }
12034 12794
12035 bool result = money.ObjectGiveMoney( 12795 bool result = money.ObjectGiveMoney(
12036 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12796 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
12037 12797
12038 if (result) 12798 if (result)
12039 { 12799 {
@@ -12058,6 +12818,610 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12058 } 12818 }
12059 12819
12060 #endregion 12820 #endregion
12821
12822 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12823 {
12824 SceneObjectGroup group = m_host.ParentGroup;
12825
12826 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12827 return;
12828 if (group.IsAttachment)
12829 return;
12830
12831 if (frames.Data.Length > 0) // We are getting a new motion
12832 {
12833 if (group.RootPart.KeyframeMotion != null)
12834 group.RootPart.KeyframeMotion.Delete();
12835 group.RootPart.KeyframeMotion = null;
12836
12837 int idx = 0;
12838
12839 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12840 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12841
12842 while (idx < options.Data.Length)
12843 {
12844 int option = (int)options.GetLSLIntegerItem(idx++);
12845 int remain = options.Data.Length - idx;
12846
12847 switch (option)
12848 {
12849 case ScriptBaseClass.KFM_MODE:
12850 if (remain < 1)
12851 break;
12852 int modeval = (int)options.GetLSLIntegerItem(idx++);
12853 switch(modeval)
12854 {
12855 case ScriptBaseClass.KFM_FORWARD:
12856 mode = KeyframeMotion.PlayMode.Forward;
12857 break;
12858 case ScriptBaseClass.KFM_REVERSE:
12859 mode = KeyframeMotion.PlayMode.Reverse;
12860 break;
12861 case ScriptBaseClass.KFM_LOOP:
12862 mode = KeyframeMotion.PlayMode.Loop;
12863 break;
12864 case ScriptBaseClass.KFM_PING_PONG:
12865 mode = KeyframeMotion.PlayMode.PingPong;
12866 break;
12867 }
12868 break;
12869 case ScriptBaseClass.KFM_DATA:
12870 if (remain < 1)
12871 break;
12872 int dataval = (int)options.GetLSLIntegerItem(idx++);
12873 data = (KeyframeMotion.DataFormat)dataval;
12874 break;
12875 }
12876 }
12877
12878 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12879
12880 idx = 0;
12881
12882 int elemLength = 2;
12883 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12884 elemLength = 3;
12885
12886 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12887 while (idx < frames.Data.Length)
12888 {
12889 int remain = frames.Data.Length - idx;
12890
12891 if (remain < elemLength)
12892 break;
12893
12894 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12895 frame.Position = null;
12896 frame.Rotation = null;
12897
12898 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12899 {
12900 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12901 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12902 }
12903 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12904 {
12905 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12906 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12907 q.Normalize();
12908 frame.Rotation = q;
12909 }
12910
12911 float tempf = (float)frames.GetLSLFloatItem(idx++);
12912 frame.TimeMS = (int)(tempf * 1000.0f);
12913
12914 keyframes.Add(frame);
12915 }
12916
12917 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12918 group.RootPart.KeyframeMotion.Start();
12919 }
12920 else
12921 {
12922 if (group.RootPart.KeyframeMotion == null)
12923 return;
12924
12925 if (options.Data.Length == 0)
12926 {
12927 group.RootPart.KeyframeMotion.Stop();
12928 return;
12929 }
12930
12931 int code = (int)options.GetLSLIntegerItem(0);
12932
12933 int idx = 0;
12934
12935 while (idx < options.Data.Length)
12936 {
12937 int option = (int)options.GetLSLIntegerItem(idx++);
12938 int remain = options.Data.Length - idx;
12939
12940 switch (option)
12941 {
12942 case ScriptBaseClass.KFM_COMMAND:
12943 int cmd = (int)options.GetLSLIntegerItem(idx++);
12944 switch (cmd)
12945 {
12946 case ScriptBaseClass.KFM_CMD_PLAY:
12947 group.RootPart.KeyframeMotion.Start();
12948 break;
12949 case ScriptBaseClass.KFM_CMD_STOP:
12950 group.RootPart.KeyframeMotion.Stop();
12951 break;
12952 case ScriptBaseClass.KFM_CMD_PAUSE:
12953 group.RootPart.KeyframeMotion.Pause();
12954 break;
12955 }
12956 break;
12957 }
12958 }
12959 }
12960 }
12961
12962 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12963 {
12964 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12965
12966 int idx = 0;
12967 int idxStart = 0;
12968
12969 bool positionChanged = false;
12970 Vector3 finalPos = Vector3.Zero;
12971
12972 try
12973 {
12974 while (idx < rules.Length)
12975 {
12976 ++rulesParsed;
12977 int code = rules.GetLSLIntegerItem(idx++);
12978
12979 int remain = rules.Length - idx;
12980 idxStart = idx;
12981
12982 switch (code)
12983 {
12984 case (int)ScriptBaseClass.PRIM_POSITION:
12985 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12986 {
12987 if (remain < 1)
12988 return null;
12989
12990 LSL_Vector v;
12991 v = rules.GetVector3Item(idx++);
12992
12993 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12994 if (part == null)
12995 break;
12996
12997 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12998 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12999 if (part.LinkNum > 1)
13000 {
13001 localRot = GetPartLocalRot(part);
13002 localPos = GetPartLocalPos(part);
13003 }
13004
13005 v -= localPos;
13006 v /= localRot;
13007
13008 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
13009
13010 v = v + 2 * sitOffset;
13011
13012 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
13013 av.SendAvatarDataToAllAgents();
13014
13015 }
13016 break;
13017
13018 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13019 case (int)ScriptBaseClass.PRIM_ROTATION:
13020 {
13021 if (remain < 1)
13022 return null;
13023
13024 LSL_Rotation r;
13025 r = rules.GetQuaternionItem(idx++);
13026
13027 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13028 if (part == null)
13029 break;
13030
13031 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13032 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13033
13034 if (part.LinkNum > 1)
13035 localRot = GetPartLocalRot(part);
13036
13037 r = r * llGetRootRotation() / localRot;
13038 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
13039 av.SendAvatarDataToAllAgents();
13040 }
13041 break;
13042
13043 // parse rest doing nothing but number of parameters error check
13044 case (int)ScriptBaseClass.PRIM_SIZE:
13045 case (int)ScriptBaseClass.PRIM_MATERIAL:
13046 case (int)ScriptBaseClass.PRIM_PHANTOM:
13047 case (int)ScriptBaseClass.PRIM_PHYSICS:
13048 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
13049 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13050 case (int)ScriptBaseClass.PRIM_NAME:
13051 case (int)ScriptBaseClass.PRIM_DESC:
13052 if (remain < 1)
13053 return null;
13054 idx++;
13055 break;
13056
13057 case (int)ScriptBaseClass.PRIM_GLOW:
13058 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13059 case (int)ScriptBaseClass.PRIM_TEXGEN:
13060 if (remain < 2)
13061 return null;
13062 idx += 2;
13063 break;
13064
13065 case (int)ScriptBaseClass.PRIM_TYPE:
13066 if (remain < 3)
13067 return null;
13068 code = (int)rules.GetLSLIntegerItem(idx++);
13069 remain = rules.Length - idx;
13070 switch (code)
13071 {
13072 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13073 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13074 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13075 if (remain < 6)
13076 return null;
13077 idx += 6;
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13081 if (remain < 5)
13082 return null;
13083 idx += 5;
13084 break;
13085
13086 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13087 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13088 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13089 if (remain < 11)
13090 return null;
13091 idx += 11;
13092 break;
13093
13094 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13095 if (remain < 2)
13096 return null;
13097 idx += 2;
13098 break;
13099 }
13100 break;
13101
13102 case (int)ScriptBaseClass.PRIM_COLOR:
13103 case (int)ScriptBaseClass.PRIM_TEXT:
13104 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13105 case (int)ScriptBaseClass.PRIM_OMEGA:
13106 if (remain < 3)
13107 return null;
13108 idx += 3;
13109 break;
13110
13111 case (int)ScriptBaseClass.PRIM_TEXTURE:
13112 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13113 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13114 if (remain < 5)
13115 return null;
13116 idx += 5;
13117 break;
13118
13119 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13120 if (remain < 7)
13121 return null;
13122
13123 idx += 7;
13124 break;
13125
13126 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13127 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13128 return null;
13129
13130 return rules.GetSublist(idx, -1);
13131 }
13132 }
13133 }
13134 catch (InvalidCastException e)
13135 {
13136 ShoutError(string.Format(
13137 "{0} error running rule #{1}: arg #{2} ",
13138 originFunc, rulesParsed, idx - idxStart) + e.Message);
13139 }
13140 finally
13141 {
13142 if (positionChanged)
13143 {
13144 av.OffsetPosition = finalPos;
13145// av.SendAvatarDataToAllAgents();
13146 av.SendTerseUpdateToAllClients();
13147 positionChanged = false;
13148 }
13149 }
13150 return null;
13151 }
13152
13153 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13154 {
13155 // avatars case
13156 // replies as SL wiki
13157
13158// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13159 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13160
13161 int idx = 0;
13162 while (idx < rules.Length)
13163 {
13164 int code = (int)rules.GetLSLIntegerItem(idx++);
13165 int remain = rules.Length - idx;
13166
13167 switch (code)
13168 {
13169 case (int)ScriptBaseClass.PRIM_MATERIAL:
13170 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13171 break;
13172
13173 case (int)ScriptBaseClass.PRIM_PHYSICS:
13174 res.Add(new LSL_Integer(0));
13175 break;
13176
13177 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13178 res.Add(new LSL_Integer(0));
13179 break;
13180
13181 case (int)ScriptBaseClass.PRIM_PHANTOM:
13182 res.Add(new LSL_Integer(0));
13183 break;
13184
13185 case (int)ScriptBaseClass.PRIM_POSITION:
13186
13187 Vector3 pos = avatar.OffsetPosition;
13188
13189 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13190 pos -= sitOffset;
13191
13192 if( sitPart != null)
13193 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13194
13195 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13196 break;
13197
13198 case (int)ScriptBaseClass.PRIM_SIZE:
13199 // as in llGetAgentSize above
13200// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13201 Vector3 s = avatar.Appearance.AvatarSize;
13202 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13203
13204 break;
13205
13206 case (int)ScriptBaseClass.PRIM_ROTATION:
13207 Quaternion rot = avatar.Rotation;
13208 if (sitPart != null)
13209 {
13210 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13211 }
13212
13213 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13214 break;
13215
13216 case (int)ScriptBaseClass.PRIM_TYPE:
13217 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13218 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13219 res.Add(new LSL_Vector(0f,1.0f,0f));
13220 res.Add(new LSL_Float(0.0f));
13221 res.Add(new LSL_Vector(0, 0, 0));
13222 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13223 res.Add(new LSL_Vector(0, 0, 0));
13224 break;
13225
13226 case (int)ScriptBaseClass.PRIM_TEXTURE:
13227 if (remain < 1)
13228 return null;
13229
13230 int face = (int)rules.GetLSLIntegerItem(idx++);
13231 if (face == ScriptBaseClass.ALL_SIDES)
13232 {
13233 for (face = 0; face < 21; face++)
13234 {
13235 res.Add(new LSL_String(""));
13236 res.Add(new LSL_Vector(0,0,0));
13237 res.Add(new LSL_Vector(0,0,0));
13238 res.Add(new LSL_Float(0.0));
13239 }
13240 }
13241 else
13242 {
13243 if (face >= 0 && face < 21)
13244 {
13245 res.Add(new LSL_String(""));
13246 res.Add(new LSL_Vector(0,0,0));
13247 res.Add(new LSL_Vector(0,0,0));
13248 res.Add(new LSL_Float(0.0));
13249 }
13250 }
13251 break;
13252
13253 case (int)ScriptBaseClass.PRIM_COLOR:
13254 if (remain < 1)
13255 return null;
13256
13257 face = (int)rules.GetLSLIntegerItem(idx++);
13258
13259 if (face == ScriptBaseClass.ALL_SIDES)
13260 {
13261 for (face = 0; face < 21; face++)
13262 {
13263 res.Add(new LSL_Vector(0,0,0));
13264 res.Add(new LSL_Float(0));
13265 }
13266 }
13267 else
13268 {
13269 res.Add(new LSL_Vector(0,0,0));
13270 res.Add(new LSL_Float(0));
13271 }
13272 break;
13273
13274 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13275 if (remain < 1)
13276 return null;
13277 face = (int)rules.GetLSLIntegerItem(idx++);
13278
13279 if (face == ScriptBaseClass.ALL_SIDES)
13280 {
13281 for (face = 0; face < 21; face++)
13282 {
13283 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13284 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13285 }
13286 }
13287 else
13288 {
13289 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13290 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13291 }
13292 break;
13293
13294 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13295 if (remain < 1)
13296 return null;
13297 face = (int)rules.GetLSLIntegerItem(idx++);
13298
13299 if (face == ScriptBaseClass.ALL_SIDES)
13300 {
13301 for (face = 0; face < 21; face++)
13302 {
13303 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13304 }
13305 }
13306 else
13307 {
13308 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13309 }
13310 break;
13311
13312 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13313 res.Add(new LSL_Integer(0));
13314 res.Add(new LSL_Integer(0));// softness
13315 res.Add(new LSL_Float(0.0f)); // gravity
13316 res.Add(new LSL_Float(0.0f)); // friction
13317 res.Add(new LSL_Float(0.0f)); // wind
13318 res.Add(new LSL_Float(0.0f)); // tension
13319 res.Add(new LSL_Vector(0f,0f,0f));
13320 break;
13321
13322 case (int)ScriptBaseClass.PRIM_TEXGEN:
13323 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13324 if (remain < 1)
13325 return null;
13326 face = (int)rules.GetLSLIntegerItem(idx++);
13327
13328 if (face == ScriptBaseClass.ALL_SIDES)
13329 {
13330 for (face = 0; face < 21; face++)
13331 {
13332 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13333 }
13334 }
13335 else
13336 {
13337 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13338 }
13339 break;
13340
13341 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13342 res.Add(new LSL_Integer(0));
13343 res.Add(new LSL_Vector(0f,0f,0f));
13344 res.Add(new LSL_Float(0f)); // intensity
13345 res.Add(new LSL_Float(0f)); // radius
13346 res.Add(new LSL_Float(0f)); // falloff
13347 break;
13348
13349 case (int)ScriptBaseClass.PRIM_GLOW:
13350 if (remain < 1)
13351 return null;
13352 face = (int)rules.GetLSLIntegerItem(idx++);
13353
13354 if (face == ScriptBaseClass.ALL_SIDES)
13355 {
13356 for (face = 0; face < 21; face++)
13357 {
13358 res.Add(new LSL_Float(0f));
13359 }
13360 }
13361 else
13362 {
13363 res.Add(new LSL_Float(0f));
13364 }
13365 break;
13366
13367 case (int)ScriptBaseClass.PRIM_TEXT:
13368 res.Add(new LSL_String(""));
13369 res.Add(new LSL_Vector(0f,0f,0f));
13370 res.Add(new LSL_Float(1.0f));
13371 break;
13372
13373 case (int)ScriptBaseClass.PRIM_NAME:
13374 res.Add(new LSL_String(avatar.Name));
13375 break;
13376
13377 case (int)ScriptBaseClass.PRIM_DESC:
13378 res.Add(new LSL_String(""));
13379 break;
13380
13381 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13382 Quaternion lrot = avatar.Rotation;
13383
13384 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13385 {
13386 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13387 }
13388 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13389 break;
13390
13391 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13392 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13393 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13394 lpos -= lsitOffset;
13395
13396 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13397 {
13398 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13399 }
13400 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13401 break;
13402
13403 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13404 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13405 return null;
13406
13407 return rules.GetSublist(idx, -1);
13408 }
13409 }
13410
13411 return null;
13412 }
13413
13414 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
13415 {
13416 if (m_UrlModule != null)
13417 {
13418 string type = "text.plain";
13419 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
13420 type = "text/html";
13421
13422 m_UrlModule.HttpContentType(new UUID(id),type);
13423 }
13424 }
12061 } 13425 }
12062 13426
12063 public class NotecardCache 13427 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
index 21bae27..bd776b6 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/MOD_Api.cs
@@ -136,7 +136,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType); 136// ((MethodInfo)MethodBase.GetCurrentMethod()).ReturnType);
137 137
138 Type returntype = m_comms.LookupReturnType(fname); 138 Type returntype = m_comms.LookupReturnType(fname);
139 if (returntype != typeof(string)) 139 if (returntype != typeof(void))
140 MODError(String.Format("return type mismatch for {0}",fname)); 140 MODError(String.Format("return type mismatch for {0}",fname));
141 141
142 modInvoke(fname,parms); 142 modInvoke(fname,parms);
@@ -329,6 +329,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
329 if (result != null) 329 if (result != null)
330 return result; 330 return result;
331 331
332 Type returntype = m_comms.LookupReturnType(fname);
333 if (returntype == typeof(void))
334 return null;
335
332 MODError(String.Format("Invocation of {0} failed; null return value",fname)); 336 MODError(String.Format("Invocation of {0} failed; null return value",fname));
333 } 337 }
334 catch (Exception e) 338 catch (Exception e)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 415166a..f4e4f44 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -139,6 +139,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 139 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
140 internal float m_ScriptDelayFactor = 1.0f; 140 internal float m_ScriptDelayFactor = 1.0f;
141 internal float m_ScriptDistanceFactor = 1.0f; 141 internal float m_ScriptDistanceFactor = 1.0f;
142 internal bool m_debuggerSafe = false;
142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 143 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
143 144
144 protected IUrlModule m_UrlModule = null; 145 protected IUrlModule m_UrlModule = null;
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
149 m_ScriptEngine = scriptEngine; 150 m_ScriptEngine = scriptEngine;
150 m_host = host; 151 m_host = host;
151 m_item = item; 152 m_item = item;
153 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
152 154
153 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 155 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
154 156
@@ -212,7 +214,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
212 214
213 internal void OSSLError(string msg) 215 internal void OSSLError(string msg)
214 { 216 {
215 throw new ScriptException("OSSL Runtime Error: " + msg); 217 if (m_debuggerSafe)
218 {
219 OSSLShoutError(msg);
220 }
221 else
222 {
223 throw new ScriptException("OSSL Runtime Error: " + msg);
224 }
216 } 225 }
217 226
218 /// <summary> 227 /// <summary>
@@ -931,18 +940,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
931 if (target != null) 940 if (target != null)
932 { 941 {
933 UUID animID=UUID.Zero; 942 UUID animID=UUID.Zero;
934 lock (m_host.TaskInventory) 943 m_host.TaskInventory.LockItemsForRead(true);
944 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
935 { 945 {
936 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 946 if (inv.Value.Name == animation)
937 { 947 {
938 if (inv.Value.Name == animation) 948 if (inv.Value.Type == (int)AssetType.Animation)
939 { 949 animID = inv.Value.AssetID;
940 if (inv.Value.Type == (int)AssetType.Animation) 950 continue;
941 animID = inv.Value.AssetID;
942 continue;
943 }
944 } 951 }
945 } 952 }
953 m_host.TaskInventory.LockItemsForRead(false);
946 if (animID == UUID.Zero) 954 if (animID == UUID.Zero)
947 target.Animator.AddAnimation(animation, m_host.UUID); 955 target.Animator.AddAnimation(animation, m_host.UUID);
948 else 956 else
@@ -983,6 +991,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
983 else 991 else
984 animID = UUID.Zero; 992 animID = UUID.Zero;
985 } 993 }
994 m_host.TaskInventory.LockItemsForRead(false);
986 995
987 if (animID == UUID.Zero) 996 if (animID == UUID.Zero)
988 target.Animator.RemoveAnimation(animation); 997 target.Animator.RemoveAnimation(animation);
@@ -1645,7 +1654,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 } 1654 }
1646 } 1655 }
1647 1656
1648 public Object osParseJSONNew(string JSON) 1657 private Object osParseJSONNew(string JSON)
1649 { 1658 {
1650 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew"); 1659 CheckThreatLevel(ThreatLevel.None, "osParseJSONNew");
1651 1660
@@ -1847,15 +1856,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 { 1856 {
1848 UUID assetID = UUID.Zero; 1857 UUID assetID = UUID.Zero;
1849 1858
1850 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1859 bool notecardNameIsUUID = UUID.TryParse(notecardNameOrUuid, out assetID);
1860
1861 if (!notecardNameIsUUID)
1851 { 1862 {
1852 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1863 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1853 {
1854 if (item.Type == 7 && item.Name == notecardNameOrUuid)
1855 {
1856 assetID = item.AssetID;
1857 }
1858 }
1859 } 1864 }
1860 1865
1861 if (assetID == UUID.Zero) 1866 if (assetID == UUID.Zero)
@@ -1866,7 +1871,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1866 AssetBase a = World.AssetService.Get(assetID.ToString()); 1871 AssetBase a = World.AssetService.Get(assetID.ToString());
1867 1872
1868 if (a == null) 1873 if (a == null)
1869 return UUID.Zero; 1874 {
1875 // Whoops, it's still possible here that the notecard name was properly
1876 // formatted like a UUID but isn't an asset UUID so lets look it up by name after all
1877 assetID = SearchTaskInventoryForAssetId(notecardNameOrUuid);
1878 if (assetID == UUID.Zero)
1879 return UUID.Zero;
1880
1881 if (!NotecardCache.IsCached(assetID))
1882 {
1883 a = World.AssetService.Get(assetID.ToString());
1884
1885 if (a == null)
1886 {
1887 return UUID.Zero;
1888 }
1889 }
1890 }
1870 1891
1871 string data = Encoding.UTF8.GetString(a.Data); 1892 string data = Encoding.UTF8.GetString(a.Data);
1872 NotecardCache.Cache(assetID, data); 1893 NotecardCache.Cache(assetID, data);
@@ -1874,6 +1895,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1874 1895
1875 return assetID; 1896 return assetID;
1876 } 1897 }
1898 protected UUID SearchTaskInventoryForAssetId(string name)
1899 {
1900 UUID assetId = UUID.Zero;
1901 m_host.TaskInventory.LockItemsForRead(true);
1902 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1903 {
1904 if (item.Type == 7 && item.Name == name)
1905 {
1906 assetId = item.AssetID;
1907 }
1908 }
1909 m_host.TaskInventory.LockItemsForRead(false);
1910 return assetId;
1911 }
1877 1912
1878 /// <summary> 1913 /// <summary>
1879 /// Directly get an entire notecard at once. 1914 /// Directly get an entire notecard at once.
@@ -2351,7 +2386,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2351 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2386 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2352 m_host.AddScriptLPS(1); 2387 m_host.AddScriptLPS(1);
2353 2388
2354 return NpcCreate(firstname, lastname, position, notecard, false, false); 2389 return NpcCreate(firstname, lastname, position, notecard, true, false);
2355 } 2390 }
2356 2391
2357 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2392 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2362,24 +2397,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2362 return NpcCreate( 2397 return NpcCreate(
2363 firstname, lastname, position, notecard, 2398 firstname, lastname, position, notecard,
2364 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2399 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2365 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2400 false);
2401// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2366 } 2402 }
2367 2403
2368 private LSL_Key NpcCreate( 2404 private LSL_Key NpcCreate(
2369 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2405 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2370 { 2406 {
2407 if (!owned)
2408 OSSLError("Unowned NPCs are unsupported");
2409
2410 string groupTitle = String.Empty;
2411
2412 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2413 return new LSL_Key(UUID.Zero.ToString());
2414
2415 if (firstname != String.Empty || lastname != String.Empty)
2416 {
2417 if (firstname != "Shown outfit:")
2418 groupTitle = "- NPC -";
2419 }
2420
2371 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2421 INPCModule module = World.RequestModuleInterface<INPCModule>();
2372 if (module != null) 2422 if (module != null)
2373 { 2423 {
2374 AvatarAppearance appearance = null; 2424 AvatarAppearance appearance = null;
2375 2425
2376 UUID id; 2426// UUID id;
2377 if (UUID.TryParse(notecard, out id)) 2427// if (UUID.TryParse(notecard, out id))
2378 { 2428// {
2379 ScenePresence clonePresence = World.GetScenePresence(id); 2429// ScenePresence clonePresence = World.GetScenePresence(id);
2380 if (clonePresence != null) 2430// if (clonePresence != null)
2381 appearance = clonePresence.Appearance; 2431// appearance = clonePresence.Appearance;
2382 } 2432// }
2383 2433
2384 if (appearance == null) 2434 if (appearance == null)
2385 { 2435 {
@@ -2387,9 +2437,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2387 2437
2388 if (appearanceSerialized != null) 2438 if (appearanceSerialized != null)
2389 { 2439 {
2390 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2440 try
2391 appearance = new AvatarAppearance(); 2441 {
2392 appearance.Unpack(appearanceOsd); 2442 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2443 appearance = new AvatarAppearance();
2444 appearance.Unpack(appearanceOsd);
2445 }
2446 catch
2447 {
2448 return UUID.Zero.ToString();
2449 }
2393 } 2450 }
2394 else 2451 else
2395 { 2452 {
@@ -2408,6 +2465,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2408 World, 2465 World,
2409 appearance); 2466 appearance);
2410 2467
2468 ScenePresence sp;
2469 if (World.TryGetScenePresence(x, out sp))
2470 {
2471 sp.Grouptitle = groupTitle;
2472 sp.SendAvatarDataToAllAgents();
2473 }
2411 return new LSL_Key(x.ToString()); 2474 return new LSL_Key(x.ToString());
2412 } 2475 }
2413 2476
@@ -2705,16 +2768,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2705 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2768 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2706 m_host.AddScriptLPS(1); 2769 m_host.AddScriptLPS(1);
2707 2770
2708 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2771 ManualResetEvent ev = new ManualResetEvent(false);
2709 if (module != null)
2710 {
2711 UUID npcId = new UUID(npc.m_string);
2712 2772
2713 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2773 Util.FireAndForget(delegate(object x) {
2714 return; 2774 try
2775 {
2776 INPCModule module = World.RequestModuleInterface<INPCModule>();
2777 if (module != null)
2778 {
2779 UUID npcId = new UUID(npc.m_string);
2715 2780
2716 module.DeleteNPC(npcId, World); 2781 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2717 } 2782 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2783 {
2784 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2785 return;
2786 }
2787
2788 module.DeleteNPC(npcId, World);
2789 }
2790 }
2791 finally
2792 {
2793 ev.Set();
2794 }
2795 });
2796 ev.WaitOne();
2718 } 2797 }
2719 2798
2720 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2799 public void osNpcPlayAnimation(LSL_Key npc, string animation)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 88ab515..a47e452 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -93,7 +93,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
93 private const int AGENT = 1; 93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10; 94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20; 95 private const int NPC = 0x20;
96 private const int OS_NPC = 0x01000000;
97 private const int ACTIVE = 2; 96 private const int ACTIVE = 2;
98 private const int PASSIVE = 4; 97 private const int PASSIVE = 4;
99 private const int SCRIPTED = 8; 98 private const int SCRIPTED = 8;
@@ -240,7 +239,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
240 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 239 List<SensedEntity> sensedEntities = new List<SensedEntity>();
241 240
242 // Is the sensor type is AGENT and not SCRIPTED then include agents 241 // Is the sensor type is AGENT and not SCRIPTED then include agents
243 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC | OS_NPC)) != 0 && (ts.type & SCRIPTED) == 0) 242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 { 243 {
245 sensedEntities.AddRange(doAgentSensor(ts)); 244 sensedEntities.AddRange(doAgentSensor(ts));
246 } 245 }
@@ -339,7 +338,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
339 float dy; 338 float dy;
340 float dz; 339 float dz;
341 340
342 Quaternion q = SensePoint.GetWorldRotation(); 341// Quaternion q = SensePoint.RotationOffset;
342 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
343 if (SensePoint.ParentGroup.IsAttachment) 343 if (SensePoint.ParentGroup.IsAttachment)
344 { 344 {
345 // In attachments, rotate the sensor cone with the 345 // In attachments, rotate the sensor cone with the
@@ -353,7 +353,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
353 // Position of a sensor in a child prim attached to an avatar 353 // Position of a sensor in a child prim attached to an avatar
354 // will be still wrong. 354 // will be still wrong.
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
356 q = avatar.GetWorldRotation() * q; 356 fromRegionPos = avatar.AbsolutePosition;
357 q = avatar.Rotation;
357 } 358 }
358 359
359 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 360 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -397,7 +398,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
397 objtype = 0; 398 objtype = 0;
398 399
399 part = ((SceneObjectGroup)ent).RootPart; 400 part = ((SceneObjectGroup)ent).RootPart;
400 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore 401 if (part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.Tree &&
402 part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.NewTree &&
403 part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
401 continue; 404 continue;
402 405
403 if (part.Inventory.ContainsScripts()) 406 if (part.Inventory.ContainsScripts())
@@ -480,7 +483,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
480 // Position of a sensor in a child prim attached to an avatar 483 // Position of a sensor in a child prim attached to an avatar
481 // will be still wrong. 484 // will be still wrong.
482 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 485 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
483 q = avatar.GetWorldRotation() * q; 486 if (avatar == null)
487 return sensedEntities;
488 fromRegionPos = avatar.AbsolutePosition;
489 q = avatar.Rotation;
484 } 490 }
485 491
486 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 492 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -496,7 +502,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
496// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 502// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
497// presence.Name, presence.PresenceType, ts.name, ts.type); 503// presence.Name, presence.PresenceType, ts.name, ts.type);
498 504
499 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 505 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
500 { 506 {
501 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 507 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
502 if (npcData == null || !npcData.SenseAsAgent) 508 if (npcData == null || !npcData.SenseAsAgent)
@@ -696,4 +702,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
696 return retList; 702 return retList;
697 } 703 }
698 } 704 }
699} \ No newline at end of file 705}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index 0b14565..68aacd2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -123,25 +123,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
123 if (Timers.Count == 0) 123 if (Timers.Count == 0)
124 return; 124 return;
125 125
126 Dictionary<string, TimerInfo>.ValueCollection tvals;
126 lock (TimerListLock) 127 lock (TimerListLock)
127 { 128 {
128 // Go through all timers 129 // Go through all timers
129 Dictionary<string, TimerInfo>.ValueCollection tvals = Timers.Values; 130 tvals = Timers.Values;
130 foreach (TimerInfo ts in tvals) 131 }
132
133 foreach (TimerInfo ts in tvals)
134 {
135 // Time has passed?
136 if (ts.next < DateTime.Now.Ticks)
131 { 137 {
132 // Time has passed? 138 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
133 if (ts.next < DateTime.Now.Ticks) 139 // Add it to queue
134 { 140 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
135 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 141 new EventParams("timer", new Object[0],
136 // Add it to queue 142 new DetectParams[0]));
137 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 143 // set next interval
138 new EventParams("timer", new Object[0], 144
139 new DetectParams[0])); 145 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
140 // set next interval 146 ts.next = DateTime.Now.Ticks + ts.interval;
141
142 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
143 ts.next = DateTime.Now.Ticks + ts.interval;
144 }
145 } 147 }
146 } 148 }
147 } 149 }
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 a6ea88c..daf89e5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 void llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
211 LSL_String llTransferLindenDollars(string destination, int amount); 212 LSL_String llTransferLindenDollars(string destination, int amount);
212 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
213 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
@@ -331,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
331 void llSensorRemove(); 332 void llSensorRemove();
332 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
333 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
334 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
335 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
336 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -357,11 +359,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
357 void llSetParcelMusicURL(string url); 359 void llSetParcelMusicURL(string url);
358 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 360 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
359 void llSetPos(LSL_Vector pos); 361 void llSetPos(LSL_Vector pos);
362 LSL_Integer llSetRegionPos(LSL_Vector pos);
360 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
361 void llSetPrimitiveParams(LSL_List rules); 364 void llSetPrimitiveParams(LSL_List rules);
362 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
363 void llSetPrimURL(string url); 366 void llSetPrimURL(string url);
364 LSL_Integer llSetRegionPos(LSL_Vector pos);
365 void llSetRemoteScriptAccessPin(int pin); 367 void llSetRemoteScriptAccessPin(int pin);
366 void llSetRot(LSL_Rotation rot); 368 void llSetRot(LSL_Rotation rot);
367 void llSetScale(LSL_Vector scale); 369 void llSetScale(LSL_Vector scale);
@@ -381,6 +383,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
381 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 383 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
382 void llSetVehicleType(int type); 384 void llSetVehicleType(int type);
383 void llSetVehicleVectorParam(int param, LSL_Vector vec); 385 void llSetVehicleVectorParam(int param, LSL_Vector vec);
386 void llSetVelocity(LSL_Vector velocity, int local);
384 void llShout(int channelID, string text); 387 void llShout(int channelID, string text);
385 LSL_Float llSin(double f); 388 LSL_Float llSin(double f);
386 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 389 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -424,10 +427,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
424 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
425 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
426 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
427 void print(string str); 430 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
431 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
428 432
429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
430 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
431 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
436 LSL_List llGetPhysicsMaterial();
437 void llSetContentType(LSL_Key id, LSL_Integer content_type);
432 } 438 }
433} 439}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 51d0581..a652cb8 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -144,7 +144,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
144 // Avatar Info Commands 144 // Avatar Info Commands
145 string osGetAgentIP(string agent); 145 string osGetAgentIP(string agent);
146 LSL_List osGetAgents(); 146 LSL_List osGetAgents();
147 147
148 // Teleport commands 148 // Teleport commands
149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 149 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 150 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
@@ -260,7 +260,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
260 string osGetScriptEngineName(); 260 string osGetScriptEngineName();
261 string osGetSimulatorVersion(); 261 string osGetSimulatorVersion();
262 string osGetPhysicsEngineType(); 262 string osGetPhysicsEngineType();
263 Object osParseJSONNew(string JSON);
264 Hashtable osParseJSON(string JSON); 263 Hashtable osParseJSON(string JSON);
265 264
266 void osMessageObject(key objectUUID,string message); 265 void osMessageObject(key objectUUID,string message);
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 559068d..6efa73f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -56,7 +56,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
56 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
57 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
58 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
59 public const int OS_NPC = 0x01000000;
60 59
61 public const int CONTROL_FWD = 1; 60 public const int CONTROL_FWD = 1;
62 public const int CONTROL_BACK = 2; 61 public const int CONTROL_BACK = 2;
@@ -81,6 +80,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
81 public const int PERMISSION_CHANGE_PERMISSIONS = 512; 80 public const int PERMISSION_CHANGE_PERMISSIONS = 512;
82 public const int PERMISSION_TRACK_CAMERA = 1024; 81 public const int PERMISSION_TRACK_CAMERA = 1024;
83 public const int PERMISSION_CONTROL_CAMERA = 2048; 82 public const int PERMISSION_CONTROL_CAMERA = 2048;
83 public const int PERMISSION_TELEPORT = 4096;
84 84
85 public const int AGENT_FLYING = 1; 85 public const int AGENT_FLYING = 1;
86 public const int AGENT_ATTACHMENTS = 2; 86 public const int AGENT_ATTACHMENTS = 2;
@@ -95,6 +95,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
95 public const int AGENT_CROUCHING = 1024; 95 public const int AGENT_CROUCHING = 1024;
96 public const int AGENT_BUSY = 2048; 96 public const int AGENT_BUSY = 2048;
97 public const int AGENT_ALWAYS_RUN = 4096; 97 public const int AGENT_ALWAYS_RUN = 4096;
98 public const int AGENT_MALE = 8192;
98 99
99 //Particle Systems 100 //Particle Systems
100 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 101 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -337,6 +338,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
337 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 338 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
338 public const int CHANGED_MEDIA = 2048; 339 public const int CHANGED_MEDIA = 2048;
339 public const int CHANGED_ANIMATION = 16384; 340 public const int CHANGED_ANIMATION = 16384;
341 public const int CHANGED_POSITION = 32768;
340 public const int TYPE_INVALID = 0; 342 public const int TYPE_INVALID = 0;
341 public const int TYPE_INTEGER = 1; 343 public const int TYPE_INTEGER = 1;
342 public const int TYPE_FLOAT = 2; 344 public const int TYPE_FLOAT = 2;
@@ -674,7 +676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
674 public const int FRICTION = 2; 676 public const int FRICTION = 2;
675 public const int RESTITUTION = 4; 677 public const int RESTITUTION = 4;
676 public const int GRAVITY_MULTIPLIER = 8; 678 public const int GRAVITY_MULTIPLIER = 8;
677 679
678 // extra constants for llSetPrimMediaParams 680 // extra constants for llSetPrimMediaParams
679 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 681 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
680 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); 682 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
@@ -746,7 +748,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
746 748
747 public static readonly LSLInteger RCERR_UNKNOWN = -1; 749 public static readonly LSLInteger RCERR_UNKNOWN = -1;
748 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 750 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
749 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 751 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
750 752
751 public const int KFM_MODE = 1; 753 public const int KFM_MODE = 1;
752 public const int KFM_LOOP = 1; 754 public const int KFM_LOOP = 1;
@@ -770,5 +772,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
770 /// process message parameter as regex 772 /// process message parameter as regex
771 /// </summary> 773 /// </summary>
772 public const int OS_LISTEN_REGEX_MESSAGE = 0x2; 774 public const int OS_LISTEN_REGEX_MESSAGE = 0x2;
775
776 public const int CONTENT_TYPE_TEXT = 0;
777 public const int CONTENT_TYPE_HTML = 1;
773 } 778 }
774} 779}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 398c125..6f3677c 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();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -554,11 +561,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
554 return m_LSL_Functions.llGetLinkNumberOfSides(link); 561 return m_LSL_Functions.llGetLinkNumberOfSides(link);
555 } 562 }
556 563
557 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
558 {
559 m_LSL_Functions.llSetKeyframedMotion(frames, options);
560 }
561
562 public LSL_Integer llGetListEntryType(LSL_List src, int index) 564 public LSL_Integer llGetListEntryType(LSL_List src, int index)
563 { 565 {
564 return m_LSL_Functions.llGetListEntryType(src, index); 566 return m_LSL_Functions.llGetListEntryType(src, index);
@@ -584,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
584 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
585 } 587 }
586 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
587 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
588 { 595 {
589 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -849,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
849 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
850 } 857 }
851 858
852 public LSL_Integer llGetUsedMemory()
853 {
854 return m_LSL_Functions.llGetUsedMemory();
855 }
856
857 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
858 { 860 {
859 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,9 +876,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 m_LSL_Functions.llGiveInventoryList(destination, category, inventory); 876 m_LSL_Functions.llGiveInventoryList(destination, category, inventory);
875 } 877 }
876 878
877 public void llGiveMoney(string destination, int amount) 879 public LSL_Integer llGiveMoney(string destination, int amount)
878 { 880 {
879 m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
880 } 882 }
881 883
882 public LSL_String llTransferLindenDollars(string destination, int amount) 884 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -1493,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1493 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1494 } 1496 }
1495 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1496 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1497 { 1504 {
1498 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1618,6 +1625,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1618 m_LSL_Functions.llSetPos(pos); 1625 m_LSL_Functions.llSetPos(pos);
1619 } 1626 }
1620 1627
1628 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1629 {
1630 return m_LSL_Functions.llSetRegionPos(pos);
1631 }
1632
1621 public void llSetPrimitiveParams(LSL_List rules) 1633 public void llSetPrimitiveParams(LSL_List rules)
1622 { 1634 {
1623 m_LSL_Functions.llSetPrimitiveParams(rules); 1635 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1633,11 +1645,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1633 m_LSL_Functions.llSetPrimURL(url); 1645 m_LSL_Functions.llSetPrimURL(url);
1634 } 1646 }
1635 1647
1636 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1637 {
1638 return m_LSL_Functions.llSetRegionPos(pos);
1639 }
1640
1641 public void llSetRemoteScriptAccessPin(int pin) 1648 public void llSetRemoteScriptAccessPin(int pin)
1642 { 1649 {
1643 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1650 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1733,6 +1740,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1733 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1740 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1734 } 1741 }
1735 1742
1743 public void llSetVelocity(LSL_Vector velocity, int local)
1744 {
1745 m_LSL_Functions.llSetVelocity(velocity, local);
1746 }
1747
1736 public void llShout(int channelID, string text) 1748 public void llShout(int channelID, string text)
1737 { 1749 {
1738 m_LSL_Functions.llShout(channelID, text); 1750 m_LSL_Functions.llShout(channelID, text);
@@ -1983,9 +1995,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1983 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1984 } 1996 }
1985 1997
1986 public void print(string str) 1998 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1999 {
2000 return m_LSL_Functions.llGetLinkNumberOfSides(link);
2001 }
2002
2003 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
2004 {
2005 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2006 }
2007
2008 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
2009 {
2010 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
2011 }
2012
2013 public LSL_List llGetPhysicsMaterial()
2014 {
2015 return m_LSL_Functions.llGetPhysicsMaterial();
2016 }
2017
2018 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
1987 { 2019 {
1988 m_LSL_Functions.print(str); 2020 m_LSL_Functions.llSetContentType(id, content_type);
1989 } 2021 }
1990 } 2022 }
1991} 2023}
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/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index c9902e4..b63773b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -435,11 +435,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
435 return m_OSSL_Functions.osParseJSON(JSON); 435 return m_OSSL_Functions.osParseJSON(JSON);
436 } 436 }
437 437
438 public Object osParseJSONNew(string JSON)
439 {
440 return m_OSSL_Functions.osParseJSONNew(JSON);
441 }
442
443 public void osMessageObject(key objectUUID,string message) 438 public void osMessageObject(key objectUUID,string message)
444 { 439 {
445 m_OSSL_Functions.osMessageObject(objectUUID,message); 440 m_OSSL_Functions.osMessageObject(objectUUID,message);
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 e02d35e..e44a106 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;
38using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
39 40
40namespace OpenSim.Region.ScriptEngine.Shared 41namespace OpenSim.Region.ScriptEngine.Shared
@@ -120,6 +121,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
120 Type = 0; 121 Type = 0;
121 Velocity = new LSL_Types.Vector3(); 122 Velocity = new LSL_Types.Vector3();
122 initializeSurfaceTouch(); 123 initializeSurfaceTouch();
124 Country = String.Empty;
123 } 125 }
124 126
125 public UUID Key; 127 public UUID Key;
@@ -151,6 +153,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
151 private int touchFace; 153 private int touchFace;
152 public int TouchFace { get { return touchFace; } } 154 public int TouchFace { get { return touchFace; } }
153 155
156 public string Country;
157
154 // This can be done in two places including the constructor 158 // This can be done in two places including the constructor
155 // so be carefull what gets added here 159 // so be carefull what gets added here
156 private void initializeSurfaceTouch() 160 private void initializeSurfaceTouch()
@@ -198,6 +202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
198 return; 202 return;
199 203
200 Name = presence.Firstname + " " + presence.Lastname; 204 Name = presence.Firstname + " " + presence.Lastname;
205 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
206 if (account != null)
207 Country = account.UserCountry;
208
201 Owner = Key; 209 Owner = Key;
202 Position = new LSL_Types.Vector3(presence.AbsolutePosition); 210 Position = new LSL_Types.Vector3(presence.AbsolutePosition);
203 Rotation = new LSL_Types.Quaternion( 211 Rotation = new LSL_Types.Quaternion(
@@ -207,22 +215,27 @@ namespace OpenSim.Region.ScriptEngine.Shared
207 presence.Rotation.W); 215 presence.Rotation.W);
208 Velocity = new LSL_Types.Vector3(presence.Velocity); 216 Velocity = new LSL_Types.Vector3(presence.Velocity);
209 217
210 if (presence.PresenceType != PresenceType.Npc) 218 Type = 0x01; // Avatar
211 { 219 if (presence.PresenceType == PresenceType.Npc)
212 Type = AGENT; 220 Type = 0x20;
213 } 221
214 else 222 // Cope Impl. We don't use OS_NPC.
215 { 223 //if (presence.PresenceType != PresenceType.Npc)
216 Type = OS_NPC; 224 //{
217 225 // Type = AGENT;
218 INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); 226 //}
219 INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene); 227 //else
220 228 //{
221 if (npcData.SenseAsAgent) 229 // Type = OS_NPC;
222 { 230
223 Type |= AGENT; 231 // INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
224 } 232 // INPC npcData = npcModule.GetNPC(presence.UUID, presence.Scene);
225 } 233
234 // if (npcData.SenseAsAgent)
235 // {
236 // Type |= AGENT;
237 // }
238 //}
226 239
227 if (presence.Velocity != Vector3.Zero) 240 if (presence.Velocity != Vector3.Zero)
228 Type |= ACTIVE; 241 Type |= ACTIVE;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 887a317..8da06d1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -165,13 +166,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
165 166
166 public UUID ItemID { get; private set; } 167 public UUID ItemID { get; private set; }
167 168
168 public UUID ObjectID { get { return Part.UUID; } } 169 public UUID ObjectID { get; private set; }
169 170
170 public uint LocalID { get { return Part.LocalId; } } 171 public uint LocalID { get; private set; }
171 172
172 public UUID RootObjectID { get { return Part.ParentGroup.UUID; } } 173 public UUID RootObjectID { get; private set; }
173 174
174 public uint RootLocalID { get { return Part.ParentGroup.LocalId; } } 175 public uint RootLocalID { get; private set; }
175 176
176 public UUID AssetID { get; private set; } 177 public UUID AssetID { get; private set; }
177 178
@@ -235,8 +236,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
235 StartParam = startParam; 236 StartParam = startParam;
236 m_MaxScriptQueue = maxScriptQueue; 237 m_MaxScriptQueue = maxScriptQueue;
237 m_postOnRez = postOnRez; 238 m_postOnRez = postOnRez;
238 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 239 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
239 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 240 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
240 241
241 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") 242 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
242 { 243 {
@@ -481,27 +482,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
481 PostEvent(new EventParams("attach", 482 PostEvent(new EventParams("attach",
482 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 483 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
483 } 484 }
485
484 } 486 }
485 } 487 }
486 488
487 private void ReleaseControls() 489 private void ReleaseControls()
488 { 490 {
489 int permsMask; 491 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
490 UUID permsGranter; 492
491 lock (Part.TaskInventory) 493 if (part != null)
492 { 494 {
493 if (!Part.TaskInventory.ContainsKey(ItemID)) 495 int permsMask;
496 UUID permsGranter;
497 part.TaskInventory.LockItemsForRead(true);
498 if (!part.TaskInventory.ContainsKey(ItemID))
499 {
500 part.TaskInventory.LockItemsForRead(false);
494 return; 501 return;
502 }
503 permsGranter = part.TaskInventory[ItemID].PermsGranter;
504 permsMask = part.TaskInventory[ItemID].PermsMask;
505 part.TaskInventory.LockItemsForRead(false);
495 506
496 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 507 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
497 permsMask = Part.TaskInventory[ItemID].PermsMask; 508 {
498 } 509 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
499 510 if (presence != null)
500 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 511 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
501 { 512 }
502 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
503 if (presence != null)
504 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
505 } 513 }
506 } 514 }
507 515
@@ -656,6 +664,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
656 return true; 664 return true;
657 } 665 }
658 666
667 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
659 public void SetState(string state) 668 public void SetState(string state)
660 { 669 {
661 if (state == State) 670 if (state == State)
@@ -667,7 +676,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
667 new DetectParams[0])); 676 new DetectParams[0]));
668 PostEvent(new EventParams("state_entry", new Object[0], 677 PostEvent(new EventParams("state_entry", new Object[0],
669 new DetectParams[0])); 678 new DetectParams[0]));
670 679
671 throw new EventAbortException(); 680 throw new EventAbortException();
672 } 681 }
673 682
@@ -757,57 +766,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
757 /// <returns></returns> 766 /// <returns></returns>
758 public object EventProcessor() 767 public object EventProcessor()
759 { 768 {
769 EventParams data = null;
760 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 770 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
761 if (!Running) 771 if (!Running)
762 return 0; 772 return 0;
763 773
764 lock (m_Script)
765 {
766// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 774// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
767 775
768 if (Suspended) 776 if (Suspended)
769 return 0; 777 return 0;
770
771 EventParams data = null;
772 778
773 lock (EventQueue) 779 lock (EventQueue)
780 {
781 data = (EventParams) EventQueue.Dequeue();
782 if (data == null) // Shouldn't happen
774 { 783 {
775 data = (EventParams)EventQueue.Dequeue(); 784 if (EventQueue.Count > 0 && Running && !ShuttingDown)
776 if (data == null) // Shouldn't happen
777 { 785 {
778 if (EventQueue.Count > 0 && Running && !ShuttingDown) 786 m_CurrentWorkItem = Engine.QueueEventHandler(this);
779 {
780 m_CurrentWorkItem = Engine.QueueEventHandler(this);
781 }
782 else
783 {
784 m_CurrentWorkItem = null;
785 }
786 return 0;
787 } 787 }
788 788 else
789 if (data.EventName == "timer")
790 m_TimerQueued = false;
791 if (data.EventName == "control")
792 { 789 {
793 if (m_ControlEventsInQueue > 0) 790 m_CurrentWorkItem = null;
794 m_ControlEventsInQueue--;
795 } 791 }
796 if (data.EventName == "collision") 792 return 0;
797 m_CollisionInQueue = false;
798 } 793 }
799 794
795 if (data.EventName == "timer")
796 m_TimerQueued = false;
797 if (data.EventName == "control")
798 {
799 if (m_ControlEventsInQueue > 0)
800 m_ControlEventsInQueue--;
801 }
802 if (data.EventName == "collision")
803 m_CollisionInQueue = false;
804 }
805
806 lock(m_Script)
807 {
808
809// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
810 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
811
800 if (DebugLevel >= 2) 812 if (DebugLevel >= 2)
801 m_log.DebugFormat( 813 m_log.DebugFormat(
802 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 814 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
803 data.EventName, 815 data.EventName,
804 ScriptName, 816 ScriptName,
805 Part.Name, 817 part.Name,
806 Part.LocalId, 818 part.LocalId,
807 Part.ParentGroup.Name, 819 part.ParentGroup.Name,
808 Part.ParentGroup.UUID, 820 part.ParentGroup.UUID,
809 Part.AbsolutePosition, 821 part.AbsolutePosition,
810 Part.ParentGroup.Scene.Name); 822 part.ParentGroup.Scene.Name);
811 823
812 m_DetectParams = data.DetectParams; 824 m_DetectParams = data.DetectParams;
813 825
@@ -820,17 +832,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
820 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 832 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
821 State, 833 State,
822 ScriptName, 834 ScriptName,
823 Part.Name, 835 part.Name,
824 Part.LocalId, 836 part.LocalId,
825 Part.ParentGroup.Name, 837 part.ParentGroup.Name,
826 Part.ParentGroup.UUID, 838 part.ParentGroup.UUID,
827 Part.AbsolutePosition, 839 part.AbsolutePosition,
828 Part.ParentGroup.Scene.Name); 840 part.ParentGroup.Scene.Name);
829 841
830 AsyncCommandManager.RemoveScript(Engine, 842 AsyncCommandManager.RemoveScript(Engine,
831 LocalID, ItemID); 843 LocalID, ItemID);
832 844
833 Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); 845 if (part != null)
846 {
847 part.SetScriptEvents(ItemID,
848 (int)m_Script.GetStateEventFlags(State));
849 }
834 } 850 }
835 else 851 else
836 { 852 {
@@ -893,17 +909,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
893 text = text.Substring(0, 1000); 909 text = text.Substring(0, 1000);
894 Engine.World.SimChat(Utils.StringToBytes(text), 910 Engine.World.SimChat(Utils.StringToBytes(text),
895 ChatTypeEnum.DebugChannel, 2147483647, 911 ChatTypeEnum.DebugChannel, 2147483647,
896 Part.AbsolutePosition, 912 part.AbsolutePosition,
897 Part.Name, Part.UUID, false); 913 part.Name, part.UUID, false);
898 914
899 915
900 m_log.DebugFormat( 916 m_log.DebugFormat(
901 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", 917 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}",
902 ScriptName, 918 ScriptName,
903 PrimName, 919 PrimName,
904 Part.UUID, 920 part.UUID,
905 Part.AbsolutePosition, 921 part.AbsolutePosition,
906 Part.ParentGroup.Scene.Name, 922 part.ParentGroup.Scene.Name,
907 text.Replace("\n", "\\n"), 923 text.Replace("\n", "\\n"),
908 e.InnerException); 924 e.InnerException);
909 } 925 }
@@ -923,12 +939,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
923 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 939 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
924 { 940 {
925 m_InSelfDelete = true; 941 m_InSelfDelete = true;
926 Engine.World.DeleteSceneObject(Part.ParentGroup, false); 942 if (part != null)
943 Engine.World.DeleteSceneObject(part.ParentGroup, false);
927 } 944 }
928 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 945 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
929 { 946 {
930 m_InSelfDelete = true; 947 m_InSelfDelete = true;
931 Part.Inventory.RemoveInventoryItem(ItemID); 948 if (part != null)
949 part.Inventory.RemoveInventoryItem(ItemID);
932 } 950 }
933 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 951 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
934 { 952 {
@@ -982,14 +1000,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
982 ReleaseControls(); 1000 ReleaseControls();
983 1001
984 Stop(timeout); 1002 Stop(timeout);
985 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1003 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
986 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1004 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1005 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1006 part.CollisionSound = UUID.Zero;
987 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1007 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
988 EventQueue.Clear(); 1008 EventQueue.Clear();
989 m_Script.ResetVars(); 1009 m_Script.ResetVars();
990 State = "default"; 1010 State = "default";
991 1011
992 Part.SetScriptEvents(ItemID, 1012 part.SetScriptEvents(ItemID,
993 (int)m_Script.GetStateEventFlags(State)); 1013 (int)m_Script.GetStateEventFlags(State));
994 if (running) 1014 if (running)
995 Start(); 1015 Start();
@@ -998,6 +1018,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
998 new Object[0], new DetectParams[0])); 1018 new Object[0], new DetectParams[0]));
999 } 1019 }
1000 1020
1021 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
1001 public void ApiResetScript() 1022 public void ApiResetScript()
1002 { 1023 {
1003 // bool running = Running; 1024 // bool running = Running;
@@ -1006,15 +1027,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1006 ReleaseControls(); 1027 ReleaseControls();
1007 1028
1008 m_Script.ResetVars(); 1029 m_Script.ResetVars();
1009 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1030 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1010 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1031 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1032 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1033 part.CollisionSound = UUID.Zero;
1011 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1034 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1012 1035
1013 EventQueue.Clear(); 1036 EventQueue.Clear();
1014 m_Script.ResetVars(); 1037 m_Script.ResetVars();
1015 State = "default"; 1038 State = "default";
1016 1039
1017 Part.SetScriptEvents(ItemID, 1040 part.SetScriptEvents(ItemID,
1018 (int)m_Script.GetStateEventFlags(State)); 1041 (int)m_Script.GetStateEventFlags(State));
1019 1042
1020 if (m_CurrentEvent != "state_entry") 1043 if (m_CurrentEvent != "state_entry")
@@ -1028,10 +1051,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1028 1051
1029 public Dictionary<string, object> GetVars() 1052 public Dictionary<string, object> GetVars()
1030 { 1053 {
1031 if (m_Script != null) 1054 return m_Script.GetVars();
1032 return m_Script.GetVars();
1033 else
1034 return new Dictionary<string, object>();
1035 } 1055 }
1036 1056
1037 public void SetVars(Dictionary<string, object> vars) 1057 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 f6d94a3..c685afb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -102,19 +102,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
102 102
103 public override string ToString() 103 public override string ToString()
104 { 104 {
105 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 105 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
106 return s; 106 return s;
107 } 107 }
108 108
109 public static explicit operator LSLString(Vector3 vec) 109 public static explicit operator LSLString(Vector3 vec)
110 { 110 {
111 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 111 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
112 return new LSLString(s); 112 return new LSLString(s);
113 } 113 }
114 114
115 public static explicit operator string(Vector3 vec) 115 public static explicit operator string(Vector3 vec)
116 { 116 {
117 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 117 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
118 return s; 118 return s;
119 } 119 }
120 120
@@ -414,19 +414,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
414 414
415 public override string ToString() 415 public override string ToString()
416 { 416 {
417 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 417 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
418 return st; 418 return st;
419 } 419 }
420 420
421 public static explicit operator string(Quaternion r) 421 public static explicit operator string(Quaternion r)
422 { 422 {
423 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 423 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
424 return s; 424 return s;
425 } 425 }
426 426
427 public static explicit operator LSLString(Quaternion r) 427 public static explicit operator LSLString(Quaternion r)
428 { 428 {
429 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 429 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
430 return new LSLString(s); 430 return new LSLString(s);
431 } 431 }
432 432
@@ -537,7 +537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
537 else if (o is LSL_Types.LSLFloat) 537 else if (o is LSL_Types.LSLFloat)
538 size += 8; 538 size += 8;
539 else if (o is LSL_Types.LSLString) 539 else if (o is LSL_Types.LSLString)
540 size += ((LSL_Types.LSLString)o).m_string.Length; 540 size += ((LSL_Types.LSLString)o).m_string == null ? 0 : ((LSL_Types.LSLString)o).m_string.Length;
541 else if (o is LSL_Types.key) 541 else if (o is LSL_Types.key)
542 size += ((LSL_Types.key)o).value.Length; 542 size += ((LSL_Types.key)o).value.Length;
543 else if (o is LSL_Types.Vector3) 543 else if (o is LSL_Types.Vector3)
@@ -546,6 +546,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
546 size += 64; 546 size += 64;
547 else if (o is int) 547 else if (o is int)
548 size += 4; 548 size += 4;
549 else if (o is uint)
550 size += 4;
549 else if (o is string) 551 else if (o is string)
550 size += ((string)o).Length; 552 size += ((string)o).Length;
551 else if (o is float) 553 else if (o is float)
@@ -736,24 +738,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
736 738
737 public static bool operator ==(list a, list b) 739 public static bool operator ==(list a, list b)
738 { 740 {
739 int la = -1; 741 int la = a.Length;
740 int lb = -1; 742 int lb = b.Length;
741 try { la = a.Length; }
742 catch (NullReferenceException) { }
743 try { lb = b.Length; }
744 catch (NullReferenceException) { }
745 743
746 return la == lb; 744 return la == lb;
747 } 745 }
748 746
749 public static bool operator !=(list a, list b) 747 public static bool operator !=(list a, list b)
750 { 748 {
751 int la = -1; 749 int la = a.Length;
752 int lb = -1; 750 int lb = b.Length;
753 try { la = a.Length; }
754 catch (NullReferenceException) { }
755 try {lb = b.Length;}
756 catch (NullReferenceException) { }
757 751
758 return la != lb; 752 return la != lb;
759 } 753 }
@@ -987,7 +981,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
987 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 981 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
988 } 982 }
989 983
990 if (ascending == 0) 984 if (ascending != 1)
991 { 985 {
992 ret = 0 - ret; 986 ret = 0 - ret;
993 } 987 }
@@ -1020,6 +1014,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
1020 stride = 1; 1014 stride = 1;
1021 } 1015 }
1022 1016
1017 if ((Data.Length % stride) != 0)
1018 return new list(ret);
1019
1023 // we can optimize here in the case where stride == 1 and the list 1020 // we can optimize here in the case where stride == 1 and the list
1024 // consists of homogeneous types 1021 // consists of homogeneous types
1025 1022
@@ -1039,7 +1036,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1039 if (homogeneous) 1036 if (homogeneous)
1040 { 1037 {
1041 Array.Sort(ret, new HomogeneousComparer()); 1038 Array.Sort(ret, new HomogeneousComparer());
1042 if (ascending == 0) 1039 if (ascending != 1)
1043 { 1040 {
1044 Array.Reverse(ret); 1041 Array.Reverse(ret);
1045 } 1042 }
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 5804aa8..9d1e143 100644
--- a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
+++ b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
@@ -28,6 +28,7 @@
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.Globalization; 32using System.Globalization;
32using System.IO; 33using System.IO;
33using System.Linq; 34using System.Linq;
@@ -148,6 +149,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
148 private Dictionary<UUID, IScriptInstance> m_Scripts = 149 private Dictionary<UUID, IScriptInstance> m_Scripts =
149 new Dictionary<UUID, IScriptInstance>(); 150 new Dictionary<UUID, IScriptInstance>();
150 151
152 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
153
151 // Maps the asset ID to the assembly 154 // Maps the asset ID to the assembly
152 155
153 private Dictionary<UUID, string> m_Assemblies = 156 private Dictionary<UUID, string> m_Assemblies =
@@ -170,6 +173,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
170 IWorkItemResult m_CurrentCompile = null; 173 IWorkItemResult m_CurrentCompile = null;
171 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 174 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
172 175
176 private void lockScriptsForRead(bool locked)
177 {
178 if (locked)
179 {
180 if (m_scriptsLock.RecursiveReadCount > 0)
181 {
182 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.");
183 m_scriptsLock.ExitReadLock();
184 }
185 if (m_scriptsLock.RecursiveWriteCount > 0)
186 {
187 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
188 m_scriptsLock.ExitWriteLock();
189 }
190
191 while (!m_scriptsLock.TryEnterReadLock(60000))
192 {
193 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.");
194 if (m_scriptsLock.IsWriteLockHeld)
195 {
196 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
197 }
198 }
199 }
200 else
201 {
202 if (m_scriptsLock.RecursiveReadCount > 0)
203 {
204 m_scriptsLock.ExitReadLock();
205 }
206 }
207 }
208 private void lockScriptsForWrite(bool locked)
209 {
210 if (locked)
211 {
212 if (m_scriptsLock.RecursiveReadCount > 0)
213 {
214 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.");
215 m_scriptsLock.ExitReadLock();
216 }
217 if (m_scriptsLock.RecursiveWriteCount > 0)
218 {
219 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
220 m_scriptsLock.ExitWriteLock();
221 }
222
223 while (!m_scriptsLock.TryEnterWriteLock(60000))
224 {
225 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.");
226 if (m_scriptsLock.IsWriteLockHeld)
227 {
228 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
229 }
230 }
231 }
232 else
233 {
234 if (m_scriptsLock.RecursiveWriteCount > 0)
235 {
236 m_scriptsLock.ExitWriteLock();
237 }
238 }
239 }
240
173 private ScriptEngineConsoleCommands m_consoleCommands; 241 private ScriptEngineConsoleCommands m_consoleCommands;
174 242
175 public string ScriptEngineName 243 public string ScriptEngineName
@@ -699,64 +767,69 @@ namespace OpenSim.Region.ScriptEngine.XEngine
699 { 767 {
700 if (!m_Enabled) 768 if (!m_Enabled)
701 return; 769 return;
770 lockScriptsForRead(true);
702 771
703 lock (m_Scripts) 772 List<IScriptInstance> instancesToDel = new List<IScriptInstance>(m_Scripts.Values);
704 {
705 m_log.InfoFormat(
706 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName);
707 773
708 foreach (IScriptInstance instance in m_Scripts.Values) 774// foreach (IScriptInstance instance in m_Scripts.Values)
775 foreach (IScriptInstance instance in instancesToDel)
776 {
777 // Force a final state save
778 //
779 if (m_Assemblies.ContainsKey(instance.AssetID))
709 { 780 {
710 // Force a final state save 781 string assembly = m_Assemblies[instance.AssetID];
711 //
712 if (m_Assemblies.ContainsKey(instance.AssetID))
713 {
714 string assembly = m_Assemblies[instance.AssetID];
715 782
716 try 783 try
717 { 784 {
718 instance.SaveState(assembly); 785 instance.SaveState(assembly);
719 }
720 catch (Exception e)
721 {
722 m_log.Error(
723 string.Format(
724 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
725 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
726 , e);
727 }
728 } 786 }
787 catch (Exception e)
788 {
789 m_log.Error(
790 string.Format(
791 "[XEngine]: Failed final state save for script {0}.{1}, item UUID {2}, prim UUID {3} in {4}. Exception ",
792 instance.PrimName, instance.ScriptName, instance.ItemID, instance.ObjectID, World.Name)
793 , e);
794 }
795 }
729 796
730 // Clear the event queue and abort the instance thread 797 // Clear the event queue and abort the instance thread
731 // 798 //
732 instance.ClearQueue(); 799 instance.ClearQueue();
733 instance.Stop(0); 800 instance.Stop(0);
734 801
735 // Release events, timer, etc 802 // Release events, timer, etc
736 // 803 //
737 instance.DestroyScriptInstance(); 804 instance.DestroyScriptInstance();
738 805
739 // Unload scripts and app domains. 806 // Unload scripts and app domains
740 // Must be done explicitly because they have infinite 807 // Must be done explicitly because they have infinite
741 // lifetime. 808 // lifetime
742 // However, don't bother to do this if the simulator is shutting 809 //
743 // down since it takes a long time with many scripts. 810// if (!m_SimulatorShuttingDown)
744 if (!m_SimulatorShuttingDown) 811 {
812 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
813 if (m_DomainScripts[instance.AppDomain].Count == 0)
745 { 814 {
746 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 815 m_DomainScripts.Remove(instance.AppDomain);
747 if (m_DomainScripts[instance.AppDomain].Count == 0) 816 UnloadAppDomain(instance.AppDomain);
748 {
749 m_DomainScripts.Remove(instance.AppDomain);
750 UnloadAppDomain(instance.AppDomain);
751 }
752 } 817 }
753 } 818 }
754 819
755 m_Scripts.Clear(); 820// m_Scripts.Clear();
756 m_PrimObjects.Clear(); 821// m_PrimObjects.Clear();
757 m_Assemblies.Clear(); 822// m_Assemblies.Clear();
758 m_DomainScripts.Clear(); 823// m_DomainScripts.Clear();
759 } 824 }
825 lockScriptsForRead(false);
826 lockScriptsForWrite(true);
827 m_Scripts.Clear();
828 lockScriptsForWrite(false);
829 m_PrimObjects.Clear();
830 m_Assemblies.Clear();
831 m_DomainScripts.Clear();
832
760 lock (m_ScriptEngines) 833 lock (m_ScriptEngines)
761 { 834 {
762 m_ScriptEngines.Remove(this); 835 m_ScriptEngines.Remove(this);
@@ -825,22 +898,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
825 898
826 List<IScriptInstance> instances = new List<IScriptInstance>(); 899 List<IScriptInstance> instances = new List<IScriptInstance>();
827 900
828 lock (m_Scripts) 901 lockScriptsForRead(true);
829 { 902 foreach (IScriptInstance instance in m_Scripts.Values)
830 foreach (IScriptInstance instance in m_Scripts.Values)
831 instances.Add(instance); 903 instances.Add(instance);
832 } 904 lockScriptsForRead(false);
833 905
834 foreach (IScriptInstance i in instances) 906 foreach (IScriptInstance i in instances)
835 { 907 {
836 string assembly = String.Empty; 908 string assembly = String.Empty;
837 909
838 lock (m_Scripts) 910
839 {
840 if (!m_Assemblies.ContainsKey(i.AssetID)) 911 if (!m_Assemblies.ContainsKey(i.AssetID))
841 continue; 912 continue;
842 assembly = m_Assemblies[i.AssetID]; 913 assembly = m_Assemblies[i.AssetID];
843 } 914
844 915
845 try 916 try
846 { 917 {
@@ -1244,97 +1315,93 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1244 } 1315 }
1245 1316
1246 ScriptInstance instance = null; 1317 ScriptInstance instance = null;
1247 lock (m_Scripts) 1318 // Create the object record
1319 lockScriptsForRead(true);
1320 if ((!m_Scripts.ContainsKey(itemID)) ||
1321 (m_Scripts[itemID].AssetID != assetID))
1248 { 1322 {
1249 // Create the object record 1323 lockScriptsForRead(false);
1250 if ((!m_Scripts.ContainsKey(itemID)) ||
1251 (m_Scripts[itemID].AssetID != assetID))
1252 {
1253 UUID appDomain = assetID;
1254 1324
1255 if (part.ParentGroup.IsAttachment) 1325 UUID appDomain = assetID;
1256 appDomain = part.ParentGroup.RootPart.UUID;
1257 1326
1258 if (!m_AppDomains.ContainsKey(appDomain)) 1327 if (part.ParentGroup.IsAttachment)
1259 { 1328 appDomain = part.ParentGroup.RootPart.UUID;
1260 try
1261 {
1262 AppDomainSetup appSetup = new AppDomainSetup();
1263 appSetup.PrivateBinPath = Path.Combine(
1264 m_ScriptEnginesPath,
1265 m_Scene.RegionInfo.RegionID.ToString());
1266 1329
1267 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1330 if (!m_AppDomains.ContainsKey(appDomain))
1268 Evidence evidence = new Evidence(baseEvidence); 1331 {
1332 try
1333 {
1334 AppDomainSetup appSetup = new AppDomainSetup();
1335 appSetup.PrivateBinPath = Path.Combine(
1336 m_ScriptEnginesPath,
1337 m_Scene.RegionInfo.RegionID.ToString());
1269 1338
1270 AppDomain sandbox; 1339 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1271 if (m_AppDomainLoading) 1340 Evidence evidence = new Evidence(baseEvidence);
1272 {
1273 sandbox = AppDomain.CreateDomain(
1274 m_Scene.RegionInfo.RegionID.ToString(),
1275 evidence, appSetup);
1276 sandbox.AssemblyResolve +=
1277 new ResolveEventHandler(
1278 AssemblyResolver.OnAssemblyResolve);
1279 }
1280 else
1281 {
1282 sandbox = AppDomain.CurrentDomain;
1283 }
1284
1285 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1286 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1287 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1288 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1289 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1290 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1291 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1292
1293 m_AppDomains[appDomain] = sandbox;
1294 1341
1295 m_DomainScripts[appDomain] = new List<UUID>(); 1342 AppDomain sandbox;
1343 if (m_AppDomainLoading)
1344 {
1345 sandbox = AppDomain.CreateDomain(
1346 m_Scene.RegionInfo.RegionID.ToString(),
1347 evidence, appSetup);
1348 m_AppDomains[appDomain].AssemblyResolve +=
1349 new ResolveEventHandler(
1350 AssemblyResolver.OnAssemblyResolve);
1296 } 1351 }
1297 catch (Exception e) 1352 else
1298 { 1353 {
1299 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1354 sandbox = AppDomain.CurrentDomain;
1300 m_ScriptErrorMessage += "Exception creating app domain:\n";
1301 m_ScriptFailCount++;
1302 lock (m_AddingAssemblies)
1303 {
1304 m_AddingAssemblies[assembly]--;
1305 }
1306 return false;
1307 } 1355 }
1308 }
1309 m_DomainScripts[appDomain].Add(itemID);
1310
1311 instance = new ScriptInstance(this, part,
1312 item,
1313 startParam, postOnRez,
1314 m_MaxScriptQueue);
1315 1356
1316 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) 1357 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource))
1317 return false; 1358 return false;
1318 1359
1319// if (DebugLevel >= 1) 1360 m_AppDomains[appDomain] = sandbox;
1320// m_log.DebugFormat(
1321// "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1322// part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1323// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1324 1361
1325 if (presence != null) 1362 m_DomainScripts[appDomain] = new List<UUID>();
1363 }
1364 catch (Exception e)
1326 { 1365 {
1327 ShowScriptSaveResponse(item.OwnerID, 1366 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1328 assetID, "Compile successful", true); 1367 m_ScriptErrorMessage += "Exception creating app domain:\n";
1368 m_ScriptFailCount++;
1369 lock (m_AddingAssemblies)
1370 {
1371 m_AddingAssemblies[assembly]--;
1372 }
1373 return false;
1329 } 1374 }
1375 }
1376 m_DomainScripts[appDomain].Add(itemID);
1377
1378 instance = new ScriptInstance(this, part,
1379 item,
1380 startParam, postOnRez,
1381 m_MaxScriptQueue);
1330 1382
1331 instance.AppDomain = appDomain; 1383 instance.Load(m_AppDomains[appDomain], assembly, stateSource);
1332 instance.LineMap = linemap; 1384// m_log.DebugFormat(
1385// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1386// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1387// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1333 1388
1334 m_Scripts[itemID] = instance; 1389 if (presence != null)
1390 {
1391 ShowScriptSaveResponse(item.OwnerID,
1392 assetID, "Compile successful", true);
1335 } 1393 }
1336 }
1337 1394
1395 instance.AppDomain = appDomain;
1396 instance.LineMap = linemap;
1397 lockScriptsForWrite(true);
1398 m_Scripts[itemID] = instance;
1399 lockScriptsForWrite(false);
1400 }
1401 else
1402 {
1403 lockScriptsForRead(false);
1404 }
1338 lock (m_PrimObjects) 1405 lock (m_PrimObjects)
1339 { 1406 {
1340 if (!m_PrimObjects.ContainsKey(localID)) 1407 if (!m_PrimObjects.ContainsKey(localID))
@@ -1352,7 +1419,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1352 m_AddingAssemblies[assembly]--; 1419 m_AddingAssemblies[assembly]--;
1353 } 1420 }
1354 1421
1355 if (instance != null) 1422 if (instance!=null)
1356 instance.Init(); 1423 instance.Init();
1357 1424
1358 bool runIt; 1425 bool runIt;
@@ -1375,18 +1442,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1375 m_CompileDict.Remove(itemID); 1442 m_CompileDict.Remove(itemID);
1376 } 1443 }
1377 1444
1378 IScriptInstance instance = null; 1445 lockScriptsForRead(true);
1379 1446 // Do we even have it?
1380 lock (m_Scripts) 1447 if (!m_Scripts.ContainsKey(itemID))
1381 { 1448 {
1382 // Do we even have it? 1449 // Do we even have it?
1383 if (!m_Scripts.ContainsKey(itemID)) 1450 if (!m_Scripts.ContainsKey(itemID))
1384 return; 1451 return;
1385 1452
1386 instance = m_Scripts[itemID]; 1453 lockScriptsForRead(false);
1454 lockScriptsForWrite(true);
1387 m_Scripts.Remove(itemID); 1455 m_Scripts.Remove(itemID);
1456 lockScriptsForWrite(false);
1457
1458 return;
1388 } 1459 }
1460
1389 1461
1462 IScriptInstance instance=m_Scripts[itemID];
1463 lockScriptsForRead(false);
1464 lockScriptsForWrite(true);
1465 m_Scripts.Remove(itemID);
1466 lockScriptsForWrite(false);
1390 instance.ClearQueue(); 1467 instance.ClearQueue();
1391 1468
1392 instance.Stop(m_WaitForEventCompletionOnScriptStop); 1469 instance.Stop(m_WaitForEventCompletionOnScriptStop);
@@ -1423,8 +1500,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1423 1500
1424 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1501 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1425 if (handlerObjectRemoved != null) 1502 if (handlerObjectRemoved != null)
1426 handlerObjectRemoved(instance.ObjectID); 1503 {
1504 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1505 handlerObjectRemoved(part.UUID);
1506 }
1427 1507
1508 CleanAssemblies();
1509
1428 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1510 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1429 if (handlerScriptRemoved != null) 1511 if (handlerScriptRemoved != null)
1430 handlerScriptRemoved(itemID); 1512 handlerScriptRemoved(itemID);
@@ -1685,12 +1767,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1685 private IScriptInstance GetInstance(UUID itemID) 1767 private IScriptInstance GetInstance(UUID itemID)
1686 { 1768 {
1687 IScriptInstance instance; 1769 IScriptInstance instance;
1688 lock (m_Scripts) 1770 lockScriptsForRead(true);
1771 if (!m_Scripts.ContainsKey(itemID))
1689 { 1772 {
1690 if (!m_Scripts.ContainsKey(itemID)) 1773 lockScriptsForRead(false);
1691 return null; 1774 return null;
1692 instance = m_Scripts[itemID];
1693 } 1775 }
1776 instance = m_Scripts[itemID];
1777 lockScriptsForRead(false);
1694 return instance; 1778 return instance;
1695 } 1779 }
1696 1780
@@ -1714,6 +1798,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1714 return false; 1798 return false;
1715 } 1799 }
1716 1800
1801 [DebuggerNonUserCode]
1717 public void ApiResetScript(UUID itemID) 1802 public void ApiResetScript(UUID itemID)
1718 { 1803 {
1719 IScriptInstance instance = GetInstance(itemID); 1804 IScriptInstance instance = GetInstance(itemID);
@@ -1775,6 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1775 return UUID.Zero; 1860 return UUID.Zero;
1776 } 1861 }
1777 1862
1863 [DebuggerNonUserCode]
1778 public void SetState(UUID itemID, string newState) 1864 public void SetState(UUID itemID, string newState)
1779 { 1865 {
1780 IScriptInstance instance = GetInstance(itemID); 1866 IScriptInstance instance = GetInstance(itemID);
@@ -1797,11 +1883,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1797 1883
1798 List<IScriptInstance> instances = new List<IScriptInstance>(); 1884 List<IScriptInstance> instances = new List<IScriptInstance>();
1799 1885
1800 lock (m_Scripts) 1886 lockScriptsForRead(true);
1801 { 1887 foreach (IScriptInstance instance in m_Scripts.Values)
1802 foreach (IScriptInstance instance in m_Scripts.Values)
1803 instances.Add(instance); 1888 instances.Add(instance);
1804 } 1889 lockScriptsForRead(false);
1805 1890
1806 foreach (IScriptInstance i in instances) 1891 foreach (IScriptInstance i in instances)
1807 { 1892 {