aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3142
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs9
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs26
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs8
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
-rw-r--r--OpenSim/Region/ScriptEngine/XEngine/XEngine.cs360
19 files changed, 3117 insertions, 1024 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 993d10f..3cbdde5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -301,6 +301,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
301 return null; 301 return null;
302 } 302 }
303 303
304 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
305 {
306 // Remove a specific script
307
308 // Remove dataserver events
309 m_Dataserver[engine].RemoveEvents(localID, itemID);
310
311 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
312 if (comms != null)
313 comms.DeleteListener(itemID);
314
315 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
316 xmlrpc.DeleteChannels(itemID);
317 xmlrpc.CancelSRDRequests(itemID);
318
319 // Remove Sensors
320 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
321
322 }
323
304 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 324 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
305 { 325 {
306 List<Object> data = new List<Object>(); 326 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index a8679e2..41de257 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116 protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118
119 private Dictionary<string, string> MovementAnimationsForLSL =
120 new Dictionary<string, string> {
121 {"FLY", "Flying"},
122 {"FLYSLOW", "FlyingSlow"},
123 {"HOVER_UP", "Hovering Up"},
124 {"HOVER_DOWN", "Hovering Down"},
125 {"HOVER", "Hovering"},
126 {"LAND", "Landing"},
127 {"FALLDOWN", "Falling Down"},
128 {"PREJUMP", "PreJumping"},
129 {"JUMP", "Jumping"},
130 {"STANDUP", "Standing Up"},
131 {"SOFT_LAND", "Soft Landing"},
132 {"STAND", "Standing"},
133 {"CROUCHWALK", "CrouchWalking"},
134 {"RUN", "Running"},
135 {"WALK", "Walking"},
136 {"CROUCH", "Crouching"},
137 {"TURNLEFT", "Turning Left"},
138 {"TURNRIGHT", "Turning Right"}
139 };
109 140
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 141 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 142 {
143 m_ShoutSayTimer = new Timer(1000);
144 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
145 m_ShoutSayTimer.AutoReset = true;
146 m_ShoutSayTimer.Start();
147
112 m_ScriptEngine = ScriptEngine; 148 m_ScriptEngine = ScriptEngine;
113 m_host = host; 149 m_host = host;
114 m_item = item; 150 m_item = item;
151 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 152
116 LoadLimits(); // read script limits from config. 153 LoadLimits(); // read script limits from config.
117 154
@@ -171,6 +208,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 208 get { return m_ScriptEngine.World; }
172 } 209 }
173 210
211 [DebuggerNonUserCode]
174 public void state(string newState) 212 public void state(string newState)
175 { 213 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 214 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +218,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 218 /// Reset the named script. The script must be present
181 /// in the same prim. 219 /// in the same prim.
182 /// </summary> 220 /// </summary>
221 [DebuggerNonUserCode]
183 public void llResetScript() 222 public void llResetScript()
184 { 223 {
185 m_host.AddScriptLPS(1); 224 m_host.AddScriptLPS(1);
@@ -236,9 +275,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 275 }
237 } 276 }
238 277
278 public List<ScenePresence> GetLinkAvatars(int linkType)
279 {
280 List<ScenePresence> ret = new List<ScenePresence>();
281 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
282 return ret;
283
284 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
285
286 switch (linkType)
287 {
288 case ScriptBaseClass.LINK_SET:
289 return avs;
290
291 case ScriptBaseClass.LINK_ROOT:
292 return ret;
293
294 case ScriptBaseClass.LINK_ALL_OTHERS:
295 return avs;
296
297 case ScriptBaseClass.LINK_ALL_CHILDREN:
298 return avs;
299
300 case ScriptBaseClass.LINK_THIS:
301 return ret;
302
303 default:
304 if (linkType < 0)
305 return ret;
306
307 int partCount = m_host.ParentGroup.GetPartCount();
308
309 if (linkType <= partCount)
310 {
311 return ret;
312 }
313 else
314 {
315 linkType = linkType - partCount;
316 if (linkType > avs.Count)
317 {
318 return ret;
319 }
320 else
321 {
322 ret.Add(avs[linkType-1]);
323 return ret;
324 }
325 }
326 }
327 }
328
239 public List<SceneObjectPart> GetLinkParts(int linkType) 329 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 330 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 331 List<SceneObjectPart> ret = new List<SceneObjectPart>();
332 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
333 return ret;
242 ret.Add(m_host); 334 ret.Add(m_host);
243 335
244 switch (linkType) 336 switch (linkType)
@@ -432,31 +524,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
432 524
433 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 525 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
434 526
435 /// <summary> 527 // Utility function for llRot2Euler
436 /// Convert an LSL rotation to a Euler vector. 528
437 /// </summary> 529 // normalize an angle between -PI and PI (-180 to +180 degrees)
438 /// <remarks> 530 protected double NormalizeAngle(double angle)
439 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
440 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
441 /// </remarks>
442 /// <param name="r"></param>
443 /// <returns></returns>
444 public LSL_Vector llRot2Euler(LSL_Rotation r)
445 { 531 {
446 m_host.AddScriptLPS(1); 532 if (angle > -Math.PI && angle < Math.PI)
533 return angle;
534
535 int numPis = (int)(Math.PI / angle);
536 double remainder = angle - Math.PI * numPis;
537 if (numPis % 2 == 1)
538 return Math.PI - angle;
539 return remainder;
540 }
447 541
448 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 542 public LSL_Vector llRot2Euler(LSL_Rotation q1)
449 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 543 {
450 if (m == 0.0) return new LSL_Vector(); 544 m_host.AddScriptLPS(1);
451 double x = Math.Atan2(-v.y, v.z); 545 LSL_Vector eul = new LSL_Vector();
452 double sin = v.x / m;
453 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
454 double y = Math.Asin(sin);
455 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
456 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)));
457 double z = Math.Atan2(v.y, v.x);
458 546
459 return new LSL_Vector(x, y, z); 547 double sqw = q1.s*q1.s;
548 double sqx = q1.x*q1.x;
549 double sqy = q1.z*q1.z;
550 double sqz = q1.y*q1.y;
551 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
552 double test = q1.x*q1.z + q1.y*q1.s;
553 if (test > 0.4999*unit) { // singularity at north pole
554 eul.z = 2 * Math.Atan2(q1.x,q1.s);
555 eul.y = Math.PI/2;
556 eul.x = 0;
557 return eul;
558 }
559 if (test < -0.4999*unit) { // singularity at south pole
560 eul.z = -2 * Math.Atan2(q1.x,q1.s);
561 eul.y = -Math.PI/2;
562 eul.x = 0;
563 return eul;
564 }
565 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
566 eul.y = Math.Asin(2*test/unit);
567 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
568 return eul;
460 } 569 }
461 570
462 /* From wiki: 571 /* From wiki:
@@ -658,77 +767,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
658 { 767 {
659 //A and B should both be normalized 768 //A and B should both be normalized
660 m_host.AddScriptLPS(1); 769 m_host.AddScriptLPS(1);
661 LSL_Rotation rotBetween; 770 /* This method is more accurate than the SL one, and thus causes problems
662 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 771 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
663 // continue calculation. 772
664 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 773 double dotProduct = LSL_Vector.Dot(a, b);
774 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
775 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
776 double angle = Math.Acos(dotProduct / magProduct);
777 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
778 double s = Math.Sin(angle / 2);
779
780 double x = axis.x * s;
781 double y = axis.y * s;
782 double z = axis.z * s;
783 double w = Math.Cos(angle / 2);
784
785 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
786 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
787
788 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
789 */
790
791 // This method mimics the 180 errors found in SL
792 // See www.euclideanspace.com... angleBetween
793 LSL_Vector vec_a = a;
794 LSL_Vector vec_b = b;
795
796 // Eliminate zero length
797 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
798 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
799 if (vec_a_mag < 0.00001 ||
800 vec_b_mag < 0.00001)
665 { 801 {
666 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 802 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
667 } 803 }
668 else 804
805 // Normalize
806 vec_a = llVecNorm(vec_a);
807 vec_b = llVecNorm(vec_b);
808
809 // Calculate axis and rotation angle
810 LSL_Vector axis = vec_a % vec_b;
811 LSL_Float cos_theta = vec_a * vec_b;
812
813 // Check if parallel
814 if (cos_theta > 0.99999)
669 { 815 {
670 a = LSL_Vector.Norm(a); 816 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
671 b = LSL_Vector.Norm(b); 817 }
672 double dotProduct = LSL_Vector.Dot(a, b); 818
673 // There are two degenerate cases possible. These are for vectors 180 or 819 // Check if anti-parallel
674 // 0 degrees apart. These have to be detected and handled individually. 820 else if (cos_theta < -0.99999)
675 // 821 {
676 // Check for vectors 180 degrees apart. 822 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
677 // A dot product of -1 would mean the angle between vectors is 180 degrees. 823 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
678 if (dotProduct < -0.9999999f) 824 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
679 { 825 }
680 // First assume X axis is orthogonal to the vectors. 826 else // other rotation
681 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 827 {
682 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 828 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
683 // Check for near zero vector. A very small non-zero number here will create 829 axis = llVecNorm(axis);
684 // a rotation in an undesired direction. 830 double x, y, z, s, t;
685 if (LSL_Vector.Mag(orthoVector) > 0.0001) 831 s = Math.Cos(theta);
686 { 832 t = Math.Sin(theta);
687 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 833 x = axis.x * t;
688 } 834 y = axis.y * t;
689 // If the magnitude of the vector was near zero, then assume the X axis is not 835 z = axis.z * t;
690 // orthogonal and use the Z axis instead. 836 return new LSL_Rotation(x,y,z,s);
691 else
692 {
693 // Set 180 z rotation.
694 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
695 }
696 }
697 // Check for parallel vectors.
698 // A dot product of 1 would mean the angle between vectors is 0 degrees.
699 else if (dotProduct > 0.9999999f)
700 {
701 // Set zero rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
703 }
704 else
705 {
706 // All special checks have been performed so get the axis of rotation.
707 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
708 // Quarternion s value is the length of the unit vector + dot product.
709 double qs = 1.0 + dotProduct;
710 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
711 // Normalize the rotation.
712 double mag = LSL_Rotation.Mag(rotBetween);
713 // We shouldn't have to worry about a divide by zero here. The qs value will be
714 // non-zero because we already know if we're here, then the dotProduct is not -1 so
715 // qs will not be zero. Also, we've already handled the input vectors being zero so the
716 // crossProduct vector should also not be zero.
717 rotBetween.x = rotBetween.x / mag;
718 rotBetween.y = rotBetween.y / mag;
719 rotBetween.z = rotBetween.z / mag;
720 rotBetween.s = rotBetween.s / mag;
721 // Check for undefined values and set zero rotation if any found. This code might not actually be required
722 // any longer since zero vectors are checked for at the top.
723 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
724 {
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
726 }
727 }
728 } 837 }
729 return rotBetween;
730 } 838 }
731 839
732 public void llWhisper(int channelID, string text) 840 public void llWhisper(int channelID, string text)
733 { 841 {
734 m_host.AddScriptLPS(1); 842 m_host.AddScriptLPS(1);
@@ -748,6 +856,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
748 { 856 {
749 m_host.AddScriptLPS(1); 857 m_host.AddScriptLPS(1);
750 858
859 if (channelID == 0)
860 m_SayShoutCount++;
861
862 if (m_SayShoutCount >= 11)
863 ScriptSleep(2000);
864
751 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 865 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
752 { 866 {
753 Console.WriteLine(text); 867 Console.WriteLine(text);
@@ -770,6 +884,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
770 { 884 {
771 m_host.AddScriptLPS(1); 885 m_host.AddScriptLPS(1);
772 886
887 if (channelID == 0)
888 m_SayShoutCount++;
889
890 if (m_SayShoutCount >= 11)
891 ScriptSleep(2000);
892
773 if (text.Length > 1023) 893 if (text.Length > 1023)
774 text = text.Substring(0, 1023); 894 text = text.Substring(0, 1023);
775 895
@@ -1072,10 +1192,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1072 return detectedParams.TouchUV; 1192 return detectedParams.TouchUV;
1073 } 1193 }
1074 1194
1195 [DebuggerNonUserCode]
1075 public virtual void llDie() 1196 public virtual void llDie()
1076 { 1197 {
1077 m_host.AddScriptLPS(1); 1198 m_host.AddScriptLPS(1);
1078 throw new SelfDeleteException(); 1199 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1079 } 1200 }
1080 1201
1081 public LSL_Float llGround(LSL_Vector offset) 1202 public LSL_Float llGround(LSL_Vector offset)
@@ -1148,6 +1269,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1148 1269
1149 public void llSetStatus(int status, int value) 1270 public void llSetStatus(int status, int value)
1150 { 1271 {
1272 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1273 return;
1151 m_host.AddScriptLPS(1); 1274 m_host.AddScriptLPS(1);
1152 1275
1153 int statusrotationaxis = 0; 1276 int statusrotationaxis = 0;
@@ -1171,6 +1294,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1171 if (!allow) 1294 if (!allow)
1172 return; 1295 return;
1173 1296
1297 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1298 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1299 return;
1300
1174 m_host.ScriptSetPhysicsStatus(true); 1301 m_host.ScriptSetPhysicsStatus(true);
1175 } 1302 }
1176 else 1303 else
@@ -1379,6 +1506,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1379 { 1506 {
1380 m_host.AddScriptLPS(1); 1507 m_host.AddScriptLPS(1);
1381 1508
1509 SetColor(m_host, color, face);
1510 }
1511
1512 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1513 {
1514 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1515 return;
1516
1517 Primitive.TextureEntry tex = part.Shape.Textures;
1518 Color4 texcolor;
1519 if (face >= 0 && face < GetNumberOfSides(part))
1520 {
1521 texcolor = tex.CreateFace((uint)face).RGBA;
1522 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1523 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1524 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1525 tex.FaceTextures[face].RGBA = texcolor;
1526 part.UpdateTextureEntry(tex.GetBytes());
1527 return;
1528 }
1529 else if (face == ScriptBaseClass.ALL_SIDES)
1530 {
1531 for (uint i = 0; i < GetNumberOfSides(part); i++)
1532 {
1533 if (tex.FaceTextures[i] != null)
1534 {
1535 texcolor = tex.FaceTextures[i].RGBA;
1536 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1537 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1538 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1539 tex.FaceTextures[i].RGBA = texcolor;
1540 }
1541 texcolor = tex.DefaultTexture.RGBA;
1542 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1543 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1544 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1545 tex.DefaultTexture.RGBA = texcolor;
1546 }
1547 part.UpdateTextureEntry(tex.GetBytes());
1548 return;
1549 }
1550
1382 if (face == ScriptBaseClass.ALL_SIDES) 1551 if (face == ScriptBaseClass.ALL_SIDES)
1383 face = SceneObjectPart.ALL_SIDES; 1552 face = SceneObjectPart.ALL_SIDES;
1384 1553
@@ -1387,6 +1556,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1387 1556
1388 public void SetTexGen(SceneObjectPart part, int face,int style) 1557 public void SetTexGen(SceneObjectPart part, int face,int style)
1389 { 1558 {
1559 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1560 return;
1561
1390 Primitive.TextureEntry tex = part.Shape.Textures; 1562 Primitive.TextureEntry tex = part.Shape.Textures;
1391 MappingType textype; 1563 MappingType textype;
1392 textype = MappingType.Default; 1564 textype = MappingType.Default;
@@ -1417,6 +1589,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1417 1589
1418 public void SetGlow(SceneObjectPart part, int face, float glow) 1590 public void SetGlow(SceneObjectPart part, int face, float glow)
1419 { 1591 {
1592 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1593 return;
1594
1420 Primitive.TextureEntry tex = part.Shape.Textures; 1595 Primitive.TextureEntry tex = part.Shape.Textures;
1421 if (face >= 0 && face < GetNumberOfSides(part)) 1596 if (face >= 0 && face < GetNumberOfSides(part))
1422 { 1597 {
@@ -1442,6 +1617,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1442 1617
1443 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1618 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1444 { 1619 {
1620 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1621 return;
1445 1622
1446 Shininess sval = new Shininess(); 1623 Shininess sval = new Shininess();
1447 1624
@@ -1492,6 +1669,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 1669
1493 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1670 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1494 { 1671 {
1672 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1673 return;
1674
1495 Primitive.TextureEntry tex = part.Shape.Textures; 1675 Primitive.TextureEntry tex = part.Shape.Textures;
1496 if (face >= 0 && face < GetNumberOfSides(part)) 1676 if (face >= 0 && face < GetNumberOfSides(part))
1497 { 1677 {
@@ -1552,13 +1732,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1552 m_host.AddScriptLPS(1); 1732 m_host.AddScriptLPS(1);
1553 1733
1554 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1734 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1555 1735 if (parts.Count > 0)
1556 foreach (SceneObjectPart part in parts) 1736 {
1557 SetAlpha(part, alpha, face); 1737 try
1738 {
1739 parts[0].ParentGroup.areUpdatesSuspended = true;
1740 foreach (SceneObjectPart part in parts)
1741 SetAlpha(part, alpha, face);
1742 }
1743 finally
1744 {
1745 parts[0].ParentGroup.areUpdatesSuspended = false;
1746 }
1747 }
1558 } 1748 }
1559 1749
1560 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1750 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1561 { 1751 {
1752 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1753 return;
1754
1562 Primitive.TextureEntry tex = part.Shape.Textures; 1755 Primitive.TextureEntry tex = part.Shape.Textures;
1563 Color4 texcolor; 1756 Color4 texcolor;
1564 if (face >= 0 && face < GetNumberOfSides(part)) 1757 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1611,7 +1804,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1611 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1804 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1612 float wind, float tension, LSL_Vector Force) 1805 float wind, float tension, LSL_Vector Force)
1613 { 1806 {
1614 if (part == null) 1807 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return; 1808 return;
1616 1809
1617 if (flexi) 1810 if (flexi)
@@ -1645,7 +1838,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1838 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1839 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1840 {
1648 if (part == null) 1841 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1842 return;
1650 1843
1651 if (light) 1844 if (light)
@@ -1724,15 +1917,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 m_host.AddScriptLPS(1); 1917 m_host.AddScriptLPS(1);
1725 1918
1726 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1919 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1727 1920 if (parts.Count > 0)
1728 foreach (SceneObjectPart part in parts) 1921 {
1729 SetTexture(part, texture, face); 1922 try
1730 1923 {
1924 parts[0].ParentGroup.areUpdatesSuspended = true;
1925 foreach (SceneObjectPart part in parts)
1926 SetTexture(part, texture, face);
1927 }
1928 finally
1929 {
1930 parts[0].ParentGroup.areUpdatesSuspended = false;
1931 }
1932 }
1731 ScriptSleep(200); 1933 ScriptSleep(200);
1732 } 1934 }
1733 1935
1734 protected void SetTexture(SceneObjectPart part, string texture, int face) 1936 protected void SetTexture(SceneObjectPart part, string texture, int face)
1735 { 1937 {
1938 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1939 return;
1940
1736 UUID textureID = new UUID(); 1941 UUID textureID = new UUID();
1737 1942
1738 textureID = InventoryKey(texture, (int)AssetType.Texture); 1943 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1777,6 +1982,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1777 1982
1778 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 1983 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1779 { 1984 {
1985 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1986 return;
1987
1780 Primitive.TextureEntry tex = part.Shape.Textures; 1988 Primitive.TextureEntry tex = part.Shape.Textures;
1781 if (face >= 0 && face < GetNumberOfSides(part)) 1989 if (face >= 0 && face < GetNumberOfSides(part))
1782 { 1990 {
@@ -1813,6 +2021,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 2021
1814 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2022 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2023 {
2024 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2025 return;
2026
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2027 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2028 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2029 {
@@ -1849,6 +2060,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2060
1850 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2061 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1851 { 2062 {
2063 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2064 return;
2065
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2066 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2067 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2068 {
@@ -1953,26 +2167,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1953 return real_vec; 2167 return real_vec;
1954 } 2168 }
1955 2169
2170 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2171 {
2172 return new LSL_Integer(SetRegionPos(m_host, pos));
2173 }
2174
2175 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2176 {
2177 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2178 return 0;
2179
2180 SceneObjectGroup grp = part.ParentGroup;
2181
2182 if (grp.IsAttachment)
2183 return 0;
2184
2185 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2186 return 0;
2187
2188 if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
2189 return 0;
2190
2191 float constrainedX = (float)targetPos.x;
2192 float constrainedY = (float)targetPos.y;
2193
2194 if (constrainedX < 0.0f)
2195 constrainedX = 0.0f;
2196 if (constrainedY < 0.0f)
2197 constrainedY = 0.0f;
2198 if (constrainedX >= (float)Constants.RegionSize)
2199 constrainedX = (float)Constants.RegionSize - 0.1f;
2200 if (constrainedY >= (float)Constants.RegionSize)
2201 constrainedY = (float)Constants.RegionSize -0.1f;
2202
2203 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2204
2205 if (targetPos.z < ground)
2206 targetPos.z = ground;
2207
2208 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2209
2210 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2211 return 0;
2212
2213 grp.UpdateGroupPosition(dest);
2214
2215 return 1;
2216 }
2217
1956 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2218 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1957 { 2219 {
1958 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2220 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2221 return;
2222
1959 LSL_Vector currentPos = GetPartLocalPos(part); 2223 LSL_Vector currentPos = GetPartLocalPos(part);
2224 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1960 2225
1961 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1962 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1963 2226
1964 if (part.ParentGroup.RootPart == part) 2227 if (part.ParentGroup.RootPart == part)
1965 { 2228 {
1966 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1967 targetPos.z = ground;
1968 SceneObjectGroup parent = part.ParentGroup; 2229 SceneObjectGroup parent = part.ParentGroup;
1969 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2230 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1970 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2231 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2232 return;
2233 Util.FireAndForget(delegate(object x) {
2234 parent.UpdateGroupPosition(dest);
2235 });
1971 } 2236 }
1972 else 2237 else
1973 { 2238 {
1974 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2239 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1975 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1976 SceneObjectGroup parent = part.ParentGroup; 2240 SceneObjectGroup parent = part.ParentGroup;
1977 parent.HasGroupChanged = true; 2241 parent.HasGroupChanged = true;
1978 parent.ScheduleGroupForTerseUpdate(); 2242 parent.ScheduleGroupForTerseUpdate();
@@ -2005,17 +2269,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2005 else 2269 else
2006 { 2270 {
2007 if (part.ParentGroup.IsAttachment) 2271 if (part.ParentGroup.IsAttachment)
2008 {
2009 pos = part.AttachedPos; 2272 pos = part.AttachedPos;
2010 }
2011 else 2273 else
2012 {
2013 pos = part.AbsolutePosition; 2274 pos = part.AbsolutePosition;
2014 }
2015 } 2275 }
2016 2276
2017// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2018
2019 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2277 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2020 } 2278 }
2021 2279
@@ -2024,9 +2282,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 m_host.AddScriptLPS(1); 2282 m_host.AddScriptLPS(1);
2025 2283
2026 // try to let this work as in SL... 2284 // try to let this work as in SL...
2027 if (m_host.ParentID == 0) 2285 if (m_host.LinkNum < 2)
2028 { 2286 {
2029 // special case: If we are root, rotate complete SOG to new rotation 2287 // Special case: If we are root, rotate complete SOG to new
2288 // rotation.
2289 // We are root if the link number is 0 (single prim) or 1
2290 // (root prim). ParentID may be nonzero in attachments and
2291 // using it would cause attachments and HUDs to rotate
2292 // to the wrong positions.
2030 SetRot(m_host, Rot2Quaternion(rot)); 2293 SetRot(m_host, Rot2Quaternion(rot));
2031 } 2294 }
2032 else 2295 else
@@ -2051,6 +2314,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2051 2314
2052 protected void SetRot(SceneObjectPart part, Quaternion rot) 2315 protected void SetRot(SceneObjectPart part, Quaternion rot)
2053 { 2316 {
2317 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2318 return;
2319
2054 part.UpdateRotation(rot); 2320 part.UpdateRotation(rot);
2055 // Update rotation does not move the object in the physics scene if it's a linkset. 2321 // Update rotation does not move the object in the physics scene if it's a linkset.
2056 2322
@@ -2066,7 +2332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2066 // scene 2332 // scene
2067 PhysicsActor pa = part.PhysActor; 2333 PhysicsActor pa = part.PhysActor;
2068 2334
2069 if (pa != null && !pa.IsPhysical) 2335 if (pa != null && !pa.IsPhysical && part == part.ParentGroup.RootPart)
2070 { 2336 {
2071 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2337 part.ParentGroup.ResetChildPrimPhysicsPositions();
2072 } 2338 }
@@ -2205,13 +2471,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2205 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2471 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2206 { 2472 {
2207 m_host.AddScriptLPS(1); 2473 m_host.AddScriptLPS(1);
2208 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2474 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2209 } 2475 }
2210 2476
2211 public void llSetTorque(LSL_Vector torque, int local) 2477 public void llSetTorque(LSL_Vector torque, int local)
2212 { 2478 {
2213 m_host.AddScriptLPS(1); 2479 m_host.AddScriptLPS(1);
2214 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2480 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2215 } 2481 }
2216 2482
2217 public LSL_Vector llGetTorque() 2483 public LSL_Vector llGetTorque()
@@ -2232,16 +2498,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2232 { 2498 {
2233 m_host.AddScriptLPS(1); 2499 m_host.AddScriptLPS(1);
2234 2500
2235 Vector3 vel; 2501 Vector3 vel = Vector3.Zero;
2236 2502
2237 if (m_host.ParentGroup.IsAttachment) 2503 if (m_host.ParentGroup.IsAttachment)
2238 { 2504 {
2239 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2505 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2240 vel = avatar.Velocity; 2506 if (avatar != null)
2507 vel = avatar.Velocity;
2241 } 2508 }
2242 else 2509 else
2243 { 2510 {
2244 vel = m_host.Velocity; 2511 vel = m_host.ParentGroup.RootPart.Velocity;
2245 } 2512 }
2246 2513
2247 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2514 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2790,8 +3057,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2790 3057
2791 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3058 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2792 { 3059 {
2793 //Recoil. 3060 // recoil
2794 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3061 llvel *= -groupmass;
3062 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2795 } 3063 }
2796 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3064 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
2797 return; 3065 return;
@@ -2813,35 +3081,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2813 public void llLookAt(LSL_Vector target, double strength, double damping) 3081 public void llLookAt(LSL_Vector target, double strength, double damping)
2814 { 3082 {
2815 m_host.AddScriptLPS(1); 3083 m_host.AddScriptLPS(1);
2816 // Determine where we are looking from
2817 LSL_Vector from = llGetPos();
2818 3084
2819 // Work out the normalised vector from the source to the target 3085 // Get the normalized vector to the target
2820 LSL_Vector delta = llVecNorm(target - from); 3086 LSL_Vector d1 = llVecNorm(target - llGetPos());
2821 LSL_Vector angle = new LSL_Vector(0,0,0);
2822 3087
2823 // Calculate the yaw 3088 // Get the bearing (yaw)
2824 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3089 LSL_Vector a1 = new LSL_Vector(0,0,0);
2825 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3090 a1.z = llAtan2(d1.y, d1.x);
2826 3091
2827 // Calculate pitch 3092 // Get the elevation (pitch)
2828 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3093 LSL_Vector a2 = new LSL_Vector(0,0,0);
3094 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2829 3095
2830 // we need to convert from a vector describing 3096 LSL_Rotation r1 = llEuler2Rot(a1);
2831 // the angles of rotation in radians into rotation value 3097 LSL_Rotation r2 = llEuler2Rot(a2);
2832 LSL_Rotation rot = llEuler2Rot(angle); 3098 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2833
2834 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2835 // set the rotation of the object, copy that behavior
2836 PhysicsActor pa = m_host.PhysActor;
2837 3099
2838 if (strength == 0 || pa == null || !pa.IsPhysical) 3100 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2839 { 3101 {
2840 llSetRot(rot); 3102 // Do nothing if either value is 0 (this has been checked in SL)
3103 if (strength <= 0.0 || damping <= 0.0)
3104 return;
3105
3106 llSetRot(r3 * r2 * r1);
2841 } 3107 }
2842 else 3108 else
2843 { 3109 {
2844 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3110 if (strength == 0)
3111 {
3112 llSetRot(r3 * r2 * r1);
3113 return;
3114 }
3115
3116 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2845 } 3117 }
2846 } 3118 }
2847 3119
@@ -2887,17 +3159,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2887 } 3159 }
2888 else 3160 else
2889 { 3161 {
2890 if (m_host.IsRoot) 3162 // new SL always returns object mass
2891 { 3163// if (m_host.IsRoot)
3164// {
2892 return m_host.ParentGroup.GetMass(); 3165 return m_host.ParentGroup.GetMass();
2893 } 3166// }
2894 else 3167// else
2895 { 3168// {
2896 return m_host.GetMass(); 3169// return m_host.GetMass();
2897 } 3170// }
2898 } 3171 }
2899 } 3172 }
2900 3173
3174
3175 public LSL_Float llGetMassMKS()
3176 {
3177 return 100f * llGetMass();
3178 }
3179
2901 public void llCollisionFilter(string name, string id, int accept) 3180 public void llCollisionFilter(string name, string id, int accept)
2902 { 3181 {
2903 m_host.AddScriptLPS(1); 3182 m_host.AddScriptLPS(1);
@@ -2972,7 +3251,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2972 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3251 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2973 3252
2974 if (attachmentsModule != null) 3253 if (attachmentsModule != null)
2975 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3254 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
2976 else 3255 else
2977 return false; 3256 return false;
2978 } 3257 }
@@ -3005,9 +3284,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3005 { 3284 {
3006 m_host.AddScriptLPS(1); 3285 m_host.AddScriptLPS(1);
3007 3286
3008// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3009// return;
3010
3011 if (m_item.PermsGranter != m_host.OwnerID) 3287 if (m_item.PermsGranter != m_host.OwnerID)
3012 return; 3288 return;
3013 3289
@@ -3050,6 +3326,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3050 3326
3051 public void llInstantMessage(string user, string message) 3327 public void llInstantMessage(string user, string message)
3052 { 3328 {
3329 UUID result;
3330 if (!UUID.TryParse(user, out result))
3331 {
3332 ShoutError("An invalid key was passed to llInstantMessage");
3333 ScriptSleep(2000);
3334 return;
3335 }
3336
3337
3053 m_host.AddScriptLPS(1); 3338 m_host.AddScriptLPS(1);
3054 3339
3055 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3340 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3064,14 +3349,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3064 UUID friendTransactionID = UUID.Random(); 3349 UUID friendTransactionID = UUID.Random();
3065 3350
3066 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3351 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3067 3352
3068 GridInstantMessage msg = new GridInstantMessage(); 3353 GridInstantMessage msg = new GridInstantMessage();
3069 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3354 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3070 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3355 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3071 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3356 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3072// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3357// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3073// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3358// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3074 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3359// DateTime dt = DateTime.UtcNow;
3360//
3361// // Ticks from UtcNow, but make it look like local. Evil, huh?
3362// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3363//
3364// try
3365// {
3366// // Convert that to the PST timezone
3367// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3368// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3369// }
3370// catch
3371// {
3372// // No logging here, as it could be VERY spammy
3373// }
3374//
3375// // And make it look local again to fool the unix time util
3376// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3377
3378 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3379
3075 //if (client != null) 3380 //if (client != null)
3076 //{ 3381 //{
3077 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3382 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3085,12 +3390,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3085 msg.message = message.Substring(0, 1024); 3390 msg.message = message.Substring(0, 1024);
3086 else 3391 else
3087 msg.message = message; 3392 msg.message = message;
3088 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3393 msg.dialog = (byte)19; // MessageFromObject
3089 msg.fromGroup = false;// fromGroup; 3394 msg.fromGroup = false;// fromGroup;
3090 msg.offline = (byte)0; //offline; 3395 msg.offline = (byte)0; //offline;
3091 msg.ParentEstateID = 0; //ParentEstateID; 3396 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3092 msg.Position = new Vector3(m_host.AbsolutePosition); 3397 msg.Position = new Vector3(m_host.AbsolutePosition);
3093 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3398 msg.RegionID = World.RegionInfo.RegionID.Guid;
3094 msg.binaryBucket 3399 msg.binaryBucket
3095 = Util.StringToBytes256( 3400 = Util.StringToBytes256(
3096 "{0}/{1}/{2}/{3}", 3401 "{0}/{1}/{2}/{3}",
@@ -3118,7 +3423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3118 } 3423 }
3119 3424
3120 emailModule.SendEmail(m_host.UUID, address, subject, message); 3425 emailModule.SendEmail(m_host.UUID, address, subject, message);
3121 llSleep(EMAIL_PAUSE_TIME); 3426 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3122 } 3427 }
3123 3428
3124 public void llGetNextEmail(string address, string subject) 3429 public void llGetNextEmail(string address, string subject)
@@ -3362,15 +3667,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3362 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3667 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3363 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3668 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3364 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3669 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3670 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3365 ScriptBaseClass.PERMISSION_ATTACH; 3671 ScriptBaseClass.PERMISSION_ATTACH;
3366 3672
3367 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3673 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3368 { 3674 {
3369 lock (m_host.TaskInventory) 3675 m_host.TaskInventory.LockItemsForWrite(true);
3370 { 3676 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3371 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3677 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3372 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3678 m_host.TaskInventory.LockItemsForWrite(false);
3373 }
3374 3679
3375 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3680 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3376 "run_time_permissions", new Object[] { 3681 "run_time_permissions", new Object[] {
@@ -3380,28 +3685,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3380 return; 3685 return;
3381 } 3686 }
3382 } 3687 }
3383 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3688 else
3384 { 3689 {
3385 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3690 bool sitting = false;
3386 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3691 if (m_host.SitTargetAvatar == agentID)
3387 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3692 {
3388 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3693 sitting = true;
3389 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3694 }
3695 else
3696 {
3697 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3698 {
3699 if (p.SitTargetAvatar == agentID)
3700 sitting = true;
3701 }
3702 }
3390 3703
3391 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3704 if (sitting)
3392 { 3705 {
3393 lock (m_host.TaskInventory) 3706 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3707 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3708 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3709 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3710 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3711
3712 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3394 { 3713 {
3714 m_host.TaskInventory.LockItemsForWrite(true);
3395 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3715 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3396 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3716 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3397 } 3717 m_host.TaskInventory.LockItemsForWrite(false);
3398 3718
3399 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3719 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3400 "run_time_permissions", new Object[] { 3720 "run_time_permissions", new Object[] {
3401 new LSL_Integer(perm) }, 3721 new LSL_Integer(perm) },
3402 new DetectParams[0])); 3722 new DetectParams[0]));
3403 3723
3404 return; 3724 return;
3725 }
3405 } 3726 }
3406 } 3727 }
3407 3728
@@ -3438,11 +3759,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3438 3759
3439 if (!m_waitingForScriptAnswer) 3760 if (!m_waitingForScriptAnswer)
3440 { 3761 {
3441 lock (m_host.TaskInventory) 3762 m_host.TaskInventory.LockItemsForWrite(true);
3442 { 3763 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3443 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3764 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3444 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3765 m_host.TaskInventory.LockItemsForWrite(false);
3445 }
3446 3766
3447 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3767 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3448 m_waitingForScriptAnswer=true; 3768 m_waitingForScriptAnswer=true;
@@ -3471,14 +3791,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3471 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3791 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3472 llReleaseControls(); 3792 llReleaseControls();
3473 3793
3474 lock (m_host.TaskInventory) 3794 m_host.TaskInventory.LockItemsForWrite(true);
3475 { 3795 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3476 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3796 m_host.TaskInventory.LockItemsForWrite(false);
3477 } 3797
3478 3798 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3479 m_ScriptEngine.PostScriptEvent( 3799 "run_time_permissions", new Object[] {
3480 m_item.ItemID, 3800 new LSL_Integer(answer) },
3481 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3801 new DetectParams[0]));
3482 } 3802 }
3483 3803
3484 public LSL_String llGetPermissionsKey() 3804 public LSL_String llGetPermissionsKey()
@@ -3517,14 +3837,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3517 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3837 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3518 { 3838 {
3519 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3839 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3520 3840 if (parts.Count > 0)
3521 foreach (SceneObjectPart part in parts) 3841 {
3522 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3842 try
3843 {
3844 parts[0].ParentGroup.areUpdatesSuspended = true;
3845 foreach (SceneObjectPart part in parts)
3846 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3847 }
3848 finally
3849 {
3850 parts[0].ParentGroup.areUpdatesSuspended = false;
3851 }
3852 }
3523 } 3853 }
3524 3854
3525 public void llCreateLink(string target, int parent) 3855 public void llCreateLink(string target, int parent)
3526 { 3856 {
3527 m_host.AddScriptLPS(1); 3857 m_host.AddScriptLPS(1);
3858
3528 UUID targetID; 3859 UUID targetID;
3529 3860
3530 if (!UUID.TryParse(target, out targetID)) 3861 if (!UUID.TryParse(target, out targetID))
@@ -3630,10 +3961,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3630 // Restructuring Multiple Prims. 3961 // Restructuring Multiple Prims.
3631 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 3962 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3632 parts.Remove(parentPrim.RootPart); 3963 parts.Remove(parentPrim.RootPart);
3633 foreach (SceneObjectPart part in parts) 3964 if (parts.Count > 0)
3634 { 3965 {
3635 parentPrim.DelinkFromGroup(part.LocalId, true); 3966 try
3967 {
3968 parts[0].ParentGroup.areUpdatesSuspended = true;
3969 foreach (SceneObjectPart part in parts)
3970 {
3971 parentPrim.DelinkFromGroup(part.LocalId, true);
3972 }
3973 }
3974 finally
3975 {
3976 parts[0].ParentGroup.areUpdatesSuspended = false;
3977 }
3636 } 3978 }
3979
3637 parentPrim.HasGroupChanged = true; 3980 parentPrim.HasGroupChanged = true;
3638 parentPrim.ScheduleGroupForFullUpdate(); 3981 parentPrim.ScheduleGroupForFullUpdate();
3639 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 3982 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3642,12 +3985,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3642 { 3985 {
3643 SceneObjectPart newRoot = parts[0]; 3986 SceneObjectPart newRoot = parts[0];
3644 parts.Remove(newRoot); 3987 parts.Remove(newRoot);
3645 foreach (SceneObjectPart part in parts) 3988
3989 try
3646 { 3990 {
3647 // Required for linking 3991 parts[0].ParentGroup.areUpdatesSuspended = true;
3648 part.ClearUpdateSchedule(); 3992 foreach (SceneObjectPart part in parts)
3649 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 3993 {
3994 part.ClearUpdateSchedule();
3995 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
3996 }
3650 } 3997 }
3998 finally
3999 {
4000 parts[0].ParentGroup.areUpdatesSuspended = false;
4001 }
4002
4003
3651 newRoot.ParentGroup.HasGroupChanged = true; 4004 newRoot.ParentGroup.HasGroupChanged = true;
3652 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4005 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3653 } 4006 }
@@ -3667,6 +4020,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3667 public void llBreakAllLinks() 4020 public void llBreakAllLinks()
3668 { 4021 {
3669 m_host.AddScriptLPS(1); 4022 m_host.AddScriptLPS(1);
4023
4024 TaskInventoryItem item = m_item;
4025
4026 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4027 && !m_automaticLinkPermission)
4028 {
4029 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4030 return;
4031 }
4032
3670 SceneObjectGroup parentPrim = m_host.ParentGroup; 4033 SceneObjectGroup parentPrim = m_host.ParentGroup;
3671 if (parentPrim.AttachmentPoint != 0) 4034 if (parentPrim.AttachmentPoint != 0)
3672 return; // Fail silently if attached 4035 return; // Fail silently if attached
@@ -3686,25 +4049,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3686 public LSL_String llGetLinkKey(int linknum) 4049 public LSL_String llGetLinkKey(int linknum)
3687 { 4050 {
3688 m_host.AddScriptLPS(1); 4051 m_host.AddScriptLPS(1);
3689 List<UUID> keytable = new List<UUID>();
3690 // parse for sitting avatare-uuids
3691 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3692 {
3693 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3694 keytable.Add(presence.UUID);
3695 });
3696
3697 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3698 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3699 {
3700 return keytable[totalprims - linknum].ToString();
3701 }
3702
3703 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3704 {
3705 return m_host.UUID.ToString();
3706 }
3707
3708 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4052 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3709 if (part != null) 4053 if (part != null)
3710 { 4054 {
@@ -3712,6 +4056,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3712 } 4056 }
3713 else 4057 else
3714 { 4058 {
4059 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4060 {
4061 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4062
4063 if (linknum < 0)
4064 return UUID.Zero.ToString();
4065
4066 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4067 if (avatars.Count > linknum)
4068 {
4069 return avatars[linknum].UUID.ToString();
4070 }
4071 }
3715 return UUID.Zero.ToString(); 4072 return UUID.Zero.ToString();
3716 } 4073 }
3717 } 4074 }
@@ -3811,17 +4168,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3811 m_host.AddScriptLPS(1); 4168 m_host.AddScriptLPS(1);
3812 int count = 0; 4169 int count = 0;
3813 4170
3814 lock (m_host.TaskInventory) 4171 m_host.TaskInventory.LockItemsForRead(true);
4172 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3815 { 4173 {
3816 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4174 if (inv.Value.Type == type || type == -1)
3817 { 4175 {
3818 if (inv.Value.Type == type || type == -1) 4176 count = count + 1;
3819 {
3820 count = count + 1;
3821 }
3822 } 4177 }
3823 } 4178 }
3824 4179
4180 m_host.TaskInventory.LockItemsForRead(false);
3825 return count; 4181 return count;
3826 } 4182 }
3827 4183
@@ -3830,16 +4186,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3830 m_host.AddScriptLPS(1); 4186 m_host.AddScriptLPS(1);
3831 ArrayList keys = new ArrayList(); 4187 ArrayList keys = new ArrayList();
3832 4188
3833 lock (m_host.TaskInventory) 4189 m_host.TaskInventory.LockItemsForRead(true);
4190 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3834 { 4191 {
3835 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4192 if (inv.Value.Type == type || type == -1)
3836 { 4193 {
3837 if (inv.Value.Type == type || type == -1) 4194 keys.Add(inv.Value.Name);
3838 {
3839 keys.Add(inv.Value.Name);
3840 }
3841 } 4195 }
3842 } 4196 }
4197 m_host.TaskInventory.LockItemsForRead(false);
3843 4198
3844 if (keys.Count == 0) 4199 if (keys.Count == 0)
3845 { 4200 {
@@ -3876,25 +4231,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3876 } 4231 }
3877 4232
3878 // move the first object found with this inventory name 4233 // move the first object found with this inventory name
3879 lock (m_host.TaskInventory) 4234 m_host.TaskInventory.LockItemsForRead(true);
4235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3880 { 4236 {
3881 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4237 if (inv.Value.Name == inventory)
3882 { 4238 {
3883 if (inv.Value.Name == inventory) 4239 found = true;
3884 { 4240 objId = inv.Key;
3885 found = true; 4241 assetType = inv.Value.Type;
3886 objId = inv.Key; 4242 objName = inv.Value.Name;
3887 assetType = inv.Value.Type; 4243 break;
3888 objName = inv.Value.Name;
3889 break;
3890 }
3891 } 4244 }
3892 } 4245 }
4246 m_host.TaskInventory.LockItemsForRead(false);
3893 4247
3894 if (!found) 4248 if (!found)
3895 { 4249 {
3896 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4250 llSay(0, String.Format("Could not find object '{0}'", inventory));
3897 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4251 return;
4252// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3898 } 4253 }
3899 4254
3900 // check if destination is an object 4255 // check if destination is an object
@@ -3920,48 +4275,68 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3920 return; 4275 return;
3921 } 4276 }
3922 } 4277 }
4278
3923 // destination is an avatar 4279 // destination is an avatar
3924 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4280 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3925 4281
3926 if (agentItem == null) 4282 if (agentItem == null)
3927 return; 4283 return;
3928 4284
3929 byte[] bucket = new byte[17]; 4285 byte[] bucket = new byte[1];
3930 bucket[0] = (byte)assetType; 4286 bucket[0] = (byte)assetType;
3931 byte[] objBytes = agentItem.ID.GetBytes(); 4287 //byte[] objBytes = agentItem.ID.GetBytes();
3932 Array.Copy(objBytes, 0, bucket, 1, 16); 4288 //Array.Copy(objBytes, 0, bucket, 1, 16);
3933 4289
3934 GridInstantMessage msg = new GridInstantMessage(World, 4290 GridInstantMessage msg = new GridInstantMessage(World,
3935 m_host.UUID, m_host.Name+", an object owned by "+ 4291 m_host.OwnerID, m_host.Name, destId,
3936 resolveName(m_host.OwnerID)+",", destId,
3937 (byte)InstantMessageDialog.TaskInventoryOffered, 4292 (byte)InstantMessageDialog.TaskInventoryOffered,
3938 false, objName+"\n"+m_host.Name+" is located at "+ 4293 false, objName+". "+m_host.Name+" is located at "+
3939 World.RegionInfo.RegionName+" "+ 4294 World.RegionInfo.RegionName+" "+
3940 m_host.AbsolutePosition.ToString(), 4295 m_host.AbsolutePosition.ToString(),
3941 agentItem.ID, true, m_host.AbsolutePosition, 4296 agentItem.ID, true, m_host.AbsolutePosition,
3942 bucket); 4297 bucket);
3943 if (m_TransferModule != null) 4298
3944 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4299 ScenePresence sp;
4300
4301 if (World.TryGetScenePresence(destId, out sp))
4302 {
4303 sp.ControllingClient.SendInstantMessage(msg);
4304 }
4305 else
4306 {
4307 if (m_TransferModule != null)
4308 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4309 }
4310
4311 //This delay should only occur when giving inventory to avatars.
3945 ScriptSleep(3000); 4312 ScriptSleep(3000);
3946 } 4313 }
3947 } 4314 }
3948 4315
4316 [DebuggerNonUserCode]
3949 public void llRemoveInventory(string name) 4317 public void llRemoveInventory(string name)
3950 { 4318 {
3951 m_host.AddScriptLPS(1); 4319 m_host.AddScriptLPS(1);
3952 4320
3953 lock (m_host.TaskInventory) 4321 List<TaskInventoryItem> inv;
4322 try
3954 { 4323 {
3955 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4324 m_host.TaskInventory.LockItemsForRead(true);
4325 inv = new List<TaskInventoryItem>(m_host.TaskInventory.Values);
4326 }
4327 finally
4328 {
4329 m_host.TaskInventory.LockItemsForRead(false);
4330 }
4331 foreach (TaskInventoryItem item in inv)
4332 {
4333 if (item.Name == name)
3956 { 4334 {
3957 if (item.Name == name) 4335 if (item.ItemID == m_item.ItemID)
3958 { 4336 throw new ScriptDeleteException();
3959 if (item.ItemID == m_item.ItemID) 4337 else
3960 throw new ScriptDeleteException(); 4338 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3961 else 4339 return;
3962 m_host.Inventory.RemoveInventoryItem(item.ItemID);
3963 return;
3964 }
3965 } 4340 }
3966 } 4341 }
3967 } 4342 }
@@ -3996,115 +4371,122 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3996 { 4371 {
3997 m_host.AddScriptLPS(1); 4372 m_host.AddScriptLPS(1);
3998 4373
3999 UUID uuid = (UUID)id; 4374 UUID uuid;
4000 PresenceInfo pinfo = null; 4375 if (UUID.TryParse(id, out uuid))
4001 UserAccount account;
4002
4003 UserInfoCacheEntry ce;
4004 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4005 { 4376 {
4006 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4377 PresenceInfo pinfo = null;
4007 if (account == null) 4378 UserAccount account;
4379
4380 UserInfoCacheEntry ce;
4381 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4008 { 4382 {
4009 m_userInfoCache[uuid] = null; // Cache negative 4383 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4010 return UUID.Zero.ToString(); 4384 if (account == null)
4011 } 4385 {
4386 m_userInfoCache[uuid] = null; // Cache negative
4387 return UUID.Zero.ToString();
4388 }
4012 4389
4013 4390
4014 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4391 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4015 if (pinfos != null && pinfos.Length > 0) 4392 if (pinfos != null && pinfos.Length > 0)
4016 {
4017 foreach (PresenceInfo p in pinfos)
4018 { 4393 {
4019 if (p.RegionID != UUID.Zero) 4394 foreach (PresenceInfo p in pinfos)
4020 { 4395 {
4021 pinfo = p; 4396 if (p.RegionID != UUID.Zero)
4397 {
4398 pinfo = p;
4399 }
4022 } 4400 }
4023 } 4401 }
4024 }
4025 4402
4026 ce = new UserInfoCacheEntry(); 4403 ce = new UserInfoCacheEntry();
4027 ce.time = Util.EnvironmentTickCount(); 4404 ce.time = Util.EnvironmentTickCount();
4028 ce.account = account; 4405 ce.account = account;
4029 ce.pinfo = pinfo; 4406 ce.pinfo = pinfo;
4030 } 4407 m_userInfoCache[uuid] = ce;
4031 else 4408 }
4032 { 4409 else
4033 if (ce == null) 4410 {
4034 return UUID.Zero.ToString(); 4411 if (ce == null)
4412 return UUID.Zero.ToString();
4035 4413
4036 account = ce.account; 4414 account = ce.account;
4037 pinfo = ce.pinfo; 4415 pinfo = ce.pinfo;
4038 } 4416 }
4039 4417
4040 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4418 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4041 {
4042 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4043 if (pinfos != null && pinfos.Length > 0)
4044 { 4419 {
4045 foreach (PresenceInfo p in pinfos) 4420 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4421 if (pinfos != null && pinfos.Length > 0)
4046 { 4422 {
4047 if (p.RegionID != UUID.Zero) 4423 foreach (PresenceInfo p in pinfos)
4048 { 4424 {
4049 pinfo = p; 4425 if (p.RegionID != UUID.Zero)
4426 {
4427 pinfo = p;
4428 }
4050 } 4429 }
4051 } 4430 }
4052 } 4431 else
4053 else 4432 pinfo = null;
4054 pinfo = null;
4055 4433
4056 ce.time = Util.EnvironmentTickCount(); 4434 ce.time = Util.EnvironmentTickCount();
4057 ce.pinfo = pinfo; 4435 ce.pinfo = pinfo;
4058 } 4436 }
4059 4437
4060 string reply = String.Empty; 4438 string reply = String.Empty;
4061 4439
4062 switch (data) 4440 switch (data)
4063 { 4441 {
4064 case 1: // DATA_ONLINE (0|1) 4442 case 1: // DATA_ONLINE (0|1)
4065 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4443 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4066 reply = "1"; 4444 reply = "1";
4067 else 4445 else
4068 reply = "0"; 4446 reply = "0";
4069 break; 4447 break;
4070 case 2: // DATA_NAME (First Last) 4448 case 2: // DATA_NAME (First Last)
4071 reply = account.FirstName + " " + account.LastName; 4449 reply = account.FirstName + " " + account.LastName;
4072 break; 4450 break;
4073 case 3: // DATA_BORN (YYYY-MM-DD) 4451 case 3: // DATA_BORN (YYYY-MM-DD)
4074 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4452 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4075 born = born.AddSeconds(account.Created); 4453 born = born.AddSeconds(account.Created);
4076 reply = born.ToString("yyyy-MM-dd"); 4454 reply = born.ToString("yyyy-MM-dd");
4077 break; 4455 break;
4078 case 4: // DATA_RATING (0,0,0,0,0,0) 4456 case 4: // DATA_RATING (0,0,0,0,0,0)
4079 reply = "0,0,0,0,0,0"; 4457 reply = "0,0,0,0,0,0";
4080 break; 4458 break;
4081 case 7: // DATA_USERLEVEL (integer) 4459 case 8: // DATA_PAYINFO (0|1|2|3)
4082 reply = account.UserLevel.ToString(); 4460 reply = "0";
4083 break; 4461 break;
4084 case 8: // DATA_PAYINFO (0|1|2|3) 4462 default:
4085 reply = "0"; 4463 return UUID.Zero.ToString(); // Raise no event
4086 break; 4464 }
4087 default:
4088 return UUID.Zero.ToString(); // Raise no event
4089 }
4090 4465
4091 UUID rq = UUID.Random(); 4466 UUID rq = UUID.Random();
4092 4467
4093 UUID tid = AsyncCommands. 4468 UUID tid = AsyncCommands.
4094 DataserverPlugin.RegisterRequest(m_host.LocalId, 4469 DataserverPlugin.RegisterRequest(m_host.LocalId,
4095 m_item.ItemID, rq.ToString()); 4470 m_item.ItemID, rq.ToString());
4096 4471
4097 AsyncCommands. 4472 AsyncCommands.
4098 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4473 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4099 4474
4100 ScriptSleep(100); 4475 ScriptSleep(100);
4101 return tid.ToString(); 4476 return tid.ToString();
4477 }
4478 else
4479 {
4480 ShoutError("Invalid UUID passed to llRequestAgentData.");
4481 }
4482 return "";
4102 } 4483 }
4103 4484
4104 public LSL_String llRequestInventoryData(string name) 4485 public LSL_String llRequestInventoryData(string name)
4105 { 4486 {
4106 m_host.AddScriptLPS(1); 4487 m_host.AddScriptLPS(1);
4107 4488
4489 //Clone is thread safe
4108 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 4490 TaskInventoryDictionary itemDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
4109 4491
4110 foreach (TaskInventoryItem item in itemDictionary.Values) 4492 foreach (TaskInventoryItem item in itemDictionary.Values)
@@ -4156,13 +4538,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4156 if (UUID.TryParse(agent, out agentId)) 4538 if (UUID.TryParse(agent, out agentId))
4157 { 4539 {
4158 ScenePresence presence = World.GetScenePresence(agentId); 4540 ScenePresence presence = World.GetScenePresence(agentId);
4159 if (presence != null) 4541 if (presence != null && presence.PresenceType != PresenceType.Npc)
4160 { 4542 {
4543 // agent must not be a god
4544 if (presence.UserLevel >= 200) return;
4545
4161 // agent must be over the owners land 4546 // agent must be over the owners land
4162 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4547 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4163 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4548 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4164 { 4549 {
4165 World.TeleportClientHome(agentId, presence.ControllingClient); 4550 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4551 {
4552 // They can't be teleported home for some reason
4553 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4554 if (regionInfo != null)
4555 {
4556 World.RequestTeleportLocation(
4557 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4558 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4559 }
4560 }
4166 } 4561 }
4167 } 4562 }
4168 } 4563 }
@@ -4274,7 +4669,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4274 UUID av = new UUID(); 4669 UUID av = new UUID();
4275 if (!UUID.TryParse(agent,out av)) 4670 if (!UUID.TryParse(agent,out av))
4276 { 4671 {
4277 LSLError("First parameter to llDialog needs to be a key"); 4672 //LSLError("First parameter to llDialog needs to be a key");
4278 return; 4673 return;
4279 } 4674 }
4280 4675
@@ -4306,25 +4701,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4306 public void llCollisionSound(string impact_sound, double impact_volume) 4701 public void llCollisionSound(string impact_sound, double impact_volume)
4307 { 4702 {
4308 m_host.AddScriptLPS(1); 4703 m_host.AddScriptLPS(1);
4309 4704
4705 if(impact_sound == "")
4706 {
4707 m_host.CollisionSoundVolume = (float)impact_volume;
4708 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4709 m_host.CollisionSoundType = 0;
4710 return;
4711 }
4310 // TODO: Parameter check logic required. 4712 // TODO: Parameter check logic required.
4311 UUID soundId = UUID.Zero; 4713 UUID soundId = UUID.Zero;
4312 if (!UUID.TryParse(impact_sound, out soundId)) 4714 if (!UUID.TryParse(impact_sound, out soundId))
4313 { 4715 {
4314 lock (m_host.TaskInventory) 4716 m_host.TaskInventory.LockItemsForRead(true);
4717 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
4315 { 4718 {
4316 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 4719 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound)
4317 { 4720 {
4318 if (item.Type == (int)AssetType.Sound && item.Name == impact_sound) 4721 soundId = item.AssetID;
4319 { 4722 break;
4320 soundId = item.AssetID;
4321 break;
4322 }
4323 } 4723 }
4324 } 4724 }
4725 m_host.TaskInventory.LockItemsForRead(false);
4325 } 4726 }
4326 m_host.CollisionSound = soundId;
4327 m_host.CollisionSoundVolume = (float)impact_volume; 4727 m_host.CollisionSoundVolume = (float)impact_volume;
4728 m_host.CollisionSound = soundId;
4729 m_host.CollisionSoundType = 1;
4328 } 4730 }
4329 4731
4330 public LSL_String llGetAnimation(string id) 4732 public LSL_String llGetAnimation(string id)
@@ -4338,14 +4740,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4338 4740
4339 if (m_host.RegionHandle == presence.RegionHandle) 4741 if (m_host.RegionHandle == presence.RegionHandle)
4340 { 4742 {
4341 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4342
4343 if (presence != null) 4743 if (presence != null)
4344 { 4744 {
4345 AnimationSet currentAnims = presence.Animator.Animations; 4745 if (presence.SitGround)
4346 string currentAnimationState = String.Empty; 4746 return "Sitting on Ground";
4347 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4747 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4348 return currentAnimationState; 4748 return "Sitting";
4749
4750 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4751 string lslMovementAnimation;
4752
4753 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4754 return lslMovementAnimation;
4349 } 4755 }
4350 } 4756 }
4351 4757
@@ -4361,6 +4767,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4361 UUID partItemID; 4767 UUID partItemID;
4362 foreach (SceneObjectPart part in parts) 4768 foreach (SceneObjectPart part in parts)
4363 { 4769 {
4770 //Clone is thread safe
4364 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone(); 4771 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)part.TaskInventory.Clone();
4365 4772
4366 foreach (TaskInventoryItem item in itemsDictionary.Values) 4773 foreach (TaskInventoryItem item in itemsDictionary.Values)
@@ -4494,7 +4901,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4494 { 4901 {
4495 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4902 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4496 float distance_term = distance * distance * distance; // Script Energy 4903 float distance_term = distance * distance * distance; // Script Energy
4497 float pusher_mass = m_host.GetMass(); 4904 // use total object mass and not part
4905 float pusher_mass = m_host.ParentGroup.GetMass();
4498 4906
4499 float PUSH_ATTENUATION_DISTANCE = 17f; 4907 float PUSH_ATTENUATION_DISTANCE = 17f;
4500 float PUSH_ATTENUATION_SCALE = 5f; 4908 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4733,23 +5141,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4733 { 5141 {
4734 m_host.AddScriptLPS(1); 5142 m_host.AddScriptLPS(1);
4735 5143
4736 lock (m_host.TaskInventory) 5144 m_host.TaskInventory.LockItemsForRead(true);
5145 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
4737 { 5146 {
4738 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 5147 if (inv.Value.Name == name)
4739 { 5148 {
4740 if (inv.Value.Name == name) 5149 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify))
4741 { 5150 {
4742 if ((inv.Value.CurrentPermissions & (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) == (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify)) 5151 m_host.TaskInventory.LockItemsForRead(false);
4743 { 5152 return inv.Value.AssetID.ToString();
4744 return inv.Value.AssetID.ToString(); 5153 }
4745 } 5154 else
4746 else 5155 {
4747 { 5156 m_host.TaskInventory.LockItemsForRead(false);
4748 return UUID.Zero.ToString(); 5157 return UUID.Zero.ToString();
4749 }
4750 } 5158 }
4751 } 5159 }
4752 } 5160 }
5161 m_host.TaskInventory.LockItemsForRead(false);
4753 5162
4754 return UUID.Zero.ToString(); 5163 return UUID.Zero.ToString();
4755 } 5164 }
@@ -4883,7 +5292,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4883 public LSL_Vector llGetCenterOfMass() 5292 public LSL_Vector llGetCenterOfMass()
4884 { 5293 {
4885 m_host.AddScriptLPS(1); 5294 m_host.AddScriptLPS(1);
4886 Vector3 center = m_host.GetGeometricCenter(); 5295 Vector3 center = m_host.GetCenterOfMass();
4887 return new LSL_Vector(center.X,center.Y,center.Z); 5296 return new LSL_Vector(center.X,center.Y,center.Z);
4888 } 5297 }
4889 5298
@@ -4902,14 +5311,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4902 { 5311 {
4903 m_host.AddScriptLPS(1); 5312 m_host.AddScriptLPS(1);
4904 5313
4905 if (src == null) 5314 return src.Length;
4906 {
4907 return 0;
4908 }
4909 else
4910 {
4911 return src.Length;
4912 }
4913 } 5315 }
4914 5316
4915 public LSL_Integer llList2Integer(LSL_List src, int index) 5317 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4955,7 +5357,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4955 else if (src.Data[index] is LSL_Float) 5357 else if (src.Data[index] is LSL_Float)
4956 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5358 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4957 else if (src.Data[index] is LSL_String) 5359 else if (src.Data[index] is LSL_String)
4958 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5360 {
5361 string str = ((LSL_String) src.Data[index]).m_string;
5362 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5363 if (m != Match.Empty)
5364 {
5365 str = m.Value;
5366 double d = 0.0;
5367 if (!Double.TryParse(str, out d))
5368 return 0.0;
5369
5370 return d;
5371 }
5372 return 0.0;
5373 }
4959 return Convert.ToDouble(src.Data[index]); 5374 return Convert.ToDouble(src.Data[index]);
4960 } 5375 }
4961 catch (FormatException) 5376 catch (FormatException)
@@ -5228,7 +5643,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5228 } 5643 }
5229 } 5644 }
5230 } 5645 }
5231 else { 5646 else
5647 {
5232 object[] array = new object[src.Length]; 5648 object[] array = new object[src.Length];
5233 Array.Copy(src.Data, 0, array, 0, src.Length); 5649 Array.Copy(src.Data, 0, array, 0, src.Length);
5234 result = new LSL_List(array); 5650 result = new LSL_List(array);
@@ -5335,7 +5751,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5335 public LSL_Integer llGetRegionAgentCount() 5751 public LSL_Integer llGetRegionAgentCount()
5336 { 5752 {
5337 m_host.AddScriptLPS(1); 5753 m_host.AddScriptLPS(1);
5338 return new LSL_Integer(World.GetRootAgentCount()); 5754
5755 int count = 0;
5756 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5757 count++;
5758 });
5759
5760 return new LSL_Integer(count);
5339 } 5761 }
5340 5762
5341 public LSL_Vector llGetRegionCorner() 5763 public LSL_Vector llGetRegionCorner()
@@ -5615,6 +6037,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5615 flags |= ScriptBaseClass.AGENT_SITTING; 6037 flags |= ScriptBaseClass.AGENT_SITTING;
5616 } 6038 }
5617 6039
6040 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6041 {
6042 flags |= ScriptBaseClass.AGENT_MALE;
6043 }
6044
5618 return flags; 6045 return flags;
5619 } 6046 }
5620 6047
@@ -5761,10 +6188,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5761 m_host.AddScriptLPS(1); 6188 m_host.AddScriptLPS(1);
5762 6189
5763 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6190 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5764 6191 if (parts.Count > 0)
5765 foreach (var part in parts)
5766 { 6192 {
5767 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6193 try
6194 {
6195 parts[0].ParentGroup.areUpdatesSuspended = true;
6196 foreach (var part in parts)
6197 {
6198 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6199 }
6200 }
6201 finally
6202 {
6203 parts[0].ParentGroup.areUpdatesSuspended = false;
6204 }
5768 } 6205 }
5769 } 6206 }
5770 6207
@@ -5816,13 +6253,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5816 6253
5817 if (m_host.OwnerID == land.LandData.OwnerID) 6254 if (m_host.OwnerID == land.LandData.OwnerID)
5818 { 6255 {
5819 World.TeleportClientHome(agentID, presence.ControllingClient); 6256 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6257 presence.TeleportWithMomentum(pos, null);
6258 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5820 } 6259 }
5821 } 6260 }
5822 } 6261 }
5823 ScriptSleep(5000); 6262 ScriptSleep(5000);
5824 } 6263 }
5825 6264
6265 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6266 {
6267 return ParseString2List(str, separators, in_spacers, false);
6268 }
6269
5826 public LSL_Integer llOverMyLand(string id) 6270 public LSL_Integer llOverMyLand(string id)
5827 { 6271 {
5828 m_host.AddScriptLPS(1); 6272 m_host.AddScriptLPS(1);
@@ -5887,8 +6331,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5887 UUID agentId = new UUID(); 6331 UUID agentId = new UUID();
5888 if (!UUID.TryParse(agent, out agentId)) 6332 if (!UUID.TryParse(agent, out agentId))
5889 return new LSL_Integer(0); 6333 return new LSL_Integer(0);
6334 if (agentId == m_host.GroupID)
6335 return new LSL_Integer(1);
5890 ScenePresence presence = World.GetScenePresence(agentId); 6336 ScenePresence presence = World.GetScenePresence(agentId);
5891 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6337 if (presence == null || presence.IsChildAgent) // Return false for child agents
5892 return new LSL_Integer(0); 6338 return new LSL_Integer(0);
5893 IClientAPI client = presence.ControllingClient; 6339 IClientAPI client = presence.ControllingClient;
5894 if (m_host.GroupID == client.ActiveGroupId) 6340 if (m_host.GroupID == client.ActiveGroupId)
@@ -6023,7 +6469,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6023 return m_host.ParentGroup.AttachmentPoint; 6469 return m_host.ParentGroup.AttachmentPoint;
6024 } 6470 }
6025 6471
6026 public LSL_Integer llGetFreeMemory() 6472 public virtual LSL_Integer llGetFreeMemory()
6027 { 6473 {
6028 m_host.AddScriptLPS(1); 6474 m_host.AddScriptLPS(1);
6029 // Make scripts designed for LSO happy 6475 // Make scripts designed for LSO happy
@@ -6140,7 +6586,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6140 SetParticleSystem(m_host, rules); 6586 SetParticleSystem(m_host, rules);
6141 } 6587 }
6142 6588
6143 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6589 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6590 {
6144 6591
6145 6592
6146 if (rules.Length == 0) 6593 if (rules.Length == 0)
@@ -6334,14 +6781,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6334 6781
6335 protected UUID GetTaskInventoryItem(string name) 6782 protected UUID GetTaskInventoryItem(string name)
6336 { 6783 {
6337 lock (m_host.TaskInventory) 6784 m_host.TaskInventory.LockItemsForRead(true);
6785 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6338 { 6786 {
6339 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 6787 if (inv.Value.Name == name)
6340 { 6788 {
6341 if (inv.Value.Name == name) 6789 m_host.TaskInventory.LockItemsForRead(false);
6342 return inv.Key; 6790 return inv.Key;
6343 } 6791 }
6344 } 6792 }
6793 m_host.TaskInventory.LockItemsForRead(false);
6345 6794
6346 return UUID.Zero; 6795 return UUID.Zero;
6347 } 6796 }
@@ -6379,16 +6828,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6379 if (folderID == UUID.Zero) 6828 if (folderID == UUID.Zero)
6380 return; 6829 return;
6381 6830
6382 byte[] bucket = new byte[17]; 6831 byte[] bucket = new byte[1];
6383 bucket[0] = (byte)AssetType.Folder; 6832 bucket[0] = (byte)AssetType.Folder;
6384 byte[] objBytes = folderID.GetBytes(); 6833 //byte[] objBytes = folderID.GetBytes();
6385 Array.Copy(objBytes, 0, bucket, 1, 16); 6834 //Array.Copy(objBytes, 0, bucket, 1, 16);
6386 6835
6387 GridInstantMessage msg = new GridInstantMessage(World, 6836 GridInstantMessage msg = new GridInstantMessage(World,
6388 m_host.UUID, m_host.Name+", an object owned by "+ 6837 m_host.OwnerID, m_host.Name, destID,
6389 resolveName(m_host.OwnerID)+",", destID, 6838 (byte)InstantMessageDialog.TaskInventoryOffered,
6390 (byte)InstantMessageDialog.InventoryOffered, 6839 false, category+". "+m_host.Name+" is located at "+
6391 false, category+"\n"+m_host.Name+" is located at "+
6392 World.RegionInfo.RegionName+" "+ 6840 World.RegionInfo.RegionName+" "+
6393 m_host.AbsolutePosition.ToString(), 6841 m_host.AbsolutePosition.ToString(),
6394 folderID, true, m_host.AbsolutePosition, 6842 folderID, true, m_host.AbsolutePosition,
@@ -6469,7 +6917,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6469 { 6917 {
6470 // LSL quaternions can normalize to 0, normal Quaternions can't. 6918 // LSL quaternions can normalize to 0, normal Quaternions can't.
6471 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6919 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6472 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6920 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6473 6921
6474 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6922 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6475 part.SitTargetOrientation = Rot2Quaternion(rot); 6923 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6626,13 +7074,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6626 UUID av = new UUID(); 7074 UUID av = new UUID();
6627 if (!UUID.TryParse(avatar,out av)) 7075 if (!UUID.TryParse(avatar,out av))
6628 { 7076 {
6629 LSLError("First parameter to llDialog needs to be a key"); 7077 //LSLError("First parameter to llDialog needs to be a key");
6630 return; 7078 return;
6631 } 7079 }
6632 if (buttons.Length < 1) 7080 if (buttons.Length < 1)
6633 { 7081 {
6634 LSLError("No less than 1 button can be shown"); 7082 buttons.Add("OK");
6635 return;
6636 } 7083 }
6637 if (buttons.Length > 12) 7084 if (buttons.Length > 12)
6638 { 7085 {
@@ -6649,7 +7096,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6649 } 7096 }
6650 if (buttons.Data[i].ToString().Length > 24) 7097 if (buttons.Data[i].ToString().Length > 24)
6651 { 7098 {
6652 LSLError("button label cannot be longer than 24 characters"); 7099 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6653 return; 7100 return;
6654 } 7101 }
6655 buts[i] = buttons.Data[i].ToString(); 7102 buts[i] = buttons.Data[i].ToString();
@@ -6708,22 +7155,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6708 } 7155 }
6709 7156
6710 // copy the first script found with this inventory name 7157 // copy the first script found with this inventory name
6711 lock (m_host.TaskInventory) 7158 TaskInventoryItem scriptItem = null;
7159 m_host.TaskInventory.LockItemsForRead(true);
7160 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
6712 { 7161 {
6713 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 7162 if (inv.Value.Name == name)
6714 { 7163 {
6715 if (inv.Value.Name == name) 7164 // make sure the object is a script
7165 if (10 == inv.Value.Type)
6716 { 7166 {
6717 // make sure the object is a script 7167 found = true;
6718 if (10 == inv.Value.Type) 7168 srcId = inv.Key;
6719 { 7169 scriptItem = inv.Value;
6720 found = true; 7170 break;
6721 srcId = inv.Key;
6722 break;
6723 }
6724 } 7171 }
6725 } 7172 }
6726 } 7173 }
7174 m_host.TaskInventory.LockItemsForRead(false);
6727 7175
6728 if (!found) 7176 if (!found)
6729 { 7177 {
@@ -6731,9 +7179,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6731 return; 7179 return;
6732 } 7180 }
6733 7181
6734 // the rest of the permission checks are done in RezScript, so check the pin there as well 7182 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6735 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param); 7183 if (dest != null)
7184 {
7185 if ((scriptItem.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7186 {
7187 // the rest of the permission checks are done in RezScript, so check the pin there as well
7188 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6736 7189
7190 if ((scriptItem.BasePermissions & (uint)PermissionMask.Copy) == 0)
7191 m_host.Inventory.RemoveInventoryItem(srcId);
7192 }
7193 }
6737 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7194 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6738 ScriptSleep(3000); 7195 ScriptSleep(3000);
6739 } 7196 }
@@ -6796,19 +7253,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6796 public LSL_String llMD5String(string src, int nonce) 7253 public LSL_String llMD5String(string src, int nonce)
6797 { 7254 {
6798 m_host.AddScriptLPS(1); 7255 m_host.AddScriptLPS(1);
6799 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7256 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6800 } 7257 }
6801 7258
6802 public LSL_String llSHA1String(string src) 7259 public LSL_String llSHA1String(string src)
6803 { 7260 {
6804 m_host.AddScriptLPS(1); 7261 m_host.AddScriptLPS(1);
6805 return Util.SHA1Hash(src).ToLower(); 7262 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6806 } 7263 }
6807 7264
6808 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7265 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6809 { 7266 {
6810 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7267 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6811 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7268 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7269 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7270 return shapeBlock;
6812 7271
6813 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7272 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6814 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7273 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6913,6 +7372,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6913 // Prim type box, cylinder and prism. 7372 // Prim type box, cylinder and prism.
6914 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) 7373 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)
6915 { 7374 {
7375 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7376 return;
7377
6916 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7378 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6917 ObjectShapePacket.ObjectDataBlock shapeBlock; 7379 ObjectShapePacket.ObjectDataBlock shapeBlock;
6918 7380
@@ -6966,6 +7428,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6966 // Prim type sphere. 7428 // Prim type sphere.
6967 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7429 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6968 { 7430 {
7431 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7432 return;
7433
6969 ObjectShapePacket.ObjectDataBlock shapeBlock; 7434 ObjectShapePacket.ObjectDataBlock shapeBlock;
6970 7435
6971 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7436 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7007,6 +7472,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7007 // Prim type torus, tube and ring. 7472 // Prim type torus, tube and ring.
7008 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) 7473 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)
7009 { 7474 {
7475 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7476 return;
7477
7010 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.
7011 ObjectShapePacket.ObjectDataBlock shapeBlock; 7479 ObjectShapePacket.ObjectDataBlock shapeBlock;
7012 7480
@@ -7142,6 +7610,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7142 // Prim type sculpt. 7610 // Prim type sculpt.
7143 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7611 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7144 { 7612 {
7613 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7614 return;
7615
7145 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7616 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7146 UUID sculptId; 7617 UUID sculptId;
7147 7618
@@ -7166,7 +7637,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7166 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7637 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7167 { 7638 {
7168 // default 7639 // default
7169 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7640 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7170 } 7641 }
7171 7642
7172 part.Shape.SetSculptProperties((byte)type, sculptId); 7643 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7182,34 +7653,311 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7182 ScriptSleep(200); 7653 ScriptSleep(200);
7183 } 7654 }
7184 7655
7185 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7656 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7186 { 7657 {
7187 m_host.AddScriptLPS(1); 7658 m_host.AddScriptLPS(1);
7188 7659
7189 setLinkPrimParams(linknumber, rules); 7660 setLinkPrimParams(linknumber, rules);
7661 }
7662
7663 private void setLinkPrimParams(int linknumber, LSL_List rules)
7664 {
7665 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7666 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7667 if (parts.Count>0)
7668 {
7669 try
7670 {
7671 parts[0].ParentGroup.areUpdatesSuspended = true;
7672 foreach (SceneObjectPart part in parts)
7673 SetPrimParams(part, rules);
7674 }
7675 finally
7676 {
7677 parts[0].ParentGroup.areUpdatesSuspended = false;
7678 }
7679 }
7680 if (avatars.Count > 0)
7681 {
7682 foreach (ScenePresence avatar in avatars)
7683 SetPrimParams(avatar, rules);
7684 }
7685 }
7686
7687 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7688 float material_density, float material_friction,
7689 float material_restitution, float material_gravity_modifier)
7690 {
7691 ExtraPhysicsData physdata = new ExtraPhysicsData();
7692 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7693 physdata.Density = part.Density;
7694 physdata.Friction = part.Friction;
7695 physdata.Bounce = part.Bounciness;
7696 physdata.GravitationModifier = part.GravityModifier;
7190 7697
7698 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7699 physdata.Density = material_density;
7700 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7701 physdata.Friction = material_friction;
7702 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7703 physdata.Bounce = material_restitution;
7704 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7705 physdata.GravitationModifier = material_gravity_modifier;
7706
7707 part.UpdateExtraPhysics(physdata);
7708 }
7709
7710 public void llSetPhysicsMaterial(int material_bits,
7711 float material_gravity_modifier, float material_restitution,
7712 float material_friction, float material_density)
7713 {
7714 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7715 }
7716
7717 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7718 {
7719 llSetLinkPrimitiveParamsFast(linknumber, rules);
7191 ScriptSleep(200); 7720 ScriptSleep(200);
7192 } 7721 }
7193 7722
7194 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7723 // vector up using libomv (c&p from sop )
7724 // vector up rotated by r
7725 private Vector3 Zrot(Quaternion r)
7195 { 7726 {
7196 m_host.AddScriptLPS(1); 7727 double x, y, z, m;
7197 7728
7198 setLinkPrimParams(linknumber, rules); 7729 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7730 if (Math.Abs(1.0 - m) > 0.000001)
7731 {
7732 m = 1.0 / Math.Sqrt(m);
7733 r.X *= (float)m;
7734 r.Y *= (float)m;
7735 r.Z *= (float)m;
7736 r.W *= (float)m;
7737 }
7738
7739 x = 2 * (r.X * r.Z + r.Y * r.W);
7740 y = 2 * (-r.X * r.W + r.Y * r.Z);
7741 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7742
7743 return new Vector3((float)x, (float)y, (float)z);
7199 } 7744 }
7200 7745
7201 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7746 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7202 { 7747 {
7203 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7748 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7204 7749
7205 foreach (SceneObjectPart part in parts) 7750 int idx = 0;
7206 SetPrimParams(part, rules); 7751 SceneObjectPart sitpart = World.GetSceneObjectPart(av.ParentID); // betting this will be used
7752
7753 bool positionChanged = false;
7754 Vector3 finalPos = Vector3.Zero;
7755
7756 try
7757 {
7758 while (idx < rules.Length)
7759 {
7760 int code = rules.GetLSLIntegerItem(idx++);
7761
7762 int remain = rules.Length - idx;
7763
7764 switch (code)
7765 {
7766 // a avatar is a child
7767 case (int)ScriptBaseClass.PRIM_POSITION:
7768 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7769 {
7770 if (remain < 1)
7771 return;
7772 LSL_Vector v;
7773 v = rules.GetVector3Item(idx++);
7774
7775 if (sitpart == null)
7776 break;
7777
7778 Vector3 pos = new Vector3((float)v.x, (float)v.y, (float)v.z); // requested absolute position
7779
7780 if (sitpart != sitpart.ParentGroup.RootPart)
7781 {
7782 pos -= sitpart.OffsetPosition; // remove sit part offset
7783 Quaternion rot = sitpart.RotationOffset;
7784 pos *= Quaternion.Conjugate(rot); // removed sit part rotation
7785 }
7786 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f * 2.0f);
7787 pos += sitOffset;
7788
7789 finalPos = pos;
7790 positionChanged = true;
7791 }
7792 break;
7793
7794 case (int)ScriptBaseClass.PRIM_ROTATION:
7795 {
7796 if (remain < 1)
7797 return;
7798
7799 if (sitpart == null)
7800 break;
7801
7802 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7803 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested world rotation
7804
7805// need to replicate SL bug
7806 SceneObjectGroup sitgrp = sitpart.ParentGroup;
7807 if (sitgrp != null && sitgrp.RootPart != sitpart)
7808 {
7809 rot = sitgrp.RootPart.RotationOffset * rot;
7810 }
7811
7812 Quaternion srot = sitpart.RotationOffset;
7813 rot = Quaternion.Conjugate(srot) * rot; // removed sit part offset rotation
7814 av.Rotation = rot;
7815 av.SendAvatarDataToAllAgents();
7816 }
7817 break;
7818
7819 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7820 {
7821 if (remain < 1)
7822 return;
7823
7824 if (sitpart == null)
7825 break;
7826
7827 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7828 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested offset rotation
7829 if (sitpart != sitpart.ParentGroup.RootPart)
7830 {
7831 Quaternion srot = sitpart.RotationOffset;
7832 rot = Quaternion.Conjugate(srot) * rot; // remove sit part offset rotation
7833 }
7834 av.Rotation = rot;
7835 av.SendAvatarDataToAllAgents();
7836 }
7837 break;
7838
7839 // parse rest doing nothing but number of parameters error check
7840 case (int)ScriptBaseClass.PRIM_SIZE:
7841 case (int)ScriptBaseClass.PRIM_MATERIAL:
7842 case (int)ScriptBaseClass.PRIM_PHANTOM:
7843 case (int)ScriptBaseClass.PRIM_PHYSICS:
7844 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7845 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7846 case (int)ScriptBaseClass.PRIM_NAME:
7847 case (int)ScriptBaseClass.PRIM_DESC:
7848 if (remain < 1)
7849 return;
7850 idx++;
7851 break;
7852
7853 case (int)ScriptBaseClass.PRIM_GLOW:
7854 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7855 case (int)ScriptBaseClass.PRIM_TEXGEN:
7856 if (remain < 2)
7857 return;
7858 idx += 2;
7859 break;
7860
7861 case (int)ScriptBaseClass.PRIM_TYPE:
7862 if (remain < 3)
7863 return;
7864 code = (int)rules.GetLSLIntegerItem(idx++);
7865 remain = rules.Length - idx;
7866 switch (code)
7867 {
7868 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7869 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7870 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7871 if (remain < 6)
7872 return;
7873 idx += 6;
7874 break;
7875
7876 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7877 if (remain < 5)
7878 return;
7879 idx += 5;
7880 break;
7881
7882 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7883 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7884 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7885 if (remain < 11)
7886 return;
7887 idx += 11;
7888 break;
7889
7890 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7891 if (remain < 2)
7892 return;
7893 idx += 2;
7894 break;
7895 }
7896 break;
7897
7898 case (int)ScriptBaseClass.PRIM_COLOR:
7899 case (int)ScriptBaseClass.PRIM_TEXT:
7900 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7901 case (int)ScriptBaseClass.PRIM_OMEGA:
7902 if (remain < 3)
7903 return;
7904 idx += 3;
7905 break;
7906
7907 case (int)ScriptBaseClass.PRIM_TEXTURE:
7908 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7909 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7910 if (remain < 5)
7911 return;
7912 idx += 5;
7913 break;
7914
7915 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7916 if (remain < 7)
7917 return;
7918
7919 idx += 7;
7920 break;
7921
7922 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7923 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7924 return;
7925
7926 if (positionChanged)
7927 {
7928 positionChanged = false;
7929 av.OffsetPosition = finalPos;
7930 av.SendAvatarDataToAllAgents();
7931 }
7932
7933 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7934 LSL_List new_rules = rules.GetSublist(idx, -1);
7935 setLinkPrimParams((int)new_linknumber, new_rules);
7936 return;
7937 }
7938 }
7939 }
7940
7941 finally
7942 {
7943 if (positionChanged)
7944 {
7945 av.OffsetPosition = finalPos;
7946 av.SendAvatarDataToAllAgents();
7947 positionChanged = false;
7948 }
7949 }
7207 } 7950 }
7208 7951
7209 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7952 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7210 { 7953 {
7954 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7955 return;
7956
7211 int idx = 0; 7957 int idx = 0;
7212 7958
7959 SceneObjectGroup parentgrp = part.ParentGroup;
7960
7213 bool positionChanged = false; 7961 bool positionChanged = false;
7214 LSL_Vector currentPosition = GetPartLocalPos(part); 7962 LSL_Vector currentPosition = GetPartLocalPos(part);
7215 7963
@@ -7232,8 +7980,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7232 return; 7980 return;
7233 7981
7234 v=rules.GetVector3Item(idx++); 7982 v=rules.GetVector3Item(idx++);
7235 positionChanged = true;
7236 currentPosition = GetSetPosTarget(part, v, currentPosition); 7983 currentPosition = GetSetPosTarget(part, v, currentPosition);
7984 positionChanged = true;
7237 7985
7238 break; 7986 break;
7239 case (int)ScriptBaseClass.PRIM_SIZE: 7987 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7249,8 +7997,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7249 return; 7997 return;
7250 7998
7251 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7999 LSL_Rotation q = rules.GetQuaternionItem(idx++);
8000 SceneObjectPart rootPart = parentgrp.RootPart;
7252 // try to let this work as in SL... 8001 // try to let this work as in SL...
7253 if (part.ParentID == 0) 8002 if (rootPart == part)
7254 { 8003 {
7255 // special case: If we are root, rotate complete SOG to new rotation 8004 // special case: If we are root, rotate complete SOG to new rotation
7256 SetRot(part, Rot2Quaternion(q)); 8005 SetRot(part, Rot2Quaternion(q));
@@ -7258,7 +8007,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7258 else 8007 else
7259 { 8008 {
7260 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8009 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7261 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8010 // sounds like sl bug that we need to replicate
7262 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8011 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7263 } 8012 }
7264 8013
@@ -7511,7 +8260,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7511 return; 8260 return;
7512 8261
7513 string ph = rules.Data[idx++].ToString(); 8262 string ph = rules.Data[idx++].ToString();
7514 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8263 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7515 8264
7516 break; 8265 break;
7517 8266
@@ -7529,12 +8278,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7529 part.ScriptSetPhysicsStatus(physics); 8278 part.ScriptSetPhysicsStatus(physics);
7530 break; 8279 break;
7531 8280
8281 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8282 if (remain < 1)
8283 return;
8284
8285 int shape_type = rules.GetLSLIntegerItem(idx++);
8286
8287 ExtraPhysicsData physdata = new ExtraPhysicsData();
8288 physdata.Density = part.Density;
8289 physdata.Bounce = part.Bounciness;
8290 physdata.GravitationModifier = part.GravityModifier;
8291 physdata.PhysShapeType = (PhysShapeType)shape_type;
8292
8293 part.UpdateExtraPhysics(physdata);
8294
8295 break;
8296
8297 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8298 if (remain < 5)
8299 return;
8300
8301 int material_bits = rules.GetLSLIntegerItem(idx++);
8302 float material_density = (float)rules.GetLSLFloatItem(idx++);
8303 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8304 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8305 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8306
8307 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8308
8309 break;
8310
7532 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8311 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7533 if (remain < 1) 8312 if (remain < 1)
7534 return; 8313 return;
7535 string temp = rules.Data[idx++].ToString(); 8314 string temp = rules.Data[idx++].ToString();
7536 8315
7537 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8316 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7538 8317
7539 break; 8318 break;
7540 8319
@@ -7584,13 +8363,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7584 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8363 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7585 TargetOmega(part, axis, (double)spinrate, (double)gain); 8364 TargetOmega(part, axis, (double)spinrate, (double)gain);
7586 break; 8365 break;
8366
7587 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8367 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7588 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8368 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7589 return; 8369 return;
8370
8371 // do a pending position change before jumping to other part/avatar
8372 if (positionChanged)
8373 {
8374 positionChanged = false;
8375 if (parentgrp == null)
8376 return;
8377
8378 if (parentgrp.RootPart == part)
8379 {
8380
8381 Util.FireAndForget(delegate(object x)
8382 {
8383 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8384 });
8385 }
8386 else
8387 {
8388 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8389 parentgrp.HasGroupChanged = true;
8390 parentgrp.ScheduleGroupForTerseUpdate();
8391 }
8392 }
8393
7590 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8394 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7591 LSL_List new_rules = rules.GetSublist(idx, -1); 8395 LSL_List new_rules = rules.GetSublist(idx, -1);
7592 setLinkPrimParams((int)new_linknumber, new_rules); 8396 setLinkPrimParams((int)new_linknumber, new_rules);
7593
7594 return; 8397 return;
7595 } 8398 }
7596 } 8399 }
@@ -7602,7 +8405,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7602 if (part.ParentGroup.RootPart == part) 8405 if (part.ParentGroup.RootPart == part)
7603 { 8406 {
7604 SceneObjectGroup parent = part.ParentGroup; 8407 SceneObjectGroup parent = part.ParentGroup;
7605 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8408 Util.FireAndForget(delegate(object x) {
8409 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8410 });
7606 } 8411 }
7607 else 8412 else
7608 { 8413 {
@@ -7773,13 +8578,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7773 public LSL_Integer llGetNumberOfPrims() 8578 public LSL_Integer llGetNumberOfPrims()
7774 { 8579 {
7775 m_host.AddScriptLPS(1); 8580 m_host.AddScriptLPS(1);
7776 int avatarCount = 0; 8581 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7777 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8582
7778 {
7779 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7780 avatarCount++;
7781 });
7782
7783 return m_host.ParentGroup.PrimCount + avatarCount; 8583 return m_host.ParentGroup.PrimCount + avatarCount;
7784 } 8584 }
7785 8585
@@ -7795,55 +8595,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7795 m_host.AddScriptLPS(1); 8595 m_host.AddScriptLPS(1);
7796 UUID objID = UUID.Zero; 8596 UUID objID = UUID.Zero;
7797 LSL_List result = new LSL_List(); 8597 LSL_List result = new LSL_List();
8598
8599 // If the ID is not valid, return null result
7798 if (!UUID.TryParse(obj, out objID)) 8600 if (!UUID.TryParse(obj, out objID))
7799 { 8601 {
7800 result.Add(new LSL_Vector()); 8602 result.Add(new LSL_Vector());
7801 result.Add(new LSL_Vector()); 8603 result.Add(new LSL_Vector());
7802 return result; 8604 return result;
7803 } 8605 }
8606
8607 // Check if this is an attached prim. If so, replace
8608 // the UUID with the avatar UUID and report it's bounding box
8609 SceneObjectPart part = World.GetSceneObjectPart(objID);
8610 if (part != null && part.ParentGroup.IsAttachment)
8611 objID = part.ParentGroup.AttachedAvatar;
8612
8613 // Find out if this is an avatar ID. If so, return it's box
7804 ScenePresence presence = World.GetScenePresence(objID); 8614 ScenePresence presence = World.GetScenePresence(objID);
7805 if (presence != null) 8615 if (presence != null)
7806 { 8616 {
7807 if (presence.ParentID == 0) // not sat on an object 8617 // As per LSL Wiki, there is no difference between sitting
8618 // and standing avatar since server 1.36
8619 LSL_Vector lower;
8620 LSL_Vector upper;
8621 if (presence.Animator.Animations.DefaultAnimation.AnimID
8622 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7808 { 8623 {
7809 LSL_Vector lower; 8624 // This is for ground sitting avatars
7810 LSL_Vector upper; 8625 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7811 if (presence.Animator.Animations.DefaultAnimation.AnimID 8626 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7812 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8627 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7813 {
7814 // This is for ground sitting avatars
7815 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7816 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7817 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7818 }
7819 else
7820 {
7821 // This is for standing/flying avatars
7822 float height = presence.Appearance.AvatarHeight / 2.0f;
7823 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7824 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7825 }
7826 result.Add(lower);
7827 result.Add(upper);
7828 return result;
7829 } 8628 }
7830 else 8629 else
7831 { 8630 {
7832 // sitting on an object so we need the bounding box of that 8631 // This is for standing/flying avatars
7833 // which should include the avatar so set the UUID to the 8632 float height = presence.Appearance.AvatarHeight / 2.0f;
7834 // UUID of the object the avatar is sat on and allow it to fall through 8633 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7835 // to processing an object 8634 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7836 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7837 objID = p.UUID;
7838 } 8635 }
8636
8637 // Adjust to the documented error offsets (see LSL Wiki)
8638 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8639 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8640
8641 if (lower.x > upper.x)
8642 lower.x = upper.x;
8643 if (lower.y > upper.y)
8644 lower.y = upper.y;
8645 if (lower.z > upper.z)
8646 lower.z = upper.z;
8647
8648 result.Add(lower);
8649 result.Add(upper);
8650 return result;
7839 } 8651 }
7840 SceneObjectPart part = World.GetSceneObjectPart(objID); 8652
8653 part = World.GetSceneObjectPart(objID);
7841 // Currently only works for single prims without a sitting avatar 8654 // Currently only works for single prims without a sitting avatar
7842 if (part != null) 8655 if (part != null)
7843 { 8656 {
7844 Vector3 halfSize = part.Scale / 2.0f; 8657 float minX;
7845 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8658 float maxX;
7846 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8659 float minY;
8660 float maxY;
8661 float minZ;
8662 float maxZ;
8663
8664 // This BBox is in sim coordinates, with the offset being
8665 // a contained point.
8666 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8667 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8668
8669 minX -= offsets[0].X;
8670 maxX -= offsets[0].X;
8671 minY -= offsets[0].Y;
8672 maxY -= offsets[0].Y;
8673 minZ -= offsets[0].Z;
8674 maxZ -= offsets[0].Z;
8675
8676 LSL_Vector lower;
8677 LSL_Vector upper;
8678
8679 // Adjust to the documented error offsets (see LSL Wiki)
8680 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8681 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8682
8683 if (lower.x > upper.x)
8684 lower.x = upper.x;
8685 if (lower.y > upper.y)
8686 lower.y = upper.y;
8687 if (lower.z > upper.z)
8688 lower.z = upper.z;
8689
7847 result.Add(lower); 8690 result.Add(lower);
7848 result.Add(upper); 8691 result.Add(upper);
7849 return result; 8692 return result;
@@ -7857,7 +8700,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7857 8700
7858 public LSL_Vector llGetGeometricCenter() 8701 public LSL_Vector llGetGeometricCenter()
7859 { 8702 {
7860 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8703 Vector3 tmp = m_host.GetGeometricCenter();
8704 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7861 } 8705 }
7862 8706
7863 public LSL_List llGetPrimitiveParams(LSL_List rules) 8707 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7870,16 +8714,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7870 { 8714 {
7871 m_host.AddScriptLPS(1); 8715 m_host.AddScriptLPS(1);
7872 8716
8717 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8718 // keep other options as before
8719
7873 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8720 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8721 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7874 8722
7875 LSL_List res = new LSL_List(); 8723 LSL_List res = new LSL_List();
7876 8724
7877 foreach (var part in parts) 8725 if (parts.Count > 0)
7878 { 8726 {
7879 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8727 foreach (var part in parts)
7880 res += partRes; 8728 {
8729 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8730 res += partRes;
8731 }
8732 }
8733 if (avatars.Count > 0)
8734 {
8735 foreach (ScenePresence avatar in avatars)
8736 {
8737 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8738 res += avaRes;
8739 }
7881 } 8740 }
8741 return res;
8742 }
8743
8744 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8745 {
8746 // avatars case
8747 // replies as SL wiki
8748
8749 LSL_List res = new LSL_List();
8750// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8751 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8752
8753 int idx = 0;
8754 while (idx < rules.Length)
8755 {
8756 int code = (int)rules.GetLSLIntegerItem(idx++);
8757 int remain = rules.Length - idx;
8758
8759 switch (code)
8760 {
8761 case (int)ScriptBaseClass.PRIM_MATERIAL:
8762 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8763 break;
8764
8765 case (int)ScriptBaseClass.PRIM_PHYSICS:
8766 res.Add(new LSL_Integer(0));
8767 break;
8768
8769 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8770 res.Add(new LSL_Integer(0));
8771 break;
8772
8773 case (int)ScriptBaseClass.PRIM_PHANTOM:
8774 res.Add(new LSL_Integer(0));
8775 break;
8776
8777 case (int)ScriptBaseClass.PRIM_POSITION:
8778
8779 Vector3 pos = avatar.OffsetPosition;
8780
8781 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8782 pos -= sitOffset;
8783
8784 if( sitPart != null)
8785 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8786
8787 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8788 break;
8789
8790 case (int)ScriptBaseClass.PRIM_SIZE:
8791 // as in llGetAgentSize above
8792 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8793 break;
8794
8795 case (int)ScriptBaseClass.PRIM_ROTATION:
8796 Quaternion rot = avatar.Rotation;
8797 if (sitPart != null)
8798 {
8799 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8800 }
8801
8802 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8803 break;
8804
8805 case (int)ScriptBaseClass.PRIM_TYPE:
8806 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8807 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8808 res.Add(new LSL_Vector(0f,1.0f,0f));
8809 res.Add(new LSL_Float(0.0f));
8810 res.Add(new LSL_Vector(0, 0, 0));
8811 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8812 res.Add(new LSL_Vector(0, 0, 0));
8813 break;
8814
8815 case (int)ScriptBaseClass.PRIM_TEXTURE:
8816 if (remain < 1)
8817 return res;
8818
8819 int face = (int)rules.GetLSLIntegerItem(idx++);
8820 if (face == ScriptBaseClass.ALL_SIDES)
8821 {
8822 for (face = 0; face < 21; face++)
8823 {
8824 res.Add(new LSL_String(""));
8825 res.Add(new LSL_Vector(0,0,0));
8826 res.Add(new LSL_Vector(0,0,0));
8827 res.Add(new LSL_Float(0.0));
8828 }
8829 }
8830 else
8831 {
8832 if (face >= 0 && face < 21)
8833 {
8834 res.Add(new LSL_String(""));
8835 res.Add(new LSL_Vector(0,0,0));
8836 res.Add(new LSL_Vector(0,0,0));
8837 res.Add(new LSL_Float(0.0));
8838 }
8839 }
8840 break;
8841
8842 case (int)ScriptBaseClass.PRIM_COLOR:
8843 if (remain < 1)
8844 return res;
8845
8846 face = (int)rules.GetLSLIntegerItem(idx++);
8847
8848 if (face == ScriptBaseClass.ALL_SIDES)
8849 {
8850 for (face = 0; face < 21; face++)
8851 {
8852 res.Add(new LSL_Vector(0,0,0));
8853 res.Add(new LSL_Float(0));
8854 }
8855 }
8856 else
8857 {
8858 res.Add(new LSL_Vector(0,0,0));
8859 res.Add(new LSL_Float(0));
8860 }
8861 break;
8862
8863 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8864 if (remain < 1)
8865 return res;
8866 face = (int)rules.GetLSLIntegerItem(idx++);
8867
8868 if (face == ScriptBaseClass.ALL_SIDES)
8869 {
8870 for (face = 0; face < 21; face++)
8871 {
8872 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8873 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8874 }
8875 }
8876 else
8877 {
8878 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8879 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8880 }
8881 break;
8882
8883 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8884 if (remain < 1)
8885 return res;
8886 face = (int)rules.GetLSLIntegerItem(idx++);
8887
8888 if (face == ScriptBaseClass.ALL_SIDES)
8889 {
8890 for (face = 0; face < 21; face++)
8891 {
8892 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8893 }
8894 }
8895 else
8896 {
8897 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8898 }
8899 break;
7882 8900
8901 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8902 res.Add(new LSL_Integer(0));
8903 res.Add(new LSL_Integer(0));// softness
8904 res.Add(new LSL_Float(0.0f)); // gravity
8905 res.Add(new LSL_Float(0.0f)); // friction
8906 res.Add(new LSL_Float(0.0f)); // wind
8907 res.Add(new LSL_Float(0.0f)); // tension
8908 res.Add(new LSL_Vector(0f,0f,0f));
8909 break;
8910
8911 case (int)ScriptBaseClass.PRIM_TEXGEN:
8912 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8913 if (remain < 1)
8914 return res;
8915 face = (int)rules.GetLSLIntegerItem(idx++);
8916
8917 if (face == ScriptBaseClass.ALL_SIDES)
8918 {
8919 for (face = 0; face < 21; face++)
8920 {
8921 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8922 }
8923 }
8924 else
8925 {
8926 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8927 }
8928 break;
8929
8930 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8931 res.Add(new LSL_Integer(0));
8932 res.Add(new LSL_Vector(0f,0f,0f));
8933 res.Add(new LSL_Float(0f)); // intensity
8934 res.Add(new LSL_Float(0f)); // radius
8935 res.Add(new LSL_Float(0f)); // falloff
8936 break;
8937
8938 case (int)ScriptBaseClass.PRIM_GLOW:
8939 if (remain < 1)
8940 return res;
8941 face = (int)rules.GetLSLIntegerItem(idx++);
8942
8943 if (face == ScriptBaseClass.ALL_SIDES)
8944 {
8945 for (face = 0; face < 21; face++)
8946 {
8947 res.Add(new LSL_Float(0f));
8948 }
8949 }
8950 else
8951 {
8952 res.Add(new LSL_Float(0f));
8953 }
8954 break;
8955
8956 case (int)ScriptBaseClass.PRIM_TEXT:
8957 res.Add(new LSL_String(""));
8958 res.Add(new LSL_Vector(0f,0f,0f));
8959 res.Add(new LSL_Float(1.0f));
8960 break;
8961
8962 case (int)ScriptBaseClass.PRIM_NAME:
8963 res.Add(new LSL_String(avatar.Name));
8964 break;
8965
8966 case (int)ScriptBaseClass.PRIM_DESC:
8967 res.Add(new LSL_String(""));
8968 break;
8969
8970 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8971 Quaternion lrot = avatar.Rotation;
8972
8973 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
8974 {
8975 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
8976 }
8977 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
8978 break;
8979
8980 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8981 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
8982 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
8983 lpos -= lsitOffset;
8984
8985 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
8986 {
8987 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
8988 }
8989 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
8990 break;
8991
8992 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8993 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
8994 return res;
8995 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
8996 LSL_List new_rules = rules.GetSublist(idx, -1);
8997
8998 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
8999 return res;
9000 }
9001 }
7883 return res; 9002 return res;
7884 } 9003 }
7885 9004
@@ -7923,13 +9042,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7923 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9042 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7924 part.AbsolutePosition.Y, 9043 part.AbsolutePosition.Y,
7925 part.AbsolutePosition.Z); 9044 part.AbsolutePosition.Z);
7926 // For some reason, the part.AbsolutePosition.* values do not change if the
7927 // linkset is rotated; they always reflect the child prim's world position
7928 // as though the linkset is unrotated. This is incompatible behavior with SL's
7929 // implementation, so will break scripts imported from there (not to mention it
7930 // makes it more difficult to determine a child prim's actual inworld position).
7931 if (part.ParentID != 0)
7932 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7933 res.Add(v); 9045 res.Add(v);
7934 break; 9046 break;
7935 9047
@@ -8100,56 +9212,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8100 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9212 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8101 if (remain < 1) 9213 if (remain < 1)
8102 return res; 9214 return res;
8103 9215 face = (int)rules.GetLSLIntegerItem(idx++);
8104 face=(int)rules.GetLSLIntegerItem(idx++);
8105 9216
8106 tex = part.Shape.Textures; 9217 tex = part.Shape.Textures;
9218 int shiny;
8107 if (face == ScriptBaseClass.ALL_SIDES) 9219 if (face == ScriptBaseClass.ALL_SIDES)
8108 { 9220 {
8109 for (face = 0; face < GetNumberOfSides(part); face++) 9221 for (face = 0; face < GetNumberOfSides(part); face++)
8110 { 9222 {
8111 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9223 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8112 // Convert Shininess to PRIM_SHINY_* 9224 if (shinyness == Shininess.High)
8113 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9225 {
8114 // PRIM_BUMP_* 9226 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8115 res.Add(new LSL_Integer((int)texface.Bump)); 9227 }
9228 else if (shinyness == Shininess.Medium)
9229 {
9230 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9231 }
9232 else if (shinyness == Shininess.Low)
9233 {
9234 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9235 }
9236 else
9237 {
9238 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9239 }
9240 res.Add(new LSL_Integer(shiny));
9241 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8116 } 9242 }
8117 } 9243 }
8118 else 9244 else
8119 { 9245 {
8120 if (face >= 0 && face < GetNumberOfSides(part)) 9246 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9247 if (shinyness == Shininess.High)
8121 { 9248 {
8122 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9249 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8123 // Convert Shininess to PRIM_SHINY_* 9250 }
8124 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9251 else if (shinyness == Shininess.Medium)
8125 // PRIM_BUMP_* 9252 {
8126 res.Add(new LSL_Integer((int)texface.Bump)); 9253 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9254 }
9255 else if (shinyness == Shininess.Low)
9256 {
9257 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8127 } 9258 }
9259 else
9260 {
9261 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9262 }
9263 res.Add(new LSL_Integer(shiny));
9264 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8128 } 9265 }
8129 break; 9266 break;
8130 9267
8131 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9268 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8132 if (remain < 1) 9269 if (remain < 1)
8133 return res; 9270 return res;
8134 9271 face = (int)rules.GetLSLIntegerItem(idx++);
8135 face=(int)rules.GetLSLIntegerItem(idx++);
8136 9272
8137 tex = part.Shape.Textures; 9273 tex = part.Shape.Textures;
9274 int fullbright;
8138 if (face == ScriptBaseClass.ALL_SIDES) 9275 if (face == ScriptBaseClass.ALL_SIDES)
8139 { 9276 {
8140 for (face = 0; face < GetNumberOfSides(part); face++) 9277 for (face = 0; face < GetNumberOfSides(part); face++)
8141 { 9278 {
8142 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9279 if (tex.GetFace((uint)face).Fullbright == true)
8143 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9280 {
9281 fullbright = ScriptBaseClass.TRUE;
9282 }
9283 else
9284 {
9285 fullbright = ScriptBaseClass.FALSE;
9286 }
9287 res.Add(new LSL_Integer(fullbright));
8144 } 9288 }
8145 } 9289 }
8146 else 9290 else
8147 { 9291 {
8148 if (face >= 0 && face < GetNumberOfSides(part)) 9292 if (tex.GetFace((uint)face).Fullbright == true)
8149 { 9293 {
8150 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9294 fullbright = ScriptBaseClass.TRUE;
8151 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9295 }
9296 else
9297 {
9298 fullbright = ScriptBaseClass.FALSE;
8152 } 9299 }
9300 res.Add(new LSL_Integer(fullbright));
8153 } 9301 }
8154 break; 9302 break;
8155 9303
@@ -8171,27 +9319,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8171 break; 9319 break;
8172 9320
8173 case (int)ScriptBaseClass.PRIM_TEXGEN: 9321 case (int)ScriptBaseClass.PRIM_TEXGEN:
9322 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8174 if (remain < 1) 9323 if (remain < 1)
8175 return res; 9324 return res;
8176 9325 face = (int)rules.GetLSLIntegerItem(idx++);
8177 face=(int)rules.GetLSLIntegerItem(idx++);
8178 9326
8179 tex = part.Shape.Textures; 9327 tex = part.Shape.Textures;
8180 if (face == ScriptBaseClass.ALL_SIDES) 9328 if (face == ScriptBaseClass.ALL_SIDES)
8181 { 9329 {
8182 for (face = 0; face < GetNumberOfSides(part); face++) 9330 for (face = 0; face < GetNumberOfSides(part); face++)
8183 { 9331 {
8184 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9332 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8185 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9333 {
8186 res.Add(new LSL_Integer((uint)texgen >> 1)); 9334 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9335 }
9336 else
9337 {
9338 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9339 }
8187 } 9340 }
8188 } 9341 }
8189 else 9342 else
8190 { 9343 {
8191 if (face >= 0 && face < GetNumberOfSides(part)) 9344 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9345 {
9346 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9347 }
9348 else
8192 { 9349 {
8193 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9350 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8194 res.Add(new LSL_Integer((uint)texgen >> 1));
8195 } 9351 }
8196 } 9352 }
8197 break; 9353 break;
@@ -8214,25 +9370,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8214 case (int)ScriptBaseClass.PRIM_GLOW: 9370 case (int)ScriptBaseClass.PRIM_GLOW:
8215 if (remain < 1) 9371 if (remain < 1)
8216 return res; 9372 return res;
8217 9373 face = (int)rules.GetLSLIntegerItem(idx++);
8218 face=(int)rules.GetLSLIntegerItem(idx++);
8219 9374
8220 tex = part.Shape.Textures; 9375 tex = part.Shape.Textures;
9376 float primglow;
8221 if (face == ScriptBaseClass.ALL_SIDES) 9377 if (face == ScriptBaseClass.ALL_SIDES)
8222 { 9378 {
8223 for (face = 0; face < GetNumberOfSides(part); face++) 9379 for (face = 0; face < GetNumberOfSides(part); face++)
8224 { 9380 {
8225 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9381 primglow = tex.GetFace((uint)face).Glow;
8226 res.Add(new LSL_Float(texface.Glow)); 9382 res.Add(new LSL_Float(primglow));
8227 } 9383 }
8228 } 9384 }
8229 else 9385 else
8230 { 9386 {
8231 if (face >= 0 && face < GetNumberOfSides(part)) 9387 primglow = tex.GetFace((uint)face).Glow;
8232 { 9388 res.Add(new LSL_Float(primglow));
8233 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8234 res.Add(new LSL_Float(texface.Glow));
8235 }
8236 } 9389 }
8237 break; 9390 break;
8238 9391
@@ -8244,18 +9397,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8244 textColor.B)); 9397 textColor.B));
8245 res.Add(new LSL_Float(textColor.A)); 9398 res.Add(new LSL_Float(textColor.A));
8246 break; 9399 break;
9400
8247 case (int)ScriptBaseClass.PRIM_NAME: 9401 case (int)ScriptBaseClass.PRIM_NAME:
8248 res.Add(new LSL_String(part.Name)); 9402 res.Add(new LSL_String(part.Name));
8249 break; 9403 break;
9404
8250 case (int)ScriptBaseClass.PRIM_DESC: 9405 case (int)ScriptBaseClass.PRIM_DESC:
8251 res.Add(new LSL_String(part.Description)); 9406 res.Add(new LSL_String(part.Description));
8252 break; 9407 break;
9408
8253 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9409 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8254 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9410 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8255 break; 9411 break;
9412
8256 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9413 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8257 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9414 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8258 break; 9415 break;
9416
9417 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9418 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9419 return res;
9420 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9421 LSL_List new_rules = rules.GetSublist(idx, -1);
9422 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9423 res += tres;
9424 return res;
8259 } 9425 }
8260 } 9426 }
8261 return res; 9427 return res;
@@ -8848,8 +10014,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8848 // The function returns an ordered list 10014 // The function returns an ordered list
8849 // representing the tokens found in the supplied 10015 // representing the tokens found in the supplied
8850 // sources string. If two successive tokenizers 10016 // sources string. If two successive tokenizers
8851 // are encountered, then a NULL entry is added 10017 // are encountered, then a null-string entry is
8852 // to the list. 10018 // added to the list.
8853 // 10019 //
8854 // It is a precondition that the source and 10020 // It is a precondition that the source and
8855 // toekizer lisst are non-null. If they are null, 10021 // toekizer lisst are non-null. If they are null,
@@ -8857,7 +10023,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8857 // while their lengths are being determined. 10023 // while their lengths are being determined.
8858 // 10024 //
8859 // A small amount of working memoryis required 10025 // A small amount of working memoryis required
8860 // of approximately 8*#tokenizers. 10026 // of approximately 8*#tokenizers + 8*srcstrlen.
8861 // 10027 //
8862 // There are many ways in which this function 10028 // There are many ways in which this function
8863 // can be implemented, this implementation is 10029 // can be implemented, this implementation is
@@ -8873,155 +10039,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8873 // and eliminates redundant tokenizers as soon 10039 // and eliminates redundant tokenizers as soon
8874 // as is possible. 10040 // as is possible.
8875 // 10041 //
8876 // The implementation tries to avoid any copying 10042 // The implementation tries to minimize temporary
8877 // of arrays or other objects. 10043 // garbage generation.
8878 // </remarks> 10044 // </remarks>
8879 10045
8880 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10046 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8881 { 10047 {
8882 int beginning = 0; 10048 return ParseString2List(src, separators, spacers, true);
8883 int srclen = src.Length; 10049 }
8884 int seplen = separators.Length;
8885 object[] separray = separators.Data;
8886 int spclen = spacers.Length;
8887 object[] spcarray = spacers.Data;
8888 int mlen = seplen+spclen;
8889
8890 int[] offset = new int[mlen+1];
8891 bool[] active = new bool[mlen];
8892
8893 int best;
8894 int j;
8895
8896 // Initial capacity reduces resize cost
8897 10050
8898 LSL_List tokens = new LSL_List(); 10051 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10052 {
10053 int srclen = src.Length;
10054 int seplen = separators.Length;
10055 object[] separray = separators.Data;
10056 int spclen = spacers.Length;
10057 object[] spcarray = spacers.Data;
10058 int dellen = 0;
10059 string[] delarray = new string[seplen+spclen];
8899 10060
8900 // All entries are initially valid 10061 int outlen = 0;
10062 string[] outarray = new string[srclen*2+1];
8901 10063
8902 for (int i = 0; i < mlen; i++) 10064 int i, j;
8903 active[i] = true; 10065 string d;
8904 10066
8905 offset[mlen] = srclen; 10067 m_host.AddScriptLPS(1);
8906 10068
8907 while (beginning < srclen) 10069 /*
10070 * Convert separator and spacer lists to C# strings.
10071 * Also filter out null strings so we don't hang.
10072 */
10073 for (i = 0; i < seplen; i ++)
8908 { 10074 {
10075 d = separray[i].ToString();
10076 if (d.Length > 0)
10077 {
10078 delarray[dellen++] = d;
10079 }
10080 }
10081 seplen = dellen;
8909 10082
8910 best = mlen; // as bad as it gets 10083 for (i = 0; i < spclen; i ++)
10084 {
10085 d = spcarray[i].ToString();
10086 if (d.Length > 0)
10087 {
10088 delarray[dellen++] = d;
10089 }
10090 }
8911 10091
8912 // Scan for separators 10092 /*
10093 * Scan through source string from beginning to end.
10094 */
10095 for (i = 0;;)
10096 {
8913 10097
8914 for (j = 0; j < seplen; j++) 10098 /*
10099 * Find earliest delimeter in src starting at i (if any).
10100 */
10101 int earliestDel = -1;
10102 int earliestSrc = srclen;
10103 string earliestStr = null;
10104 for (j = 0; j < dellen; j ++)
8915 { 10105 {
8916 if (separray[j].ToString() == String.Empty) 10106 d = delarray[j];
8917 active[j] = false; 10107 if (d != null)
8918
8919 if (active[j])
8920 { 10108 {
8921 // scan all of the markers 10109 int index = src.IndexOf(d, i);
8922 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10110 if (index < 0)
8923 { 10111 {
8924 // not present at all 10112 delarray[j] = null; // delim nowhere in src, don't check it anymore
8925 active[j] = false;
8926 } 10113 }
8927 else 10114 else if (index < earliestSrc)
8928 { 10115 {
8929 // present and correct 10116 earliestSrc = index; // where delimeter starts in source string
8930 if (offset[j] < offset[best]) 10117 earliestDel = j; // where delimeter is in delarray[]
8931 { 10118 earliestStr = d; // the delimeter string from delarray[]
8932 // closest so far 10119 if (index == i) break; // can't do any better than found at beg of string
8933 best = j;
8934 if (offset[best] == beginning)
8935 break;
8936 }
8937 } 10120 }
8938 } 10121 }
8939 } 10122 }
8940 10123
8941 // Scan for spacers 10124 /*
8942 10125 * Output source string starting at i through start of earliest delimeter.
8943 if (offset[best] != beginning) 10126 */
10127 if (keepNulls || (earliestSrc > i))
8944 { 10128 {
8945 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10129 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8946 {
8947 if (spcarray[j-seplen].ToString() == String.Empty)
8948 active[j] = false;
8949
8950 if (active[j])
8951 {
8952 // scan all of the markers
8953 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8954 {
8955 // not present at all
8956 active[j] = false;
8957 }
8958 else
8959 {
8960 // present and correct
8961 if (offset[j] < offset[best])
8962 {
8963 // closest so far
8964 best = j;
8965 }
8966 }
8967 }
8968 }
8969 } 10130 }
8970 10131
8971 // This is the normal exit from the scanning loop 10132 /*
10133 * If no delimeter found at or after i, we're done scanning.
10134 */
10135 if (earliestDel < 0) break;
8972 10136
8973 if (best == mlen) 10137 /*
10138 * If delimeter was a spacer, output the spacer.
10139 */
10140 if (earliestDel >= seplen)
8974 { 10141 {
8975 // no markers were found on this pass 10142 outarray[outlen++] = earliestStr;
8976 // so we're pretty much done
8977 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8978 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8979 break;
8980 } 10143 }
8981 10144
8982 // Otherwise we just add the newly delimited token 10145 /*
8983 // and recalculate where the search should continue. 10146 * Look at rest of src string following delimeter.
8984 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10147 */
8985 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10148 i = earliestSrc + earliestStr.Length;
8986
8987 if (best < seplen)
8988 {
8989 beginning = offset[best] + (separray[best].ToString()).Length;
8990 }
8991 else
8992 {
8993 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8994 string str = spcarray[best - seplen].ToString();
8995 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8996 tokens.Add(new LSL_String(str));
8997 }
8998 } 10149 }
8999 10150
9000 // This an awkward an not very intuitive boundary case. If the 10151 /*
9001 // last substring is a tokenizer, then there is an implied trailing 10152 * Make up an exact-sized output array suitable for an LSL_List object.
9002 // null list entry. Hopefully the single comparison will not be too 10153 */
9003 // arduous. Alternatively the 'break' could be replced with a return 10154 object[] outlist = new object[outlen];
9004 // but that's shabby programming. 10155 for (i = 0; i < outlen; i ++)
9005
9006 if ((beginning == srclen) && (keepNulls))
9007 { 10156 {
9008 if (srclen != 0) 10157 outlist[i] = new LSL_String(outarray[i]);
9009 tokens.Add(new LSL_String(""));
9010 } 10158 }
9011 10159 return new LSL_List(outlist);
9012 return tokens;
9013 }
9014
9015 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9016 {
9017 m_host.AddScriptLPS(1);
9018 return this.ParseString(src, separators, spacers, false);
9019 }
9020
9021 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9022 {
9023 m_host.AddScriptLPS(1);
9024 return this.ParseString(src, separators, spacers, true);
9025 } 10160 }
9026 10161
9027 public LSL_Integer llGetObjectPermMask(int mask) 10162 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9098,28 +10233,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9098 { 10233 {
9099 m_host.AddScriptLPS(1); 10234 m_host.AddScriptLPS(1);
9100 10235
9101 lock (m_host.TaskInventory) 10236 m_host.TaskInventory.LockItemsForRead(true);
10237 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9102 { 10238 {
9103 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10239 if (inv.Value.Name == item)
9104 { 10240 {
9105 if (inv.Value.Name == item) 10241 m_host.TaskInventory.LockItemsForRead(false);
10242 switch (mask)
9106 { 10243 {
9107 switch (mask) 10244 case 0:
9108 { 10245 return (int)inv.Value.BasePermissions;
9109 case 0: 10246 case 1:
9110 return (int)inv.Value.BasePermissions; 10247 return (int)inv.Value.CurrentPermissions;
9111 case 1: 10248 case 2:
9112 return (int)inv.Value.CurrentPermissions; 10249 return (int)inv.Value.GroupPermissions;
9113 case 2: 10250 case 3:
9114 return (int)inv.Value.GroupPermissions; 10251 return (int)inv.Value.EveryonePermissions;
9115 case 3: 10252 case 4:
9116 return (int)inv.Value.EveryonePermissions; 10253 return (int)inv.Value.NextPermissions;
9117 case 4:
9118 return (int)inv.Value.NextPermissions;
9119 }
9120 } 10254 }
9121 } 10255 }
9122 } 10256 }
10257 m_host.TaskInventory.LockItemsForRead(false);
9123 10258
9124 return -1; 10259 return -1;
9125 } 10260 }
@@ -9166,16 +10301,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9166 { 10301 {
9167 m_host.AddScriptLPS(1); 10302 m_host.AddScriptLPS(1);
9168 10303
9169 lock (m_host.TaskInventory) 10304 m_host.TaskInventory.LockItemsForRead(true);
10305 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9170 { 10306 {
9171 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10307 if (inv.Value.Name == item)
9172 { 10308 {
9173 if (inv.Value.Name == item) 10309 m_host.TaskInventory.LockItemsForRead(false);
9174 { 10310 return inv.Value.CreatorID.ToString();
9175 return inv.Value.CreatorID.ToString();
9176 }
9177 } 10311 }
9178 } 10312 }
10313 m_host.TaskInventory.LockItemsForRead(false);
9179 10314
9180 llSay(0, "No item name '" + item + "'"); 10315 llSay(0, "No item name '" + item + "'");
9181 10316
@@ -9317,9 +10452,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9317 { 10452 {
9318 try 10453 try
9319 { 10454 {
10455 /*
9320 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10456 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9321 if (obj != null) 10457 if (obj != null)
9322 return (double)obj.GetMass(); 10458 return (double)obj.GetMass();
10459 */
10460 // return total object mass
10461 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10462 if (obj != null)
10463 return obj.GetMass();
10464
9323 // the object is null so the key is for an avatar 10465 // the object is null so the key is for an avatar
9324 ScenePresence avatar = World.GetScenePresence(key); 10466 ScenePresence avatar = World.GetScenePresence(key);
9325 if (avatar != null) 10467 if (avatar != null)
@@ -9339,7 +10481,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9339 } 10481 }
9340 10482
9341 /// <summary> 10483 /// <summary>
9342 /// illListReplaceList removes the sub-list defined by the inclusive indices 10484 /// llListReplaceList removes the sub-list defined by the inclusive indices
9343 /// start and end and inserts the src list in its place. The inclusive 10485 /// start and end and inserts the src list in its place. The inclusive
9344 /// nature of the indices means that at least one element must be deleted 10486 /// nature of the indices means that at least one element must be deleted
9345 /// if the indices are within the bounds of the existing list. I.e. 2,2 10487 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9396,16 +10538,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9396 // based upon end. Note that if end exceeds the upper 10538 // based upon end. Note that if end exceeds the upper
9397 // bound in this case, the entire destination list 10539 // bound in this case, the entire destination list
9398 // is removed. 10540 // is removed.
9399 else 10541 else if (start == 0)
9400 { 10542 {
9401 if (end + 1 < dest.Length) 10543 if (end + 1 < dest.Length)
9402 {
9403 return src + dest.GetSublist(end + 1, -1); 10544 return src + dest.GetSublist(end + 1, -1);
9404 }
9405 else 10545 else
9406 {
9407 return src; 10546 return src;
9408 } 10547 }
10548 else // Start < 0
10549 {
10550 if (end + 1 < dest.Length)
10551 return dest.GetSublist(end + 1, -1);
10552 else
10553 return new LSL_List();
9409 } 10554 }
9410 } 10555 }
9411 // Finally, if start > end, we strip away a prefix and 10556 // Finally, if start > end, we strip away a prefix and
@@ -9456,17 +10601,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9456 int width = 0; 10601 int width = 0;
9457 int height = 0; 10602 int height = 0;
9458 10603
9459 ParcelMediaCommandEnum? commandToSend = null; 10604 uint commandToSend = 0;
9460 float time = 0.0f; // default is from start 10605 float time = 0.0f; // default is from start
9461 10606
9462 ScenePresence presence = null; 10607 ScenePresence presence = null;
9463 10608
9464 for (int i = 0; i < commandList.Data.Length; i++) 10609 for (int i = 0; i < commandList.Data.Length; i++)
9465 { 10610 {
9466 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10611 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9467 switch (command) 10612 switch (command)
9468 { 10613 {
9469 case ParcelMediaCommandEnum.Agent: 10614 case (uint)ParcelMediaCommandEnum.Agent:
9470 // we send only to one agent 10615 // we send only to one agent
9471 if ((i + 1) < commandList.Length) 10616 if ((i + 1) < commandList.Length)
9472 { 10617 {
@@ -9483,25 +10628,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9483 } 10628 }
9484 break; 10629 break;
9485 10630
9486 case ParcelMediaCommandEnum.Loop: 10631 case (uint)ParcelMediaCommandEnum.Loop:
9487 loop = 1; 10632 loop = 1;
9488 commandToSend = command; 10633 commandToSend = command;
9489 update = true; //need to send the media update packet to set looping 10634 update = true; //need to send the media update packet to set looping
9490 break; 10635 break;
9491 10636
9492 case ParcelMediaCommandEnum.Play: 10637 case (uint)ParcelMediaCommandEnum.Play:
9493 loop = 0; 10638 loop = 0;
9494 commandToSend = command; 10639 commandToSend = command;
9495 update = true; //need to send the media update packet to make sure it doesn't loop 10640 update = true; //need to send the media update packet to make sure it doesn't loop
9496 break; 10641 break;
9497 10642
9498 case ParcelMediaCommandEnum.Pause: 10643 case (uint)ParcelMediaCommandEnum.Pause:
9499 case ParcelMediaCommandEnum.Stop: 10644 case (uint)ParcelMediaCommandEnum.Stop:
9500 case ParcelMediaCommandEnum.Unload: 10645 case (uint)ParcelMediaCommandEnum.Unload:
9501 commandToSend = command; 10646 commandToSend = command;
9502 break; 10647 break;
9503 10648
9504 case ParcelMediaCommandEnum.Url: 10649 case (uint)ParcelMediaCommandEnum.Url:
9505 if ((i + 1) < commandList.Length) 10650 if ((i + 1) < commandList.Length)
9506 { 10651 {
9507 if (commandList.Data[i + 1] is LSL_String) 10652 if (commandList.Data[i + 1] is LSL_String)
@@ -9514,7 +10659,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9514 } 10659 }
9515 break; 10660 break;
9516 10661
9517 case ParcelMediaCommandEnum.Texture: 10662 case (uint)ParcelMediaCommandEnum.Texture:
9518 if ((i + 1) < commandList.Length) 10663 if ((i + 1) < commandList.Length)
9519 { 10664 {
9520 if (commandList.Data[i + 1] is LSL_String) 10665 if (commandList.Data[i + 1] is LSL_String)
@@ -9527,7 +10672,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9527 } 10672 }
9528 break; 10673 break;
9529 10674
9530 case ParcelMediaCommandEnum.Time: 10675 case (uint)ParcelMediaCommandEnum.Time:
9531 if ((i + 1) < commandList.Length) 10676 if ((i + 1) < commandList.Length)
9532 { 10677 {
9533 if (commandList.Data[i + 1] is LSL_Float) 10678 if (commandList.Data[i + 1] is LSL_Float)
@@ -9539,7 +10684,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9539 } 10684 }
9540 break; 10685 break;
9541 10686
9542 case ParcelMediaCommandEnum.AutoAlign: 10687 case (uint)ParcelMediaCommandEnum.AutoAlign:
9543 if ((i + 1) < commandList.Length) 10688 if ((i + 1) < commandList.Length)
9544 { 10689 {
9545 if (commandList.Data[i + 1] is LSL_Integer) 10690 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9553,7 +10698,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9553 } 10698 }
9554 break; 10699 break;
9555 10700
9556 case ParcelMediaCommandEnum.Type: 10701 case (uint)ParcelMediaCommandEnum.Type:
9557 if ((i + 1) < commandList.Length) 10702 if ((i + 1) < commandList.Length)
9558 { 10703 {
9559 if (commandList.Data[i + 1] is LSL_String) 10704 if (commandList.Data[i + 1] is LSL_String)
@@ -9566,7 +10711,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9566 } 10711 }
9567 break; 10712 break;
9568 10713
9569 case ParcelMediaCommandEnum.Desc: 10714 case (uint)ParcelMediaCommandEnum.Desc:
9570 if ((i + 1) < commandList.Length) 10715 if ((i + 1) < commandList.Length)
9571 { 10716 {
9572 if (commandList.Data[i + 1] is LSL_String) 10717 if (commandList.Data[i + 1] is LSL_String)
@@ -9579,7 +10724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9579 } 10724 }
9580 break; 10725 break;
9581 10726
9582 case ParcelMediaCommandEnum.Size: 10727 case (uint)ParcelMediaCommandEnum.Size:
9583 if ((i + 2) < commandList.Length) 10728 if ((i + 2) < commandList.Length)
9584 { 10729 {
9585 if (commandList.Data[i + 1] is LSL_Integer) 10730 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9649,7 +10794,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9649 } 10794 }
9650 } 10795 }
9651 10796
9652 if (commandToSend != null) 10797 if (commandToSend != 0)
9653 { 10798 {
9654 // the commandList contained a start/stop/... command, too 10799 // the commandList contained a start/stop/... command, too
9655 if (presence == null) 10800 if (presence == null)
@@ -9686,7 +10831,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9686 10831
9687 if (aList.Data[i] != null) 10832 if (aList.Data[i] != null)
9688 { 10833 {
9689 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10834 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9690 { 10835 {
9691 case ParcelMediaCommandEnum.Url: 10836 case ParcelMediaCommandEnum.Url:
9692 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10837 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9729,16 +10874,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9729 { 10874 {
9730 m_host.AddScriptLPS(1); 10875 m_host.AddScriptLPS(1);
9731 10876
9732 lock (m_host.TaskInventory) 10877 m_host.TaskInventory.LockItemsForRead(true);
10878 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
9733 { 10879 {
9734 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 10880 if (inv.Value.Name == name)
9735 { 10881 {
9736 if (inv.Value.Name == name) 10882 m_host.TaskInventory.LockItemsForRead(false);
9737 { 10883 return inv.Value.Type;
9738 return inv.Value.Type;
9739 }
9740 } 10884 }
9741 } 10885 }
10886 m_host.TaskInventory.LockItemsForRead(false);
9742 10887
9743 return -1; 10888 return -1;
9744 } 10889 }
@@ -9749,15 +10894,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9749 10894
9750 if (quick_pay_buttons.Data.Length < 4) 10895 if (quick_pay_buttons.Data.Length < 4)
9751 { 10896 {
9752 LSLError("List must have at least 4 elements"); 10897 int x;
9753 return; 10898 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10899 {
10900 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10901 }
9754 } 10902 }
9755 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10903 int[] nPrice = new int[5];
9756 10904 nPrice[0] = price;
9757 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10905 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9758 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10906 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9759 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10907 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9760 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10908 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10909 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9761 m_host.ParentGroup.HasGroupChanged = true; 10910 m_host.ParentGroup.HasGroupChanged = true;
9762 } 10911 }
9763 10912
@@ -9774,7 +10923,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9774 return new LSL_Vector(); 10923 return new LSL_Vector();
9775 } 10924 }
9776 10925
9777 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10926// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10927 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9778 if (presence != null) 10928 if (presence != null)
9779 { 10929 {
9780 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10930 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9796,7 +10946,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9796 return new LSL_Rotation(); 10946 return new LSL_Rotation();
9797 } 10947 }
9798 10948
9799 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10949// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10950 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9800 if (presence != null) 10951 if (presence != null)
9801 { 10952 {
9802 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10953 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9856,8 +11007,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9856 { 11007 {
9857 m_host.AddScriptLPS(1); 11008 m_host.AddScriptLPS(1);
9858 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11009 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9859 if (detectedParams == null) return; // only works on the first detected avatar 11010 if (detectedParams == null)
9860 11011 {
11012 if (m_host.ParentGroup.IsAttachment == true)
11013 {
11014 detectedParams = new DetectParams();
11015 detectedParams.Key = m_host.OwnerID;
11016 }
11017 else
11018 {
11019 return;
11020 }
11021 }
11022
9861 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11023 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9862 if (avatar != null) 11024 if (avatar != null)
9863 { 11025 {
@@ -9865,6 +11027,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9865 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11027 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9866 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11028 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9867 } 11029 }
11030
9868 ScriptSleep(1000); 11031 ScriptSleep(1000);
9869 } 11032 }
9870 11033
@@ -9988,12 +11151,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9988 11151
9989 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11152 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9990 object[] data = rules.Data; 11153 object[] data = rules.Data;
9991 for (int i = 0; i < data.Length; ++i) { 11154 for (int i = 0; i < data.Length; ++i)
11155 {
9992 int type = Convert.ToInt32(data[i++].ToString()); 11156 int type = Convert.ToInt32(data[i++].ToString());
9993 if (i >= data.Length) break; // odd number of entries => ignore the last 11157 if (i >= data.Length) break; // odd number of entries => ignore the last
9994 11158
9995 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11159 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9996 switch (type) { 11160 switch (type)
11161 {
9997 case ScriptBaseClass.CAMERA_FOCUS: 11162 case ScriptBaseClass.CAMERA_FOCUS:
9998 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11163 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9999 case ScriptBaseClass.CAMERA_POSITION: 11164 case ScriptBaseClass.CAMERA_POSITION:
@@ -10099,19 +11264,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10099 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11264 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10100 { 11265 {
10101 m_host.AddScriptLPS(1); 11266 m_host.AddScriptLPS(1);
10102 string ret = String.Empty; 11267
10103 string src1 = llBase64ToString(str1); 11268 if (str1 == String.Empty)
10104 string src2 = llBase64ToString(str2); 11269 return String.Empty;
10105 int c = 0; 11270 if (str2 == String.Empty)
10106 for (int i = 0; i < src1.Length; i++) 11271 return str1;
11272
11273 int len = str2.Length;
11274 if ((len % 4) != 0) // LL is EVIL!!!!
10107 { 11275 {
10108 ret += (char) (src1[i] ^ src2[c]); 11276 while (str2.EndsWith("="))
11277 str2 = str2.Substring(0, str2.Length - 1);
11278
11279 len = str2.Length;
11280 int mod = len % 4;
11281
11282 if (mod == 1)
11283 str2 = str2.Substring(0, str2.Length - 1);
11284 else if (mod == 2)
11285 str2 += "==";
11286 else if (mod == 3)
11287 str2 += "=";
11288 }
10109 11289
10110 c++; 11290 byte[] data1;
10111 if (c >= src2.Length) 11291 byte[] data2;
10112 c = 0; 11292 try
11293 {
11294 data1 = Convert.FromBase64String(str1);
11295 data2 = Convert.FromBase64String(str2);
11296 }
11297 catch (Exception)
11298 {
11299 return new LSL_String(String.Empty);
10113 } 11300 }
10114 return llStringToBase64(ret); 11301
11302 byte[] d2 = new Byte[data1.Length];
11303 int pos = 0;
11304
11305 if (data1.Length <= data2.Length)
11306 {
11307 Array.Copy(data2, 0, d2, 0, data1.Length);
11308 }
11309 else
11310 {
11311 while (pos < data1.Length)
11312 {
11313 len = data1.Length - pos;
11314 if (len > data2.Length)
11315 len = data2.Length;
11316
11317 Array.Copy(data2, 0, d2, pos, len);
11318 pos += len;
11319 }
11320 }
11321
11322 for (pos = 0 ; pos < data1.Length ; pos++ )
11323 data1[pos] ^= d2[pos];
11324
11325 return Convert.ToBase64String(data1);
10115 } 11326 }
10116 11327
10117 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11328 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10168,12 +11379,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10168 Regex r = new Regex(authregex); 11379 Regex r = new Regex(authregex);
10169 int[] gnums = r.GetGroupNumbers(); 11380 int[] gnums = r.GetGroupNumbers();
10170 Match m = r.Match(url); 11381 Match m = r.Match(url);
10171 if (m.Success) { 11382 if (m.Success)
10172 for (int i = 1; i < gnums.Length; i++) { 11383 {
11384 for (int i = 1; i < gnums.Length; i++)
11385 {
10173 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11386 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10174 //CaptureCollection cc = g.Captures; 11387 //CaptureCollection cc = g.Captures;
10175 } 11388 }
10176 if (m.Groups.Count == 5) { 11389 if (m.Groups.Count == 5)
11390 {
10177 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11391 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10178 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11392 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10179 } 11393 }
@@ -10376,6 +11590,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10376 11590
10377 LSL_List ret = new LSL_List(); 11591 LSL_List ret = new LSL_List();
10378 UUID key = new UUID(); 11592 UUID key = new UUID();
11593
11594
10379 if (UUID.TryParse(id, out key)) 11595 if (UUID.TryParse(id, out key))
10380 { 11596 {
10381 ScenePresence av = World.GetScenePresence(key); 11597 ScenePresence av = World.GetScenePresence(key);
@@ -10393,13 +11609,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10393 ret.Add(new LSL_String("")); 11609 ret.Add(new LSL_String(""));
10394 break; 11610 break;
10395 case ScriptBaseClass.OBJECT_POS: 11611 case ScriptBaseClass.OBJECT_POS:
10396 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11612 Vector3 avpos;
11613
11614 if (av.ParentID != 0 && av.ParentPart != null)
11615 {
11616 avpos = av.OffsetPosition;
11617
11618 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11619 avpos -= sitOffset;
11620
11621 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11622 }
11623 else
11624 avpos = av.AbsolutePosition;
11625
11626 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10397 break; 11627 break;
10398 case ScriptBaseClass.OBJECT_ROT: 11628 case ScriptBaseClass.OBJECT_ROT:
10399 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11629 Quaternion avrot = av.Rotation;
11630 if (av.ParentID != 0 && av.ParentPart != null)
11631 {
11632 avrot = av.ParentPart.GetWorldRotation() * avrot;
11633 }
11634 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10400 break; 11635 break;
10401 case ScriptBaseClass.OBJECT_VELOCITY: 11636 case ScriptBaseClass.OBJECT_VELOCITY:
10402 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11637 Vector3 avvel = av.Velocity;
11638 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10403 break; 11639 break;
10404 case ScriptBaseClass.OBJECT_OWNER: 11640 case ScriptBaseClass.OBJECT_OWNER:
10405 ret.Add(new LSL_String(id)); 11641 ret.Add(new LSL_String(id));
@@ -10455,17 +11691,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10455 case ScriptBaseClass.OBJECT_NAME: 11691 case ScriptBaseClass.OBJECT_NAME:
10456 ret.Add(new LSL_String(obj.Name)); 11692 ret.Add(new LSL_String(obj.Name));
10457 break; 11693 break;
10458 case ScriptBaseClass.OBJECT_DESC: 11694 case ScriptBaseClass.OBJECT_DESC:
10459 ret.Add(new LSL_String(obj.Description)); 11695 ret.Add(new LSL_String(obj.Description));
10460 break; 11696 break;
10461 case ScriptBaseClass.OBJECT_POS: 11697 case ScriptBaseClass.OBJECT_POS:
10462 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11698 Vector3 opos = obj.AbsolutePosition;
11699 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10463 break; 11700 break;
10464 case ScriptBaseClass.OBJECT_ROT: 11701 case ScriptBaseClass.OBJECT_ROT:
10465 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 11702// Quaternion orot = obj.RotationOffset;
11703// ret.Add(new LSL_Rotation(orot.X, orot.Y, orot.Z, orot.W));
11704
11705 LSL_Rotation objrot = GetPartRot(obj);
11706 ret.Add(objrot);
10466 break; 11707 break;
10467 case ScriptBaseClass.OBJECT_VELOCITY: 11708 case ScriptBaseClass.OBJECT_VELOCITY:
10468 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11709 Vector3 ovel = obj.Velocity;
11710 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10469 break; 11711 break;
10470 case ScriptBaseClass.OBJECT_OWNER: 11712 case ScriptBaseClass.OBJECT_OWNER:
10471 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11713 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10499,9 +11741,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10499 // The value returned in SL for normal prims is prim count 11741 // The value returned in SL for normal prims is prim count
10500 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11742 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10501 break; 11743 break;
10502 // The following 3 costs I have intentionaly coded to return zero. They are part of 11744
10503 // "Land Impact" calculations. These calculations are probably not applicable 11745 // costs below may need to be diferent for root parts, need to check
10504 // to OpenSim and are not yet complete in SL
10505 case ScriptBaseClass.OBJECT_SERVER_COST: 11746 case ScriptBaseClass.OBJECT_SERVER_COST:
10506 // The linden calculation is here 11747 // The linden calculation is here
10507 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11748 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10509,16 +11750,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10509 ret.Add(new LSL_Float(0)); 11750 ret.Add(new LSL_Float(0));
10510 break; 11751 break;
10511 case ScriptBaseClass.OBJECT_STREAMING_COST: 11752 case ScriptBaseClass.OBJECT_STREAMING_COST:
10512 // The linden calculation is here 11753 // The value returned in SL for normal prims is prim count * 0.06
10513 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11754 ret.Add(new LSL_Float(obj.StreamingCost));
10514 // The value returned in SL for normal prims looks like the prim count * 0.06
10515 ret.Add(new LSL_Float(0));
10516 break; 11755 break;
10517 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11756 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10518 // The linden calculation is here 11757 // The value returned in SL for normal prims is prim count
10519 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11758 ret.Add(new LSL_Float(obj.PhysicsCost));
10520 // The value returned in SL for normal prims looks like the prim count
10521 ret.Add(new LSL_Float(0));
10522 break; 11759 break;
10523 default: 11760 default:
10524 // Invalid or unhandled constant. 11761 // Invalid or unhandled constant.
@@ -10536,15 +11773,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10536 11773
10537 internal UUID ScriptByName(string name) 11774 internal UUID ScriptByName(string name)
10538 { 11775 {
10539 lock (m_host.TaskInventory) 11776 m_host.TaskInventory.LockItemsForRead(true);
11777
11778 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
10540 { 11779 {
10541 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 11780 if (item.Type == 10 && item.Name == name)
10542 { 11781 {
10543 if (item.Type == 10 && item.Name == name) 11782 m_host.TaskInventory.LockItemsForRead(false);
10544 return item.ItemID; 11783 return item.ItemID;
10545 } 11784 }
10546 } 11785 }
10547 11786
11787 m_host.TaskInventory.LockItemsForRead(false);
11788
10548 return UUID.Zero; 11789 return UUID.Zero;
10549 } 11790 }
10550 11791
@@ -10585,6 +11826,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10585 { 11826 {
10586 m_host.AddScriptLPS(1); 11827 m_host.AddScriptLPS(1);
10587 11828
11829 //Clone is thread safe
10588 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11830 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10589 11831
10590 UUID assetID = UUID.Zero; 11832 UUID assetID = UUID.Zero;
@@ -10647,6 +11889,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10647 { 11889 {
10648 m_host.AddScriptLPS(1); 11890 m_host.AddScriptLPS(1);
10649 11891
11892 //Clone is thread safe
10650 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone(); 11893 TaskInventoryDictionary itemsDictionary = (TaskInventoryDictionary)m_host.TaskInventory.Clone();
10651 11894
10652 UUID assetID = UUID.Zero; 11895 UUID assetID = UUID.Zero;
@@ -10727,15 +11970,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10727 return GetLinkPrimitiveParams(obj, rules); 11970 return GetLinkPrimitiveParams(obj, rules);
10728 } 11971 }
10729 11972
10730 public void print(string str) 11973 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10731 { 11974 {
10732 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11975 List<SceneObjectPart> parts = GetLinkParts(link);
10733 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11976 if (parts.Count < 1)
10734 if (ossl != null) 11977 return 0;
10735 { 11978
10736 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11979 return GetNumberOfSides(parts[0]);
10737 m_log.Info("LSL print():" + str);
10738 }
10739 } 11980 }
10740 11981
10741 private string Name2Username(string name) 11982 private string Name2Username(string name)
@@ -10781,6 +12022,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10781 return rq.ToString(); 12022 return rq.ToString();
10782 } 12023 }
10783 12024
12025 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12026 {
12027 m_SayShoutCount = 0;
12028 }
12029
10784 private struct Tri 12030 private struct Tri
10785 { 12031 {
10786 public Vector3 p1; 12032 public Vector3 p1;
@@ -11055,6 +12301,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11055 12301
11056 return contacts[0]; 12302 return contacts[0];
11057 } 12303 }
12304/*
12305 // not done:
12306 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12307 {
12308 ContactResult[] contacts = null;
12309 World.ForEachSOG(delegate(SceneObjectGroup group)
12310 {
12311 if (m_host.ParentGroup == group)
12312 return;
12313
12314 if (group.IsAttachment)
12315 return;
12316
12317 if(group.RootPart.PhysActor != null)
12318 return;
12319
12320 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12321 });
12322 return contacts;
12323 }
12324*/
11058 12325
11059 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12326 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11060 { 12327 {
@@ -11096,32 +12363,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11096 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12363 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11097 12364
11098 12365
11099 if (checkTerrain) 12366 if (World.SuportsRayCastFiltered())
11100 { 12367 {
11101 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12368 if (dist == 0)
11102 if (groundContact != null) 12369 return list;
11103 results.Add((ContactResult)groundContact);
11104 }
11105 12370
11106 if (checkAgents) 12371 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11107 { 12372 if (checkTerrain)
11108 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12373 rayfilter |= RayFilterFlags.land;
11109 foreach (ContactResult r in agentHits) 12374// if (checkAgents)
11110 results.Add(r); 12375// rayfilter |= RayFilterFlags.agent;
11111 } 12376 if (checkPhysical)
12377 rayfilter |= RayFilterFlags.physical;
12378 if (checkNonPhysical)
12379 rayfilter |= RayFilterFlags.nonphysical;
12380 if (detectPhantom)
12381 rayfilter |= RayFilterFlags.LSLPhanton;
12382
12383 Vector3 direction = dir * ( 1/dist);
12384
12385 if(rayfilter == 0)
12386 {
12387 list.Add(new LSL_Integer(0));
12388 return list;
12389 }
12390
12391 // get some more contacts to sort ???
12392 int physcount = 4 * count;
12393 if (physcount > 20)
12394 physcount = 20;
12395
12396 object physresults;
12397 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12398
12399 if (physresults == null)
12400 {
12401 list.Add(new LSL_Integer(-3)); // timeout error
12402 return list;
12403 }
12404
12405 results = (List<ContactResult>)physresults;
11112 12406
11113 if (checkPhysical || checkNonPhysical || detectPhantom) 12407 // for now physics doesn't detect sitted avatars so do it outside physics
12408 if (checkAgents)
12409 {
12410 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12411 foreach (ContactResult r in agentHits)
12412 results.Add(r);
12413 }
12414
12415 // TODO: Replace this with a better solution. ObjectIntersection can only
12416 // detect nonphysical phantoms. They are detected by virtue of being
12417 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12418 // physicsl phantoms as done by the physics scene
12419 // We don't want anything else but phantoms here.
12420 if (detectPhantom)
12421 {
12422 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12423 foreach (ContactResult r in objectHits)
12424 results.Add(r);
12425 }
12426 }
12427 else
11114 { 12428 {
11115 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12429 if (checkTerrain)
11116 foreach (ContactResult r in objectHits) 12430 {
11117 results.Add(r); 12431 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12432 if (groundContact != null)
12433 results.Add((ContactResult)groundContact);
12434 }
12435
12436 if (checkAgents)
12437 {
12438 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12439 foreach (ContactResult r in agentHits)
12440 results.Add(r);
12441 }
12442
12443 if (checkPhysical || checkNonPhysical || detectPhantom)
12444 {
12445 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12446 foreach (ContactResult r in objectHits)
12447 results.Add(r);
12448 }
11118 } 12449 }
11119 12450
11120 results.Sort(delegate(ContactResult a, ContactResult b) 12451 results.Sort(delegate(ContactResult a, ContactResult b)
11121 { 12452 {
11122 return a.Depth.CompareTo(b.Depth); 12453 return a.Depth.CompareTo(b.Depth);
11123 }); 12454 });
11124 12455
11125 int values = 0; 12456 int values = 0;
11126 SceneObjectGroup thisgrp = m_host.ParentGroup; 12457 SceneObjectGroup thisgrp = m_host.ParentGroup;
11127 12458
@@ -11214,7 +12545,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11214 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12545 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11215 if (!isAccount) return 0; 12546 if (!isAccount) return 0;
11216 if (estate.HasAccess(id)) return 1; 12547 if (estate.HasAccess(id)) return 1;
11217 if (estate.IsBanned(id)) 12548 if (estate.IsBanned(id, World.GetUserFlags(id)))
11218 estate.RemoveBan(id); 12549 estate.RemoveBan(id);
11219 estate.AddEstateUser(id); 12550 estate.AddEstateUser(id);
11220 break; 12551 break;
@@ -11233,14 +12564,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11233 break; 12564 break;
11234 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12565 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11235 if (!isAccount) return 0; 12566 if (!isAccount) return 0;
11236 if (estate.IsBanned(id)) return 1; 12567 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11237 EstateBan ban = new EstateBan(); 12568 EstateBan ban = new EstateBan();
11238 ban.EstateID = estate.EstateID; 12569 ban.EstateID = estate.EstateID;
11239 ban.BannedUserID = id; 12570 ban.BannedUserID = id;
11240 estate.AddBan(ban); 12571 estate.AddBan(ban);
11241 break; 12572 break;
11242 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12573 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11243 if (!isAccount || !estate.IsBanned(id)) return 0; 12574 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11244 estate.RemoveBan(id); 12575 estate.RemoveBan(id);
11245 break; 12576 break;
11246 default: return 0; 12577 default: return 0;
@@ -11269,7 +12600,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11269 return 16384; 12600 return 16384;
11270 } 12601 }
11271 12602
11272 public LSL_Integer llGetUsedMemory() 12603 public virtual LSL_Integer llGetUsedMemory()
11273 { 12604 {
11274 m_host.AddScriptLPS(1); 12605 m_host.AddScriptLPS(1);
11275 // The value returned for LSO scripts in SL 12606 // The value returned for LSO scripts in SL
@@ -11297,7 +12628,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11297 public void llSetSoundQueueing(int queue) 12628 public void llSetSoundQueueing(int queue)
11298 { 12629 {
11299 m_host.AddScriptLPS(1); 12630 m_host.AddScriptLPS(1);
11300 NotImplemented("llSetSoundQueueing");
11301 } 12631 }
11302 12632
11303 public void llCollisionSprite(string impact_sprite) 12633 public void llCollisionSprite(string impact_sprite)
@@ -11309,10 +12639,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11309 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12639 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11310 { 12640 {
11311 m_host.AddScriptLPS(1); 12641 m_host.AddScriptLPS(1);
11312 NotImplemented("llGodLikeRezObject"); 12642
12643 if (!World.Permissions.IsGod(m_host.OwnerID))
12644 NotImplemented("llGodLikeRezObject");
12645
12646 AssetBase rezAsset = World.AssetService.Get(inventory);
12647 if (rezAsset == null)
12648 {
12649 llSay(0, "Asset not found");
12650 return;
12651 }
12652
12653 SceneObjectGroup group = null;
12654
12655 try
12656 {
12657 string xmlData = Utils.BytesToString(rezAsset.Data);
12658 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12659 }
12660 catch
12661 {
12662 llSay(0, "Asset not found");
12663 return;
12664 }
12665
12666 if (group == null)
12667 {
12668 llSay(0, "Asset not found");
12669 return;
12670 }
12671
12672 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12673 group.RootPart.AttachOffset = group.AbsolutePosition;
12674
12675 group.ResetIDs();
12676
12677 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12678 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12679 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12680 group.ScheduleGroupForFullUpdate();
12681
12682 // objects rezzed with this method are die_at_edge by default.
12683 group.RootPart.SetDieAtEdge(true);
12684
12685 group.ResumeScripts();
12686
12687 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12688 "object_rez", new Object[] {
12689 new LSL_String(
12690 group.RootPart.UUID.ToString()) },
12691 new DetectParams[0]));
12692 }
12693
12694 public LSL_String llTransferLindenDollars(string destination, int amount)
12695 {
12696 UUID txn = UUID.Random();
12697
12698 Util.FireAndForget(delegate(object x)
12699 {
12700 int replycode = 0;
12701 string replydata = destination + "," + amount.ToString();
12702
12703 try
12704 {
12705 TaskInventoryItem item = m_item;
12706 if (item == null)
12707 {
12708 replydata = "SERVICE_ERROR";
12709 return;
12710 }
12711
12712 m_host.AddScriptLPS(1);
12713
12714 if (item.PermsGranter == UUID.Zero)
12715 {
12716 replydata = "MISSING_PERMISSION_DEBIT";
12717 return;
12718 }
12719
12720 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12721 {
12722 replydata = "MISSING_PERMISSION_DEBIT";
12723 return;
12724 }
12725
12726 UUID toID = new UUID();
12727
12728 if (!UUID.TryParse(destination, out toID))
12729 {
12730 replydata = "INVALID_AGENT";
12731 return;
12732 }
12733
12734 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12735
12736 if (money == null)
12737 {
12738 replydata = "TRANSFERS_DISABLED";
12739 return;
12740 }
12741
12742 bool result = money.ObjectGiveMoney(
12743 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12744
12745 if (result)
12746 {
12747 replycode = 1;
12748 return;
12749 }
12750
12751 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12752 }
12753 finally
12754 {
12755 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12756 "transaction_result", new Object[] {
12757 new LSL_String(txn.ToString()),
12758 new LSL_Integer(replycode),
12759 new LSL_String(replydata) },
12760 new DetectParams[0]));
12761 }
12762 });
12763
12764 return txn.ToString();
11313 } 12765 }
11314 12766
11315 #endregion 12767 #endregion
12768
12769 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12770 {
12771 SceneObjectGroup group = m_host.ParentGroup;
12772
12773 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12774 return;
12775 if (group.IsAttachment)
12776 return;
12777
12778 if (frames.Data.Length > 0) // We are getting a new motion
12779 {
12780 if (group.RootPart.KeyframeMotion != null)
12781 group.RootPart.KeyframeMotion.Stop();
12782 group.RootPart.KeyframeMotion = null;
12783
12784 int idx = 0;
12785
12786 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12787 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12788
12789 while (idx < options.Data.Length)
12790 {
12791 int option = (int)options.GetLSLIntegerItem(idx++);
12792 int remain = options.Data.Length - idx;
12793
12794 switch (option)
12795 {
12796 case ScriptBaseClass.KFM_MODE:
12797 if (remain < 1)
12798 break;
12799 int modeval = (int)options.GetLSLIntegerItem(idx++);
12800 switch(modeval)
12801 {
12802 case ScriptBaseClass.KFM_FORWARD:
12803 mode = KeyframeMotion.PlayMode.Forward;
12804 break;
12805 case ScriptBaseClass.KFM_REVERSE:
12806 mode = KeyframeMotion.PlayMode.Reverse;
12807 break;
12808 case ScriptBaseClass.KFM_LOOP:
12809 mode = KeyframeMotion.PlayMode.Loop;
12810 break;
12811 case ScriptBaseClass.KFM_PING_PONG:
12812 mode = KeyframeMotion.PlayMode.PingPong;
12813 break;
12814 }
12815 break;
12816 case ScriptBaseClass.KFM_DATA:
12817 if (remain < 1)
12818 break;
12819 int dataval = (int)options.GetLSLIntegerItem(idx++);
12820 data = (KeyframeMotion.DataFormat)dataval;
12821 break;
12822 }
12823 }
12824
12825 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12826
12827 idx = 0;
12828
12829 int elemLength = 2;
12830 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12831 elemLength = 3;
12832
12833 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12834 while (idx < frames.Data.Length)
12835 {
12836 int remain = frames.Data.Length - idx;
12837
12838 if (remain < elemLength)
12839 break;
12840
12841 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12842 frame.Position = null;
12843 frame.Rotation = null;
12844
12845 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12846 {
12847 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12848 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12849 }
12850 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12851 {
12852 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12853 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12854 }
12855
12856 float tempf = (float)frames.GetLSLFloatItem(idx++);
12857 frame.TimeMS = (int)(tempf * 1000.0f);
12858
12859 keyframes.Add(frame);
12860 }
12861
12862 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12863 group.RootPart.KeyframeMotion.Start();
12864 }
12865 else
12866 {
12867 if (group.RootPart.KeyframeMotion == null)
12868 return;
12869
12870 if (options.Data.Length == 0)
12871 {
12872 group.RootPart.KeyframeMotion.Stop();
12873 return;
12874 }
12875
12876 int code = (int)options.GetLSLIntegerItem(0);
12877
12878 int idx = 0;
12879
12880 while (idx < options.Data.Length)
12881 {
12882 int option = (int)options.GetLSLIntegerItem(idx++);
12883 int remain = options.Data.Length - idx;
12884
12885 switch (option)
12886 {
12887 case ScriptBaseClass.KFM_COMMAND:
12888 int cmd = (int)options.GetLSLIntegerItem(idx++);
12889 switch (cmd)
12890 {
12891 case ScriptBaseClass.KFM_CMD_PLAY:
12892 group.RootPart.KeyframeMotion.Start();
12893 break;
12894 case ScriptBaseClass.KFM_CMD_STOP:
12895 group.RootPart.KeyframeMotion.Stop();
12896 break;
12897 case ScriptBaseClass.KFM_CMD_PAUSE:
12898 group.RootPart.KeyframeMotion.Pause();
12899 break;
12900 }
12901 break;
12902 }
12903 }
12904 }
12905 }
11316 } 12906 }
11317 12907
11318 public class NotecardCache 12908 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 7fa25f5..795376b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -920,18 +929,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
920 if (target != null) 929 if (target != null)
921 { 930 {
922 UUID animID=UUID.Zero; 931 UUID animID=UUID.Zero;
923 lock (m_host.TaskInventory) 932 m_host.TaskInventory.LockItemsForRead(true);
933 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
924 { 934 {
925 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 935 if (inv.Value.Name == animation)
926 { 936 {
927 if (inv.Value.Name == animation) 937 if (inv.Value.Type == (int)AssetType.Animation)
928 { 938 animID = inv.Value.AssetID;
929 if (inv.Value.Type == (int)AssetType.Animation) 939 continue;
930 animID = inv.Value.AssetID;
931 continue;
932 }
933 } 940 }
934 } 941 }
942 m_host.TaskInventory.LockItemsForRead(false);
935 if (animID == UUID.Zero) 943 if (animID == UUID.Zero)
936 target.Animator.AddAnimation(animation, m_host.UUID); 944 target.Animator.AddAnimation(animation, m_host.UUID);
937 else 945 else
@@ -972,6 +980,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
972 else 980 else
973 animID = UUID.Zero; 981 animID = UUID.Zero;
974 } 982 }
983 m_host.TaskInventory.LockItemsForRead(false);
975 984
976 if (animID == UUID.Zero) 985 if (animID == UUID.Zero)
977 target.Animator.RemoveAnimation(animation); 986 target.Animator.RemoveAnimation(animation);
@@ -1792,6 +1801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 1801
1793 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1802 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1794 { 1803 {
1804 m_host.TaskInventory.LockItemsForRead(true);
1795 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1805 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1796 { 1806 {
1797 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1807 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1799,6 +1809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1799 assetID = item.AssetID; 1809 assetID = item.AssetID;
1800 } 1810 }
1801 } 1811 }
1812 m_host.TaskInventory.LockItemsForRead(false);
1802 } 1813 }
1803 1814
1804 if (assetID == UUID.Zero) 1815 if (assetID == UUID.Zero)
@@ -2271,7 +2282,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2271 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2282 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2272 m_host.AddScriptLPS(1); 2283 m_host.AddScriptLPS(1);
2273 2284
2274 return NpcCreate(firstname, lastname, position, notecard, false, false); 2285 return NpcCreate(firstname, lastname, position, notecard, true, false);
2275 } 2286 }
2276 2287
2277 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2288 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2282,24 +2293,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2282 return NpcCreate( 2293 return NpcCreate(
2283 firstname, lastname, position, notecard, 2294 firstname, lastname, position, notecard,
2284 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2295 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2285 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2296 false);
2297// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2286 } 2298 }
2287 2299
2288 private LSL_Key NpcCreate( 2300 private LSL_Key NpcCreate(
2289 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2301 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2290 { 2302 {
2303 if (!owned)
2304 OSSLError("Unowned NPCs are unsupported");
2305
2306 string groupTitle = String.Empty;
2307
2308 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2309 return new LSL_Key(UUID.Zero.ToString());
2310
2311 if (firstname != String.Empty || lastname != String.Empty)
2312 {
2313 if (firstname != "Shown outfit:")
2314 groupTitle = "- NPC -";
2315 }
2316
2291 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2317 INPCModule module = World.RequestModuleInterface<INPCModule>();
2292 if (module != null) 2318 if (module != null)
2293 { 2319 {
2294 AvatarAppearance appearance = null; 2320 AvatarAppearance appearance = null;
2295 2321
2296 UUID id; 2322// UUID id;
2297 if (UUID.TryParse(notecard, out id)) 2323// if (UUID.TryParse(notecard, out id))
2298 { 2324// {
2299 ScenePresence clonePresence = World.GetScenePresence(id); 2325// ScenePresence clonePresence = World.GetScenePresence(id);
2300 if (clonePresence != null) 2326// if (clonePresence != null)
2301 appearance = clonePresence.Appearance; 2327// appearance = clonePresence.Appearance;
2302 } 2328// }
2303 2329
2304 if (appearance == null) 2330 if (appearance == null)
2305 { 2331 {
@@ -2327,6 +2353,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2327 World, 2353 World,
2328 appearance); 2354 appearance);
2329 2355
2356 ScenePresence sp;
2357 if (World.TryGetScenePresence(x, out sp))
2358 {
2359 sp.Grouptitle = groupTitle;
2360 sp.SendAvatarDataToAllAgents();
2361 }
2330 return new LSL_Key(x.ToString()); 2362 return new LSL_Key(x.ToString());
2331 } 2363 }
2332 2364
@@ -2618,16 +2650,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2618 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2650 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2619 m_host.AddScriptLPS(1); 2651 m_host.AddScriptLPS(1);
2620 2652
2621 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2653 ManualResetEvent ev = new ManualResetEvent(false);
2622 if (module != null)
2623 {
2624 UUID npcId = new UUID(npc.m_string);
2625 2654
2626 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2655 Util.FireAndForget(delegate(object x) {
2627 return; 2656 try
2657 {
2658 INPCModule module = World.RequestModuleInterface<INPCModule>();
2659 if (module != null)
2660 {
2661 UUID npcId = new UUID(npc.m_string);
2628 2662
2629 module.DeleteNPC(npcId, World); 2663 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2630 } 2664 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2665 {
2666 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2667 return;
2668 }
2669
2670 module.DeleteNPC(npcId, World);
2671 }
2672 }
2673 finally
2674 {
2675 ev.Set();
2676 }
2677 });
2678 ev.WaitOne();
2631 } 2679 }
2632 2680
2633 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2681 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3161,4 +3209,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3161 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3209 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3162 } 3210 }
3163 } 3211 }
3164} \ No newline at end of file 3212}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3844753..19f3ce1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -319,7 +319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.GetWorldRotation(); 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, rotate the sensor cone with the 326 // In attachments, rotate the sensor cone with the
@@ -333,7 +334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
333 // Position of a sensor in a child prim attached to an avatar 334 // Position of a sensor in a child prim attached to an avatar
334 // will be still wrong. 335 // will be still wrong.
335 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 336 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
336 q = avatar.Rotation * q; 337 fromRegionPos = avatar.AbsolutePosition;
338 q = avatar.Rotation;
337 } 339 }
338 340
339 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 341 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -463,7 +465,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
463 // Position of a sensor in a child prim attached to an avatar 465 // Position of a sensor in a child prim attached to an avatar
464 // will be still wrong. 466 // will be still wrong.
465 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 467 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
466 q = avatar.Rotation * q; 468 if (avatar == null)
469 return sensedEntities;
470 fromRegionPos = avatar.AbsolutePosition;
471 q = avatar.Rotation;
467 } 472 }
468 473
469 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 474 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index d39b204..749fc97 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,12 @@ 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 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -355,6 +357,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 357 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 358 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 359 void llSetPos(LSL_Vector pos);
360 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 361 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 362 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 363 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -421,9 +424,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
421 LSL_Vector llWind(LSL_Vector offset); 424 LSL_Vector llWind(LSL_Vector offset);
422 LSL_String llXorBase64Strings(string str1, string str2); 425 LSL_String llXorBase64Strings(string str1, string str2);
423 LSL_String llXorBase64StringsCorrect(string str1, string str2); 426 LSL_String llXorBase64StringsCorrect(string str1, string str2);
424 void print(string str); 427 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
428 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
425 429
426 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 430 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
427 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 431 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
432 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
428 } 433 }
429} 434}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index e92518d..7382495 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index b6c21e6..5c6ad8a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
95 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
96 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
97 98
98 //Particle Systems 99 //Particle Systems
99 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -282,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -586,6 +588,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
586 public const int PRIM_MEDIA_PERM_OWNER = 1; 588 public const int PRIM_MEDIA_PERM_OWNER = 1;
587 public const int PRIM_MEDIA_PERM_GROUP = 2; 589 public const int PRIM_MEDIA_PERM_GROUP = 2;
588 public const int PRIM_MEDIA_PERM_ANYONE = 4; 590 public const int PRIM_MEDIA_PERM_ANYONE = 4;
591
592 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
593 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
594 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
595 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
596
597 public const int PRIM_PHYSICS_MATERIAL = 31;
598 public const int DENSITY = 1;
599 public const int FRICTION = 2;
600 public const int RESTITUTION = 4;
601 public const int GRAVITY_MULTIPLIER = 8;
589 602
590 // extra constants for llSetPrimMediaParams 603 // extra constants for llSetPrimMediaParams
591 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 604 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -659,5 +672,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
659 public static readonly LSLInteger RCERR_UNKNOWN = -1; 672 public static readonly LSLInteger RCERR_UNKNOWN = -1;
660 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 673 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
661 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 674 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
675
676 public const int KFM_MODE = 1;
677 public const int KFM_LOOP = 1;
678 public const int KFM_REVERSE = 3;
679 public const int KFM_FORWARD = 0;
680 public const int KFM_PING_PONG = 2;
681 public const int KFM_DATA = 2;
682 public const int KFM_TRANSLATION = 2;
683 public const int KFM_ROTATION = 1;
684 public const int KFM_COMMAND = 0;
685 public const int KFM_CMD_PLAY = 0;
686 public const int KFM_CMD_STOP = 1;
687 public const int KFM_CMD_PAUSE = 2;
662 } 688 }
663} 689}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 06f5617..976969a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -164,6 +165,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
164 m_LSL_Functions.llBreakLink(linknum); 165 m_LSL_Functions.llBreakLink(linknum);
165 } 166 }
166 167
168 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
169 {
170 return m_LSL_Functions.llCastRay(start, end, options);
171 }
172
167 public LSL_Integer llCeil(double f) 173 public LSL_Integer llCeil(double f)
168 { 174 {
169 return m_LSL_Functions.llCeil(f); 175 return m_LSL_Functions.llCeil(f);
@@ -314,6 +320,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 320 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 321 }
316 322
323 [DebuggerNonUserCode]
317 public void llDie() 324 public void llDie()
318 { 325 {
319 m_LSL_Functions.llDie(); 326 m_LSL_Functions.llDie();
@@ -474,6 +481,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 481 return m_LSL_Functions.llGetFreeMemory();
475 } 482 }
476 483
484 public LSL_Integer llGetUsedMemory()
485 {
486 return m_LSL_Functions.llGetUsedMemory();
487 }
488
477 public LSL_Integer llGetFreeURLs() 489 public LSL_Integer llGetFreeURLs()
478 { 490 {
479 return m_LSL_Functions.llGetFreeURLs(); 491 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +591,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 591 return m_LSL_Functions.llGetMass();
580 } 592 }
581 593
594 public LSL_Float llGetMassMKS()
595 {
596 return m_LSL_Functions.llGetMassMKS();
597 }
598
582 public LSL_Integer llGetMemoryLimit() 599 public LSL_Integer llGetMemoryLimit()
583 { 600 {
584 return m_LSL_Functions.llGetMemoryLimit(); 601 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +861,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 861 return m_LSL_Functions.llGetUnixTime();
845 } 862 }
846 863
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 864 public LSL_Vector llGetVel()
853 { 865 {
854 return m_LSL_Functions.llGetVel(); 866 return m_LSL_Functions.llGetVel();
@@ -874,6 +886,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 886 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 887 }
876 888
889 public LSL_String llTransferLindenDollars(string destination, int amount)
890 {
891 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
892 }
893
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 894 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 895 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 896 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1598,6 +1615,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1598 m_LSL_Functions.llSetPos(pos); 1615 m_LSL_Functions.llSetPos(pos);
1599 } 1616 }
1600 1617
1618 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1619 {
1620 return m_LSL_Functions.llSetRegionPos(pos);
1621 }
1622
1601 public void llSetPrimitiveParams(LSL_List rules) 1623 public void llSetPrimitiveParams(LSL_List rules)
1602 { 1624 {
1603 m_LSL_Functions.llSetPrimitiveParams(rules); 1625 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1958,9 +1980,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1958 return m_LSL_Functions.llClearLinkMedia(link, face); 1980 return m_LSL_Functions.llClearLinkMedia(link, face);
1959 } 1981 }
1960 1982
1961 public void print(string str) 1983 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1984 {
1985 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1986 }
1987
1988 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1989 {
1990 m_LSL_Functions.llSetKeyframedMotion(frames, options);
1991 }
1992
1993 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1962 { 1994 {
1963 m_LSL_Functions.print(str); 1995 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1964 } 1996 }
1965 } 1997 }
1966} 1998}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..7e7e278 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index 306090e..3797683 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.IO; 29using System.IO;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Runtime.Remoting; 31using System.Runtime.Remoting;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Threading; 33using System.Threading;
@@ -221,13 +222,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
221 222
222 if (part != null) 223 if (part != null)
223 { 224 {
224 lock (part.TaskInventory) 225 part.TaskInventory.LockItemsForRead(true);
226 if (part.TaskInventory.ContainsKey(ItemID))
225 { 227 {
226 if (part.TaskInventory.ContainsKey(ItemID)) 228 ScriptTask = part.TaskInventory[ItemID];
227 {
228 ScriptTask = part.TaskInventory[ItemID];
229 }
230 } 229 }
230 part.TaskInventory.LockItemsForRead(false);
231 } 231 }
232 232
233 ApiManager am = new ApiManager(); 233 ApiManager am = new ApiManager();
@@ -426,14 +426,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
426 { 426 {
427 int permsMask; 427 int permsMask;
428 UUID permsGranter; 428 UUID permsGranter;
429 lock (part.TaskInventory) 429 part.TaskInventory.LockItemsForRead(true);
430 if (!part.TaskInventory.ContainsKey(ItemID))
430 { 431 {
431 if (!part.TaskInventory.ContainsKey(ItemID)) 432 part.TaskInventory.LockItemsForRead(false);
432 return; 433 return;
433
434 permsGranter = part.TaskInventory[ItemID].PermsGranter;
435 permsMask = part.TaskInventory[ItemID].PermsMask;
436 } 434 }
435 permsGranter = part.TaskInventory[ItemID].PermsGranter;
436 permsMask = part.TaskInventory[ItemID].PermsMask;
437 part.TaskInventory.LockItemsForRead(false);
437 438
438 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 439 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
439 { 440 {
@@ -561,6 +562,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
561 return true; 562 return true;
562 } 563 }
563 564
565 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
564 public void SetState(string state) 566 public void SetState(string state)
565 { 567 {
566 if (state == State) 568 if (state == State)
@@ -572,7 +574,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
572 new DetectParams[0])); 574 new DetectParams[0]));
573 PostEvent(new EventParams("state_entry", new Object[0], 575 PostEvent(new EventParams("state_entry", new Object[0],
574 new DetectParams[0])); 576 new DetectParams[0]));
575 577
576 throw new EventAbortException(); 578 throw new EventAbortException();
577 } 579 }
578 580
@@ -662,45 +664,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
662 /// <returns></returns> 664 /// <returns></returns>
663 public object EventProcessor() 665 public object EventProcessor()
664 { 666 {
667 EventParams data = null;
665 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 668 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
666 if (!Running) 669 if (!Running)
667 return 0; 670 return 0;
668 671
669 lock (m_Script)
670 {
671// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 672// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
672 673
673 if (Suspended) 674 if (Suspended)
674 return 0; 675 return 0;
675
676 EventParams data = null;
677 676
678 lock (EventQueue) 677 lock (EventQueue)
678 {
679 data = (EventParams) EventQueue.Dequeue();
680 if (data == null) // Shouldn't happen
679 { 681 {
680 data = (EventParams)EventQueue.Dequeue(); 682 if (EventQueue.Count > 0 && Running && !ShuttingDown)
681 if (data == null) // Shouldn't happen
682 { 683 {
683 if (EventQueue.Count > 0 && Running && !ShuttingDown) 684 m_CurrentWorkItem = Engine.QueueEventHandler(this);
684 {
685 m_CurrentWorkItem = Engine.QueueEventHandler(this);
686 }
687 else
688 {
689 m_CurrentWorkItem = null;
690 }
691 return 0;
692 } 685 }
693 686 else
694 if (data.EventName == "timer")
695 m_TimerQueued = false;
696 if (data.EventName == "control")
697 { 687 {
698 if (m_ControlEventsInQueue > 0) 688 m_CurrentWorkItem = null;
699 m_ControlEventsInQueue--;
700 } 689 }
701 if (data.EventName == "collision") 690 return 0;
702 m_CollisionInQueue = false;
703 } 691 }
692
693 if (data.EventName == "timer")
694 m_TimerQueued = false;
695 if (data.EventName == "control")
696 {
697 if (m_ControlEventsInQueue > 0)
698 m_ControlEventsInQueue--;
699 }
700 if (data.EventName == "collision")
701 m_CollisionInQueue = false;
702 }
703
704 lock(m_Script)
705 {
704 706
705// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 707// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
706 708
@@ -855,6 +857,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
855 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 857 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
856 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 858 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
857 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 859 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
860 part.CollisionSound = UUID.Zero;
858 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 861 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
859 EventQueue.Clear(); 862 EventQueue.Clear();
860 m_Script.ResetVars(); 863 m_Script.ResetVars();
@@ -869,6 +872,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
869 new Object[0], new DetectParams[0])); 872 new Object[0], new DetectParams[0]));
870 } 873 }
871 874
875 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
872 public void ApiResetScript() 876 public void ApiResetScript()
873 { 877 {
874 // bool running = Running; 878 // bool running = Running;
@@ -880,6 +884,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
880 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 884 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
881 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 885 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
882 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 886 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
887 part.CollisionSound = UUID.Zero;
883 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 888 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
884 889
885 EventQueue.Clear(); 890 EventQueue.Clear();
@@ -900,10 +905,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
900 905
901 public Dictionary<string, object> GetVars() 906 public Dictionary<string, object> GetVars()
902 { 907 {
903 if (m_Script != null) 908 return m_Script.GetVars();
904 return m_Script.GetVars();
905 else
906 return new Dictionary<string, object>();
907 } 909 }
908 910
909 public void SetVars(Dictionary<string, object> vars) 911 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..8adf4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {
diff --git a/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs b/OpenSim/Region/ScriptEngine/XEngine/XEngine.cs
index 06ed9d6..b1583b2 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.Reflection; 34using System.Reflection;
@@ -120,6 +121,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
120 private Dictionary<UUID, IScriptInstance> m_Scripts = 121 private Dictionary<UUID, IScriptInstance> m_Scripts =
121 new Dictionary<UUID, IScriptInstance>(); 122 new Dictionary<UUID, IScriptInstance>();
122 123
124 private OpenMetaverse.ReaderWriterLockSlim m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
125
123 // Maps the asset ID to the assembly 126 // Maps the asset ID to the assembly
124 127
125 private Dictionary<UUID, string> m_Assemblies = 128 private Dictionary<UUID, string> m_Assemblies =
@@ -142,6 +145,71 @@ namespace OpenSim.Region.ScriptEngine.XEngine
142 IWorkItemResult m_CurrentCompile = null; 145 IWorkItemResult m_CurrentCompile = null;
143 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>(); 146 private Dictionary<UUID, int> m_CompileDict = new Dictionary<UUID, int>();
144 147
148 private void lockScriptsForRead(bool locked)
149 {
150 if (locked)
151 {
152 if (m_scriptsLock.RecursiveReadCount > 0)
153 {
154 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.");
155 m_scriptsLock.ExitReadLock();
156 }
157 if (m_scriptsLock.RecursiveWriteCount > 0)
158 {
159 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
160 m_scriptsLock.ExitWriteLock();
161 }
162
163 while (!m_scriptsLock.TryEnterReadLock(60000))
164 {
165 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.");
166 if (m_scriptsLock.IsWriteLockHeld)
167 {
168 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
169 }
170 }
171 }
172 else
173 {
174 if (m_scriptsLock.RecursiveReadCount > 0)
175 {
176 m_scriptsLock.ExitReadLock();
177 }
178 }
179 }
180 private void lockScriptsForWrite(bool locked)
181 {
182 if (locked)
183 {
184 if (m_scriptsLock.RecursiveReadCount > 0)
185 {
186 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.");
187 m_scriptsLock.ExitReadLock();
188 }
189 if (m_scriptsLock.RecursiveWriteCount > 0)
190 {
191 m_log.Error("[XEngine.m_Scripts] Recursive write lock requested. This should not happen and means something needs to be fixed.");
192 m_scriptsLock.ExitWriteLock();
193 }
194
195 while (!m_scriptsLock.TryEnterWriteLock(60000))
196 {
197 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.");
198 if (m_scriptsLock.IsWriteLockHeld)
199 {
200 m_scriptsLock = new OpenMetaverse.ReaderWriterLockSlim();
201 }
202 }
203 }
204 else
205 {
206 if (m_scriptsLock.RecursiveWriteCount > 0)
207 {
208 m_scriptsLock.ExitWriteLock();
209 }
210 }
211 }
212
145 public string ScriptEngineName 213 public string ScriptEngineName
146 { 214 {
147 get { return "XEngine"; } 215 get { return "XEngine"; }
@@ -567,44 +635,37 @@ namespace OpenSim.Region.ScriptEngine.XEngine
567 { 635 {
568 if (!m_Enabled) 636 if (!m_Enabled)
569 return; 637 return;
570 638 lockScriptsForRead(true);
571 lock (m_Scripts) 639 foreach (IScriptInstance instance in m_Scripts.Values)
572 { 640 {
573 m_log.InfoFormat( 641 // Force a final state save
574 "[XEngine]: Shutting down {0} scripts in {1}", m_Scripts.Count, m_Scene.RegionInfo.RegionName); 642 //
575 643 if (m_Assemblies.ContainsKey(instance.AssetID))
576 foreach (IScriptInstance instance in m_Scripts.Values)
577 { 644 {
578 // Force a final state save 645 string assembly = m_Assemblies[instance.AssetID];
579 // 646 instance.SaveState(assembly);
580 if (m_Assemblies.ContainsKey(instance.AssetID)) 647 }
581 {
582 string assembly = m_Assemblies[instance.AssetID];
583 instance.SaveState(assembly);
584 }
585 648
586 // Clear the event queue and abort the instance thread 649 // Clear the event queue and abort the instance thread
587 // 650 //
588 instance.ClearQueue(); 651 instance.ClearQueue();
589 instance.Stop(0); 652 instance.Stop(0);
590 653
591 // Release events, timer, etc 654 // Release events, timer, etc
592 // 655 //
593 instance.DestroyScriptInstance(); 656 instance.DestroyScriptInstance();
594 657
595 // Unload scripts and app domains. 658 // Unload scripts and app domains
596 // Must be done explicitly because they have infinite 659 // Must be done explicitly because they have infinite
597 // lifetime. 660 // lifetime
598 // However, don't bother to do this if the simulator is shutting 661 //
599 // down since it takes a long time with many scripts. 662 if (!m_SimulatorShuttingDown)
600 if (!m_SimulatorShuttingDown) 663 {
664 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID);
665 if (m_DomainScripts[instance.AppDomain].Count == 0)
601 { 666 {
602 m_DomainScripts[instance.AppDomain].Remove(instance.ItemID); 667 m_DomainScripts.Remove(instance.AppDomain);
603 if (m_DomainScripts[instance.AppDomain].Count == 0) 668 UnloadAppDomain(instance.AppDomain);
604 {
605 m_DomainScripts.Remove(instance.AppDomain);
606 UnloadAppDomain(instance.AppDomain);
607 }
608 } 669 }
609 } 670 }
610 671
@@ -613,6 +674,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
613 m_Assemblies.Clear(); 674 m_Assemblies.Clear();
614 m_DomainScripts.Clear(); 675 m_DomainScripts.Clear();
615 } 676 }
677 lockScriptsForRead(false);
678 lockScriptsForWrite(true);
679 m_Scripts.Clear();
680 lockScriptsForWrite(false);
681 m_PrimObjects.Clear();
682 m_Assemblies.Clear();
683 m_DomainScripts.Clear();
684
616 lock (m_ScriptEngines) 685 lock (m_ScriptEngines)
617 { 686 {
618 m_ScriptEngines.Remove(this); 687 m_ScriptEngines.Remove(this);
@@ -677,22 +746,20 @@ namespace OpenSim.Region.ScriptEngine.XEngine
677 746
678 List<IScriptInstance> instances = new List<IScriptInstance>(); 747 List<IScriptInstance> instances = new List<IScriptInstance>();
679 748
680 lock (m_Scripts) 749 lockScriptsForRead(true);
681 { 750 foreach (IScriptInstance instance in m_Scripts.Values)
682 foreach (IScriptInstance instance in m_Scripts.Values)
683 instances.Add(instance); 751 instances.Add(instance);
684 } 752 lockScriptsForRead(false);
685 753
686 foreach (IScriptInstance i in instances) 754 foreach (IScriptInstance i in instances)
687 { 755 {
688 string assembly = String.Empty; 756 string assembly = String.Empty;
689 757
690 lock (m_Scripts) 758
691 {
692 if (!m_Assemblies.ContainsKey(i.AssetID)) 759 if (!m_Assemblies.ContainsKey(i.AssetID))
693 continue; 760 continue;
694 assembly = m_Assemblies[i.AssetID]; 761 assembly = m_Assemblies[i.AssetID];
695 } 762
696 763
697 i.SaveState(assembly); 764 i.SaveState(assembly);
698 } 765 }
@@ -1048,96 +1115,99 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1048 } 1115 }
1049 1116
1050 ScriptInstance instance = null; 1117 ScriptInstance instance = null;
1051 lock (m_Scripts) 1118 // Create the object record
1119 lockScriptsForRead(true);
1120 if ((!m_Scripts.ContainsKey(itemID)) ||
1121 (m_Scripts[itemID].AssetID != assetID))
1052 { 1122 {
1053 // Create the object record 1123 lockScriptsForRead(false);
1054 if ((!m_Scripts.ContainsKey(itemID)) ||
1055 (m_Scripts[itemID].AssetID != assetID))
1056 {
1057 UUID appDomain = assetID;
1058 1124
1059 if (part.ParentGroup.IsAttachment) 1125 UUID appDomain = assetID;
1060 appDomain = part.ParentGroup.RootPart.UUID;
1061 1126
1062 if (!m_AppDomains.ContainsKey(appDomain)) 1127 if (part.ParentGroup.IsAttachment)
1063 { 1128 appDomain = part.ParentGroup.RootPart.UUID;
1064 try
1065 {
1066 AppDomainSetup appSetup = new AppDomainSetup();
1067 appSetup.PrivateBinPath = Path.Combine(
1068 m_ScriptEnginesPath,
1069 m_Scene.RegionInfo.RegionID.ToString());
1070 1129
1071 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence; 1130 if (!m_AppDomains.ContainsKey(appDomain))
1072 Evidence evidence = new Evidence(baseEvidence); 1131 {
1132 try
1133 {
1134 AppDomainSetup appSetup = new AppDomainSetup();
1135 appSetup.PrivateBinPath = Path.Combine(
1136 m_ScriptEnginesPath,
1137 m_Scene.RegionInfo.RegionID.ToString());
1073 1138
1074 AppDomain sandbox; 1139 Evidence baseEvidence = AppDomain.CurrentDomain.Evidence;
1075 if (m_AppDomainLoading) 1140 Evidence evidence = new Evidence(baseEvidence);
1076 {
1077 sandbox = AppDomain.CreateDomain(
1078 m_Scene.RegionInfo.RegionID.ToString(),
1079 evidence, appSetup);
1080 sandbox.AssemblyResolve +=
1081 new ResolveEventHandler(
1082 AssemblyResolver.OnAssemblyResolve);
1083 }
1084 else
1085 {
1086 sandbox = AppDomain.CurrentDomain;
1087 }
1088
1089 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1090 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1091 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1092 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1093 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1094 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1095 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1096
1097 m_AppDomains[appDomain] = sandbox;
1098 1141
1099 m_DomainScripts[appDomain] = new List<UUID>(); 1142 AppDomain sandbox;
1143 if (m_AppDomainLoading)
1144 {
1145 sandbox = AppDomain.CreateDomain(
1146 m_Scene.RegionInfo.RegionID.ToString(),
1147 evidence, appSetup);
1148 m_AppDomains[appDomain].AssemblyResolve +=
1149 new ResolveEventHandler(
1150 AssemblyResolver.OnAssemblyResolve);
1100 } 1151 }
1101 catch (Exception e) 1152 else
1102 { 1153 {
1103 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString()); 1154 sandbox = AppDomain.CurrentDomain;
1104 m_ScriptErrorMessage += "Exception creating app domain:\n";
1105 m_ScriptFailCount++;
1106 lock (m_AddingAssemblies)
1107 {
1108 m_AddingAssemblies[assembly]--;
1109 }
1110 return false;
1111 } 1155 }
1112 }
1113 m_DomainScripts[appDomain].Add(itemID);
1114
1115 instance = new ScriptInstance(this, part,
1116 itemID, assetID, assembly,
1117 m_AppDomains[appDomain],
1118 part.ParentGroup.RootPart.Name,
1119 item.Name, startParam, postOnRez,
1120 stateSource, m_MaxScriptQueue);
1121
1122// if (DebugLevel >= 1)
1123 m_log.DebugFormat(
1124 "[XEngine] Loaded script {0}.{1}, item UUID {2}, prim UUID {3} @ {4}.{5}",
1125 part.ParentGroup.RootPart.Name, item.Name, itemID, part.UUID,
1126 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1127 1156
1128 if (presence != null) 1157 //PolicyLevel sandboxPolicy = PolicyLevel.CreateAppDomainLevel();
1158 //AllMembershipCondition sandboxMembershipCondition = new AllMembershipCondition();
1159 //PermissionSet sandboxPermissionSet = sandboxPolicy.GetNamedPermissionSet("Internet");
1160 //PolicyStatement sandboxPolicyStatement = new PolicyStatement(sandboxPermissionSet);
1161 //CodeGroup sandboxCodeGroup = new UnionCodeGroup(sandboxMembershipCondition, sandboxPolicyStatement);
1162 //sandboxPolicy.RootCodeGroup = sandboxCodeGroup;
1163 //sandbox.SetAppDomainPolicy(sandboxPolicy);
1164
1165 m_AppDomains[appDomain] = sandbox;
1166
1167 m_DomainScripts[appDomain] = new List<UUID>();
1168 }
1169 catch (Exception e)
1129 { 1170 {
1130 ShowScriptSaveResponse(item.OwnerID, 1171 m_log.ErrorFormat("[XEngine] Exception creating app domain:\n {0}", e.ToString());
1131 assetID, "Compile successful", true); 1172 m_ScriptErrorMessage += "Exception creating app domain:\n";
1173 m_ScriptFailCount++;
1174 lock (m_AddingAssemblies)
1175 {
1176 m_AddingAssemblies[assembly]--;
1177 }
1178 return false;
1132 } 1179 }
1180 }
1181 m_DomainScripts[appDomain].Add(itemID);
1182
1183 instance = new ScriptInstance(this, part,
1184 itemID, assetID, assembly,
1185 m_AppDomains[appDomain],
1186 part.ParentGroup.RootPart.Name,
1187 item.Name, startParam, postOnRez,
1188 stateSource, m_MaxScriptQueue);
1189
1190 m_log.DebugFormat(
1191 "[XEngine] Loaded script {0}.{1}, script UUID {2}, prim UUID {3} @ {4}.{5}",
1192 part.ParentGroup.RootPart.Name, item.Name, assetID, part.UUID,
1193 part.ParentGroup.RootPart.AbsolutePosition, part.ParentGroup.Scene.RegionInfo.RegionName);
1133 1194
1134 instance.AppDomain = appDomain; 1195 if (presence != null)
1135 instance.LineMap = linemap; 1196 {
1136 1197 ShowScriptSaveResponse(item.OwnerID,
1137 m_Scripts[itemID] = instance; 1198 assetID, "Compile successful", true);
1138 } 1199 }
1139 }
1140 1200
1201 instance.AppDomain = appDomain;
1202 instance.LineMap = linemap;
1203 lockScriptsForWrite(true);
1204 m_Scripts[itemID] = instance;
1205 lockScriptsForWrite(false);
1206 }
1207 else
1208 {
1209 lockScriptsForRead(false);
1210 }
1141 lock (m_PrimObjects) 1211 lock (m_PrimObjects)
1142 { 1212 {
1143 if (!m_PrimObjects.ContainsKey(localID)) 1213 if (!m_PrimObjects.ContainsKey(localID))
@@ -1155,9 +1225,9 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1155 m_AddingAssemblies[assembly]--; 1225 m_AddingAssemblies[assembly]--;
1156 } 1226 }
1157 1227
1158 if (instance != null) 1228 if (instance!=null)
1159 instance.Init(); 1229 instance.Init();
1160 1230
1161 return true; 1231 return true;
1162 } 1232 }
1163 1233
@@ -1170,18 +1240,28 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1170 m_CompileDict.Remove(itemID); 1240 m_CompileDict.Remove(itemID);
1171 } 1241 }
1172 1242
1173 IScriptInstance instance = null; 1243 lockScriptsForRead(true);
1174 1244 // Do we even have it?
1175 lock (m_Scripts) 1245 if (!m_Scripts.ContainsKey(itemID))
1176 { 1246 {
1177 // Do we even have it? 1247 // Do we even have it?
1178 if (!m_Scripts.ContainsKey(itemID)) 1248 if (!m_Scripts.ContainsKey(itemID))
1179 return; 1249 return;
1180 1250
1181 instance = m_Scripts[itemID]; 1251 lockScriptsForRead(false);
1252 lockScriptsForWrite(true);
1182 m_Scripts.Remove(itemID); 1253 m_Scripts.Remove(itemID);
1254 lockScriptsForWrite(false);
1255
1256 return;
1183 } 1257 }
1258
1184 1259
1260 IScriptInstance instance=m_Scripts[itemID];
1261 lockScriptsForRead(false);
1262 lockScriptsForWrite(true);
1263 m_Scripts.Remove(itemID);
1264 lockScriptsForWrite(false);
1185 instance.ClearQueue(); 1265 instance.ClearQueue();
1186 1266
1187 // Give the script some time to finish processing its last event. Simply aborting the script thread can 1267 // Give the script some time to finish processing its last event. Simply aborting the script thread can
@@ -1220,8 +1300,13 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1220 1300
1221 ObjectRemoved handlerObjectRemoved = OnObjectRemoved; 1301 ObjectRemoved handlerObjectRemoved = OnObjectRemoved;
1222 if (handlerObjectRemoved != null) 1302 if (handlerObjectRemoved != null)
1223 handlerObjectRemoved(instance.ObjectID); 1303 {
1304 SceneObjectPart part = m_Scene.GetSceneObjectPart(localID);
1305 handlerObjectRemoved(part.UUID);
1306 }
1224 1307
1308 CleanAssemblies();
1309
1225 ScriptRemoved handlerScriptRemoved = OnScriptRemoved; 1310 ScriptRemoved handlerScriptRemoved = OnScriptRemoved;
1226 if (handlerScriptRemoved != null) 1311 if (handlerScriptRemoved != null)
1227 handlerScriptRemoved(itemID); 1312 handlerScriptRemoved(itemID);
@@ -1482,12 +1567,14 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1482 private IScriptInstance GetInstance(UUID itemID) 1567 private IScriptInstance GetInstance(UUID itemID)
1483 { 1568 {
1484 IScriptInstance instance; 1569 IScriptInstance instance;
1485 lock (m_Scripts) 1570 lockScriptsForRead(true);
1571 if (!m_Scripts.ContainsKey(itemID))
1486 { 1572 {
1487 if (!m_Scripts.ContainsKey(itemID)) 1573 lockScriptsForRead(false);
1488 return null; 1574 return null;
1489 instance = m_Scripts[itemID];
1490 } 1575 }
1576 instance = m_Scripts[itemID];
1577 lockScriptsForRead(false);
1491 return instance; 1578 return instance;
1492 } 1579 }
1493 1580
@@ -1518,6 +1605,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1518 return false; 1605 return false;
1519 } 1606 }
1520 1607
1608 [DebuggerNonUserCode]
1521 public void ApiResetScript(UUID itemID) 1609 public void ApiResetScript(UUID itemID)
1522 { 1610 {
1523 IScriptInstance instance = GetInstance(itemID); 1611 IScriptInstance instance = GetInstance(itemID);
@@ -1569,6 +1657,7 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1569 return UUID.Zero; 1657 return UUID.Zero;
1570 } 1658 }
1571 1659
1660 [DebuggerNonUserCode]
1572 public void SetState(UUID itemID, string newState) 1661 public void SetState(UUID itemID, string newState)
1573 { 1662 {
1574 IScriptInstance instance = GetInstance(itemID); 1663 IScriptInstance instance = GetInstance(itemID);
@@ -1591,11 +1680,10 @@ namespace OpenSim.Region.ScriptEngine.XEngine
1591 1680
1592 List<IScriptInstance> instances = new List<IScriptInstance>(); 1681 List<IScriptInstance> instances = new List<IScriptInstance>();
1593 1682
1594 lock (m_Scripts) 1683 lockScriptsForRead(true);
1595 { 1684 foreach (IScriptInstance instance in m_Scripts.Values)
1596 foreach (IScriptInstance instance in m_Scripts.Values)
1597 instances.Add(instance); 1685 instances.Add(instance);
1598 } 1686 lockScriptsForRead(false);
1599 1687
1600 foreach (IScriptInstance i in instances) 1688 foreach (IScriptInstance i in instances)
1601 { 1689 {
@@ -2050,5 +2138,17 @@ namespace OpenSim.Region.ScriptEngine.XEngine
2050// else 2138// else
2051// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID); 2139// m_log.DebugFormat("[XEngine]: Could not find script with ID {0} to resume", itemID);
2052 } 2140 }
2141
2142 public bool HasScript(UUID itemID, out bool running)
2143 {
2144 running = true;
2145
2146 IScriptInstance instance = GetInstance(itemID);
2147 if (instance == null)
2148 return false;
2149
2150 running = instance.Running;
2151 return true;
2152 }
2053 } 2153 }
2054} 2154}