aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3530
1 files changed, 2434 insertions, 1096 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 975bf2d..8892b69 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70using System.Linq; 74using System.Linq;
71using PermissionMask = OpenSim.Framework.PermissionMask; 75using PermissionMask = OpenSim.Framework.PermissionMask;
72 76
@@ -115,11 +119,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
115 protected int m_notecardLineReadCharsMax = 255; 119 protected int m_notecardLineReadCharsMax = 255;
116 protected int m_scriptConsoleChannel = 0; 120 protected int m_scriptConsoleChannel = 0;
117 protected bool m_scriptConsoleChannelEnabled = false; 121 protected bool m_scriptConsoleChannelEnabled = false;
122 protected bool m_debuggerSafe = false;
118 protected IUrlModule m_UrlModule = null; 123 protected IUrlModule m_UrlModule = null;
119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 124 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 125 new Dictionary<UUID, UserInfoCacheEntry>();
126 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
121 protected ISoundModule m_SoundModule = null; 127 protected ISoundModule m_SoundModule = null;
122 128
129// protected Timer m_ShoutSayTimer;
130 protected int m_SayShoutCount = 0;
131 DateTime m_lastSayShoutCheck;
132
133 private Dictionary<string, string> MovementAnimationsForLSL =
134 new Dictionary<string, string> {
135 {"FLY", "Flying"},
136 {"FLYSLOW", "FlyingSlow"},
137 {"HOVER_UP", "Hovering Up"},
138 {"HOVER_DOWN", "Hovering Down"},
139 {"HOVER", "Hovering"},
140 {"LAND", "Landing"},
141 {"FALLDOWN", "Falling Down"},
142 {"PREJUMP", "PreJumping"},
143 {"JUMP", "Jumping"},
144 {"STANDUP", "Standing Up"},
145 {"SOFT_LAND", "Soft Landing"},
146 {"STAND", "Standing"},
147 {"CROUCHWALK", "CrouchWalking"},
148 {"RUN", "Running"},
149 {"WALK", "Walking"},
150 {"CROUCH", "Crouching"},
151 {"TURNLEFT", "Turning Left"},
152 {"TURNRIGHT", "Turning Right"}
153 };
123 //An array of HTTP/1.1 headers that are not allowed to be used 154 //An array of HTTP/1.1 headers that are not allowed to be used
124 //as custom headers by llHTTPRequest. 155 //as custom headers by llHTTPRequest.
125 private string[] HttpStandardHeaders = 156 private string[] HttpStandardHeaders =
@@ -140,9 +171,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 public void Initialize( 171 public void Initialize(
141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
142 { 173 {
174 m_lastSayShoutCheck = DateTime.UtcNow;
175
143 m_ScriptEngine = scriptEngine; 176 m_ScriptEngine = scriptEngine;
144 m_host = host; 177 m_host = host;
145 m_item = item; 178 m_item = item;
179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 m_coopSleepHandle = coopSleepHandle; 180 m_coopSleepHandle = coopSleepHandle;
147 181
148 LoadConfig(); 182 LoadConfig();
@@ -231,6 +265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
231 get { return m_ScriptEngine.World; } 265 get { return m_ScriptEngine.World; }
232 } 266 }
233 267
268 [DebuggerNonUserCode]
234 public void state(string newState) 269 public void state(string newState)
235 { 270 {
236 m_ScriptEngine.SetState(m_item.ItemID, newState); 271 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -240,6 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
240 /// Reset the named script. The script must be present 275 /// Reset the named script. The script must be present
241 /// in the same prim. 276 /// in the same prim.
242 /// </summary> 277 /// </summary>
278 [DebuggerNonUserCode]
243 public void llResetScript() 279 public void llResetScript()
244 { 280 {
245 m_host.AddScriptLPS(1); 281 m_host.AddScriptLPS(1);
@@ -302,6 +338,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
302 } 338 }
303 } 339 }
304 340
341 public List<ScenePresence> GetLinkAvatars(int linkType)
342 {
343 List<ScenePresence> ret = new List<ScenePresence>();
344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
345 return ret;
346
347 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
348
349 switch (linkType)
350 {
351 case ScriptBaseClass.LINK_SET:
352 return avs;
353
354 case ScriptBaseClass.LINK_ROOT:
355 return ret;
356
357 case ScriptBaseClass.LINK_ALL_OTHERS:
358 return avs;
359
360 case ScriptBaseClass.LINK_ALL_CHILDREN:
361 return avs;
362
363 case ScriptBaseClass.LINK_THIS:
364 return ret;
365
366 default:
367 if (linkType < 0)
368 return ret;
369
370 int partCount = m_host.ParentGroup.GetPartCount();
371
372 if (linkType <= partCount)
373 {
374 return ret;
375 }
376 else
377 {
378 linkType = linkType - partCount;
379 if (linkType > avs.Count)
380 {
381 return ret;
382 }
383 else
384 {
385 ret.Add(avs[linkType-1]);
386 return ret;
387 }
388 }
389 }
390 }
391
305 /// <summary> 392 /// <summary>
306 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
307 /// </summary> 394 /// </summary>
@@ -384,6 +471,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 471 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
385 { 472 {
386 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 473 List<SceneObjectPart> ret = new List<SceneObjectPart>();
474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
475 return ret;
387 ret.Add(part); 476 ret.Add(part);
388 477
389 switch (linkType) 478 switch (linkType)
@@ -537,31 +626,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
537 626
538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 627 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
539 628
540 /// <summary> 629 // Utility function for llRot2Euler
541 /// Convert an LSL rotation to a Euler vector. 630
542 /// </summary> 631 // normalize an angle between -PI and PI (-180 to +180 degrees)
543 /// <remarks> 632 protected double NormalizeAngle(double angle)
544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
546 /// </remarks>
547 /// <param name="r"></param>
548 /// <returns></returns>
549 public LSL_Vector llRot2Euler(LSL_Rotation r)
550 { 633 {
551 m_host.AddScriptLPS(1); 634 if (angle > -Math.PI && angle < Math.PI)
635 return angle;
552 636
553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 637 int numPis = (int)(Math.PI / angle);
554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 638 double remainder = angle - Math.PI * numPis;
555 if (m == 0.0) return new LSL_Vector(); 639 if (numPis % 2 == 1)
556 double x = Math.Atan2(-v.y, v.z); 640 return Math.PI - angle;
557 double sin = v.x / m; 641 return remainder;
558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 642 }
559 double y = Math.Asin(sin);
560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
561 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
562 double z = Math.Atan2(v.y, v.x);
563 643
564 return new LSL_Vector(x, y, z); 644 public LSL_Vector llRot2Euler(LSL_Rotation q1)
645 {
646 m_host.AddScriptLPS(1);
647 LSL_Vector eul = new LSL_Vector();
648
649 double sqw = q1.s*q1.s;
650 double sqx = q1.x*q1.x;
651 double sqy = q1.z*q1.z;
652 double sqz = q1.y*q1.y;
653 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
654 double test = q1.x*q1.z + q1.y*q1.s;
655 if (test > 0.4999*unit) { // singularity at north pole
656 eul.z = 2 * Math.Atan2(q1.x,q1.s);
657 eul.y = Math.PI/2;
658 eul.x = 0;
659 return eul;
660 }
661 if (test < -0.4999*unit) { // singularity at south pole
662 eul.z = -2 * Math.Atan2(q1.x,q1.s);
663 eul.y = -Math.PI/2;
664 eul.x = 0;
665 return eul;
666 }
667 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
668 eul.y = Math.Asin(2*test/unit);
669 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
670 return eul;
565 } 671 }
566 672
567 /* From wiki: 673 /* From wiki:
@@ -614,18 +720,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
614 m_host.AddScriptLPS(1); 720 m_host.AddScriptLPS(1);
615 721
616 double x,y,z,s; 722 double x,y,z,s;
617 723 v.x *= 0.5;
618 double c1 = Math.Cos(v.x * 0.5); 724 v.y *= 0.5;
619 double c2 = Math.Cos(v.y * 0.5); 725 v.z *= 0.5;
620 double c3 = Math.Cos(v.z * 0.5); 726 double c1 = Math.Cos(v.x);
621 double s1 = Math.Sin(v.x * 0.5); 727 double c2 = Math.Cos(v.y);
622 double s2 = Math.Sin(v.y * 0.5); 728 double c1c2 = c1 * c2;
623 double s3 = Math.Sin(v.z * 0.5); 729 double s1 = Math.Sin(v.x);
624 730 double s2 = Math.Sin(v.y);
625 x = s1 * c2 * c3 + c1 * s2 * s3; 731 double s1s2 = s1 * s2;
626 y = c1 * s2 * c3 - s1 * c2 * s3; 732 double c1s2 = c1 * s2;
627 z = s1 * s2 * c3 + c1 * c2 * s3; 733 double s1c2 = s1 * c2;
628 s = c1 * c2 * c3 - s1 * s2 * s3; 734 double c3 = Math.Cos(v.z);
735 double s3 = Math.Sin(v.z);
736
737 x = s1c2 * c3 + c1s2 * s3;
738 y = c1s2 * c3 - s1c2 * s3;
739 z = s1s2 * c3 + c1c2 * s3;
740 s = c1c2 * c3 - s1s2 * s3;
629 741
630 return new LSL_Rotation(x, y, z, s); 742 return new LSL_Rotation(x, y, z, s);
631 } 743 }
@@ -763,77 +875,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
763 { 875 {
764 //A and B should both be normalized 876 //A and B should both be normalized
765 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
766 LSL_Rotation rotBetween; 878 /* This method is more accurate than the SL one, and thus causes problems
767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 879 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
768 // continue calculation. 880
769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 881 double dotProduct = LSL_Vector.Dot(a, b);
770 { 882 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 883 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
772 } 884 double angle = Math.Acos(dotProduct / magProduct);
773 else 885 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
774 { 886 double s = Math.Sin(angle / 2);
775 a = LSL_Vector.Norm(a); 887
776 b = LSL_Vector.Norm(b); 888 double x = axis.x * s;
777 double dotProduct = LSL_Vector.Dot(a, b); 889 double y = axis.y * s;
778 // There are two degenerate cases possible. These are for vectors 180 or 890 double z = axis.z * s;
779 // 0 degrees apart. These have to be detected and handled individually. 891 double w = Math.Cos(angle / 2);
780 // 892
781 // Check for vectors 180 degrees apart. 893 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
782 // A dot product of -1 would mean the angle between vectors is 180 degrees. 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
783 if (dotProduct < -0.9999999f) 895
784 { 896 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
785 // First assume X axis is orthogonal to the vectors. 897 */
786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 898
787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 899 // This method mimics the 180 errors found in SL
788 // Check for near zero vector. A very small non-zero number here will create 900 // See www.euclideanspace.com... angleBetween
789 // a rotation in an undesired direction. 901 LSL_Vector vec_a = a;
790 if (LSL_Vector.Mag(orthoVector) > 0.0001) 902 LSL_Vector vec_b = b;
791 { 903
792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 904 // Eliminate zero length
793 } 905 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
794 // If the magnitude of the vector was near zero, then assume the X axis is not 906 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
795 // orthogonal and use the Z axis instead. 907 if (vec_a_mag < 0.00001 ||
796 else 908 vec_b_mag < 0.00001)
797 { 909 {
798 // Set 180 z rotation. 910 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 911 }
800 } 912
801 } 913 // Normalize
802 // Check for parallel vectors. 914 vec_a = llVecNorm(vec_a);
803 // A dot product of 1 would mean the angle between vectors is 0 degrees. 915 vec_b = llVecNorm(vec_b);
804 else if (dotProduct > 0.9999999f) 916
805 { 917 // Calculate axis and rotation angle
806 // Set zero rotation. 918 LSL_Vector axis = vec_a % vec_b;
807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 919 LSL_Float cos_theta = vec_a * vec_b;
808 } 920
809 else 921 // Check if parallel
810 { 922 if (cos_theta > 0.99999)
811 // All special checks have been performed so get the axis of rotation. 923 {
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 924 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813 // Quarternion s value is the length of the unit vector + dot product. 925 }
814 double qs = 1.0 + dotProduct; 926
815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 927 // Check if anti-parallel
816 // Normalize the rotation. 928 else if (cos_theta < -0.99999)
817 double mag = LSL_Rotation.Mag(rotBetween); 929 {
818 // We shouldn't have to worry about a divide by zero here. The qs value will be 930 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
819 // non-zero because we already know if we're here, then the dotProduct is not -1 so 931 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
820 // qs will not be zero. Also, we've already handled the input vectors being zero so the 932 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
821 // crossProduct vector should also not be zero. 933 }
822 rotBetween.x = rotBetween.x / mag; 934 else // other rotation
823 rotBetween.y = rotBetween.y / mag; 935 {
824 rotBetween.z = rotBetween.z / mag; 936 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
825 rotBetween.s = rotBetween.s / mag; 937 axis = llVecNorm(axis);
826 // Check for undefined values and set zero rotation if any found. This code might not actually be required 938 double x, y, z, s, t;
827 // any longer since zero vectors are checked for at the top. 939 s = Math.Cos(theta);
828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 940 t = Math.Sin(theta);
829 { 941 x = axis.x * t;
830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 942 y = axis.y * t;
831 } 943 z = axis.z * t;
832 } 944 return new LSL_Rotation(x,y,z,s);
833 } 945 }
834 return rotBetween; 946 }
835 } 947
836
837 public void llWhisper(int channelID, string text) 948 public void llWhisper(int channelID, string text)
838 { 949 {
839 m_host.AddScriptLPS(1); 950 m_host.AddScriptLPS(1);
@@ -849,10 +960,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 960 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
850 } 961 }
851 962
963 private void CheckSayShoutTime()
964 {
965 DateTime now = DateTime.UtcNow;
966 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
967 {
968 m_lastSayShoutCheck = now;
969 m_SayShoutCount = 0;
970 }
971 else
972 m_SayShoutCount++;
973 }
974
852 public void llSay(int channelID, string text) 975 public void llSay(int channelID, string text)
853 { 976 {
854 m_host.AddScriptLPS(1); 977 m_host.AddScriptLPS(1);
855 978
979 if (channelID == 0)
980// m_SayShoutCount++;
981 CheckSayShoutTime();
982
983 if (m_SayShoutCount >= 11)
984 ScriptSleep(2000);
985
856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 986 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
857 { 987 {
858 Console.WriteLine(text); 988 Console.WriteLine(text);
@@ -875,6 +1005,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 { 1005 {
876 m_host.AddScriptLPS(1); 1006 m_host.AddScriptLPS(1);
877 1007
1008 if (channelID == 0)
1009// m_SayShoutCount++;
1010 CheckSayShoutTime();
1011
1012 if (m_SayShoutCount >= 11)
1013 ScriptSleep(2000);
1014
878 if (text.Length > 1023) 1015 if (text.Length > 1023)
879 text = text.Substring(0, 1023); 1016 text = text.Substring(0, 1023);
880 1017
@@ -906,22 +1043,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
906 1043
907 public void llRegionSayTo(string target, int channel, string msg) 1044 public void llRegionSayTo(string target, int channel, string msg)
908 { 1045 {
1046 string error = String.Empty;
1047
909 if (msg.Length > 1023) 1048 if (msg.Length > 1023)
910 msg = msg.Substring(0, 1023); 1049 msg = msg.Substring(0, 1023);
911 1050
912 m_host.AddScriptLPS(1); 1051 m_host.AddScriptLPS(1);
913 1052
914 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
915 {
916 return;
917 }
918
919 UUID TargetID; 1053 UUID TargetID;
920 UUID.TryParse(target, out TargetID); 1054 UUID.TryParse(target, out TargetID);
921 1055
922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1056 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
923 if (wComm != null) 1057 if (wComm != null)
924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1058 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1059 LSLError(error);
925 } 1060 }
926 1061
927 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1062 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1177,10 +1312,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 return detectedParams.TouchUV; 1312 return detectedParams.TouchUV;
1178 } 1313 }
1179 1314
1315 [DebuggerNonUserCode]
1180 public virtual void llDie() 1316 public virtual void llDie()
1181 { 1317 {
1182 m_host.AddScriptLPS(1); 1318 m_host.AddScriptLPS(1);
1183 throw new SelfDeleteException(); 1319 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1184 } 1320 }
1185 1321
1186 public LSL_Float llGround(LSL_Vector offset) 1322 public LSL_Float llGround(LSL_Vector offset)
@@ -1251,6 +1387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1251 1387
1252 public void llSetStatus(int status, int value) 1388 public void llSetStatus(int status, int value)
1253 { 1389 {
1390 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1391 return;
1254 m_host.AddScriptLPS(1); 1392 m_host.AddScriptLPS(1);
1255 1393
1256 int statusrotationaxis = 0; 1394 int statusrotationaxis = 0;
@@ -1274,6 +1412,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1274 if (!allow) 1412 if (!allow)
1275 return; 1413 return;
1276 1414
1415 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1416 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1417 return;
1418
1277 m_host.ScriptSetPhysicsStatus(true); 1419 m_host.ScriptSetPhysicsStatus(true);
1278 } 1420 }
1279 else 1421 else
@@ -1474,12 +1616,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1474 { 1616 {
1475 m_host.AddScriptLPS(1); 1617 m_host.AddScriptLPS(1);
1476 1618
1619 SetColor(m_host, color, face);
1620 }
1621
1622 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1623 {
1624 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1625 return;
1626
1627 Primitive.TextureEntry tex = part.Shape.Textures;
1628 Color4 texcolor;
1629 if (face >= 0 && face < GetNumberOfSides(part))
1630 {
1631 texcolor = tex.CreateFace((uint)face).RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.FaceTextures[face].RGBA = texcolor;
1636 part.UpdateTextureEntry(tex.GetBytes());
1637 return;
1638 }
1639 else if (face == ScriptBaseClass.ALL_SIDES)
1640 {
1641 for (uint i = 0; i < GetNumberOfSides(part); i++)
1642 {
1643 if (tex.FaceTextures[i] != null)
1644 {
1645 texcolor = tex.FaceTextures[i].RGBA;
1646 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1647 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1648 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1649 tex.FaceTextures[i].RGBA = texcolor;
1650 }
1651 texcolor = tex.DefaultTexture.RGBA;
1652 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1653 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1654 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1655 tex.DefaultTexture.RGBA = texcolor;
1656 }
1657 part.UpdateTextureEntry(tex.GetBytes());
1658 return;
1659 }
1660
1477 if (face == ScriptBaseClass.ALL_SIDES) 1661 if (face == ScriptBaseClass.ALL_SIDES)
1478 face = SceneObjectPart.ALL_SIDES; 1662 face = SceneObjectPart.ALL_SIDES;
1479 1663
1480 m_host.SetFaceColorAlpha(face, color, null); 1664 m_host.SetFaceColorAlpha(face, color, null);
1481 } 1665 }
1482 1666
1667 /*
1483 public void llSetContentType(LSL_Key id, LSL_Integer type) 1668 public void llSetContentType(LSL_Key id, LSL_Integer type)
1484 { 1669 {
1485 m_host.AddScriptLPS(1); 1670 m_host.AddScriptLPS(1);
@@ -1546,9 +1731,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1546 break; 1731 break;
1547 } 1732 }
1548 } 1733 }
1734 */
1549 1735
1550 public void SetTexGen(SceneObjectPart part, int face,int style) 1736 public void SetTexGen(SceneObjectPart part, int face,int style)
1551 { 1737 {
1738 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1739 return;
1740
1552 Primitive.TextureEntry tex = part.Shape.Textures; 1741 Primitive.TextureEntry tex = part.Shape.Textures;
1553 MappingType textype; 1742 MappingType textype;
1554 textype = MappingType.Default; 1743 textype = MappingType.Default;
@@ -1579,6 +1768,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 1768
1580 public void SetGlow(SceneObjectPart part, int face, float glow) 1769 public void SetGlow(SceneObjectPart part, int face, float glow)
1581 { 1770 {
1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1772 return;
1773
1582 Primitive.TextureEntry tex = part.Shape.Textures; 1774 Primitive.TextureEntry tex = part.Shape.Textures;
1583 if (face >= 0 && face < GetNumberOfSides(part)) 1775 if (face >= 0 && face < GetNumberOfSides(part))
1584 { 1776 {
@@ -1604,6 +1796,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1604 1796
1605 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1797 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1606 { 1798 {
1799 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1800 return;
1607 1801
1608 Shininess sval = new Shininess(); 1802 Shininess sval = new Shininess();
1609 1803
@@ -1654,6 +1848,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1654 1848
1655 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1849 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1656 { 1850 {
1851 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1852 return;
1853
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1854 Primitive.TextureEntry tex = part.Shape.Textures;
1658 if (face >= 0 && face < GetNumberOfSides(part)) 1855 if (face >= 0 && face < GetNumberOfSides(part))
1659 { 1856 {
@@ -1714,13 +1911,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 m_host.AddScriptLPS(1); 1911 m_host.AddScriptLPS(1);
1715 1912
1716 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1913 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1717 1914 if (parts.Count > 0)
1718 foreach (SceneObjectPart part in parts) 1915 {
1719 SetAlpha(part, alpha, face); 1916 try
1917 {
1918 foreach (SceneObjectPart part in parts)
1919 SetAlpha(part, alpha, face);
1920 }
1921 finally
1922 {
1923 }
1924 }
1720 } 1925 }
1721 1926
1722 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1927 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1723 { 1928 {
1929 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1930 return;
1931
1724 Primitive.TextureEntry tex = part.Shape.Textures; 1932 Primitive.TextureEntry tex = part.Shape.Textures;
1725 Color4 texcolor; 1933 Color4 texcolor;
1726 if (face >= 0 && face < GetNumberOfSides(part)) 1934 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1773,7 +1981,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1773 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1981 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1774 float wind, float tension, LSL_Vector Force) 1982 float wind, float tension, LSL_Vector Force)
1775 { 1983 {
1776 if (part == null) 1984 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1777 return; 1985 return;
1778 1986
1779 if (flexi) 1987 if (flexi)
@@ -1814,7 +2022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 /// <param name="falloff"></param> 2022 /// <param name="falloff"></param>
1815 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 2023 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1816 { 2024 {
1817 if (part == null) 2025 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1818 return; 2026 return;
1819 2027
1820 if (light) 2028 if (light)
@@ -1847,11 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 Primitive.TextureEntry tex = part.Shape.Textures; 2055 Primitive.TextureEntry tex = part.Shape.Textures;
1848 Color4 texcolor; 2056 Color4 texcolor;
1849 LSL_Vector rgb = new LSL_Vector(); 2057 LSL_Vector rgb = new LSL_Vector();
2058 int nsides = GetNumberOfSides(part);
2059
1850 if (face == ScriptBaseClass.ALL_SIDES) 2060 if (face == ScriptBaseClass.ALL_SIDES)
1851 { 2061 {
1852 int i; 2062 int i;
1853 2063 for (i = 0; i < nsides; i++)
1854 for (i = 0 ; i < GetNumberOfSides(part); i++)
1855 { 2064 {
1856 texcolor = tex.GetFace((uint)i).RGBA; 2065 texcolor = tex.GetFace((uint)i).RGBA;
1857 rgb.x += texcolor.R; 2066 rgb.x += texcolor.R;
@@ -1859,14 +2068,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1859 rgb.z += texcolor.B; 2068 rgb.z += texcolor.B;
1860 } 2069 }
1861 2070
1862 rgb.x /= (float)GetNumberOfSides(part); 2071 float invnsides = 1.0f / (float)nsides;
1863 rgb.y /= (float)GetNumberOfSides(part); 2072
1864 rgb.z /= (float)GetNumberOfSides(part); 2073 rgb.x *= invnsides;
2074 rgb.y *= invnsides;
2075 rgb.z *= invnsides;
1865 2076
1866 return rgb; 2077 return rgb;
1867 } 2078 }
1868 2079 if (face >= 0 && face < nsides)
1869 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2080 {
1871 texcolor = tex.GetFace((uint)face).RGBA; 2081 texcolor = tex.GetFace((uint)face).RGBA;
1872 rgb.x = texcolor.R; 2082 rgb.x = texcolor.R;
@@ -1893,15 +2103,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1893 m_host.AddScriptLPS(1); 2103 m_host.AddScriptLPS(1);
1894 2104
1895 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2105 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1896 2106 if (parts.Count > 0)
1897 foreach (SceneObjectPart part in parts) 2107 {
1898 SetTexture(part, texture, face); 2108 try
1899 2109 {
2110 foreach (SceneObjectPart part in parts)
2111 SetTexture(part, texture, face);
2112 }
2113 finally
2114 {
2115 }
2116 }
1900 ScriptSleep(200); 2117 ScriptSleep(200);
1901 } 2118 }
1902 2119
1903 protected void SetTexture(SceneObjectPart part, string texture, int face) 2120 protected void SetTexture(SceneObjectPart part, string texture, int face)
1904 { 2121 {
2122 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2123 return;
2124
1905 UUID textureID = new UUID(); 2125 UUID textureID = new UUID();
1906 2126
1907 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2127 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1946,6 +2166,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1946 2166
1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2167 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1948 { 2168 {
2169 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2170 return;
2171
1949 Primitive.TextureEntry tex = part.Shape.Textures; 2172 Primitive.TextureEntry tex = part.Shape.Textures;
1950 if (face >= 0 && face < GetNumberOfSides(part)) 2173 if (face >= 0 && face < GetNumberOfSides(part))
1951 { 2174 {
@@ -1982,6 +2205,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1982 2205
1983 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2206 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1984 { 2207 {
2208 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2209 return;
2210
1985 Primitive.TextureEntry tex = part.Shape.Textures; 2211 Primitive.TextureEntry tex = part.Shape.Textures;
1986 if (face >= 0 && face < GetNumberOfSides(part)) 2212 if (face >= 0 && face < GetNumberOfSides(part))
1987 { 2213 {
@@ -2018,6 +2244,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2018 2244
2019 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2245 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2020 { 2246 {
2247 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2248 return;
2249
2021 Primitive.TextureEntry tex = part.Shape.Textures; 2250 Primitive.TextureEntry tex = part.Shape.Textures;
2022 if (face >= 0 && face < GetNumberOfSides(part)) 2251 if (face >= 0 && face < GetNumberOfSides(part))
2023 { 2252 {
@@ -2159,7 +2388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2159 return end; 2388 return end;
2160 } 2389 }
2161 2390
2162 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2391 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2163 { 2392 {
2164 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2393 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2165 return fromPos; 2394 return fromPos;
@@ -2175,9 +2404,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2175 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2404 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2176 targetPos.z = ground; 2405 targetPos.z = ground;
2177 } 2406 }
2178 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2407 if (adjust)
2408 return SetPosAdjust(fromPos, targetPos);
2179 2409
2180 return real_vec; 2410 return targetPos;
2181 } 2411 }
2182 2412
2183 /// <summary> 2413 /// <summary>
@@ -2188,27 +2418,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2418 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2189 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2419 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2190 { 2420 {
2191 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2421 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2422 return;
2423
2192 LSL_Vector currentPos = GetPartLocalPos(part); 2424 LSL_Vector currentPos = GetPartLocalPos(part);
2425 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2193 2426
2194 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2195 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2196 2427
2197 if (part.ParentGroup.RootPart == part) 2428 if (part.ParentGroup.RootPart == part)
2198 { 2429 {
2199 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2200 targetPos.z = ground;
2201 SceneObjectGroup parent = part.ParentGroup; 2430 SceneObjectGroup parent = part.ParentGroup;
2202 parent.UpdateGroupPosition(!adjust ? targetPos : 2431 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2203 SetPosAdjust(currentPos, targetPos)); 2432 return;
2433 Util.FireAndForget(delegate(object x) {
2434 parent.UpdateGroupPosition((Vector3)toPos);
2435 });
2204 } 2436 }
2205 else 2437 else
2206 { 2438 {
2207 part.OffsetPosition = !adjust ? targetPos : 2439 part.OffsetPosition = (Vector3)toPos;
2208 SetPosAdjust(currentPos, targetPos); 2440// SceneObjectGroup parent = part.ParentGroup;
2209 SceneObjectGroup parent = part.ParentGroup; 2441// parent.HasGroupChanged = true;
2210 parent.HasGroupChanged = true; 2442// parent.ScheduleGroupForTerseUpdate();
2211 parent.ScheduleGroupForTerseUpdate(); 2443 part.ScheduleTerseUpdate();
2212 } 2444 }
2213 } 2445 }
2214 2446
@@ -2237,13 +2469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2237 else 2469 else
2238 { 2470 {
2239 if (part.ParentGroup.IsAttachment) 2471 if (part.ParentGroup.IsAttachment)
2240 {
2241 pos = part.AttachedPos; 2472 pos = part.AttachedPos;
2242 }
2243 else 2473 else
2244 {
2245 pos = part.AbsolutePosition; 2474 pos = part.AbsolutePosition;
2246 }
2247 } 2475 }
2248 2476
2249// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2477// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2255,8 +2483,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2255 { 2483 {
2256 m_host.AddScriptLPS(1); 2484 m_host.AddScriptLPS(1);
2257 2485
2486
2487 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2488 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2489 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2490 // RootPart != null should shortcircuit
2491
2258 // try to let this work as in SL... 2492 // try to let this work as in SL...
2259 if (m_host.ParentID == 0) 2493 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2260 { 2494 {
2261 // special case: If we are root, rotate complete SOG to new rotation 2495 // special case: If we are root, rotate complete SOG to new rotation
2262 SetRot(m_host, rot); 2496 SetRot(m_host, rot);
@@ -2283,25 +2517,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2283 2517
2284 protected void SetRot(SceneObjectPart part, Quaternion rot) 2518 protected void SetRot(SceneObjectPart part, Quaternion rot)
2285 { 2519 {
2286 part.UpdateRotation(rot); 2520 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2287 // Update rotation does not move the object in the physics scene if it's a linkset. 2521 return;
2288 2522
2289//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2523 bool isroot = (part == part.ParentGroup.RootPart);
2290// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2524 bool isphys;
2291 2525
2292 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2293 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2294 // It's perfectly okay when the object is not an active physical body though.
2295 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2296 // but only if the object is not physial and active. This is important for rotating doors.
2297 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2298 // scene
2299 PhysicsActor pa = part.PhysActor; 2526 PhysicsActor pa = part.PhysActor;
2300 2527
2301 if (pa != null && !pa.IsPhysical) 2528 // keep using physactor ideia of isphysical
2529 // it should be SOP ideia of that
2530 // not much of a issue with ubitODE
2531 if (pa != null && pa.IsPhysical)
2532 isphys = true;
2533 else
2534 isphys = false;
2535
2536 // SL doesn't let scripts rotate root of physical linksets
2537 if (isroot && isphys)
2538 return;
2539
2540 part.UpdateRotation(rot);
2541
2542 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2543 // so do a nasty update of parts positions if is a root part rotation
2544 if (isroot && pa != null) // with if above implies non physical root part
2302 { 2545 {
2303 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2546 part.ParentGroup.ResetChildPrimPhysicsPositions();
2304 } 2547 }
2548 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2549 {
2550 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2551 if (sittingavas.Count > 0)
2552 {
2553 foreach (ScenePresence av in sittingavas)
2554 {
2555 if (isroot || part.LocalId == av.ParentID)
2556 av.SendTerseUpdateToAllClients();
2557 }
2558 }
2559 }
2305 } 2560 }
2306 2561
2307 /// <summary> 2562 /// <summary>
@@ -2318,6 +2573,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2318 2573
2319 m_host.AddScriptLPS(1); 2574 m_host.AddScriptLPS(1);
2320 Quaternion q = m_host.GetWorldRotation(); 2575 Quaternion q = m_host.GetWorldRotation();
2576
2577 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2578 {
2579 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2580 if (avatar != null)
2581 {
2582 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2583 q = avatar.CameraRotation * q; // Mouselook
2584 else
2585 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2586 }
2587 }
2588
2321 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2589 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2322 } 2590 }
2323 2591
@@ -2345,14 +2613,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2345 return new LSL_Rotation(q); 2613 return new LSL_Rotation(q);
2346 } 2614 }
2347 2615
2348 return new LSL_Rotation(part.GetWorldRotation()); 2616 q = part.GetWorldRotation();
2617 if (part.ParentGroup.AttachmentPoint != 0)
2618 {
2619 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2620 if (avatar != null)
2621 {
2622 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2623 q = avatar.CameraRotation * q; // Mouselook
2624 else
2625 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2626 }
2627 }
2628
2629 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2349 } 2630 }
2350 2631
2351 public LSL_Rotation llGetLocalRot() 2632 public LSL_Rotation llGetLocalRot()
2352 { 2633 {
2353 m_host.AddScriptLPS(1); 2634 return GetPartLocalRot(m_host);
2635 }
2354 2636
2355 return new LSL_Rotation(m_host.RotationOffset); 2637 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2638 {
2639 m_host.AddScriptLPS(1);
2640 Quaternion rot = part.RotationOffset;
2641 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2356 } 2642 }
2357 2643
2358 public void llSetForce(LSL_Vector force, int local) 2644 public void llSetForce(LSL_Vector force, int local)
@@ -2382,32 +2668,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2382 return force; 2668 return force;
2383 } 2669 }
2384 2670
2385 public void llSetVelocity(LSL_Vector velocity, int local)
2386 {
2387 m_host.AddScriptLPS(1);
2388
2389 if (!m_host.ParentGroup.IsDeleted)
2390 {
2391 if (local != 0)
2392 velocity *= llGetRot();
2393
2394 m_host.ParentGroup.RootPart.Velocity = velocity;
2395 }
2396 }
2397
2398 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local)
2399 {
2400 m_host.AddScriptLPS(1);
2401
2402 if (!m_host.ParentGroup.IsDeleted)
2403 {
2404 if (local != 0)
2405 angularVelocity *= llGetRot();
2406
2407 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
2408 }
2409 }
2410
2411 public LSL_Integer llTarget(LSL_Vector position, double range) 2671 public LSL_Integer llTarget(LSL_Vector position, double range)
2412 { 2672 {
2413 m_host.AddScriptLPS(1); 2673 m_host.AddScriptLPS(1);
@@ -2458,16 +2718,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2458 m_host.ApplyImpulse(v, local != 0); 2718 m_host.ApplyImpulse(v, local != 0);
2459 } 2719 }
2460 2720
2721
2461 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2722 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2462 { 2723 {
2463 m_host.AddScriptLPS(1); 2724 m_host.AddScriptLPS(1);
2464 m_host.ApplyAngularImpulse(force, local != 0); 2725 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2465 } 2726 }
2466 2727
2467 public void llSetTorque(LSL_Vector torque, int local) 2728 public void llSetTorque(LSL_Vector torque, int local)
2468 { 2729 {
2469 m_host.AddScriptLPS(1); 2730 m_host.AddScriptLPS(1);
2470 m_host.SetAngularImpulse(torque, local != 0); 2731 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2471 } 2732 }
2472 2733
2473 public LSL_Vector llGetTorque() 2734 public LSL_Vector llGetTorque()
@@ -2484,20 +2745,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2484 llSetTorque(torque, local); 2745 llSetTorque(torque, local);
2485 } 2746 }
2486 2747
2748 public void llSetVelocity(LSL_Vector vel, int local)
2749 {
2750 m_host.AddScriptLPS(1);
2751 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2752 }
2753
2487 public LSL_Vector llGetVel() 2754 public LSL_Vector llGetVel()
2488 { 2755 {
2489 m_host.AddScriptLPS(1); 2756 m_host.AddScriptLPS(1);
2490 2757
2491 Vector3 vel; 2758 Vector3 vel = Vector3.Zero;
2492 2759
2493 if (m_host.ParentGroup.IsAttachment) 2760 if (m_host.ParentGroup.IsAttachment)
2494 { 2761 {
2495 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2762 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2496 vel = avatar.Velocity; 2763 if (avatar != null)
2764 vel = avatar.Velocity;
2497 } 2765 }
2498 else 2766 else
2499 { 2767 {
2500 vel = m_host.Velocity; 2768 vel = m_host.ParentGroup.RootPart.Velocity;
2501 } 2769 }
2502 2770
2503 return new LSL_Vector(vel); 2771 return new LSL_Vector(vel);
@@ -2510,11 +2778,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2510 return new LSL_Vector(m_host.Acceleration); 2778 return new LSL_Vector(m_host.Acceleration);
2511 } 2779 }
2512 2780
2513 public LSL_Vector llGetOmega() 2781 public void llSetAngularVelocity(LSL_Vector avel, int local)
2514 { 2782 {
2515 m_host.AddScriptLPS(1); 2783 m_host.AddScriptLPS(1);
2784 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2785 }
2516 2786
2517 return new LSL_Vector(m_host.AngularVelocity); 2787 public LSL_Vector llGetOmega()
2788 {
2789 m_host.AddScriptLPS(1);
2790 Vector3 avel = m_host.AngularVelocity;
2791 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2518 } 2792 }
2519 2793
2520 public LSL_Float llGetTimeOfDay() 2794 public LSL_Float llGetTimeOfDay()
@@ -2875,7 +3149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2875 return src.ToLower(); 3149 return src.ToLower();
2876 } 3150 }
2877 3151
2878 public void llGiveMoney(string destination, int amount) 3152 public LSL_Integer llGiveMoney(string destination, int amount)
2879 { 3153 {
2880 Util.FireAndForget(x => 3154 Util.FireAndForget(x =>
2881 { 3155 {
@@ -2906,9 +3180,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2906 return; 3180 return;
2907 } 3181 }
2908 3182
3183 string reason;
2909 money.ObjectGiveMoney( 3184 money.ObjectGiveMoney(
2910 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3185 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason);
2911 }); 3186 });
3187
3188 return 0;
2912 } 3189 }
2913 3190
2914 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3191 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2987,13 +3264,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2987 new_group.RootPart.UUID.ToString()) }, 3264 new_group.RootPart.UUID.ToString()) },
2988 new DetectParams[0])); 3265 new DetectParams[0]));
2989 3266
2990 float groupmass = new_group.GetMass(); 3267 // do recoil
3268 SceneObjectGroup hostgrp = m_host.ParentGroup;
3269 if (hostgrp == null)
3270 return;
3271
3272 if (hostgrp.IsAttachment) // don't recoil avatars
3273 return;
2991 3274
2992 PhysicsActor pa = new_group.RootPart.PhysActor; 3275 PhysicsActor pa = new_group.RootPart.PhysActor;
2993 3276
2994 //Recoil. 3277 //Recoil.
2995 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3278 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2996 { 3279 {
3280 float groupmass = new_group.GetMass();
2997 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3281 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2998 if (recoil != Vector3.Zero) 3282 if (recoil != Vector3.Zero)
2999 { 3283 {
@@ -3001,6 +3285,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3001 } 3285 }
3002 } 3286 }
3003 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3287 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3288 return;
3289
3004 }); 3290 });
3005 3291
3006 //ScriptSleep((int)((groupmass * velmag) / 10)); 3292 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -3015,35 +3301,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3015 public void llLookAt(LSL_Vector target, double strength, double damping) 3301 public void llLookAt(LSL_Vector target, double strength, double damping)
3016 { 3302 {
3017 m_host.AddScriptLPS(1); 3303 m_host.AddScriptLPS(1);
3018 // Determine where we are looking from
3019 LSL_Vector from = llGetPos();
3020 3304
3021 // Work out the normalised vector from the source to the target 3305 // Get the normalized vector to the target
3022 LSL_Vector delta = llVecNorm(target - from); 3306 LSL_Vector d1 = llVecNorm(target - llGetPos());
3023 LSL_Vector angle = new LSL_Vector(0,0,0);
3024 3307
3025 // Calculate the yaw 3308 // Get the bearing (yaw)
3026 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3309 LSL_Vector a1 = new LSL_Vector(0,0,0);
3027 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3310 a1.z = llAtan2(d1.y, d1.x);
3028 3311
3029 // Calculate pitch 3312 // Get the elevation (pitch)
3030 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3313 LSL_Vector a2 = new LSL_Vector(0,0,0);
3314 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
3031 3315
3032 // we need to convert from a vector describing 3316 LSL_Rotation r1 = llEuler2Rot(a1);
3033 // the angles of rotation in radians into rotation value 3317 LSL_Rotation r2 = llEuler2Rot(a2);
3034 LSL_Rotation rot = llEuler2Rot(angle); 3318 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
3035 3319
3036 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3320 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3037 // set the rotation of the object, copy that behavior
3038 PhysicsActor pa = m_host.PhysActor;
3039
3040 if (strength == 0 || pa == null || !pa.IsPhysical)
3041 { 3321 {
3042 llSetRot(rot); 3322 // Do nothing if either value is 0 (this has been checked in SL)
3323 if (strength <= 0.0 || damping <= 0.0)
3324 return;
3325
3326 llSetRot(r3 * r2 * r1);
3043 } 3327 }
3044 else 3328 else
3045 { 3329 {
3046 m_host.StartLookAt(rot, (float)strength, (float)damping); 3330 if (strength == 0)
3331 {
3332 llSetRot(r3 * r2 * r1);
3333 return;
3334 }
3335
3336 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3047 } 3337 }
3048 } 3338 }
3049 3339
@@ -3090,17 +3380,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3090 } 3380 }
3091 else 3381 else
3092 { 3382 {
3093 if (m_host.IsRoot) 3383 // new SL always returns object mass
3094 { 3384// if (m_host.IsRoot)
3385// {
3095 return m_host.ParentGroup.GetMass(); 3386 return m_host.ParentGroup.GetMass();
3096 } 3387// }
3097 else 3388// else
3098 { 3389// {
3099 return m_host.GetMass(); 3390// return m_host.GetMass();
3100 } 3391// }
3101 } 3392 }
3102 } 3393 }
3103 3394
3395
3396 public LSL_Float llGetMassMKS()
3397 {
3398 return 100f * llGetMass();
3399 }
3400
3104 public void llCollisionFilter(string name, string id, int accept) 3401 public void llCollisionFilter(string name, string id, int accept)
3105 { 3402 {
3106 m_host.AddScriptLPS(1); 3403 m_host.AddScriptLPS(1);
@@ -3148,8 +3445,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3148 { 3445 {
3149 // Unregister controls from Presence 3446 // Unregister controls from Presence
3150 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3447 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3151 // Remove Take Control permission.
3152 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3153 } 3448 }
3154 } 3449 }
3155 } 3450 }
@@ -3177,7 +3472,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3177 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3472 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3178 3473
3179 if (attachmentsModule != null) 3474 if (attachmentsModule != null)
3180 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3475 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3181 else 3476 else
3182 return false; 3477 return false;
3183 } 3478 }
@@ -3207,9 +3502,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3207 { 3502 {
3208 m_host.AddScriptLPS(1); 3503 m_host.AddScriptLPS(1);
3209 3504
3210// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3211// return;
3212
3213 if (m_item.PermsGranter != m_host.OwnerID) 3505 if (m_item.PermsGranter != m_host.OwnerID)
3214 return; 3506 return;
3215 3507
@@ -3252,6 +3544,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3252 3544
3253 public void llInstantMessage(string user, string message) 3545 public void llInstantMessage(string user, string message)
3254 { 3546 {
3547 UUID result;
3548 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3549 {
3550 ShoutError("An invalid key was passed to llInstantMessage");
3551 ScriptSleep(2000);
3552 return;
3553 }
3554
3555
3255 m_host.AddScriptLPS(1); 3556 m_host.AddScriptLPS(1);
3256 3557
3257 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3558 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3266,14 +3567,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3266 UUID friendTransactionID = UUID.Random(); 3567 UUID friendTransactionID = UUID.Random();
3267 3568
3268 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3569 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3269 3570
3270 GridInstantMessage msg = new GridInstantMessage(); 3571 GridInstantMessage msg = new GridInstantMessage();
3271 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3572 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3272 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3573 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3273 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3574 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3274// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3575// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3275// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3576// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3276 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3577// DateTime dt = DateTime.UtcNow;
3578//
3579// // Ticks from UtcNow, but make it look like local. Evil, huh?
3580// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3581//
3582// try
3583// {
3584// // Convert that to the PST timezone
3585// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3586// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3587// }
3588// catch
3589// {
3590// // No logging here, as it could be VERY spammy
3591// }
3592//
3593// // And make it look local again to fool the unix time util
3594// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3595
3596 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3597
3277 //if (client != null) 3598 //if (client != null)
3278 //{ 3599 //{
3279 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3600 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3287,10 +3608,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3287 msg.message = message.Substring(0, 1024); 3608 msg.message = message.Substring(0, 1024);
3288 else 3609 else
3289 msg.message = message; 3610 msg.message = message;
3290 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3611 msg.dialog = (byte)19; // MessageFromObject
3291 msg.fromGroup = false;// fromGroup; 3612 msg.fromGroup = false;// fromGroup;
3292 msg.offline = (byte)0; //offline; 3613 msg.offline = (byte)0; //offline;
3293 msg.ParentEstateID = 0; //ParentEstateID; 3614 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3294 msg.Position = new Vector3(m_host.AbsolutePosition); 3615 msg.Position = new Vector3(m_host.AbsolutePosition);
3295 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3616 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3296 3617
@@ -3322,7 +3643,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3322 } 3643 }
3323 3644
3324 emailModule.SendEmail(m_host.UUID, address, subject, message); 3645 emailModule.SendEmail(m_host.UUID, address, subject, message);
3325 llSleep(EMAIL_PAUSE_TIME); 3646 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3326 } 3647 }
3327 3648
3328 public void llGetNextEmail(string address, string subject) 3649 public void llGetNextEmail(string address, string subject)
@@ -3568,7 +3889,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3568 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3889 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3569 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3890 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3570 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3891 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3892 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3571 ScriptBaseClass.PERMISSION_ATTACH; 3893 ScriptBaseClass.PERMISSION_ATTACH;
3894
3572 } 3895 }
3573 else 3896 else
3574 { 3897 {
@@ -3585,15 +3908,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3585 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3908 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3586 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3909 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3587 } 3910 }
3911 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3912 {
3913 implicitPerms = perm;
3914 }
3588 } 3915 }
3589 3916
3590 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3917 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3591 { 3918 {
3592 lock (m_host.TaskInventory) 3919 m_host.TaskInventory.LockItemsForWrite(true);
3593 { 3920 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3594 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3921 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3595 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3922 m_host.TaskInventory.LockItemsForWrite(false);
3596 }
3597 3923
3598 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3924 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3599 "run_time_permissions", new Object[] { 3925 "run_time_permissions", new Object[] {
@@ -3636,11 +3962,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3636 3962
3637 if (!m_waitingForScriptAnswer) 3963 if (!m_waitingForScriptAnswer)
3638 { 3964 {
3639 lock (m_host.TaskInventory) 3965 m_host.TaskInventory.LockItemsForWrite(true);
3640 { 3966 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3641 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3967 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3642 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3968 m_host.TaskInventory.LockItemsForWrite(false);
3643 }
3644 3969
3645 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3970 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3646 m_waitingForScriptAnswer=true; 3971 m_waitingForScriptAnswer=true;
@@ -3669,14 +3994,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3669 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3994 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3670 llReleaseControls(); 3995 llReleaseControls();
3671 3996
3672 lock (m_host.TaskInventory) 3997 m_host.TaskInventory.LockItemsForWrite(true);
3673 { 3998 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3674 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3999 m_host.TaskInventory.LockItemsForWrite(false);
3675 } 4000
3676 4001 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3677 m_ScriptEngine.PostScriptEvent( 4002 "run_time_permissions", new Object[] {
3678 m_item.ItemID, 4003 new LSL_Integer(answer) },
3679 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 4004 new DetectParams[0]));
3680 } 4005 }
3681 4006
3682 public LSL_String llGetPermissionsKey() 4007 public LSL_String llGetPermissionsKey()
@@ -3715,14 +4040,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3715 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 4040 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3716 { 4041 {
3717 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4042 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3718 4043 if (parts.Count > 0)
3719 foreach (SceneObjectPart part in parts) 4044 {
3720 part.SetFaceColorAlpha(face, color, null); 4045 try
4046 {
4047 foreach (SceneObjectPart part in parts)
4048 part.SetFaceColorAlpha(face, color, null);
4049 }
4050 finally
4051 {
4052 }
4053 }
3721 } 4054 }
3722 4055
3723 public void llCreateLink(string target, int parent) 4056 public void llCreateLink(string target, int parent)
3724 { 4057 {
3725 m_host.AddScriptLPS(1); 4058 m_host.AddScriptLPS(1);
4059
3726 UUID targetID; 4060 UUID targetID;
3727 4061
3728 if (!UUID.TryParse(target, out targetID)) 4062 if (!UUID.TryParse(target, out targetID))
@@ -3828,10 +4162,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3828 // Restructuring Multiple Prims. 4162 // Restructuring Multiple Prims.
3829 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4163 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3830 parts.Remove(parentPrim.RootPart); 4164 parts.Remove(parentPrim.RootPart);
3831 foreach (SceneObjectPart part in parts) 4165 if (parts.Count > 0)
3832 { 4166 {
3833 parentPrim.DelinkFromGroup(part.LocalId, true); 4167 try
4168 {
4169 foreach (SceneObjectPart part in parts)
4170 {
4171 parentPrim.DelinkFromGroup(part.LocalId, true);
4172 }
4173 }
4174 finally
4175 {
4176 }
3834 } 4177 }
4178
3835 parentPrim.HasGroupChanged = true; 4179 parentPrim.HasGroupChanged = true;
3836 parentPrim.ScheduleGroupForFullUpdate(); 4180 parentPrim.ScheduleGroupForFullUpdate();
3837 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4181 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3840,12 +4184,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3840 { 4184 {
3841 SceneObjectPart newRoot = parts[0]; 4185 SceneObjectPart newRoot = parts[0];
3842 parts.Remove(newRoot); 4186 parts.Remove(newRoot);
3843 foreach (SceneObjectPart part in parts) 4187
4188 try
3844 { 4189 {
3845 // Required for linking 4190 foreach (SceneObjectPart part in parts)
3846 part.ClearUpdateSchedule(); 4191 {
3847 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4192 part.ClearUpdateSchedule();
4193 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4194 }
3848 } 4195 }
4196 finally
4197 {
4198 }
4199
4200
3849 newRoot.ParentGroup.HasGroupChanged = true; 4201 newRoot.ParentGroup.HasGroupChanged = true;
3850 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4202 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3851 } 4203 }
@@ -3865,6 +4217,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3865 public void llBreakAllLinks() 4217 public void llBreakAllLinks()
3866 { 4218 {
3867 m_host.AddScriptLPS(1); 4219 m_host.AddScriptLPS(1);
4220
4221 TaskInventoryItem item = m_item;
4222
4223 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4224 && !m_automaticLinkPermission)
4225 {
4226 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4227 return;
4228 }
4229
3868 SceneObjectGroup parentPrim = m_host.ParentGroup; 4230 SceneObjectGroup parentPrim = m_host.ParentGroup;
3869 if (parentPrim.AttachmentPoint != 0) 4231 if (parentPrim.AttachmentPoint != 0)
3870 return; // Fail silently if attached 4232 return; // Fail silently if attached
@@ -3884,13 +4246,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3884 public LSL_String llGetLinkKey(int linknum) 4246 public LSL_String llGetLinkKey(int linknum)
3885 { 4247 {
3886 m_host.AddScriptLPS(1); 4248 m_host.AddScriptLPS(1);
4249 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4250 if (part != null)
4251 {
4252 return part.UUID.ToString();
4253 }
4254 else
4255 {
4256 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4257 {
4258 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3887 4259
3888 ISceneEntity entity = GetLinkEntity(linknum); 4260 if (linknum < 0)
4261 return UUID.Zero.ToString();
3889 4262
3890 if (entity != null) 4263 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3891 return entity.UUID.ToString(); 4264 if (avatars.Count > linknum)
3892 else 4265 {
3893 return ScriptBaseClass.NULL_KEY; 4266 return avatars[linknum].UUID.ToString();
4267 }
4268 }
4269 return UUID.Zero.ToString();
4270 }
3894 } 4271 }
3895 4272
3896 /// <summary> 4273 /// <summary>
@@ -3949,17 +4326,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3949 m_host.AddScriptLPS(1); 4326 m_host.AddScriptLPS(1);
3950 int count = 0; 4327 int count = 0;
3951 4328
3952 lock (m_host.TaskInventory) 4329 m_host.TaskInventory.LockItemsForRead(true);
4330 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3953 { 4331 {
3954 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4332 if (inv.Value.Type == type || type == -1)
3955 { 4333 {
3956 if (inv.Value.Type == type || type == -1) 4334 count = count + 1;
3957 {
3958 count = count + 1;
3959 }
3960 } 4335 }
3961 } 4336 }
3962 4337
4338 m_host.TaskInventory.LockItemsForRead(false);
3963 return count; 4339 return count;
3964 } 4340 }
3965 4341
@@ -3968,16 +4344,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3968 m_host.AddScriptLPS(1); 4344 m_host.AddScriptLPS(1);
3969 ArrayList keys = new ArrayList(); 4345 ArrayList keys = new ArrayList();
3970 4346
3971 lock (m_host.TaskInventory) 4347 m_host.TaskInventory.LockItemsForRead(true);
4348 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3972 { 4349 {
3973 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4350 if (inv.Value.Type == type || type == -1)
3974 { 4351 {
3975 if (inv.Value.Type == type || type == -1) 4352 keys.Add(inv.Value.Name);
3976 {
3977 keys.Add(inv.Value.Name);
3978 }
3979 } 4353 }
3980 } 4354 }
4355 m_host.TaskInventory.LockItemsForRead(false);
3981 4356
3982 if (keys.Count == 0) 4357 if (keys.Count == 0)
3983 { 4358 {
@@ -4015,7 +4390,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4015 if (item == null) 4390 if (item == null)
4016 { 4391 {
4017 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4392 llSay(0, String.Format("Could not find object '{0}'", inventory));
4018 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4393 return;
4394// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4019 } 4395 }
4020 4396
4021 UUID objId = item.ItemID; 4397 UUID objId = item.ItemID;
@@ -4043,33 +4419,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4043 return; 4419 return;
4044 } 4420 }
4045 } 4421 }
4422
4046 // destination is an avatar 4423 // destination is an avatar
4047 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4424 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4048 4425
4049 if (agentItem == null) 4426 if (agentItem == null)
4050 return; 4427 return;
4051 4428
4052 if (m_TransferModule != null) 4429 byte[] bucket = new byte[1];
4053 { 4430 bucket[0] = (byte)item.Type;
4054 byte[] bucket = new byte[1]; 4431 //byte[] objBytes = agentItem.ID.GetBytes();
4055 bucket[0] = (byte)item.Type; 4432 //Array.Copy(objBytes, 0, bucket, 1, 16);
4433
4434 GridInstantMessage msg = new GridInstantMessage(World,
4435 m_host.OwnerID, m_host.Name, destId,
4436 (byte)InstantMessageDialog.TaskInventoryOffered,
4437 false, item.Name+". "+m_host.Name+" is located at "+
4438 World.RegionInfo.RegionName+" "+
4439 m_host.AbsolutePosition.ToString(),
4440 agentItem.ID, true, m_host.AbsolutePosition,
4441 bucket, true);
4056 4442
4057 GridInstantMessage msg = new GridInstantMessage(World, 4443 ScenePresence sp;
4058 m_host.OwnerID, m_host.Name, destId,
4059 (byte)InstantMessageDialog.TaskInventoryOffered,
4060 false, item.Name+". "+m_host.Name+" is located at "+
4061 World.RegionInfo.RegionName+" "+
4062 m_host.AbsolutePosition.ToString(),
4063 agentItem.ID, true, m_host.AbsolutePosition,
4064 bucket, true);
4065 4444
4066 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4445 if (World.TryGetScenePresence(destId, out sp))
4446 {
4447 sp.ControllingClient.SendInstantMessage(msg);
4067 } 4448 }
4068 4449 else
4450 {
4451 if (m_TransferModule != null)
4452 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4453 }
4454
4455 //This delay should only occur when giving inventory to avatars.
4069 ScriptSleep(3000); 4456 ScriptSleep(3000);
4070 } 4457 }
4071 } 4458 }
4072 4459
4460 [DebuggerNonUserCode]
4073 public void llRemoveInventory(string name) 4461 public void llRemoveInventory(string name)
4074 { 4462 {
4075 m_host.AddScriptLPS(1); 4463 m_host.AddScriptLPS(1);
@@ -4124,109 +4512,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4124 { 4512 {
4125 m_host.AddScriptLPS(1); 4513 m_host.AddScriptLPS(1);
4126 4514
4127 UUID uuid = (UUID)id; 4515 UUID uuid;
4128 PresenceInfo pinfo = null; 4516 if (UUID.TryParse(id, out uuid))
4129 UserAccount account;
4130
4131 UserInfoCacheEntry ce;
4132 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4133 { 4517 {
4134 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4518 PresenceInfo pinfo = null;
4135 if (account == null) 4519 UserAccount account;
4520
4521 UserInfoCacheEntry ce;
4522 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4136 { 4523 {
4137 m_userInfoCache[uuid] = null; // Cache negative 4524 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4138 return UUID.Zero.ToString(); 4525 if (account == null)
4139 } 4526 {
4527 m_userInfoCache[uuid] = null; // Cache negative
4528 return UUID.Zero.ToString();
4529 }
4140 4530
4141 4531
4142 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4532 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4143 if (pinfos != null && pinfos.Length > 0) 4533 if (pinfos != null && pinfos.Length > 0)
4144 {
4145 foreach (PresenceInfo p in pinfos)
4146 { 4534 {
4147 if (p.RegionID != UUID.Zero) 4535 foreach (PresenceInfo p in pinfos)
4148 { 4536 {
4149 pinfo = p; 4537 if (p.RegionID != UUID.Zero)
4538 {
4539 pinfo = p;
4540 }
4150 } 4541 }
4151 } 4542 }
4152 }
4153 4543
4154 ce = new UserInfoCacheEntry(); 4544 ce = new UserInfoCacheEntry();
4155 ce.time = Util.EnvironmentTickCount(); 4545 ce.time = Util.EnvironmentTickCount();
4156 ce.account = account; 4546 ce.account = account;
4157 ce.pinfo = pinfo; 4547 ce.pinfo = pinfo;
4158 } 4548 m_userInfoCache[uuid] = ce;
4159 else 4549 }
4160 { 4550 else
4161 if (ce == null) 4551 {
4162 return UUID.Zero.ToString(); 4552 if (ce == null)
4553 return UUID.Zero.ToString();
4163 4554
4164 account = ce.account; 4555 account = ce.account;
4165 pinfo = ce.pinfo; 4556 pinfo = ce.pinfo;
4166 } 4557 }
4167 4558
4168 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4559 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4169 {
4170 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4171 if (pinfos != null && pinfos.Length > 0)
4172 { 4560 {
4173 foreach (PresenceInfo p in pinfos) 4561 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4562 if (pinfos != null && pinfos.Length > 0)
4174 { 4563 {
4175 if (p.RegionID != UUID.Zero) 4564 foreach (PresenceInfo p in pinfos)
4176 { 4565 {
4177 pinfo = p; 4566 if (p.RegionID != UUID.Zero)
4567 {
4568 pinfo = p;
4569 }
4178 } 4570 }
4179 } 4571 }
4180 } 4572 else
4181 else 4573 pinfo = null;
4182 pinfo = null;
4183 4574
4184 ce.time = Util.EnvironmentTickCount(); 4575 ce.time = Util.EnvironmentTickCount();
4185 ce.pinfo = pinfo; 4576 ce.pinfo = pinfo;
4186 } 4577 }
4187 4578
4188 string reply = String.Empty; 4579 string reply = String.Empty;
4189 4580
4190 switch (data) 4581 switch (data)
4191 { 4582 {
4192 case 1: // DATA_ONLINE (0|1) 4583 case 1: // DATA_ONLINE (0|1)
4193 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4584 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4194 reply = "1"; 4585 reply = "1";
4195 else 4586 else
4196 reply = "0"; 4587 reply = "0";
4197 break; 4588 break;
4198 case 2: // DATA_NAME (First Last) 4589 case 2: // DATA_NAME (First Last)
4199 reply = account.FirstName + " " + account.LastName; 4590 reply = account.FirstName + " " + account.LastName;
4200 break; 4591 break;
4201 case 3: // DATA_BORN (YYYY-MM-DD) 4592 case 3: // DATA_BORN (YYYY-MM-DD)
4202 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4593 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4203 born = born.AddSeconds(account.Created); 4594 born = born.AddSeconds(account.Created);
4204 reply = born.ToString("yyyy-MM-dd"); 4595 reply = born.ToString("yyyy-MM-dd");
4205 break; 4596 break;
4206 case 4: // DATA_RATING (0,0,0,0,0,0) 4597 case 4: // DATA_RATING (0,0,0,0,0,0)
4207 reply = "0,0,0,0,0,0"; 4598 reply = "0,0,0,0,0,0";
4208 break; 4599 break;
4209 case 7: // DATA_USERLEVEL (integer) 4600 case 8: // DATA_PAYINFO (0|1|2|3)
4210 reply = account.UserLevel.ToString(); 4601 reply = "0";
4211 break; 4602 break;
4212 case 8: // DATA_PAYINFO (0|1|2|3) 4603 default:
4213 reply = "0"; 4604 return UUID.Zero.ToString(); // Raise no event
4214 break; 4605 }
4215 default:
4216 return UUID.Zero.ToString(); // Raise no event
4217 }
4218 4606
4219 UUID rq = UUID.Random(); 4607 UUID rq = UUID.Random();
4220 4608
4221 UUID tid = AsyncCommands. 4609 UUID tid = AsyncCommands.
4222 DataserverPlugin.RegisterRequest(m_host.LocalId, 4610 DataserverPlugin.RegisterRequest(m_host.LocalId,
4223 m_item.ItemID, rq.ToString()); 4611 m_item.ItemID, rq.ToString());
4224 4612
4225 AsyncCommands. 4613 AsyncCommands.
4226 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4614 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4227 4615
4228 ScriptSleep(100); 4616 ScriptSleep(100);
4229 return tid.ToString(); 4617 return tid.ToString();
4618 }
4619 else
4620 {
4621 ShoutError("Invalid UUID passed to llRequestAgentData.");
4622 }
4623 return "";
4230 } 4624 }
4231 4625
4232 public LSL_String llRequestInventoryData(string name) 4626 public LSL_String llRequestInventoryData(string name)
@@ -4283,12 +4677,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4283 if (UUID.TryParse(agent, out agentId)) 4677 if (UUID.TryParse(agent, out agentId))
4284 { 4678 {
4285 ScenePresence presence = World.GetScenePresence(agentId); 4679 ScenePresence presence = World.GetScenePresence(agentId);
4286 if (presence != null) 4680 if (presence != null && presence.PresenceType != PresenceType.Npc)
4287 { 4681 {
4682 // agent must not be a god
4683 if (presence.UserLevel >= 200) return;
4684
4288 // agent must be over the owners land 4685 // agent must be over the owners land
4289 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4686 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4290 { 4687 {
4291 World.TeleportClientHome(agentId, presence.ControllingClient); 4688 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4689 {
4690 // They can't be teleported home for some reason
4691 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4692 if (regionInfo != null)
4693 {
4694 World.RequestTeleportLocation(
4695 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4696 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4697 }
4698 }
4292 } 4699 }
4293 } 4700 }
4294 } 4701 }
@@ -4306,20 +4713,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4306 ScenePresence presence = World.GetScenePresence(agentId); 4713 ScenePresence presence = World.GetScenePresence(agentId);
4307 if (presence != null && presence.PresenceType != PresenceType.Npc) 4714 if (presence != null && presence.PresenceType != PresenceType.Npc)
4308 { 4715 {
4309 // agent must not be a god
4310 if (presence.GodLevel >= 200) return;
4311
4312 if (destination == String.Empty) 4716 if (destination == String.Empty)
4313 destination = World.RegionInfo.RegionName; 4717 destination = World.RegionInfo.RegionName;
4314 4718
4315 // agent must be over the owners land 4719 if (m_item.PermsGranter == agentId)
4316 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4720 {
4721 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4722 {
4723 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4724 }
4725 }
4726
4727 // agent must be wearing the object
4728 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4317 { 4729 {
4318 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4730 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4319 } 4731 }
4320 else // or must be wearing the prim 4732 else
4321 { 4733 {
4322 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4734 // agent must not be a god
4735 if (presence.GodLevel >= 200) return;
4736
4737 // agent must be over the owners land
4738 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
4739 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
4740 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4323 { 4741 {
4324 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4742 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4325 } 4743 }
@@ -4333,24 +4751,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4333 m_host.AddScriptLPS(1); 4751 m_host.AddScriptLPS(1);
4334 UUID agentId = new UUID(); 4752 UUID agentId = new UUID();
4335 4753
4336 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4754 ulong regionHandle = Utils.UIntsToLong((uint)(global_coords.x / 256) * 256, (uint)(global_coords.y / 256) * 256);
4337 4755
4338 if (UUID.TryParse(agent, out agentId)) 4756 if (UUID.TryParse(agent, out agentId))
4339 { 4757 {
4758 // This function is owner only!
4759 if (m_host.OwnerID != agentId)
4760 return;
4761
4340 ScenePresence presence = World.GetScenePresence(agentId); 4762 ScenePresence presence = World.GetScenePresence(agentId);
4763
4764 // Can't TP sitting avatars
4765 if (presence.ParentID != 0) // Sitting
4766 return;
4767
4341 if (presence != null && presence.PresenceType != PresenceType.Npc) 4768 if (presence != null && presence.PresenceType != PresenceType.Npc)
4342 { 4769 {
4343 // agent must not be a god 4770 if (m_item.PermsGranter == agentId)
4344 if (presence.GodLevel >= 200) return;
4345
4346 // agent must be over the owners land
4347 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4348 { 4771 {
4349 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4772 // If attached using llAttachToAvatarTemp, cowardly refuse
4350 } 4773 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
4351 else // or must be wearing the prim 4774 return;
4352 { 4775
4353 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4776 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4354 { 4777 {
4355 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4778 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4356 } 4779 }
@@ -4394,7 +4817,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4394 UUID av = new UUID(); 4817 UUID av = new UUID();
4395 if (!UUID.TryParse(agent,out av)) 4818 if (!UUID.TryParse(agent,out av))
4396 { 4819 {
4397 LSLError("First parameter to llDialog needs to be a key");
4398 return; 4820 return;
4399 } 4821 }
4400 4822
@@ -4427,9 +4849,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4427 { 4849 {
4428 m_host.AddScriptLPS(1); 4850 m_host.AddScriptLPS(1);
4429 4851
4852 if(impact_sound == "")
4853 {
4854 m_host.CollisionSoundVolume = (float)impact_volume;
4855 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4856 m_host.CollisionSoundType = 0;
4857 return;
4858 }
4430 // TODO: Parameter check logic required. 4859 // TODO: Parameter check logic required.
4431 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4860 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4432 m_host.CollisionSoundVolume = (float)impact_volume; 4861 m_host.CollisionSoundVolume = (float)impact_volume;
4862 m_host.CollisionSoundType = 1;
4433 } 4863 }
4434 4864
4435 public LSL_String llGetAnimation(string id) 4865 public LSL_String llGetAnimation(string id)
@@ -4443,14 +4873,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4443 4873
4444 if (m_host.RegionHandle == presence.RegionHandle) 4874 if (m_host.RegionHandle == presence.RegionHandle)
4445 { 4875 {
4446 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4447
4448 if (presence != null) 4876 if (presence != null)
4449 { 4877 {
4450 AnimationSet currentAnims = presence.Animator.Animations; 4878 if (presence.SitGround)
4451 string currentAnimationState = String.Empty; 4879 return "Sitting on Ground";
4452 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4880 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4453 return currentAnimationState; 4881 return "Sitting";
4882
4883 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4884 string lslMovementAnimation;
4885
4886 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4887 return lslMovementAnimation;
4454 } 4888 }
4455 } 4889 }
4456 4890
@@ -4598,7 +5032,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4598 { 5032 {
4599 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 5033 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4600 float distance_term = distance * distance * distance; // Script Energy 5034 float distance_term = distance * distance * distance; // Script Energy
4601 float pusher_mass = m_host.GetMass(); 5035 // use total object mass and not part
5036 float pusher_mass = m_host.ParentGroup.GetMass();
4602 5037
4603 float PUSH_ATTENUATION_DISTANCE = 17f; 5038 float PUSH_ATTENUATION_DISTANCE = 17f;
4604 float PUSH_ATTENUATION_SCALE = 5f; 5039 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4835,6 +5270,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4835 { 5270 {
4836 return item.AssetID.ToString(); 5271 return item.AssetID.ToString();
4837 } 5272 }
5273 m_host.TaskInventory.LockItemsForRead(false);
4838 5274
4839 return UUID.Zero.ToString(); 5275 return UUID.Zero.ToString();
4840 } 5276 }
@@ -4987,14 +5423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4987 { 5423 {
4988 m_host.AddScriptLPS(1); 5424 m_host.AddScriptLPS(1);
4989 5425
4990 if (src == null) 5426 return src.Length;
4991 {
4992 return 0;
4993 }
4994 else
4995 {
4996 return src.Length;
4997 }
4998 } 5427 }
4999 5428
5000 public LSL_Integer llList2Integer(LSL_List src, int index) 5429 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5065,7 +5494,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5065 else if (src.Data[index] is LSL_Float) 5494 else if (src.Data[index] is LSL_Float)
5066 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5495 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5067 else if (src.Data[index] is LSL_String) 5496 else if (src.Data[index] is LSL_String)
5068 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5497 {
5498 string str = ((LSL_String) src.Data[index]).m_string;
5499 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5500 if (m != Match.Empty)
5501 {
5502 str = m.Value;
5503 double d = 0.0;
5504 if (!Double.TryParse(str, out d))
5505 return 0.0;
5506
5507 return d;
5508 }
5509 return 0.0;
5510 }
5069 return Convert.ToDouble(src.Data[index]); 5511 return Convert.ToDouble(src.Data[index]);
5070 } 5512 }
5071 catch (FormatException) 5513 catch (FormatException)
@@ -5107,7 +5549,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5107 // for completion and should LSL_Key ever be implemented 5549 // for completion and should LSL_Key ever be implemented
5108 // as it's own struct 5550 // as it's own struct
5109 else if (!(src.Data[index] is LSL_String || 5551 else if (!(src.Data[index] is LSL_String ||
5110 src.Data[index] is LSL_Key)) 5552 src.Data[index] is LSL_Key ||
5553 src.Data[index] is String))
5111 { 5554 {
5112 return ""; 5555 return "";
5113 } 5556 }
@@ -5365,7 +5808,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5365 } 5808 }
5366 } 5809 }
5367 } 5810 }
5368 else { 5811 else
5812 {
5369 object[] array = new object[src.Length]; 5813 object[] array = new object[src.Length];
5370 Array.Copy(src.Data, 0, array, 0, src.Length); 5814 Array.Copy(src.Data, 0, array, 0, src.Length);
5371 result = new LSL_List(array); 5815 result = new LSL_List(array);
@@ -5472,7 +5916,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5472 public LSL_Integer llGetRegionAgentCount() 5916 public LSL_Integer llGetRegionAgentCount()
5473 { 5917 {
5474 m_host.AddScriptLPS(1); 5918 m_host.AddScriptLPS(1);
5475 return new LSL_Integer(World.GetRootAgentCount()); 5919
5920 int count = 0;
5921 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5922 count++;
5923 });
5924
5925 return new LSL_Integer(count);
5476 } 5926 }
5477 5927
5478 public LSL_Vector llGetRegionCorner() 5928 public LSL_Vector llGetRegionCorner()
@@ -5713,6 +6163,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5713 flags |= ScriptBaseClass.AGENT_AWAY; 6163 flags |= ScriptBaseClass.AGENT_AWAY;
5714 } 6164 }
5715 6165
6166 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6167 UUID[] anims = agent.Animator.GetAnimationArray();
6168 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6169 {
6170 flags |= ScriptBaseClass.AGENT_BUSY;
6171 }
6172
5716 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6173 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5717 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6174 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5718 { 6175 {
@@ -5760,6 +6217,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5760 flags |= ScriptBaseClass.AGENT_SITTING; 6217 flags |= ScriptBaseClass.AGENT_SITTING;
5761 } 6218 }
5762 6219
6220 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6221 {
6222 flags |= ScriptBaseClass.AGENT_MALE;
6223 }
6224
5763 return flags; 6225 return flags;
5764 } 6226 }
5765 6227
@@ -5905,9 +6367,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5905 6367
5906 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6368 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5907 6369
5908 foreach (SceneObjectPart part in parts) 6370 try
6371 {
6372 foreach (SceneObjectPart part in parts)
6373 {
6374 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6375 }
6376 }
6377 finally
5909 { 6378 {
5910 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5911 } 6379 }
5912 } 6380 }
5913 6381
@@ -5961,13 +6429,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5961 6429
5962 if (m_host.OwnerID == land.LandData.OwnerID) 6430 if (m_host.OwnerID == land.LandData.OwnerID)
5963 { 6431 {
5964 World.TeleportClientHome(agentID, presence.ControllingClient); 6432 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6433 presence.TeleportWithMomentum(p, null);
6434 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5965 } 6435 }
5966 } 6436 }
5967 } 6437 }
5968 ScriptSleep(5000); 6438 ScriptSleep(5000);
5969 } 6439 }
5970 6440
6441 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6442 {
6443 return ParseString2List(str, separators, in_spacers, false);
6444 }
6445
5971 public LSL_Integer llOverMyLand(string id) 6446 public LSL_Integer llOverMyLand(string id)
5972 { 6447 {
5973 m_host.AddScriptLPS(1); 6448 m_host.AddScriptLPS(1);
@@ -6020,26 +6495,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6020 } 6495 }
6021 else 6496 else
6022 { 6497 {
6023 agentSize = GetAgentSize(avatar); 6498// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6499 Vector3 s = avatar.Appearance.AvatarSize;
6500 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
6024 } 6501 }
6025
6026 return agentSize; 6502 return agentSize;
6027 } 6503 }
6028 6504
6029 public LSL_Integer llSameGroup(string agent) 6505 public LSL_Integer llSameGroup(string id)
6030 { 6506 {
6031 m_host.AddScriptLPS(1); 6507 m_host.AddScriptLPS(1);
6032 UUID agentId = new UUID(); 6508 UUID uuid = new UUID();
6033 if (!UUID.TryParse(agent, out agentId)) 6509 if (!UUID.TryParse(id, out uuid))
6034 return new LSL_Integer(0); 6510 return new LSL_Integer(0);
6035 ScenePresence presence = World.GetScenePresence(agentId); 6511
6036 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6512 // Check if it's a group key
6037 return new LSL_Integer(0); 6513 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6038 IClientAPI client = presence.ControllingClient;
6039 if (m_host.GroupID == client.ActiveGroupId)
6040 return new LSL_Integer(1); 6514 return new LSL_Integer(1);
6041 else 6515
6516 // We got passed a UUID.Zero
6517 if (uuid == UUID.Zero)
6518 return new LSL_Integer(0);
6519
6520 // Handle the case where id names an avatar
6521 ScenePresence presence = World.GetScenePresence(uuid);
6522 if (presence != null)
6523 {
6524 if (presence.IsChildAgent)
6525 return new LSL_Integer(0);
6526
6527 IClientAPI client = presence.ControllingClient;
6528 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6529 return new LSL_Integer(1);
6530
6531 return new LSL_Integer(0);
6532 }
6533
6534 // Handle object case
6535 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6536 if (part != null)
6537 {
6538 // This will handle both deed and non-deed and also the no
6539 // group case
6540 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6541 return new LSL_Integer(1);
6542
6042 return new LSL_Integer(0); 6543 return new LSL_Integer(0);
6544 }
6545
6546 return new LSL_Integer(0);
6043 } 6547 }
6044 6548
6045 public void llUnSit(string id) 6549 public void llUnSit(string id)
@@ -6598,6 +7102,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6598 7102
6599 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7103 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6600 { 7104 {
7105 // LSL quaternions can normalize to 0, normal Quaternions can't.
7106 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7107 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7108
6601 part.SitTargetPosition = offset; 7109 part.SitTargetPosition = offset;
6602 part.SitTargetOrientation = rot; 7110 part.SitTargetOrientation = rot;
6603 part.ParentGroup.HasGroupChanged = true; 7111 part.ParentGroup.HasGroupChanged = true;
@@ -6784,30 +7292,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6784 UUID av = new UUID(); 7292 UUID av = new UUID();
6785 if (!UUID.TryParse(avatar,out av)) 7293 if (!UUID.TryParse(avatar,out av))
6786 { 7294 {
6787 LSLError("First parameter to llDialog needs to be a key"); 7295 //LSLError("First parameter to llDialog needs to be a key");
6788 return; 7296 return;
6789 } 7297 }
6790 if (buttons.Length < 1) 7298 if (buttons.Length < 1)
6791 { 7299 {
6792 LSLError("No less than 1 button can be shown"); 7300 buttons.Add("OK");
6793 return;
6794 } 7301 }
6795 if (buttons.Length > 12) 7302 if (buttons.Length > 12)
6796 { 7303 {
6797 LSLError("No more than 12 buttons can be shown"); 7304 ShoutError("button list too long, must be 12 or fewer entries");
6798 return;
6799 } 7305 }
6800 string[] buts = new string[buttons.Length]; 7306 int length = buttons.Length;
6801 for (int i = 0; i < buttons.Length; i++) 7307 if (length > 12)
7308 length = 12;
7309
7310 string[] buts = new string[length];
7311 for (int i = 0; i < length; i++)
6802 { 7312 {
6803 if (buttons.Data[i].ToString() == String.Empty) 7313 if (buttons.Data[i].ToString() == String.Empty)
6804 { 7314 {
6805 LSLError("button label cannot be blank"); 7315 ShoutError("button label cannot be blank");
6806 return; 7316 return;
6807 } 7317 }
6808 if (buttons.Data[i].ToString().Length > 24) 7318 if (buttons.Data[i].ToString().Length > 24)
6809 { 7319 {
6810 LSLError("button label cannot be longer than 24 characters"); 7320 ShoutError("button label cannot be longer than 24 characters");
6811 return; 7321 return;
6812 } 7322 }
6813 buts[i] = buttons.Data[i].ToString(); 7323 buts[i] = buttons.Data[i].ToString();
@@ -6874,9 +7384,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6874 return; 7384 return;
6875 } 7385 }
6876 7386
6877 // the rest of the permission checks are done in RezScript, so check the pin there as well 7387 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6878 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7388 if (dest != null)
7389 {
7390 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7391 {
7392 // the rest of the permission checks are done in RezScript, so check the pin there as well
7393 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6879 7394
7395 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7396 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7397 }
7398 }
6880 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7399 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6881 ScriptSleep(3000); 7400 ScriptSleep(3000);
6882 } 7401 }
@@ -6950,19 +7469,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6950 public LSL_String llMD5String(string src, int nonce) 7469 public LSL_String llMD5String(string src, int nonce)
6951 { 7470 {
6952 m_host.AddScriptLPS(1); 7471 m_host.AddScriptLPS(1);
6953 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7472 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6954 } 7473 }
6955 7474
6956 public LSL_String llSHA1String(string src) 7475 public LSL_String llSHA1String(string src)
6957 { 7476 {
6958 m_host.AddScriptLPS(1); 7477 m_host.AddScriptLPS(1);
6959 return Util.SHA1Hash(src).ToLower(); 7478 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6960 } 7479 }
6961 7480
6962 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7481 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6963 { 7482 {
6964 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7483 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6965 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7484 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7485 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7486 return shapeBlock;
6966 7487
6967 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7488 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6968 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7489 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7067,6 +7588,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7067 // Prim type box, cylinder and prism. 7588 // Prim type box, cylinder and prism.
7068 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) 7589 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)
7069 { 7590 {
7591 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7592 return;
7593
7070 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7594 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7071 ObjectShapePacket.ObjectDataBlock shapeBlock; 7595 ObjectShapePacket.ObjectDataBlock shapeBlock;
7072 7596
@@ -7120,6 +7644,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7120 // Prim type sphere. 7644 // Prim type sphere.
7121 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7645 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7122 { 7646 {
7647 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7648 return;
7649
7123 ObjectShapePacket.ObjectDataBlock shapeBlock; 7650 ObjectShapePacket.ObjectDataBlock shapeBlock;
7124 7651
7125 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7652 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7161,6 +7688,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7161 // Prim type torus, tube and ring. 7688 // Prim type torus, tube and ring.
7162 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) 7689 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)
7163 { 7690 {
7691 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7692 return;
7693
7164 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7694 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7165 ObjectShapePacket.ObjectDataBlock shapeBlock; 7695 ObjectShapePacket.ObjectDataBlock shapeBlock;
7166 7696
@@ -7296,6 +7826,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7296 // Prim type sculpt. 7826 // Prim type sculpt.
7297 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7827 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7298 { 7828 {
7829 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7830 return;
7831
7299 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7832 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7300 UUID sculptId; 7833 UUID sculptId;
7301 7834
@@ -7318,7 +7851,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7318 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7851 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7319 { 7852 {
7320 // default 7853 // default
7321 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7854 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7322 } 7855 }
7323 7856
7324 part.Shape.SetSculptProperties((byte)type, sculptId); 7857 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7335,15 +7868,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7335 ScriptSleep(200); 7868 ScriptSleep(200);
7336 } 7869 }
7337 7870
7338 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7339 {
7340 m_host.AddScriptLPS(1);
7341
7342 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7343
7344 ScriptSleep(200);
7345 }
7346
7347 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7871 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7348 { 7872 {
7349 m_host.AddScriptLPS(1); 7873 m_host.AddScriptLPS(1);
@@ -7351,169 +7875,135 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7351 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7875 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7352 } 7876 }
7353 7877
7354 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7878 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7355 { 7879 {
7356 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7880 List<object> parts = new List<object>();
7881 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7882 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7883 foreach (SceneObjectPart p in prims)
7884 parts.Add(p);
7885 foreach (ScenePresence p in avatars)
7886 parts.Add(p);
7357 7887
7358 LSL_List remaining = null; 7888 LSL_List remaining = null;
7359 uint rulesParsed = 0; 7889 uint rulesParsed = 0;
7360 7890
7361 foreach (SceneObjectPart part in parts) 7891 if (parts.Count > 0)
7362 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7363
7364 while (remaining != null && remaining.Length > 2)
7365 { 7892 {
7366 linknumber = remaining.GetLSLIntegerItem(0); 7893 foreach (object part in parts)
7367 rules = remaining.GetSublist(1, -1);
7368 parts = GetLinkParts(linknumber);
7369
7370 foreach (SceneObjectPart part in parts)
7371 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7372 }
7373 }
7374
7375 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7376 {
7377 SceneObjectGroup group = m_host.ParentGroup;
7378
7379 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7380 return;
7381 if (group.IsAttachment)
7382 return;
7383
7384 if (frames.Data.Length > 0) // We are getting a new motion
7385 {
7386 if (group.RootPart.KeyframeMotion != null)
7387 group.RootPart.KeyframeMotion.Delete();
7388 group.RootPart.KeyframeMotion = null;
7389
7390 int idx = 0;
7391
7392 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7393 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7394
7395 while (idx < options.Data.Length)
7396 { 7894 {
7397 int option = (int)options.GetLSLIntegerItem(idx++); 7895 if (part is SceneObjectPart)
7398 int remain = options.Data.Length - idx; 7896 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7897 else
7898 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7899 }
7399 7900
7400 switch (option) 7901 while ((object)remaining != null && remaining.Length > 2)
7902 {
7903 linknumber = remaining.GetLSLIntegerItem(0);
7904 rules = remaining.GetSublist(1, -1);
7905 parts.Clear();
7906 prims = GetLinkParts(linknumber);
7907 avatars = GetLinkAvatars(linknumber);
7908 foreach (SceneObjectPart p in prims)
7909 parts.Add(p);
7910 foreach (ScenePresence p in avatars)
7911 parts.Add(p);
7912
7913 remaining = null;
7914 foreach (object part in parts)
7401 { 7915 {
7402 case ScriptBaseClass.KFM_MODE: 7916 if (part is SceneObjectPart)
7403 if (remain < 1) 7917 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7404 break; 7918 else
7405 int modeval = (int)options.GetLSLIntegerItem(idx++); 7919 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7406 switch(modeval)
7407 {
7408 case ScriptBaseClass.KFM_FORWARD:
7409 mode = KeyframeMotion.PlayMode.Forward;
7410 break;
7411 case ScriptBaseClass.KFM_REVERSE:
7412 mode = KeyframeMotion.PlayMode.Reverse;
7413 break;
7414 case ScriptBaseClass.KFM_LOOP:
7415 mode = KeyframeMotion.PlayMode.Loop;
7416 break;
7417 case ScriptBaseClass.KFM_PING_PONG:
7418 mode = KeyframeMotion.PlayMode.PingPong;
7419 break;
7420 }
7421 break;
7422 case ScriptBaseClass.KFM_DATA:
7423 if (remain < 1)
7424 break;
7425 int dataval = (int)options.GetLSLIntegerItem(idx++);
7426 data = (KeyframeMotion.DataFormat)dataval;
7427 break;
7428 } 7920 }
7429 } 7921 }
7922 }
7923 }
7430 7924
7431 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); 7925 public LSL_List llGetPhysicsMaterial()
7926 {
7927 LSL_List result = new LSL_List();
7432 7928
7433 idx = 0; 7929 result.Add(new LSL_Float(m_host.GravityModifier));
7930 result.Add(new LSL_Float(m_host.Restitution));
7931 result.Add(new LSL_Float(m_host.Friction));
7932 result.Add(new LSL_Float(m_host.Density));
7434 7933
7435 int elemLength = 2; 7934 return result;
7436 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 7935 }
7437 elemLength = 3;
7438 7936
7439 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 7937 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7440 while (idx < frames.Data.Length) 7938 float material_density, float material_friction,
7441 { 7939 float material_restitution, float material_gravity_modifier)
7442 int remain = frames.Data.Length - idx; 7940 {
7941 ExtraPhysicsData physdata = new ExtraPhysicsData();
7942 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7943 physdata.Density = part.Density;
7944 physdata.Friction = part.Friction;
7945 physdata.Bounce = part.Restitution;
7946 physdata.GravitationModifier = part.GravityModifier;
7443 7947
7444 if (remain < elemLength) 7948 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7445 break; 7949 physdata.Density = material_density;
7950 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7951 physdata.Friction = material_friction;
7952 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7953 physdata.Bounce = material_restitution;
7954 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7955 physdata.GravitationModifier = material_gravity_modifier;
7446 7956
7447 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 7957 part.UpdateExtraPhysics(physdata);
7448 frame.Position = null; 7958 }
7449 frame.Rotation = null;
7450 7959
7451 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 7960 public void llSetPhysicsMaterial(int material_bits,
7452 { 7961 float material_gravity_modifier, float material_restitution,
7453 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); 7962 float material_friction, float material_density)
7454 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); 7963 {
7455 } 7964 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7456 if ((data & KeyframeMotion.DataFormat.Rotation) != 0) 7965 }
7457 {
7458 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7459 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7460 q.Normalize();
7461 frame.Rotation = q;
7462 }
7463 7966
7464 float tempf = (float)frames.GetLSLFloatItem(idx++); 7967 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7465 frame.TimeMS = (int)(tempf * 1000.0f); 7968 {
7969 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7970 llSetLinkPrimitiveParamsFast(linknumber, rules);
7971 ScriptSleep(200);
7972 }
7466 7973
7467 keyframes.Add(frame); 7974 // vector up using libomv (c&p from sop )
7468 } 7975 // vector up rotated by r
7976 private Vector3 Zrot(Quaternion r)
7977 {
7978 double x, y, z, m;
7469 7979
7470 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 7980 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7471 group.RootPart.KeyframeMotion.Start(); 7981 if (Math.Abs(1.0 - m) > 0.000001)
7472 }
7473 else
7474 { 7982 {
7475 if (group.RootPart.KeyframeMotion == null) 7983 m = 1.0 / Math.Sqrt(m);
7476 return; 7984 r.X *= (float)m;
7477 7985 r.Y *= (float)m;
7478 if (options.Data.Length == 0) 7986 r.Z *= (float)m;
7479 { 7987 r.W *= (float)m;
7480 group.RootPart.KeyframeMotion.Stop(); 7988 }
7481 return;
7482 }
7483
7484 int idx = 0;
7485 7989
7486 while (idx < options.Data.Length) 7990 x = 2 * (r.X * r.Z + r.Y * r.W);
7487 { 7991 y = 2 * (-r.X * r.W + r.Y * r.Z);
7488 int option = (int)options.GetLSLIntegerItem(idx++); 7992 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7489 7993
7490 switch (option) 7994 return new Vector3((float)x, (float)y, (float)z);
7491 {
7492 case ScriptBaseClass.KFM_COMMAND:
7493 int cmd = (int)options.GetLSLIntegerItem(idx++);
7494 switch (cmd)
7495 {
7496 case ScriptBaseClass.KFM_CMD_PLAY:
7497 group.RootPart.KeyframeMotion.Start();
7498 break;
7499 case ScriptBaseClass.KFM_CMD_STOP:
7500 group.RootPart.KeyframeMotion.Stop();
7501 break;
7502 case ScriptBaseClass.KFM_CMD_PAUSE:
7503 group.RootPart.KeyframeMotion.Pause();
7504 break;
7505 }
7506 break;
7507 }
7508 }
7509 }
7510 } 7995 }
7511 7996
7512 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7997 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7513 { 7998 {
7999 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8000 return null;
8001
7514 int idx = 0; 8002 int idx = 0;
7515 int idxStart = 0; 8003 int idxStart = 0;
7516 8004
8005 SceneObjectGroup parentgrp = part.ParentGroup;
8006
7517 bool positionChanged = false; 8007 bool positionChanged = false;
7518 LSL_Vector currentPosition = GetPartLocalPos(part); 8008 LSL_Vector currentPosition = GetPartLocalPos(part);
7519 8009
@@ -7538,8 +8028,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7538 return null; 8028 return null;
7539 8029
7540 v=rules.GetVector3Item(idx++); 8030 v=rules.GetVector3Item(idx++);
8031 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8032 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8033 else
8034 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7541 positionChanged = true; 8035 positionChanged = true;
7542 currentPosition = GetSetPosTarget(part, v, currentPosition);
7543 8036
7544 break; 8037 break;
7545 case (int)ScriptBaseClass.PRIM_SIZE: 8038 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7556,7 +8049,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7556 8049
7557 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8050 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7558 // try to let this work as in SL... 8051 // try to let this work as in SL...
7559 if (part.ParentID == 0) 8052 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7560 { 8053 {
7561 // special case: If we are root, rotate complete SOG to new rotation 8054 // special case: If we are root, rotate complete SOG to new rotation
7562 SetRot(part, q); 8055 SetRot(part, q);
@@ -7850,6 +8343,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7850 8343
7851 break; 8344 break;
7852 8345
8346 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8347 if (remain < 5)
8348 return null;
8349
8350 int material_bits = rules.GetLSLIntegerItem(idx++);
8351 float material_density = (float)rules.GetLSLFloatItem(idx++);
8352 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8353 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8354 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8355
8356 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8357
8358 break;
8359
7853 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8360 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7854 if (remain < 1) 8361 if (remain < 1)
7855 return null; 8362 return null;
@@ -7929,14 +8436,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7929 if (part.ParentGroup.RootPart == part) 8436 if (part.ParentGroup.RootPart == part)
7930 { 8437 {
7931 SceneObjectGroup parent = part.ParentGroup; 8438 SceneObjectGroup parent = part.ParentGroup;
7932 parent.UpdateGroupPosition(currentPosition); 8439 Util.FireAndForget(delegate(object x) {
8440 parent.UpdateGroupPosition(currentPosition);
8441 });
7933 } 8442 }
7934 else 8443 else
7935 { 8444 {
7936 part.OffsetPosition = currentPosition; 8445 part.OffsetPosition = currentPosition;
7937 SceneObjectGroup parent = part.ParentGroup; 8446// SceneObjectGroup parent = part.ParentGroup;
7938 parent.HasGroupChanged = true; 8447// parent.HasGroupChanged = true;
7939 parent.ScheduleGroupForTerseUpdate(); 8448// parent.ScheduleGroupForTerseUpdate();
8449 part.ScheduleTerseUpdate();
7940 } 8450 }
7941 } 8451 }
7942 } 8452 }
@@ -7974,10 +8484,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7974 8484
7975 public LSL_String llXorBase64Strings(string str1, string str2) 8485 public LSL_String llXorBase64Strings(string str1, string str2)
7976 { 8486 {
7977 m_host.AddScriptLPS(1); 8487 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7978 Deprecated("llXorBase64Strings"); 8488
7979 ScriptSleep(300); 8489 ScriptSleep(300);
7980 return String.Empty; 8490 m_host.AddScriptLPS(1);
8491
8492 if (str1 == String.Empty)
8493 return String.Empty;
8494 if (str2 == String.Empty)
8495 return str1;
8496
8497 int len = str2.Length;
8498 if ((len % 4) != 0) // LL is EVIL!!!!
8499 {
8500 while (str2.EndsWith("="))
8501 str2 = str2.Substring(0, str2.Length - 1);
8502
8503 len = str2.Length;
8504 int mod = len % 4;
8505
8506 if (mod == 1)
8507 str2 = str2.Substring(0, str2.Length - 1);
8508 else if (mod == 2)
8509 str2 += "==";
8510 else if (mod == 3)
8511 str2 += "=";
8512 }
8513
8514 byte[] data1;
8515 byte[] data2;
8516 try
8517 {
8518 data1 = Convert.FromBase64String(str1);
8519 data2 = Convert.FromBase64String(str2);
8520 }
8521 catch (Exception)
8522 {
8523 return new LSL_String(String.Empty);
8524 }
8525
8526 // For cases where the decoded length of s2 is greater
8527 // than the decoded length of s1, simply perform a normal
8528 // decode and XOR
8529 //
8530 if (data2.Length >= data1.Length)
8531 {
8532 for (int pos = 0 ; pos < data1.Length ; pos++ )
8533 data1[pos] ^= data2[pos];
8534
8535 return Convert.ToBase64String(data1);
8536 }
8537
8538 // Remove padding
8539 while (str1.EndsWith("="))
8540 str1 = str1.Substring(0, str1.Length - 1);
8541 while (str2.EndsWith("="))
8542 str2 = str2.Substring(0, str2.Length - 1);
8543
8544 byte[] d1 = new byte[str1.Length];
8545 byte[] d2 = new byte[str2.Length];
8546
8547 for (int i = 0 ; i < str1.Length ; i++)
8548 {
8549 int idx = b64.IndexOf(str1.Substring(i, 1));
8550 if (idx == -1)
8551 idx = 0;
8552 d1[i] = (byte)idx;
8553 }
8554
8555 for (int i = 0 ; i < str2.Length ; i++)
8556 {
8557 int idx = b64.IndexOf(str2.Substring(i, 1));
8558 if (idx == -1)
8559 idx = 0;
8560 d2[i] = (byte)idx;
8561 }
8562
8563 string output = String.Empty;
8564
8565 for (int pos = 0 ; pos < d1.Length ; pos++)
8566 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8567
8568 while (output.Length % 3 > 0)
8569 output += "=";
8570
8571 return output;
7981 } 8572 }
7982 8573
7983 public void llRemoteDataSetRegion() 8574 public void llRemoteDataSetRegion()
@@ -8102,8 +8693,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8102 public LSL_Integer llGetNumberOfPrims() 8693 public LSL_Integer llGetNumberOfPrims()
8103 { 8694 {
8104 m_host.AddScriptLPS(1); 8695 m_host.AddScriptLPS(1);
8105 8696 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
8106 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8697
8698 return m_host.ParentGroup.PrimCount + avatarCount;
8107 } 8699 }
8108 8700
8109 /// <summary> 8701 /// <summary>
@@ -8118,55 +8710,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8118 m_host.AddScriptLPS(1); 8710 m_host.AddScriptLPS(1);
8119 UUID objID = UUID.Zero; 8711 UUID objID = UUID.Zero;
8120 LSL_List result = new LSL_List(); 8712 LSL_List result = new LSL_List();
8713
8714 // If the ID is not valid, return null result
8121 if (!UUID.TryParse(obj, out objID)) 8715 if (!UUID.TryParse(obj, out objID))
8122 { 8716 {
8123 result.Add(new LSL_Vector()); 8717 result.Add(new LSL_Vector());
8124 result.Add(new LSL_Vector()); 8718 result.Add(new LSL_Vector());
8125 return result; 8719 return result;
8126 } 8720 }
8721
8722 // Check if this is an attached prim. If so, replace
8723 // the UUID with the avatar UUID and report it's bounding box
8724 SceneObjectPart part = World.GetSceneObjectPart(objID);
8725 if (part != null && part.ParentGroup.IsAttachment)
8726 objID = part.ParentGroup.AttachedAvatar;
8727
8728 // Find out if this is an avatar ID. If so, return it's box
8127 ScenePresence presence = World.GetScenePresence(objID); 8729 ScenePresence presence = World.GetScenePresence(objID);
8128 if (presence != null) 8730 if (presence != null)
8129 { 8731 {
8130 if (presence.ParentID == 0) // not sat on an object 8732 // As per LSL Wiki, there is no difference between sitting
8733 // and standing avatar since server 1.36
8734 LSL_Vector lower;
8735 LSL_Vector upper;
8736
8737 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8738
8739 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8740 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8741/*
8131 { 8742 {
8132 LSL_Vector lower; 8743 // This is for ground sitting avatars
8133 LSL_Vector upper; 8744 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8134 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8745 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8135 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8746 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8136 {
8137 // This is for ground sitting avatars
8138 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8139 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8140 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8141 }
8142 else
8143 {
8144 // This is for standing/flying avatars
8145 float height = presence.Appearance.AvatarHeight / 2.0f;
8146 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8147 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8148 }
8149 result.Add(lower);
8150 result.Add(upper);
8151 return result;
8152 } 8747 }
8153 else 8748 else
8154 { 8749 {
8155 // sitting on an object so we need the bounding box of that 8750 // This is for standing/flying avatars
8156 // which should include the avatar so set the UUID to the 8751 float height = presence.Appearance.AvatarHeight / 2.0f;
8157 // UUID of the object the avatar is sat on and allow it to fall through 8752 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8158 // to processing an object 8753 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8159 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID); 8754 }
8160 objID = p.UUID; 8755
8756 // Adjust to the documented error offsets (see LSL Wiki)
8757 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8758 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8759*/
8760 {
8761 // This is for ground sitting avatars TODO!
8762 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8763 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8161 } 8764 }
8765 else
8766 {
8767 // This is for standing/flying avatars
8768 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8769 upper = new LSL_Vector(box.X, box.Y, box.Z);
8770 }
8771
8772 if (lower.x > upper.x)
8773 lower.x = upper.x;
8774 if (lower.y > upper.y)
8775 lower.y = upper.y;
8776 if (lower.z > upper.z)
8777 lower.z = upper.z;
8778
8779 result.Add(lower);
8780 result.Add(upper);
8781 return result;
8162 } 8782 }
8163 SceneObjectPart part = World.GetSceneObjectPart(objID); 8783
8784 part = World.GetSceneObjectPart(objID);
8164 // Currently only works for single prims without a sitting avatar 8785 // Currently only works for single prims without a sitting avatar
8165 if (part != null) 8786 if (part != null)
8166 { 8787 {
8167 Vector3 halfSize = part.Scale / 2.0f; 8788 float minX;
8168 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8789 float maxX;
8169 LSL_Vector upper = new LSL_Vector(halfSize); 8790 float minY;
8791 float maxY;
8792 float minZ;
8793 float maxZ;
8794
8795 // This BBox is in sim coordinates, with the offset being
8796 // a contained point.
8797 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8798 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8799
8800 minX -= offsets[0].X;
8801 maxX -= offsets[0].X;
8802 minY -= offsets[0].Y;
8803 maxY -= offsets[0].Y;
8804 minZ -= offsets[0].Z;
8805 maxZ -= offsets[0].Z;
8806
8807 LSL_Vector lower;
8808 LSL_Vector upper;
8809
8810 // Adjust to the documented error offsets (see LSL Wiki)
8811 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8812 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8813
8814 if (lower.x > upper.x)
8815 lower.x = upper.x;
8816 if (lower.y > upper.y)
8817 lower.y = upper.y;
8818 if (lower.z > upper.z)
8819 lower.z = upper.z;
8820
8170 result.Add(lower); 8821 result.Add(lower);
8171 result.Add(upper); 8822 result.Add(upper);
8172 return result; 8823 return result;
@@ -8183,227 +8834,70 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8183 return new LSL_Vector(m_host.GetGeometricCenter()); 8834 return new LSL_Vector(m_host.GetGeometricCenter());
8184 } 8835 }
8185 8836
8186 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8837 public LSL_List llGetPrimitiveParams(LSL_List rules)
8187 { 8838 {
8188 LSL_List result = new LSL_List(); 8839 m_host.AddScriptLPS(1);
8189 LSL_List remaining = null;
8190
8191 while (true)
8192 {
8193// m_log.DebugFormat(
8194// "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}",
8195// rules.Length, entity != null ? entity.Name : "NULL");
8196
8197 if (entity == null)
8198 return result;
8199 8840
8200 if (entity is SceneObjectPart) 8841 LSL_List result = new LSL_List();
8201 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
8202 else
8203 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
8204 8842
8205 if (remaining == null || remaining.Length < 2) 8843 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8206 return result;
8207 8844
8845 while ((object)remaining != null && remaining.Length > 2)
8846 {
8208 int linknumber = remaining.GetLSLIntegerItem(0); 8847 int linknumber = remaining.GetLSLIntegerItem(0);
8209 rules = remaining.GetSublist(1, -1); 8848 rules = remaining.GetSublist(1, -1);
8210 entity = GetLinkEntity(linknumber); 8849 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8211 }
8212 }
8213 8850
8214 public LSL_List llGetPrimitiveParams(LSL_List rules) 8851 foreach (SceneObjectPart part in parts)
8215 { 8852 remaining = GetPrimParams(part, rules, ref result);
8216 m_host.AddScriptLPS(1); 8853 }
8217 8854
8218 return GetEntityParams(m_host, rules); 8855 return result;
8219 } 8856 }
8220 8857
8221 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8858 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8222 { 8859 {
8223 m_host.AddScriptLPS(1); 8860 m_host.AddScriptLPS(1);
8224 8861
8225 return GetEntityParams(GetLinkEntity(linknumber), rules); 8862 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8226 } 8863 // keep other options as before
8227 8864
8228 public LSL_Vector GetAgentSize(ScenePresence sp) 8865 List<SceneObjectPart> parts;
8229 { 8866 List<ScenePresence> avatars;
8230 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8867
8231 } 8868 LSL_List res = new LSL_List();
8869 LSL_List remaining = null;
8232 8870
8233 /// <summary> 8871 while (rules.Length > 0)
8234 /// Gets params for a seated avatar in a linkset.
8235 /// </summary>
8236 /// <returns></returns>
8237 /// <param name='sp'></param>
8238 /// <param name='rules'></param>
8239 /// <param name='res'></param>
8240 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8241 {
8242 int idx = 0;
8243 while (idx < rules.Length)
8244 { 8872 {
8245 int code = (int)rules.GetLSLIntegerItem(idx++); 8873 parts = GetLinkParts(linknumber);
8246 int remain = rules.Length-idx; 8874 avatars = GetLinkAvatars(linknumber);
8247 8875
8248 switch (code) 8876 remaining = null;
8877 foreach (SceneObjectPart part in parts)
8249 { 8878 {
8250 case (int)ScriptBaseClass.PRIM_MATERIAL: 8879 remaining = GetPrimParams(part, rules, ref res);
8251 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8880 }
8252 break; 8881 foreach (ScenePresence avatar in avatars)
8253 8882 {
8254 case (int)ScriptBaseClass.PRIM_PHYSICS: 8883 remaining = GetPrimParams(avatar, rules, ref res);
8255 res.Add(ScriptBaseClass.FALSE); 8884 }
8256 break;
8257
8258 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8259 res.Add(ScriptBaseClass.FALSE);
8260 break;
8261
8262 case (int)ScriptBaseClass.PRIM_PHANTOM:
8263 res.Add(ScriptBaseClass.FALSE);
8264 break;
8265
8266 case (int)ScriptBaseClass.PRIM_POSITION:
8267 res.Add(new LSL_Vector(sp.AbsolutePosition));
8268 break;
8269
8270 case (int)ScriptBaseClass.PRIM_SIZE:
8271 res.Add(GetAgentSize(sp));
8272 break;
8273
8274 case (int)ScriptBaseClass.PRIM_ROTATION:
8275 res.Add(sp.GetWorldRotation());
8276 break;
8277
8278 case (int)ScriptBaseClass.PRIM_TYPE:
8279 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8280 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8281 res.Add(new LSL_Vector(0, 1, 0));
8282 res.Add(new LSL_Float(0));
8283 res.Add(new LSL_Vector(0, 0, 0));
8284 res.Add(new LSL_Vector(1, 1, 0));
8285 res.Add(new LSL_Vector(0, 0, 0));
8286 break;
8287
8288 case (int)ScriptBaseClass.PRIM_TEXTURE:
8289 if (remain < 1)
8290 return null;
8291
8292 int face = (int)rules.GetLSLIntegerItem(idx++);
8293 if (face > 21)
8294 break;
8295
8296 res.Add(new LSL_String(""));
8297 res.Add(ScriptBaseClass.ZERO_VECTOR);
8298 res.Add(ScriptBaseClass.ZERO_VECTOR);
8299 res.Add(new LSL_Float(0));
8300 break;
8301
8302 case (int)ScriptBaseClass.PRIM_COLOR:
8303 if (remain < 1)
8304 return null;
8305
8306 face = (int)rules.GetLSLIntegerItem(idx++);
8307 if (face > 21)
8308 break;
8309
8310 res.Add(ScriptBaseClass.ZERO_VECTOR);
8311 res.Add(new LSL_Float(0));
8312 break;
8313
8314 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8315 if (remain < 1)
8316 return null;
8317
8318 face = (int)rules.GetLSLIntegerItem(idx++);
8319 if (face > 21)
8320 break;
8321
8322 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8323 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8324 break;
8325
8326 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8327 if (remain < 1)
8328 return null;
8329
8330 face = (int)rules.GetLSLIntegerItem(idx++);
8331 if (face > 21)
8332 break;
8333
8334 res.Add(ScriptBaseClass.FALSE);
8335 break;
8336
8337 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8338 res.Add(ScriptBaseClass.FALSE);
8339 res.Add(new LSL_Integer(0));
8340 res.Add(new LSL_Float(0));
8341 res.Add(new LSL_Float(0));
8342 res.Add(new LSL_Float(0));
8343 res.Add(new LSL_Float(0));
8344 res.Add(ScriptBaseClass.ZERO_VECTOR);
8345 break;
8346
8347 case (int)ScriptBaseClass.PRIM_TEXGEN:
8348 if (remain < 1)
8349 return null;
8350
8351 face = (int)rules.GetLSLIntegerItem(idx++);
8352 if (face > 21)
8353 break;
8354
8355 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8356 break;
8357
8358 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8359 res.Add(ScriptBaseClass.FALSE);
8360 res.Add(ScriptBaseClass.ZERO_VECTOR);
8361 res.Add(ScriptBaseClass.ZERO_VECTOR);
8362 break;
8363
8364 case (int)ScriptBaseClass.PRIM_GLOW:
8365 if (remain < 1)
8366 return null;
8367
8368 face = (int)rules.GetLSLIntegerItem(idx++);
8369 if (face > 21)
8370 break;
8371
8372 res.Add(new LSL_Float(0));
8373 break;
8374
8375 case (int)ScriptBaseClass.PRIM_TEXT:
8376 res.Add(new LSL_String(""));
8377 res.Add(ScriptBaseClass.ZERO_VECTOR);
8378 res.Add(new LSL_Float(1));
8379 break;
8380
8381 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8382 res.Add(new LSL_Rotation(sp.Rotation));
8383 break;
8384
8385 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8386 res.Add(new LSL_Vector(sp.OffsetPosition));
8387 break;
8388
8389 case (int)ScriptBaseClass.PRIM_SLICE:
8390 res.Add(new LSL_Vector(0, 1, 0));
8391 break;
8392
8393 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8394 if(remain < 3)
8395 return null;
8396 8885
8397 return rules.GetSublist(idx, -1); 8886 if ((object)remaining != null && remaining.Length > 0)
8887 {
8888 linknumber = remaining.GetLSLIntegerItem(0);
8889 rules = remaining.GetSublist(1, -1);
8398 } 8890 }
8891 else
8892 break;
8399 } 8893 }
8400 8894
8401 return null; 8895 return res;
8402 } 8896 }
8403 8897
8404 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8898 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8405 { 8899 {
8406 int idx = 0; 8900 int idx=0;
8407 while (idx < rules.Length) 8901 while (idx < rules.Length)
8408 { 8902 {
8409 int code = (int)rules.GetLSLIntegerItem(idx++); 8903 int code = (int)rules.GetLSLIntegerItem(idx++);
@@ -8437,19 +8931,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8437 break; 8931 break;
8438 8932
8439 case (int)ScriptBaseClass.PRIM_POSITION: 8933 case (int)ScriptBaseClass.PRIM_POSITION:
8440 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8934 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8441 8935 part.AbsolutePosition.Y,
8442 // For some reason, the part.AbsolutePosition.* values do not change if the 8936 part.AbsolutePosition.Z);
8443 // linkset is rotated; they always reflect the child prim's world position
8444 // as though the linkset is unrotated. This is incompatible behavior with SL's
8445 // implementation, so will break scripts imported from there (not to mention it
8446 // makes it more difficult to determine a child prim's actual inworld position).
8447 if (!part.IsRoot)
8448 {
8449 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8450 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8451 }
8452
8453 res.Add(v); 8937 res.Add(v);
8454 break; 8938 break;
8455 8939
@@ -8619,30 +9103,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8619 if (remain < 1) 9103 if (remain < 1)
8620 return null; 9104 return null;
8621 9105
8622 face=(int)rules.GetLSLIntegerItem(idx++); 9106 face = (int)rules.GetLSLIntegerItem(idx++);
8623 9107
8624 tex = part.Shape.Textures; 9108 tex = part.Shape.Textures;
9109 int shiny;
8625 if (face == ScriptBaseClass.ALL_SIDES) 9110 if (face == ScriptBaseClass.ALL_SIDES)
8626 { 9111 {
8627 for (face = 0; face < GetNumberOfSides(part); face++) 9112 for (face = 0; face < GetNumberOfSides(part); face++)
8628 { 9113 {
8629 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9114 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8630 // Convert Shininess to PRIM_SHINY_* 9115 if (shinyness == Shininess.High)
8631 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9116 {
8632 // PRIM_BUMP_* 9117 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8633 res.Add(new LSL_Integer((int)texface.Bump)); 9118 }
9119 else if (shinyness == Shininess.Medium)
9120 {
9121 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9122 }
9123 else if (shinyness == Shininess.Low)
9124 {
9125 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9126 }
9127 else
9128 {
9129 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9130 }
9131 res.Add(new LSL_Integer(shiny));
9132 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8634 } 9133 }
8635 } 9134 }
8636 else 9135 else
8637 { 9136 {
8638 if (face >= 0 && face < GetNumberOfSides(part)) 9137 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9138 if (shinyness == Shininess.High)
8639 { 9139 {
8640 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9140 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8641 // Convert Shininess to PRIM_SHINY_*
8642 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8643 // PRIM_BUMP_*
8644 res.Add(new LSL_Integer((int)texface.Bump));
8645 } 9141 }
9142 else if (shinyness == Shininess.Medium)
9143 {
9144 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9145 }
9146 else if (shinyness == Shininess.Low)
9147 {
9148 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9149 }
9150 else
9151 {
9152 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9153 }
9154 res.Add(new LSL_Integer(shiny));
9155 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8646 } 9156 }
8647 break; 9157 break;
8648 9158
@@ -8653,21 +9163,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8653 face = (int)rules.GetLSLIntegerItem(idx++); 9163 face = (int)rules.GetLSLIntegerItem(idx++);
8654 9164
8655 tex = part.Shape.Textures; 9165 tex = part.Shape.Textures;
9166 int fullbright;
8656 if (face == ScriptBaseClass.ALL_SIDES) 9167 if (face == ScriptBaseClass.ALL_SIDES)
8657 { 9168 {
8658 for (face = 0; face < GetNumberOfSides(part); face++) 9169 for (face = 0; face < GetNumberOfSides(part); face++)
8659 { 9170 {
8660 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9171 if (tex.GetFace((uint)face).Fullbright == true)
8661 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9172 {
9173 fullbright = ScriptBaseClass.TRUE;
9174 }
9175 else
9176 {
9177 fullbright = ScriptBaseClass.FALSE;
9178 }
9179 res.Add(new LSL_Integer(fullbright));
8662 } 9180 }
8663 } 9181 }
8664 else 9182 else
8665 { 9183 {
8666 if (face >= 0 && face < GetNumberOfSides(part)) 9184 if (tex.GetFace((uint)face).Fullbright == true)
8667 { 9185 {
8668 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9186 fullbright = ScriptBaseClass.TRUE;
8669 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9187 }
9188 else
9189 {
9190 fullbright = ScriptBaseClass.FALSE;
8670 } 9191 }
9192 res.Add(new LSL_Integer(fullbright));
8671 } 9193 }
8672 break; 9194 break;
8673 9195
@@ -8689,27 +9211,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8689 break; 9211 break;
8690 9212
8691 case (int)ScriptBaseClass.PRIM_TEXGEN: 9213 case (int)ScriptBaseClass.PRIM_TEXGEN:
9214 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8692 if (remain < 1) 9215 if (remain < 1)
8693 return null; 9216 return null;
8694 9217
8695 face=(int)rules.GetLSLIntegerItem(idx++); 9218 face = (int)rules.GetLSLIntegerItem(idx++);
8696 9219
8697 tex = part.Shape.Textures; 9220 tex = part.Shape.Textures;
8698 if (face == ScriptBaseClass.ALL_SIDES) 9221 if (face == ScriptBaseClass.ALL_SIDES)
8699 { 9222 {
8700 for (face = 0; face < GetNumberOfSides(part); face++) 9223 for (face = 0; face < GetNumberOfSides(part); face++)
8701 { 9224 {
8702 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9225 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8703 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9226 {
8704 res.Add(new LSL_Integer((uint)texgen >> 1)); 9227 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9228 }
9229 else
9230 {
9231 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9232 }
8705 } 9233 }
8706 } 9234 }
8707 else 9235 else
8708 { 9236 {
8709 if (face >= 0 && face < GetNumberOfSides(part)) 9237 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8710 { 9238 {
8711 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9239 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8712 res.Add(new LSL_Integer((uint)texgen >> 1)); 9240 }
9241 else
9242 {
9243 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8713 } 9244 }
8714 } 9245 }
8715 break; 9246 break;
@@ -8733,24 +9264,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8733 if (remain < 1) 9264 if (remain < 1)
8734 return null; 9265 return null;
8735 9266
8736 face=(int)rules.GetLSLIntegerItem(idx++); 9267 face = (int)rules.GetLSLIntegerItem(idx++);
8737 9268
8738 tex = part.Shape.Textures; 9269 tex = part.Shape.Textures;
9270 float primglow;
8739 if (face == ScriptBaseClass.ALL_SIDES) 9271 if (face == ScriptBaseClass.ALL_SIDES)
8740 { 9272 {
8741 for (face = 0; face < GetNumberOfSides(part); face++) 9273 for (face = 0; face < GetNumberOfSides(part); face++)
8742 { 9274 {
8743 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9275 primglow = tex.GetFace((uint)face).Glow;
8744 res.Add(new LSL_Float(texface.Glow)); 9276 res.Add(new LSL_Float(primglow));
8745 } 9277 }
8746 } 9278 }
8747 else 9279 else
8748 { 9280 {
8749 if (face >= 0 && face < GetNumberOfSides(part)) 9281 primglow = tex.GetFace((uint)face).Glow;
8750 { 9282 res.Add(new LSL_Float(primglow));
8751 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8752 res.Add(new LSL_Float(texface.Glow));
8753 }
8754 } 9283 }
8755 break; 9284 break;
8756 9285
@@ -8762,15 +9291,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8762 textColor.B)); 9291 textColor.B));
8763 res.Add(new LSL_Float(textColor.A)); 9292 res.Add(new LSL_Float(textColor.A));
8764 break; 9293 break;
9294
8765 case (int)ScriptBaseClass.PRIM_NAME: 9295 case (int)ScriptBaseClass.PRIM_NAME:
8766 res.Add(new LSL_String(part.Name)); 9296 res.Add(new LSL_String(part.Name));
8767 break; 9297 break;
9298
8768 case (int)ScriptBaseClass.PRIM_DESC: 9299 case (int)ScriptBaseClass.PRIM_DESC:
8769 res.Add(new LSL_String(part.Description)); 9300 res.Add(new LSL_String(part.Description));
8770 break; 9301 break;
8771 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9302 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8772 res.Add(new LSL_Rotation(part.RotationOffset)); 9303 res.Add(new LSL_Rotation(part.RotationOffset));
8773 break; 9304 break;
9305
8774 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9306 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8775 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9307 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8776 break; 9308 break;
@@ -9383,8 +9915,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9383 // The function returns an ordered list 9915 // The function returns an ordered list
9384 // representing the tokens found in the supplied 9916 // representing the tokens found in the supplied
9385 // sources string. If two successive tokenizers 9917 // sources string. If two successive tokenizers
9386 // are encountered, then a NULL entry is added 9918 // are encountered, then a null-string entry is
9387 // to the list. 9919 // added to the list.
9388 // 9920 //
9389 // It is a precondition that the source and 9921 // It is a precondition that the source and
9390 // toekizer lisst are non-null. If they are null, 9922 // toekizer lisst are non-null. If they are null,
@@ -9392,7 +9924,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9392 // while their lengths are being determined. 9924 // while their lengths are being determined.
9393 // 9925 //
9394 // A small amount of working memoryis required 9926 // A small amount of working memoryis required
9395 // of approximately 8*#tokenizers. 9927 // of approximately 8*#tokenizers + 8*srcstrlen.
9396 // 9928 //
9397 // There are many ways in which this function 9929 // There are many ways in which this function
9398 // can be implemented, this implementation is 9930 // can be implemented, this implementation is
@@ -9408,155 +9940,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9408 // and eliminates redundant tokenizers as soon 9940 // and eliminates redundant tokenizers as soon
9409 // as is possible. 9941 // as is possible.
9410 // 9942 //
9411 // The implementation tries to avoid any copying 9943 // The implementation tries to minimize temporary
9412 // of arrays or other objects. 9944 // garbage generation.
9413 // </remarks> 9945 // </remarks>
9414 9946
9415 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9947 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9416 { 9948 {
9417 int beginning = 0; 9949 return ParseString2List(src, separators, spacers, true);
9418 int srclen = src.Length; 9950 }
9419 int seplen = separators.Length;
9420 object[] separray = separators.Data;
9421 int spclen = spacers.Length;
9422 object[] spcarray = spacers.Data;
9423 int mlen = seplen+spclen;
9424
9425 int[] offset = new int[mlen+1];
9426 bool[] active = new bool[mlen];
9427
9428 int best;
9429 int j;
9430
9431 // Initial capacity reduces resize cost
9432 9951
9433 LSL_List tokens = new LSL_List(); 9952 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9953 {
9954 int srclen = src.Length;
9955 int seplen = separators.Length;
9956 object[] separray = separators.Data;
9957 int spclen = spacers.Length;
9958 object[] spcarray = spacers.Data;
9959 int dellen = 0;
9960 string[] delarray = new string[seplen+spclen];
9434 9961
9435 // All entries are initially valid 9962 int outlen = 0;
9963 string[] outarray = new string[srclen*2+1];
9436 9964
9437 for (int i = 0; i < mlen; i++) 9965 int i, j;
9438 active[i] = true; 9966 string d;
9439 9967
9440 offset[mlen] = srclen; 9968 m_host.AddScriptLPS(1);
9441 9969
9442 while (beginning < srclen) 9970 /*
9971 * Convert separator and spacer lists to C# strings.
9972 * Also filter out null strings so we don't hang.
9973 */
9974 for (i = 0; i < seplen; i ++)
9443 { 9975 {
9976 d = separray[i].ToString();
9977 if (d.Length > 0)
9978 {
9979 delarray[dellen++] = d;
9980 }
9981 }
9982 seplen = dellen;
9444 9983
9445 best = mlen; // as bad as it gets 9984 for (i = 0; i < spclen; i ++)
9985 {
9986 d = spcarray[i].ToString();
9987 if (d.Length > 0)
9988 {
9989 delarray[dellen++] = d;
9990 }
9991 }
9446 9992
9447 // Scan for separators 9993 /*
9994 * Scan through source string from beginning to end.
9995 */
9996 for (i = 0;;)
9997 {
9448 9998
9449 for (j = 0; j < seplen; j++) 9999 /*
10000 * Find earliest delimeter in src starting at i (if any).
10001 */
10002 int earliestDel = -1;
10003 int earliestSrc = srclen;
10004 string earliestStr = null;
10005 for (j = 0; j < dellen; j ++)
9450 { 10006 {
9451 if (separray[j].ToString() == String.Empty) 10007 d = delarray[j];
9452 active[j] = false; 10008 if (d != null)
9453
9454 if (active[j])
9455 { 10009 {
9456 // scan all of the markers 10010 int index = src.IndexOf(d, i);
9457 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10011 if (index < 0)
9458 { 10012 {
9459 // not present at all 10013 delarray[j] = null; // delim nowhere in src, don't check it anymore
9460 active[j] = false;
9461 } 10014 }
9462 else 10015 else if (index < earliestSrc)
9463 { 10016 {
9464 // present and correct 10017 earliestSrc = index; // where delimeter starts in source string
9465 if (offset[j] < offset[best]) 10018 earliestDel = j; // where delimeter is in delarray[]
9466 { 10019 earliestStr = d; // the delimeter string from delarray[]
9467 // closest so far 10020 if (index == i) break; // can't do any better than found at beg of string
9468 best = j;
9469 if (offset[best] == beginning)
9470 break;
9471 }
9472 } 10021 }
9473 } 10022 }
9474 } 10023 }
9475 10024
9476 // Scan for spacers 10025 /*
9477 10026 * Output source string starting at i through start of earliest delimeter.
9478 if (offset[best] != beginning) 10027 */
10028 if (keepNulls || (earliestSrc > i))
9479 { 10029 {
9480 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10030 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9481 {
9482 if (spcarray[j-seplen].ToString() == String.Empty)
9483 active[j] = false;
9484
9485 if (active[j])
9486 {
9487 // scan all of the markers
9488 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9489 {
9490 // not present at all
9491 active[j] = false;
9492 }
9493 else
9494 {
9495 // present and correct
9496 if (offset[j] < offset[best])
9497 {
9498 // closest so far
9499 best = j;
9500 }
9501 }
9502 }
9503 }
9504 } 10031 }
9505 10032
9506 // This is the normal exit from the scanning loop 10033 /*
10034 * If no delimeter found at or after i, we're done scanning.
10035 */
10036 if (earliestDel < 0) break;
9507 10037
9508 if (best == mlen) 10038 /*
10039 * If delimeter was a spacer, output the spacer.
10040 */
10041 if (earliestDel >= seplen)
9509 { 10042 {
9510 // no markers were found on this pass 10043 outarray[outlen++] = earliestStr;
9511 // so we're pretty much done
9512 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9513 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9514 break;
9515 } 10044 }
9516 10045
9517 // Otherwise we just add the newly delimited token 10046 /*
9518 // and recalculate where the search should continue. 10047 * Look at rest of src string following delimeter.
9519 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10048 */
9520 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10049 i = earliestSrc + earliestStr.Length;
9521
9522 if (best < seplen)
9523 {
9524 beginning = offset[best] + (separray[best].ToString()).Length;
9525 }
9526 else
9527 {
9528 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9529 string str = spcarray[best - seplen].ToString();
9530 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9531 tokens.Add(new LSL_String(str));
9532 }
9533 } 10050 }
9534 10051
9535 // This an awkward an not very intuitive boundary case. If the 10052 /*
9536 // last substring is a tokenizer, then there is an implied trailing 10053 * Make up an exact-sized output array suitable for an LSL_List object.
9537 // null list entry. Hopefully the single comparison will not be too 10054 */
9538 // arduous. Alternatively the 'break' could be replced with a return 10055 object[] outlist = new object[outlen];
9539 // but that's shabby programming. 10056 for (i = 0; i < outlen; i ++)
9540
9541 if ((beginning == srclen) && (keepNulls))
9542 { 10057 {
9543 if (srclen != 0) 10058 outlist[i] = new LSL_String(outarray[i]);
9544 tokens.Add(new LSL_String(""));
9545 } 10059 }
9546 10060 return new LSL_List(outlist);
9547 return tokens;
9548 }
9549
9550 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9551 {
9552 m_host.AddScriptLPS(1);
9553 return this.ParseString(src, separators, spacers, false);
9554 }
9555
9556 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9557 {
9558 m_host.AddScriptLPS(1);
9559 return this.ParseString(src, separators, spacers, true);
9560 } 10061 }
9561 10062
9562 public LSL_Integer llGetObjectPermMask(int mask) 10063 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9651,6 +10152,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9651 case 4: 10152 case 4:
9652 return (int)item.NextPermissions; 10153 return (int)item.NextPermissions;
9653 } 10154 }
10155 m_host.TaskInventory.LockItemsForRead(false);
9654 10156
9655 return -1; 10157 return -1;
9656 } 10158 }
@@ -9854,31 +10356,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9854 UUID key = new UUID(); 10356 UUID key = new UUID();
9855 if (UUID.TryParse(id, out key)) 10357 if (UUID.TryParse(id, out key))
9856 { 10358 {
9857 try 10359 // return total object mass
9858 { 10360 SceneObjectPart part = World.GetSceneObjectPart(key);
9859 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10361 if (part != null)
9860 if (obj != null) 10362 return part.ParentGroup.GetMass();
9861 return (double)obj.GetMass(); 10363
9862 // the object is null so the key is for an avatar 10364 // the object is null so the key is for an avatar
9863 ScenePresence avatar = World.GetScenePresence(key); 10365 ScenePresence avatar = World.GetScenePresence(key);
9864 if (avatar != null) 10366 if (avatar != null)
9865 if (avatar.IsChildAgent)
9866 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9867 // child agents have a mass of 1.0
9868 return 1;
9869 else
9870 return (double)avatar.GetMass();
9871 }
9872 catch (KeyNotFoundException)
9873 { 10367 {
9874 return 0; // The Object/Agent not in the region so just return zero 10368 if (avatar.IsChildAgent)
10369 {
10370 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10371 // child agents have a mass of 1.0
10372 return 1;
10373 }
10374 else
10375 {
10376 return (double)avatar.GetMass();
10377 }
9875 } 10378 }
9876 } 10379 }
9877 return 0; 10380 return 0;
9878 } 10381 }
9879 10382
9880 /// <summary> 10383 /// <summary>
9881 /// illListReplaceList removes the sub-list defined by the inclusive indices 10384 /// llListReplaceList removes the sub-list defined by the inclusive indices
9882 /// start and end and inserts the src list in its place. The inclusive 10385 /// start and end and inserts the src list in its place. The inclusive
9883 /// nature of the indices means that at least one element must be deleted 10386 /// nature of the indices means that at least one element must be deleted
9884 /// if the indices are within the bounds of the existing list. I.e. 2,2 10387 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9935,16 +10438,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9935 // based upon end. Note that if end exceeds the upper 10438 // based upon end. Note that if end exceeds the upper
9936 // bound in this case, the entire destination list 10439 // bound in this case, the entire destination list
9937 // is removed. 10440 // is removed.
9938 else 10441 else if (start == 0)
9939 { 10442 {
9940 if (end + 1 < dest.Length) 10443 if (end + 1 < dest.Length)
9941 {
9942 return src + dest.GetSublist(end + 1, -1); 10444 return src + dest.GetSublist(end + 1, -1);
9943 }
9944 else 10445 else
9945 {
9946 return src; 10446 return src;
9947 } 10447 }
10448 else // Start < 0
10449 {
10450 if (end + 1 < dest.Length)
10451 return dest.GetSublist(end + 1, -1);
10452 else
10453 return new LSL_List();
9948 } 10454 }
9949 } 10455 }
9950 // Finally, if start > end, we strip away a prefix and 10456 // Finally, if start > end, we strip away a prefix and
@@ -9995,17 +10501,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9995 int width = 0; 10501 int width = 0;
9996 int height = 0; 10502 int height = 0;
9997 10503
9998 ParcelMediaCommandEnum? commandToSend = null; 10504 uint commandToSend = 0;
9999 float time = 0.0f; // default is from start 10505 float time = 0.0f; // default is from start
10000 10506
10001 ScenePresence presence = null; 10507 ScenePresence presence = null;
10002 10508
10003 for (int i = 0; i < commandList.Data.Length; i++) 10509 for (int i = 0; i < commandList.Data.Length; i++)
10004 { 10510 {
10005 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10511 uint command = (uint)(commandList.GetLSLIntegerItem(i));
10006 switch (command) 10512 switch (command)
10007 { 10513 {
10008 case ParcelMediaCommandEnum.Agent: 10514 case (uint)ParcelMediaCommandEnum.Agent:
10009 // we send only to one agent 10515 // we send only to one agent
10010 if ((i + 1) < commandList.Length) 10516 if ((i + 1) < commandList.Length)
10011 { 10517 {
@@ -10022,25 +10528,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10022 } 10528 }
10023 break; 10529 break;
10024 10530
10025 case ParcelMediaCommandEnum.Loop: 10531 case (uint)ParcelMediaCommandEnum.Loop:
10026 loop = 1; 10532 loop = 1;
10027 commandToSend = command; 10533 commandToSend = command;
10028 update = true; //need to send the media update packet to set looping 10534 update = true; //need to send the media update packet to set looping
10029 break; 10535 break;
10030 10536
10031 case ParcelMediaCommandEnum.Play: 10537 case (uint)ParcelMediaCommandEnum.Play:
10032 loop = 0; 10538 loop = 0;
10033 commandToSend = command; 10539 commandToSend = command;
10034 update = true; //need to send the media update packet to make sure it doesn't loop 10540 update = true; //need to send the media update packet to make sure it doesn't loop
10035 break; 10541 break;
10036 10542
10037 case ParcelMediaCommandEnum.Pause: 10543 case (uint)ParcelMediaCommandEnum.Pause:
10038 case ParcelMediaCommandEnum.Stop: 10544 case (uint)ParcelMediaCommandEnum.Stop:
10039 case ParcelMediaCommandEnum.Unload: 10545 case (uint)ParcelMediaCommandEnum.Unload:
10040 commandToSend = command; 10546 commandToSend = command;
10041 break; 10547 break;
10042 10548
10043 case ParcelMediaCommandEnum.Url: 10549 case (uint)ParcelMediaCommandEnum.Url:
10044 if ((i + 1) < commandList.Length) 10550 if ((i + 1) < commandList.Length)
10045 { 10551 {
10046 if (commandList.Data[i + 1] is LSL_String) 10552 if (commandList.Data[i + 1] is LSL_String)
@@ -10053,7 +10559,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10053 } 10559 }
10054 break; 10560 break;
10055 10561
10056 case ParcelMediaCommandEnum.Texture: 10562 case (uint)ParcelMediaCommandEnum.Texture:
10057 if ((i + 1) < commandList.Length) 10563 if ((i + 1) < commandList.Length)
10058 { 10564 {
10059 if (commandList.Data[i + 1] is LSL_String) 10565 if (commandList.Data[i + 1] is LSL_String)
@@ -10066,7 +10572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10066 } 10572 }
10067 break; 10573 break;
10068 10574
10069 case ParcelMediaCommandEnum.Time: 10575 case (uint)ParcelMediaCommandEnum.Time:
10070 if ((i + 1) < commandList.Length) 10576 if ((i + 1) < commandList.Length)
10071 { 10577 {
10072 if (commandList.Data[i + 1] is LSL_Float) 10578 if (commandList.Data[i + 1] is LSL_Float)
@@ -10078,7 +10584,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10078 } 10584 }
10079 break; 10585 break;
10080 10586
10081 case ParcelMediaCommandEnum.AutoAlign: 10587 case (uint)ParcelMediaCommandEnum.AutoAlign:
10082 if ((i + 1) < commandList.Length) 10588 if ((i + 1) < commandList.Length)
10083 { 10589 {
10084 if (commandList.Data[i + 1] is LSL_Integer) 10590 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10092,7 +10598,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10092 } 10598 }
10093 break; 10599 break;
10094 10600
10095 case ParcelMediaCommandEnum.Type: 10601 case (uint)ParcelMediaCommandEnum.Type:
10096 if ((i + 1) < commandList.Length) 10602 if ((i + 1) < commandList.Length)
10097 { 10603 {
10098 if (commandList.Data[i + 1] is LSL_String) 10604 if (commandList.Data[i + 1] is LSL_String)
@@ -10105,7 +10611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10105 } 10611 }
10106 break; 10612 break;
10107 10613
10108 case ParcelMediaCommandEnum.Desc: 10614 case (uint)ParcelMediaCommandEnum.Desc:
10109 if ((i + 1) < commandList.Length) 10615 if ((i + 1) < commandList.Length)
10110 { 10616 {
10111 if (commandList.Data[i + 1] is LSL_String) 10617 if (commandList.Data[i + 1] is LSL_String)
@@ -10118,7 +10624,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10118 } 10624 }
10119 break; 10625 break;
10120 10626
10121 case ParcelMediaCommandEnum.Size: 10627 case (uint)ParcelMediaCommandEnum.Size:
10122 if ((i + 2) < commandList.Length) 10628 if ((i + 2) < commandList.Length)
10123 { 10629 {
10124 if (commandList.Data[i + 1] is LSL_Integer) 10630 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10188,7 +10694,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10188 } 10694 }
10189 } 10695 }
10190 10696
10191 if (commandToSend != null) 10697 if (commandToSend != 0)
10192 { 10698 {
10193 // the commandList contained a start/stop/... command, too 10699 // the commandList contained a start/stop/... command, too
10194 if (presence == null) 10700 if (presence == null)
@@ -10225,7 +10731,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10225 10731
10226 if (aList.Data[i] != null) 10732 if (aList.Data[i] != null)
10227 { 10733 {
10228 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10734 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10229 { 10735 {
10230 case ParcelMediaCommandEnum.Url: 10736 case ParcelMediaCommandEnum.Url:
10231 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10737 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10282,15 +10788,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10282 10788
10283 if (quick_pay_buttons.Data.Length < 4) 10789 if (quick_pay_buttons.Data.Length < 4)
10284 { 10790 {
10285 LSLError("List must have at least 4 elements"); 10791 int x;
10286 return; 10792 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10793 {
10794 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10795 }
10287 } 10796 }
10288 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10797 int[] nPrice = new int[5];
10289 10798 nPrice[0] = price;
10290 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10799 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10291 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10800 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10292 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10801 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10293 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10802 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10803 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10294 m_host.ParentGroup.HasGroupChanged = true; 10804 m_host.ParentGroup.HasGroupChanged = true;
10295 } 10805 }
10296 10806
@@ -10307,7 +10817,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10307 return Vector3.Zero; 10817 return Vector3.Zero;
10308 } 10818 }
10309 10819
10310 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10820// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10821 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10311 if (presence != null) 10822 if (presence != null)
10312 { 10823 {
10313 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10824 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10330,7 +10841,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10330 return Quaternion.Identity; 10841 return Quaternion.Identity;
10331 } 10842 }
10332 10843
10333 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10844// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10845 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10334 if (presence != null) 10846 if (presence != null)
10335 { 10847 {
10336 return new LSL_Rotation(presence.CameraRotation); 10848 return new LSL_Rotation(presence.CameraRotation);
@@ -10390,14 +10902,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10390 { 10902 {
10391 m_host.AddScriptLPS(1); 10903 m_host.AddScriptLPS(1);
10392 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10904 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10393 if (detectedParams == null) return; // only works on the first detected avatar 10905 if (detectedParams == null)
10394 10906 {
10907 if (m_host.ParentGroup.IsAttachment == true)
10908 {
10909 detectedParams = new DetectParams();
10910 detectedParams.Key = m_host.OwnerID;
10911 }
10912 else
10913 {
10914 return;
10915 }
10916 }
10917
10395 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10918 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10396 if (avatar != null) 10919 if (avatar != null)
10397 { 10920 {
10398 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10921 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10399 simname, pos, lookAt); 10922 simname, pos, lookAt);
10400 } 10923 }
10924
10401 ScriptSleep(1000); 10925 ScriptSleep(1000);
10402 } 10926 }
10403 10927
@@ -10521,12 +11045,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10521 11045
10522 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11046 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10523 object[] data = rules.Data; 11047 object[] data = rules.Data;
10524 for (int i = 0; i < data.Length; ++i) { 11048 for (int i = 0; i < data.Length; ++i)
11049 {
10525 int type = Convert.ToInt32(data[i++].ToString()); 11050 int type = Convert.ToInt32(data[i++].ToString());
10526 if (i >= data.Length) break; // odd number of entries => ignore the last 11051 if (i >= data.Length) break; // odd number of entries => ignore the last
10527 11052
10528 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11053 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10529 switch (type) { 11054 switch (type)
11055 {
10530 case ScriptBaseClass.CAMERA_FOCUS: 11056 case ScriptBaseClass.CAMERA_FOCUS:
10531 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11057 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10532 case ScriptBaseClass.CAMERA_POSITION: 11058 case ScriptBaseClass.CAMERA_POSITION:
@@ -10631,19 +11157,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10631 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11157 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10632 { 11158 {
10633 m_host.AddScriptLPS(1); 11159 m_host.AddScriptLPS(1);
10634 string ret = String.Empty; 11160
10635 string src1 = llBase64ToString(str1); 11161 if (str1 == String.Empty)
10636 string src2 = llBase64ToString(str2); 11162 return String.Empty;
10637 int c = 0; 11163 if (str2 == String.Empty)
10638 for (int i = 0; i < src1.Length; i++) 11164 return str1;
11165
11166 int len = str2.Length;
11167 if ((len % 4) != 0) // LL is EVIL!!!!
11168 {
11169 while (str2.EndsWith("="))
11170 str2 = str2.Substring(0, str2.Length - 1);
11171
11172 len = str2.Length;
11173 int mod = len % 4;
11174
11175 if (mod == 1)
11176 str2 = str2.Substring(0, str2.Length - 1);
11177 else if (mod == 2)
11178 str2 += "==";
11179 else if (mod == 3)
11180 str2 += "=";
11181 }
11182
11183 byte[] data1;
11184 byte[] data2;
11185 try
11186 {
11187 data1 = Convert.FromBase64String(str1);
11188 data2 = Convert.FromBase64String(str2);
11189 }
11190 catch (Exception)
10639 { 11191 {
10640 ret += (char) (src1[i] ^ src2[c]); 11192 return new LSL_String(String.Empty);
11193 }
10641 11194
10642 c++; 11195 byte[] d2 = new Byte[data1.Length];
10643 if (c >= src2.Length) 11196 int pos = 0;
10644 c = 0; 11197
11198 if (data1.Length <= data2.Length)
11199 {
11200 Array.Copy(data2, 0, d2, 0, data1.Length);
10645 } 11201 }
10646 return llStringToBase64(ret); 11202 else
11203 {
11204 while (pos < data1.Length)
11205 {
11206 len = data1.Length - pos;
11207 if (len > data2.Length)
11208 len = data2.Length;
11209
11210 Array.Copy(data2, 0, d2, pos, len);
11211 pos += len;
11212 }
11213 }
11214
11215 for (pos = 0 ; pos < data1.Length ; pos++ )
11216 data1[pos] ^= d2[pos];
11217
11218 return Convert.ToBase64String(data1);
10647 } 11219 }
10648 11220
10649 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11221 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10747,16 +11319,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10747 if (userAgent != null) 11319 if (userAgent != null)
10748 httpHeaders["User-Agent"] = userAgent; 11320 httpHeaders["User-Agent"] = userAgent;
10749 11321
11322 // See if the URL contains any header hacks
11323 string[] urlParts = url.Split(new char[] {'\n'});
11324 if (urlParts.Length > 1)
11325 {
11326 // Iterate the passed headers and parse them
11327 for (int i = 1 ; i < urlParts.Length ; i++ )
11328 {
11329 // The rest of those would be added to the body in SL.
11330 // Let's not do that.
11331 if (urlParts[i] == String.Empty)
11332 break;
11333
11334 // See if this could be a valid header
11335 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11336 if (headerParts.Length != 2)
11337 continue;
11338
11339 string headerName = headerParts[0].Trim();
11340 string headerValue = headerParts[1].Trim();
11341
11342 // Filter out headers that could be used to abuse
11343 // another system or cloak the request
11344 if (headerName.ToLower() == "x-secondlife-shard" ||
11345 headerName.ToLower() == "x-secondlife-object-name" ||
11346 headerName.ToLower() == "x-secondlife-object-key" ||
11347 headerName.ToLower() == "x-secondlife-region" ||
11348 headerName.ToLower() == "x-secondlife-local-position" ||
11349 headerName.ToLower() == "x-secondlife-local-velocity" ||
11350 headerName.ToLower() == "x-secondlife-local-rotation" ||
11351 headerName.ToLower() == "x-secondlife-owner-name" ||
11352 headerName.ToLower() == "x-secondlife-owner-key" ||
11353 headerName.ToLower() == "connection" ||
11354 headerName.ToLower() == "content-length" ||
11355 headerName.ToLower() == "from" ||
11356 headerName.ToLower() == "host" ||
11357 headerName.ToLower() == "proxy-authorization" ||
11358 headerName.ToLower() == "referer" ||
11359 headerName.ToLower() == "trailer" ||
11360 headerName.ToLower() == "transfer-encoding" ||
11361 headerName.ToLower() == "via" ||
11362 headerName.ToLower() == "authorization")
11363 continue;
11364
11365 httpHeaders[headerName] = headerValue;
11366 }
11367
11368 // Finally, strip any protocol specifier from the URL
11369 url = urlParts[0].Trim();
11370 int idx = url.IndexOf(" HTTP/");
11371 if (idx != -1)
11372 url = url.Substring(0, idx);
11373 }
11374
10750 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11375 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10751 Regex r = new Regex(authregex); 11376 Regex r = new Regex(authregex);
10752 int[] gnums = r.GetGroupNumbers(); 11377 int[] gnums = r.GetGroupNumbers();
10753 Match m = r.Match(url); 11378 Match m = r.Match(url);
10754 if (m.Success) { 11379 if (m.Success)
10755 for (int i = 1; i < gnums.Length; i++) { 11380 {
11381 for (int i = 1; i < gnums.Length; i++)
11382 {
10756 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11383 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10757 //CaptureCollection cc = g.Captures; 11384 //CaptureCollection cc = g.Captures;
10758 } 11385 }
10759 if (m.Groups.Count == 5) { 11386 if (m.Groups.Count == 5)
11387 {
10760 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11388 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10761 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11389 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10762 } 11390 }
@@ -10959,6 +11587,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10959 11587
10960 LSL_List ret = new LSL_List(); 11588 LSL_List ret = new LSL_List();
10961 UUID key = new UUID(); 11589 UUID key = new UUID();
11590
11591
10962 if (UUID.TryParse(id, out key)) 11592 if (UUID.TryParse(id, out key))
10963 { 11593 {
10964 ScenePresence av = World.GetScenePresence(key); 11594 ScenePresence av = World.GetScenePresence(key);
@@ -10976,13 +11606,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10976 ret.Add(new LSL_String("")); 11606 ret.Add(new LSL_String(""));
10977 break; 11607 break;
10978 case ScriptBaseClass.OBJECT_POS: 11608 case ScriptBaseClass.OBJECT_POS:
10979 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11609 Vector3 avpos;
11610
11611 if (av.ParentID != 0 && av.ParentPart != null)
11612 {
11613 avpos = av.OffsetPosition;
11614
11615 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11616 avpos -= sitOffset;
11617
11618 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11619 }
11620 else
11621 avpos = av.AbsolutePosition;
11622
11623 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10980 break; 11624 break;
10981 case ScriptBaseClass.OBJECT_ROT: 11625 case ScriptBaseClass.OBJECT_ROT:
10982 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11626 Quaternion avrot = av.Rotation;
11627 if (av.ParentID != 0 && av.ParentPart != null)
11628 {
11629 avrot = av.ParentPart.GetWorldRotation() * avrot;
11630 }
11631 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10983 break; 11632 break;
10984 case ScriptBaseClass.OBJECT_VELOCITY: 11633 case ScriptBaseClass.OBJECT_VELOCITY:
10985 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11634 Vector3 avvel = av.Velocity;
11635 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10986 break; 11636 break;
10987 case ScriptBaseClass.OBJECT_OWNER: 11637 case ScriptBaseClass.OBJECT_OWNER:
10988 ret.Add(new LSL_String(id)); 11638 ret.Add(new LSL_String(id));
@@ -11067,11 +11717,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11067 case ScriptBaseClass.OBJECT_NAME: 11717 case ScriptBaseClass.OBJECT_NAME:
11068 ret.Add(new LSL_String(obj.Name)); 11718 ret.Add(new LSL_String(obj.Name));
11069 break; 11719 break;
11070 case ScriptBaseClass.OBJECT_DESC: 11720 case ScriptBaseClass.OBJECT_DESC:
11071 ret.Add(new LSL_String(obj.Description)); 11721 ret.Add(new LSL_String(obj.Description));
11072 break; 11722 break;
11073 case ScriptBaseClass.OBJECT_POS: 11723 case ScriptBaseClass.OBJECT_POS:
11074 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11724 Vector3 opos = obj.AbsolutePosition;
11725 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
11075 break; 11726 break;
11076 case ScriptBaseClass.OBJECT_ROT: 11727 case ScriptBaseClass.OBJECT_ROT:
11077 { 11728 {
@@ -11121,9 +11772,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11121 // The value returned in SL for normal prims is prim count 11772 // The value returned in SL for normal prims is prim count
11122 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11773 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11123 break; 11774 break;
11124 // The following 3 costs I have intentionaly coded to return zero. They are part of 11775
11125 // "Land Impact" calculations. These calculations are probably not applicable 11776 // costs below may need to be diferent for root parts, need to check
11126 // to OpenSim and are not yet complete in SL
11127 case ScriptBaseClass.OBJECT_SERVER_COST: 11777 case ScriptBaseClass.OBJECT_SERVER_COST:
11128 // The linden calculation is here 11778 // The linden calculation is here
11129 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11779 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -11131,16 +11781,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11131 ret.Add(new LSL_Float(0)); 11781 ret.Add(new LSL_Float(0));
11132 break; 11782 break;
11133 case ScriptBaseClass.OBJECT_STREAMING_COST: 11783 case ScriptBaseClass.OBJECT_STREAMING_COST:
11134 // The linden calculation is here 11784 // The value returned in SL for normal prims is prim count * 0.06
11135 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11785 ret.Add(new LSL_Float(obj.StreamingCost));
11136 // The value returned in SL for normal prims looks like the prim count * 0.06
11137 ret.Add(new LSL_Float(0));
11138 break; 11786 break;
11139 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11787 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11140 // The linden calculation is here 11788 // The value returned in SL for normal prims is prim count
11141 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11789 ret.Add(new LSL_Float(obj.PhysicsCost));
11142 // The value returned in SL for normal prims looks like the prim count
11143 ret.Add(new LSL_Float(0));
11144 break; 11790 break;
11145 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11791 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11146 ret.Add(new LSL_Float(0)); 11792 ret.Add(new LSL_Float(0));
@@ -11399,15 +12045,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11399 return result; 12045 return result;
11400 } 12046 }
11401 12047
11402 public void print(string str) 12048 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11403 { 12049 {
11404 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12050 List<SceneObjectPart> parts = GetLinkParts(link);
11405 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12051 if (parts.Count < 1)
11406 if (ossl != null) 12052 return 0;
11407 { 12053
11408 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12054 return GetNumberOfSides(parts[0]);
11409 m_log.Info("LSL print():" + str);
11410 }
11411 } 12055 }
11412 12056
11413 private string Name2Username(string name) 12057 private string Name2Username(string name)
@@ -11452,7 +12096,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11452 12096
11453 return rq.ToString(); 12097 return rq.ToString();
11454 } 12098 }
11455 12099/*
12100 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12101 {
12102 m_SayShoutCount = 0;
12103 }
12104*/
11456 private struct Tri 12105 private struct Tri
11457 { 12106 {
11458 public Vector3 p1; 12107 public Vector3 p1;
@@ -11601,9 +12250,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11601 12250
11602 ContactResult result = new ContactResult (); 12251 ContactResult result = new ContactResult ();
11603 result.ConsumerID = group.LocalId; 12252 result.ConsumerID = group.LocalId;
11604 result.Depth = intersection.distance; 12253// result.Depth = intersection.distance;
11605 result.Normal = intersection.normal; 12254 result.Normal = intersection.normal;
11606 result.Pos = intersection.ipoint; 12255 result.Pos = intersection.ipoint;
12256 result.Depth = Vector3.Mag(rayStart - result.Pos);
11607 12257
11608 contacts.Add(result); 12258 contacts.Add(result);
11609 }); 12259 });
@@ -11736,6 +12386,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11736 12386
11737 return contacts[0]; 12387 return contacts[0];
11738 } 12388 }
12389/*
12390 // not done:
12391 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12392 {
12393 ContactResult[] contacts = null;
12394 World.ForEachSOG(delegate(SceneObjectGroup group)
12395 {
12396 if (m_host.ParentGroup == group)
12397 return;
12398
12399 if (group.IsAttachment)
12400 return;
12401
12402 if(group.RootPart.PhysActor != null)
12403 return;
12404
12405 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12406 });
12407 return contacts;
12408 }
12409*/
11739 12410
11740 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12411 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11741 { 12412 {
@@ -11859,18 +12530,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11859 } 12530 }
11860 } 12531 }
11861 12532
12533 // Double check this
11862 if (checkTerrain) 12534 if (checkTerrain)
11863 { 12535 {
11864 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12536 bool skipGroundCheck = false;
11865 if (groundContact != null) 12537
11866 results.Add((ContactResult)groundContact); 12538 foreach (ContactResult c in results)
12539 {
12540 if (c.ConsumerID == 0) // Physics gave us a ground collision
12541 skipGroundCheck = true;
12542 }
12543
12544 if (!skipGroundCheck)
12545 {
12546 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12547 if (groundContact != null)
12548 results.Add((ContactResult)groundContact);
12549 }
11867 } 12550 }
11868 12551
11869 results.Sort(delegate(ContactResult a, ContactResult b) 12552 results.Sort(delegate(ContactResult a, ContactResult b)
11870 { 12553 {
11871 return a.Depth.CompareTo(b.Depth); 12554 return a.Depth.CompareTo(b.Depth);
11872 }); 12555 });
11873 12556
11874 int values = 0; 12557 int values = 0;
11875 SceneObjectGroup thisgrp = m_host.ParentGroup; 12558 SceneObjectGroup thisgrp = m_host.ParentGroup;
11876 12559
@@ -11963,7 +12646,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11963 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12646 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11964 if (!isAccount) return 0; 12647 if (!isAccount) return 0;
11965 if (estate.HasAccess(id)) return 1; 12648 if (estate.HasAccess(id)) return 1;
11966 if (estate.IsBanned(id)) 12649 if (estate.IsBanned(id, World.GetUserFlags(id)))
11967 estate.RemoveBan(id); 12650 estate.RemoveBan(id);
11968 estate.AddEstateUser(id); 12651 estate.AddEstateUser(id);
11969 break; 12652 break;
@@ -11982,14 +12665,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11982 break; 12665 break;
11983 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12666 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11984 if (!isAccount) return 0; 12667 if (!isAccount) return 0;
11985 if (estate.IsBanned(id)) return 1; 12668 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11986 EstateBan ban = new EstateBan(); 12669 EstateBan ban = new EstateBan();
11987 ban.EstateID = estate.EstateID; 12670 ban.EstateID = estate.EstateID;
11988 ban.BannedUserID = id; 12671 ban.BannedUserID = id;
11989 estate.AddBan(ban); 12672 estate.AddBan(ban);
11990 break; 12673 break;
11991 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12674 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11992 if (!isAccount || !estate.IsBanned(id)) return 0; 12675 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11993 estate.RemoveBan(id); 12676 estate.RemoveBan(id);
11994 break; 12677 break;
11995 default: return 0; 12678 default: return 0;
@@ -12054,13 +12737,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12054 public void llCollisionSprite(string impact_sprite) 12737 public void llCollisionSprite(string impact_sprite)
12055 { 12738 {
12056 m_host.AddScriptLPS(1); 12739 m_host.AddScriptLPS(1);
12057 NotImplemented("llCollisionSprite"); 12740 // Viewer 2.0 broke this and it's likely LL has no intention
12741 // of fixing it. Therefore, letting this be a NOP seems appropriate.
12058 } 12742 }
12059 12743
12060 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12744 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
12061 { 12745 {
12062 m_host.AddScriptLPS(1); 12746 m_host.AddScriptLPS(1);
12063 NotImplemented("llGodLikeRezObject"); 12747
12748 if (!World.Permissions.IsGod(m_host.OwnerID))
12749 NotImplemented("llGodLikeRezObject");
12750
12751 AssetBase rezAsset = World.AssetService.Get(inventory);
12752 if (rezAsset == null)
12753 {
12754 llSay(0, "Asset not found");
12755 return;
12756 }
12757
12758 SceneObjectGroup group = null;
12759
12760 try
12761 {
12762 string xmlData = Utils.BytesToString(rezAsset.Data);
12763 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12764 }
12765 catch
12766 {
12767 llSay(0, "Asset not found");
12768 return;
12769 }
12770
12771 if (group == null)
12772 {
12773 llSay(0, "Asset not found");
12774 return;
12775 }
12776
12777 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12778 group.RootPart.AttachOffset = group.AbsolutePosition;
12779
12780 group.ResetIDs();
12781
12782 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12783 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12784 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12785 group.ScheduleGroupForFullUpdate();
12786
12787 // objects rezzed with this method are die_at_edge by default.
12788 group.RootPart.SetDieAtEdge(true);
12789
12790 group.ResumeScripts();
12791
12792 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12793 "object_rez", new Object[] {
12794 new LSL_String(
12795 group.RootPart.UUID.ToString()) },
12796 new DetectParams[0]));
12064 } 12797 }
12065 12798
12066 public LSL_String llTransferLindenDollars(string destination, int amount) 12799 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -12111,8 +12844,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12111 return; 12844 return;
12112 } 12845 }
12113 12846
12847 string reason;
12114 bool result = money.ObjectGiveMoney( 12848 bool result = money.ObjectGiveMoney(
12115 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12849 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
12116 12850
12117 if (result) 12851 if (result)
12118 { 12852 {
@@ -12120,7 +12854,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12120 return; 12854 return;
12121 } 12855 }
12122 12856
12123 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 12857 replydata = reason;
12124 } 12858 }
12125 finally 12859 finally
12126 { 12860 {
@@ -12137,6 +12871,610 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12137 } 12871 }
12138 12872
12139 #endregion 12873 #endregion
12874
12875 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12876 {
12877 SceneObjectGroup group = m_host.ParentGroup;
12878
12879 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12880 return;
12881 if (group.IsAttachment)
12882 return;
12883
12884 if (frames.Data.Length > 0) // We are getting a new motion
12885 {
12886 if (group.RootPart.KeyframeMotion != null)
12887 group.RootPart.KeyframeMotion.Delete();
12888 group.RootPart.KeyframeMotion = null;
12889
12890 int idx = 0;
12891
12892 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12893 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12894
12895 while (idx < options.Data.Length)
12896 {
12897 int option = (int)options.GetLSLIntegerItem(idx++);
12898 int remain = options.Data.Length - idx;
12899
12900 switch (option)
12901 {
12902 case ScriptBaseClass.KFM_MODE:
12903 if (remain < 1)
12904 break;
12905 int modeval = (int)options.GetLSLIntegerItem(idx++);
12906 switch(modeval)
12907 {
12908 case ScriptBaseClass.KFM_FORWARD:
12909 mode = KeyframeMotion.PlayMode.Forward;
12910 break;
12911 case ScriptBaseClass.KFM_REVERSE:
12912 mode = KeyframeMotion.PlayMode.Reverse;
12913 break;
12914 case ScriptBaseClass.KFM_LOOP:
12915 mode = KeyframeMotion.PlayMode.Loop;
12916 break;
12917 case ScriptBaseClass.KFM_PING_PONG:
12918 mode = KeyframeMotion.PlayMode.PingPong;
12919 break;
12920 }
12921 break;
12922 case ScriptBaseClass.KFM_DATA:
12923 if (remain < 1)
12924 break;
12925 int dataval = (int)options.GetLSLIntegerItem(idx++);
12926 data = (KeyframeMotion.DataFormat)dataval;
12927 break;
12928 }
12929 }
12930
12931 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12932
12933 idx = 0;
12934
12935 int elemLength = 2;
12936 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12937 elemLength = 3;
12938
12939 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12940 while (idx < frames.Data.Length)
12941 {
12942 int remain = frames.Data.Length - idx;
12943
12944 if (remain < elemLength)
12945 break;
12946
12947 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12948 frame.Position = null;
12949 frame.Rotation = null;
12950
12951 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12952 {
12953 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12954 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12955 }
12956 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12957 {
12958 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12959 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12960 q.Normalize();
12961 frame.Rotation = q;
12962 }
12963
12964 float tempf = (float)frames.GetLSLFloatItem(idx++);
12965 frame.TimeMS = (int)(tempf * 1000.0f);
12966
12967 keyframes.Add(frame);
12968 }
12969
12970 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12971 group.RootPart.KeyframeMotion.Start();
12972 }
12973 else
12974 {
12975 if (group.RootPart.KeyframeMotion == null)
12976 return;
12977
12978 if (options.Data.Length == 0)
12979 {
12980 group.RootPart.KeyframeMotion.Stop();
12981 return;
12982 }
12983
12984 int code = (int)options.GetLSLIntegerItem(0);
12985
12986 int idx = 0;
12987
12988 while (idx < options.Data.Length)
12989 {
12990 int option = (int)options.GetLSLIntegerItem(idx++);
12991 int remain = options.Data.Length - idx;
12992
12993 switch (option)
12994 {
12995 case ScriptBaseClass.KFM_COMMAND:
12996 int cmd = (int)options.GetLSLIntegerItem(idx++);
12997 switch (cmd)
12998 {
12999 case ScriptBaseClass.KFM_CMD_PLAY:
13000 group.RootPart.KeyframeMotion.Start();
13001 break;
13002 case ScriptBaseClass.KFM_CMD_STOP:
13003 group.RootPart.KeyframeMotion.Stop();
13004 break;
13005 case ScriptBaseClass.KFM_CMD_PAUSE:
13006 group.RootPart.KeyframeMotion.Pause();
13007 break;
13008 }
13009 break;
13010 }
13011 }
13012 }
13013 }
13014
13015 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
13016 {
13017 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
13018
13019 int idx = 0;
13020 int idxStart = 0;
13021
13022 bool positionChanged = false;
13023 Vector3 finalPos = Vector3.Zero;
13024
13025 try
13026 {
13027 while (idx < rules.Length)
13028 {
13029 ++rulesParsed;
13030 int code = rules.GetLSLIntegerItem(idx++);
13031
13032 int remain = rules.Length - idx;
13033 idxStart = idx;
13034
13035 switch (code)
13036 {
13037 case (int)ScriptBaseClass.PRIM_POSITION:
13038 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13039 {
13040 if (remain < 1)
13041 return null;
13042
13043 LSL_Vector v;
13044 v = rules.GetVector3Item(idx++);
13045
13046 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13047 if (part == null)
13048 break;
13049
13050 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13051 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13052 if (part.LinkNum > 1)
13053 {
13054 localRot = GetPartLocalRot(part);
13055 localPos = GetPartLocalPos(part);
13056 }
13057
13058 v -= localPos;
13059 v /= localRot;
13060
13061 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
13062
13063 v = v + 2 * sitOffset;
13064
13065 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
13066 av.SendAvatarDataToAllAgents();
13067
13068 }
13069 break;
13070
13071 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13072 case (int)ScriptBaseClass.PRIM_ROTATION:
13073 {
13074 if (remain < 1)
13075 return null;
13076
13077 LSL_Rotation r;
13078 r = rules.GetQuaternionItem(idx++);
13079
13080 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13081 if (part == null)
13082 break;
13083
13084 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13085 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13086
13087 if (part.LinkNum > 1)
13088 localRot = GetPartLocalRot(part);
13089
13090 r = r * llGetRootRotation() / localRot;
13091 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
13092 av.SendAvatarDataToAllAgents();
13093 }
13094 break;
13095
13096 // parse rest doing nothing but number of parameters error check
13097 case (int)ScriptBaseClass.PRIM_SIZE:
13098 case (int)ScriptBaseClass.PRIM_MATERIAL:
13099 case (int)ScriptBaseClass.PRIM_PHANTOM:
13100 case (int)ScriptBaseClass.PRIM_PHYSICS:
13101 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
13102 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13103 case (int)ScriptBaseClass.PRIM_NAME:
13104 case (int)ScriptBaseClass.PRIM_DESC:
13105 if (remain < 1)
13106 return null;
13107 idx++;
13108 break;
13109
13110 case (int)ScriptBaseClass.PRIM_GLOW:
13111 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13112 case (int)ScriptBaseClass.PRIM_TEXGEN:
13113 if (remain < 2)
13114 return null;
13115 idx += 2;
13116 break;
13117
13118 case (int)ScriptBaseClass.PRIM_TYPE:
13119 if (remain < 3)
13120 return null;
13121 code = (int)rules.GetLSLIntegerItem(idx++);
13122 remain = rules.Length - idx;
13123 switch (code)
13124 {
13125 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13126 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13127 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13128 if (remain < 6)
13129 return null;
13130 idx += 6;
13131 break;
13132
13133 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13134 if (remain < 5)
13135 return null;
13136 idx += 5;
13137 break;
13138
13139 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13140 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13141 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13142 if (remain < 11)
13143 return null;
13144 idx += 11;
13145 break;
13146
13147 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13148 if (remain < 2)
13149 return null;
13150 idx += 2;
13151 break;
13152 }
13153 break;
13154
13155 case (int)ScriptBaseClass.PRIM_COLOR:
13156 case (int)ScriptBaseClass.PRIM_TEXT:
13157 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13158 case (int)ScriptBaseClass.PRIM_OMEGA:
13159 if (remain < 3)
13160 return null;
13161 idx += 3;
13162 break;
13163
13164 case (int)ScriptBaseClass.PRIM_TEXTURE:
13165 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13166 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13167 if (remain < 5)
13168 return null;
13169 idx += 5;
13170 break;
13171
13172 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13173 if (remain < 7)
13174 return null;
13175
13176 idx += 7;
13177 break;
13178
13179 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13180 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13181 return null;
13182
13183 return rules.GetSublist(idx, -1);
13184 }
13185 }
13186 }
13187 catch (InvalidCastException e)
13188 {
13189 ShoutError(string.Format(
13190 "{0} error running rule #{1}: arg #{2} ",
13191 originFunc, rulesParsed, idx - idxStart) + e.Message);
13192 }
13193 finally
13194 {
13195 if (positionChanged)
13196 {
13197 av.OffsetPosition = finalPos;
13198// av.SendAvatarDataToAllAgents();
13199 av.SendTerseUpdateToAllClients();
13200 positionChanged = false;
13201 }
13202 }
13203 return null;
13204 }
13205
13206 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13207 {
13208 // avatars case
13209 // replies as SL wiki
13210
13211// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13212 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13213
13214 int idx = 0;
13215 while (idx < rules.Length)
13216 {
13217 int code = (int)rules.GetLSLIntegerItem(idx++);
13218 int remain = rules.Length - idx;
13219
13220 switch (code)
13221 {
13222 case (int)ScriptBaseClass.PRIM_MATERIAL:
13223 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13224 break;
13225
13226 case (int)ScriptBaseClass.PRIM_PHYSICS:
13227 res.Add(new LSL_Integer(0));
13228 break;
13229
13230 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13231 res.Add(new LSL_Integer(0));
13232 break;
13233
13234 case (int)ScriptBaseClass.PRIM_PHANTOM:
13235 res.Add(new LSL_Integer(0));
13236 break;
13237
13238 case (int)ScriptBaseClass.PRIM_POSITION:
13239
13240 Vector3 pos = avatar.OffsetPosition;
13241
13242 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13243 pos -= sitOffset;
13244
13245 if( sitPart != null)
13246 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13247
13248 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13249 break;
13250
13251 case (int)ScriptBaseClass.PRIM_SIZE:
13252 // as in llGetAgentSize above
13253// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13254 Vector3 s = avatar.Appearance.AvatarSize;
13255 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13256
13257 break;
13258
13259 case (int)ScriptBaseClass.PRIM_ROTATION:
13260 Quaternion rot = avatar.Rotation;
13261 if (sitPart != null)
13262 {
13263 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13264 }
13265
13266 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13267 break;
13268
13269 case (int)ScriptBaseClass.PRIM_TYPE:
13270 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13271 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13272 res.Add(new LSL_Vector(0f,1.0f,0f));
13273 res.Add(new LSL_Float(0.0f));
13274 res.Add(new LSL_Vector(0, 0, 0));
13275 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13276 res.Add(new LSL_Vector(0, 0, 0));
13277 break;
13278
13279 case (int)ScriptBaseClass.PRIM_TEXTURE:
13280 if (remain < 1)
13281 return null;
13282
13283 int face = (int)rules.GetLSLIntegerItem(idx++);
13284 if (face == ScriptBaseClass.ALL_SIDES)
13285 {
13286 for (face = 0; face < 21; face++)
13287 {
13288 res.Add(new LSL_String(""));
13289 res.Add(new LSL_Vector(0,0,0));
13290 res.Add(new LSL_Vector(0,0,0));
13291 res.Add(new LSL_Float(0.0));
13292 }
13293 }
13294 else
13295 {
13296 if (face >= 0 && face < 21)
13297 {
13298 res.Add(new LSL_String(""));
13299 res.Add(new LSL_Vector(0,0,0));
13300 res.Add(new LSL_Vector(0,0,0));
13301 res.Add(new LSL_Float(0.0));
13302 }
13303 }
13304 break;
13305
13306 case (int)ScriptBaseClass.PRIM_COLOR:
13307 if (remain < 1)
13308 return null;
13309
13310 face = (int)rules.GetLSLIntegerItem(idx++);
13311
13312 if (face == ScriptBaseClass.ALL_SIDES)
13313 {
13314 for (face = 0; face < 21; face++)
13315 {
13316 res.Add(new LSL_Vector(0,0,0));
13317 res.Add(new LSL_Float(0));
13318 }
13319 }
13320 else
13321 {
13322 res.Add(new LSL_Vector(0,0,0));
13323 res.Add(new LSL_Float(0));
13324 }
13325 break;
13326
13327 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13328 if (remain < 1)
13329 return null;
13330 face = (int)rules.GetLSLIntegerItem(idx++);
13331
13332 if (face == ScriptBaseClass.ALL_SIDES)
13333 {
13334 for (face = 0; face < 21; face++)
13335 {
13336 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13337 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13338 }
13339 }
13340 else
13341 {
13342 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13343 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13344 }
13345 break;
13346
13347 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13348 if (remain < 1)
13349 return null;
13350 face = (int)rules.GetLSLIntegerItem(idx++);
13351
13352 if (face == ScriptBaseClass.ALL_SIDES)
13353 {
13354 for (face = 0; face < 21; face++)
13355 {
13356 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13357 }
13358 }
13359 else
13360 {
13361 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13362 }
13363 break;
13364
13365 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13366 res.Add(new LSL_Integer(0));
13367 res.Add(new LSL_Integer(0));// softness
13368 res.Add(new LSL_Float(0.0f)); // gravity
13369 res.Add(new LSL_Float(0.0f)); // friction
13370 res.Add(new LSL_Float(0.0f)); // wind
13371 res.Add(new LSL_Float(0.0f)); // tension
13372 res.Add(new LSL_Vector(0f,0f,0f));
13373 break;
13374
13375 case (int)ScriptBaseClass.PRIM_TEXGEN:
13376 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13377 if (remain < 1)
13378 return null;
13379 face = (int)rules.GetLSLIntegerItem(idx++);
13380
13381 if (face == ScriptBaseClass.ALL_SIDES)
13382 {
13383 for (face = 0; face < 21; face++)
13384 {
13385 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13386 }
13387 }
13388 else
13389 {
13390 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13391 }
13392 break;
13393
13394 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13395 res.Add(new LSL_Integer(0));
13396 res.Add(new LSL_Vector(0f,0f,0f));
13397 res.Add(new LSL_Float(0f)); // intensity
13398 res.Add(new LSL_Float(0f)); // radius
13399 res.Add(new LSL_Float(0f)); // falloff
13400 break;
13401
13402 case (int)ScriptBaseClass.PRIM_GLOW:
13403 if (remain < 1)
13404 return null;
13405 face = (int)rules.GetLSLIntegerItem(idx++);
13406
13407 if (face == ScriptBaseClass.ALL_SIDES)
13408 {
13409 for (face = 0; face < 21; face++)
13410 {
13411 res.Add(new LSL_Float(0f));
13412 }
13413 }
13414 else
13415 {
13416 res.Add(new LSL_Float(0f));
13417 }
13418 break;
13419
13420 case (int)ScriptBaseClass.PRIM_TEXT:
13421 res.Add(new LSL_String(""));
13422 res.Add(new LSL_Vector(0f,0f,0f));
13423 res.Add(new LSL_Float(1.0f));
13424 break;
13425
13426 case (int)ScriptBaseClass.PRIM_NAME:
13427 res.Add(new LSL_String(avatar.Name));
13428 break;
13429
13430 case (int)ScriptBaseClass.PRIM_DESC:
13431 res.Add(new LSL_String(""));
13432 break;
13433
13434 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13435 Quaternion lrot = avatar.Rotation;
13436
13437 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13438 {
13439 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13440 }
13441 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13442 break;
13443
13444 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13445 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13446 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13447 lpos -= lsitOffset;
13448
13449 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13450 {
13451 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13452 }
13453 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13454 break;
13455
13456 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13457 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13458 return null;
13459
13460 return rules.GetSublist(idx, -1);
13461 }
13462 }
13463
13464 return null;
13465 }
13466
13467 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
13468 {
13469 if (m_UrlModule != null)
13470 {
13471 string type = "text.plain";
13472 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
13473 type = "text/html";
13474
13475 m_UrlModule.HttpContentType(new UUID(id),type);
13476 }
13477 }
12140 } 13478 }
12141 13479
12142 public class NotecardCache 13480 public class NotecardCache