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.cs3518
-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.cs21
-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.cs12
-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.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs60
-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.cs175
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs385
21 files changed, 3309 insertions, 1448 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 8650b91..89f4706 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,12 +1616,55 @@ 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
1480 m_host.SetFaceColorAlpha(face, color, null); 1664 m_host.SetFaceColorAlpha(face, color, null);
1481 } 1665 }
1482 1666
1667 /*
1483 public void llSetContentType(LSL_Key id, LSL_Integer type) 1668 public void llSetContentType(LSL_Key id, LSL_Integer type)
1484 { 1669 {
1485 m_host.AddScriptLPS(1); 1670 m_host.AddScriptLPS(1);
@@ -1546,9 +1731,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1546 break; 1731 break;
1547 } 1732 }
1548 } 1733 }
1734 */
1549 1735
1550 public void SetTexGen(SceneObjectPart part, int face,int style) 1736 public void SetTexGen(SceneObjectPart part, int face,int style)
1551 { 1737 {
1738 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1739 return;
1740
1552 Primitive.TextureEntry tex = part.Shape.Textures; 1741 Primitive.TextureEntry tex = part.Shape.Textures;
1553 MappingType textype; 1742 MappingType textype;
1554 textype = MappingType.Default; 1743 textype = MappingType.Default;
@@ -1579,6 +1768,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 1768
1580 public void SetGlow(SceneObjectPart part, int face, float glow) 1769 public void SetGlow(SceneObjectPart part, int face, float glow)
1581 { 1770 {
1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1772 return;
1773
1582 Primitive.TextureEntry tex = part.Shape.Textures; 1774 Primitive.TextureEntry tex = part.Shape.Textures;
1583 if (face >= 0 && face < GetNumberOfSides(part)) 1775 if (face >= 0 && face < GetNumberOfSides(part))
1584 { 1776 {
@@ -1604,6 +1796,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1604 1796
1605 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1797 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1606 { 1798 {
1799 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1800 return;
1607 1801
1608 Shininess sval = new Shininess(); 1802 Shininess sval = new Shininess();
1609 1803
@@ -1654,6 +1848,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1654 1848
1655 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1849 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1656 { 1850 {
1851 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1852 return;
1853
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1854 Primitive.TextureEntry tex = part.Shape.Textures;
1658 if (face >= 0 && face < GetNumberOfSides(part)) 1855 if (face >= 0 && face < GetNumberOfSides(part))
1659 { 1856 {
@@ -1714,13 +1911,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 m_host.AddScriptLPS(1); 1911 m_host.AddScriptLPS(1);
1715 1912
1716 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1913 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1717 1914 if (parts.Count > 0)
1718 foreach (SceneObjectPart part in parts) 1915 {
1719 SetAlpha(part, alpha, face); 1916 try
1917 {
1918 foreach (SceneObjectPart part in parts)
1919 SetAlpha(part, alpha, face);
1920 }
1921 finally
1922 {
1923 }
1924 }
1720 } 1925 }
1721 1926
1722 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1927 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1723 { 1928 {
1929 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1930 return;
1931
1724 Primitive.TextureEntry tex = part.Shape.Textures; 1932 Primitive.TextureEntry tex = part.Shape.Textures;
1725 Color4 texcolor; 1933 Color4 texcolor;
1726 if (face >= 0 && face < GetNumberOfSides(part)) 1934 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1773,7 +1981,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1773 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1981 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1774 float wind, float tension, LSL_Vector Force) 1982 float wind, float tension, LSL_Vector Force)
1775 { 1983 {
1776 if (part == null) 1984 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1777 return; 1985 return;
1778 1986
1779 if (flexi) 1987 if (flexi)
@@ -1814,7 +2022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 /// <param name="falloff"></param> 2022 /// <param name="falloff"></param>
1815 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 2023 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1816 { 2024 {
1817 if (part == null) 2025 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1818 return; 2026 return;
1819 2027
1820 if (light) 2028 if (light)
@@ -1847,11 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 Primitive.TextureEntry tex = part.Shape.Textures; 2055 Primitive.TextureEntry tex = part.Shape.Textures;
1848 Color4 texcolor; 2056 Color4 texcolor;
1849 LSL_Vector rgb = new LSL_Vector(); 2057 LSL_Vector rgb = new LSL_Vector();
2058 int nsides = GetNumberOfSides(part);
2059
1850 if (face == ScriptBaseClass.ALL_SIDES) 2060 if (face == ScriptBaseClass.ALL_SIDES)
1851 { 2061 {
1852 int i; 2062 int i;
1853 2063 for (i = 0; i < nsides; i++)
1854 for (i = 0 ; i < GetNumberOfSides(part); i++)
1855 { 2064 {
1856 texcolor = tex.GetFace((uint)i).RGBA; 2065 texcolor = tex.GetFace((uint)i).RGBA;
1857 rgb.x += texcolor.R; 2066 rgb.x += texcolor.R;
@@ -1859,14 +2068,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1859 rgb.z += texcolor.B; 2068 rgb.z += texcolor.B;
1860 } 2069 }
1861 2070
1862 rgb.x /= (float)GetNumberOfSides(part); 2071 float invnsides = 1.0f / (float)nsides;
1863 rgb.y /= (float)GetNumberOfSides(part); 2072
1864 rgb.z /= (float)GetNumberOfSides(part); 2073 rgb.x *= invnsides;
2074 rgb.y *= invnsides;
2075 rgb.z *= invnsides;
1865 2076
1866 return rgb; 2077 return rgb;
1867 } 2078 }
1868 2079 if (face >= 0 && face < nsides)
1869 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2080 {
1871 texcolor = tex.GetFace((uint)face).RGBA; 2081 texcolor = tex.GetFace((uint)face).RGBA;
1872 rgb.x = texcolor.R; 2082 rgb.x = texcolor.R;
@@ -1893,15 +2103,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1893 m_host.AddScriptLPS(1); 2103 m_host.AddScriptLPS(1);
1894 2104
1895 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2105 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1896 2106 if (parts.Count > 0)
1897 foreach (SceneObjectPart part in parts) 2107 {
1898 SetTexture(part, texture, face); 2108 try
1899 2109 {
2110 foreach (SceneObjectPart part in parts)
2111 SetTexture(part, texture, face);
2112 }
2113 finally
2114 {
2115 }
2116 }
1900 ScriptSleep(200); 2117 ScriptSleep(200);
1901 } 2118 }
1902 2119
1903 protected void SetTexture(SceneObjectPart part, string texture, int face) 2120 protected void SetTexture(SceneObjectPart part, string texture, int face)
1904 { 2121 {
2122 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2123 return;
2124
1905 UUID textureID = new UUID(); 2125 UUID textureID = new UUID();
1906 2126
1907 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2127 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1946,6 +2166,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1946 2166
1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2167 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1948 { 2168 {
2169 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2170 return;
2171
1949 Primitive.TextureEntry tex = part.Shape.Textures; 2172 Primitive.TextureEntry tex = part.Shape.Textures;
1950 if (face >= 0 && face < GetNumberOfSides(part)) 2173 if (face >= 0 && face < GetNumberOfSides(part))
1951 { 2174 {
@@ -1982,6 +2205,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1982 2205
1983 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2206 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1984 { 2207 {
2208 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2209 return;
2210
1985 Primitive.TextureEntry tex = part.Shape.Textures; 2211 Primitive.TextureEntry tex = part.Shape.Textures;
1986 if (face >= 0 && face < GetNumberOfSides(part)) 2212 if (face >= 0 && face < GetNumberOfSides(part))
1987 { 2213 {
@@ -2018,6 +2244,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2018 2244
2019 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2245 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2020 { 2246 {
2247 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2248 return;
2249
2021 Primitive.TextureEntry tex = part.Shape.Textures; 2250 Primitive.TextureEntry tex = part.Shape.Textures;
2022 if (face >= 0 && face < GetNumberOfSides(part)) 2251 if (face >= 0 && face < GetNumberOfSides(part))
2023 { 2252 {
@@ -2159,7 +2388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2159 return end; 2388 return end;
2160 } 2389 }
2161 2390
2162 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2391 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2163 { 2392 {
2164 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2393 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2165 return fromPos; 2394 return fromPos;
@@ -2175,9 +2404,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2175 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2404 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2176 targetPos.z = ground; 2405 targetPos.z = ground;
2177 } 2406 }
2178 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2407 if (adjust)
2408 return SetPosAdjust(fromPos, targetPos);
2179 2409
2180 return real_vec; 2410 return targetPos;
2181 } 2411 }
2182 2412
2183 /// <summary> 2413 /// <summary>
@@ -2188,27 +2418,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2418 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2189 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2419 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2190 { 2420 {
2191 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2421 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2422 return;
2423
2192 LSL_Vector currentPos = GetPartLocalPos(part); 2424 LSL_Vector currentPos = GetPartLocalPos(part);
2425 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2193 2426
2194 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2195 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2196 2427
2197 if (part.ParentGroup.RootPart == part) 2428 if (part.ParentGroup.RootPart == part)
2198 { 2429 {
2199 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2200 targetPos.z = ground;
2201 SceneObjectGroup parent = part.ParentGroup; 2430 SceneObjectGroup parent = part.ParentGroup;
2202 parent.UpdateGroupPosition(!adjust ? targetPos : 2431 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2203 SetPosAdjust(currentPos, targetPos)); 2432 return;
2433 Util.FireAndForget(delegate(object x) {
2434 parent.UpdateGroupPosition((Vector3)toPos);
2435 });
2204 } 2436 }
2205 else 2437 else
2206 { 2438 {
2207 part.OffsetPosition = !adjust ? targetPos : 2439 part.OffsetPosition = (Vector3)toPos;
2208 SetPosAdjust(currentPos, targetPos); 2440// SceneObjectGroup parent = part.ParentGroup;
2209 SceneObjectGroup parent = part.ParentGroup; 2441// parent.HasGroupChanged = true;
2210 parent.HasGroupChanged = true; 2442// parent.ScheduleGroupForTerseUpdate();
2211 parent.ScheduleGroupForTerseUpdate(); 2443 part.ScheduleTerseUpdate();
2212 } 2444 }
2213 } 2445 }
2214 2446
@@ -2237,13 +2469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2237 else 2469 else
2238 { 2470 {
2239 if (part.ParentGroup.IsAttachment) 2471 if (part.ParentGroup.IsAttachment)
2240 {
2241 pos = part.AttachedPos; 2472 pos = part.AttachedPos;
2242 }
2243 else 2473 else
2244 {
2245 pos = part.AbsolutePosition; 2474 pos = part.AbsolutePosition;
2246 }
2247 } 2475 }
2248 2476
2249// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2477// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2255,8 +2483,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2255 { 2483 {
2256 m_host.AddScriptLPS(1); 2484 m_host.AddScriptLPS(1);
2257 2485
2486
2487 // 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
2488 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2489 // 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.
2490 // RootPart != null should shortcircuit
2491
2258 // try to let this work as in SL... 2492 // try to let this work as in SL...
2259 if (m_host.ParentID == 0) 2493 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2260 { 2494 {
2261 // special case: If we are root, rotate complete SOG to new rotation 2495 // special case: If we are root, rotate complete SOG to new rotation
2262 SetRot(m_host, rot); 2496 SetRot(m_host, rot);
@@ -2283,25 +2517,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2283 2517
2284 protected void SetRot(SceneObjectPart part, Quaternion rot) 2518 protected void SetRot(SceneObjectPart part, Quaternion rot)
2285 { 2519 {
2286 part.UpdateRotation(rot); 2520 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2287 // Update rotation does not move the object in the physics scene if it's a linkset. 2521 return;
2288 2522
2289//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2523 bool isroot = (part == part.ParentGroup.RootPart);
2290// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2524 bool isphys;
2291 2525
2292 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2293 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2294 // It's perfectly okay when the object is not an active physical body though.
2295 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2296 // but only if the object is not physial and active. This is important for rotating doors.
2297 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2298 // scene
2299 PhysicsActor pa = part.PhysActor; 2526 PhysicsActor pa = part.PhysActor;
2300 2527
2301 if (pa != null && !pa.IsPhysical) 2528 // keep using physactor ideia of isphysical
2529 // it should be SOP ideia of that
2530 // not much of a issue with ubitODE
2531 if (pa != null && pa.IsPhysical)
2532 isphys = true;
2533 else
2534 isphys = false;
2535
2536 // SL doesn't let scripts rotate root of physical linksets
2537 if (isroot && isphys)
2538 return;
2539
2540 part.UpdateRotation(rot);
2541
2542 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2543 // so do a nasty update of parts positions if is a root part rotation
2544 if (isroot && pa != null) // with if above implies non physical root part
2302 { 2545 {
2303 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2546 part.ParentGroup.ResetChildPrimPhysicsPositions();
2304 } 2547 }
2548 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2549 {
2550 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2551 if (sittingavas.Count > 0)
2552 {
2553 foreach (ScenePresence av in sittingavas)
2554 {
2555 if (isroot || part.LocalId == av.ParentID)
2556 av.SendTerseUpdateToAllClients();
2557 }
2558 }
2559 }
2305 } 2560 }
2306 2561
2307 /// <summary> 2562 /// <summary>
@@ -2318,6 +2573,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2318 2573
2319 m_host.AddScriptLPS(1); 2574 m_host.AddScriptLPS(1);
2320 Quaternion q = m_host.GetWorldRotation(); 2575 Quaternion q = m_host.GetWorldRotation();
2576
2577 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2578 {
2579 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2580 if (avatar != null)
2581 {
2582 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2583 q = avatar.CameraRotation * q; // Mouselook
2584 else
2585 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2586 }
2587 }
2588
2321 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2589 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2322 } 2590 }
2323 2591
@@ -2345,14 +2613,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2345 return new LSL_Rotation(q); 2613 return new LSL_Rotation(q);
2346 } 2614 }
2347 2615
2348 return new LSL_Rotation(part.GetWorldRotation()); 2616 q = part.GetWorldRotation();
2617 if (part.ParentGroup.AttachmentPoint != 0)
2618 {
2619 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2620 if (avatar != null)
2621 {
2622 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2623 q = avatar.CameraRotation * q; // Mouselook
2624 else
2625 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2626 }
2627 }
2628
2629 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2349 } 2630 }
2350 2631
2351 public LSL_Rotation llGetLocalRot() 2632 public LSL_Rotation llGetLocalRot()
2352 { 2633 {
2353 m_host.AddScriptLPS(1); 2634 return GetPartLocalRot(m_host);
2635 }
2354 2636
2355 return new LSL_Rotation(m_host.RotationOffset); 2637 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2638 {
2639 m_host.AddScriptLPS(1);
2640 Quaternion rot = part.RotationOffset;
2641 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2356 } 2642 }
2357 2643
2358 public void llSetForce(LSL_Vector force, int local) 2644 public void llSetForce(LSL_Vector force, int local)
@@ -2382,32 +2668,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2382 return force; 2668 return force;
2383 } 2669 }
2384 2670
2385 public void llSetVelocity(LSL_Vector velocity, int local)
2386 {
2387 m_host.AddScriptLPS(1);
2388
2389 if (!m_host.ParentGroup.IsDeleted)
2390 {
2391 if (local != 0)
2392 velocity *= llGetRot();
2393
2394 m_host.ParentGroup.RootPart.Velocity = velocity;
2395 }
2396 }
2397
2398 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local)
2399 {
2400 m_host.AddScriptLPS(1);
2401
2402 if (!m_host.ParentGroup.IsDeleted)
2403 {
2404 if (local != 0)
2405 angularVelocity *= llGetRot();
2406
2407 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
2408 }
2409 }
2410
2411 public LSL_Integer llTarget(LSL_Vector position, double range) 2671 public LSL_Integer llTarget(LSL_Vector position, double range)
2412 { 2672 {
2413 m_host.AddScriptLPS(1); 2673 m_host.AddScriptLPS(1);
@@ -2458,16 +2718,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2458 m_host.ApplyImpulse(v, local != 0); 2718 m_host.ApplyImpulse(v, local != 0);
2459 } 2719 }
2460 2720
2721
2461 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2722 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2462 { 2723 {
2463 m_host.AddScriptLPS(1); 2724 m_host.AddScriptLPS(1);
2464 m_host.ApplyAngularImpulse(force, local != 0); 2725 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2465 } 2726 }
2466 2727
2467 public void llSetTorque(LSL_Vector torque, int local) 2728 public void llSetTorque(LSL_Vector torque, int local)
2468 { 2729 {
2469 m_host.AddScriptLPS(1); 2730 m_host.AddScriptLPS(1);
2470 m_host.SetAngularImpulse(torque, local != 0); 2731 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2471 } 2732 }
2472 2733
2473 public LSL_Vector llGetTorque() 2734 public LSL_Vector llGetTorque()
@@ -2484,20 +2745,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2484 llSetTorque(torque, local); 2745 llSetTorque(torque, local);
2485 } 2746 }
2486 2747
2748 public void llSetVelocity(LSL_Vector vel, int local)
2749 {
2750 m_host.AddScriptLPS(1);
2751 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2752 }
2753
2487 public LSL_Vector llGetVel() 2754 public LSL_Vector llGetVel()
2488 { 2755 {
2489 m_host.AddScriptLPS(1); 2756 m_host.AddScriptLPS(1);
2490 2757
2491 Vector3 vel; 2758 Vector3 vel = Vector3.Zero;
2492 2759
2493 if (m_host.ParentGroup.IsAttachment) 2760 if (m_host.ParentGroup.IsAttachment)
2494 { 2761 {
2495 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2762 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2496 vel = avatar.Velocity; 2763 if (avatar != null)
2764 vel = avatar.Velocity;
2497 } 2765 }
2498 else 2766 else
2499 { 2767 {
2500 vel = m_host.Velocity; 2768 vel = m_host.ParentGroup.RootPart.Velocity;
2501 } 2769 }
2502 2770
2503 return new LSL_Vector(vel); 2771 return new LSL_Vector(vel);
@@ -2510,11 +2778,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2510 return new LSL_Vector(m_host.Acceleration); 2778 return new LSL_Vector(m_host.Acceleration);
2511 } 2779 }
2512 2780
2513 public LSL_Vector llGetOmega() 2781 public void llSetAngularVelocity(LSL_Vector avel, int local)
2514 { 2782 {
2515 m_host.AddScriptLPS(1); 2783 m_host.AddScriptLPS(1);
2784 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2785 }
2516 2786
2517 return new LSL_Vector(m_host.AngularVelocity); 2787 public LSL_Vector llGetOmega()
2788 {
2789 m_host.AddScriptLPS(1);
2790 Vector3 avel = m_host.AngularVelocity;
2791 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2518 } 2792 }
2519 2793
2520 public LSL_Float llGetTimeOfDay() 2794 public LSL_Float llGetTimeOfDay()
@@ -2875,7 +3149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2875 return src.ToLower(); 3149 return src.ToLower();
2876 } 3150 }
2877 3151
2878 public void llGiveMoney(string destination, int amount) 3152 public LSL_Integer llGiveMoney(string destination, int amount)
2879 { 3153 {
2880 Util.FireAndForget(x => 3154 Util.FireAndForget(x =>
2881 { 3155 {
@@ -2906,9 +3180,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2906 return; 3180 return;
2907 } 3181 }
2908 3182
3183 string reason;
2909 money.ObjectGiveMoney( 3184 money.ObjectGiveMoney(
2910 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3185 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason);
2911 }); 3186 });
3187
3188 return 0;
2912 } 3189 }
2913 3190
2914 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3191 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -3004,6 +3281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3004 } 3281 }
3005 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3282 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3006 } 3283 }
3284 return;
3007 }); 3285 });
3008 3286
3009 //ScriptSleep((int)((groupmass * velmag) / 10)); 3287 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -3018,35 +3296,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3018 public void llLookAt(LSL_Vector target, double strength, double damping) 3296 public void llLookAt(LSL_Vector target, double strength, double damping)
3019 { 3297 {
3020 m_host.AddScriptLPS(1); 3298 m_host.AddScriptLPS(1);
3021 // Determine where we are looking from
3022 LSL_Vector from = llGetPos();
3023
3024 // Work out the normalised vector from the source to the target
3025 LSL_Vector delta = llVecNorm(target - from);
3026 LSL_Vector angle = new LSL_Vector(0,0,0);
3027 3299
3028 // Calculate the yaw 3300 // Get the normalized vector to the target
3029 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3301 LSL_Vector d1 = llVecNorm(target - llGetPos());
3030 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO;
3031 3302
3032 // Calculate pitch 3303 // Get the bearing (yaw)
3033 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3304 LSL_Vector a1 = new LSL_Vector(0,0,0);
3305 a1.z = llAtan2(d1.y, d1.x);
3034 3306
3035 // we need to convert from a vector describing 3307 // Get the elevation (pitch)
3036 // the angles of rotation in radians into rotation value 3308 LSL_Vector a2 = new LSL_Vector(0,0,0);
3037 LSL_Rotation rot = llEuler2Rot(angle); 3309 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
3038 3310
3039 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3311 LSL_Rotation r1 = llEuler2Rot(a1);
3040 // set the rotation of the object, copy that behavior 3312 LSL_Rotation r2 = llEuler2Rot(a2);
3041 PhysicsActor pa = m_host.PhysActor; 3313 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
3042 3314
3043 if (strength == 0 || pa == null || !pa.IsPhysical) 3315 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3044 { 3316 {
3045 llSetRot(rot); 3317 // Do nothing if either value is 0 (this has been checked in SL)
3318 if (strength <= 0.0 || damping <= 0.0)
3319 return;
3320
3321 llSetRot(r3 * r2 * r1);
3046 } 3322 }
3047 else 3323 else
3048 { 3324 {
3049 m_host.StartLookAt(rot, (float)strength, (float)damping); 3325 if (strength == 0)
3326 {
3327 llSetRot(r3 * r2 * r1);
3328 return;
3329 }
3330
3331 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3050 } 3332 }
3051 } 3333 }
3052 3334
@@ -3093,17 +3375,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3093 } 3375 }
3094 else 3376 else
3095 { 3377 {
3096 if (m_host.IsRoot) 3378 // new SL always returns object mass
3097 { 3379// if (m_host.IsRoot)
3380// {
3098 return m_host.ParentGroup.GetMass(); 3381 return m_host.ParentGroup.GetMass();
3099 } 3382// }
3100 else 3383// else
3101 { 3384// {
3102 return m_host.GetMass(); 3385// return m_host.GetMass();
3103 } 3386// }
3104 } 3387 }
3105 } 3388 }
3106 3389
3390
3391 public LSL_Float llGetMassMKS()
3392 {
3393 return 100f * llGetMass();
3394 }
3395
3107 public void llCollisionFilter(string name, string id, int accept) 3396 public void llCollisionFilter(string name, string id, int accept)
3108 { 3397 {
3109 m_host.AddScriptLPS(1); 3398 m_host.AddScriptLPS(1);
@@ -3151,8 +3440,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3151 { 3440 {
3152 // Unregister controls from Presence 3441 // Unregister controls from Presence
3153 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3442 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3154 // Remove Take Control permission.
3155 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3156 } 3443 }
3157 } 3444 }
3158 } 3445 }
@@ -3180,7 +3467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3180 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3467 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3181 3468
3182 if (attachmentsModule != null) 3469 if (attachmentsModule != null)
3183 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3470 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3184 else 3471 else
3185 return false; 3472 return false;
3186 } 3473 }
@@ -3210,9 +3497,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3210 { 3497 {
3211 m_host.AddScriptLPS(1); 3498 m_host.AddScriptLPS(1);
3212 3499
3213// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3214// return;
3215
3216 if (m_item.PermsGranter != m_host.OwnerID) 3500 if (m_item.PermsGranter != m_host.OwnerID)
3217 return; 3501 return;
3218 3502
@@ -3255,6 +3539,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3255 3539
3256 public void llInstantMessage(string user, string message) 3540 public void llInstantMessage(string user, string message)
3257 { 3541 {
3542 UUID result;
3543 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3544 {
3545 ShoutError("An invalid key was passed to llInstantMessage");
3546 ScriptSleep(2000);
3547 return;
3548 }
3549
3550
3258 m_host.AddScriptLPS(1); 3551 m_host.AddScriptLPS(1);
3259 3552
3260 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3553 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3269,14 +3562,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3269 UUID friendTransactionID = UUID.Random(); 3562 UUID friendTransactionID = UUID.Random();
3270 3563
3271 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3564 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3272 3565
3273 GridInstantMessage msg = new GridInstantMessage(); 3566 GridInstantMessage msg = new GridInstantMessage();
3274 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3567 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3275 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3568 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3276 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3569 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3277// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3570// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3278// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3571// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3279 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3572// DateTime dt = DateTime.UtcNow;
3573//
3574// // Ticks from UtcNow, but make it look like local. Evil, huh?
3575// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3576//
3577// try
3578// {
3579// // Convert that to the PST timezone
3580// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3581// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3582// }
3583// catch
3584// {
3585// // No logging here, as it could be VERY spammy
3586// }
3587//
3588// // And make it look local again to fool the unix time util
3589// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3590
3591 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3592
3280 //if (client != null) 3593 //if (client != null)
3281 //{ 3594 //{
3282 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3595 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3290,10 +3603,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3290 msg.message = message.Substring(0, 1024); 3603 msg.message = message.Substring(0, 1024);
3291 else 3604 else
3292 msg.message = message; 3605 msg.message = message;
3293 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3606 msg.dialog = (byte)19; // MessageFromObject
3294 msg.fromGroup = false;// fromGroup; 3607 msg.fromGroup = false;// fromGroup;
3295 msg.offline = (byte)0; //offline; 3608 msg.offline = (byte)0; //offline;
3296 msg.ParentEstateID = 0; //ParentEstateID; 3609 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3297 msg.Position = new Vector3(m_host.AbsolutePosition); 3610 msg.Position = new Vector3(m_host.AbsolutePosition);
3298 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3611 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3299 3612
@@ -3571,7 +3884,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3571 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3884 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3572 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3885 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3573 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3886 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3887 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3574 ScriptBaseClass.PERMISSION_ATTACH; 3888 ScriptBaseClass.PERMISSION_ATTACH;
3889
3575 } 3890 }
3576 else 3891 else
3577 { 3892 {
@@ -3588,15 +3903,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3588 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3903 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3589 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3904 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3590 } 3905 }
3906 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3907 {
3908 implicitPerms = perm;
3909 }
3591 } 3910 }
3592 3911
3593 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3912 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3594 { 3913 {
3595 lock (m_host.TaskInventory) 3914 m_host.TaskInventory.LockItemsForWrite(true);
3596 { 3915 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3597 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3916 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3598 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3917 m_host.TaskInventory.LockItemsForWrite(false);
3599 }
3600 3918
3601 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3919 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3602 "run_time_permissions", new Object[] { 3920 "run_time_permissions", new Object[] {
@@ -3639,11 +3957,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3639 3957
3640 if (!m_waitingForScriptAnswer) 3958 if (!m_waitingForScriptAnswer)
3641 { 3959 {
3642 lock (m_host.TaskInventory) 3960 m_host.TaskInventory.LockItemsForWrite(true);
3643 { 3961 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3644 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3962 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3645 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3963 m_host.TaskInventory.LockItemsForWrite(false);
3646 }
3647 3964
3648 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3965 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3649 m_waitingForScriptAnswer=true; 3966 m_waitingForScriptAnswer=true;
@@ -3672,14 +3989,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3672 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3989 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3673 llReleaseControls(); 3990 llReleaseControls();
3674 3991
3675 lock (m_host.TaskInventory) 3992 m_host.TaskInventory.LockItemsForWrite(true);
3676 { 3993 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3677 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3994 m_host.TaskInventory.LockItemsForWrite(false);
3678 } 3995
3679 3996 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3680 m_ScriptEngine.PostScriptEvent( 3997 "run_time_permissions", new Object[] {
3681 m_item.ItemID, 3998 new LSL_Integer(answer) },
3682 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3999 new DetectParams[0]));
3683 } 4000 }
3684 4001
3685 public LSL_String llGetPermissionsKey() 4002 public LSL_String llGetPermissionsKey()
@@ -3718,14 +4035,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3718 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 4035 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3719 { 4036 {
3720 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4037 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3721 4038 if (parts.Count > 0)
3722 foreach (SceneObjectPart part in parts) 4039 {
3723 part.SetFaceColorAlpha(face, color, null); 4040 try
4041 {
4042 foreach (SceneObjectPart part in parts)
4043 part.SetFaceColorAlpha(face, color, null);
4044 }
4045 finally
4046 {
4047 }
4048 }
3724 } 4049 }
3725 4050
3726 public void llCreateLink(string target, int parent) 4051 public void llCreateLink(string target, int parent)
3727 { 4052 {
3728 m_host.AddScriptLPS(1); 4053 m_host.AddScriptLPS(1);
4054
3729 UUID targetID; 4055 UUID targetID;
3730 4056
3731 if (!UUID.TryParse(target, out targetID)) 4057 if (!UUID.TryParse(target, out targetID))
@@ -3831,10 +4157,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3831 // Restructuring Multiple Prims. 4157 // Restructuring Multiple Prims.
3832 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4158 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3833 parts.Remove(parentPrim.RootPart); 4159 parts.Remove(parentPrim.RootPart);
3834 foreach (SceneObjectPart part in parts) 4160 if (parts.Count > 0)
3835 { 4161 {
3836 parentPrim.DelinkFromGroup(part.LocalId, true); 4162 try
4163 {
4164 foreach (SceneObjectPart part in parts)
4165 {
4166 parentPrim.DelinkFromGroup(part.LocalId, true);
4167 }
4168 }
4169 finally
4170 {
4171 }
3837 } 4172 }
4173
3838 parentPrim.HasGroupChanged = true; 4174 parentPrim.HasGroupChanged = true;
3839 parentPrim.ScheduleGroupForFullUpdate(); 4175 parentPrim.ScheduleGroupForFullUpdate();
3840 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4176 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3843,12 +4179,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 { 4179 {
3844 SceneObjectPart newRoot = parts[0]; 4180 SceneObjectPart newRoot = parts[0];
3845 parts.Remove(newRoot); 4181 parts.Remove(newRoot);
3846 foreach (SceneObjectPart part in parts) 4182
4183 try
3847 { 4184 {
3848 // Required for linking 4185 foreach (SceneObjectPart part in parts)
3849 part.ClearUpdateSchedule(); 4186 {
3850 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4187 part.ClearUpdateSchedule();
4188 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4189 }
3851 } 4190 }
4191 finally
4192 {
4193 }
4194
4195
3852 newRoot.ParentGroup.HasGroupChanged = true; 4196 newRoot.ParentGroup.HasGroupChanged = true;
3853 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4197 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3854 } 4198 }
@@ -3868,6 +4212,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3868 public void llBreakAllLinks() 4212 public void llBreakAllLinks()
3869 { 4213 {
3870 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
4215
4216 TaskInventoryItem item = m_item;
4217
4218 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4219 && !m_automaticLinkPermission)
4220 {
4221 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4222 return;
4223 }
4224
3871 SceneObjectGroup parentPrim = m_host.ParentGroup; 4225 SceneObjectGroup parentPrim = m_host.ParentGroup;
3872 if (parentPrim.AttachmentPoint != 0) 4226 if (parentPrim.AttachmentPoint != 0)
3873 return; // Fail silently if attached 4227 return; // Fail silently if attached
@@ -3887,13 +4241,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3887 public LSL_String llGetLinkKey(int linknum) 4241 public LSL_String llGetLinkKey(int linknum)
3888 { 4242 {
3889 m_host.AddScriptLPS(1); 4243 m_host.AddScriptLPS(1);
4244 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4245 if (part != null)
4246 {
4247 return part.UUID.ToString();
4248 }
4249 else
4250 {
4251 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4252 {
4253 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3890 4254
3891 ISceneEntity entity = GetLinkEntity(linknum); 4255 if (linknum < 0)
4256 return UUID.Zero.ToString();
3892 4257
3893 if (entity != null) 4258 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3894 return entity.UUID.ToString(); 4259 if (avatars.Count > linknum)
3895 else 4260 {
3896 return ScriptBaseClass.NULL_KEY; 4261 return avatars[linknum].UUID.ToString();
4262 }
4263 }
4264 return UUID.Zero.ToString();
4265 }
3897 } 4266 }
3898 4267
3899 /// <summary> 4268 /// <summary>
@@ -3952,17 +4321,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3952 m_host.AddScriptLPS(1); 4321 m_host.AddScriptLPS(1);
3953 int count = 0; 4322 int count = 0;
3954 4323
3955 lock (m_host.TaskInventory) 4324 m_host.TaskInventory.LockItemsForRead(true);
4325 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3956 { 4326 {
3957 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4327 if (inv.Value.Type == type || type == -1)
3958 { 4328 {
3959 if (inv.Value.Type == type || type == -1) 4329 count = count + 1;
3960 {
3961 count = count + 1;
3962 }
3963 } 4330 }
3964 } 4331 }
3965 4332
4333 m_host.TaskInventory.LockItemsForRead(false);
3966 return count; 4334 return count;
3967 } 4335 }
3968 4336
@@ -3971,16 +4339,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 m_host.AddScriptLPS(1); 4339 m_host.AddScriptLPS(1);
3972 ArrayList keys = new ArrayList(); 4340 ArrayList keys = new ArrayList();
3973 4341
3974 lock (m_host.TaskInventory) 4342 m_host.TaskInventory.LockItemsForRead(true);
4343 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3975 { 4344 {
3976 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4345 if (inv.Value.Type == type || type == -1)
3977 { 4346 {
3978 if (inv.Value.Type == type || type == -1) 4347 keys.Add(inv.Value.Name);
3979 {
3980 keys.Add(inv.Value.Name);
3981 }
3982 } 4348 }
3983 } 4349 }
4350 m_host.TaskInventory.LockItemsForRead(false);
3984 4351
3985 if (keys.Count == 0) 4352 if (keys.Count == 0)
3986 { 4353 {
@@ -4018,7 +4385,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4018 if (item == null) 4385 if (item == null)
4019 { 4386 {
4020 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4387 llSay(0, String.Format("Could not find object '{0}'", inventory));
4021 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4388 return;
4389// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4022 } 4390 }
4023 4391
4024 UUID objId = item.ItemID; 4392 UUID objId = item.ItemID;
@@ -4046,33 +4414,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4046 return; 4414 return;
4047 } 4415 }
4048 } 4416 }
4417
4049 // destination is an avatar 4418 // destination is an avatar
4050 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4419 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4051 4420
4052 if (agentItem == null) 4421 if (agentItem == null)
4053 return; 4422 return;
4054 4423
4055 if (m_TransferModule != null) 4424 byte[] bucket = new byte[1];
4056 { 4425 bucket[0] = (byte)item.Type;
4057 byte[] bucket = new byte[1]; 4426 //byte[] objBytes = agentItem.ID.GetBytes();
4058 bucket[0] = (byte)item.Type; 4427 //Array.Copy(objBytes, 0, bucket, 1, 16);
4059 4428
4060 GridInstantMessage msg = new GridInstantMessage(World, 4429 GridInstantMessage msg = new GridInstantMessage(World,
4061 m_host.OwnerID, m_host.Name, destId, 4430 m_host.OwnerID, m_host.Name, destId,
4062 (byte)InstantMessageDialog.TaskInventoryOffered, 4431 (byte)InstantMessageDialog.TaskInventoryOffered,
4063 false, item.Name+". "+m_host.Name+" is located at "+ 4432 false, item.Name+". "+m_host.Name+" is located at "+
4064 World.RegionInfo.RegionName+" "+ 4433 World.RegionInfo.RegionName+" "+
4065 m_host.AbsolutePosition.ToString(), 4434 m_host.AbsolutePosition.ToString(),
4066 agentItem.ID, true, m_host.AbsolutePosition, 4435 agentItem.ID, true, m_host.AbsolutePosition,
4067 bucket, true); 4436 bucket, true);
4068 4437
4069 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4438 ScenePresence sp;
4070 }
4071 4439
4440 if (World.TryGetScenePresence(destId, out sp))
4441 {
4442 sp.ControllingClient.SendInstantMessage(msg);
4443 }
4444 else
4445 {
4446 if (m_TransferModule != null)
4447 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4448 }
4449
4450 //This delay should only occur when giving inventory to avatars.
4072 ScriptSleep(3000); 4451 ScriptSleep(3000);
4073 } 4452 }
4074 } 4453 }
4075 4454
4455 [DebuggerNonUserCode]
4076 public void llRemoveInventory(string name) 4456 public void llRemoveInventory(string name)
4077 { 4457 {
4078 m_host.AddScriptLPS(1); 4458 m_host.AddScriptLPS(1);
@@ -4127,109 +4507,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4127 { 4507 {
4128 m_host.AddScriptLPS(1); 4508 m_host.AddScriptLPS(1);
4129 4509
4130 UUID uuid = (UUID)id; 4510 UUID uuid;
4131 PresenceInfo pinfo = null; 4511 if (UUID.TryParse(id, out uuid))
4132 UserAccount account;
4133
4134 UserInfoCacheEntry ce;
4135 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4136 { 4512 {
4137 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4513 PresenceInfo pinfo = null;
4138 if (account == null) 4514 UserAccount account;
4515
4516 UserInfoCacheEntry ce;
4517 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4139 { 4518 {
4140 m_userInfoCache[uuid] = null; // Cache negative 4519 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4141 return UUID.Zero.ToString(); 4520 if (account == null)
4142 } 4521 {
4522 m_userInfoCache[uuid] = null; // Cache negative
4523 return UUID.Zero.ToString();
4524 }
4143 4525
4144 4526
4145 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4527 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4146 if (pinfos != null && pinfos.Length > 0) 4528 if (pinfos != null && pinfos.Length > 0)
4147 {
4148 foreach (PresenceInfo p in pinfos)
4149 { 4529 {
4150 if (p.RegionID != UUID.Zero) 4530 foreach (PresenceInfo p in pinfos)
4151 { 4531 {
4152 pinfo = p; 4532 if (p.RegionID != UUID.Zero)
4533 {
4534 pinfo = p;
4535 }
4153 } 4536 }
4154 } 4537 }
4155 }
4156 4538
4157 ce = new UserInfoCacheEntry(); 4539 ce = new UserInfoCacheEntry();
4158 ce.time = Util.EnvironmentTickCount(); 4540 ce.time = Util.EnvironmentTickCount();
4159 ce.account = account; 4541 ce.account = account;
4160 ce.pinfo = pinfo; 4542 ce.pinfo = pinfo;
4161 } 4543 m_userInfoCache[uuid] = ce;
4162 else 4544 }
4163 { 4545 else
4164 if (ce == null) 4546 {
4165 return UUID.Zero.ToString(); 4547 if (ce == null)
4548 return UUID.Zero.ToString();
4166 4549
4167 account = ce.account; 4550 account = ce.account;
4168 pinfo = ce.pinfo; 4551 pinfo = ce.pinfo;
4169 } 4552 }
4170 4553
4171 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4554 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4172 {
4173 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4174 if (pinfos != null && pinfos.Length > 0)
4175 { 4555 {
4176 foreach (PresenceInfo p in pinfos) 4556 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4557 if (pinfos != null && pinfos.Length > 0)
4177 { 4558 {
4178 if (p.RegionID != UUID.Zero) 4559 foreach (PresenceInfo p in pinfos)
4179 { 4560 {
4180 pinfo = p; 4561 if (p.RegionID != UUID.Zero)
4562 {
4563 pinfo = p;
4564 }
4181 } 4565 }
4182 } 4566 }
4183 } 4567 else
4184 else 4568 pinfo = null;
4185 pinfo = null;
4186 4569
4187 ce.time = Util.EnvironmentTickCount(); 4570 ce.time = Util.EnvironmentTickCount();
4188 ce.pinfo = pinfo; 4571 ce.pinfo = pinfo;
4189 } 4572 }
4190 4573
4191 string reply = String.Empty; 4574 string reply = String.Empty;
4192 4575
4193 switch (data) 4576 switch (data)
4194 { 4577 {
4195 case 1: // DATA_ONLINE (0|1) 4578 case 1: // DATA_ONLINE (0|1)
4196 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4579 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4197 reply = "1"; 4580 reply = "1";
4198 else 4581 else
4199 reply = "0"; 4582 reply = "0";
4200 break; 4583 break;
4201 case 2: // DATA_NAME (First Last) 4584 case 2: // DATA_NAME (First Last)
4202 reply = account.FirstName + " " + account.LastName; 4585 reply = account.FirstName + " " + account.LastName;
4203 break; 4586 break;
4204 case 3: // DATA_BORN (YYYY-MM-DD) 4587 case 3: // DATA_BORN (YYYY-MM-DD)
4205 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4588 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4206 born = born.AddSeconds(account.Created); 4589 born = born.AddSeconds(account.Created);
4207 reply = born.ToString("yyyy-MM-dd"); 4590 reply = born.ToString("yyyy-MM-dd");
4208 break; 4591 break;
4209 case 4: // DATA_RATING (0,0,0,0,0,0) 4592 case 4: // DATA_RATING (0,0,0,0,0,0)
4210 reply = "0,0,0,0,0,0"; 4593 reply = "0,0,0,0,0,0";
4211 break; 4594 break;
4212 case 7: // DATA_USERLEVEL (integer) 4595 case 8: // DATA_PAYINFO (0|1|2|3)
4213 reply = account.UserLevel.ToString(); 4596 reply = "0";
4214 break; 4597 break;
4215 case 8: // DATA_PAYINFO (0|1|2|3) 4598 default:
4216 reply = "0"; 4599 return UUID.Zero.ToString(); // Raise no event
4217 break; 4600 }
4218 default:
4219 return UUID.Zero.ToString(); // Raise no event
4220 }
4221 4601
4222 UUID rq = UUID.Random(); 4602 UUID rq = UUID.Random();
4223 4603
4224 UUID tid = AsyncCommands. 4604 UUID tid = AsyncCommands.
4225 DataserverPlugin.RegisterRequest(m_host.LocalId, 4605 DataserverPlugin.RegisterRequest(m_host.LocalId,
4226 m_item.ItemID, rq.ToString()); 4606 m_item.ItemID, rq.ToString());
4227 4607
4228 AsyncCommands. 4608 AsyncCommands.
4229 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4609 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4230 4610
4231 ScriptSleep(100); 4611 ScriptSleep(100);
4232 return tid.ToString(); 4612 return tid.ToString();
4613 }
4614 else
4615 {
4616 ShoutError("Invalid UUID passed to llRequestAgentData.");
4617 }
4618 return "";
4233 } 4619 }
4234 4620
4235 public LSL_String llRequestInventoryData(string name) 4621 public LSL_String llRequestInventoryData(string name)
@@ -4286,12 +4672,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4286 if (UUID.TryParse(agent, out agentId)) 4672 if (UUID.TryParse(agent, out agentId))
4287 { 4673 {
4288 ScenePresence presence = World.GetScenePresence(agentId); 4674 ScenePresence presence = World.GetScenePresence(agentId);
4289 if (presence != null) 4675 if (presence != null && presence.PresenceType != PresenceType.Npc)
4290 { 4676 {
4677 // agent must not be a god
4678 if (presence.UserLevel >= 200) return;
4679
4291 // agent must be over the owners land 4680 // agent must be over the owners land
4292 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4681 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4293 { 4682 {
4294 World.TeleportClientHome(agentId, presence.ControllingClient); 4683 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4684 {
4685 // They can't be teleported home for some reason
4686 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4687 if (regionInfo != null)
4688 {
4689 World.RequestTeleportLocation(
4690 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4691 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4692 }
4693 }
4295 } 4694 }
4296 } 4695 }
4297 } 4696 }
@@ -4309,20 +4708,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4309 ScenePresence presence = World.GetScenePresence(agentId); 4708 ScenePresence presence = World.GetScenePresence(agentId);
4310 if (presence != null && presence.PresenceType != PresenceType.Npc) 4709 if (presence != null && presence.PresenceType != PresenceType.Npc)
4311 { 4710 {
4312 // agent must not be a god
4313 if (presence.GodLevel >= 200) return;
4314
4315 if (destination == String.Empty) 4711 if (destination == String.Empty)
4316 destination = World.RegionInfo.RegionName; 4712 destination = World.RegionInfo.RegionName;
4317 4713
4318 // agent must be over the owners land 4714 if (m_item.PermsGranter == agentId)
4319 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4715 {
4716 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4717 {
4718 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4719 }
4720 }
4721
4722 // agent must be wearing the object
4723 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4320 { 4724 {
4321 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4725 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4322 } 4726 }
4323 else // or must be wearing the prim 4727 else
4324 { 4728 {
4325 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4729 // agent must not be a god
4730 if (presence.GodLevel >= 200) return;
4731
4732 // agent must be over the owners land
4733 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
4734 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
4735 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4326 { 4736 {
4327 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4737 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4328 } 4738 }
@@ -4336,24 +4746,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4336 m_host.AddScriptLPS(1); 4746 m_host.AddScriptLPS(1);
4337 UUID agentId = new UUID(); 4747 UUID agentId = new UUID();
4338 4748
4339 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4749 ulong regionHandle = Utils.UIntsToLong((uint)(global_coords.x / 256) * 256, (uint)(global_coords.y / 256) * 256);
4340 4750
4341 if (UUID.TryParse(agent, out agentId)) 4751 if (UUID.TryParse(agent, out agentId))
4342 { 4752 {
4753 // This function is owner only!
4754 if (m_host.OwnerID != agentId)
4755 return;
4756
4343 ScenePresence presence = World.GetScenePresence(agentId); 4757 ScenePresence presence = World.GetScenePresence(agentId);
4758
4759 // Can't TP sitting avatars
4760 if (presence.ParentID != 0) // Sitting
4761 return;
4762
4344 if (presence != null && presence.PresenceType != PresenceType.Npc) 4763 if (presence != null && presence.PresenceType != PresenceType.Npc)
4345 { 4764 {
4346 // agent must not be a god 4765 if (m_item.PermsGranter == agentId)
4347 if (presence.GodLevel >= 200) return;
4348
4349 // agent must be over the owners land
4350 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4351 { 4766 {
4352 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4767 // If attached using llAttachToAvatarTemp, cowardly refuse
4353 } 4768 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
4354 else // or must be wearing the prim 4769 return;
4355 { 4770
4356 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4771 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4357 { 4772 {
4358 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4773 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4359 } 4774 }
@@ -4397,7 +4812,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4397 UUID av = new UUID(); 4812 UUID av = new UUID();
4398 if (!UUID.TryParse(agent,out av)) 4813 if (!UUID.TryParse(agent,out av))
4399 { 4814 {
4400 LSLError("First parameter to llDialog needs to be a key");
4401 return; 4815 return;
4402 } 4816 }
4403 4817
@@ -4430,9 +4844,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4430 { 4844 {
4431 m_host.AddScriptLPS(1); 4845 m_host.AddScriptLPS(1);
4432 4846
4847 if(impact_sound == "")
4848 {
4849 m_host.CollisionSoundVolume = (float)impact_volume;
4850 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4851 m_host.CollisionSoundType = 0;
4852 return;
4853 }
4433 // TODO: Parameter check logic required. 4854 // TODO: Parameter check logic required.
4434 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4855 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4435 m_host.CollisionSoundVolume = (float)impact_volume; 4856 m_host.CollisionSoundVolume = (float)impact_volume;
4857 m_host.CollisionSoundType = 1;
4436 } 4858 }
4437 4859
4438 public LSL_String llGetAnimation(string id) 4860 public LSL_String llGetAnimation(string id)
@@ -4446,14 +4868,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4446 4868
4447 if (m_host.RegionHandle == presence.RegionHandle) 4869 if (m_host.RegionHandle == presence.RegionHandle)
4448 { 4870 {
4449 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4450
4451 if (presence != null) 4871 if (presence != null)
4452 { 4872 {
4453 AnimationSet currentAnims = presence.Animator.Animations; 4873 if (presence.SitGround)
4454 string currentAnimationState = String.Empty; 4874 return "Sitting on Ground";
4455 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4875 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4456 return currentAnimationState; 4876 return "Sitting";
4877
4878 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4879 string lslMovementAnimation;
4880
4881 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4882 return lslMovementAnimation;
4457 } 4883 }
4458 } 4884 }
4459 4885
@@ -4601,7 +5027,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4601 { 5027 {
4602 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 5028 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4603 float distance_term = distance * distance * distance; // Script Energy 5029 float distance_term = distance * distance * distance; // Script Energy
4604 float pusher_mass = m_host.GetMass(); 5030 // use total object mass and not part
5031 float pusher_mass = m_host.ParentGroup.GetMass();
4605 5032
4606 float PUSH_ATTENUATION_DISTANCE = 17f; 5033 float PUSH_ATTENUATION_DISTANCE = 17f;
4607 float PUSH_ATTENUATION_SCALE = 5f; 5034 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4838,6 +5265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4838 { 5265 {
4839 return item.AssetID.ToString(); 5266 return item.AssetID.ToString();
4840 } 5267 }
5268 m_host.TaskInventory.LockItemsForRead(false);
4841 5269
4842 return UUID.Zero.ToString(); 5270 return UUID.Zero.ToString();
4843 } 5271 }
@@ -4990,14 +5418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4990 { 5418 {
4991 m_host.AddScriptLPS(1); 5419 m_host.AddScriptLPS(1);
4992 5420
4993 if (src == null) 5421 return src.Length;
4994 {
4995 return 0;
4996 }
4997 else
4998 {
4999 return src.Length;
5000 }
5001 } 5422 }
5002 5423
5003 public LSL_Integer llList2Integer(LSL_List src, int index) 5424 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5068,7 +5489,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5068 else if (src.Data[index] is LSL_Float) 5489 else if (src.Data[index] is LSL_Float)
5069 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5490 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5070 else if (src.Data[index] is LSL_String) 5491 else if (src.Data[index] is LSL_String)
5071 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5492 {
5493 string str = ((LSL_String) src.Data[index]).m_string;
5494 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5495 if (m != Match.Empty)
5496 {
5497 str = m.Value;
5498 double d = 0.0;
5499 if (!Double.TryParse(str, out d))
5500 return 0.0;
5501
5502 return d;
5503 }
5504 return 0.0;
5505 }
5072 return Convert.ToDouble(src.Data[index]); 5506 return Convert.ToDouble(src.Data[index]);
5073 } 5507 }
5074 catch (FormatException) 5508 catch (FormatException)
@@ -5110,7 +5544,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5110 // for completion and should LSL_Key ever be implemented 5544 // for completion and should LSL_Key ever be implemented
5111 // as it's own struct 5545 // as it's own struct
5112 else if (!(src.Data[index] is LSL_String || 5546 else if (!(src.Data[index] is LSL_String ||
5113 src.Data[index] is LSL_Key)) 5547 src.Data[index] is LSL_Key ||
5548 src.Data[index] is String))
5114 { 5549 {
5115 return ""; 5550 return "";
5116 } 5551 }
@@ -5368,7 +5803,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5368 } 5803 }
5369 } 5804 }
5370 } 5805 }
5371 else { 5806 else
5807 {
5372 object[] array = new object[src.Length]; 5808 object[] array = new object[src.Length];
5373 Array.Copy(src.Data, 0, array, 0, src.Length); 5809 Array.Copy(src.Data, 0, array, 0, src.Length);
5374 result = new LSL_List(array); 5810 result = new LSL_List(array);
@@ -5475,7 +5911,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5475 public LSL_Integer llGetRegionAgentCount() 5911 public LSL_Integer llGetRegionAgentCount()
5476 { 5912 {
5477 m_host.AddScriptLPS(1); 5913 m_host.AddScriptLPS(1);
5478 return new LSL_Integer(World.GetRootAgentCount()); 5914
5915 int count = 0;
5916 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5917 count++;
5918 });
5919
5920 return new LSL_Integer(count);
5479 } 5921 }
5480 5922
5481 public LSL_Vector llGetRegionCorner() 5923 public LSL_Vector llGetRegionCorner()
@@ -5716,6 +6158,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5716 flags |= ScriptBaseClass.AGENT_AWAY; 6158 flags |= ScriptBaseClass.AGENT_AWAY;
5717 } 6159 }
5718 6160
6161 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6162 UUID[] anims = agent.Animator.GetAnimationArray();
6163 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6164 {
6165 flags |= ScriptBaseClass.AGENT_BUSY;
6166 }
6167
5719 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6168 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5720 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6169 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5721 { 6170 {
@@ -5763,6 +6212,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5763 flags |= ScriptBaseClass.AGENT_SITTING; 6212 flags |= ScriptBaseClass.AGENT_SITTING;
5764 } 6213 }
5765 6214
6215 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6216 {
6217 flags |= ScriptBaseClass.AGENT_MALE;
6218 }
6219
5766 return flags; 6220 return flags;
5767 } 6221 }
5768 6222
@@ -5908,9 +6362,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5908 6362
5909 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6363 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5910 6364
5911 foreach (SceneObjectPart part in parts) 6365 try
6366 {
6367 foreach (SceneObjectPart part in parts)
6368 {
6369 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6370 }
6371 }
6372 finally
5912 { 6373 {
5913 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5914 } 6374 }
5915 } 6375 }
5916 6376
@@ -5964,13 +6424,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5964 6424
5965 if (m_host.OwnerID == land.LandData.OwnerID) 6425 if (m_host.OwnerID == land.LandData.OwnerID)
5966 { 6426 {
5967 World.TeleportClientHome(agentID, presence.ControllingClient); 6427 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6428 presence.TeleportWithMomentum(p, null);
6429 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5968 } 6430 }
5969 } 6431 }
5970 } 6432 }
5971 ScriptSleep(5000); 6433 ScriptSleep(5000);
5972 } 6434 }
5973 6435
6436 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6437 {
6438 return ParseString2List(str, separators, in_spacers, false);
6439 }
6440
5974 public LSL_Integer llOverMyLand(string id) 6441 public LSL_Integer llOverMyLand(string id)
5975 { 6442 {
5976 m_host.AddScriptLPS(1); 6443 m_host.AddScriptLPS(1);
@@ -6023,26 +6490,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6023 } 6490 }
6024 else 6491 else
6025 { 6492 {
6026 agentSize = GetAgentSize(avatar); 6493// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6494 Vector3 s = avatar.Appearance.AvatarSize;
6495 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
6027 } 6496 }
6028
6029 return agentSize; 6497 return agentSize;
6030 } 6498 }
6031 6499
6032 public LSL_Integer llSameGroup(string agent) 6500 public LSL_Integer llSameGroup(string id)
6033 { 6501 {
6034 m_host.AddScriptLPS(1); 6502 m_host.AddScriptLPS(1);
6035 UUID agentId = new UUID(); 6503 UUID uuid = new UUID();
6036 if (!UUID.TryParse(agent, out agentId)) 6504 if (!UUID.TryParse(id, out uuid))
6037 return new LSL_Integer(0); 6505 return new LSL_Integer(0);
6038 ScenePresence presence = World.GetScenePresence(agentId); 6506
6039 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6507 // Check if it's a group key
6040 return new LSL_Integer(0); 6508 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6041 IClientAPI client = presence.ControllingClient;
6042 if (m_host.GroupID == client.ActiveGroupId)
6043 return new LSL_Integer(1); 6509 return new LSL_Integer(1);
6044 else 6510
6511 // We got passed a UUID.Zero
6512 if (uuid == UUID.Zero)
6513 return new LSL_Integer(0);
6514
6515 // Handle the case where id names an avatar
6516 ScenePresence presence = World.GetScenePresence(uuid);
6517 if (presence != null)
6518 {
6519 if (presence.IsChildAgent)
6520 return new LSL_Integer(0);
6521
6522 IClientAPI client = presence.ControllingClient;
6523 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6524 return new LSL_Integer(1);
6525
6526 return new LSL_Integer(0);
6527 }
6528
6529 // Handle object case
6530 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6531 if (part != null)
6532 {
6533 // This will handle both deed and non-deed and also the no
6534 // group case
6535 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6536 return new LSL_Integer(1);
6537
6045 return new LSL_Integer(0); 6538 return new LSL_Integer(0);
6539 }
6540
6541 return new LSL_Integer(0);
6046 } 6542 }
6047 6543
6048 public void llUnSit(string id) 6544 public void llUnSit(string id)
@@ -6601,6 +7097,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6601 7097
6602 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7098 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6603 { 7099 {
7100 // LSL quaternions can normalize to 0, normal Quaternions can't.
7101 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7102 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7103
6604 part.SitTargetPosition = offset; 7104 part.SitTargetPosition = offset;
6605 part.SitTargetOrientation = rot; 7105 part.SitTargetOrientation = rot;
6606 part.ParentGroup.HasGroupChanged = true; 7106 part.ParentGroup.HasGroupChanged = true;
@@ -6787,30 +7287,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6787 UUID av = new UUID(); 7287 UUID av = new UUID();
6788 if (!UUID.TryParse(avatar,out av)) 7288 if (!UUID.TryParse(avatar,out av))
6789 { 7289 {
6790 LSLError("First parameter to llDialog needs to be a key"); 7290 //LSLError("First parameter to llDialog needs to be a key");
6791 return; 7291 return;
6792 } 7292 }
6793 if (buttons.Length < 1) 7293 if (buttons.Length < 1)
6794 { 7294 {
6795 LSLError("No less than 1 button can be shown"); 7295 buttons.Add("OK");
6796 return;
6797 } 7296 }
6798 if (buttons.Length > 12) 7297 if (buttons.Length > 12)
6799 { 7298 {
6800 LSLError("No more than 12 buttons can be shown"); 7299 ShoutError("button list too long, must be 12 or fewer entries");
6801 return;
6802 } 7300 }
6803 string[] buts = new string[buttons.Length]; 7301 int length = buttons.Length;
6804 for (int i = 0; i < buttons.Length; i++) 7302 if (length > 12)
7303 length = 12;
7304
7305 string[] buts = new string[length];
7306 for (int i = 0; i < length; i++)
6805 { 7307 {
6806 if (buttons.Data[i].ToString() == String.Empty) 7308 if (buttons.Data[i].ToString() == String.Empty)
6807 { 7309 {
6808 LSLError("button label cannot be blank"); 7310 ShoutError("button label cannot be blank");
6809 return; 7311 return;
6810 } 7312 }
6811 if (buttons.Data[i].ToString().Length > 24) 7313 if (buttons.Data[i].ToString().Length > 24)
6812 { 7314 {
6813 LSLError("button label cannot be longer than 24 characters"); 7315 ShoutError("button label cannot be longer than 24 characters");
6814 return; 7316 return;
6815 } 7317 }
6816 buts[i] = buttons.Data[i].ToString(); 7318 buts[i] = buttons.Data[i].ToString();
@@ -6877,9 +7379,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6877 return; 7379 return;
6878 } 7380 }
6879 7381
6880 // the rest of the permission checks are done in RezScript, so check the pin there as well 7382 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6881 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7383 if (dest != null)
7384 {
7385 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7386 {
7387 // the rest of the permission checks are done in RezScript, so check the pin there as well
7388 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6882 7389
7390 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7391 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7392 }
7393 }
6883 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7394 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6884 ScriptSleep(3000); 7395 ScriptSleep(3000);
6885 } 7396 }
@@ -6953,19 +7464,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6953 public LSL_String llMD5String(string src, int nonce) 7464 public LSL_String llMD5String(string src, int nonce)
6954 { 7465 {
6955 m_host.AddScriptLPS(1); 7466 m_host.AddScriptLPS(1);
6956 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7467 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6957 } 7468 }
6958 7469
6959 public LSL_String llSHA1String(string src) 7470 public LSL_String llSHA1String(string src)
6960 { 7471 {
6961 m_host.AddScriptLPS(1); 7472 m_host.AddScriptLPS(1);
6962 return Util.SHA1Hash(src).ToLower(); 7473 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6963 } 7474 }
6964 7475
6965 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7476 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6966 { 7477 {
6967 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7478 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6968 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7479 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7480 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7481 return shapeBlock;
6969 7482
6970 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7483 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6971 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7484 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7070,6 +7583,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7070 // Prim type box, cylinder and prism. 7583 // Prim type box, cylinder and prism.
7071 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) 7584 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)
7072 { 7585 {
7586 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7587 return;
7588
7073 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7589 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7074 ObjectShapePacket.ObjectDataBlock shapeBlock; 7590 ObjectShapePacket.ObjectDataBlock shapeBlock;
7075 7591
@@ -7123,6 +7639,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7123 // Prim type sphere. 7639 // Prim type sphere.
7124 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7640 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7125 { 7641 {
7642 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7643 return;
7644
7126 ObjectShapePacket.ObjectDataBlock shapeBlock; 7645 ObjectShapePacket.ObjectDataBlock shapeBlock;
7127 7646
7128 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7647 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7164,6 +7683,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7164 // Prim type torus, tube and ring. 7683 // Prim type torus, tube and ring.
7165 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) 7684 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)
7166 { 7685 {
7686 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7687 return;
7688
7167 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7689 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7168 ObjectShapePacket.ObjectDataBlock shapeBlock; 7690 ObjectShapePacket.ObjectDataBlock shapeBlock;
7169 7691
@@ -7299,6 +7821,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7299 // Prim type sculpt. 7821 // Prim type sculpt.
7300 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7822 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7301 { 7823 {
7824 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7825 return;
7826
7302 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7827 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7303 UUID sculptId; 7828 UUID sculptId;
7304 7829
@@ -7321,7 +7846,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7321 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7846 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7322 { 7847 {
7323 // default 7848 // default
7324 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7849 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7325 } 7850 }
7326 7851
7327 part.Shape.SetSculptProperties((byte)type, sculptId); 7852 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7338,15 +7863,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7338 ScriptSleep(200); 7863 ScriptSleep(200);
7339 } 7864 }
7340 7865
7341 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7342 {
7343 m_host.AddScriptLPS(1);
7344
7345 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7346
7347 ScriptSleep(200);
7348 }
7349
7350 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7866 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7351 { 7867 {
7352 m_host.AddScriptLPS(1); 7868 m_host.AddScriptLPS(1);
@@ -7354,169 +7870,135 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7354 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7870 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7355 } 7871 }
7356 7872
7357 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7873 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7358 { 7874 {
7359 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7875 List<object> parts = new List<object>();
7876 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7877 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7878 foreach (SceneObjectPart p in prims)
7879 parts.Add(p);
7880 foreach (ScenePresence p in avatars)
7881 parts.Add(p);
7360 7882
7361 LSL_List remaining = null; 7883 LSL_List remaining = null;
7362 uint rulesParsed = 0; 7884 uint rulesParsed = 0;
7363 7885
7364 foreach (SceneObjectPart part in parts) 7886 if (parts.Count > 0)
7365 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7366
7367 while (remaining != null && remaining.Length > 2)
7368 { 7887 {
7369 linknumber = remaining.GetLSLIntegerItem(0); 7888 foreach (object part in parts)
7370 rules = remaining.GetSublist(1, -1);
7371 parts = GetLinkParts(linknumber);
7372
7373 foreach (SceneObjectPart part in parts)
7374 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7375 }
7376 }
7377
7378 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7379 {
7380 SceneObjectGroup group = m_host.ParentGroup;
7381
7382 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7383 return;
7384 if (group.IsAttachment)
7385 return;
7386
7387 if (frames.Data.Length > 0) // We are getting a new motion
7388 {
7389 if (group.RootPart.KeyframeMotion != null)
7390 group.RootPart.KeyframeMotion.Delete();
7391 group.RootPart.KeyframeMotion = null;
7392
7393 int idx = 0;
7394
7395 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7396 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7397
7398 while (idx < options.Data.Length)
7399 { 7889 {
7400 int option = (int)options.GetLSLIntegerItem(idx++); 7890 if (part is SceneObjectPart)
7401 int remain = options.Data.Length - idx; 7891 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7892 else
7893 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7894 }
7402 7895
7403 switch (option) 7896 while ((object)remaining != null && remaining.Length > 2)
7897 {
7898 linknumber = remaining.GetLSLIntegerItem(0);
7899 rules = remaining.GetSublist(1, -1);
7900 parts.Clear();
7901 prims = GetLinkParts(linknumber);
7902 avatars = GetLinkAvatars(linknumber);
7903 foreach (SceneObjectPart p in prims)
7904 parts.Add(p);
7905 foreach (ScenePresence p in avatars)
7906 parts.Add(p);
7907
7908 remaining = null;
7909 foreach (object part in parts)
7404 { 7910 {
7405 case ScriptBaseClass.KFM_MODE: 7911 if (part is SceneObjectPart)
7406 if (remain < 1) 7912 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7407 break; 7913 else
7408 int modeval = (int)options.GetLSLIntegerItem(idx++); 7914 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7409 switch(modeval)
7410 {
7411 case ScriptBaseClass.KFM_FORWARD:
7412 mode = KeyframeMotion.PlayMode.Forward;
7413 break;
7414 case ScriptBaseClass.KFM_REVERSE:
7415 mode = KeyframeMotion.PlayMode.Reverse;
7416 break;
7417 case ScriptBaseClass.KFM_LOOP:
7418 mode = KeyframeMotion.PlayMode.Loop;
7419 break;
7420 case ScriptBaseClass.KFM_PING_PONG:
7421 mode = KeyframeMotion.PlayMode.PingPong;
7422 break;
7423 }
7424 break;
7425 case ScriptBaseClass.KFM_DATA:
7426 if (remain < 1)
7427 break;
7428 int dataval = (int)options.GetLSLIntegerItem(idx++);
7429 data = (KeyframeMotion.DataFormat)dataval;
7430 break;
7431 } 7915 }
7432 } 7916 }
7917 }
7918 }
7433 7919
7434 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); 7920 public LSL_List llGetPhysicsMaterial()
7921 {
7922 LSL_List result = new LSL_List();
7435 7923
7436 idx = 0; 7924 result.Add(new LSL_Float(m_host.GravityModifier));
7925 result.Add(new LSL_Float(m_host.Restitution));
7926 result.Add(new LSL_Float(m_host.Friction));
7927 result.Add(new LSL_Float(m_host.Density));
7437 7928
7438 int elemLength = 2; 7929 return result;
7439 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 7930 }
7440 elemLength = 3;
7441 7931
7442 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 7932 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7443 while (idx < frames.Data.Length) 7933 float material_density, float material_friction,
7444 { 7934 float material_restitution, float material_gravity_modifier)
7445 int remain = frames.Data.Length - idx; 7935 {
7936 ExtraPhysicsData physdata = new ExtraPhysicsData();
7937 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7938 physdata.Density = part.Density;
7939 physdata.Friction = part.Friction;
7940 physdata.Bounce = part.Restitution;
7941 physdata.GravitationModifier = part.GravityModifier;
7446 7942
7447 if (remain < elemLength) 7943 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7448 break; 7944 physdata.Density = material_density;
7945 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7946 physdata.Friction = material_friction;
7947 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7948 physdata.Bounce = material_restitution;
7949 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7950 physdata.GravitationModifier = material_gravity_modifier;
7449 7951
7450 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 7952 part.UpdateExtraPhysics(physdata);
7451 frame.Position = null; 7953 }
7452 frame.Rotation = null;
7453 7954
7454 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 7955 public void llSetPhysicsMaterial(int material_bits,
7455 { 7956 float material_gravity_modifier, float material_restitution,
7456 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); 7957 float material_friction, float material_density)
7457 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); 7958 {
7458 } 7959 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7459 if ((data & KeyframeMotion.DataFormat.Rotation) != 0) 7960 }
7460 {
7461 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7462 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7463 q.Normalize();
7464 frame.Rotation = q;
7465 }
7466 7961
7467 float tempf = (float)frames.GetLSLFloatItem(idx++); 7962 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7468 frame.TimeMS = (int)(tempf * 1000.0f); 7963 {
7964 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7965 llSetLinkPrimitiveParamsFast(linknumber, rules);
7966 ScriptSleep(200);
7967 }
7469 7968
7470 keyframes.Add(frame); 7969 // vector up using libomv (c&p from sop )
7471 } 7970 // vector up rotated by r
7971 private Vector3 Zrot(Quaternion r)
7972 {
7973 double x, y, z, m;
7472 7974
7473 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 7975 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7474 group.RootPart.KeyframeMotion.Start(); 7976 if (Math.Abs(1.0 - m) > 0.000001)
7475 }
7476 else
7477 { 7977 {
7478 if (group.RootPart.KeyframeMotion == null) 7978 m = 1.0 / Math.Sqrt(m);
7479 return; 7979 r.X *= (float)m;
7480 7980 r.Y *= (float)m;
7481 if (options.Data.Length == 0) 7981 r.Z *= (float)m;
7482 { 7982 r.W *= (float)m;
7483 group.RootPart.KeyframeMotion.Stop(); 7983 }
7484 return;
7485 }
7486
7487 int idx = 0;
7488 7984
7489 while (idx < options.Data.Length) 7985 x = 2 * (r.X * r.Z + r.Y * r.W);
7490 { 7986 y = 2 * (-r.X * r.W + r.Y * r.Z);
7491 int option = (int)options.GetLSLIntegerItem(idx++); 7987 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7492 7988
7493 switch (option) 7989 return new Vector3((float)x, (float)y, (float)z);
7494 {
7495 case ScriptBaseClass.KFM_COMMAND:
7496 int cmd = (int)options.GetLSLIntegerItem(idx++);
7497 switch (cmd)
7498 {
7499 case ScriptBaseClass.KFM_CMD_PLAY:
7500 group.RootPart.KeyframeMotion.Start();
7501 break;
7502 case ScriptBaseClass.KFM_CMD_STOP:
7503 group.RootPart.KeyframeMotion.Stop();
7504 break;
7505 case ScriptBaseClass.KFM_CMD_PAUSE:
7506 group.RootPart.KeyframeMotion.Pause();
7507 break;
7508 }
7509 break;
7510 }
7511 }
7512 }
7513 } 7990 }
7514 7991
7515 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7992 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7516 { 7993 {
7994 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7995 return null;
7996
7517 int idx = 0; 7997 int idx = 0;
7518 int idxStart = 0; 7998 int idxStart = 0;
7519 7999
8000 SceneObjectGroup parentgrp = part.ParentGroup;
8001
7520 bool positionChanged = false; 8002 bool positionChanged = false;
7521 LSL_Vector currentPosition = GetPartLocalPos(part); 8003 LSL_Vector currentPosition = GetPartLocalPos(part);
7522 8004
@@ -7541,8 +8023,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7541 return null; 8023 return null;
7542 8024
7543 v=rules.GetVector3Item(idx++); 8025 v=rules.GetVector3Item(idx++);
8026 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8027 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8028 else
8029 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7544 positionChanged = true; 8030 positionChanged = true;
7545 currentPosition = GetSetPosTarget(part, v, currentPosition);
7546 8031
7547 break; 8032 break;
7548 case (int)ScriptBaseClass.PRIM_SIZE: 8033 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7559,7 +8044,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7559 8044
7560 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8045 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7561 // try to let this work as in SL... 8046 // try to let this work as in SL...
7562 if (part.ParentID == 0) 8047 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7563 { 8048 {
7564 // special case: If we are root, rotate complete SOG to new rotation 8049 // special case: If we are root, rotate complete SOG to new rotation
7565 SetRot(part, q); 8050 SetRot(part, q);
@@ -7853,6 +8338,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7853 8338
7854 break; 8339 break;
7855 8340
8341 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8342 if (remain < 5)
8343 return null;
8344
8345 int material_bits = rules.GetLSLIntegerItem(idx++);
8346 float material_density = (float)rules.GetLSLFloatItem(idx++);
8347 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8348 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8349 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8350
8351 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8352
8353 break;
8354
7856 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8355 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7857 if (remain < 1) 8356 if (remain < 1)
7858 return null; 8357 return null;
@@ -7932,14 +8431,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7932 if (part.ParentGroup.RootPart == part) 8431 if (part.ParentGroup.RootPart == part)
7933 { 8432 {
7934 SceneObjectGroup parent = part.ParentGroup; 8433 SceneObjectGroup parent = part.ParentGroup;
7935 parent.UpdateGroupPosition(currentPosition); 8434 Util.FireAndForget(delegate(object x) {
8435 parent.UpdateGroupPosition(currentPosition);
8436 });
7936 } 8437 }
7937 else 8438 else
7938 { 8439 {
7939 part.OffsetPosition = currentPosition; 8440 part.OffsetPosition = currentPosition;
7940 SceneObjectGroup parent = part.ParentGroup; 8441// SceneObjectGroup parent = part.ParentGroup;
7941 parent.HasGroupChanged = true; 8442// parent.HasGroupChanged = true;
7942 parent.ScheduleGroupForTerseUpdate(); 8443// parent.ScheduleGroupForTerseUpdate();
8444 part.ScheduleTerseUpdate();
7943 } 8445 }
7944 } 8446 }
7945 } 8447 }
@@ -7977,10 +8479,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7977 8479
7978 public LSL_String llXorBase64Strings(string str1, string str2) 8480 public LSL_String llXorBase64Strings(string str1, string str2)
7979 { 8481 {
7980 m_host.AddScriptLPS(1); 8482 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7981 Deprecated("llXorBase64Strings"); 8483
7982 ScriptSleep(300); 8484 ScriptSleep(300);
7983 return String.Empty; 8485 m_host.AddScriptLPS(1);
8486
8487 if (str1 == String.Empty)
8488 return String.Empty;
8489 if (str2 == String.Empty)
8490 return str1;
8491
8492 int len = str2.Length;
8493 if ((len % 4) != 0) // LL is EVIL!!!!
8494 {
8495 while (str2.EndsWith("="))
8496 str2 = str2.Substring(0, str2.Length - 1);
8497
8498 len = str2.Length;
8499 int mod = len % 4;
8500
8501 if (mod == 1)
8502 str2 = str2.Substring(0, str2.Length - 1);
8503 else if (mod == 2)
8504 str2 += "==";
8505 else if (mod == 3)
8506 str2 += "=";
8507 }
8508
8509 byte[] data1;
8510 byte[] data2;
8511 try
8512 {
8513 data1 = Convert.FromBase64String(str1);
8514 data2 = Convert.FromBase64String(str2);
8515 }
8516 catch (Exception)
8517 {
8518 return new LSL_String(String.Empty);
8519 }
8520
8521 // For cases where the decoded length of s2 is greater
8522 // than the decoded length of s1, simply perform a normal
8523 // decode and XOR
8524 //
8525 if (data2.Length >= data1.Length)
8526 {
8527 for (int pos = 0 ; pos < data1.Length ; pos++ )
8528 data1[pos] ^= data2[pos];
8529
8530 return Convert.ToBase64String(data1);
8531 }
8532
8533 // Remove padding
8534 while (str1.EndsWith("="))
8535 str1 = str1.Substring(0, str1.Length - 1);
8536 while (str2.EndsWith("="))
8537 str2 = str2.Substring(0, str2.Length - 1);
8538
8539 byte[] d1 = new byte[str1.Length];
8540 byte[] d2 = new byte[str2.Length];
8541
8542 for (int i = 0 ; i < str1.Length ; i++)
8543 {
8544 int idx = b64.IndexOf(str1.Substring(i, 1));
8545 if (idx == -1)
8546 idx = 0;
8547 d1[i] = (byte)idx;
8548 }
8549
8550 for (int i = 0 ; i < str2.Length ; i++)
8551 {
8552 int idx = b64.IndexOf(str2.Substring(i, 1));
8553 if (idx == -1)
8554 idx = 0;
8555 d2[i] = (byte)idx;
8556 }
8557
8558 string output = String.Empty;
8559
8560 for (int pos = 0 ; pos < d1.Length ; pos++)
8561 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8562
8563 while (output.Length % 3 > 0)
8564 output += "=";
8565
8566 return output;
7984 } 8567 }
7985 8568
7986 public void llRemoteDataSetRegion() 8569 public void llRemoteDataSetRegion()
@@ -8105,8 +8688,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8105 public LSL_Integer llGetNumberOfPrims() 8688 public LSL_Integer llGetNumberOfPrims()
8106 { 8689 {
8107 m_host.AddScriptLPS(1); 8690 m_host.AddScriptLPS(1);
8108 8691 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
8109 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8692
8693 return m_host.ParentGroup.PrimCount + avatarCount;
8110 } 8694 }
8111 8695
8112 /// <summary> 8696 /// <summary>
@@ -8121,55 +8705,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8121 m_host.AddScriptLPS(1); 8705 m_host.AddScriptLPS(1);
8122 UUID objID = UUID.Zero; 8706 UUID objID = UUID.Zero;
8123 LSL_List result = new LSL_List(); 8707 LSL_List result = new LSL_List();
8708
8709 // If the ID is not valid, return null result
8124 if (!UUID.TryParse(obj, out objID)) 8710 if (!UUID.TryParse(obj, out objID))
8125 { 8711 {
8126 result.Add(new LSL_Vector()); 8712 result.Add(new LSL_Vector());
8127 result.Add(new LSL_Vector()); 8713 result.Add(new LSL_Vector());
8128 return result; 8714 return result;
8129 } 8715 }
8716
8717 // Check if this is an attached prim. If so, replace
8718 // the UUID with the avatar UUID and report it's bounding box
8719 SceneObjectPart part = World.GetSceneObjectPart(objID);
8720 if (part != null && part.ParentGroup.IsAttachment)
8721 objID = part.ParentGroup.AttachedAvatar;
8722
8723 // Find out if this is an avatar ID. If so, return it's box
8130 ScenePresence presence = World.GetScenePresence(objID); 8724 ScenePresence presence = World.GetScenePresence(objID);
8131 if (presence != null) 8725 if (presence != null)
8132 { 8726 {
8133 if (presence.ParentID == 0) // not sat on an object 8727 // As per LSL Wiki, there is no difference between sitting
8728 // and standing avatar since server 1.36
8729 LSL_Vector lower;
8730 LSL_Vector upper;
8731
8732 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8733
8734 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8735 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8736/*
8134 { 8737 {
8135 LSL_Vector lower; 8738 // This is for ground sitting avatars
8136 LSL_Vector upper; 8739 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8137 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8740 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8138 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8741 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8139 {
8140 // This is for ground sitting avatars
8141 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8142 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8143 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8144 }
8145 else
8146 {
8147 // This is for standing/flying avatars
8148 float height = presence.Appearance.AvatarHeight / 2.0f;
8149 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8150 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8151 }
8152 result.Add(lower);
8153 result.Add(upper);
8154 return result;
8155 } 8742 }
8156 else 8743 else
8157 { 8744 {
8158 // sitting on an object so we need the bounding box of that 8745 // This is for standing/flying avatars
8159 // which should include the avatar so set the UUID to the 8746 float height = presence.Appearance.AvatarHeight / 2.0f;
8160 // UUID of the object the avatar is sat on and allow it to fall through 8747 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8161 // to processing an object 8748 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8162 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
8163 objID = p.UUID;
8164 } 8749 }
8750
8751 // Adjust to the documented error offsets (see LSL Wiki)
8752 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8753 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8754*/
8755 {
8756 // This is for ground sitting avatars TODO!
8757 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8758 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8759 }
8760 else
8761 {
8762 // This is for standing/flying avatars
8763 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8764 upper = new LSL_Vector(box.X, box.Y, box.Z);
8765 }
8766
8767 if (lower.x > upper.x)
8768 lower.x = upper.x;
8769 if (lower.y > upper.y)
8770 lower.y = upper.y;
8771 if (lower.z > upper.z)
8772 lower.z = upper.z;
8773
8774 result.Add(lower);
8775 result.Add(upper);
8776 return result;
8165 } 8777 }
8166 SceneObjectPart part = World.GetSceneObjectPart(objID); 8778
8779 part = World.GetSceneObjectPart(objID);
8167 // Currently only works for single prims without a sitting avatar 8780 // Currently only works for single prims without a sitting avatar
8168 if (part != null) 8781 if (part != null)
8169 { 8782 {
8170 Vector3 halfSize = part.Scale / 2.0f; 8783 float minX;
8171 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8784 float maxX;
8172 LSL_Vector upper = new LSL_Vector(halfSize); 8785 float minY;
8786 float maxY;
8787 float minZ;
8788 float maxZ;
8789
8790 // This BBox is in sim coordinates, with the offset being
8791 // a contained point.
8792 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8793 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8794
8795 minX -= offsets[0].X;
8796 maxX -= offsets[0].X;
8797 minY -= offsets[0].Y;
8798 maxY -= offsets[0].Y;
8799 minZ -= offsets[0].Z;
8800 maxZ -= offsets[0].Z;
8801
8802 LSL_Vector lower;
8803 LSL_Vector upper;
8804
8805 // Adjust to the documented error offsets (see LSL Wiki)
8806 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8807 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8808
8809 if (lower.x > upper.x)
8810 lower.x = upper.x;
8811 if (lower.y > upper.y)
8812 lower.y = upper.y;
8813 if (lower.z > upper.z)
8814 lower.z = upper.z;
8815
8173 result.Add(lower); 8816 result.Add(lower);
8174 result.Add(upper); 8817 result.Add(upper);
8175 return result; 8818 return result;
@@ -8186,227 +8829,70 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8186 return new LSL_Vector(m_host.GetGeometricCenter()); 8829 return new LSL_Vector(m_host.GetGeometricCenter());
8187 } 8830 }
8188 8831
8189 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8832 public LSL_List llGetPrimitiveParams(LSL_List rules)
8190 { 8833 {
8191 LSL_List result = new LSL_List(); 8834 m_host.AddScriptLPS(1);
8192 LSL_List remaining = null;
8193
8194 while (true)
8195 {
8196// m_log.DebugFormat(
8197// "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}",
8198// rules.Length, entity != null ? entity.Name : "NULL");
8199
8200 if (entity == null)
8201 return result;
8202 8835
8203 if (entity is SceneObjectPart) 8836 LSL_List result = new LSL_List();
8204 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
8205 else
8206 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
8207 8837
8208 if (remaining == null || remaining.Length < 2) 8838 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8209 return result;
8210 8839
8840 while ((object)remaining != null && remaining.Length > 2)
8841 {
8211 int linknumber = remaining.GetLSLIntegerItem(0); 8842 int linknumber = remaining.GetLSLIntegerItem(0);
8212 rules = remaining.GetSublist(1, -1); 8843 rules = remaining.GetSublist(1, -1);
8213 entity = GetLinkEntity(linknumber); 8844 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8214 }
8215 }
8216 8845
8217 public LSL_List llGetPrimitiveParams(LSL_List rules) 8846 foreach (SceneObjectPart part in parts)
8218 { 8847 remaining = GetPrimParams(part, rules, ref result);
8219 m_host.AddScriptLPS(1); 8848 }
8220 8849
8221 return GetEntityParams(m_host, rules); 8850 return result;
8222 } 8851 }
8223 8852
8224 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8853 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8225 { 8854 {
8226 m_host.AddScriptLPS(1); 8855 m_host.AddScriptLPS(1);
8227 8856
8228 return GetEntityParams(GetLinkEntity(linknumber), rules); 8857 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8229 } 8858 // keep other options as before
8230 8859
8231 public LSL_Vector GetAgentSize(ScenePresence sp) 8860 List<SceneObjectPart> parts;
8232 { 8861 List<ScenePresence> avatars;
8233 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8862
8234 } 8863 LSL_List res = new LSL_List();
8864 LSL_List remaining = null;
8235 8865
8236 /// <summary> 8866 while (rules.Length > 0)
8237 /// Gets params for a seated avatar in a linkset.
8238 /// </summary>
8239 /// <returns></returns>
8240 /// <param name='sp'></param>
8241 /// <param name='rules'></param>
8242 /// <param name='res'></param>
8243 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8244 {
8245 int idx = 0;
8246 while (idx < rules.Length)
8247 { 8867 {
8248 int code = (int)rules.GetLSLIntegerItem(idx++); 8868 parts = GetLinkParts(linknumber);
8249 int remain = rules.Length-idx; 8869 avatars = GetLinkAvatars(linknumber);
8250 8870
8251 switch (code) 8871 remaining = null;
8872 foreach (SceneObjectPart part in parts)
8252 { 8873 {
8253 case (int)ScriptBaseClass.PRIM_MATERIAL: 8874 remaining = GetPrimParams(part, rules, ref res);
8254 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8875 }
8255 break; 8876 foreach (ScenePresence avatar in avatars)
8256 8877 {
8257 case (int)ScriptBaseClass.PRIM_PHYSICS: 8878 remaining = GetPrimParams(avatar, rules, ref res);
8258 res.Add(ScriptBaseClass.FALSE); 8879 }
8259 break;
8260
8261 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8262 res.Add(ScriptBaseClass.FALSE);
8263 break;
8264
8265 case (int)ScriptBaseClass.PRIM_PHANTOM:
8266 res.Add(ScriptBaseClass.FALSE);
8267 break;
8268
8269 case (int)ScriptBaseClass.PRIM_POSITION:
8270 res.Add(new LSL_Vector(sp.AbsolutePosition));
8271 break;
8272
8273 case (int)ScriptBaseClass.PRIM_SIZE:
8274 res.Add(GetAgentSize(sp));
8275 break;
8276
8277 case (int)ScriptBaseClass.PRIM_ROTATION:
8278 res.Add(sp.GetWorldRotation());
8279 break;
8280
8281 case (int)ScriptBaseClass.PRIM_TYPE:
8282 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8283 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8284 res.Add(new LSL_Vector(0, 1, 0));
8285 res.Add(new LSL_Float(0));
8286 res.Add(new LSL_Vector(0, 0, 0));
8287 res.Add(new LSL_Vector(1, 1, 0));
8288 res.Add(new LSL_Vector(0, 0, 0));
8289 break;
8290
8291 case (int)ScriptBaseClass.PRIM_TEXTURE:
8292 if (remain < 1)
8293 return null;
8294
8295 int face = (int)rules.GetLSLIntegerItem(idx++);
8296 if (face > 21)
8297 break;
8298
8299 res.Add(new LSL_String(""));
8300 res.Add(ScriptBaseClass.ZERO_VECTOR);
8301 res.Add(ScriptBaseClass.ZERO_VECTOR);
8302 res.Add(new LSL_Float(0));
8303 break;
8304
8305 case (int)ScriptBaseClass.PRIM_COLOR:
8306 if (remain < 1)
8307 return null;
8308
8309 face = (int)rules.GetLSLIntegerItem(idx++);
8310 if (face > 21)
8311 break;
8312
8313 res.Add(ScriptBaseClass.ZERO_VECTOR);
8314 res.Add(new LSL_Float(0));
8315 break;
8316
8317 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8318 if (remain < 1)
8319 return null;
8320
8321 face = (int)rules.GetLSLIntegerItem(idx++);
8322 if (face > 21)
8323 break;
8324
8325 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8326 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8327 break;
8328
8329 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8330 if (remain < 1)
8331 return null;
8332
8333 face = (int)rules.GetLSLIntegerItem(idx++);
8334 if (face > 21)
8335 break;
8336
8337 res.Add(ScriptBaseClass.FALSE);
8338 break;
8339
8340 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8341 res.Add(ScriptBaseClass.FALSE);
8342 res.Add(new LSL_Integer(0));
8343 res.Add(new LSL_Float(0));
8344 res.Add(new LSL_Float(0));
8345 res.Add(new LSL_Float(0));
8346 res.Add(new LSL_Float(0));
8347 res.Add(ScriptBaseClass.ZERO_VECTOR);
8348 break;
8349
8350 case (int)ScriptBaseClass.PRIM_TEXGEN:
8351 if (remain < 1)
8352 return null;
8353
8354 face = (int)rules.GetLSLIntegerItem(idx++);
8355 if (face > 21)
8356 break;
8357
8358 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8359 break;
8360
8361 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8362 res.Add(ScriptBaseClass.FALSE);
8363 res.Add(ScriptBaseClass.ZERO_VECTOR);
8364 res.Add(ScriptBaseClass.ZERO_VECTOR);
8365 break;
8366
8367 case (int)ScriptBaseClass.PRIM_GLOW:
8368 if (remain < 1)
8369 return null;
8370
8371 face = (int)rules.GetLSLIntegerItem(idx++);
8372 if (face > 21)
8373 break;
8374
8375 res.Add(new LSL_Float(0));
8376 break;
8377
8378 case (int)ScriptBaseClass.PRIM_TEXT:
8379 res.Add(new LSL_String(""));
8380 res.Add(ScriptBaseClass.ZERO_VECTOR);
8381 res.Add(new LSL_Float(1));
8382 break;
8383
8384 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8385 res.Add(new LSL_Rotation(sp.Rotation));
8386 break;
8387
8388 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8389 res.Add(new LSL_Vector(sp.OffsetPosition));
8390 break;
8391
8392 case (int)ScriptBaseClass.PRIM_SLICE:
8393 res.Add(new LSL_Vector(0, 1, 0));
8394 break;
8395
8396 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8397 if(remain < 3)
8398 return null;
8399 8880
8400 return rules.GetSublist(idx, -1); 8881 if ((object)remaining != null && remaining.Length > 0)
8882 {
8883 linknumber = remaining.GetLSLIntegerItem(0);
8884 rules = remaining.GetSublist(1, -1);
8401 } 8885 }
8886 else
8887 break;
8402 } 8888 }
8403 8889
8404 return null; 8890 return res;
8405 } 8891 }
8406 8892
8407 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8893 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8408 { 8894 {
8409 int idx = 0; 8895 int idx=0;
8410 while (idx < rules.Length) 8896 while (idx < rules.Length)
8411 { 8897 {
8412 int code = (int)rules.GetLSLIntegerItem(idx++); 8898 int code = (int)rules.GetLSLIntegerItem(idx++);
@@ -8440,19 +8926,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8440 break; 8926 break;
8441 8927
8442 case (int)ScriptBaseClass.PRIM_POSITION: 8928 case (int)ScriptBaseClass.PRIM_POSITION:
8443 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8929 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8444 8930 part.AbsolutePosition.Y,
8445 // For some reason, the part.AbsolutePosition.* values do not change if the 8931 part.AbsolutePosition.Z);
8446 // linkset is rotated; they always reflect the child prim's world position
8447 // as though the linkset is unrotated. This is incompatible behavior with SL's
8448 // implementation, so will break scripts imported from there (not to mention it
8449 // makes it more difficult to determine a child prim's actual inworld position).
8450 if (!part.IsRoot)
8451 {
8452 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8453 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8454 }
8455
8456 res.Add(v); 8932 res.Add(v);
8457 break; 8933 break;
8458 8934
@@ -8622,30 +9098,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8622 if (remain < 1) 9098 if (remain < 1)
8623 return null; 9099 return null;
8624 9100
8625 face=(int)rules.GetLSLIntegerItem(idx++); 9101 face = (int)rules.GetLSLIntegerItem(idx++);
8626 9102
8627 tex = part.Shape.Textures; 9103 tex = part.Shape.Textures;
9104 int shiny;
8628 if (face == ScriptBaseClass.ALL_SIDES) 9105 if (face == ScriptBaseClass.ALL_SIDES)
8629 { 9106 {
8630 for (face = 0; face < GetNumberOfSides(part); face++) 9107 for (face = 0; face < GetNumberOfSides(part); face++)
8631 { 9108 {
8632 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9109 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8633 // Convert Shininess to PRIM_SHINY_* 9110 if (shinyness == Shininess.High)
8634 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9111 {
8635 // PRIM_BUMP_* 9112 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8636 res.Add(new LSL_Integer((int)texface.Bump)); 9113 }
9114 else if (shinyness == Shininess.Medium)
9115 {
9116 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9117 }
9118 else if (shinyness == Shininess.Low)
9119 {
9120 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9121 }
9122 else
9123 {
9124 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9125 }
9126 res.Add(new LSL_Integer(shiny));
9127 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8637 } 9128 }
8638 } 9129 }
8639 else 9130 else
8640 { 9131 {
8641 if (face >= 0 && face < GetNumberOfSides(part)) 9132 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9133 if (shinyness == Shininess.High)
8642 { 9134 {
8643 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9135 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8644 // Convert Shininess to PRIM_SHINY_*
8645 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8646 // PRIM_BUMP_*
8647 res.Add(new LSL_Integer((int)texface.Bump));
8648 } 9136 }
9137 else if (shinyness == Shininess.Medium)
9138 {
9139 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9140 }
9141 else if (shinyness == Shininess.Low)
9142 {
9143 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9144 }
9145 else
9146 {
9147 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9148 }
9149 res.Add(new LSL_Integer(shiny));
9150 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8649 } 9151 }
8650 break; 9152 break;
8651 9153
@@ -8656,21 +9158,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8656 face = (int)rules.GetLSLIntegerItem(idx++); 9158 face = (int)rules.GetLSLIntegerItem(idx++);
8657 9159
8658 tex = part.Shape.Textures; 9160 tex = part.Shape.Textures;
9161 int fullbright;
8659 if (face == ScriptBaseClass.ALL_SIDES) 9162 if (face == ScriptBaseClass.ALL_SIDES)
8660 { 9163 {
8661 for (face = 0; face < GetNumberOfSides(part); face++) 9164 for (face = 0; face < GetNumberOfSides(part); face++)
8662 { 9165 {
8663 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9166 if (tex.GetFace((uint)face).Fullbright == true)
8664 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9167 {
9168 fullbright = ScriptBaseClass.TRUE;
9169 }
9170 else
9171 {
9172 fullbright = ScriptBaseClass.FALSE;
9173 }
9174 res.Add(new LSL_Integer(fullbright));
8665 } 9175 }
8666 } 9176 }
8667 else 9177 else
8668 { 9178 {
8669 if (face >= 0 && face < GetNumberOfSides(part)) 9179 if (tex.GetFace((uint)face).Fullbright == true)
8670 { 9180 {
8671 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9181 fullbright = ScriptBaseClass.TRUE;
8672 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9182 }
9183 else
9184 {
9185 fullbright = ScriptBaseClass.FALSE;
8673 } 9186 }
9187 res.Add(new LSL_Integer(fullbright));
8674 } 9188 }
8675 break; 9189 break;
8676 9190
@@ -8692,27 +9206,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8692 break; 9206 break;
8693 9207
8694 case (int)ScriptBaseClass.PRIM_TEXGEN: 9208 case (int)ScriptBaseClass.PRIM_TEXGEN:
9209 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8695 if (remain < 1) 9210 if (remain < 1)
8696 return null; 9211 return null;
8697 9212
8698 face=(int)rules.GetLSLIntegerItem(idx++); 9213 face = (int)rules.GetLSLIntegerItem(idx++);
8699 9214
8700 tex = part.Shape.Textures; 9215 tex = part.Shape.Textures;
8701 if (face == ScriptBaseClass.ALL_SIDES) 9216 if (face == ScriptBaseClass.ALL_SIDES)
8702 { 9217 {
8703 for (face = 0; face < GetNumberOfSides(part); face++) 9218 for (face = 0; face < GetNumberOfSides(part); face++)
8704 { 9219 {
8705 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9220 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8706 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9221 {
8707 res.Add(new LSL_Integer((uint)texgen >> 1)); 9222 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9223 }
9224 else
9225 {
9226 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9227 }
8708 } 9228 }
8709 } 9229 }
8710 else 9230 else
8711 { 9231 {
8712 if (face >= 0 && face < GetNumberOfSides(part)) 9232 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9233 {
9234 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9235 }
9236 else
8713 { 9237 {
8714 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9238 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8715 res.Add(new LSL_Integer((uint)texgen >> 1));
8716 } 9239 }
8717 } 9240 }
8718 break; 9241 break;
@@ -8736,24 +9259,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8736 if (remain < 1) 9259 if (remain < 1)
8737 return null; 9260 return null;
8738 9261
8739 face=(int)rules.GetLSLIntegerItem(idx++); 9262 face = (int)rules.GetLSLIntegerItem(idx++);
8740 9263
8741 tex = part.Shape.Textures; 9264 tex = part.Shape.Textures;
9265 float primglow;
8742 if (face == ScriptBaseClass.ALL_SIDES) 9266 if (face == ScriptBaseClass.ALL_SIDES)
8743 { 9267 {
8744 for (face = 0; face < GetNumberOfSides(part); face++) 9268 for (face = 0; face < GetNumberOfSides(part); face++)
8745 { 9269 {
8746 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9270 primglow = tex.GetFace((uint)face).Glow;
8747 res.Add(new LSL_Float(texface.Glow)); 9271 res.Add(new LSL_Float(primglow));
8748 } 9272 }
8749 } 9273 }
8750 else 9274 else
8751 { 9275 {
8752 if (face >= 0 && face < GetNumberOfSides(part)) 9276 primglow = tex.GetFace((uint)face).Glow;
8753 { 9277 res.Add(new LSL_Float(primglow));
8754 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8755 res.Add(new LSL_Float(texface.Glow));
8756 }
8757 } 9278 }
8758 break; 9279 break;
8759 9280
@@ -8765,15 +9286,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8765 textColor.B)); 9286 textColor.B));
8766 res.Add(new LSL_Float(textColor.A)); 9287 res.Add(new LSL_Float(textColor.A));
8767 break; 9288 break;
9289
8768 case (int)ScriptBaseClass.PRIM_NAME: 9290 case (int)ScriptBaseClass.PRIM_NAME:
8769 res.Add(new LSL_String(part.Name)); 9291 res.Add(new LSL_String(part.Name));
8770 break; 9292 break;
9293
8771 case (int)ScriptBaseClass.PRIM_DESC: 9294 case (int)ScriptBaseClass.PRIM_DESC:
8772 res.Add(new LSL_String(part.Description)); 9295 res.Add(new LSL_String(part.Description));
8773 break; 9296 break;
8774 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9297 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8775 res.Add(new LSL_Rotation(part.RotationOffset)); 9298 res.Add(new LSL_Rotation(part.RotationOffset));
8776 break; 9299 break;
9300
8777 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9301 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8778 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9302 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8779 break; 9303 break;
@@ -9386,8 +9910,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9386 // The function returns an ordered list 9910 // The function returns an ordered list
9387 // representing the tokens found in the supplied 9911 // representing the tokens found in the supplied
9388 // sources string. If two successive tokenizers 9912 // sources string. If two successive tokenizers
9389 // are encountered, then a NULL entry is added 9913 // are encountered, then a null-string entry is
9390 // to the list. 9914 // added to the list.
9391 // 9915 //
9392 // It is a precondition that the source and 9916 // It is a precondition that the source and
9393 // toekizer lisst are non-null. If they are null, 9917 // toekizer lisst are non-null. If they are null,
@@ -9395,7 +9919,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9395 // while their lengths are being determined. 9919 // while their lengths are being determined.
9396 // 9920 //
9397 // A small amount of working memoryis required 9921 // A small amount of working memoryis required
9398 // of approximately 8*#tokenizers. 9922 // of approximately 8*#tokenizers + 8*srcstrlen.
9399 // 9923 //
9400 // There are many ways in which this function 9924 // There are many ways in which this function
9401 // can be implemented, this implementation is 9925 // can be implemented, this implementation is
@@ -9411,155 +9935,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9411 // and eliminates redundant tokenizers as soon 9935 // and eliminates redundant tokenizers as soon
9412 // as is possible. 9936 // as is possible.
9413 // 9937 //
9414 // The implementation tries to avoid any copying 9938 // The implementation tries to minimize temporary
9415 // of arrays or other objects. 9939 // garbage generation.
9416 // </remarks> 9940 // </remarks>
9417 9941
9418 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9942 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9419 { 9943 {
9420 int beginning = 0; 9944 return ParseString2List(src, separators, spacers, true);
9421 int srclen = src.Length; 9945 }
9422 int seplen = separators.Length;
9423 object[] separray = separators.Data;
9424 int spclen = spacers.Length;
9425 object[] spcarray = spacers.Data;
9426 int mlen = seplen+spclen;
9427
9428 int[] offset = new int[mlen+1];
9429 bool[] active = new bool[mlen];
9430
9431 int best;
9432 int j;
9433
9434 // Initial capacity reduces resize cost
9435 9946
9436 LSL_List tokens = new LSL_List(); 9947 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9948 {
9949 int srclen = src.Length;
9950 int seplen = separators.Length;
9951 object[] separray = separators.Data;
9952 int spclen = spacers.Length;
9953 object[] spcarray = spacers.Data;
9954 int dellen = 0;
9955 string[] delarray = new string[seplen+spclen];
9437 9956
9438 // All entries are initially valid 9957 int outlen = 0;
9958 string[] outarray = new string[srclen*2+1];
9439 9959
9440 for (int i = 0; i < mlen; i++) 9960 int i, j;
9441 active[i] = true; 9961 string d;
9442 9962
9443 offset[mlen] = srclen; 9963 m_host.AddScriptLPS(1);
9444 9964
9445 while (beginning < srclen) 9965 /*
9966 * Convert separator and spacer lists to C# strings.
9967 * Also filter out null strings so we don't hang.
9968 */
9969 for (i = 0; i < seplen; i ++)
9446 { 9970 {
9971 d = separray[i].ToString();
9972 if (d.Length > 0)
9973 {
9974 delarray[dellen++] = d;
9975 }
9976 }
9977 seplen = dellen;
9447 9978
9448 best = mlen; // as bad as it gets 9979 for (i = 0; i < spclen; i ++)
9980 {
9981 d = spcarray[i].ToString();
9982 if (d.Length > 0)
9983 {
9984 delarray[dellen++] = d;
9985 }
9986 }
9449 9987
9450 // Scan for separators 9988 /*
9989 * Scan through source string from beginning to end.
9990 */
9991 for (i = 0;;)
9992 {
9451 9993
9452 for (j = 0; j < seplen; j++) 9994 /*
9995 * Find earliest delimeter in src starting at i (if any).
9996 */
9997 int earliestDel = -1;
9998 int earliestSrc = srclen;
9999 string earliestStr = null;
10000 for (j = 0; j < dellen; j ++)
9453 { 10001 {
9454 if (separray[j].ToString() == String.Empty) 10002 d = delarray[j];
9455 active[j] = false; 10003 if (d != null)
9456
9457 if (active[j])
9458 { 10004 {
9459 // scan all of the markers 10005 int index = src.IndexOf(d, i);
9460 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10006 if (index < 0)
9461 { 10007 {
9462 // not present at all 10008 delarray[j] = null; // delim nowhere in src, don't check it anymore
9463 active[j] = false;
9464 } 10009 }
9465 else 10010 else if (index < earliestSrc)
9466 { 10011 {
9467 // present and correct 10012 earliestSrc = index; // where delimeter starts in source string
9468 if (offset[j] < offset[best]) 10013 earliestDel = j; // where delimeter is in delarray[]
9469 { 10014 earliestStr = d; // the delimeter string from delarray[]
9470 // closest so far 10015 if (index == i) break; // can't do any better than found at beg of string
9471 best = j;
9472 if (offset[best] == beginning)
9473 break;
9474 }
9475 } 10016 }
9476 } 10017 }
9477 } 10018 }
9478 10019
9479 // Scan for spacers 10020 /*
9480 10021 * Output source string starting at i through start of earliest delimeter.
9481 if (offset[best] != beginning) 10022 */
10023 if (keepNulls || (earliestSrc > i))
9482 { 10024 {
9483 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10025 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9484 {
9485 if (spcarray[j-seplen].ToString() == String.Empty)
9486 active[j] = false;
9487
9488 if (active[j])
9489 {
9490 // scan all of the markers
9491 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9492 {
9493 // not present at all
9494 active[j] = false;
9495 }
9496 else
9497 {
9498 // present and correct
9499 if (offset[j] < offset[best])
9500 {
9501 // closest so far
9502 best = j;
9503 }
9504 }
9505 }
9506 }
9507 } 10026 }
9508 10027
9509 // This is the normal exit from the scanning loop 10028 /*
10029 * If no delimeter found at or after i, we're done scanning.
10030 */
10031 if (earliestDel < 0) break;
9510 10032
9511 if (best == mlen) 10033 /*
10034 * If delimeter was a spacer, output the spacer.
10035 */
10036 if (earliestDel >= seplen)
9512 { 10037 {
9513 // no markers were found on this pass 10038 outarray[outlen++] = earliestStr;
9514 // so we're pretty much done
9515 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9516 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9517 break;
9518 } 10039 }
9519 10040
9520 // Otherwise we just add the newly delimited token 10041 /*
9521 // and recalculate where the search should continue. 10042 * Look at rest of src string following delimeter.
9522 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10043 */
9523 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10044 i = earliestSrc + earliestStr.Length;
9524
9525 if (best < seplen)
9526 {
9527 beginning = offset[best] + (separray[best].ToString()).Length;
9528 }
9529 else
9530 {
9531 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9532 string str = spcarray[best - seplen].ToString();
9533 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9534 tokens.Add(new LSL_String(str));
9535 }
9536 } 10045 }
9537 10046
9538 // This an awkward an not very intuitive boundary case. If the 10047 /*
9539 // last substring is a tokenizer, then there is an implied trailing 10048 * Make up an exact-sized output array suitable for an LSL_List object.
9540 // null list entry. Hopefully the single comparison will not be too 10049 */
9541 // arduous. Alternatively the 'break' could be replced with a return 10050 object[] outlist = new object[outlen];
9542 // but that's shabby programming. 10051 for (i = 0; i < outlen; i ++)
9543
9544 if ((beginning == srclen) && (keepNulls))
9545 { 10052 {
9546 if (srclen != 0) 10053 outlist[i] = new LSL_String(outarray[i]);
9547 tokens.Add(new LSL_String(""));
9548 } 10054 }
9549 10055 return new LSL_List(outlist);
9550 return tokens;
9551 }
9552
9553 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9554 {
9555 m_host.AddScriptLPS(1);
9556 return this.ParseString(src, separators, spacers, false);
9557 }
9558
9559 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9560 {
9561 m_host.AddScriptLPS(1);
9562 return this.ParseString(src, separators, spacers, true);
9563 } 10056 }
9564 10057
9565 public LSL_Integer llGetObjectPermMask(int mask) 10058 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9654,6 +10147,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9654 case 4: 10147 case 4:
9655 return (int)item.NextPermissions; 10148 return (int)item.NextPermissions;
9656 } 10149 }
10150 m_host.TaskInventory.LockItemsForRead(false);
9657 10151
9658 return -1; 10152 return -1;
9659 } 10153 }
@@ -9857,31 +10351,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9857 UUID key = new UUID(); 10351 UUID key = new UUID();
9858 if (UUID.TryParse(id, out key)) 10352 if (UUID.TryParse(id, out key))
9859 { 10353 {
9860 try 10354 // return total object mass
9861 { 10355 SceneObjectPart part = World.GetSceneObjectPart(key);
9862 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10356 if (part != null)
9863 if (obj != null) 10357 return part.ParentGroup.GetMass();
9864 return (double)obj.GetMass(); 10358
9865 // the object is null so the key is for an avatar 10359 // the object is null so the key is for an avatar
9866 ScenePresence avatar = World.GetScenePresence(key); 10360 ScenePresence avatar = World.GetScenePresence(key);
9867 if (avatar != null) 10361 if (avatar != null)
9868 if (avatar.IsChildAgent)
9869 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9870 // child agents have a mass of 1.0
9871 return 1;
9872 else
9873 return (double)avatar.GetMass();
9874 }
9875 catch (KeyNotFoundException)
9876 { 10362 {
9877 return 0; // The Object/Agent not in the region so just return zero 10363 if (avatar.IsChildAgent)
10364 {
10365 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10366 // child agents have a mass of 1.0
10367 return 1;
10368 }
10369 else
10370 {
10371 return (double)avatar.GetMass();
10372 }
9878 } 10373 }
9879 } 10374 }
9880 return 0; 10375 return 0;
9881 } 10376 }
9882 10377
9883 /// <summary> 10378 /// <summary>
9884 /// illListReplaceList removes the sub-list defined by the inclusive indices 10379 /// llListReplaceList removes the sub-list defined by the inclusive indices
9885 /// start and end and inserts the src list in its place. The inclusive 10380 /// start and end and inserts the src list in its place. The inclusive
9886 /// nature of the indices means that at least one element must be deleted 10381 /// nature of the indices means that at least one element must be deleted
9887 /// if the indices are within the bounds of the existing list. I.e. 2,2 10382 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9938,16 +10433,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9938 // based upon end. Note that if end exceeds the upper 10433 // based upon end. Note that if end exceeds the upper
9939 // bound in this case, the entire destination list 10434 // bound in this case, the entire destination list
9940 // is removed. 10435 // is removed.
9941 else 10436 else if (start == 0)
9942 { 10437 {
9943 if (end + 1 < dest.Length) 10438 if (end + 1 < dest.Length)
9944 {
9945 return src + dest.GetSublist(end + 1, -1); 10439 return src + dest.GetSublist(end + 1, -1);
9946 }
9947 else 10440 else
9948 {
9949 return src; 10441 return src;
9950 } 10442 }
10443 else // Start < 0
10444 {
10445 if (end + 1 < dest.Length)
10446 return dest.GetSublist(end + 1, -1);
10447 else
10448 return new LSL_List();
9951 } 10449 }
9952 } 10450 }
9953 // Finally, if start > end, we strip away a prefix and 10451 // Finally, if start > end, we strip away a prefix and
@@ -9998,17 +10496,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9998 int width = 0; 10496 int width = 0;
9999 int height = 0; 10497 int height = 0;
10000 10498
10001 ParcelMediaCommandEnum? commandToSend = null; 10499 uint commandToSend = 0;
10002 float time = 0.0f; // default is from start 10500 float time = 0.0f; // default is from start
10003 10501
10004 ScenePresence presence = null; 10502 ScenePresence presence = null;
10005 10503
10006 for (int i = 0; i < commandList.Data.Length; i++) 10504 for (int i = 0; i < commandList.Data.Length; i++)
10007 { 10505 {
10008 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10506 uint command = (uint)(commandList.GetLSLIntegerItem(i));
10009 switch (command) 10507 switch (command)
10010 { 10508 {
10011 case ParcelMediaCommandEnum.Agent: 10509 case (uint)ParcelMediaCommandEnum.Agent:
10012 // we send only to one agent 10510 // we send only to one agent
10013 if ((i + 1) < commandList.Length) 10511 if ((i + 1) < commandList.Length)
10014 { 10512 {
@@ -10025,25 +10523,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10025 } 10523 }
10026 break; 10524 break;
10027 10525
10028 case ParcelMediaCommandEnum.Loop: 10526 case (uint)ParcelMediaCommandEnum.Loop:
10029 loop = 1; 10527 loop = 1;
10030 commandToSend = command; 10528 commandToSend = command;
10031 update = true; //need to send the media update packet to set looping 10529 update = true; //need to send the media update packet to set looping
10032 break; 10530 break;
10033 10531
10034 case ParcelMediaCommandEnum.Play: 10532 case (uint)ParcelMediaCommandEnum.Play:
10035 loop = 0; 10533 loop = 0;
10036 commandToSend = command; 10534 commandToSend = command;
10037 update = true; //need to send the media update packet to make sure it doesn't loop 10535 update = true; //need to send the media update packet to make sure it doesn't loop
10038 break; 10536 break;
10039 10537
10040 case ParcelMediaCommandEnum.Pause: 10538 case (uint)ParcelMediaCommandEnum.Pause:
10041 case ParcelMediaCommandEnum.Stop: 10539 case (uint)ParcelMediaCommandEnum.Stop:
10042 case ParcelMediaCommandEnum.Unload: 10540 case (uint)ParcelMediaCommandEnum.Unload:
10043 commandToSend = command; 10541 commandToSend = command;
10044 break; 10542 break;
10045 10543
10046 case ParcelMediaCommandEnum.Url: 10544 case (uint)ParcelMediaCommandEnum.Url:
10047 if ((i + 1) < commandList.Length) 10545 if ((i + 1) < commandList.Length)
10048 { 10546 {
10049 if (commandList.Data[i + 1] is LSL_String) 10547 if (commandList.Data[i + 1] is LSL_String)
@@ -10056,7 +10554,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10056 } 10554 }
10057 break; 10555 break;
10058 10556
10059 case ParcelMediaCommandEnum.Texture: 10557 case (uint)ParcelMediaCommandEnum.Texture:
10060 if ((i + 1) < commandList.Length) 10558 if ((i + 1) < commandList.Length)
10061 { 10559 {
10062 if (commandList.Data[i + 1] is LSL_String) 10560 if (commandList.Data[i + 1] is LSL_String)
@@ -10069,7 +10567,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10069 } 10567 }
10070 break; 10568 break;
10071 10569
10072 case ParcelMediaCommandEnum.Time: 10570 case (uint)ParcelMediaCommandEnum.Time:
10073 if ((i + 1) < commandList.Length) 10571 if ((i + 1) < commandList.Length)
10074 { 10572 {
10075 if (commandList.Data[i + 1] is LSL_Float) 10573 if (commandList.Data[i + 1] is LSL_Float)
@@ -10081,7 +10579,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10081 } 10579 }
10082 break; 10580 break;
10083 10581
10084 case ParcelMediaCommandEnum.AutoAlign: 10582 case (uint)ParcelMediaCommandEnum.AutoAlign:
10085 if ((i + 1) < commandList.Length) 10583 if ((i + 1) < commandList.Length)
10086 { 10584 {
10087 if (commandList.Data[i + 1] is LSL_Integer) 10585 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10095,7 +10593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10095 } 10593 }
10096 break; 10594 break;
10097 10595
10098 case ParcelMediaCommandEnum.Type: 10596 case (uint)ParcelMediaCommandEnum.Type:
10099 if ((i + 1) < commandList.Length) 10597 if ((i + 1) < commandList.Length)
10100 { 10598 {
10101 if (commandList.Data[i + 1] is LSL_String) 10599 if (commandList.Data[i + 1] is LSL_String)
@@ -10108,7 +10606,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10108 } 10606 }
10109 break; 10607 break;
10110 10608
10111 case ParcelMediaCommandEnum.Desc: 10609 case (uint)ParcelMediaCommandEnum.Desc:
10112 if ((i + 1) < commandList.Length) 10610 if ((i + 1) < commandList.Length)
10113 { 10611 {
10114 if (commandList.Data[i + 1] is LSL_String) 10612 if (commandList.Data[i + 1] is LSL_String)
@@ -10121,7 +10619,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10121 } 10619 }
10122 break; 10620 break;
10123 10621
10124 case ParcelMediaCommandEnum.Size: 10622 case (uint)ParcelMediaCommandEnum.Size:
10125 if ((i + 2) < commandList.Length) 10623 if ((i + 2) < commandList.Length)
10126 { 10624 {
10127 if (commandList.Data[i + 1] is LSL_Integer) 10625 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10191,7 +10689,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10191 } 10689 }
10192 } 10690 }
10193 10691
10194 if (commandToSend != null) 10692 if (commandToSend != 0)
10195 { 10693 {
10196 // the commandList contained a start/stop/... command, too 10694 // the commandList contained a start/stop/... command, too
10197 if (presence == null) 10695 if (presence == null)
@@ -10228,7 +10726,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10228 10726
10229 if (aList.Data[i] != null) 10727 if (aList.Data[i] != null)
10230 { 10728 {
10231 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10729 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10232 { 10730 {
10233 case ParcelMediaCommandEnum.Url: 10731 case ParcelMediaCommandEnum.Url:
10234 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10732 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10285,15 +10783,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10285 10783
10286 if (quick_pay_buttons.Data.Length < 4) 10784 if (quick_pay_buttons.Data.Length < 4)
10287 { 10785 {
10288 LSLError("List must have at least 4 elements"); 10786 int x;
10289 return; 10787 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10788 {
10789 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10790 }
10290 } 10791 }
10291 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10792 int[] nPrice = new int[5];
10292 10793 nPrice[0] = price;
10293 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10794 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10294 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10795 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10295 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10796 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10296 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10797 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10798 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10297 m_host.ParentGroup.HasGroupChanged = true; 10799 m_host.ParentGroup.HasGroupChanged = true;
10298 } 10800 }
10299 10801
@@ -10310,7 +10812,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10310 return Vector3.Zero; 10812 return Vector3.Zero;
10311 } 10813 }
10312 10814
10313 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10815// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10816 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10314 if (presence != null) 10817 if (presence != null)
10315 { 10818 {
10316 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10819 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10333,7 +10836,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10333 return Quaternion.Identity; 10836 return Quaternion.Identity;
10334 } 10837 }
10335 10838
10336 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10839// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10840 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10337 if (presence != null) 10841 if (presence != null)
10338 { 10842 {
10339 return new LSL_Rotation(presence.CameraRotation); 10843 return new LSL_Rotation(presence.CameraRotation);
@@ -10393,14 +10897,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10393 { 10897 {
10394 m_host.AddScriptLPS(1); 10898 m_host.AddScriptLPS(1);
10395 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10899 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10396 if (detectedParams == null) return; // only works on the first detected avatar 10900 if (detectedParams == null)
10397 10901 {
10902 if (m_host.ParentGroup.IsAttachment == true)
10903 {
10904 detectedParams = new DetectParams();
10905 detectedParams.Key = m_host.OwnerID;
10906 }
10907 else
10908 {
10909 return;
10910 }
10911 }
10912
10398 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10913 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10399 if (avatar != null) 10914 if (avatar != null)
10400 { 10915 {
10401 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10916 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10402 simname, pos, lookAt); 10917 simname, pos, lookAt);
10403 } 10918 }
10919
10404 ScriptSleep(1000); 10920 ScriptSleep(1000);
10405 } 10921 }
10406 10922
@@ -10524,12 +11040,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10524 11040
10525 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11041 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10526 object[] data = rules.Data; 11042 object[] data = rules.Data;
10527 for (int i = 0; i < data.Length; ++i) { 11043 for (int i = 0; i < data.Length; ++i)
11044 {
10528 int type = Convert.ToInt32(data[i++].ToString()); 11045 int type = Convert.ToInt32(data[i++].ToString());
10529 if (i >= data.Length) break; // odd number of entries => ignore the last 11046 if (i >= data.Length) break; // odd number of entries => ignore the last
10530 11047
10531 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11048 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10532 switch (type) { 11049 switch (type)
11050 {
10533 case ScriptBaseClass.CAMERA_FOCUS: 11051 case ScriptBaseClass.CAMERA_FOCUS:
10534 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11052 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10535 case ScriptBaseClass.CAMERA_POSITION: 11053 case ScriptBaseClass.CAMERA_POSITION:
@@ -10634,19 +11152,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10634 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11152 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10635 { 11153 {
10636 m_host.AddScriptLPS(1); 11154 m_host.AddScriptLPS(1);
10637 string ret = String.Empty; 11155
10638 string src1 = llBase64ToString(str1); 11156 if (str1 == String.Empty)
10639 string src2 = llBase64ToString(str2); 11157 return String.Empty;
10640 int c = 0; 11158 if (str2 == String.Empty)
10641 for (int i = 0; i < src1.Length; i++) 11159 return str1;
11160
11161 int len = str2.Length;
11162 if ((len % 4) != 0) // LL is EVIL!!!!
11163 {
11164 while (str2.EndsWith("="))
11165 str2 = str2.Substring(0, str2.Length - 1);
11166
11167 len = str2.Length;
11168 int mod = len % 4;
11169
11170 if (mod == 1)
11171 str2 = str2.Substring(0, str2.Length - 1);
11172 else if (mod == 2)
11173 str2 += "==";
11174 else if (mod == 3)
11175 str2 += "=";
11176 }
11177
11178 byte[] data1;
11179 byte[] data2;
11180 try
11181 {
11182 data1 = Convert.FromBase64String(str1);
11183 data2 = Convert.FromBase64String(str2);
11184 }
11185 catch (Exception)
11186 {
11187 return new LSL_String(String.Empty);
11188 }
11189
11190 byte[] d2 = new Byte[data1.Length];
11191 int pos = 0;
11192
11193 if (data1.Length <= data2.Length)
10642 { 11194 {
10643 ret += (char) (src1[i] ^ src2[c]); 11195 Array.Copy(data2, 0, d2, 0, data1.Length);
11196 }
11197 else
11198 {
11199 while (pos < data1.Length)
11200 {
11201 len = data1.Length - pos;
11202 if (len > data2.Length)
11203 len = data2.Length;
10644 11204
10645 c++; 11205 Array.Copy(data2, 0, d2, pos, len);
10646 if (c >= src2.Length) 11206 pos += len;
10647 c = 0; 11207 }
10648 } 11208 }
10649 return llStringToBase64(ret); 11209
11210 for (pos = 0 ; pos < data1.Length ; pos++ )
11211 data1[pos] ^= d2[pos];
11212
11213 return Convert.ToBase64String(data1);
10650 } 11214 }
10651 11215
10652 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11216 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10750,16 +11314,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10750 if (userAgent != null) 11314 if (userAgent != null)
10751 httpHeaders["User-Agent"] = userAgent; 11315 httpHeaders["User-Agent"] = userAgent;
10752 11316
11317 // See if the URL contains any header hacks
11318 string[] urlParts = url.Split(new char[] {'\n'});
11319 if (urlParts.Length > 1)
11320 {
11321 // Iterate the passed headers and parse them
11322 for (int i = 1 ; i < urlParts.Length ; i++ )
11323 {
11324 // The rest of those would be added to the body in SL.
11325 // Let's not do that.
11326 if (urlParts[i] == String.Empty)
11327 break;
11328
11329 // See if this could be a valid header
11330 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11331 if (headerParts.Length != 2)
11332 continue;
11333
11334 string headerName = headerParts[0].Trim();
11335 string headerValue = headerParts[1].Trim();
11336
11337 // Filter out headers that could be used to abuse
11338 // another system or cloak the request
11339 if (headerName.ToLower() == "x-secondlife-shard" ||
11340 headerName.ToLower() == "x-secondlife-object-name" ||
11341 headerName.ToLower() == "x-secondlife-object-key" ||
11342 headerName.ToLower() == "x-secondlife-region" ||
11343 headerName.ToLower() == "x-secondlife-local-position" ||
11344 headerName.ToLower() == "x-secondlife-local-velocity" ||
11345 headerName.ToLower() == "x-secondlife-local-rotation" ||
11346 headerName.ToLower() == "x-secondlife-owner-name" ||
11347 headerName.ToLower() == "x-secondlife-owner-key" ||
11348 headerName.ToLower() == "connection" ||
11349 headerName.ToLower() == "content-length" ||
11350 headerName.ToLower() == "from" ||
11351 headerName.ToLower() == "host" ||
11352 headerName.ToLower() == "proxy-authorization" ||
11353 headerName.ToLower() == "referer" ||
11354 headerName.ToLower() == "trailer" ||
11355 headerName.ToLower() == "transfer-encoding" ||
11356 headerName.ToLower() == "via" ||
11357 headerName.ToLower() == "authorization")
11358 continue;
11359
11360 httpHeaders[headerName] = headerValue;
11361 }
11362
11363 // Finally, strip any protocol specifier from the URL
11364 url = urlParts[0].Trim();
11365 int idx = url.IndexOf(" HTTP/");
11366 if (idx != -1)
11367 url = url.Substring(0, idx);
11368 }
11369
10753 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11370 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10754 Regex r = new Regex(authregex); 11371 Regex r = new Regex(authregex);
10755 int[] gnums = r.GetGroupNumbers(); 11372 int[] gnums = r.GetGroupNumbers();
10756 Match m = r.Match(url); 11373 Match m = r.Match(url);
10757 if (m.Success) { 11374 if (m.Success)
10758 for (int i = 1; i < gnums.Length; i++) { 11375 {
11376 for (int i = 1; i < gnums.Length; i++)
11377 {
10759 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11378 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10760 //CaptureCollection cc = g.Captures; 11379 //CaptureCollection cc = g.Captures;
10761 } 11380 }
10762 if (m.Groups.Count == 5) { 11381 if (m.Groups.Count == 5)
11382 {
10763 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11383 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10764 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11384 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10765 } 11385 }
@@ -10962,6 +11582,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10962 11582
10963 LSL_List ret = new LSL_List(); 11583 LSL_List ret = new LSL_List();
10964 UUID key = new UUID(); 11584 UUID key = new UUID();
11585
11586
10965 if (UUID.TryParse(id, out key)) 11587 if (UUID.TryParse(id, out key))
10966 { 11588 {
10967 ScenePresence av = World.GetScenePresence(key); 11589 ScenePresence av = World.GetScenePresence(key);
@@ -10979,13 +11601,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10979 ret.Add(new LSL_String("")); 11601 ret.Add(new LSL_String(""));
10980 break; 11602 break;
10981 case ScriptBaseClass.OBJECT_POS: 11603 case ScriptBaseClass.OBJECT_POS:
10982 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11604 Vector3 avpos;
11605
11606 if (av.ParentID != 0 && av.ParentPart != null)
11607 {
11608 avpos = av.OffsetPosition;
11609
11610 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11611 avpos -= sitOffset;
11612
11613 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11614 }
11615 else
11616 avpos = av.AbsolutePosition;
11617
11618 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10983 break; 11619 break;
10984 case ScriptBaseClass.OBJECT_ROT: 11620 case ScriptBaseClass.OBJECT_ROT:
10985 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11621 Quaternion avrot = av.Rotation;
11622 if (av.ParentID != 0 && av.ParentPart != null)
11623 {
11624 avrot = av.ParentPart.GetWorldRotation() * avrot;
11625 }
11626 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10986 break; 11627 break;
10987 case ScriptBaseClass.OBJECT_VELOCITY: 11628 case ScriptBaseClass.OBJECT_VELOCITY:
10988 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11629 Vector3 avvel = av.Velocity;
11630 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10989 break; 11631 break;
10990 case ScriptBaseClass.OBJECT_OWNER: 11632 case ScriptBaseClass.OBJECT_OWNER:
10991 ret.Add(new LSL_String(id)); 11633 ret.Add(new LSL_String(id));
@@ -11070,11 +11712,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11070 case ScriptBaseClass.OBJECT_NAME: 11712 case ScriptBaseClass.OBJECT_NAME:
11071 ret.Add(new LSL_String(obj.Name)); 11713 ret.Add(new LSL_String(obj.Name));
11072 break; 11714 break;
11073 case ScriptBaseClass.OBJECT_DESC: 11715 case ScriptBaseClass.OBJECT_DESC:
11074 ret.Add(new LSL_String(obj.Description)); 11716 ret.Add(new LSL_String(obj.Description));
11075 break; 11717 break;
11076 case ScriptBaseClass.OBJECT_POS: 11718 case ScriptBaseClass.OBJECT_POS:
11077 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11719 Vector3 opos = obj.AbsolutePosition;
11720 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
11078 break; 11721 break;
11079 case ScriptBaseClass.OBJECT_ROT: 11722 case ScriptBaseClass.OBJECT_ROT:
11080 { 11723 {
@@ -11124,9 +11767,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11124 // The value returned in SL for normal prims is prim count 11767 // The value returned in SL for normal prims is prim count
11125 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11768 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11126 break; 11769 break;
11127 // The following 3 costs I have intentionaly coded to return zero. They are part of 11770
11128 // "Land Impact" calculations. These calculations are probably not applicable 11771 // costs below may need to be diferent for root parts, need to check
11129 // to OpenSim and are not yet complete in SL
11130 case ScriptBaseClass.OBJECT_SERVER_COST: 11772 case ScriptBaseClass.OBJECT_SERVER_COST:
11131 // The linden calculation is here 11773 // The linden calculation is here
11132 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11774 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -11134,16 +11776,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11134 ret.Add(new LSL_Float(0)); 11776 ret.Add(new LSL_Float(0));
11135 break; 11777 break;
11136 case ScriptBaseClass.OBJECT_STREAMING_COST: 11778 case ScriptBaseClass.OBJECT_STREAMING_COST:
11137 // The linden calculation is here 11779 // The value returned in SL for normal prims is prim count * 0.06
11138 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11780 ret.Add(new LSL_Float(obj.StreamingCost));
11139 // The value returned in SL for normal prims looks like the prim count * 0.06
11140 ret.Add(new LSL_Float(0));
11141 break; 11781 break;
11142 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11782 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11143 // The linden calculation is here 11783 // The value returned in SL for normal prims is prim count
11144 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11784 ret.Add(new LSL_Float(obj.PhysicsCost));
11145 // The value returned in SL for normal prims looks like the prim count
11146 ret.Add(new LSL_Float(0));
11147 break; 11785 break;
11148 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11786 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11149 ret.Add(new LSL_Float(0)); 11787 ret.Add(new LSL_Float(0));
@@ -11402,15 +12040,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11402 return result; 12040 return result;
11403 } 12041 }
11404 12042
11405 public void print(string str) 12043 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11406 { 12044 {
11407 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12045 List<SceneObjectPart> parts = GetLinkParts(link);
11408 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12046 if (parts.Count < 1)
11409 if (ossl != null) 12047 return 0;
11410 { 12048
11411 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12049 return GetNumberOfSides(parts[0]);
11412 m_log.Info("LSL print():" + str);
11413 }
11414 } 12050 }
11415 12051
11416 private string Name2Username(string name) 12052 private string Name2Username(string name)
@@ -11455,7 +12091,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11455 12091
11456 return rq.ToString(); 12092 return rq.ToString();
11457 } 12093 }
11458 12094/*
12095 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12096 {
12097 m_SayShoutCount = 0;
12098 }
12099*/
11459 private struct Tri 12100 private struct Tri
11460 { 12101 {
11461 public Vector3 p1; 12102 public Vector3 p1;
@@ -11604,9 +12245,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11604 12245
11605 ContactResult result = new ContactResult (); 12246 ContactResult result = new ContactResult ();
11606 result.ConsumerID = group.LocalId; 12247 result.ConsumerID = group.LocalId;
11607 result.Depth = intersection.distance; 12248// result.Depth = intersection.distance;
11608 result.Normal = intersection.normal; 12249 result.Normal = intersection.normal;
11609 result.Pos = intersection.ipoint; 12250 result.Pos = intersection.ipoint;
12251 result.Depth = Vector3.Mag(rayStart - result.Pos);
11610 12252
11611 contacts.Add(result); 12253 contacts.Add(result);
11612 }); 12254 });
@@ -11739,6 +12381,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11739 12381
11740 return contacts[0]; 12382 return contacts[0];
11741 } 12383 }
12384/*
12385 // not done:
12386 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12387 {
12388 ContactResult[] contacts = null;
12389 World.ForEachSOG(delegate(SceneObjectGroup group)
12390 {
12391 if (m_host.ParentGroup == group)
12392 return;
12393
12394 if (group.IsAttachment)
12395 return;
12396
12397 if(group.RootPart.PhysActor != null)
12398 return;
12399
12400 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12401 });
12402 return contacts;
12403 }
12404*/
11742 12405
11743 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12406 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11744 { 12407 {
@@ -11862,18 +12525,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11862 } 12525 }
11863 } 12526 }
11864 12527
12528 // Double check this
11865 if (checkTerrain) 12529 if (checkTerrain)
11866 { 12530 {
11867 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12531 bool skipGroundCheck = false;
11868 if (groundContact != null) 12532
11869 results.Add((ContactResult)groundContact); 12533 foreach (ContactResult c in results)
12534 {
12535 if (c.ConsumerID == 0) // Physics gave us a ground collision
12536 skipGroundCheck = true;
12537 }
12538
12539 if (!skipGroundCheck)
12540 {
12541 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12542 if (groundContact != null)
12543 results.Add((ContactResult)groundContact);
12544 }
11870 } 12545 }
11871 12546
11872 results.Sort(delegate(ContactResult a, ContactResult b) 12547 results.Sort(delegate(ContactResult a, ContactResult b)
11873 { 12548 {
11874 return a.Depth.CompareTo(b.Depth); 12549 return a.Depth.CompareTo(b.Depth);
11875 }); 12550 });
11876 12551
11877 int values = 0; 12552 int values = 0;
11878 SceneObjectGroup thisgrp = m_host.ParentGroup; 12553 SceneObjectGroup thisgrp = m_host.ParentGroup;
11879 12554
@@ -11966,7 +12641,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11966 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12641 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11967 if (!isAccount) return 0; 12642 if (!isAccount) return 0;
11968 if (estate.HasAccess(id)) return 1; 12643 if (estate.HasAccess(id)) return 1;
11969 if (estate.IsBanned(id)) 12644 if (estate.IsBanned(id, World.GetUserFlags(id)))
11970 estate.RemoveBan(id); 12645 estate.RemoveBan(id);
11971 estate.AddEstateUser(id); 12646 estate.AddEstateUser(id);
11972 break; 12647 break;
@@ -11985,14 +12660,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11985 break; 12660 break;
11986 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12661 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11987 if (!isAccount) return 0; 12662 if (!isAccount) return 0;
11988 if (estate.IsBanned(id)) return 1; 12663 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11989 EstateBan ban = new EstateBan(); 12664 EstateBan ban = new EstateBan();
11990 ban.EstateID = estate.EstateID; 12665 ban.EstateID = estate.EstateID;
11991 ban.BannedUserID = id; 12666 ban.BannedUserID = id;
11992 estate.AddBan(ban); 12667 estate.AddBan(ban);
11993 break; 12668 break;
11994 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12669 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11995 if (!isAccount || !estate.IsBanned(id)) return 0; 12670 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11996 estate.RemoveBan(id); 12671 estate.RemoveBan(id);
11997 break; 12672 break;
11998 default: return 0; 12673 default: return 0;
@@ -12057,13 +12732,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12057 public void llCollisionSprite(string impact_sprite) 12732 public void llCollisionSprite(string impact_sprite)
12058 { 12733 {
12059 m_host.AddScriptLPS(1); 12734 m_host.AddScriptLPS(1);
12060 NotImplemented("llCollisionSprite"); 12735 // Viewer 2.0 broke this and it's likely LL has no intention
12736 // of fixing it. Therefore, letting this be a NOP seems appropriate.
12061 } 12737 }
12062 12738
12063 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12739 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
12064 { 12740 {
12065 m_host.AddScriptLPS(1); 12741 m_host.AddScriptLPS(1);
12066 NotImplemented("llGodLikeRezObject"); 12742
12743 if (!World.Permissions.IsGod(m_host.OwnerID))
12744 NotImplemented("llGodLikeRezObject");
12745
12746 AssetBase rezAsset = World.AssetService.Get(inventory);
12747 if (rezAsset == null)
12748 {
12749 llSay(0, "Asset not found");
12750 return;
12751 }
12752
12753 SceneObjectGroup group = null;
12754
12755 try
12756 {
12757 string xmlData = Utils.BytesToString(rezAsset.Data);
12758 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12759 }
12760 catch
12761 {
12762 llSay(0, "Asset not found");
12763 return;
12764 }
12765
12766 if (group == null)
12767 {
12768 llSay(0, "Asset not found");
12769 return;
12770 }
12771
12772 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12773 group.RootPart.AttachOffset = group.AbsolutePosition;
12774
12775 group.ResetIDs();
12776
12777 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12778 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12779 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12780 group.ScheduleGroupForFullUpdate();
12781
12782 // objects rezzed with this method are die_at_edge by default.
12783 group.RootPart.SetDieAtEdge(true);
12784
12785 group.ResumeScripts();
12786
12787 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12788 "object_rez", new Object[] {
12789 new LSL_String(
12790 group.RootPart.UUID.ToString()) },
12791 new DetectParams[0]));
12067 } 12792 }
12068 12793
12069 public LSL_String llTransferLindenDollars(string destination, int amount) 12794 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -12114,8 +12839,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12114 return; 12839 return;
12115 } 12840 }
12116 12841
12842 string reason;
12117 bool result = money.ObjectGiveMoney( 12843 bool result = money.ObjectGiveMoney(
12118 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12844 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
12119 12845
12120 if (result) 12846 if (result)
12121 { 12847 {
@@ -12123,7 +12849,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12123 return; 12849 return;
12124 } 12850 }
12125 12851
12126 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 12852 replydata = reason;
12127 } 12853 }
12128 finally 12854 finally
12129 { 12855 {
@@ -12140,6 +12866,610 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12140 } 12866 }
12141 12867
12142 #endregion 12868 #endregion
12869
12870 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12871 {
12872 SceneObjectGroup group = m_host.ParentGroup;
12873
12874 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12875 return;
12876 if (group.IsAttachment)
12877 return;
12878
12879 if (frames.Data.Length > 0) // We are getting a new motion
12880 {
12881 if (group.RootPart.KeyframeMotion != null)
12882 group.RootPart.KeyframeMotion.Delete();
12883 group.RootPart.KeyframeMotion = null;
12884
12885 int idx = 0;
12886
12887 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12888 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12889
12890 while (idx < options.Data.Length)
12891 {
12892 int option = (int)options.GetLSLIntegerItem(idx++);
12893 int remain = options.Data.Length - idx;
12894
12895 switch (option)
12896 {
12897 case ScriptBaseClass.KFM_MODE:
12898 if (remain < 1)
12899 break;
12900 int modeval = (int)options.GetLSLIntegerItem(idx++);
12901 switch(modeval)
12902 {
12903 case ScriptBaseClass.KFM_FORWARD:
12904 mode = KeyframeMotion.PlayMode.Forward;
12905 break;
12906 case ScriptBaseClass.KFM_REVERSE:
12907 mode = KeyframeMotion.PlayMode.Reverse;
12908 break;
12909 case ScriptBaseClass.KFM_LOOP:
12910 mode = KeyframeMotion.PlayMode.Loop;
12911 break;
12912 case ScriptBaseClass.KFM_PING_PONG:
12913 mode = KeyframeMotion.PlayMode.PingPong;
12914 break;
12915 }
12916 break;
12917 case ScriptBaseClass.KFM_DATA:
12918 if (remain < 1)
12919 break;
12920 int dataval = (int)options.GetLSLIntegerItem(idx++);
12921 data = (KeyframeMotion.DataFormat)dataval;
12922 break;
12923 }
12924 }
12925
12926 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12927
12928 idx = 0;
12929
12930 int elemLength = 2;
12931 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12932 elemLength = 3;
12933
12934 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12935 while (idx < frames.Data.Length)
12936 {
12937 int remain = frames.Data.Length - idx;
12938
12939 if (remain < elemLength)
12940 break;
12941
12942 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12943 frame.Position = null;
12944 frame.Rotation = null;
12945
12946 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12947 {
12948 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12949 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12950 }
12951 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12952 {
12953 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12954 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12955 q.Normalize();
12956 frame.Rotation = q;
12957 }
12958
12959 float tempf = (float)frames.GetLSLFloatItem(idx++);
12960 frame.TimeMS = (int)(tempf * 1000.0f);
12961
12962 keyframes.Add(frame);
12963 }
12964
12965 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12966 group.RootPart.KeyframeMotion.Start();
12967 }
12968 else
12969 {
12970 if (group.RootPart.KeyframeMotion == null)
12971 return;
12972
12973 if (options.Data.Length == 0)
12974 {
12975 group.RootPart.KeyframeMotion.Stop();
12976 return;
12977 }
12978
12979 int code = (int)options.GetLSLIntegerItem(0);
12980
12981 int idx = 0;
12982
12983 while (idx < options.Data.Length)
12984 {
12985 int option = (int)options.GetLSLIntegerItem(idx++);
12986 int remain = options.Data.Length - idx;
12987
12988 switch (option)
12989 {
12990 case ScriptBaseClass.KFM_COMMAND:
12991 int cmd = (int)options.GetLSLIntegerItem(idx++);
12992 switch (cmd)
12993 {
12994 case ScriptBaseClass.KFM_CMD_PLAY:
12995 group.RootPart.KeyframeMotion.Start();
12996 break;
12997 case ScriptBaseClass.KFM_CMD_STOP:
12998 group.RootPart.KeyframeMotion.Stop();
12999 break;
13000 case ScriptBaseClass.KFM_CMD_PAUSE:
13001 group.RootPart.KeyframeMotion.Pause();
13002 break;
13003 }
13004 break;
13005 }
13006 }
13007 }
13008 }
13009
13010 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
13011 {
13012 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
13013
13014 int idx = 0;
13015 int idxStart = 0;
13016
13017 bool positionChanged = false;
13018 Vector3 finalPos = Vector3.Zero;
13019
13020 try
13021 {
13022 while (idx < rules.Length)
13023 {
13024 ++rulesParsed;
13025 int code = rules.GetLSLIntegerItem(idx++);
13026
13027 int remain = rules.Length - idx;
13028 idxStart = idx;
13029
13030 switch (code)
13031 {
13032 case (int)ScriptBaseClass.PRIM_POSITION:
13033 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13034 {
13035 if (remain < 1)
13036 return null;
13037
13038 LSL_Vector v;
13039 v = rules.GetVector3Item(idx++);
13040
13041 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13042 if (part == null)
13043 break;
13044
13045 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13046 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13047 if (part.LinkNum > 1)
13048 {
13049 localRot = GetPartLocalRot(part);
13050 localPos = GetPartLocalPos(part);
13051 }
13052
13053 v -= localPos;
13054 v /= localRot;
13055
13056 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
13057
13058 v = v + 2 * sitOffset;
13059
13060 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
13061 av.SendAvatarDataToAllAgents();
13062
13063 }
13064 break;
13065
13066 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13067 case (int)ScriptBaseClass.PRIM_ROTATION:
13068 {
13069 if (remain < 1)
13070 return null;
13071
13072 LSL_Rotation r;
13073 r = rules.GetQuaternionItem(idx++);
13074
13075 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13076 if (part == null)
13077 break;
13078
13079 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13080 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13081
13082 if (part.LinkNum > 1)
13083 localRot = GetPartLocalRot(part);
13084
13085 r = r * llGetRootRotation() / localRot;
13086 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
13087 av.SendAvatarDataToAllAgents();
13088 }
13089 break;
13090
13091 // parse rest doing nothing but number of parameters error check
13092 case (int)ScriptBaseClass.PRIM_SIZE:
13093 case (int)ScriptBaseClass.PRIM_MATERIAL:
13094 case (int)ScriptBaseClass.PRIM_PHANTOM:
13095 case (int)ScriptBaseClass.PRIM_PHYSICS:
13096 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
13097 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13098 case (int)ScriptBaseClass.PRIM_NAME:
13099 case (int)ScriptBaseClass.PRIM_DESC:
13100 if (remain < 1)
13101 return null;
13102 idx++;
13103 break;
13104
13105 case (int)ScriptBaseClass.PRIM_GLOW:
13106 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13107 case (int)ScriptBaseClass.PRIM_TEXGEN:
13108 if (remain < 2)
13109 return null;
13110 idx += 2;
13111 break;
13112
13113 case (int)ScriptBaseClass.PRIM_TYPE:
13114 if (remain < 3)
13115 return null;
13116 code = (int)rules.GetLSLIntegerItem(idx++);
13117 remain = rules.Length - idx;
13118 switch (code)
13119 {
13120 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13121 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13122 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13123 if (remain < 6)
13124 return null;
13125 idx += 6;
13126 break;
13127
13128 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13129 if (remain < 5)
13130 return null;
13131 idx += 5;
13132 break;
13133
13134 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13135 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13136 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13137 if (remain < 11)
13138 return null;
13139 idx += 11;
13140 break;
13141
13142 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13143 if (remain < 2)
13144 return null;
13145 idx += 2;
13146 break;
13147 }
13148 break;
13149
13150 case (int)ScriptBaseClass.PRIM_COLOR:
13151 case (int)ScriptBaseClass.PRIM_TEXT:
13152 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13153 case (int)ScriptBaseClass.PRIM_OMEGA:
13154 if (remain < 3)
13155 return null;
13156 idx += 3;
13157 break;
13158
13159 case (int)ScriptBaseClass.PRIM_TEXTURE:
13160 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13161 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13162 if (remain < 5)
13163 return null;
13164 idx += 5;
13165 break;
13166
13167 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13168 if (remain < 7)
13169 return null;
13170
13171 idx += 7;
13172 break;
13173
13174 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13175 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13176 return null;
13177
13178 return rules.GetSublist(idx, -1);
13179 }
13180 }
13181 }
13182 catch (InvalidCastException e)
13183 {
13184 ShoutError(string.Format(
13185 "{0} error running rule #{1}: arg #{2} ",
13186 originFunc, rulesParsed, idx - idxStart) + e.Message);
13187 }
13188 finally
13189 {
13190 if (positionChanged)
13191 {
13192 av.OffsetPosition = finalPos;
13193// av.SendAvatarDataToAllAgents();
13194 av.SendTerseUpdateToAllClients();
13195 positionChanged = false;
13196 }
13197 }
13198 return null;
13199 }
13200
13201 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13202 {
13203 // avatars case
13204 // replies as SL wiki
13205
13206// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13207 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13208
13209 int idx = 0;
13210 while (idx < rules.Length)
13211 {
13212 int code = (int)rules.GetLSLIntegerItem(idx++);
13213 int remain = rules.Length - idx;
13214
13215 switch (code)
13216 {
13217 case (int)ScriptBaseClass.PRIM_MATERIAL:
13218 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13219 break;
13220
13221 case (int)ScriptBaseClass.PRIM_PHYSICS:
13222 res.Add(new LSL_Integer(0));
13223 break;
13224
13225 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13226 res.Add(new LSL_Integer(0));
13227 break;
13228
13229 case (int)ScriptBaseClass.PRIM_PHANTOM:
13230 res.Add(new LSL_Integer(0));
13231 break;
13232
13233 case (int)ScriptBaseClass.PRIM_POSITION:
13234
13235 Vector3 pos = avatar.OffsetPosition;
13236
13237 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13238 pos -= sitOffset;
13239
13240 if( sitPart != null)
13241 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13242
13243 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13244 break;
13245
13246 case (int)ScriptBaseClass.PRIM_SIZE:
13247 // as in llGetAgentSize above
13248// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13249 Vector3 s = avatar.Appearance.AvatarSize;
13250 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13251
13252 break;
13253
13254 case (int)ScriptBaseClass.PRIM_ROTATION:
13255 Quaternion rot = avatar.Rotation;
13256 if (sitPart != null)
13257 {
13258 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13259 }
13260
13261 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13262 break;
13263
13264 case (int)ScriptBaseClass.PRIM_TYPE:
13265 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13266 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13267 res.Add(new LSL_Vector(0f,1.0f,0f));
13268 res.Add(new LSL_Float(0.0f));
13269 res.Add(new LSL_Vector(0, 0, 0));
13270 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13271 res.Add(new LSL_Vector(0, 0, 0));
13272 break;
13273
13274 case (int)ScriptBaseClass.PRIM_TEXTURE:
13275 if (remain < 1)
13276 return null;
13277
13278 int face = (int)rules.GetLSLIntegerItem(idx++);
13279 if (face == ScriptBaseClass.ALL_SIDES)
13280 {
13281 for (face = 0; face < 21; face++)
13282 {
13283 res.Add(new LSL_String(""));
13284 res.Add(new LSL_Vector(0,0,0));
13285 res.Add(new LSL_Vector(0,0,0));
13286 res.Add(new LSL_Float(0.0));
13287 }
13288 }
13289 else
13290 {
13291 if (face >= 0 && face < 21)
13292 {
13293 res.Add(new LSL_String(""));
13294 res.Add(new LSL_Vector(0,0,0));
13295 res.Add(new LSL_Vector(0,0,0));
13296 res.Add(new LSL_Float(0.0));
13297 }
13298 }
13299 break;
13300
13301 case (int)ScriptBaseClass.PRIM_COLOR:
13302 if (remain < 1)
13303 return null;
13304
13305 face = (int)rules.GetLSLIntegerItem(idx++);
13306
13307 if (face == ScriptBaseClass.ALL_SIDES)
13308 {
13309 for (face = 0; face < 21; face++)
13310 {
13311 res.Add(new LSL_Vector(0,0,0));
13312 res.Add(new LSL_Float(0));
13313 }
13314 }
13315 else
13316 {
13317 res.Add(new LSL_Vector(0,0,0));
13318 res.Add(new LSL_Float(0));
13319 }
13320 break;
13321
13322 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13323 if (remain < 1)
13324 return null;
13325 face = (int)rules.GetLSLIntegerItem(idx++);
13326
13327 if (face == ScriptBaseClass.ALL_SIDES)
13328 {
13329 for (face = 0; face < 21; face++)
13330 {
13331 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13332 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13333 }
13334 }
13335 else
13336 {
13337 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13338 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13339 }
13340 break;
13341
13342 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13343 if (remain < 1)
13344 return null;
13345 face = (int)rules.GetLSLIntegerItem(idx++);
13346
13347 if (face == ScriptBaseClass.ALL_SIDES)
13348 {
13349 for (face = 0; face < 21; face++)
13350 {
13351 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13352 }
13353 }
13354 else
13355 {
13356 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13357 }
13358 break;
13359
13360 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13361 res.Add(new LSL_Integer(0));
13362 res.Add(new LSL_Integer(0));// softness
13363 res.Add(new LSL_Float(0.0f)); // gravity
13364 res.Add(new LSL_Float(0.0f)); // friction
13365 res.Add(new LSL_Float(0.0f)); // wind
13366 res.Add(new LSL_Float(0.0f)); // tension
13367 res.Add(new LSL_Vector(0f,0f,0f));
13368 break;
13369
13370 case (int)ScriptBaseClass.PRIM_TEXGEN:
13371 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13372 if (remain < 1)
13373 return null;
13374 face = (int)rules.GetLSLIntegerItem(idx++);
13375
13376 if (face == ScriptBaseClass.ALL_SIDES)
13377 {
13378 for (face = 0; face < 21; face++)
13379 {
13380 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13381 }
13382 }
13383 else
13384 {
13385 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13386 }
13387 break;
13388
13389 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13390 res.Add(new LSL_Integer(0));
13391 res.Add(new LSL_Vector(0f,0f,0f));
13392 res.Add(new LSL_Float(0f)); // intensity
13393 res.Add(new LSL_Float(0f)); // radius
13394 res.Add(new LSL_Float(0f)); // falloff
13395 break;
13396
13397 case (int)ScriptBaseClass.PRIM_GLOW:
13398 if (remain < 1)
13399 return null;
13400 face = (int)rules.GetLSLIntegerItem(idx++);
13401
13402 if (face == ScriptBaseClass.ALL_SIDES)
13403 {
13404 for (face = 0; face < 21; face++)
13405 {
13406 res.Add(new LSL_Float(0f));
13407 }
13408 }
13409 else
13410 {
13411 res.Add(new LSL_Float(0f));
13412 }
13413 break;
13414
13415 case (int)ScriptBaseClass.PRIM_TEXT:
13416 res.Add(new LSL_String(""));
13417 res.Add(new LSL_Vector(0f,0f,0f));
13418 res.Add(new LSL_Float(1.0f));
13419 break;
13420
13421 case (int)ScriptBaseClass.PRIM_NAME:
13422 res.Add(new LSL_String(avatar.Name));
13423 break;
13424
13425 case (int)ScriptBaseClass.PRIM_DESC:
13426 res.Add(new LSL_String(""));
13427 break;
13428
13429 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13430 Quaternion lrot = avatar.Rotation;
13431
13432 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13433 {
13434 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13435 }
13436 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13437 break;
13438
13439 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13440 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13441 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13442 lpos -= lsitOffset;
13443
13444 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13445 {
13446 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13447 }
13448 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13449 break;
13450
13451 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13452 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13453 return null;
13454
13455 return rules.GetSublist(idx, -1);
13456 }
13457 }
13458
13459 return null;
13460 }
13461
13462 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
13463 {
13464 if (m_UrlModule != null)
13465 {
13466 string type = "text.plain";
13467 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
13468 type = "text/html";
13469
13470 m_UrlModule.HttpContentType(new UUID(id),type);
13471 }
13472 }
12143 } 13473 }
12144 13474
12145 public class NotecardCache 13475 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 92dd813..edcdfbc 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 f4d5562..5c57971 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 6e74227..44a7c14 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
@@ -358,7 +358,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
358 if (avatar == null) 358 if (avatar == null)
359 return sensedEntities; 359 return sensedEntities;
360 360
361 q = avatar.GetWorldRotation() * q; 361 fromRegionPos = avatar.AbsolutePosition;
362 q = avatar.Rotation;
362 } 363 }
363 364
364 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 365 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -402,7 +403,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
402 objtype = 0; 403 objtype = 0;
403 404
404 part = ((SceneObjectGroup)ent).RootPart; 405 part = ((SceneObjectGroup)ent).RootPart;
405 if (part.ParentGroup.AttachmentPoint != 0) // Attached so ignore 406 if (part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.Tree &&
407 part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.NewTree &&
408 part.ParentGroup.AttachmentPoint != 0) // Attached so ignore
406 continue; 409 continue;
407 410
408 if (part.Inventory.ContainsScripts()) 411 if (part.Inventory.ContainsScripts())
@@ -489,8 +492,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
489 // Don't proceed if the avatar for this attachment has since been removed from the scene. 492 // Don't proceed if the avatar for this attachment has since been removed from the scene.
490 if (avatar == null) 493 if (avatar == null)
491 return sensedEntities; 494 return sensedEntities;
492 495 fromRegionPos = avatar.AbsolutePosition;
493 q = avatar.GetWorldRotation() * q; 496 q = avatar.Rotation;
494 } 497 }
495 498
496 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q); 499 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q);
@@ -506,7 +509,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
506// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}", 509// "[SENSOR REPEAT]: Inspecting scene presence {0}, type {1} on sensor sweep for {2}, type {3}",
507// presence.Name, presence.PresenceType, ts.name, ts.type); 510// presence.Name, presence.PresenceType, ts.name, ts.type);
508 511
509 if ((ts.type & NPC) == 0 && (ts.type & OS_NPC) == 0 && presence.PresenceType == PresenceType.Npc) 512 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
510 { 513 {
511 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene); 514 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
512 if (npcData == null || !npcData.SenseAsAgent) 515 if (npcData == null || !npcData.SenseAsAgent)
@@ -706,4 +709,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
706 return retList; 709 return retList;
707 } 710 }
708 } 711 }
709} \ No newline at end of file 712}
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 340edb3..d211a2b 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);
@@ -342,7 +343,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
342 void llSetDamage(double damage); 343 void llSetDamage(double damage);
343 void llSetForce(LSL_Vector force, int local); 344 void llSetForce(LSL_Vector force, int local);
344 void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local); 345 void llSetForceAndTorque(LSL_Vector force, LSL_Vector torque, int local);
345 void llSetVelocity(LSL_Vector velocity, int local);
346 void llSetAngularVelocity(LSL_Vector angularVelocity, int local); 346 void llSetAngularVelocity(LSL_Vector angularVelocity, int local);
347 void llSetHoverHeight(double height, int water, double tau); 347 void llSetHoverHeight(double height, int water, double tau);
348 void llSetInventoryPermMask(string item, int mask, int value); 348 void llSetInventoryPermMask(string item, int mask, int value);
@@ -360,11 +360,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
360 void llSetParcelMusicURL(string url); 360 void llSetParcelMusicURL(string url);
361 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 361 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
362 void llSetPos(LSL_Vector pos); 362 void llSetPos(LSL_Vector pos);
363 LSL_Integer llSetRegionPos(LSL_Vector pos);
363 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 364 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
364 void llSetPrimitiveParams(LSL_List rules); 365 void llSetPrimitiveParams(LSL_List rules);
365 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 366 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
366 void llSetPrimURL(string url); 367 void llSetPrimURL(string url);
367 LSL_Integer llSetRegionPos(LSL_Vector pos);
368 void llSetRemoteScriptAccessPin(int pin); 368 void llSetRemoteScriptAccessPin(int pin);
369 void llSetRot(LSL_Rotation rot); 369 void llSetRot(LSL_Rotation rot);
370 void llSetScale(LSL_Vector scale); 370 void llSetScale(LSL_Vector scale);
@@ -427,10 +427,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
427 LSL_Vector llWind(LSL_Vector offset); 427 LSL_Vector llWind(LSL_Vector offset);
428 LSL_String llXorBase64Strings(string str1, string str2); 428 LSL_String llXorBase64Strings(string str1, string str2);
429 LSL_String llXorBase64StringsCorrect(string str1, string str2); 429 LSL_String llXorBase64StringsCorrect(string str1, string str2);
430 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);
431 432
432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 433 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
433 void llSetKeyframedMotion(LSL_List frames, LSL_List options); 434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
434 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 435 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
436 LSL_List llGetPhysicsMaterial();
435 } 437 }
436} 438}
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 1137ad8..15b21ac 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;
@@ -685,7 +687,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
685 public const int FRICTION = 2; 687 public const int FRICTION = 2;
686 public const int RESTITUTION = 4; 688 public const int RESTITUTION = 4;
687 public const int GRAVITY_MULTIPLIER = 8; 689 public const int GRAVITY_MULTIPLIER = 8;
688 690
689 // extra constants for llSetPrimMediaParams 691 // extra constants for llSetPrimMediaParams
690 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 692 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
691 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000); 693 public static readonly LSLInteger LSL_STATUS_MALFORMED_PARAMS = new LSLInteger(1000);
@@ -757,7 +759,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
757 759
758 public static readonly LSLInteger RCERR_UNKNOWN = -1; 760 public static readonly LSLInteger RCERR_UNKNOWN = -1;
759 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 761 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
760 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 762 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
761 763
762 public const int KFM_MODE = 1; 764 public const int KFM_MODE = 1;
763 public const int KFM_LOOP = 1; 765 public const int KFM_LOOP = 1;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 7cd17e7..4fc8d65 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)
@@ -1548,11 +1550,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1548 m_LSL_Functions.llSetForceAndTorque(force, torque, local); 1550 m_LSL_Functions.llSetForceAndTorque(force, torque, local);
1549 } 1551 }
1550 1552
1551 public void llSetVelocity(LSL_Vector force, int local)
1552 {
1553 m_LSL_Functions.llSetVelocity(force, local);
1554 }
1555
1556 public void llSetAngularVelocity(LSL_Vector force, int local) 1553 public void llSetAngularVelocity(LSL_Vector force, int local)
1557 { 1554 {
1558 m_LSL_Functions.llSetAngularVelocity(force, local); 1555 m_LSL_Functions.llSetAngularVelocity(force, local);
@@ -1633,6 +1630,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1633 m_LSL_Functions.llSetPos(pos); 1630 m_LSL_Functions.llSetPos(pos);
1634 } 1631 }
1635 1632
1633 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1634 {
1635 return m_LSL_Functions.llSetRegionPos(pos);
1636 }
1637
1636 public void llSetPrimitiveParams(LSL_List rules) 1638 public void llSetPrimitiveParams(LSL_List rules)
1637 { 1639 {
1638 m_LSL_Functions.llSetPrimitiveParams(rules); 1640 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1648,11 +1650,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1648 m_LSL_Functions.llSetPrimURL(url); 1650 m_LSL_Functions.llSetPrimURL(url);
1649 } 1651 }
1650 1652
1651 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1652 {
1653 return m_LSL_Functions.llSetRegionPos(pos);
1654 }
1655
1656 public void llSetRemoteScriptAccessPin(int pin) 1653 public void llSetRemoteScriptAccessPin(int pin)
1657 { 1654 {
1658 m_LSL_Functions.llSetRemoteScriptAccessPin(pin); 1655 m_LSL_Functions.llSetRemoteScriptAccessPin(pin);
@@ -1998,9 +1995,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1998 return m_LSL_Functions.llClearLinkMedia(link, face); 1995 return m_LSL_Functions.llClearLinkMedia(link, face);
1999 } 1996 }
2000 1997
2001 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()
2002 { 2014 {
2003 m_LSL_Functions.print(str); 2015 return m_LSL_Functions.llGetPhysicsMaterial();
2004 } 2016 }
2005 } 2017 }
2006} 2018}
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 6264f5d..275b608 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
@@ -230,13 +231,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
230 ItemID = ScriptTask.ItemID; 231 ItemID = ScriptTask.ItemID;
231 AssetID = ScriptTask.AssetID; 232 AssetID = ScriptTask.AssetID;
232 } 233 }
234 LocalID = part.LocalId;
233 235
234 PrimName = part.ParentGroup.Name; 236 PrimName = part.ParentGroup.Name;
235 StartParam = startParam; 237 StartParam = startParam;
236 m_MaxScriptQueue = maxScriptQueue; 238 m_MaxScriptQueue = maxScriptQueue;
237 m_postOnRez = postOnRez; 239 m_postOnRez = postOnRez;
238 m_AttachedAvatar = Part.ParentGroup.AttachedAvatar; 240 m_AttachedAvatar = part.ParentGroup.AttachedAvatar;
239 m_RegionID = Part.ParentGroup.Scene.RegionInfo.RegionID; 241 m_RegionID = part.ParentGroup.Scene.RegionInfo.RegionID;
240 242
241 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op") 243 if (Engine.Config.GetString("ScriptStopStrategy", "abort") == "co-op")
242 { 244 {
@@ -481,27 +483,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
481 PostEvent(new EventParams("attach", 483 PostEvent(new EventParams("attach",
482 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0])); 484 new object[] { new LSL_Types.LSLString(m_AttachedAvatar.ToString()) }, new DetectParams[0]));
483 } 485 }
486
484 } 487 }
485 } 488 }
486 489
487 private void ReleaseControls() 490 private void ReleaseControls()
488 { 491 {
489 int permsMask; 492 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
490 UUID permsGranter; 493
491 lock (Part.TaskInventory) 494 if (part != null)
492 { 495 {
493 if (!Part.TaskInventory.ContainsKey(ItemID)) 496 int permsMask;
497 UUID permsGranter;
498 part.TaskInventory.LockItemsForRead(true);
499 if (!part.TaskInventory.ContainsKey(ItemID))
500 {
501 part.TaskInventory.LockItemsForRead(false);
494 return; 502 return;
503 }
504 permsGranter = part.TaskInventory[ItemID].PermsGranter;
505 permsMask = part.TaskInventory[ItemID].PermsMask;
506 part.TaskInventory.LockItemsForRead(false);
495 507
496 permsGranter = Part.TaskInventory[ItemID].PermsGranter; 508 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
497 permsMask = Part.TaskInventory[ItemID].PermsMask; 509 {
498 } 510 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
499 511 if (presence != null)
500 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 512 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
501 { 513 }
502 ScenePresence presence = Engine.World.GetScenePresence(permsGranter);
503 if (presence != null)
504 presence.UnRegisterControlEventsToScript(LocalID, ItemID);
505 } 514 }
506 } 515 }
507 516
@@ -656,6 +665,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
656 return true; 665 return true;
657 } 666 }
658 667
668 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
659 public void SetState(string state) 669 public void SetState(string state)
660 { 670 {
661 if (state == State) 671 if (state == State)
@@ -667,7 +677,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
667 new DetectParams[0])); 677 new DetectParams[0]));
668 PostEvent(new EventParams("state_entry", new Object[0], 678 PostEvent(new EventParams("state_entry", new Object[0],
669 new DetectParams[0])); 679 new DetectParams[0]));
670 680
671 throw new EventAbortException(); 681 throw new EventAbortException();
672 } 682 }
673 683
@@ -757,57 +767,60 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
757 /// <returns></returns> 767 /// <returns></returns>
758 public object EventProcessor() 768 public object EventProcessor()
759 { 769 {
770 EventParams data = null;
760 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 771 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
761 if (!Running) 772 if (!Running)
762 return 0; 773 return 0;
763 774
764 lock (m_Script)
765 {
766// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 775// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
767 776
768 if (Suspended) 777 if (Suspended)
769 return 0; 778 return 0;
770
771 EventParams data = null;
772 779
773 lock (EventQueue) 780 lock (EventQueue)
781 {
782 data = (EventParams) EventQueue.Dequeue();
783 if (data == null) // Shouldn't happen
774 { 784 {
775 data = (EventParams)EventQueue.Dequeue(); 785 if (EventQueue.Count > 0 && Running && !ShuttingDown)
776 if (data == null) // Shouldn't happen
777 { 786 {
778 if (EventQueue.Count > 0 && Running && !ShuttingDown) 787 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 } 788 }
788 789 else
789 if (data.EventName == "timer")
790 m_TimerQueued = false;
791 if (data.EventName == "control")
792 { 790 {
793 if (m_ControlEventsInQueue > 0) 791 m_CurrentWorkItem = null;
794 m_ControlEventsInQueue--;
795 } 792 }
796 if (data.EventName == "collision") 793 return 0;
797 m_CollisionInQueue = false;
798 } 794 }
799 795
796 if (data.EventName == "timer")
797 m_TimerQueued = false;
798 if (data.EventName == "control")
799 {
800 if (m_ControlEventsInQueue > 0)
801 m_ControlEventsInQueue--;
802 }
803 if (data.EventName == "collision")
804 m_CollisionInQueue = false;
805 }
806
807 lock(m_Script)
808 {
809
810// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
811 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
812
800 if (DebugLevel >= 2) 813 if (DebugLevel >= 2)
801 m_log.DebugFormat( 814 m_log.DebugFormat(
802 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 815 "[SCRIPT INSTANCE]: Processing event {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
803 data.EventName, 816 data.EventName,
804 ScriptName, 817 ScriptName,
805 Part.Name, 818 part.Name,
806 Part.LocalId, 819 part.LocalId,
807 Part.ParentGroup.Name, 820 part.ParentGroup.Name,
808 Part.ParentGroup.UUID, 821 part.ParentGroup.UUID,
809 Part.AbsolutePosition, 822 part.AbsolutePosition,
810 Part.ParentGroup.Scene.Name); 823 part.ParentGroup.Scene.Name);
811 824
812 m_DetectParams = data.DetectParams; 825 m_DetectParams = data.DetectParams;
813 826
@@ -820,17 +833,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
820 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}", 833 "[SCRIPT INSTANCE]: Changing state to {0} for {1}/{2}({3})/{4}({5}) @ {6}/{7}",
821 State, 834 State,
822 ScriptName, 835 ScriptName,
823 Part.Name, 836 part.Name,
824 Part.LocalId, 837 part.LocalId,
825 Part.ParentGroup.Name, 838 part.ParentGroup.Name,
826 Part.ParentGroup.UUID, 839 part.ParentGroup.UUID,
827 Part.AbsolutePosition, 840 part.AbsolutePosition,
828 Part.ParentGroup.Scene.Name); 841 part.ParentGroup.Scene.Name);
829 842
830 AsyncCommandManager.RemoveScript(Engine, 843 AsyncCommandManager.RemoveScript(Engine,
831 LocalID, ItemID); 844 LocalID, ItemID);
832 845
833 Part.SetScriptEvents(ItemID, (int)m_Script.GetStateEventFlags(State)); 846 if (part != null)
847 {
848 part.SetScriptEvents(ItemID,
849 (int)m_Script.GetStateEventFlags(State));
850 }
834 } 851 }
835 else 852 else
836 { 853 {
@@ -893,17 +910,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
893 text = text.Substring(0, 1000); 910 text = text.Substring(0, 1000);
894 Engine.World.SimChat(Utils.StringToBytes(text), 911 Engine.World.SimChat(Utils.StringToBytes(text),
895 ChatTypeEnum.DebugChannel, 2147483647, 912 ChatTypeEnum.DebugChannel, 2147483647,
896 Part.AbsolutePosition, 913 part.AbsolutePosition,
897 Part.Name, Part.UUID, false); 914 part.Name, part.UUID, false);
898 915
899 916
900 m_log.DebugFormat( 917 m_log.DebugFormat(
901 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}", 918 "[SCRIPT INSTANCE]: Runtime error in script {0}, part {1} {2} at {3} in {4}, displayed error {5}, actual exception {6}",
902 ScriptName, 919 ScriptName,
903 PrimName, 920 PrimName,
904 Part.UUID, 921 part.UUID,
905 Part.AbsolutePosition, 922 part.AbsolutePosition,
906 Part.ParentGroup.Scene.Name, 923 part.ParentGroup.Scene.Name,
907 text.Replace("\n", "\\n"), 924 text.Replace("\n", "\\n"),
908 e.InnerException); 925 e.InnerException);
909 } 926 }
@@ -923,12 +940,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
923 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException)) 940 else if ((e is TargetInvocationException) && (e.InnerException is SelfDeleteException))
924 { 941 {
925 m_InSelfDelete = true; 942 m_InSelfDelete = true;
926 Engine.World.DeleteSceneObject(Part.ParentGroup, false); 943 if (part != null)
944 Engine.World.DeleteSceneObject(part.ParentGroup, false);
927 } 945 }
928 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException)) 946 else if ((e is TargetInvocationException) && (e.InnerException is ScriptDeleteException))
929 { 947 {
930 m_InSelfDelete = true; 948 m_InSelfDelete = true;
931 Part.Inventory.RemoveInventoryItem(ItemID); 949 if (part != null)
950 part.Inventory.RemoveInventoryItem(ItemID);
932 } 951 }
933 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException)) 952 else if ((e is TargetInvocationException) && (e.InnerException is ScriptCoopStopException))
934 { 953 {
@@ -982,14 +1001,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
982 ReleaseControls(); 1001 ReleaseControls();
983 1002
984 Stop(timeout); 1003 Stop(timeout);
985 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1004 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
986 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1005 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1006 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1007 part.CollisionSound = UUID.Zero;
987 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1008 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
988 EventQueue.Clear(); 1009 EventQueue.Clear();
989 m_Script.ResetVars(); 1010 m_Script.ResetVars();
990 State = "default"; 1011 State = "default";
991 1012
992 Part.SetScriptEvents(ItemID, 1013 part.SetScriptEvents(ItemID,
993 (int)m_Script.GetStateEventFlags(State)); 1014 (int)m_Script.GetStateEventFlags(State));
994 if (running) 1015 if (running)
995 Start(); 1016 Start();
@@ -998,6 +1019,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
998 new Object[0], new DetectParams[0])); 1019 new Object[0], new DetectParams[0]));
999 } 1020 }
1000 1021
1022 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
1001 public void ApiResetScript() 1023 public void ApiResetScript()
1002 { 1024 {
1003 // bool running = Running; 1025 // bool running = Running;
@@ -1006,15 +1028,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1006 ReleaseControls(); 1028 ReleaseControls();
1007 1029
1008 m_Script.ResetVars(); 1030 m_Script.ResetVars();
1009 Part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 1031 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
1010 Part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 1032 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
1033 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
1034 part.CollisionSound = UUID.Zero;
1011 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 1035 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
1012 1036
1013 EventQueue.Clear(); 1037 EventQueue.Clear();
1014 m_Script.ResetVars(); 1038 m_Script.ResetVars();
1015 State = "default"; 1039 State = "default";
1016 1040
1017 Part.SetScriptEvents(ItemID, 1041 part.SetScriptEvents(ItemID,
1018 (int)m_Script.GetStateEventFlags(State)); 1042 (int)m_Script.GetStateEventFlags(State));
1019 1043
1020 if (m_CurrentEvent != "state_entry") 1044 if (m_CurrentEvent != "state_entry")
@@ -1028,10 +1052,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1028 1052
1029 public Dictionary<string, object> GetVars() 1053 public Dictionary<string, object> GetVars()
1030 { 1054 {
1031 if (m_Script != null) 1055 return m_Script.GetVars();
1032 return m_Script.GetVars();
1033 else
1034 return new Dictionary<string, object>();
1035 } 1056 }
1036 1057
1037 public void SetVars(Dictionary<string, object> vars) 1058 public void SetVars(Dictionary<string, object> vars)
@@ -1220,4 +1241,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
1220 return null; 1241 return null;
1221 } 1242 }
1222 } 1243 }
1223} \ No newline at end of file 1244}
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index 50f9377..4ba0e64 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..27d7674 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,126 @@ 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
1248 { 1319 UUID appDomain = assetID;
1249 // Create the object record 1320
1250 if ((!m_Scripts.ContainsKey(itemID)) || 1321
1251 (m_Scripts[itemID].AssetID != assetID)) 1322
1323 lockScriptsForRead(true);
1324 if ((!m_Scripts.ContainsKey(itemID)) ||
1325 (m_Scripts[itemID].AssetID != assetID))
1326 {
1327 lockScriptsForRead(false);
1328 instance = new ScriptInstance(this, part,
1329 item,
1330 startParam, postOnRez,
1331 m_MaxScriptQueue);
1332
1333
1334
1335 if (part.ParentGroup.IsAttachment)
1336 appDomain = part.ParentGroup.RootPart.UUID;
1337
1338 if (!m_AppDomains.ContainsKey(appDomain))
1252 { 1339 {
1253 UUID appDomain = assetID; 1340 try
1254
1255 if (part.ParentGroup.IsAttachment)
1256 appDomain = part.ParentGroup.RootPart.UUID;
1257
1258 if (!m_AppDomains.ContainsKey(appDomain))
1259 { 1341 {
1260 try 1342 AppDomainSetup appSetup = new AppDomainSetup();
1261 { 1343 appSetup.PrivateBinPath = Path.Combine(
1262 AppDomainSetup appSetup = new AppDomainSetup(); 1344 m_ScriptEnginesPath,
1263 appSetup.PrivateBinPath = Path.Combine( 1345 m_Scene.RegionInfo.RegionID.ToString());
1264 m_ScriptEnginesPath,
1265 m_Scene.RegionInfo.RegionID.ToString());
1266 1346
1267 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1347 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1268 Evidence evidence = new Evidence(baseEvidence); 1348 Evidence evidence = new Evidence(baseEvidence);
1269 1349
1270 AppDomain sandbox; 1350 AppDomain sandbox;
1271 if (m_AppDomainLoading) 1351 if (m_AppDomainLoading)
1352 {
1353 sandbox = AppDomain.CreateDomain(
1354 m_Scene.RegionInfo.RegionID.ToString(),
1355 evidence, appSetup);
1356 if (m_AppDomains.ContainsKey(appDomain))
1272 { 1357 {
1273 sandbox = AppDomain.CreateDomain( 1358 m_AppDomains[appDomain].AssemblyResolve +=
1274 m_Scene.RegionInfo.RegionID.ToString(),
1275 evidence, appSetup);
1276 sandbox.AssemblyResolve +=
1277 new ResolveEventHandler( 1359 new ResolveEventHandler(
1278 AssemblyResolver.OnAssemblyResolve); 1360 AssemblyResolver.OnAssemblyResolve);
1361 if (m_DomainScripts.ContainsKey(appDomain))
1362 {
1363 m_DomainScripts[appDomain].Add(itemID);
1364 }
1365 else
1366 {
1367 m_DomainScripts.Add(appDomain, new List<UUID>());
1368 m_DomainScripts[appDomain].Add(itemID);
1369 }
1279 } 1370 }
1280 else 1371 else
1281 { 1372 {
1282 sandbox = AppDomain.CurrentDomain; 1373 m_AppDomains.Add(appDomain, sandbox);
1374 m_AppDomains[appDomain].AssemblyResolve +=
1375 new ResolveEventHandler(
1376 AssemblyResolver.OnAssemblyResolve);
1377 if (m_DomainScripts.ContainsKey(appDomain))
1378 {
1379 m_DomainScripts[appDomain].Add(itemID);
1380 }
1381 else
1382 {
1383 m_DomainScripts.Add(appDomain, new List<UUID>());
1384 m_DomainScripts[appDomain].Add(itemID);
1385 }
1386
1283 } 1387 }
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 1388
1295 m_DomainScripts[appDomain] = new List<UUID>();
1296 } 1389 }
1297 catch (Exception e) 1390 else
1298 { 1391 {
1299 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1392 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 } 1393 }
1308 }
1309 m_DomainScripts[appDomain].Add(itemID);
1310
1311 instance = new ScriptInstance(this, part,
1312 item,
1313 startParam, postOnRez,
1314 m_MaxScriptQueue);
1315 1394
1316 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource)) 1395 if (!instance.Load(m_AppDomains[appDomain], assembly, stateSource))
1317 return false; 1396 return false;
1318 1397
1319// if (DebugLevel >= 1) 1398 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 1399
1325 if (presence != null) 1400 m_DomainScripts[appDomain] = new List<UUID>();
1401 }
1402 catch (Exception e)
1326 { 1403 {
1327 ShowScriptSaveResponse(item.OwnerID, 1404 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1328 assetID, "Compile successful", true); 1405 m_ScriptErrorMessage += "Exception creating app domain:\n";
1406 m_ScriptFailCount++;
1407 lock (m_AddingAssemblies)
1408 {
1409 m_AddingAssemblies[assembly]--;
1410 }
1411 return false;
1329 } 1412 }
1413 }
1414
1330 1415
1331 instance.AppDomain = appDomain; 1416 instance.Load(m_AppDomains[appDomain], assembly, stateSource);
1332 instance.LineMap = linemap; 1417// m_log.DebugFormat(
1418// "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1419// part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1420// part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1333 1421
1334 m_Scripts[itemID] = instance; 1422 if (presence != null)
1423 {
1424 ShowScriptSaveResponse(item.OwnerID,
1425 assetID, "Compile successful", true);
1335 } 1426 }
1336 }
1337 1427
1428 instance.AppDomain = appDomain;
1429 instance.LineMap = linemap;
1430 lockScriptsForWrite(true);
1431 m_Scripts[itemID] = instance;
1432 lockScriptsForWrite(false);
1433 }
1434 else
1435 {
1436 lockScriptsForRead(false);
1437 }
1338 lock (m_PrimObjects) 1438 lock (m_PrimObjects)
1339 { 1439 {
1340 if (!m_PrimObjects.ContainsKey(localID)) 1440 if (!m_PrimObjects.ContainsKey(localID))
@@ -1352,7 +1452,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1352 m_AddingAssemblies[assembly]--; 1452 m_AddingAssemblies[assembly]--;
1353 } 1453 }
1354 1454
1355 if (instance != null) 1455 if (instance!=null)
1356 instance.Init(); 1456 instance.Init();
1357 1457
1358 bool runIt; 1458 bool runIt;
@@ -1375,18 +1475,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1375 m_CompileDict.Remove(itemID); 1475 m_CompileDict.Remove(itemID);
1376 } 1476 }
1377 1477
1378 IScriptInstance instance = null; 1478 lockScriptsForRead(true);
1379 1479 // Do we even have it?
1380 lock (m_Scripts) 1480 if (!m_Scripts.ContainsKey(itemID))
1381 { 1481 {
1382 // Do we even have it? 1482 // Do we even have it?
1383 if (!m_Scripts.ContainsKey(itemID)) 1483 if (!m_Scripts.ContainsKey(itemID))
1384 return; 1484 return;
1385 1485
1386 instance = m_Scripts[itemID]; 1486 lockScriptsForRead(false);
1487 lockScriptsForWrite(true);
1387 m_Scripts.Remove(itemID); 1488 m_Scripts.Remove(itemID);
1489 lockScriptsForWrite(false);
1490
1491 return;
1388 } 1492 }
1493
1389 1494
1495 IScriptInstance instance=m_Scripts[itemID];
1496 lockScriptsForRead(false);
1497 lockScriptsForWrite(true);
1498 m_Scripts.Remove(itemID);
1499 lockScriptsForWrite(false);
1390 instance.ClearQueue(); 1500 instance.ClearQueue();
1391 1501
1392 instance.Stop(m_WaitForEventCompletionOnScriptStop); 1502 instance.Stop(m_WaitForEventCompletionOnScriptStop);
@@ -1423,8 +1533,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1423 1533
1424 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1534 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1425 if (handlerObjectRemoved != null) 1535 if (handlerObjectRemoved != null)
1426 handlerObjectRemoved(instance.ObjectID); 1536 {
1537 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1538 if (part != null)
1539 handlerObjectRemoved(part.UUID);
1540 }
1427 1541
1542 CleanAssemblies();
1543
1428 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1544 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1429 if (handlerScriptRemoved != null) 1545 if (handlerScriptRemoved != null)
1430 handlerScriptRemoved(itemID); 1546 handlerScriptRemoved(itemID);
@@ -1685,12 +1801,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1685 private IScriptInstance GetInstance(UUID itemID) 1801 private IScriptInstance GetInstance(UUID itemID)
1686 { 1802 {
1687 IScriptInstance instance; 1803 IScriptInstance instance;
1688 lock (m_Scripts) 1804 lockScriptsForRead(true);
1805 if (!m_Scripts.ContainsKey(itemID))
1689 { 1806 {
1690 if (!m_Scripts.ContainsKey(itemID)) 1807 lockScriptsForRead(false);
1691 return null; 1808 return null;
1692 instance = m_Scripts[itemID];
1693 } 1809 }
1810 instance = m_Scripts[itemID];
1811 lockScriptsForRead(false);
1694 return instance; 1812 return instance;
1695 } 1813 }
1696 1814
@@ -1714,6 +1832,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1714 return false; 1832 return false;
1715 } 1833 }
1716 1834
1835 [DebuggerNonUserCode]
1717 public void ApiResetScript(UUID itemID) 1836 public void ApiResetScript(UUID itemID)
1718 { 1837 {
1719 IScriptInstance instance = GetInstance(itemID); 1838 IScriptInstance instance = GetInstance(itemID);
@@ -1775,6 +1894,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1775 return UUID.Zero; 1894 return UUID.Zero;
1776 } 1895 }
1777 1896
1897 [DebuggerNonUserCode]
1778 public void SetState(UUID itemID, string newState) 1898 public void SetState(UUID itemID, string newState)
1779 { 1899 {
1780 IScriptInstance instance = GetInstance(itemID); 1900 IScriptInstance instance = GetInstance(itemID);
@@ -1797,11 +1917,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1797 1917
1798 List<IScriptInstance> instances = new List<IScriptInstance>(); 1918 List<IScriptInstance> instances = new List<IScriptInstance>();
1799 1919
1800 lock (m_Scripts) 1920 lockScriptsForRead(true);
1801 { 1921 foreach (IScriptInstance instance in m_Scripts.Values)
1802 foreach (IScriptInstance instance in m_Scripts.Values)
1803 instances.Add(instance); 1922 instances.Add(instance);
1804 } 1923 lockScriptsForRead(false);
1805 1924
1806 foreach (IScriptInstance i in instances) 1925 foreach (IScriptInstance i in instances)
1807 { 1926 {