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.cs3518
1 files changed, 2424 insertions, 1094 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 5663048..74f4f4b 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70using System.Linq; 74using System.Linq;
71using PermissionMask = OpenSim.Framework.PermissionMask; 75using PermissionMask = OpenSim.Framework.PermissionMask;
72 76
@@ -115,11 +119,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
115 protected int m_notecardLineReadCharsMax = 255; 119 protected int m_notecardLineReadCharsMax = 255;
116 protected int m_scriptConsoleChannel = 0; 120 protected int m_scriptConsoleChannel = 0;
117 protected bool m_scriptConsoleChannelEnabled = false; 121 protected bool m_scriptConsoleChannelEnabled = false;
122 protected bool m_debuggerSafe = false;
118 protected IUrlModule m_UrlModule = null; 123 protected IUrlModule m_UrlModule = null;
119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 124 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 125 new Dictionary<UUID, UserInfoCacheEntry>();
126 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
121 protected ISoundModule m_SoundModule = null; 127 protected ISoundModule m_SoundModule = null;
122 128
129// protected Timer m_ShoutSayTimer;
130 protected int m_SayShoutCount = 0;
131 DateTime m_lastSayShoutCheck;
132
133 private Dictionary<string, string> MovementAnimationsForLSL =
134 new Dictionary<string, string> {
135 {"FLY", "Flying"},
136 {"FLYSLOW", "FlyingSlow"},
137 {"HOVER_UP", "Hovering Up"},
138 {"HOVER_DOWN", "Hovering Down"},
139 {"HOVER", "Hovering"},
140 {"LAND", "Landing"},
141 {"FALLDOWN", "Falling Down"},
142 {"PREJUMP", "PreJumping"},
143 {"JUMP", "Jumping"},
144 {"STANDUP", "Standing Up"},
145 {"SOFT_LAND", "Soft Landing"},
146 {"STAND", "Standing"},
147 {"CROUCHWALK", "CrouchWalking"},
148 {"RUN", "Running"},
149 {"WALK", "Walking"},
150 {"CROUCH", "Crouching"},
151 {"TURNLEFT", "Turning Left"},
152 {"TURNRIGHT", "Turning Right"}
153 };
123 //An array of HTTP/1.1 headers that are not allowed to be used 154 //An array of HTTP/1.1 headers that are not allowed to be used
124 //as custom headers by llHTTPRequest. 155 //as custom headers by llHTTPRequest.
125 private string[] HttpStandardHeaders = 156 private string[] HttpStandardHeaders =
@@ -140,9 +171,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 public void Initialize( 171 public void Initialize(
141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
142 { 173 {
174 m_lastSayShoutCheck = DateTime.UtcNow;
175
143 m_ScriptEngine = scriptEngine; 176 m_ScriptEngine = scriptEngine;
144 m_host = host; 177 m_host = host;
145 m_item = item; 178 m_item = item;
179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 m_coopSleepHandle = coopSleepHandle; 180 m_coopSleepHandle = coopSleepHandle;
147 181
148 LoadConfig(); 182 LoadConfig();
@@ -231,6 +265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
231 get { return m_ScriptEngine.World; } 265 get { return m_ScriptEngine.World; }
232 } 266 }
233 267
268 [DebuggerNonUserCode]
234 public void state(string newState) 269 public void state(string newState)
235 { 270 {
236 m_ScriptEngine.SetState(m_item.ItemID, newState); 271 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -240,6 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
240 /// Reset the named script. The script must be present 275 /// Reset the named script. The script must be present
241 /// in the same prim. 276 /// in the same prim.
242 /// </summary> 277 /// </summary>
278 [DebuggerNonUserCode]
243 public void llResetScript() 279 public void llResetScript()
244 { 280 {
245 m_host.AddScriptLPS(1); 281 m_host.AddScriptLPS(1);
@@ -302,6 +338,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
302 } 338 }
303 } 339 }
304 340
341 public List<ScenePresence> GetLinkAvatars(int linkType)
342 {
343 List<ScenePresence> ret = new List<ScenePresence>();
344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
345 return ret;
346
347 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
348
349 switch (linkType)
350 {
351 case ScriptBaseClass.LINK_SET:
352 return avs;
353
354 case ScriptBaseClass.LINK_ROOT:
355 return ret;
356
357 case ScriptBaseClass.LINK_ALL_OTHERS:
358 return avs;
359
360 case ScriptBaseClass.LINK_ALL_CHILDREN:
361 return avs;
362
363 case ScriptBaseClass.LINK_THIS:
364 return ret;
365
366 default:
367 if (linkType < 0)
368 return ret;
369
370 int partCount = m_host.ParentGroup.GetPartCount();
371
372 if (linkType <= partCount)
373 {
374 return ret;
375 }
376 else
377 {
378 linkType = linkType - partCount;
379 if (linkType > avs.Count)
380 {
381 return ret;
382 }
383 else
384 {
385 ret.Add(avs[linkType-1]);
386 return ret;
387 }
388 }
389 }
390 }
391
305 /// <summary> 392 /// <summary>
306 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
307 /// </summary> 394 /// </summary>
@@ -384,6 +471,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 471 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
385 { 472 {
386 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 473 List<SceneObjectPart> ret = new List<SceneObjectPart>();
474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
475 return ret;
387 ret.Add(part); 476 ret.Add(part);
388 477
389 switch (linkType) 478 switch (linkType)
@@ -537,31 +626,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
537 626
538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 627 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
539 628
540 /// <summary> 629 // Utility function for llRot2Euler
541 /// Convert an LSL rotation to a Euler vector. 630
542 /// </summary> 631 // normalize an angle between -PI and PI (-180 to +180 degrees)
543 /// <remarks> 632 protected double NormalizeAngle(double angle)
544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
546 /// </remarks>
547 /// <param name="r"></param>
548 /// <returns></returns>
549 public LSL_Vector llRot2Euler(LSL_Rotation r)
550 { 633 {
551 m_host.AddScriptLPS(1); 634 if (angle > -Math.PI && angle < Math.PI)
635 return angle;
552 636
553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 637 int numPis = (int)(Math.PI / angle);
554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 638 double remainder = angle - Math.PI * numPis;
555 if (m == 0.0) return new LSL_Vector(); 639 if (numPis % 2 == 1)
556 double x = Math.Atan2(-v.y, v.z); 640 return Math.PI - angle;
557 double sin = v.x / m; 641 return remainder;
558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 642 }
559 double y = Math.Asin(sin);
560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
561 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
562 double z = Math.Atan2(v.y, v.x);
563 643
564 return new LSL_Vector(x, y, z); 644 public LSL_Vector llRot2Euler(LSL_Rotation q1)
645 {
646 m_host.AddScriptLPS(1);
647 LSL_Vector eul = new LSL_Vector();
648
649 double sqw = q1.s*q1.s;
650 double sqx = q1.x*q1.x;
651 double sqy = q1.z*q1.z;
652 double sqz = q1.y*q1.y;
653 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
654 double test = q1.x*q1.z + q1.y*q1.s;
655 if (test > 0.4999*unit) { // singularity at north pole
656 eul.z = 2 * Math.Atan2(q1.x,q1.s);
657 eul.y = Math.PI/2;
658 eul.x = 0;
659 return eul;
660 }
661 if (test < -0.4999*unit) { // singularity at south pole
662 eul.z = -2 * Math.Atan2(q1.x,q1.s);
663 eul.y = -Math.PI/2;
664 eul.x = 0;
665 return eul;
666 }
667 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
668 eul.y = Math.Asin(2*test/unit);
669 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
670 return eul;
565 } 671 }
566 672
567 /* From wiki: 673 /* From wiki:
@@ -614,18 +720,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
614 m_host.AddScriptLPS(1); 720 m_host.AddScriptLPS(1);
615 721
616 double x,y,z,s; 722 double x,y,z,s;
617 723 v.x *= 0.5;
618 double c1 = Math.Cos(v.x * 0.5); 724 v.y *= 0.5;
619 double c2 = Math.Cos(v.y * 0.5); 725 v.z *= 0.5;
620 double c3 = Math.Cos(v.z * 0.5); 726 double c1 = Math.Cos(v.x);
621 double s1 = Math.Sin(v.x * 0.5); 727 double c2 = Math.Cos(v.y);
622 double s2 = Math.Sin(v.y * 0.5); 728 double c1c2 = c1 * c2;
623 double s3 = Math.Sin(v.z * 0.5); 729 double s1 = Math.Sin(v.x);
624 730 double s2 = Math.Sin(v.y);
625 x = s1 * c2 * c3 + c1 * s2 * s3; 731 double s1s2 = s1 * s2;
626 y = c1 * s2 * c3 - s1 * c2 * s3; 732 double c1s2 = c1 * s2;
627 z = s1 * s2 * c3 + c1 * c2 * s3; 733 double s1c2 = s1 * c2;
628 s = c1 * c2 * c3 - s1 * s2 * s3; 734 double c3 = Math.Cos(v.z);
735 double s3 = Math.Sin(v.z);
736
737 x = s1c2 * c3 + c1s2 * s3;
738 y = c1s2 * c3 - s1c2 * s3;
739 z = s1s2 * c3 + c1c2 * s3;
740 s = c1c2 * c3 - s1s2 * s3;
629 741
630 return new LSL_Rotation(x, y, z, s); 742 return new LSL_Rotation(x, y, z, s);
631 } 743 }
@@ -763,77 +875,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
763 { 875 {
764 //A and B should both be normalized 876 //A and B should both be normalized
765 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
766 LSL_Rotation rotBetween; 878 /* This method is more accurate than the SL one, and thus causes problems
767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 879 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
768 // continue calculation. 880
769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 881 double dotProduct = LSL_Vector.Dot(a, b);
770 { 882 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 883 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
772 } 884 double angle = Math.Acos(dotProduct / magProduct);
773 else 885 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
774 { 886 double s = Math.Sin(angle / 2);
775 a = LSL_Vector.Norm(a); 887
776 b = LSL_Vector.Norm(b); 888 double x = axis.x * s;
777 double dotProduct = LSL_Vector.Dot(a, b); 889 double y = axis.y * s;
778 // There are two degenerate cases possible. These are for vectors 180 or 890 double z = axis.z * s;
779 // 0 degrees apart. These have to be detected and handled individually. 891 double w = Math.Cos(angle / 2);
780 // 892
781 // Check for vectors 180 degrees apart. 893 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
782 // A dot product of -1 would mean the angle between vectors is 180 degrees. 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
783 if (dotProduct < -0.9999999f) 895
784 { 896 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
785 // First assume X axis is orthogonal to the vectors. 897 */
786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 898
787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 899 // This method mimics the 180 errors found in SL
788 // Check for near zero vector. A very small non-zero number here will create 900 // See www.euclideanspace.com... angleBetween
789 // a rotation in an undesired direction. 901 LSL_Vector vec_a = a;
790 if (LSL_Vector.Mag(orthoVector) > 0.0001) 902 LSL_Vector vec_b = b;
791 { 903
792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 904 // Eliminate zero length
793 } 905 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
794 // If the magnitude of the vector was near zero, then assume the X axis is not 906 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
795 // orthogonal and use the Z axis instead. 907 if (vec_a_mag < 0.00001 ||
796 else 908 vec_b_mag < 0.00001)
797 { 909 {
798 // Set 180 z rotation. 910 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 911 }
800 } 912
801 } 913 // Normalize
802 // Check for parallel vectors. 914 vec_a = llVecNorm(vec_a);
803 // A dot product of 1 would mean the angle between vectors is 0 degrees. 915 vec_b = llVecNorm(vec_b);
804 else if (dotProduct > 0.9999999f) 916
805 { 917 // Calculate axis and rotation angle
806 // Set zero rotation. 918 LSL_Vector axis = vec_a % vec_b;
807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 919 LSL_Float cos_theta = vec_a * vec_b;
808 } 920
809 else 921 // Check if parallel
810 { 922 if (cos_theta > 0.99999)
811 // All special checks have been performed so get the axis of rotation. 923 {
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 924 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813 // Quarternion s value is the length of the unit vector + dot product. 925 }
814 double qs = 1.0 + dotProduct; 926
815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 927 // Check if anti-parallel
816 // Normalize the rotation. 928 else if (cos_theta < -0.99999)
817 double mag = LSL_Rotation.Mag(rotBetween); 929 {
818 // We shouldn't have to worry about a divide by zero here. The qs value will be 930 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
819 // non-zero because we already know if we're here, then the dotProduct is not -1 so 931 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
820 // qs will not be zero. Also, we've already handled the input vectors being zero so the 932 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
821 // crossProduct vector should also not be zero. 933 }
822 rotBetween.x = rotBetween.x / mag; 934 else // other rotation
823 rotBetween.y = rotBetween.y / mag; 935 {
824 rotBetween.z = rotBetween.z / mag; 936 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
825 rotBetween.s = rotBetween.s / mag; 937 axis = llVecNorm(axis);
826 // Check for undefined values and set zero rotation if any found. This code might not actually be required 938 double x, y, z, s, t;
827 // any longer since zero vectors are checked for at the top. 939 s = Math.Cos(theta);
828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 940 t = Math.Sin(theta);
829 { 941 x = axis.x * t;
830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 942 y = axis.y * t;
831 } 943 z = axis.z * t;
832 } 944 return new LSL_Rotation(x,y,z,s);
833 } 945 }
834 return rotBetween; 946 }
835 } 947
836
837 public void llWhisper(int channelID, string text) 948 public void llWhisper(int channelID, string text)
838 { 949 {
839 m_host.AddScriptLPS(1); 950 m_host.AddScriptLPS(1);
@@ -849,10 +960,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 960 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
850 } 961 }
851 962
963 private void CheckSayShoutTime()
964 {
965 DateTime now = DateTime.UtcNow;
966 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
967 {
968 m_lastSayShoutCheck = now;
969 m_SayShoutCount = 0;
970 }
971 else
972 m_SayShoutCount++;
973 }
974
852 public void llSay(int channelID, string text) 975 public void llSay(int channelID, string text)
853 { 976 {
854 m_host.AddScriptLPS(1); 977 m_host.AddScriptLPS(1);
855 978
979 if (channelID == 0)
980// m_SayShoutCount++;
981 CheckSayShoutTime();
982
983 if (m_SayShoutCount >= 11)
984 ScriptSleep(2000);
985
856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 986 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
857 { 987 {
858 Console.WriteLine(text); 988 Console.WriteLine(text);
@@ -875,6 +1005,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 { 1005 {
876 m_host.AddScriptLPS(1); 1006 m_host.AddScriptLPS(1);
877 1007
1008 if (channelID == 0)
1009// m_SayShoutCount++;
1010 CheckSayShoutTime();
1011
1012 if (m_SayShoutCount >= 11)
1013 ScriptSleep(2000);
1014
878 if (text.Length > 1023) 1015 if (text.Length > 1023)
879 text = text.Substring(0, 1023); 1016 text = text.Substring(0, 1023);
880 1017
@@ -906,22 +1043,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
906 1043
907 public void llRegionSayTo(string target, int channel, string msg) 1044 public void llRegionSayTo(string target, int channel, string msg)
908 { 1045 {
1046 string error = String.Empty;
1047
909 if (msg.Length > 1023) 1048 if (msg.Length > 1023)
910 msg = msg.Substring(0, 1023); 1049 msg = msg.Substring(0, 1023);
911 1050
912 m_host.AddScriptLPS(1); 1051 m_host.AddScriptLPS(1);
913 1052
914 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
915 {
916 return;
917 }
918
919 UUID TargetID; 1053 UUID TargetID;
920 UUID.TryParse(target, out TargetID); 1054 UUID.TryParse(target, out TargetID);
921 1055
922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1056 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
923 if (wComm != null) 1057 if (wComm != null)
924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1058 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1059 LSLError(error);
925 } 1060 }
926 1061
927 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1062 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1177,10 +1312,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 return detectedParams.TouchUV; 1312 return detectedParams.TouchUV;
1178 } 1313 }
1179 1314
1315 [DebuggerNonUserCode]
1180 public virtual void llDie() 1316 public virtual void llDie()
1181 { 1317 {
1182 m_host.AddScriptLPS(1); 1318 m_host.AddScriptLPS(1);
1183 throw new SelfDeleteException(); 1319 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1184 } 1320 }
1185 1321
1186 public LSL_Float llGround(LSL_Vector offset) 1322 public LSL_Float llGround(LSL_Vector offset)
@@ -1251,6 +1387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1251 1387
1252 public void llSetStatus(int status, int value) 1388 public void llSetStatus(int status, int value)
1253 { 1389 {
1390 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1391 return;
1254 m_host.AddScriptLPS(1); 1392 m_host.AddScriptLPS(1);
1255 1393
1256 int statusrotationaxis = 0; 1394 int statusrotationaxis = 0;
@@ -1274,6 +1412,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1274 if (!allow) 1412 if (!allow)
1275 return; 1413 return;
1276 1414
1415 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1416 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1417 return;
1418
1277 m_host.ScriptSetPhysicsStatus(true); 1419 m_host.ScriptSetPhysicsStatus(true);
1278 } 1420 }
1279 else 1421 else
@@ -1474,12 +1616,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1474 { 1616 {
1475 m_host.AddScriptLPS(1); 1617 m_host.AddScriptLPS(1);
1476 1618
1619 SetColor(m_host, color, face);
1620 }
1621
1622 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1623 {
1624 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1625 return;
1626
1627 Primitive.TextureEntry tex = part.Shape.Textures;
1628 Color4 texcolor;
1629 if (face >= 0 && face < GetNumberOfSides(part))
1630 {
1631 texcolor = tex.CreateFace((uint)face).RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.FaceTextures[face].RGBA = texcolor;
1636 part.UpdateTextureEntry(tex.GetBytes());
1637 return;
1638 }
1639 else if (face == ScriptBaseClass.ALL_SIDES)
1640 {
1641 for (uint i = 0; i < GetNumberOfSides(part); i++)
1642 {
1643 if (tex.FaceTextures[i] != null)
1644 {
1645 texcolor = tex.FaceTextures[i].RGBA;
1646 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1647 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1648 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1649 tex.FaceTextures[i].RGBA = texcolor;
1650 }
1651 texcolor = tex.DefaultTexture.RGBA;
1652 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1653 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1654 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1655 tex.DefaultTexture.RGBA = texcolor;
1656 }
1657 part.UpdateTextureEntry(tex.GetBytes());
1658 return;
1659 }
1660
1477 if (face == ScriptBaseClass.ALL_SIDES) 1661 if (face == ScriptBaseClass.ALL_SIDES)
1478 face = SceneObjectPart.ALL_SIDES; 1662 face = SceneObjectPart.ALL_SIDES;
1479 1663
1480 m_host.SetFaceColorAlpha(face, color, null); 1664 m_host.SetFaceColorAlpha(face, color, null);
1481 } 1665 }
1482 1666
1667 /*
1483 public void llSetContentType(LSL_Key id, LSL_Integer type) 1668 public void llSetContentType(LSL_Key id, LSL_Integer type)
1484 { 1669 {
1485 m_host.AddScriptLPS(1); 1670 m_host.AddScriptLPS(1);
@@ -1546,9 +1731,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1546 break; 1731 break;
1547 } 1732 }
1548 } 1733 }
1734 */
1549 1735
1550 public void SetTexGen(SceneObjectPart part, int face,int style) 1736 public void SetTexGen(SceneObjectPart part, int face,int style)
1551 { 1737 {
1738 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1739 return;
1740
1552 Primitive.TextureEntry tex = part.Shape.Textures; 1741 Primitive.TextureEntry tex = part.Shape.Textures;
1553 MappingType textype; 1742 MappingType textype;
1554 textype = MappingType.Default; 1743 textype = MappingType.Default;
@@ -1579,6 +1768,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1579 1768
1580 public void SetGlow(SceneObjectPart part, int face, float glow) 1769 public void SetGlow(SceneObjectPart part, int face, float glow)
1581 { 1770 {
1771 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1772 return;
1773
1582 Primitive.TextureEntry tex = part.Shape.Textures; 1774 Primitive.TextureEntry tex = part.Shape.Textures;
1583 if (face >= 0 && face < GetNumberOfSides(part)) 1775 if (face >= 0 && face < GetNumberOfSides(part))
1584 { 1776 {
@@ -1604,6 +1796,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1604 1796
1605 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1797 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1606 { 1798 {
1799 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1800 return;
1607 1801
1608 Shininess sval = new Shininess(); 1802 Shininess sval = new Shininess();
1609 1803
@@ -1654,6 +1848,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1654 1848
1655 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1849 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1656 { 1850 {
1851 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1852 return;
1853
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1854 Primitive.TextureEntry tex = part.Shape.Textures;
1658 if (face >= 0 && face < GetNumberOfSides(part)) 1855 if (face >= 0 && face < GetNumberOfSides(part))
1659 { 1856 {
@@ -1714,13 +1911,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 m_host.AddScriptLPS(1); 1911 m_host.AddScriptLPS(1);
1715 1912
1716 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1913 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1717 1914 if (parts.Count > 0)
1718 foreach (SceneObjectPart part in parts) 1915 {
1719 SetAlpha(part, alpha, face); 1916 try
1917 {
1918 foreach (SceneObjectPart part in parts)
1919 SetAlpha(part, alpha, face);
1920 }
1921 finally
1922 {
1923 }
1924 }
1720 } 1925 }
1721 1926
1722 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1927 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1723 { 1928 {
1929 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1930 return;
1931
1724 Primitive.TextureEntry tex = part.Shape.Textures; 1932 Primitive.TextureEntry tex = part.Shape.Textures;
1725 Color4 texcolor; 1933 Color4 texcolor;
1726 if (face >= 0 && face < GetNumberOfSides(part)) 1934 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1773,7 +1981,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1773 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1981 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1774 float wind, float tension, LSL_Vector Force) 1982 float wind, float tension, LSL_Vector Force)
1775 { 1983 {
1776 if (part == null) 1984 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1777 return; 1985 return;
1778 1986
1779 if (flexi) 1987 if (flexi)
@@ -1814,7 +2022,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1814 /// <param name="falloff"></param> 2022 /// <param name="falloff"></param>
1815 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 2023 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1816 { 2024 {
1817 if (part == null) 2025 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1818 return; 2026 return;
1819 2027
1820 if (light) 2028 if (light)
@@ -1847,11 +2055,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1847 Primitive.TextureEntry tex = part.Shape.Textures; 2055 Primitive.TextureEntry tex = part.Shape.Textures;
1848 Color4 texcolor; 2056 Color4 texcolor;
1849 LSL_Vector rgb = new LSL_Vector(); 2057 LSL_Vector rgb = new LSL_Vector();
2058 int nsides = GetNumberOfSides(part);
2059
1850 if (face == ScriptBaseClass.ALL_SIDES) 2060 if (face == ScriptBaseClass.ALL_SIDES)
1851 { 2061 {
1852 int i; 2062 int i;
1853 2063 for (i = 0; i < nsides; i++)
1854 for (i = 0 ; i < GetNumberOfSides(part); i++)
1855 { 2064 {
1856 texcolor = tex.GetFace((uint)i).RGBA; 2065 texcolor = tex.GetFace((uint)i).RGBA;
1857 rgb.x += texcolor.R; 2066 rgb.x += texcolor.R;
@@ -1859,14 +2068,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1859 rgb.z += texcolor.B; 2068 rgb.z += texcolor.B;
1860 } 2069 }
1861 2070
1862 rgb.x /= (float)GetNumberOfSides(part); 2071 float invnsides = 1.0f / (float)nsides;
1863 rgb.y /= (float)GetNumberOfSides(part); 2072
1864 rgb.z /= (float)GetNumberOfSides(part); 2073 rgb.x *= invnsides;
2074 rgb.y *= invnsides;
2075 rgb.z *= invnsides;
1865 2076
1866 return rgb; 2077 return rgb;
1867 } 2078 }
1868 2079 if (face >= 0 && face < nsides)
1869 if (face >= 0 && face < GetNumberOfSides(part))
1870 { 2080 {
1871 texcolor = tex.GetFace((uint)face).RGBA; 2081 texcolor = tex.GetFace((uint)face).RGBA;
1872 rgb.x = texcolor.R; 2082 rgb.x = texcolor.R;
@@ -1893,15 +2103,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1893 m_host.AddScriptLPS(1); 2103 m_host.AddScriptLPS(1);
1894 2104
1895 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2105 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1896 2106 if (parts.Count > 0)
1897 foreach (SceneObjectPart part in parts) 2107 {
1898 SetTexture(part, texture, face); 2108 try
1899 2109 {
2110 foreach (SceneObjectPart part in parts)
2111 SetTexture(part, texture, face);
2112 }
2113 finally
2114 {
2115 }
2116 }
1900 ScriptSleep(200); 2117 ScriptSleep(200);
1901 } 2118 }
1902 2119
1903 protected void SetTexture(SceneObjectPart part, string texture, int face) 2120 protected void SetTexture(SceneObjectPart part, string texture, int face)
1904 { 2121 {
2122 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2123 return;
2124
1905 UUID textureID = new UUID(); 2125 UUID textureID = new UUID();
1906 2126
1907 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2127 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1946,6 +2166,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1946 2166
1947 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2167 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1948 { 2168 {
2169 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2170 return;
2171
1949 Primitive.TextureEntry tex = part.Shape.Textures; 2172 Primitive.TextureEntry tex = part.Shape.Textures;
1950 if (face >= 0 && face < GetNumberOfSides(part)) 2173 if (face >= 0 && face < GetNumberOfSides(part))
1951 { 2174 {
@@ -1982,6 +2205,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1982 2205
1983 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2206 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1984 { 2207 {
2208 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2209 return;
2210
1985 Primitive.TextureEntry tex = part.Shape.Textures; 2211 Primitive.TextureEntry tex = part.Shape.Textures;
1986 if (face >= 0 && face < GetNumberOfSides(part)) 2212 if (face >= 0 && face < GetNumberOfSides(part))
1987 { 2213 {
@@ -2018,6 +2244,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2018 2244
2019 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2245 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
2020 { 2246 {
2247 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2248 return;
2249
2021 Primitive.TextureEntry tex = part.Shape.Textures; 2250 Primitive.TextureEntry tex = part.Shape.Textures;
2022 if (face >= 0 && face < GetNumberOfSides(part)) 2251 if (face >= 0 && face < GetNumberOfSides(part))
2023 { 2252 {
@@ -2159,7 +2388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2159 return end; 2388 return end;
2160 } 2389 }
2161 2390
2162 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2391 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2163 { 2392 {
2164 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2393 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2165 return fromPos; 2394 return fromPos;
@@ -2175,9 +2404,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2175 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2404 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2176 targetPos.z = ground; 2405 targetPos.z = ground;
2177 } 2406 }
2178 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2407 if (adjust)
2408 return SetPosAdjust(fromPos, targetPos);
2179 2409
2180 return real_vec; 2410 return targetPos;
2181 } 2411 }
2182 2412
2183 /// <summary> 2413 /// <summary>
@@ -2188,27 +2418,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2418 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2189 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2419 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2190 { 2420 {
2191 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2421 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2422 return;
2423
2192 LSL_Vector currentPos = GetPartLocalPos(part); 2424 LSL_Vector currentPos = GetPartLocalPos(part);
2425 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2193 2426
2194 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2195 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2196 2427
2197 if (part.ParentGroup.RootPart == part) 2428 if (part.ParentGroup.RootPart == part)
2198 { 2429 {
2199 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2200 targetPos.z = ground;
2201 SceneObjectGroup parent = part.ParentGroup; 2430 SceneObjectGroup parent = part.ParentGroup;
2202 parent.UpdateGroupPosition(!adjust ? targetPos : 2431 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2203 SetPosAdjust(currentPos, targetPos)); 2432 return;
2433 Util.FireAndForget(delegate(object x) {
2434 parent.UpdateGroupPosition((Vector3)toPos);
2435 });
2204 } 2436 }
2205 else 2437 else
2206 { 2438 {
2207 part.OffsetPosition = !adjust ? targetPos : 2439 part.OffsetPosition = (Vector3)toPos;
2208 SetPosAdjust(currentPos, targetPos); 2440// SceneObjectGroup parent = part.ParentGroup;
2209 SceneObjectGroup parent = part.ParentGroup; 2441// parent.HasGroupChanged = true;
2210 parent.HasGroupChanged = true; 2442// parent.ScheduleGroupForTerseUpdate();
2211 parent.ScheduleGroupForTerseUpdate(); 2443 part.ScheduleTerseUpdate();
2212 } 2444 }
2213 } 2445 }
2214 2446
@@ -2237,13 +2469,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2237 else 2469 else
2238 { 2470 {
2239 if (part.ParentGroup.IsAttachment) 2471 if (part.ParentGroup.IsAttachment)
2240 {
2241 pos = part.AttachedPos; 2472 pos = part.AttachedPos;
2242 }
2243 else 2473 else
2244 {
2245 pos = part.AbsolutePosition; 2474 pos = part.AbsolutePosition;
2246 }
2247 } 2475 }
2248 2476
2249// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2477// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2255,8 +2483,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2255 { 2483 {
2256 m_host.AddScriptLPS(1); 2484 m_host.AddScriptLPS(1);
2257 2485
2486
2487 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2488 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2489 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2490 // RootPart != null should shortcircuit
2491
2258 // try to let this work as in SL... 2492 // try to let this work as in SL...
2259 if (m_host.ParentID == 0) 2493 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2260 { 2494 {
2261 // special case: If we are root, rotate complete SOG to new rotation 2495 // special case: If we are root, rotate complete SOG to new rotation
2262 SetRot(m_host, rot); 2496 SetRot(m_host, rot);
@@ -2283,25 +2517,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2283 2517
2284 protected void SetRot(SceneObjectPart part, Quaternion rot) 2518 protected void SetRot(SceneObjectPart part, Quaternion rot)
2285 { 2519 {
2286 part.UpdateRotation(rot); 2520 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2287 // Update rotation does not move the object in the physics scene if it's a linkset. 2521 return;
2288 2522
2289//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2523 bool isroot = (part == part.ParentGroup.RootPart);
2290// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2524 bool isphys;
2291 2525
2292 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2293 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2294 // It's perfectly okay when the object is not an active physical body though.
2295 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2296 // but only if the object is not physial and active. This is important for rotating doors.
2297 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2298 // scene
2299 PhysicsActor pa = part.PhysActor; 2526 PhysicsActor pa = part.PhysActor;
2300 2527
2301 if (pa != null && !pa.IsPhysical) 2528 // keep using physactor ideia of isphysical
2529 // it should be SOP ideia of that
2530 // not much of a issue with ubitODE
2531 if (pa != null && pa.IsPhysical)
2532 isphys = true;
2533 else
2534 isphys = false;
2535
2536 // SL doesn't let scripts rotate root of physical linksets
2537 if (isroot && isphys)
2538 return;
2539
2540 part.UpdateRotation(rot);
2541
2542 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2543 // so do a nasty update of parts positions if is a root part rotation
2544 if (isroot && pa != null) // with if above implies non physical root part
2302 { 2545 {
2303 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2546 part.ParentGroup.ResetChildPrimPhysicsPositions();
2304 } 2547 }
2548 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2549 {
2550 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2551 if (sittingavas.Count > 0)
2552 {
2553 foreach (ScenePresence av in sittingavas)
2554 {
2555 if (isroot || part.LocalId == av.ParentID)
2556 av.SendTerseUpdateToAllClients();
2557 }
2558 }
2559 }
2305 } 2560 }
2306 2561
2307 /// <summary> 2562 /// <summary>
@@ -2318,6 +2573,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2318 2573
2319 m_host.AddScriptLPS(1); 2574 m_host.AddScriptLPS(1);
2320 Quaternion q = m_host.GetWorldRotation(); 2575 Quaternion q = m_host.GetWorldRotation();
2576
2577 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2578 {
2579 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2580 if (avatar != null)
2581 {
2582 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2583 q = avatar.CameraRotation * q; // Mouselook
2584 else
2585 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2586 }
2587 }
2588
2321 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2589 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2322 } 2590 }
2323 2591
@@ -2345,14 +2613,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2345 return new LSL_Rotation(q); 2613 return new LSL_Rotation(q);
2346 } 2614 }
2347 2615
2348 return new LSL_Rotation(part.GetWorldRotation()); 2616 q = part.GetWorldRotation();
2617 if (part.ParentGroup.AttachmentPoint != 0)
2618 {
2619 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2620 if (avatar != null)
2621 {
2622 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2623 q = avatar.CameraRotation * q; // Mouselook
2624 else
2625 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2626 }
2627 }
2628
2629 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2349 } 2630 }
2350 2631
2351 public LSL_Rotation llGetLocalRot() 2632 public LSL_Rotation llGetLocalRot()
2352 { 2633 {
2353 m_host.AddScriptLPS(1); 2634 return GetPartLocalRot(m_host);
2635 }
2354 2636
2355 return new LSL_Rotation(m_host.RotationOffset); 2637 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2638 {
2639 m_host.AddScriptLPS(1);
2640 Quaternion rot = part.RotationOffset;
2641 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2356 } 2642 }
2357 2643
2358 public void llSetForce(LSL_Vector force, int local) 2644 public void llSetForce(LSL_Vector force, int local)
@@ -2382,32 +2668,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2382 return force; 2668 return force;
2383 } 2669 }
2384 2670
2385 public void llSetVelocity(LSL_Vector velocity, int local)
2386 {
2387 m_host.AddScriptLPS(1);
2388
2389 if (!m_host.ParentGroup.IsDeleted)
2390 {
2391 if (local != 0)
2392 velocity *= llGetRot();
2393
2394 m_host.ParentGroup.RootPart.Velocity = velocity;
2395 }
2396 }
2397
2398 public void llSetAngularVelocity(LSL_Vector angularVelocity, int local)
2399 {
2400 m_host.AddScriptLPS(1);
2401
2402 if (!m_host.ParentGroup.IsDeleted)
2403 {
2404 if (local != 0)
2405 angularVelocity *= llGetRot();
2406
2407 m_host.ParentGroup.RootPart.AngularVelocity = angularVelocity;
2408 }
2409 }
2410
2411 public LSL_Integer llTarget(LSL_Vector position, double range) 2671 public LSL_Integer llTarget(LSL_Vector position, double range)
2412 { 2672 {
2413 m_host.AddScriptLPS(1); 2673 m_host.AddScriptLPS(1);
@@ -2458,16 +2718,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2458 m_host.ApplyImpulse(v, local != 0); 2718 m_host.ApplyImpulse(v, local != 0);
2459 } 2719 }
2460 2720
2721
2461 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2722 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2462 { 2723 {
2463 m_host.AddScriptLPS(1); 2724 m_host.AddScriptLPS(1);
2464 m_host.ApplyAngularImpulse(force, local != 0); 2725 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2465 } 2726 }
2466 2727
2467 public void llSetTorque(LSL_Vector torque, int local) 2728 public void llSetTorque(LSL_Vector torque, int local)
2468 { 2729 {
2469 m_host.AddScriptLPS(1); 2730 m_host.AddScriptLPS(1);
2470 m_host.SetAngularImpulse(torque, local != 0); 2731 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2471 } 2732 }
2472 2733
2473 public LSL_Vector llGetTorque() 2734 public LSL_Vector llGetTorque()
@@ -2484,20 +2745,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2484 llSetTorque(torque, local); 2745 llSetTorque(torque, local);
2485 } 2746 }
2486 2747
2748 public void llSetVelocity(LSL_Vector vel, int local)
2749 {
2750 m_host.AddScriptLPS(1);
2751 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2752 }
2753
2487 public LSL_Vector llGetVel() 2754 public LSL_Vector llGetVel()
2488 { 2755 {
2489 m_host.AddScriptLPS(1); 2756 m_host.AddScriptLPS(1);
2490 2757
2491 Vector3 vel; 2758 Vector3 vel = Vector3.Zero;
2492 2759
2493 if (m_host.ParentGroup.IsAttachment) 2760 if (m_host.ParentGroup.IsAttachment)
2494 { 2761 {
2495 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2762 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2496 vel = avatar.Velocity; 2763 if (avatar != null)
2764 vel = avatar.Velocity;
2497 } 2765 }
2498 else 2766 else
2499 { 2767 {
2500 vel = m_host.Velocity; 2768 vel = m_host.ParentGroup.RootPart.Velocity;
2501 } 2769 }
2502 2770
2503 return new LSL_Vector(vel); 2771 return new LSL_Vector(vel);
@@ -2510,11 +2778,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2510 return new LSL_Vector(m_host.Acceleration); 2778 return new LSL_Vector(m_host.Acceleration);
2511 } 2779 }
2512 2780
2513 public LSL_Vector llGetOmega() 2781 public void llSetAngularVelocity(LSL_Vector avel, int local)
2514 { 2782 {
2515 m_host.AddScriptLPS(1); 2783 m_host.AddScriptLPS(1);
2784 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2785 }
2516 2786
2517 return new LSL_Vector(m_host.AngularVelocity); 2787 public LSL_Vector llGetOmega()
2788 {
2789 m_host.AddScriptLPS(1);
2790 Vector3 avel = m_host.AngularVelocity;
2791 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2518 } 2792 }
2519 2793
2520 public LSL_Float llGetTimeOfDay() 2794 public LSL_Float llGetTimeOfDay()
@@ -2875,7 +3149,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2875 return src.ToLower(); 3149 return src.ToLower();
2876 } 3150 }
2877 3151
2878 public void llGiveMoney(string destination, int amount) 3152 public LSL_Integer llGiveMoney(string destination, int amount)
2879 { 3153 {
2880 Util.FireAndForget(x => 3154 Util.FireAndForget(x =>
2881 { 3155 {
@@ -2906,9 +3180,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2906 return; 3180 return;
2907 } 3181 }
2908 3182
3183 string reason;
2909 money.ObjectGiveMoney( 3184 money.ObjectGiveMoney(
2910 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3185 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero, out reason);
2911 }); 3186 });
3187
3188 return 0;
2912 } 3189 }
2913 3190
2914 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3191 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -3004,6 +3281,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3004 } 3281 }
3005 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3282 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3006 } 3283 }
3284 return;
3007 }); 3285 });
3008 3286
3009 //ScriptSleep((int)((groupmass * velmag) / 10)); 3287 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -3018,35 +3296,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3018 public void llLookAt(LSL_Vector target, double strength, double damping) 3296 public void llLookAt(LSL_Vector target, double strength, double damping)
3019 { 3297 {
3020 m_host.AddScriptLPS(1); 3298 m_host.AddScriptLPS(1);
3021 // Determine where we are looking from
3022 LSL_Vector from = llGetPos();
3023
3024 // Work out the normalised vector from the source to the target
3025 LSL_Vector delta = llVecNorm(target - from);
3026 LSL_Vector angle = new LSL_Vector(0,0,0);
3027 3299
3028 // Calculate the yaw 3300 // Get the normalized vector to the target
3029 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3301 LSL_Vector d1 = llVecNorm(target - llGetPos());
3030 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO;
3031 3302
3032 // Calculate pitch 3303 // Get the bearing (yaw)
3033 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3304 LSL_Vector a1 = new LSL_Vector(0,0,0);
3305 a1.z = llAtan2(d1.y, d1.x);
3034 3306
3035 // we need to convert from a vector describing 3307 // Get the elevation (pitch)
3036 // the angles of rotation in radians into rotation value 3308 LSL_Vector a2 = new LSL_Vector(0,0,0);
3037 LSL_Rotation rot = llEuler2Rot(angle); 3309 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
3038 3310
3039 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3311 LSL_Rotation r1 = llEuler2Rot(a1);
3040 // set the rotation of the object, copy that behavior 3312 LSL_Rotation r2 = llEuler2Rot(a2);
3041 PhysicsActor pa = m_host.PhysActor; 3313 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
3042 3314
3043 if (strength == 0 || pa == null || !pa.IsPhysical) 3315 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3044 { 3316 {
3045 llSetRot(rot); 3317 // Do nothing if either value is 0 (this has been checked in SL)
3318 if (strength <= 0.0 || damping <= 0.0)
3319 return;
3320
3321 llSetRot(r3 * r2 * r1);
3046 } 3322 }
3047 else 3323 else
3048 { 3324 {
3049 m_host.StartLookAt(rot, (float)strength, (float)damping); 3325 if (strength == 0)
3326 {
3327 llSetRot(r3 * r2 * r1);
3328 return;
3329 }
3330
3331 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
3050 } 3332 }
3051 } 3333 }
3052 3334
@@ -3093,17 +3375,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3093 } 3375 }
3094 else 3376 else
3095 { 3377 {
3096 if (m_host.IsRoot) 3378 // new SL always returns object mass
3097 { 3379// if (m_host.IsRoot)
3380// {
3098 return m_host.ParentGroup.GetMass(); 3381 return m_host.ParentGroup.GetMass();
3099 } 3382// }
3100 else 3383// else
3101 { 3384// {
3102 return m_host.GetMass(); 3385// return m_host.GetMass();
3103 } 3386// }
3104 } 3387 }
3105 } 3388 }
3106 3389
3390
3391 public LSL_Float llGetMassMKS()
3392 {
3393 return 100f * llGetMass();
3394 }
3395
3107 public void llCollisionFilter(string name, string id, int accept) 3396 public void llCollisionFilter(string name, string id, int accept)
3108 { 3397 {
3109 m_host.AddScriptLPS(1); 3398 m_host.AddScriptLPS(1);
@@ -3151,8 +3440,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3151 { 3440 {
3152 // Unregister controls from Presence 3441 // Unregister controls from Presence
3153 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3442 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3154 // Remove Take Control permission.
3155 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3156 } 3443 }
3157 } 3444 }
3158 } 3445 }
@@ -3180,7 +3467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3180 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3467 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3181 3468
3182 if (attachmentsModule != null) 3469 if (attachmentsModule != null)
3183 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3470 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3184 else 3471 else
3185 return false; 3472 return false;
3186 } 3473 }
@@ -3210,9 +3497,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3210 { 3497 {
3211 m_host.AddScriptLPS(1); 3498 m_host.AddScriptLPS(1);
3212 3499
3213// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3214// return;
3215
3216 if (m_item.PermsGranter != m_host.OwnerID) 3500 if (m_item.PermsGranter != m_host.OwnerID)
3217 return; 3501 return;
3218 3502
@@ -3255,6 +3539,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3255 3539
3256 public void llInstantMessage(string user, string message) 3540 public void llInstantMessage(string user, string message)
3257 { 3541 {
3542 UUID result;
3543 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3544 {
3545 ShoutError("An invalid key was passed to llInstantMessage");
3546 ScriptSleep(2000);
3547 return;
3548 }
3549
3550
3258 m_host.AddScriptLPS(1); 3551 m_host.AddScriptLPS(1);
3259 3552
3260 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3553 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3269,14 +3562,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3269 UUID friendTransactionID = UUID.Random(); 3562 UUID friendTransactionID = UUID.Random();
3270 3563
3271 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3564 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3272 3565
3273 GridInstantMessage msg = new GridInstantMessage(); 3566 GridInstantMessage msg = new GridInstantMessage();
3274 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3567 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3275 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3568 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3276 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3569 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3277// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3570// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3278// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3571// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3279 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3572// DateTime dt = DateTime.UtcNow;
3573//
3574// // Ticks from UtcNow, but make it look like local. Evil, huh?
3575// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3576//
3577// try
3578// {
3579// // Convert that to the PST timezone
3580// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3581// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3582// }
3583// catch
3584// {
3585// // No logging here, as it could be VERY spammy
3586// }
3587//
3588// // And make it look local again to fool the unix time util
3589// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3590
3591 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3592
3280 //if (client != null) 3593 //if (client != null)
3281 //{ 3594 //{
3282 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3595 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3290,10 +3603,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3290 msg.message = message.Substring(0, 1024); 3603 msg.message = message.Substring(0, 1024);
3291 else 3604 else
3292 msg.message = message; 3605 msg.message = message;
3293 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3606 msg.dialog = (byte)19; // MessageFromObject
3294 msg.fromGroup = false;// fromGroup; 3607 msg.fromGroup = false;// fromGroup;
3295 msg.offline = (byte)0; //offline; 3608 msg.offline = (byte)0; //offline;
3296 msg.ParentEstateID = 0; //ParentEstateID; 3609 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3297 msg.Position = new Vector3(m_host.AbsolutePosition); 3610 msg.Position = new Vector3(m_host.AbsolutePosition);
3298 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3611 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3299 3612
@@ -3571,7 +3884,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3571 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3884 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3572 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3885 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3573 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3886 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3887 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3574 ScriptBaseClass.PERMISSION_ATTACH; 3888 ScriptBaseClass.PERMISSION_ATTACH;
3889
3575 } 3890 }
3576 else 3891 else
3577 { 3892 {
@@ -3588,15 +3903,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3588 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3903 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3589 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3904 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3590 } 3905 }
3906 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3907 {
3908 implicitPerms = perm;
3909 }
3591 } 3910 }
3592 3911
3593 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3912 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3594 { 3913 {
3595 lock (m_host.TaskInventory) 3914 m_host.TaskInventory.LockItemsForWrite(true);
3596 { 3915 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3597 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3916 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3598 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3917 m_host.TaskInventory.LockItemsForWrite(false);
3599 }
3600 3918
3601 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3919 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3602 "run_time_permissions", new Object[] { 3920 "run_time_permissions", new Object[] {
@@ -3639,11 +3957,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3639 3957
3640 if (!m_waitingForScriptAnswer) 3958 if (!m_waitingForScriptAnswer)
3641 { 3959 {
3642 lock (m_host.TaskInventory) 3960 m_host.TaskInventory.LockItemsForWrite(true);
3643 { 3961 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3644 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3962 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3645 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3963 m_host.TaskInventory.LockItemsForWrite(false);
3646 }
3647 3964
3648 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3965 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3649 m_waitingForScriptAnswer=true; 3966 m_waitingForScriptAnswer=true;
@@ -3672,14 +3989,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3672 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3989 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3673 llReleaseControls(); 3990 llReleaseControls();
3674 3991
3675 lock (m_host.TaskInventory) 3992 m_host.TaskInventory.LockItemsForWrite(true);
3676 { 3993 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3677 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3994 m_host.TaskInventory.LockItemsForWrite(false);
3678 } 3995
3679 3996 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3680 m_ScriptEngine.PostScriptEvent( 3997 "run_time_permissions", new Object[] {
3681 m_item.ItemID, 3998 new LSL_Integer(answer) },
3682 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3999 new DetectParams[0]));
3683 } 4000 }
3684 4001
3685 public LSL_String llGetPermissionsKey() 4002 public LSL_String llGetPermissionsKey()
@@ -3718,14 +4035,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3718 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 4035 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3719 { 4036 {
3720 List<SceneObjectPart> parts = GetLinkParts(linknumber); 4037 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3721 4038 if (parts.Count > 0)
3722 foreach (SceneObjectPart part in parts) 4039 {
3723 part.SetFaceColorAlpha(face, color, null); 4040 try
4041 {
4042 foreach (SceneObjectPart part in parts)
4043 part.SetFaceColorAlpha(face, color, null);
4044 }
4045 finally
4046 {
4047 }
4048 }
3724 } 4049 }
3725 4050
3726 public void llCreateLink(string target, int parent) 4051 public void llCreateLink(string target, int parent)
3727 { 4052 {
3728 m_host.AddScriptLPS(1); 4053 m_host.AddScriptLPS(1);
4054
3729 UUID targetID; 4055 UUID targetID;
3730 4056
3731 if (!UUID.TryParse(target, out targetID)) 4057 if (!UUID.TryParse(target, out targetID))
@@ -3831,10 +4157,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3831 // Restructuring Multiple Prims. 4157 // Restructuring Multiple Prims.
3832 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4158 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3833 parts.Remove(parentPrim.RootPart); 4159 parts.Remove(parentPrim.RootPart);
3834 foreach (SceneObjectPart part in parts) 4160 if (parts.Count > 0)
3835 { 4161 {
3836 parentPrim.DelinkFromGroup(part.LocalId, true); 4162 try
4163 {
4164 foreach (SceneObjectPart part in parts)
4165 {
4166 parentPrim.DelinkFromGroup(part.LocalId, true);
4167 }
4168 }
4169 finally
4170 {
4171 }
3837 } 4172 }
4173
3838 parentPrim.HasGroupChanged = true; 4174 parentPrim.HasGroupChanged = true;
3839 parentPrim.ScheduleGroupForFullUpdate(); 4175 parentPrim.ScheduleGroupForFullUpdate();
3840 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4176 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3843,12 +4179,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3843 { 4179 {
3844 SceneObjectPart newRoot = parts[0]; 4180 SceneObjectPart newRoot = parts[0];
3845 parts.Remove(newRoot); 4181 parts.Remove(newRoot);
3846 foreach (SceneObjectPart part in parts) 4182
4183 try
3847 { 4184 {
3848 // Required for linking 4185 foreach (SceneObjectPart part in parts)
3849 part.ClearUpdateSchedule(); 4186 {
3850 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4187 part.ClearUpdateSchedule();
4188 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4189 }
3851 } 4190 }
4191 finally
4192 {
4193 }
4194
4195
3852 newRoot.ParentGroup.HasGroupChanged = true; 4196 newRoot.ParentGroup.HasGroupChanged = true;
3853 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4197 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3854 } 4198 }
@@ -3868,6 +4212,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3868 public void llBreakAllLinks() 4212 public void llBreakAllLinks()
3869 { 4213 {
3870 m_host.AddScriptLPS(1); 4214 m_host.AddScriptLPS(1);
4215
4216 TaskInventoryItem item = m_item;
4217
4218 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4219 && !m_automaticLinkPermission)
4220 {
4221 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4222 return;
4223 }
4224
3871 SceneObjectGroup parentPrim = m_host.ParentGroup; 4225 SceneObjectGroup parentPrim = m_host.ParentGroup;
3872 if (parentPrim.AttachmentPoint != 0) 4226 if (parentPrim.AttachmentPoint != 0)
3873 return; // Fail silently if attached 4227 return; // Fail silently if attached
@@ -3887,13 +4241,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3887 public LSL_String llGetLinkKey(int linknum) 4241 public LSL_String llGetLinkKey(int linknum)
3888 { 4242 {
3889 m_host.AddScriptLPS(1); 4243 m_host.AddScriptLPS(1);
4244 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4245 if (part != null)
4246 {
4247 return part.UUID.ToString();
4248 }
4249 else
4250 {
4251 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4252 {
4253 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3890 4254
3891 ISceneEntity entity = GetLinkEntity(linknum); 4255 if (linknum < 0)
4256 return UUID.Zero.ToString();
3892 4257
3893 if (entity != null) 4258 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3894 return entity.UUID.ToString(); 4259 if (avatars.Count > linknum)
3895 else 4260 {
3896 return ScriptBaseClass.NULL_KEY; 4261 return avatars[linknum].UUID.ToString();
4262 }
4263 }
4264 return UUID.Zero.ToString();
4265 }
3897 } 4266 }
3898 4267
3899 /// <summary> 4268 /// <summary>
@@ -3952,17 +4321,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3952 m_host.AddScriptLPS(1); 4321 m_host.AddScriptLPS(1);
3953 int count = 0; 4322 int count = 0;
3954 4323
3955 lock (m_host.TaskInventory) 4324 m_host.TaskInventory.LockItemsForRead(true);
4325 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3956 { 4326 {
3957 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4327 if (inv.Value.Type == type || type == -1)
3958 { 4328 {
3959 if (inv.Value.Type == type || type == -1) 4329 count = count + 1;
3960 {
3961 count = count + 1;
3962 }
3963 } 4330 }
3964 } 4331 }
3965 4332
4333 m_host.TaskInventory.LockItemsForRead(false);
3966 return count; 4334 return count;
3967 } 4335 }
3968 4336
@@ -3971,16 +4339,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 m_host.AddScriptLPS(1); 4339 m_host.AddScriptLPS(1);
3972 ArrayList keys = new ArrayList(); 4340 ArrayList keys = new ArrayList();
3973 4341
3974 lock (m_host.TaskInventory) 4342 m_host.TaskInventory.LockItemsForRead(true);
4343 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3975 { 4344 {
3976 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4345 if (inv.Value.Type == type || type == -1)
3977 { 4346 {
3978 if (inv.Value.Type == type || type == -1) 4347 keys.Add(inv.Value.Name);
3979 {
3980 keys.Add(inv.Value.Name);
3981 }
3982 } 4348 }
3983 } 4349 }
4350 m_host.TaskInventory.LockItemsForRead(false);
3984 4351
3985 if (keys.Count == 0) 4352 if (keys.Count == 0)
3986 { 4353 {
@@ -4018,7 +4385,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4018 if (item == null) 4385 if (item == null)
4019 { 4386 {
4020 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4387 llSay(0, String.Format("Could not find object '{0}'", inventory));
4021 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4388 return;
4389// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
4022 } 4390 }
4023 4391
4024 UUID objId = item.ItemID; 4392 UUID objId = item.ItemID;
@@ -4046,33 +4414,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4046 return; 4414 return;
4047 } 4415 }
4048 } 4416 }
4417
4049 // destination is an avatar 4418 // destination is an avatar
4050 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4419 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
4051 4420
4052 if (agentItem == null) 4421 if (agentItem == null)
4053 return; 4422 return;
4054 4423
4055 if (m_TransferModule != null) 4424 byte[] bucket = new byte[1];
4056 { 4425 bucket[0] = (byte)item.Type;
4057 byte[] bucket = new byte[1]; 4426 //byte[] objBytes = agentItem.ID.GetBytes();
4058 bucket[0] = (byte)item.Type; 4427 //Array.Copy(objBytes, 0, bucket, 1, 16);
4059 4428
4060 GridInstantMessage msg = new GridInstantMessage(World, 4429 GridInstantMessage msg = new GridInstantMessage(World,
4061 m_host.OwnerID, m_host.Name, destId, 4430 m_host.OwnerID, m_host.Name, destId,
4062 (byte)InstantMessageDialog.TaskInventoryOffered, 4431 (byte)InstantMessageDialog.TaskInventoryOffered,
4063 false, item.Name+". "+m_host.Name+" is located at "+ 4432 false, item.Name+". "+m_host.Name+" is located at "+
4064 World.RegionInfo.RegionName+" "+ 4433 World.RegionInfo.RegionName+" "+
4065 m_host.AbsolutePosition.ToString(), 4434 m_host.AbsolutePosition.ToString(),
4066 agentItem.ID, true, m_host.AbsolutePosition, 4435 agentItem.ID, true, m_host.AbsolutePosition,
4067 bucket, true); 4436 bucket, true);
4068 4437
4069 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4438 ScenePresence sp;
4070 }
4071 4439
4440 if (World.TryGetScenePresence(destId, out sp))
4441 {
4442 sp.ControllingClient.SendInstantMessage(msg);
4443 }
4444 else
4445 {
4446 if (m_TransferModule != null)
4447 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4448 }
4449
4450 //This delay should only occur when giving inventory to avatars.
4072 ScriptSleep(3000); 4451 ScriptSleep(3000);
4073 } 4452 }
4074 } 4453 }
4075 4454
4455 [DebuggerNonUserCode]
4076 public void llRemoveInventory(string name) 4456 public void llRemoveInventory(string name)
4077 { 4457 {
4078 m_host.AddScriptLPS(1); 4458 m_host.AddScriptLPS(1);
@@ -4127,109 +4507,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4127 { 4507 {
4128 m_host.AddScriptLPS(1); 4508 m_host.AddScriptLPS(1);
4129 4509
4130 UUID uuid = (UUID)id; 4510 UUID uuid;
4131 PresenceInfo pinfo = null; 4511 if (UUID.TryParse(id, out uuid))
4132 UserAccount account;
4133
4134 UserInfoCacheEntry ce;
4135 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4136 { 4512 {
4137 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4513 PresenceInfo pinfo = null;
4138 if (account == null) 4514 UserAccount account;
4515
4516 UserInfoCacheEntry ce;
4517 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4139 { 4518 {
4140 m_userInfoCache[uuid] = null; // Cache negative 4519 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4141 return UUID.Zero.ToString(); 4520 if (account == null)
4142 } 4521 {
4522 m_userInfoCache[uuid] = null; // Cache negative
4523 return UUID.Zero.ToString();
4524 }
4143 4525
4144 4526
4145 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4527 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4146 if (pinfos != null && pinfos.Length > 0) 4528 if (pinfos != null && pinfos.Length > 0)
4147 {
4148 foreach (PresenceInfo p in pinfos)
4149 { 4529 {
4150 if (p.RegionID != UUID.Zero) 4530 foreach (PresenceInfo p in pinfos)
4151 { 4531 {
4152 pinfo = p; 4532 if (p.RegionID != UUID.Zero)
4533 {
4534 pinfo = p;
4535 }
4153 } 4536 }
4154 } 4537 }
4155 }
4156 4538
4157 ce = new UserInfoCacheEntry(); 4539 ce = new UserInfoCacheEntry();
4158 ce.time = Util.EnvironmentTickCount(); 4540 ce.time = Util.EnvironmentTickCount();
4159 ce.account = account; 4541 ce.account = account;
4160 ce.pinfo = pinfo; 4542 ce.pinfo = pinfo;
4161 } 4543 m_userInfoCache[uuid] = ce;
4162 else 4544 }
4163 { 4545 else
4164 if (ce == null) 4546 {
4165 return UUID.Zero.ToString(); 4547 if (ce == null)
4548 return UUID.Zero.ToString();
4166 4549
4167 account = ce.account; 4550 account = ce.account;
4168 pinfo = ce.pinfo; 4551 pinfo = ce.pinfo;
4169 } 4552 }
4170 4553
4171 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4554 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4172 {
4173 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4174 if (pinfos != null && pinfos.Length > 0)
4175 { 4555 {
4176 foreach (PresenceInfo p in pinfos) 4556 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4557 if (pinfos != null && pinfos.Length > 0)
4177 { 4558 {
4178 if (p.RegionID != UUID.Zero) 4559 foreach (PresenceInfo p in pinfos)
4179 { 4560 {
4180 pinfo = p; 4561 if (p.RegionID != UUID.Zero)
4562 {
4563 pinfo = p;
4564 }
4181 } 4565 }
4182 } 4566 }
4183 } 4567 else
4184 else 4568 pinfo = null;
4185 pinfo = null;
4186 4569
4187 ce.time = Util.EnvironmentTickCount(); 4570 ce.time = Util.EnvironmentTickCount();
4188 ce.pinfo = pinfo; 4571 ce.pinfo = pinfo;
4189 } 4572 }
4190 4573
4191 string reply = String.Empty; 4574 string reply = String.Empty;
4192 4575
4193 switch (data) 4576 switch (data)
4194 { 4577 {
4195 case 1: // DATA_ONLINE (0|1) 4578 case 1: // DATA_ONLINE (0|1)
4196 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4579 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4197 reply = "1"; 4580 reply = "1";
4198 else 4581 else
4199 reply = "0"; 4582 reply = "0";
4200 break; 4583 break;
4201 case 2: // DATA_NAME (First Last) 4584 case 2: // DATA_NAME (First Last)
4202 reply = account.FirstName + " " + account.LastName; 4585 reply = account.FirstName + " " + account.LastName;
4203 break; 4586 break;
4204 case 3: // DATA_BORN (YYYY-MM-DD) 4587 case 3: // DATA_BORN (YYYY-MM-DD)
4205 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4588 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4206 born = born.AddSeconds(account.Created); 4589 born = born.AddSeconds(account.Created);
4207 reply = born.ToString("yyyy-MM-dd"); 4590 reply = born.ToString("yyyy-MM-dd");
4208 break; 4591 break;
4209 case 4: // DATA_RATING (0,0,0,0,0,0) 4592 case 4: // DATA_RATING (0,0,0,0,0,0)
4210 reply = "0,0,0,0,0,0"; 4593 reply = "0,0,0,0,0,0";
4211 break; 4594 break;
4212 case 7: // DATA_USERLEVEL (integer) 4595 case 8: // DATA_PAYINFO (0|1|2|3)
4213 reply = account.UserLevel.ToString(); 4596 reply = "0";
4214 break; 4597 break;
4215 case 8: // DATA_PAYINFO (0|1|2|3) 4598 default:
4216 reply = "0"; 4599 return UUID.Zero.ToString(); // Raise no event
4217 break; 4600 }
4218 default:
4219 return UUID.Zero.ToString(); // Raise no event
4220 }
4221 4601
4222 UUID rq = UUID.Random(); 4602 UUID rq = UUID.Random();
4223 4603
4224 UUID tid = AsyncCommands. 4604 UUID tid = AsyncCommands.
4225 DataserverPlugin.RegisterRequest(m_host.LocalId, 4605 DataserverPlugin.RegisterRequest(m_host.LocalId,
4226 m_item.ItemID, rq.ToString()); 4606 m_item.ItemID, rq.ToString());
4227 4607
4228 AsyncCommands. 4608 AsyncCommands.
4229 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4609 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4230 4610
4231 ScriptSleep(100); 4611 ScriptSleep(100);
4232 return tid.ToString(); 4612 return tid.ToString();
4613 }
4614 else
4615 {
4616 ShoutError("Invalid UUID passed to llRequestAgentData.");
4617 }
4618 return "";
4233 } 4619 }
4234 4620
4235 public LSL_String llRequestInventoryData(string name) 4621 public LSL_String llRequestInventoryData(string name)
@@ -4286,12 +4672,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4286 if (UUID.TryParse(agent, out agentId)) 4672 if (UUID.TryParse(agent, out agentId))
4287 { 4673 {
4288 ScenePresence presence = World.GetScenePresence(agentId); 4674 ScenePresence presence = World.GetScenePresence(agentId);
4289 if (presence != null) 4675 if (presence != null && presence.PresenceType != PresenceType.Npc)
4290 { 4676 {
4677 // agent must not be a god
4678 if (presence.UserLevel >= 200) return;
4679
4291 // agent must be over the owners land 4680 // agent must be over the owners land
4292 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4681 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4293 { 4682 {
4294 World.TeleportClientHome(agentId, presence.ControllingClient); 4683 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4684 {
4685 // They can't be teleported home for some reason
4686 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4687 if (regionInfo != null)
4688 {
4689 World.RequestTeleportLocation(
4690 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4691 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4692 }
4693 }
4295 } 4694 }
4296 } 4695 }
4297 } 4696 }
@@ -4309,20 +4708,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4309 ScenePresence presence = World.GetScenePresence(agentId); 4708 ScenePresence presence = World.GetScenePresence(agentId);
4310 if (presence != null && presence.PresenceType != PresenceType.Npc) 4709 if (presence != null && presence.PresenceType != PresenceType.Npc)
4311 { 4710 {
4312 // agent must not be a god
4313 if (presence.GodLevel >= 200) return;
4314
4315 if (destination == String.Empty) 4711 if (destination == String.Empty)
4316 destination = World.RegionInfo.RegionName; 4712 destination = World.RegionInfo.RegionName;
4317 4713
4318 // agent must be over the owners land 4714 if (m_item.PermsGranter == agentId)
4319 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4715 {
4716 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4717 {
4718 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4719 }
4720 }
4721
4722 // agent must be wearing the object
4723 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID)
4320 { 4724 {
4321 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4725 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4322 } 4726 }
4323 else // or must be wearing the prim 4727 else
4324 { 4728 {
4325 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4729 // agent must not be a god
4730 if (presence.GodLevel >= 200) return;
4731
4732 // agent must be over the owners land
4733 ILandObject agentLand = World.LandChannel.GetLandObject(presence.AbsolutePosition);
4734 ILandObject objectLand = World.LandChannel.GetLandObject(m_host.AbsolutePosition);
4735 if (m_host.OwnerID == objectLand.LandData.OwnerID && m_host.OwnerID == agentLand.LandData.OwnerID)
4326 { 4736 {
4327 DoLLTeleport(presence, destination, targetPos, targetLookAt); 4737 DoLLTeleport(presence, destination, targetPos, targetLookAt);
4328 } 4738 }
@@ -4336,24 +4746,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4336 m_host.AddScriptLPS(1); 4746 m_host.AddScriptLPS(1);
4337 UUID agentId = new UUID(); 4747 UUID agentId = new UUID();
4338 4748
4339 ulong regionHandle = Utils.UIntsToLong((uint)global_coords.x, (uint)global_coords.y); 4749 ulong regionHandle = Utils.UIntsToLong((uint)(global_coords.x / 256) * 256, (uint)(global_coords.y / 256) * 256);
4340 4750
4341 if (UUID.TryParse(agent, out agentId)) 4751 if (UUID.TryParse(agent, out agentId))
4342 { 4752 {
4753 // This function is owner only!
4754 if (m_host.OwnerID != agentId)
4755 return;
4756
4343 ScenePresence presence = World.GetScenePresence(agentId); 4757 ScenePresence presence = World.GetScenePresence(agentId);
4758
4759 // Can't TP sitting avatars
4760 if (presence.ParentID != 0) // Sitting
4761 return;
4762
4344 if (presence != null && presence.PresenceType != PresenceType.Npc) 4763 if (presence != null && presence.PresenceType != PresenceType.Npc)
4345 { 4764 {
4346 // agent must not be a god 4765 if (m_item.PermsGranter == agentId)
4347 if (presence.GodLevel >= 200) return;
4348
4349 // agent must be over the owners land
4350 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4351 { 4766 {
4352 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4767 // If attached using llAttachToAvatarTemp, cowardly refuse
4353 } 4768 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.ParentGroup.FromItemID == UUID.Zero)
4354 else // or must be wearing the prim 4769 return;
4355 { 4770
4356 if (m_host.ParentGroup.AttachmentPoint != 0 && m_host.OwnerID == presence.UUID) 4771 if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) != 0)
4357 { 4772 {
4358 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation); 4773 World.RequestTeleportLocation(presence.ControllingClient, regionHandle, targetPos, targetLookAt, (uint)TeleportFlags.ViaLocation);
4359 } 4774 }
@@ -4397,7 +4812,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4397 UUID av = new UUID(); 4812 UUID av = new UUID();
4398 if (!UUID.TryParse(agent,out av)) 4813 if (!UUID.TryParse(agent,out av))
4399 { 4814 {
4400 LSLError("First parameter to llDialog needs to be a key");
4401 return; 4815 return;
4402 } 4816 }
4403 4817
@@ -4430,9 +4844,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4430 { 4844 {
4431 m_host.AddScriptLPS(1); 4845 m_host.AddScriptLPS(1);
4432 4846
4847 if(impact_sound == "")
4848 {
4849 m_host.CollisionSoundVolume = (float)impact_volume;
4850 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4851 m_host.CollisionSoundType = 0;
4852 return;
4853 }
4433 // TODO: Parameter check logic required. 4854 // TODO: Parameter check logic required.
4434 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4855 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4435 m_host.CollisionSoundVolume = (float)impact_volume; 4856 m_host.CollisionSoundVolume = (float)impact_volume;
4857 m_host.CollisionSoundType = 1;
4436 } 4858 }
4437 4859
4438 public LSL_String llGetAnimation(string id) 4860 public LSL_String llGetAnimation(string id)
@@ -4446,14 +4868,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4446 4868
4447 if (m_host.RegionHandle == presence.RegionHandle) 4869 if (m_host.RegionHandle == presence.RegionHandle)
4448 { 4870 {
4449 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4450
4451 if (presence != null) 4871 if (presence != null)
4452 { 4872 {
4453 AnimationSet currentAnims = presence.Animator.Animations; 4873 if (presence.SitGround)
4454 string currentAnimationState = String.Empty; 4874 return "Sitting on Ground";
4455 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4875 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4456 return currentAnimationState; 4876 return "Sitting";
4877
4878 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4879 string lslMovementAnimation;
4880
4881 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4882 return lslMovementAnimation;
4457 } 4883 }
4458 } 4884 }
4459 4885
@@ -4601,7 +5027,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4601 { 5027 {
4602 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 5028 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4603 float distance_term = distance * distance * distance; // Script Energy 5029 float distance_term = distance * distance * distance; // Script Energy
4604 float pusher_mass = m_host.GetMass(); 5030 // use total object mass and not part
5031 float pusher_mass = m_host.ParentGroup.GetMass();
4605 5032
4606 float PUSH_ATTENUATION_DISTANCE = 17f; 5033 float PUSH_ATTENUATION_DISTANCE = 17f;
4607 float PUSH_ATTENUATION_SCALE = 5f; 5034 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4838,6 +5265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4838 { 5265 {
4839 return item.AssetID.ToString(); 5266 return item.AssetID.ToString();
4840 } 5267 }
5268 m_host.TaskInventory.LockItemsForRead(false);
4841 5269
4842 return UUID.Zero.ToString(); 5270 return UUID.Zero.ToString();
4843 } 5271 }
@@ -4990,14 +5418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4990 { 5418 {
4991 m_host.AddScriptLPS(1); 5419 m_host.AddScriptLPS(1);
4992 5420
4993 if (src == null) 5421 return src.Length;
4994 {
4995 return 0;
4996 }
4997 else
4998 {
4999 return src.Length;
5000 }
5001 } 5422 }
5002 5423
5003 public LSL_Integer llList2Integer(LSL_List src, int index) 5424 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5068,7 +5489,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5068 else if (src.Data[index] is LSL_Float) 5489 else if (src.Data[index] is LSL_Float)
5069 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5490 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5070 else if (src.Data[index] is LSL_String) 5491 else if (src.Data[index] is LSL_String)
5071 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5492 {
5493 string str = ((LSL_String) src.Data[index]).m_string;
5494 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5495 if (m != Match.Empty)
5496 {
5497 str = m.Value;
5498 double d = 0.0;
5499 if (!Double.TryParse(str, out d))
5500 return 0.0;
5501
5502 return d;
5503 }
5504 return 0.0;
5505 }
5072 return Convert.ToDouble(src.Data[index]); 5506 return Convert.ToDouble(src.Data[index]);
5073 } 5507 }
5074 catch (FormatException) 5508 catch (FormatException)
@@ -5110,7 +5544,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5110 // for completion and should LSL_Key ever be implemented 5544 // for completion and should LSL_Key ever be implemented
5111 // as it's own struct 5545 // as it's own struct
5112 else if (!(src.Data[index] is LSL_String || 5546 else if (!(src.Data[index] is LSL_String ||
5113 src.Data[index] is LSL_Key)) 5547 src.Data[index] is LSL_Key ||
5548 src.Data[index] is String))
5114 { 5549 {
5115 return ""; 5550 return "";
5116 } 5551 }
@@ -5368,7 +5803,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5368 } 5803 }
5369 } 5804 }
5370 } 5805 }
5371 else { 5806 else
5807 {
5372 object[] array = new object[src.Length]; 5808 object[] array = new object[src.Length];
5373 Array.Copy(src.Data, 0, array, 0, src.Length); 5809 Array.Copy(src.Data, 0, array, 0, src.Length);
5374 result = new LSL_List(array); 5810 result = new LSL_List(array);
@@ -5475,7 +5911,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5475 public LSL_Integer llGetRegionAgentCount() 5911 public LSL_Integer llGetRegionAgentCount()
5476 { 5912 {
5477 m_host.AddScriptLPS(1); 5913 m_host.AddScriptLPS(1);
5478 return new LSL_Integer(World.GetRootAgentCount()); 5914
5915 int count = 0;
5916 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5917 count++;
5918 });
5919
5920 return new LSL_Integer(count);
5479 } 5921 }
5480 5922
5481 public LSL_Vector llGetRegionCorner() 5923 public LSL_Vector llGetRegionCorner()
@@ -5716,6 +6158,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5716 flags |= ScriptBaseClass.AGENT_AWAY; 6158 flags |= ScriptBaseClass.AGENT_AWAY;
5717 } 6159 }
5718 6160
6161 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6162 UUID[] anims = agent.Animator.GetAnimationArray();
6163 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6164 {
6165 flags |= ScriptBaseClass.AGENT_BUSY;
6166 }
6167
5719 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6168 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5720 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6169 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5721 { 6170 {
@@ -5763,6 +6212,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5763 flags |= ScriptBaseClass.AGENT_SITTING; 6212 flags |= ScriptBaseClass.AGENT_SITTING;
5764 } 6213 }
5765 6214
6215 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6216 {
6217 flags |= ScriptBaseClass.AGENT_MALE;
6218 }
6219
5766 return flags; 6220 return flags;
5767 } 6221 }
5768 6222
@@ -5908,9 +6362,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5908 6362
5909 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6363 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5910 6364
5911 foreach (SceneObjectPart part in parts) 6365 try
6366 {
6367 foreach (SceneObjectPart part in parts)
6368 {
6369 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6370 }
6371 }
6372 finally
5912 { 6373 {
5913 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5914 } 6374 }
5915 } 6375 }
5916 6376
@@ -5964,13 +6424,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5964 6424
5965 if (m_host.OwnerID == land.LandData.OwnerID) 6425 if (m_host.OwnerID == land.LandData.OwnerID)
5966 { 6426 {
5967 World.TeleportClientHome(agentID, presence.ControllingClient); 6427 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6428 presence.TeleportWithMomentum(p, null);
6429 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5968 } 6430 }
5969 } 6431 }
5970 } 6432 }
5971 ScriptSleep(5000); 6433 ScriptSleep(5000);
5972 } 6434 }
5973 6435
6436 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6437 {
6438 return ParseString2List(str, separators, in_spacers, false);
6439 }
6440
5974 public LSL_Integer llOverMyLand(string id) 6441 public LSL_Integer llOverMyLand(string id)
5975 { 6442 {
5976 m_host.AddScriptLPS(1); 6443 m_host.AddScriptLPS(1);
@@ -6023,26 +6490,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6023 } 6490 }
6024 else 6491 else
6025 { 6492 {
6026 agentSize = GetAgentSize(avatar); 6493// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6494 Vector3 s = avatar.Appearance.AvatarSize;
6495 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
6027 } 6496 }
6028
6029 return agentSize; 6497 return agentSize;
6030 } 6498 }
6031 6499
6032 public LSL_Integer llSameGroup(string agent) 6500 public LSL_Integer llSameGroup(string id)
6033 { 6501 {
6034 m_host.AddScriptLPS(1); 6502 m_host.AddScriptLPS(1);
6035 UUID agentId = new UUID(); 6503 UUID uuid = new UUID();
6036 if (!UUID.TryParse(agent, out agentId)) 6504 if (!UUID.TryParse(id, out uuid))
6037 return new LSL_Integer(0); 6505 return new LSL_Integer(0);
6038 ScenePresence presence = World.GetScenePresence(agentId); 6506
6039 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6507 // Check if it's a group key
6040 return new LSL_Integer(0); 6508 if (uuid == m_host.ParentGroup.RootPart.GroupID)
6041 IClientAPI client = presence.ControllingClient;
6042 if (m_host.GroupID == client.ActiveGroupId)
6043 return new LSL_Integer(1); 6509 return new LSL_Integer(1);
6044 else 6510
6511 // We got passed a UUID.Zero
6512 if (uuid == UUID.Zero)
6513 return new LSL_Integer(0);
6514
6515 // Handle the case where id names an avatar
6516 ScenePresence presence = World.GetScenePresence(uuid);
6517 if (presence != null)
6518 {
6519 if (presence.IsChildAgent)
6520 return new LSL_Integer(0);
6521
6522 IClientAPI client = presence.ControllingClient;
6523 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6524 return new LSL_Integer(1);
6525
6526 return new LSL_Integer(0);
6527 }
6528
6529 // Handle object case
6530 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6531 if (part != null)
6532 {
6533 // This will handle both deed and non-deed and also the no
6534 // group case
6535 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6536 return new LSL_Integer(1);
6537
6045 return new LSL_Integer(0); 6538 return new LSL_Integer(0);
6539 }
6540
6541 return new LSL_Integer(0);
6046 } 6542 }
6047 6543
6048 public void llUnSit(string id) 6544 public void llUnSit(string id)
@@ -6631,6 +7127,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6631 7127
6632 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7128 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6633 { 7129 {
7130 // LSL quaternions can normalize to 0, normal Quaternions can't.
7131 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7132 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7133
6634 part.SitTargetPosition = offset; 7134 part.SitTargetPosition = offset;
6635 part.SitTargetOrientation = rot; 7135 part.SitTargetOrientation = rot;
6636 part.ParentGroup.HasGroupChanged = true; 7136 part.ParentGroup.HasGroupChanged = true;
@@ -6817,30 +7317,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6817 UUID av = new UUID(); 7317 UUID av = new UUID();
6818 if (!UUID.TryParse(avatar,out av)) 7318 if (!UUID.TryParse(avatar,out av))
6819 { 7319 {
6820 LSLError("First parameter to llDialog needs to be a key"); 7320 //LSLError("First parameter to llDialog needs to be a key");
6821 return; 7321 return;
6822 } 7322 }
6823 if (buttons.Length < 1) 7323 if (buttons.Length < 1)
6824 { 7324 {
6825 LSLError("No less than 1 button can be shown"); 7325 buttons.Add("OK");
6826 return;
6827 } 7326 }
6828 if (buttons.Length > 12) 7327 if (buttons.Length > 12)
6829 { 7328 {
6830 LSLError("No more than 12 buttons can be shown"); 7329 ShoutError("button list too long, must be 12 or fewer entries");
6831 return;
6832 } 7330 }
6833 string[] buts = new string[buttons.Length]; 7331 int length = buttons.Length;
6834 for (int i = 0; i < buttons.Length; i++) 7332 if (length > 12)
7333 length = 12;
7334
7335 string[] buts = new string[length];
7336 for (int i = 0; i < length; i++)
6835 { 7337 {
6836 if (buttons.Data[i].ToString() == String.Empty) 7338 if (buttons.Data[i].ToString() == String.Empty)
6837 { 7339 {
6838 LSLError("button label cannot be blank"); 7340 ShoutError("button label cannot be blank");
6839 return; 7341 return;
6840 } 7342 }
6841 if (buttons.Data[i].ToString().Length > 24) 7343 if (buttons.Data[i].ToString().Length > 24)
6842 { 7344 {
6843 LSLError("button label cannot be longer than 24 characters"); 7345 ShoutError("button label cannot be longer than 24 characters");
6844 return; 7346 return;
6845 } 7347 }
6846 buts[i] = buttons.Data[i].ToString(); 7348 buts[i] = buttons.Data[i].ToString();
@@ -6907,9 +7409,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6907 return; 7409 return;
6908 } 7410 }
6909 7411
6910 // the rest of the permission checks are done in RezScript, so check the pin there as well 7412 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6911 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7413 if (dest != null)
7414 {
7415 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7416 {
7417 // the rest of the permission checks are done in RezScript, so check the pin there as well
7418 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6912 7419
7420 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7421 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7422 }
7423 }
6913 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7424 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6914 ScriptSleep(3000); 7425 ScriptSleep(3000);
6915 } 7426 }
@@ -6983,19 +7494,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6983 public LSL_String llMD5String(string src, int nonce) 7494 public LSL_String llMD5String(string src, int nonce)
6984 { 7495 {
6985 m_host.AddScriptLPS(1); 7496 m_host.AddScriptLPS(1);
6986 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7497 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6987 } 7498 }
6988 7499
6989 public LSL_String llSHA1String(string src) 7500 public LSL_String llSHA1String(string src)
6990 { 7501 {
6991 m_host.AddScriptLPS(1); 7502 m_host.AddScriptLPS(1);
6992 return Util.SHA1Hash(src).ToLower(); 7503 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6993 } 7504 }
6994 7505
6995 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7506 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6996 { 7507 {
6997 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7508 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6998 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7509 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7510 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7511 return shapeBlock;
6999 7512
7000 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7513 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
7001 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7514 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -7100,6 +7613,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7100 // Prim type box, cylinder and prism. 7613 // Prim type box, cylinder and prism.
7101 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) 7614 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)
7102 { 7615 {
7616 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7617 return;
7618
7103 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7619 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7104 ObjectShapePacket.ObjectDataBlock shapeBlock; 7620 ObjectShapePacket.ObjectDataBlock shapeBlock;
7105 7621
@@ -7153,6 +7669,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7153 // Prim type sphere. 7669 // Prim type sphere.
7154 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7670 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7155 { 7671 {
7672 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7673 return;
7674
7156 ObjectShapePacket.ObjectDataBlock shapeBlock; 7675 ObjectShapePacket.ObjectDataBlock shapeBlock;
7157 7676
7158 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7677 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7194,6 +7713,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7194 // Prim type torus, tube and ring. 7713 // Prim type torus, tube and ring.
7195 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) 7714 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)
7196 { 7715 {
7716 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7717 return;
7718
7197 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7719 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7198 ObjectShapePacket.ObjectDataBlock shapeBlock; 7720 ObjectShapePacket.ObjectDataBlock shapeBlock;
7199 7721
@@ -7329,6 +7851,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7329 // Prim type sculpt. 7851 // Prim type sculpt.
7330 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7852 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7331 { 7853 {
7854 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7855 return;
7856
7332 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7857 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7333 UUID sculptId; 7858 UUID sculptId;
7334 7859
@@ -7351,7 +7876,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7351 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7876 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7352 { 7877 {
7353 // default 7878 // default
7354 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7879 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7355 } 7880 }
7356 7881
7357 part.Shape.SetSculptProperties((byte)type, sculptId); 7882 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7368,15 +7893,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7368 ScriptSleep(200); 7893 ScriptSleep(200);
7369 } 7894 }
7370 7895
7371 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7372 {
7373 m_host.AddScriptLPS(1);
7374
7375 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7376
7377 ScriptSleep(200);
7378 }
7379
7380 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7896 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7381 { 7897 {
7382 m_host.AddScriptLPS(1); 7898 m_host.AddScriptLPS(1);
@@ -7384,169 +7900,135 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7384 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7900 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7385 } 7901 }
7386 7902
7387 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7903 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7388 { 7904 {
7389 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7905 List<object> parts = new List<object>();
7906 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7907 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7908 foreach (SceneObjectPart p in prims)
7909 parts.Add(p);
7910 foreach (ScenePresence p in avatars)
7911 parts.Add(p);
7390 7912
7391 LSL_List remaining = null; 7913 LSL_List remaining = null;
7392 uint rulesParsed = 0; 7914 uint rulesParsed = 0;
7393 7915
7394 foreach (SceneObjectPart part in parts) 7916 if (parts.Count > 0)
7395 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7396
7397 while (remaining != null && remaining.Length > 2)
7398 { 7917 {
7399 linknumber = remaining.GetLSLIntegerItem(0); 7918 foreach (object part in parts)
7400 rules = remaining.GetSublist(1, -1);
7401 parts = GetLinkParts(linknumber);
7402
7403 foreach (SceneObjectPart part in parts)
7404 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7405 }
7406 }
7407
7408 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7409 {
7410 SceneObjectGroup group = m_host.ParentGroup;
7411
7412 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7413 return;
7414 if (group.IsAttachment)
7415 return;
7416
7417 if (frames.Data.Length > 0) // We are getting a new motion
7418 {
7419 if (group.RootPart.KeyframeMotion != null)
7420 group.RootPart.KeyframeMotion.Delete();
7421 group.RootPart.KeyframeMotion = null;
7422
7423 int idx = 0;
7424
7425 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7426 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7427
7428 while (idx < options.Data.Length)
7429 { 7919 {
7430 int option = (int)options.GetLSLIntegerItem(idx++); 7920 if (part is SceneObjectPart)
7431 int remain = options.Data.Length - idx; 7921 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7922 else
7923 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7924 }
7432 7925
7433 switch (option) 7926 while ((object)remaining != null && remaining.Length > 2)
7927 {
7928 linknumber = remaining.GetLSLIntegerItem(0);
7929 rules = remaining.GetSublist(1, -1);
7930 parts.Clear();
7931 prims = GetLinkParts(linknumber);
7932 avatars = GetLinkAvatars(linknumber);
7933 foreach (SceneObjectPart p in prims)
7934 parts.Add(p);
7935 foreach (ScenePresence p in avatars)
7936 parts.Add(p);
7937
7938 remaining = null;
7939 foreach (object part in parts)
7434 { 7940 {
7435 case ScriptBaseClass.KFM_MODE: 7941 if (part is SceneObjectPart)
7436 if (remain < 1) 7942 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7437 break; 7943 else
7438 int modeval = (int)options.GetLSLIntegerItem(idx++); 7944 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7439 switch(modeval)
7440 {
7441 case ScriptBaseClass.KFM_FORWARD:
7442 mode = KeyframeMotion.PlayMode.Forward;
7443 break;
7444 case ScriptBaseClass.KFM_REVERSE:
7445 mode = KeyframeMotion.PlayMode.Reverse;
7446 break;
7447 case ScriptBaseClass.KFM_LOOP:
7448 mode = KeyframeMotion.PlayMode.Loop;
7449 break;
7450 case ScriptBaseClass.KFM_PING_PONG:
7451 mode = KeyframeMotion.PlayMode.PingPong;
7452 break;
7453 }
7454 break;
7455 case ScriptBaseClass.KFM_DATA:
7456 if (remain < 1)
7457 break;
7458 int dataval = (int)options.GetLSLIntegerItem(idx++);
7459 data = (KeyframeMotion.DataFormat)dataval;
7460 break;
7461 } 7945 }
7462 } 7946 }
7947 }
7948 }
7463 7949
7464 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data); 7950 public LSL_List llGetPhysicsMaterial()
7951 {
7952 LSL_List result = new LSL_List();
7465 7953
7466 idx = 0; 7954 result.Add(new LSL_Float(m_host.GravityModifier));
7955 result.Add(new LSL_Float(m_host.Restitution));
7956 result.Add(new LSL_Float(m_host.Friction));
7957 result.Add(new LSL_Float(m_host.Density));
7467 7958
7468 int elemLength = 2; 7959 return result;
7469 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation)) 7960 }
7470 elemLength = 3;
7471 7961
7472 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>(); 7962 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7473 while (idx < frames.Data.Length) 7963 float material_density, float material_friction,
7474 { 7964 float material_restitution, float material_gravity_modifier)
7475 int remain = frames.Data.Length - idx; 7965 {
7966 ExtraPhysicsData physdata = new ExtraPhysicsData();
7967 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7968 physdata.Density = part.Density;
7969 physdata.Friction = part.Friction;
7970 physdata.Bounce = part.Restitution;
7971 physdata.GravitationModifier = part.GravityModifier;
7476 7972
7477 if (remain < elemLength) 7973 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7478 break; 7974 physdata.Density = material_density;
7975 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7976 physdata.Friction = material_friction;
7977 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7978 physdata.Bounce = material_restitution;
7979 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7980 physdata.GravitationModifier = material_gravity_modifier;
7479 7981
7480 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe(); 7982 part.UpdateExtraPhysics(physdata);
7481 frame.Position = null; 7983 }
7482 frame.Rotation = null;
7483 7984
7484 if ((data & KeyframeMotion.DataFormat.Translation) != 0) 7985 public void llSetPhysicsMaterial(int material_bits,
7485 { 7986 float material_gravity_modifier, float material_restitution,
7486 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++); 7987 float material_friction, float material_density)
7487 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z); 7988 {
7488 } 7989 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7489 if ((data & KeyframeMotion.DataFormat.Rotation) != 0) 7990 }
7490 {
7491 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7492 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7493 q.Normalize();
7494 frame.Rotation = q;
7495 }
7496 7991
7497 float tempf = (float)frames.GetLSLFloatItem(idx++); 7992 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7498 frame.TimeMS = (int)(tempf * 1000.0f); 7993 {
7994 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7995 llSetLinkPrimitiveParamsFast(linknumber, rules);
7996 ScriptSleep(200);
7997 }
7499 7998
7500 keyframes.Add(frame); 7999 // vector up using libomv (c&p from sop )
7501 } 8000 // vector up rotated by r
8001 private Vector3 Zrot(Quaternion r)
8002 {
8003 double x, y, z, m;
7502 8004
7503 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray()); 8005 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7504 group.RootPart.KeyframeMotion.Start(); 8006 if (Math.Abs(1.0 - m) > 0.000001)
7505 }
7506 else
7507 { 8007 {
7508 if (group.RootPart.KeyframeMotion == null) 8008 m = 1.0 / Math.Sqrt(m);
7509 return; 8009 r.X *= (float)m;
7510 8010 r.Y *= (float)m;
7511 if (options.Data.Length == 0) 8011 r.Z *= (float)m;
7512 { 8012 r.W *= (float)m;
7513 group.RootPart.KeyframeMotion.Stop(); 8013 }
7514 return;
7515 }
7516
7517 int idx = 0;
7518 8014
7519 while (idx < options.Data.Length) 8015 x = 2 * (r.X * r.Z + r.Y * r.W);
7520 { 8016 y = 2 * (-r.X * r.W + r.Y * r.Z);
7521 int option = (int)options.GetLSLIntegerItem(idx++); 8017 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7522 8018
7523 switch (option) 8019 return new Vector3((float)x, (float)y, (float)z);
7524 {
7525 case ScriptBaseClass.KFM_COMMAND:
7526 int cmd = (int)options.GetLSLIntegerItem(idx++);
7527 switch (cmd)
7528 {
7529 case ScriptBaseClass.KFM_CMD_PLAY:
7530 group.RootPart.KeyframeMotion.Start();
7531 break;
7532 case ScriptBaseClass.KFM_CMD_STOP:
7533 group.RootPart.KeyframeMotion.Stop();
7534 break;
7535 case ScriptBaseClass.KFM_CMD_PAUSE:
7536 group.RootPart.KeyframeMotion.Pause();
7537 break;
7538 }
7539 break;
7540 }
7541 }
7542 }
7543 } 8020 }
7544 8021
7545 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 8022 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7546 { 8023 {
8024 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
8025 return null;
8026
7547 int idx = 0; 8027 int idx = 0;
7548 int idxStart = 0; 8028 int idxStart = 0;
7549 8029
8030 SceneObjectGroup parentgrp = part.ParentGroup;
8031
7550 bool positionChanged = false; 8032 bool positionChanged = false;
7551 LSL_Vector currentPosition = GetPartLocalPos(part); 8033 LSL_Vector currentPosition = GetPartLocalPos(part);
7552 8034
@@ -7571,8 +8053,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7571 return null; 8053 return null;
7572 8054
7573 v=rules.GetVector3Item(idx++); 8055 v=rules.GetVector3Item(idx++);
8056 if (part.IsRoot && !part.ParentGroup.IsAttachment)
8057 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
8058 else
8059 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7574 positionChanged = true; 8060 positionChanged = true;
7575 currentPosition = GetSetPosTarget(part, v, currentPosition);
7576 8061
7577 break; 8062 break;
7578 case (int)ScriptBaseClass.PRIM_SIZE: 8063 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7589,7 +8074,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7589 8074
7590 LSL_Rotation q = rules.GetQuaternionItem(idx++); 8075 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7591 // try to let this work as in SL... 8076 // try to let this work as in SL...
7592 if (part.ParentID == 0) 8077 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7593 { 8078 {
7594 // special case: If we are root, rotate complete SOG to new rotation 8079 // special case: If we are root, rotate complete SOG to new rotation
7595 SetRot(part, q); 8080 SetRot(part, q);
@@ -7883,6 +8368,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7883 8368
7884 break; 8369 break;
7885 8370
8371 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8372 if (remain < 5)
8373 return null;
8374
8375 int material_bits = rules.GetLSLIntegerItem(idx++);
8376 float material_density = (float)rules.GetLSLFloatItem(idx++);
8377 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8378 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8379 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8380
8381 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8382
8383 break;
8384
7886 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8385 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7887 if (remain < 1) 8386 if (remain < 1)
7888 return null; 8387 return null;
@@ -7962,14 +8461,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7962 if (part.ParentGroup.RootPart == part) 8461 if (part.ParentGroup.RootPart == part)
7963 { 8462 {
7964 SceneObjectGroup parent = part.ParentGroup; 8463 SceneObjectGroup parent = part.ParentGroup;
7965 parent.UpdateGroupPosition(currentPosition); 8464 Util.FireAndForget(delegate(object x) {
8465 parent.UpdateGroupPosition(currentPosition);
8466 });
7966 } 8467 }
7967 else 8468 else
7968 { 8469 {
7969 part.OffsetPosition = currentPosition; 8470 part.OffsetPosition = currentPosition;
7970 SceneObjectGroup parent = part.ParentGroup; 8471// SceneObjectGroup parent = part.ParentGroup;
7971 parent.HasGroupChanged = true; 8472// parent.HasGroupChanged = true;
7972 parent.ScheduleGroupForTerseUpdate(); 8473// parent.ScheduleGroupForTerseUpdate();
8474 part.ScheduleTerseUpdate();
7973 } 8475 }
7974 } 8476 }
7975 } 8477 }
@@ -8007,10 +8509,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8007 8509
8008 public LSL_String llXorBase64Strings(string str1, string str2) 8510 public LSL_String llXorBase64Strings(string str1, string str2)
8009 { 8511 {
8010 m_host.AddScriptLPS(1); 8512 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
8011 Deprecated("llXorBase64Strings"); 8513
8012 ScriptSleep(300); 8514 ScriptSleep(300);
8013 return String.Empty; 8515 m_host.AddScriptLPS(1);
8516
8517 if (str1 == String.Empty)
8518 return String.Empty;
8519 if (str2 == String.Empty)
8520 return str1;
8521
8522 int len = str2.Length;
8523 if ((len % 4) != 0) // LL is EVIL!!!!
8524 {
8525 while (str2.EndsWith("="))
8526 str2 = str2.Substring(0, str2.Length - 1);
8527
8528 len = str2.Length;
8529 int mod = len % 4;
8530
8531 if (mod == 1)
8532 str2 = str2.Substring(0, str2.Length - 1);
8533 else if (mod == 2)
8534 str2 += "==";
8535 else if (mod == 3)
8536 str2 += "=";
8537 }
8538
8539 byte[] data1;
8540 byte[] data2;
8541 try
8542 {
8543 data1 = Convert.FromBase64String(str1);
8544 data2 = Convert.FromBase64String(str2);
8545 }
8546 catch (Exception)
8547 {
8548 return new LSL_String(String.Empty);
8549 }
8550
8551 // For cases where the decoded length of s2 is greater
8552 // than the decoded length of s1, simply perform a normal
8553 // decode and XOR
8554 //
8555 if (data2.Length >= data1.Length)
8556 {
8557 for (int pos = 0 ; pos < data1.Length ; pos++ )
8558 data1[pos] ^= data2[pos];
8559
8560 return Convert.ToBase64String(data1);
8561 }
8562
8563 // Remove padding
8564 while (str1.EndsWith("="))
8565 str1 = str1.Substring(0, str1.Length - 1);
8566 while (str2.EndsWith("="))
8567 str2 = str2.Substring(0, str2.Length - 1);
8568
8569 byte[] d1 = new byte[str1.Length];
8570 byte[] d2 = new byte[str2.Length];
8571
8572 for (int i = 0 ; i < str1.Length ; i++)
8573 {
8574 int idx = b64.IndexOf(str1.Substring(i, 1));
8575 if (idx == -1)
8576 idx = 0;
8577 d1[i] = (byte)idx;
8578 }
8579
8580 for (int i = 0 ; i < str2.Length ; i++)
8581 {
8582 int idx = b64.IndexOf(str2.Substring(i, 1));
8583 if (idx == -1)
8584 idx = 0;
8585 d2[i] = (byte)idx;
8586 }
8587
8588 string output = String.Empty;
8589
8590 for (int pos = 0 ; pos < d1.Length ; pos++)
8591 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8592
8593 while (output.Length % 3 > 0)
8594 output += "=";
8595
8596 return output;
8014 } 8597 }
8015 8598
8016 public void llRemoteDataSetRegion() 8599 public void llRemoteDataSetRegion()
@@ -8135,8 +8718,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8135 public LSL_Integer llGetNumberOfPrims() 8718 public LSL_Integer llGetNumberOfPrims()
8136 { 8719 {
8137 m_host.AddScriptLPS(1); 8720 m_host.AddScriptLPS(1);
8138 8721 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
8139 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8722
8723 return m_host.ParentGroup.PrimCount + avatarCount;
8140 } 8724 }
8141 8725
8142 /// <summary> 8726 /// <summary>
@@ -8151,55 +8735,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8151 m_host.AddScriptLPS(1); 8735 m_host.AddScriptLPS(1);
8152 UUID objID = UUID.Zero; 8736 UUID objID = UUID.Zero;
8153 LSL_List result = new LSL_List(); 8737 LSL_List result = new LSL_List();
8738
8739 // If the ID is not valid, return null result
8154 if (!UUID.TryParse(obj, out objID)) 8740 if (!UUID.TryParse(obj, out objID))
8155 { 8741 {
8156 result.Add(new LSL_Vector()); 8742 result.Add(new LSL_Vector());
8157 result.Add(new LSL_Vector()); 8743 result.Add(new LSL_Vector());
8158 return result; 8744 return result;
8159 } 8745 }
8746
8747 // Check if this is an attached prim. If so, replace
8748 // the UUID with the avatar UUID and report it's bounding box
8749 SceneObjectPart part = World.GetSceneObjectPart(objID);
8750 if (part != null && part.ParentGroup.IsAttachment)
8751 objID = part.ParentGroup.AttachedAvatar;
8752
8753 // Find out if this is an avatar ID. If so, return it's box
8160 ScenePresence presence = World.GetScenePresence(objID); 8754 ScenePresence presence = World.GetScenePresence(objID);
8161 if (presence != null) 8755 if (presence != null)
8162 { 8756 {
8163 if (presence.ParentID == 0) // not sat on an object 8757 // As per LSL Wiki, there is no difference between sitting
8758 // and standing avatar since server 1.36
8759 LSL_Vector lower;
8760 LSL_Vector upper;
8761
8762 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8763
8764 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8765 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8766/*
8164 { 8767 {
8165 LSL_Vector lower; 8768 // This is for ground sitting avatars
8166 LSL_Vector upper; 8769 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8167 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8770 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8168 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8771 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8169 {
8170 // This is for ground sitting avatars
8171 float height = presence.Appearance.AvatarHeight / 2.66666667f;
8172 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
8173 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
8174 }
8175 else
8176 {
8177 // This is for standing/flying avatars
8178 float height = presence.Appearance.AvatarHeight / 2.0f;
8179 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8180 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8181 }
8182 result.Add(lower);
8183 result.Add(upper);
8184 return result;
8185 } 8772 }
8186 else 8773 else
8187 { 8774 {
8188 // sitting on an object so we need the bounding box of that 8775 // This is for standing/flying avatars
8189 // which should include the avatar so set the UUID to the 8776 float height = presence.Appearance.AvatarHeight / 2.0f;
8190 // UUID of the object the avatar is sat on and allow it to fall through 8777 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
8191 // to processing an object 8778 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
8192 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
8193 objID = p.UUID;
8194 } 8779 }
8780
8781 // Adjust to the documented error offsets (see LSL Wiki)
8782 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8783 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8784*/
8785 {
8786 // This is for ground sitting avatars TODO!
8787 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8788 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8789 }
8790 else
8791 {
8792 // This is for standing/flying avatars
8793 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8794 upper = new LSL_Vector(box.X, box.Y, box.Z);
8795 }
8796
8797 if (lower.x > upper.x)
8798 lower.x = upper.x;
8799 if (lower.y > upper.y)
8800 lower.y = upper.y;
8801 if (lower.z > upper.z)
8802 lower.z = upper.z;
8803
8804 result.Add(lower);
8805 result.Add(upper);
8806 return result;
8195 } 8807 }
8196 SceneObjectPart part = World.GetSceneObjectPart(objID); 8808
8809 part = World.GetSceneObjectPart(objID);
8197 // Currently only works for single prims without a sitting avatar 8810 // Currently only works for single prims without a sitting avatar
8198 if (part != null) 8811 if (part != null)
8199 { 8812 {
8200 Vector3 halfSize = part.Scale / 2.0f; 8813 float minX;
8201 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8814 float maxX;
8202 LSL_Vector upper = new LSL_Vector(halfSize); 8815 float minY;
8816 float maxY;
8817 float minZ;
8818 float maxZ;
8819
8820 // This BBox is in sim coordinates, with the offset being
8821 // a contained point.
8822 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8823 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8824
8825 minX -= offsets[0].X;
8826 maxX -= offsets[0].X;
8827 minY -= offsets[0].Y;
8828 maxY -= offsets[0].Y;
8829 minZ -= offsets[0].Z;
8830 maxZ -= offsets[0].Z;
8831
8832 LSL_Vector lower;
8833 LSL_Vector upper;
8834
8835 // Adjust to the documented error offsets (see LSL Wiki)
8836 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8837 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8838
8839 if (lower.x > upper.x)
8840 lower.x = upper.x;
8841 if (lower.y > upper.y)
8842 lower.y = upper.y;
8843 if (lower.z > upper.z)
8844 lower.z = upper.z;
8845
8203 result.Add(lower); 8846 result.Add(lower);
8204 result.Add(upper); 8847 result.Add(upper);
8205 return result; 8848 return result;
@@ -8216,227 +8859,70 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8216 return new LSL_Vector(m_host.GetGeometricCenter()); 8859 return new LSL_Vector(m_host.GetGeometricCenter());
8217 } 8860 }
8218 8861
8219 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8862 public LSL_List llGetPrimitiveParams(LSL_List rules)
8220 { 8863 {
8221 LSL_List result = new LSL_List(); 8864 m_host.AddScriptLPS(1);
8222 LSL_List remaining = null;
8223
8224 while (true)
8225 {
8226// m_log.DebugFormat(
8227// "[LSL API]: GetEntityParams has {0} rules with scene entity named {1}",
8228// rules.Length, entity != null ? entity.Name : "NULL");
8229
8230 if (entity == null)
8231 return result;
8232 8865
8233 if (entity is SceneObjectPart) 8866 LSL_List result = new LSL_List();
8234 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
8235 else
8236 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
8237 8867
8238 if (remaining == null || remaining.Length < 2) 8868 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
8239 return result;
8240 8869
8870 while ((object)remaining != null && remaining.Length > 2)
8871 {
8241 int linknumber = remaining.GetLSLIntegerItem(0); 8872 int linknumber = remaining.GetLSLIntegerItem(0);
8242 rules = remaining.GetSublist(1, -1); 8873 rules = remaining.GetSublist(1, -1);
8243 entity = GetLinkEntity(linknumber); 8874 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8244 }
8245 }
8246 8875
8247 public LSL_List llGetPrimitiveParams(LSL_List rules) 8876 foreach (SceneObjectPart part in parts)
8248 { 8877 remaining = GetPrimParams(part, rules, ref result);
8249 m_host.AddScriptLPS(1); 8878 }
8250 8879
8251 return GetEntityParams(m_host, rules); 8880 return result;
8252 } 8881 }
8253 8882
8254 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8883 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8255 { 8884 {
8256 m_host.AddScriptLPS(1); 8885 m_host.AddScriptLPS(1);
8257 8886
8258 return GetEntityParams(GetLinkEntity(linknumber), rules); 8887 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8259 } 8888 // keep other options as before
8260 8889
8261 public LSL_Vector GetAgentSize(ScenePresence sp) 8890 List<SceneObjectPart> parts;
8262 { 8891 List<ScenePresence> avatars;
8263 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8892
8264 } 8893 LSL_List res = new LSL_List();
8894 LSL_List remaining = null;
8265 8895
8266 /// <summary> 8896 while (rules.Length > 0)
8267 /// Gets params for a seated avatar in a linkset.
8268 /// </summary>
8269 /// <returns></returns>
8270 /// <param name='sp'></param>
8271 /// <param name='rules'></param>
8272 /// <param name='res'></param>
8273 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8274 {
8275 int idx = 0;
8276 while (idx < rules.Length)
8277 { 8897 {
8278 int code = (int)rules.GetLSLIntegerItem(idx++); 8898 parts = GetLinkParts(linknumber);
8279 int remain = rules.Length-idx; 8899 avatars = GetLinkAvatars(linknumber);
8280 8900
8281 switch (code) 8901 remaining = null;
8902 foreach (SceneObjectPart part in parts)
8282 { 8903 {
8283 case (int)ScriptBaseClass.PRIM_MATERIAL: 8904 remaining = GetPrimParams(part, rules, ref res);
8284 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8905 }
8285 break; 8906 foreach (ScenePresence avatar in avatars)
8286 8907 {
8287 case (int)ScriptBaseClass.PRIM_PHYSICS: 8908 remaining = GetPrimParams(avatar, rules, ref res);
8288 res.Add(ScriptBaseClass.FALSE); 8909 }
8289 break;
8290
8291 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8292 res.Add(ScriptBaseClass.FALSE);
8293 break;
8294
8295 case (int)ScriptBaseClass.PRIM_PHANTOM:
8296 res.Add(ScriptBaseClass.FALSE);
8297 break;
8298
8299 case (int)ScriptBaseClass.PRIM_POSITION:
8300 res.Add(new LSL_Vector(sp.AbsolutePosition));
8301 break;
8302
8303 case (int)ScriptBaseClass.PRIM_SIZE:
8304 res.Add(GetAgentSize(sp));
8305 break;
8306
8307 case (int)ScriptBaseClass.PRIM_ROTATION:
8308 res.Add(sp.GetWorldRotation());
8309 break;
8310
8311 case (int)ScriptBaseClass.PRIM_TYPE:
8312 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8313 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8314 res.Add(new LSL_Vector(0, 1, 0));
8315 res.Add(new LSL_Float(0));
8316 res.Add(new LSL_Vector(0, 0, 0));
8317 res.Add(new LSL_Vector(1, 1, 0));
8318 res.Add(new LSL_Vector(0, 0, 0));
8319 break;
8320
8321 case (int)ScriptBaseClass.PRIM_TEXTURE:
8322 if (remain < 1)
8323 return null;
8324
8325 int face = (int)rules.GetLSLIntegerItem(idx++);
8326 if (face > 21)
8327 break;
8328
8329 res.Add(new LSL_String(""));
8330 res.Add(ScriptBaseClass.ZERO_VECTOR);
8331 res.Add(ScriptBaseClass.ZERO_VECTOR);
8332 res.Add(new LSL_Float(0));
8333 break;
8334
8335 case (int)ScriptBaseClass.PRIM_COLOR:
8336 if (remain < 1)
8337 return null;
8338
8339 face = (int)rules.GetLSLIntegerItem(idx++);
8340 if (face > 21)
8341 break;
8342
8343 res.Add(ScriptBaseClass.ZERO_VECTOR);
8344 res.Add(new LSL_Float(0));
8345 break;
8346
8347 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
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_SHINY_NONE);
8356 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8357 break;
8358
8359 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8360 if (remain < 1)
8361 return null;
8362
8363 face = (int)rules.GetLSLIntegerItem(idx++);
8364 if (face > 21)
8365 break;
8366
8367 res.Add(ScriptBaseClass.FALSE);
8368 break;
8369
8370 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8371 res.Add(ScriptBaseClass.FALSE);
8372 res.Add(new LSL_Integer(0));
8373 res.Add(new LSL_Float(0));
8374 res.Add(new LSL_Float(0));
8375 res.Add(new LSL_Float(0));
8376 res.Add(new LSL_Float(0));
8377 res.Add(ScriptBaseClass.ZERO_VECTOR);
8378 break;
8379
8380 case (int)ScriptBaseClass.PRIM_TEXGEN:
8381 if (remain < 1)
8382 return null;
8383
8384 face = (int)rules.GetLSLIntegerItem(idx++);
8385 if (face > 21)
8386 break;
8387
8388 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8389 break;
8390
8391 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8392 res.Add(ScriptBaseClass.FALSE);
8393 res.Add(ScriptBaseClass.ZERO_VECTOR);
8394 res.Add(ScriptBaseClass.ZERO_VECTOR);
8395 break;
8396
8397 case (int)ScriptBaseClass.PRIM_GLOW:
8398 if (remain < 1)
8399 return null;
8400
8401 face = (int)rules.GetLSLIntegerItem(idx++);
8402 if (face > 21)
8403 break;
8404
8405 res.Add(new LSL_Float(0));
8406 break;
8407
8408 case (int)ScriptBaseClass.PRIM_TEXT:
8409 res.Add(new LSL_String(""));
8410 res.Add(ScriptBaseClass.ZERO_VECTOR);
8411 res.Add(new LSL_Float(1));
8412 break;
8413
8414 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8415 res.Add(new LSL_Rotation(sp.Rotation));
8416 break;
8417
8418 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8419 res.Add(new LSL_Vector(sp.OffsetPosition));
8420 break;
8421
8422 case (int)ScriptBaseClass.PRIM_SLICE:
8423 res.Add(new LSL_Vector(0, 1, 0));
8424 break;
8425
8426 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8427 if(remain < 3)
8428 return null;
8429 8910
8430 return rules.GetSublist(idx, -1); 8911 if ((object)remaining != null && remaining.Length > 0)
8912 {
8913 linknumber = remaining.GetLSLIntegerItem(0);
8914 rules = remaining.GetSublist(1, -1);
8431 } 8915 }
8916 else
8917 break;
8432 } 8918 }
8433 8919
8434 return null; 8920 return res;
8435 } 8921 }
8436 8922
8437 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8923 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8438 { 8924 {
8439 int idx = 0; 8925 int idx=0;
8440 while (idx < rules.Length) 8926 while (idx < rules.Length)
8441 { 8927 {
8442 int code = (int)rules.GetLSLIntegerItem(idx++); 8928 int code = (int)rules.GetLSLIntegerItem(idx++);
@@ -8470,19 +8956,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8470 break; 8956 break;
8471 8957
8472 case (int)ScriptBaseClass.PRIM_POSITION: 8958 case (int)ScriptBaseClass.PRIM_POSITION:
8473 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8959 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8474 8960 part.AbsolutePosition.Y,
8475 // For some reason, the part.AbsolutePosition.* values do not change if the 8961 part.AbsolutePosition.Z);
8476 // linkset is rotated; they always reflect the child prim's world position
8477 // as though the linkset is unrotated. This is incompatible behavior with SL's
8478 // implementation, so will break scripts imported from there (not to mention it
8479 // makes it more difficult to determine a child prim's actual inworld position).
8480 if (!part.IsRoot)
8481 {
8482 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8483 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8484 }
8485
8486 res.Add(v); 8962 res.Add(v);
8487 break; 8963 break;
8488 8964
@@ -8652,30 +9128,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8652 if (remain < 1) 9128 if (remain < 1)
8653 return null; 9129 return null;
8654 9130
8655 face=(int)rules.GetLSLIntegerItem(idx++); 9131 face = (int)rules.GetLSLIntegerItem(idx++);
8656 9132
8657 tex = part.Shape.Textures; 9133 tex = part.Shape.Textures;
9134 int shiny;
8658 if (face == ScriptBaseClass.ALL_SIDES) 9135 if (face == ScriptBaseClass.ALL_SIDES)
8659 { 9136 {
8660 for (face = 0; face < GetNumberOfSides(part); face++) 9137 for (face = 0; face < GetNumberOfSides(part); face++)
8661 { 9138 {
8662 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9139 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8663 // Convert Shininess to PRIM_SHINY_* 9140 if (shinyness == Shininess.High)
8664 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9141 {
8665 // PRIM_BUMP_* 9142 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8666 res.Add(new LSL_Integer((int)texface.Bump)); 9143 }
9144 else if (shinyness == Shininess.Medium)
9145 {
9146 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9147 }
9148 else if (shinyness == Shininess.Low)
9149 {
9150 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9151 }
9152 else
9153 {
9154 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9155 }
9156 res.Add(new LSL_Integer(shiny));
9157 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8667 } 9158 }
8668 } 9159 }
8669 else 9160 else
8670 { 9161 {
8671 if (face >= 0 && face < GetNumberOfSides(part)) 9162 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9163 if (shinyness == Shininess.High)
8672 { 9164 {
8673 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9165 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8674 // Convert Shininess to PRIM_SHINY_*
8675 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8676 // PRIM_BUMP_*
8677 res.Add(new LSL_Integer((int)texface.Bump));
8678 } 9166 }
9167 else if (shinyness == Shininess.Medium)
9168 {
9169 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9170 }
9171 else if (shinyness == Shininess.Low)
9172 {
9173 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9174 }
9175 else
9176 {
9177 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9178 }
9179 res.Add(new LSL_Integer(shiny));
9180 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8679 } 9181 }
8680 break; 9182 break;
8681 9183
@@ -8686,21 +9188,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8686 face = (int)rules.GetLSLIntegerItem(idx++); 9188 face = (int)rules.GetLSLIntegerItem(idx++);
8687 9189
8688 tex = part.Shape.Textures; 9190 tex = part.Shape.Textures;
9191 int fullbright;
8689 if (face == ScriptBaseClass.ALL_SIDES) 9192 if (face == ScriptBaseClass.ALL_SIDES)
8690 { 9193 {
8691 for (face = 0; face < GetNumberOfSides(part); face++) 9194 for (face = 0; face < GetNumberOfSides(part); face++)
8692 { 9195 {
8693 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9196 if (tex.GetFace((uint)face).Fullbright == true)
8694 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9197 {
9198 fullbright = ScriptBaseClass.TRUE;
9199 }
9200 else
9201 {
9202 fullbright = ScriptBaseClass.FALSE;
9203 }
9204 res.Add(new LSL_Integer(fullbright));
8695 } 9205 }
8696 } 9206 }
8697 else 9207 else
8698 { 9208 {
8699 if (face >= 0 && face < GetNumberOfSides(part)) 9209 if (tex.GetFace((uint)face).Fullbright == true)
8700 { 9210 {
8701 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9211 fullbright = ScriptBaseClass.TRUE;
8702 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9212 }
9213 else
9214 {
9215 fullbright = ScriptBaseClass.FALSE;
8703 } 9216 }
9217 res.Add(new LSL_Integer(fullbright));
8704 } 9218 }
8705 break; 9219 break;
8706 9220
@@ -8722,27 +9236,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8722 break; 9236 break;
8723 9237
8724 case (int)ScriptBaseClass.PRIM_TEXGEN: 9238 case (int)ScriptBaseClass.PRIM_TEXGEN:
9239 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8725 if (remain < 1) 9240 if (remain < 1)
8726 return null; 9241 return null;
8727 9242
8728 face=(int)rules.GetLSLIntegerItem(idx++); 9243 face = (int)rules.GetLSLIntegerItem(idx++);
8729 9244
8730 tex = part.Shape.Textures; 9245 tex = part.Shape.Textures;
8731 if (face == ScriptBaseClass.ALL_SIDES) 9246 if (face == ScriptBaseClass.ALL_SIDES)
8732 { 9247 {
8733 for (face = 0; face < GetNumberOfSides(part); face++) 9248 for (face = 0; face < GetNumberOfSides(part); face++)
8734 { 9249 {
8735 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9250 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8736 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9251 {
8737 res.Add(new LSL_Integer((uint)texgen >> 1)); 9252 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9253 }
9254 else
9255 {
9256 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9257 }
8738 } 9258 }
8739 } 9259 }
8740 else 9260 else
8741 { 9261 {
8742 if (face >= 0 && face < GetNumberOfSides(part)) 9262 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9263 {
9264 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9265 }
9266 else
8743 { 9267 {
8744 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9268 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8745 res.Add(new LSL_Integer((uint)texgen >> 1));
8746 } 9269 }
8747 } 9270 }
8748 break; 9271 break;
@@ -8766,24 +9289,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8766 if (remain < 1) 9289 if (remain < 1)
8767 return null; 9290 return null;
8768 9291
8769 face=(int)rules.GetLSLIntegerItem(idx++); 9292 face = (int)rules.GetLSLIntegerItem(idx++);
8770 9293
8771 tex = part.Shape.Textures; 9294 tex = part.Shape.Textures;
9295 float primglow;
8772 if (face == ScriptBaseClass.ALL_SIDES) 9296 if (face == ScriptBaseClass.ALL_SIDES)
8773 { 9297 {
8774 for (face = 0; face < GetNumberOfSides(part); face++) 9298 for (face = 0; face < GetNumberOfSides(part); face++)
8775 { 9299 {
8776 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9300 primglow = tex.GetFace((uint)face).Glow;
8777 res.Add(new LSL_Float(texface.Glow)); 9301 res.Add(new LSL_Float(primglow));
8778 } 9302 }
8779 } 9303 }
8780 else 9304 else
8781 { 9305 {
8782 if (face >= 0 && face < GetNumberOfSides(part)) 9306 primglow = tex.GetFace((uint)face).Glow;
8783 { 9307 res.Add(new LSL_Float(primglow));
8784 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8785 res.Add(new LSL_Float(texface.Glow));
8786 }
8787 } 9308 }
8788 break; 9309 break;
8789 9310
@@ -8795,15 +9316,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8795 textColor.B)); 9316 textColor.B));
8796 res.Add(new LSL_Float(textColor.A)); 9317 res.Add(new LSL_Float(textColor.A));
8797 break; 9318 break;
9319
8798 case (int)ScriptBaseClass.PRIM_NAME: 9320 case (int)ScriptBaseClass.PRIM_NAME:
8799 res.Add(new LSL_String(part.Name)); 9321 res.Add(new LSL_String(part.Name));
8800 break; 9322 break;
9323
8801 case (int)ScriptBaseClass.PRIM_DESC: 9324 case (int)ScriptBaseClass.PRIM_DESC:
8802 res.Add(new LSL_String(part.Description)); 9325 res.Add(new LSL_String(part.Description));
8803 break; 9326 break;
8804 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9327 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8805 res.Add(new LSL_Rotation(part.RotationOffset)); 9328 res.Add(new LSL_Rotation(part.RotationOffset));
8806 break; 9329 break;
9330
8807 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9331 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8808 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9332 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8809 break; 9333 break;
@@ -9416,8 +9940,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9416 // The function returns an ordered list 9940 // The function returns an ordered list
9417 // representing the tokens found in the supplied 9941 // representing the tokens found in the supplied
9418 // sources string. If two successive tokenizers 9942 // sources string. If two successive tokenizers
9419 // are encountered, then a NULL entry is added 9943 // are encountered, then a null-string entry is
9420 // to the list. 9944 // added to the list.
9421 // 9945 //
9422 // It is a precondition that the source and 9946 // It is a precondition that the source and
9423 // toekizer lisst are non-null. If they are null, 9947 // toekizer lisst are non-null. If they are null,
@@ -9425,7 +9949,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9425 // while their lengths are being determined. 9949 // while their lengths are being determined.
9426 // 9950 //
9427 // A small amount of working memoryis required 9951 // A small amount of working memoryis required
9428 // of approximately 8*#tokenizers. 9952 // of approximately 8*#tokenizers + 8*srcstrlen.
9429 // 9953 //
9430 // There are many ways in which this function 9954 // There are many ways in which this function
9431 // can be implemented, this implementation is 9955 // can be implemented, this implementation is
@@ -9441,155 +9965,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9441 // and eliminates redundant tokenizers as soon 9965 // and eliminates redundant tokenizers as soon
9442 // as is possible. 9966 // as is possible.
9443 // 9967 //
9444 // The implementation tries to avoid any copying 9968 // The implementation tries to minimize temporary
9445 // of arrays or other objects. 9969 // garbage generation.
9446 // </remarks> 9970 // </remarks>
9447 9971
9448 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9972 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9449 { 9973 {
9450 int beginning = 0; 9974 return ParseString2List(src, separators, spacers, true);
9451 int srclen = src.Length; 9975 }
9452 int seplen = separators.Length;
9453 object[] separray = separators.Data;
9454 int spclen = spacers.Length;
9455 object[] spcarray = spacers.Data;
9456 int mlen = seplen+spclen;
9457
9458 int[] offset = new int[mlen+1];
9459 bool[] active = new bool[mlen];
9460
9461 int best;
9462 int j;
9463
9464 // Initial capacity reduces resize cost
9465 9976
9466 LSL_List tokens = new LSL_List(); 9977 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9978 {
9979 int srclen = src.Length;
9980 int seplen = separators.Length;
9981 object[] separray = separators.Data;
9982 int spclen = spacers.Length;
9983 object[] spcarray = spacers.Data;
9984 int dellen = 0;
9985 string[] delarray = new string[seplen+spclen];
9467 9986
9468 // All entries are initially valid 9987 int outlen = 0;
9988 string[] outarray = new string[srclen*2+1];
9469 9989
9470 for (int i = 0; i < mlen; i++) 9990 int i, j;
9471 active[i] = true; 9991 string d;
9472 9992
9473 offset[mlen] = srclen; 9993 m_host.AddScriptLPS(1);
9474 9994
9475 while (beginning < srclen) 9995 /*
9996 * Convert separator and spacer lists to C# strings.
9997 * Also filter out null strings so we don't hang.
9998 */
9999 for (i = 0; i < seplen; i ++)
9476 { 10000 {
10001 d = separray[i].ToString();
10002 if (d.Length > 0)
10003 {
10004 delarray[dellen++] = d;
10005 }
10006 }
10007 seplen = dellen;
9477 10008
9478 best = mlen; // as bad as it gets 10009 for (i = 0; i < spclen; i ++)
10010 {
10011 d = spcarray[i].ToString();
10012 if (d.Length > 0)
10013 {
10014 delarray[dellen++] = d;
10015 }
10016 }
9479 10017
9480 // Scan for separators 10018 /*
10019 * Scan through source string from beginning to end.
10020 */
10021 for (i = 0;;)
10022 {
9481 10023
9482 for (j = 0; j < seplen; j++) 10024 /*
10025 * Find earliest delimeter in src starting at i (if any).
10026 */
10027 int earliestDel = -1;
10028 int earliestSrc = srclen;
10029 string earliestStr = null;
10030 for (j = 0; j < dellen; j ++)
9483 { 10031 {
9484 if (separray[j].ToString() == String.Empty) 10032 d = delarray[j];
9485 active[j] = false; 10033 if (d != null)
9486
9487 if (active[j])
9488 { 10034 {
9489 // scan all of the markers 10035 int index = src.IndexOf(d, i);
9490 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10036 if (index < 0)
9491 { 10037 {
9492 // not present at all 10038 delarray[j] = null; // delim nowhere in src, don't check it anymore
9493 active[j] = false;
9494 } 10039 }
9495 else 10040 else if (index < earliestSrc)
9496 { 10041 {
9497 // present and correct 10042 earliestSrc = index; // where delimeter starts in source string
9498 if (offset[j] < offset[best]) 10043 earliestDel = j; // where delimeter is in delarray[]
9499 { 10044 earliestStr = d; // the delimeter string from delarray[]
9500 // closest so far 10045 if (index == i) break; // can't do any better than found at beg of string
9501 best = j;
9502 if (offset[best] == beginning)
9503 break;
9504 }
9505 } 10046 }
9506 } 10047 }
9507 } 10048 }
9508 10049
9509 // Scan for spacers 10050 /*
9510 10051 * Output source string starting at i through start of earliest delimeter.
9511 if (offset[best] != beginning) 10052 */
10053 if (keepNulls || (earliestSrc > i))
9512 { 10054 {
9513 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10055 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9514 {
9515 if (spcarray[j-seplen].ToString() == String.Empty)
9516 active[j] = false;
9517
9518 if (active[j])
9519 {
9520 // scan all of the markers
9521 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9522 {
9523 // not present at all
9524 active[j] = false;
9525 }
9526 else
9527 {
9528 // present and correct
9529 if (offset[j] < offset[best])
9530 {
9531 // closest so far
9532 best = j;
9533 }
9534 }
9535 }
9536 }
9537 } 10056 }
9538 10057
9539 // This is the normal exit from the scanning loop 10058 /*
10059 * If no delimeter found at or after i, we're done scanning.
10060 */
10061 if (earliestDel < 0) break;
9540 10062
9541 if (best == mlen) 10063 /*
10064 * If delimeter was a spacer, output the spacer.
10065 */
10066 if (earliestDel >= seplen)
9542 { 10067 {
9543 // no markers were found on this pass 10068 outarray[outlen++] = earliestStr;
9544 // so we're pretty much done
9545 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9546 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9547 break;
9548 } 10069 }
9549 10070
9550 // Otherwise we just add the newly delimited token 10071 /*
9551 // and recalculate where the search should continue. 10072 * Look at rest of src string following delimeter.
9552 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10073 */
9553 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10074 i = earliestSrc + earliestStr.Length;
9554
9555 if (best < seplen)
9556 {
9557 beginning = offset[best] + (separray[best].ToString()).Length;
9558 }
9559 else
9560 {
9561 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9562 string str = spcarray[best - seplen].ToString();
9563 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9564 tokens.Add(new LSL_String(str));
9565 }
9566 } 10075 }
9567 10076
9568 // This an awkward an not very intuitive boundary case. If the 10077 /*
9569 // last substring is a tokenizer, then there is an implied trailing 10078 * Make up an exact-sized output array suitable for an LSL_List object.
9570 // null list entry. Hopefully the single comparison will not be too 10079 */
9571 // arduous. Alternatively the 'break' could be replced with a return 10080 object[] outlist = new object[outlen];
9572 // but that's shabby programming. 10081 for (i = 0; i < outlen; i ++)
9573
9574 if ((beginning == srclen) && (keepNulls))
9575 { 10082 {
9576 if (srclen != 0) 10083 outlist[i] = new LSL_String(outarray[i]);
9577 tokens.Add(new LSL_String(""));
9578 } 10084 }
9579 10085 return new LSL_List(outlist);
9580 return tokens;
9581 }
9582
9583 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9584 {
9585 m_host.AddScriptLPS(1);
9586 return this.ParseString(src, separators, spacers, false);
9587 }
9588
9589 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9590 {
9591 m_host.AddScriptLPS(1);
9592 return this.ParseString(src, separators, spacers, true);
9593 } 10086 }
9594 10087
9595 public LSL_Integer llGetObjectPermMask(int mask) 10088 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9684,6 +10177,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9684 case 4: 10177 case 4:
9685 return (int)item.NextPermissions; 10178 return (int)item.NextPermissions;
9686 } 10179 }
10180 m_host.TaskInventory.LockItemsForRead(false);
9687 10181
9688 return -1; 10182 return -1;
9689 } 10183 }
@@ -9887,31 +10381,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9887 UUID key = new UUID(); 10381 UUID key = new UUID();
9888 if (UUID.TryParse(id, out key)) 10382 if (UUID.TryParse(id, out key))
9889 { 10383 {
9890 try 10384 // return total object mass
9891 { 10385 SceneObjectPart part = World.GetSceneObjectPart(key);
9892 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10386 if (part != null)
9893 if (obj != null) 10387 return part.ParentGroup.GetMass();
9894 return (double)obj.GetMass(); 10388
9895 // the object is null so the key is for an avatar 10389 // the object is null so the key is for an avatar
9896 ScenePresence avatar = World.GetScenePresence(key); 10390 ScenePresence avatar = World.GetScenePresence(key);
9897 if (avatar != null) 10391 if (avatar != null)
9898 if (avatar.IsChildAgent)
9899 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9900 // child agents have a mass of 1.0
9901 return 1;
9902 else
9903 return (double)avatar.GetMass();
9904 }
9905 catch (KeyNotFoundException)
9906 { 10392 {
9907 return 0; // The Object/Agent not in the region so just return zero 10393 if (avatar.IsChildAgent)
10394 {
10395 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10396 // child agents have a mass of 1.0
10397 return 1;
10398 }
10399 else
10400 {
10401 return (double)avatar.GetMass();
10402 }
9908 } 10403 }
9909 } 10404 }
9910 return 0; 10405 return 0;
9911 } 10406 }
9912 10407
9913 /// <summary> 10408 /// <summary>
9914 /// illListReplaceList removes the sub-list defined by the inclusive indices 10409 /// llListReplaceList removes the sub-list defined by the inclusive indices
9915 /// start and end and inserts the src list in its place. The inclusive 10410 /// start and end and inserts the src list in its place. The inclusive
9916 /// nature of the indices means that at least one element must be deleted 10411 /// nature of the indices means that at least one element must be deleted
9917 /// if the indices are within the bounds of the existing list. I.e. 2,2 10412 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9968,16 +10463,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9968 // based upon end. Note that if end exceeds the upper 10463 // based upon end. Note that if end exceeds the upper
9969 // bound in this case, the entire destination list 10464 // bound in this case, the entire destination list
9970 // is removed. 10465 // is removed.
9971 else 10466 else if (start == 0)
9972 { 10467 {
9973 if (end + 1 < dest.Length) 10468 if (end + 1 < dest.Length)
9974 {
9975 return src + dest.GetSublist(end + 1, -1); 10469 return src + dest.GetSublist(end + 1, -1);
9976 }
9977 else 10470 else
9978 {
9979 return src; 10471 return src;
9980 } 10472 }
10473 else // Start < 0
10474 {
10475 if (end + 1 < dest.Length)
10476 return dest.GetSublist(end + 1, -1);
10477 else
10478 return new LSL_List();
9981 } 10479 }
9982 } 10480 }
9983 // Finally, if start > end, we strip away a prefix and 10481 // Finally, if start > end, we strip away a prefix and
@@ -10028,17 +10526,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10028 int width = 0; 10526 int width = 0;
10029 int height = 0; 10527 int height = 0;
10030 10528
10031 ParcelMediaCommandEnum? commandToSend = null; 10529 uint commandToSend = 0;
10032 float time = 0.0f; // default is from start 10530 float time = 0.0f; // default is from start
10033 10531
10034 ScenePresence presence = null; 10532 ScenePresence presence = null;
10035 10533
10036 for (int i = 0; i < commandList.Data.Length; i++) 10534 for (int i = 0; i < commandList.Data.Length; i++)
10037 { 10535 {
10038 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10536 uint command = (uint)(commandList.GetLSLIntegerItem(i));
10039 switch (command) 10537 switch (command)
10040 { 10538 {
10041 case ParcelMediaCommandEnum.Agent: 10539 case (uint)ParcelMediaCommandEnum.Agent:
10042 // we send only to one agent 10540 // we send only to one agent
10043 if ((i + 1) < commandList.Length) 10541 if ((i + 1) < commandList.Length)
10044 { 10542 {
@@ -10055,25 +10553,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10055 } 10553 }
10056 break; 10554 break;
10057 10555
10058 case ParcelMediaCommandEnum.Loop: 10556 case (uint)ParcelMediaCommandEnum.Loop:
10059 loop = 1; 10557 loop = 1;
10060 commandToSend = command; 10558 commandToSend = command;
10061 update = true; //need to send the media update packet to set looping 10559 update = true; //need to send the media update packet to set looping
10062 break; 10560 break;
10063 10561
10064 case ParcelMediaCommandEnum.Play: 10562 case (uint)ParcelMediaCommandEnum.Play:
10065 loop = 0; 10563 loop = 0;
10066 commandToSend = command; 10564 commandToSend = command;
10067 update = true; //need to send the media update packet to make sure it doesn't loop 10565 update = true; //need to send the media update packet to make sure it doesn't loop
10068 break; 10566 break;
10069 10567
10070 case ParcelMediaCommandEnum.Pause: 10568 case (uint)ParcelMediaCommandEnum.Pause:
10071 case ParcelMediaCommandEnum.Stop: 10569 case (uint)ParcelMediaCommandEnum.Stop:
10072 case ParcelMediaCommandEnum.Unload: 10570 case (uint)ParcelMediaCommandEnum.Unload:
10073 commandToSend = command; 10571 commandToSend = command;
10074 break; 10572 break;
10075 10573
10076 case ParcelMediaCommandEnum.Url: 10574 case (uint)ParcelMediaCommandEnum.Url:
10077 if ((i + 1) < commandList.Length) 10575 if ((i + 1) < commandList.Length)
10078 { 10576 {
10079 if (commandList.Data[i + 1] is LSL_String) 10577 if (commandList.Data[i + 1] is LSL_String)
@@ -10086,7 +10584,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10086 } 10584 }
10087 break; 10585 break;
10088 10586
10089 case ParcelMediaCommandEnum.Texture: 10587 case (uint)ParcelMediaCommandEnum.Texture:
10090 if ((i + 1) < commandList.Length) 10588 if ((i + 1) < commandList.Length)
10091 { 10589 {
10092 if (commandList.Data[i + 1] is LSL_String) 10590 if (commandList.Data[i + 1] is LSL_String)
@@ -10099,7 +10597,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10099 } 10597 }
10100 break; 10598 break;
10101 10599
10102 case ParcelMediaCommandEnum.Time: 10600 case (uint)ParcelMediaCommandEnum.Time:
10103 if ((i + 1) < commandList.Length) 10601 if ((i + 1) < commandList.Length)
10104 { 10602 {
10105 if (commandList.Data[i + 1] is LSL_Float) 10603 if (commandList.Data[i + 1] is LSL_Float)
@@ -10111,7 +10609,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10111 } 10609 }
10112 break; 10610 break;
10113 10611
10114 case ParcelMediaCommandEnum.AutoAlign: 10612 case (uint)ParcelMediaCommandEnum.AutoAlign:
10115 if ((i + 1) < commandList.Length) 10613 if ((i + 1) < commandList.Length)
10116 { 10614 {
10117 if (commandList.Data[i + 1] is LSL_Integer) 10615 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10125,7 +10623,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10125 } 10623 }
10126 break; 10624 break;
10127 10625
10128 case ParcelMediaCommandEnum.Type: 10626 case (uint)ParcelMediaCommandEnum.Type:
10129 if ((i + 1) < commandList.Length) 10627 if ((i + 1) < commandList.Length)
10130 { 10628 {
10131 if (commandList.Data[i + 1] is LSL_String) 10629 if (commandList.Data[i + 1] is LSL_String)
@@ -10138,7 +10636,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10138 } 10636 }
10139 break; 10637 break;
10140 10638
10141 case ParcelMediaCommandEnum.Desc: 10639 case (uint)ParcelMediaCommandEnum.Desc:
10142 if ((i + 1) < commandList.Length) 10640 if ((i + 1) < commandList.Length)
10143 { 10641 {
10144 if (commandList.Data[i + 1] is LSL_String) 10642 if (commandList.Data[i + 1] is LSL_String)
@@ -10151,7 +10649,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10151 } 10649 }
10152 break; 10650 break;
10153 10651
10154 case ParcelMediaCommandEnum.Size: 10652 case (uint)ParcelMediaCommandEnum.Size:
10155 if ((i + 2) < commandList.Length) 10653 if ((i + 2) < commandList.Length)
10156 { 10654 {
10157 if (commandList.Data[i + 1] is LSL_Integer) 10655 if (commandList.Data[i + 1] is LSL_Integer)
@@ -10221,7 +10719,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10221 } 10719 }
10222 } 10720 }
10223 10721
10224 if (commandToSend != null) 10722 if (commandToSend != 0)
10225 { 10723 {
10226 // the commandList contained a start/stop/... command, too 10724 // the commandList contained a start/stop/... command, too
10227 if (presence == null) 10725 if (presence == null)
@@ -10258,7 +10756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10258 10756
10259 if (aList.Data[i] != null) 10757 if (aList.Data[i] != null)
10260 { 10758 {
10261 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10759 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10262 { 10760 {
10263 case ParcelMediaCommandEnum.Url: 10761 case ParcelMediaCommandEnum.Url:
10264 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10762 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10315,15 +10813,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10315 10813
10316 if (quick_pay_buttons.Data.Length < 4) 10814 if (quick_pay_buttons.Data.Length < 4)
10317 { 10815 {
10318 LSLError("List must have at least 4 elements"); 10816 int x;
10319 return; 10817 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10818 {
10819 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10820 }
10320 } 10821 }
10321 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10822 int[] nPrice = new int[5];
10322 10823 nPrice[0] = price;
10323 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10824 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10324 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10825 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10325 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10826 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10326 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10827 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10828 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10327 m_host.ParentGroup.HasGroupChanged = true; 10829 m_host.ParentGroup.HasGroupChanged = true;
10328 } 10830 }
10329 10831
@@ -10340,7 +10842,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10340 return Vector3.Zero; 10842 return Vector3.Zero;
10341 } 10843 }
10342 10844
10343 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10845// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10846 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10344 if (presence != null) 10847 if (presence != null)
10345 { 10848 {
10346 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10849 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10363,7 +10866,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10363 return Quaternion.Identity; 10866 return Quaternion.Identity;
10364 } 10867 }
10365 10868
10366 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10869// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10870 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10367 if (presence != null) 10871 if (presence != null)
10368 { 10872 {
10369 return new LSL_Rotation(presence.CameraRotation); 10873 return new LSL_Rotation(presence.CameraRotation);
@@ -10423,14 +10927,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10423 { 10927 {
10424 m_host.AddScriptLPS(1); 10928 m_host.AddScriptLPS(1);
10425 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10929 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10426 if (detectedParams == null) return; // only works on the first detected avatar 10930 if (detectedParams == null)
10427 10931 {
10932 if (m_host.ParentGroup.IsAttachment == true)
10933 {
10934 detectedParams = new DetectParams();
10935 detectedParams.Key = m_host.OwnerID;
10936 }
10937 else
10938 {
10939 return;
10940 }
10941 }
10942
10428 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10943 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10429 if (avatar != null) 10944 if (avatar != null)
10430 { 10945 {
10431 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10946 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10432 simname, pos, lookAt); 10947 simname, pos, lookAt);
10433 } 10948 }
10949
10434 ScriptSleep(1000); 10950 ScriptSleep(1000);
10435 } 10951 }
10436 10952
@@ -10554,12 +11070,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10554 11070
10555 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11071 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10556 object[] data = rules.Data; 11072 object[] data = rules.Data;
10557 for (int i = 0; i < data.Length; ++i) { 11073 for (int i = 0; i < data.Length; ++i)
11074 {
10558 int type = Convert.ToInt32(data[i++].ToString()); 11075 int type = Convert.ToInt32(data[i++].ToString());
10559 if (i >= data.Length) break; // odd number of entries => ignore the last 11076 if (i >= data.Length) break; // odd number of entries => ignore the last
10560 11077
10561 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11078 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10562 switch (type) { 11079 switch (type)
11080 {
10563 case ScriptBaseClass.CAMERA_FOCUS: 11081 case ScriptBaseClass.CAMERA_FOCUS:
10564 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11082 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10565 case ScriptBaseClass.CAMERA_POSITION: 11083 case ScriptBaseClass.CAMERA_POSITION:
@@ -10664,19 +11182,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10664 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11182 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10665 { 11183 {
10666 m_host.AddScriptLPS(1); 11184 m_host.AddScriptLPS(1);
10667 string ret = String.Empty; 11185
10668 string src1 = llBase64ToString(str1); 11186 if (str1 == String.Empty)
10669 string src2 = llBase64ToString(str2); 11187 return String.Empty;
10670 int c = 0; 11188 if (str2 == String.Empty)
10671 for (int i = 0; i < src1.Length; i++) 11189 return str1;
11190
11191 int len = str2.Length;
11192 if ((len % 4) != 0) // LL is EVIL!!!!
11193 {
11194 while (str2.EndsWith("="))
11195 str2 = str2.Substring(0, str2.Length - 1);
11196
11197 len = str2.Length;
11198 int mod = len % 4;
11199
11200 if (mod == 1)
11201 str2 = str2.Substring(0, str2.Length - 1);
11202 else if (mod == 2)
11203 str2 += "==";
11204 else if (mod == 3)
11205 str2 += "=";
11206 }
11207
11208 byte[] data1;
11209 byte[] data2;
11210 try
11211 {
11212 data1 = Convert.FromBase64String(str1);
11213 data2 = Convert.FromBase64String(str2);
11214 }
11215 catch (Exception)
11216 {
11217 return new LSL_String(String.Empty);
11218 }
11219
11220 byte[] d2 = new Byte[data1.Length];
11221 int pos = 0;
11222
11223 if (data1.Length <= data2.Length)
10672 { 11224 {
10673 ret += (char) (src1[i] ^ src2[c]); 11225 Array.Copy(data2, 0, d2, 0, data1.Length);
11226 }
11227 else
11228 {
11229 while (pos < data1.Length)
11230 {
11231 len = data1.Length - pos;
11232 if (len > data2.Length)
11233 len = data2.Length;
10674 11234
10675 c++; 11235 Array.Copy(data2, 0, d2, pos, len);
10676 if (c >= src2.Length) 11236 pos += len;
10677 c = 0; 11237 }
10678 } 11238 }
10679 return llStringToBase64(ret); 11239
11240 for (pos = 0 ; pos < data1.Length ; pos++ )
11241 data1[pos] ^= d2[pos];
11242
11243 return Convert.ToBase64String(data1);
10680 } 11244 }
10681 11245
10682 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11246 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10780,16 +11344,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10780 if (userAgent != null) 11344 if (userAgent != null)
10781 httpHeaders["User-Agent"] = userAgent; 11345 httpHeaders["User-Agent"] = userAgent;
10782 11346
11347 // See if the URL contains any header hacks
11348 string[] urlParts = url.Split(new char[] {'\n'});
11349 if (urlParts.Length > 1)
11350 {
11351 // Iterate the passed headers and parse them
11352 for (int i = 1 ; i < urlParts.Length ; i++ )
11353 {
11354 // The rest of those would be added to the body in SL.
11355 // Let's not do that.
11356 if (urlParts[i] == String.Empty)
11357 break;
11358
11359 // See if this could be a valid header
11360 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11361 if (headerParts.Length != 2)
11362 continue;
11363
11364 string headerName = headerParts[0].Trim();
11365 string headerValue = headerParts[1].Trim();
11366
11367 // Filter out headers that could be used to abuse
11368 // another system or cloak the request
11369 if (headerName.ToLower() == "x-secondlife-shard" ||
11370 headerName.ToLower() == "x-secondlife-object-name" ||
11371 headerName.ToLower() == "x-secondlife-object-key" ||
11372 headerName.ToLower() == "x-secondlife-region" ||
11373 headerName.ToLower() == "x-secondlife-local-position" ||
11374 headerName.ToLower() == "x-secondlife-local-velocity" ||
11375 headerName.ToLower() == "x-secondlife-local-rotation" ||
11376 headerName.ToLower() == "x-secondlife-owner-name" ||
11377 headerName.ToLower() == "x-secondlife-owner-key" ||
11378 headerName.ToLower() == "connection" ||
11379 headerName.ToLower() == "content-length" ||
11380 headerName.ToLower() == "from" ||
11381 headerName.ToLower() == "host" ||
11382 headerName.ToLower() == "proxy-authorization" ||
11383 headerName.ToLower() == "referer" ||
11384 headerName.ToLower() == "trailer" ||
11385 headerName.ToLower() == "transfer-encoding" ||
11386 headerName.ToLower() == "via" ||
11387 headerName.ToLower() == "authorization")
11388 continue;
11389
11390 httpHeaders[headerName] = headerValue;
11391 }
11392
11393 // Finally, strip any protocol specifier from the URL
11394 url = urlParts[0].Trim();
11395 int idx = url.IndexOf(" HTTP/");
11396 if (idx != -1)
11397 url = url.Substring(0, idx);
11398 }
11399
10783 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11400 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10784 Regex r = new Regex(authregex); 11401 Regex r = new Regex(authregex);
10785 int[] gnums = r.GetGroupNumbers(); 11402 int[] gnums = r.GetGroupNumbers();
10786 Match m = r.Match(url); 11403 Match m = r.Match(url);
10787 if (m.Success) { 11404 if (m.Success)
10788 for (int i = 1; i < gnums.Length; i++) { 11405 {
11406 for (int i = 1; i < gnums.Length; i++)
11407 {
10789 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11408 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10790 //CaptureCollection cc = g.Captures; 11409 //CaptureCollection cc = g.Captures;
10791 } 11410 }
10792 if (m.Groups.Count == 5) { 11411 if (m.Groups.Count == 5)
11412 {
10793 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11413 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10794 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11414 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10795 } 11415 }
@@ -10992,6 +11612,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10992 11612
10993 LSL_List ret = new LSL_List(); 11613 LSL_List ret = new LSL_List();
10994 UUID key = new UUID(); 11614 UUID key = new UUID();
11615
11616
10995 if (UUID.TryParse(id, out key)) 11617 if (UUID.TryParse(id, out key))
10996 { 11618 {
10997 ScenePresence av = World.GetScenePresence(key); 11619 ScenePresence av = World.GetScenePresence(key);
@@ -11009,13 +11631,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11009 ret.Add(new LSL_String("")); 11631 ret.Add(new LSL_String(""));
11010 break; 11632 break;
11011 case ScriptBaseClass.OBJECT_POS: 11633 case ScriptBaseClass.OBJECT_POS:
11012 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11634 Vector3 avpos;
11635
11636 if (av.ParentID != 0 && av.ParentPart != null)
11637 {
11638 avpos = av.OffsetPosition;
11639
11640 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11641 avpos -= sitOffset;
11642
11643 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11644 }
11645 else
11646 avpos = av.AbsolutePosition;
11647
11648 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
11013 break; 11649 break;
11014 case ScriptBaseClass.OBJECT_ROT: 11650 case ScriptBaseClass.OBJECT_ROT:
11015 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11651 Quaternion avrot = av.Rotation;
11652 if (av.ParentID != 0 && av.ParentPart != null)
11653 {
11654 avrot = av.ParentPart.GetWorldRotation() * avrot;
11655 }
11656 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
11016 break; 11657 break;
11017 case ScriptBaseClass.OBJECT_VELOCITY: 11658 case ScriptBaseClass.OBJECT_VELOCITY:
11018 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11659 Vector3 avvel = av.Velocity;
11660 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
11019 break; 11661 break;
11020 case ScriptBaseClass.OBJECT_OWNER: 11662 case ScriptBaseClass.OBJECT_OWNER:
11021 ret.Add(new LSL_String(id)); 11663 ret.Add(new LSL_String(id));
@@ -11100,11 +11742,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11100 case ScriptBaseClass.OBJECT_NAME: 11742 case ScriptBaseClass.OBJECT_NAME:
11101 ret.Add(new LSL_String(obj.Name)); 11743 ret.Add(new LSL_String(obj.Name));
11102 break; 11744 break;
11103 case ScriptBaseClass.OBJECT_DESC: 11745 case ScriptBaseClass.OBJECT_DESC:
11104 ret.Add(new LSL_String(obj.Description)); 11746 ret.Add(new LSL_String(obj.Description));
11105 break; 11747 break;
11106 case ScriptBaseClass.OBJECT_POS: 11748 case ScriptBaseClass.OBJECT_POS:
11107 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11749 Vector3 opos = obj.AbsolutePosition;
11750 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
11108 break; 11751 break;
11109 case ScriptBaseClass.OBJECT_ROT: 11752 case ScriptBaseClass.OBJECT_ROT:
11110 { 11753 {
@@ -11154,9 +11797,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11154 // The value returned in SL for normal prims is prim count 11797 // The value returned in SL for normal prims is prim count
11155 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11798 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
11156 break; 11799 break;
11157 // The following 3 costs I have intentionaly coded to return zero. They are part of 11800
11158 // "Land Impact" calculations. These calculations are probably not applicable 11801 // costs below may need to be diferent for root parts, need to check
11159 // to OpenSim and are not yet complete in SL
11160 case ScriptBaseClass.OBJECT_SERVER_COST: 11802 case ScriptBaseClass.OBJECT_SERVER_COST:
11161 // The linden calculation is here 11803 // The linden calculation is here
11162 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11804 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -11164,16 +11806,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11164 ret.Add(new LSL_Float(0)); 11806 ret.Add(new LSL_Float(0));
11165 break; 11807 break;
11166 case ScriptBaseClass.OBJECT_STREAMING_COST: 11808 case ScriptBaseClass.OBJECT_STREAMING_COST:
11167 // The linden calculation is here 11809 // The value returned in SL for normal prims is prim count * 0.06
11168 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11810 ret.Add(new LSL_Float(obj.StreamingCost));
11169 // The value returned in SL for normal prims looks like the prim count * 0.06
11170 ret.Add(new LSL_Float(0));
11171 break; 11811 break;
11172 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11812 case ScriptBaseClass.OBJECT_PHYSICS_COST:
11173 // The linden calculation is here 11813 // The value returned in SL for normal prims is prim count
11174 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11814 ret.Add(new LSL_Float(obj.PhysicsCost));
11175 // The value returned in SL for normal prims looks like the prim count
11176 ret.Add(new LSL_Float(0));
11177 break; 11815 break;
11178 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11816 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
11179 ret.Add(new LSL_Float(0)); 11817 ret.Add(new LSL_Float(0));
@@ -11432,15 +12070,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11432 return result; 12070 return result;
11433 } 12071 }
11434 12072
11435 public void print(string str) 12073 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11436 { 12074 {
11437 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12075 List<SceneObjectPart> parts = GetLinkParts(link);
11438 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12076 if (parts.Count < 1)
11439 if (ossl != null) 12077 return 0;
11440 { 12078
11441 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12079 return GetNumberOfSides(parts[0]);
11442 m_log.Info("LSL print():" + str);
11443 }
11444 } 12080 }
11445 12081
11446 private string Name2Username(string name) 12082 private string Name2Username(string name)
@@ -11485,7 +12121,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11485 12121
11486 return rq.ToString(); 12122 return rq.ToString();
11487 } 12123 }
11488 12124/*
12125 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12126 {
12127 m_SayShoutCount = 0;
12128 }
12129*/
11489 private struct Tri 12130 private struct Tri
11490 { 12131 {
11491 public Vector3 p1; 12132 public Vector3 p1;
@@ -11634,9 +12275,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11634 12275
11635 ContactResult result = new ContactResult (); 12276 ContactResult result = new ContactResult ();
11636 result.ConsumerID = group.LocalId; 12277 result.ConsumerID = group.LocalId;
11637 result.Depth = intersection.distance; 12278// result.Depth = intersection.distance;
11638 result.Normal = intersection.normal; 12279 result.Normal = intersection.normal;
11639 result.Pos = intersection.ipoint; 12280 result.Pos = intersection.ipoint;
12281 result.Depth = Vector3.Mag(rayStart - result.Pos);
11640 12282
11641 contacts.Add(result); 12283 contacts.Add(result);
11642 }); 12284 });
@@ -11769,6 +12411,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11769 12411
11770 return contacts[0]; 12412 return contacts[0];
11771 } 12413 }
12414/*
12415 // not done:
12416 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12417 {
12418 ContactResult[] contacts = null;
12419 World.ForEachSOG(delegate(SceneObjectGroup group)
12420 {
12421 if (m_host.ParentGroup == group)
12422 return;
12423
12424 if (group.IsAttachment)
12425 return;
12426
12427 if(group.RootPart.PhysActor != null)
12428 return;
12429
12430 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12431 });
12432 return contacts;
12433 }
12434*/
11772 12435
11773 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12436 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11774 { 12437 {
@@ -11892,18 +12555,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11892 } 12555 }
11893 } 12556 }
11894 12557
12558 // Double check this
11895 if (checkTerrain) 12559 if (checkTerrain)
11896 { 12560 {
11897 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12561 bool skipGroundCheck = false;
11898 if (groundContact != null) 12562
11899 results.Add((ContactResult)groundContact); 12563 foreach (ContactResult c in results)
12564 {
12565 if (c.ConsumerID == 0) // Physics gave us a ground collision
12566 skipGroundCheck = true;
12567 }
12568
12569 if (!skipGroundCheck)
12570 {
12571 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12572 if (groundContact != null)
12573 results.Add((ContactResult)groundContact);
12574 }
11900 } 12575 }
11901 12576
11902 results.Sort(delegate(ContactResult a, ContactResult b) 12577 results.Sort(delegate(ContactResult a, ContactResult b)
11903 { 12578 {
11904 return a.Depth.CompareTo(b.Depth); 12579 return a.Depth.CompareTo(b.Depth);
11905 }); 12580 });
11906 12581
11907 int values = 0; 12582 int values = 0;
11908 SceneObjectGroup thisgrp = m_host.ParentGroup; 12583 SceneObjectGroup thisgrp = m_host.ParentGroup;
11909 12584
@@ -11996,7 +12671,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11996 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12671 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11997 if (!isAccount) return 0; 12672 if (!isAccount) return 0;
11998 if (estate.HasAccess(id)) return 1; 12673 if (estate.HasAccess(id)) return 1;
11999 if (estate.IsBanned(id)) 12674 if (estate.IsBanned(id, World.GetUserFlags(id)))
12000 estate.RemoveBan(id); 12675 estate.RemoveBan(id);
12001 estate.AddEstateUser(id); 12676 estate.AddEstateUser(id);
12002 break; 12677 break;
@@ -12015,14 +12690,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12015 break; 12690 break;
12016 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12691 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
12017 if (!isAccount) return 0; 12692 if (!isAccount) return 0;
12018 if (estate.IsBanned(id)) return 1; 12693 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
12019 EstateBan ban = new EstateBan(); 12694 EstateBan ban = new EstateBan();
12020 ban.EstateID = estate.EstateID; 12695 ban.EstateID = estate.EstateID;
12021 ban.BannedUserID = id; 12696 ban.BannedUserID = id;
12022 estate.AddBan(ban); 12697 estate.AddBan(ban);
12023 break; 12698 break;
12024 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12699 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
12025 if (!isAccount || !estate.IsBanned(id)) return 0; 12700 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
12026 estate.RemoveBan(id); 12701 estate.RemoveBan(id);
12027 break; 12702 break;
12028 default: return 0; 12703 default: return 0;
@@ -12087,13 +12762,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12087 public void llCollisionSprite(string impact_sprite) 12762 public void llCollisionSprite(string impact_sprite)
12088 { 12763 {
12089 m_host.AddScriptLPS(1); 12764 m_host.AddScriptLPS(1);
12090 NotImplemented("llCollisionSprite"); 12765 // Viewer 2.0 broke this and it's likely LL has no intention
12766 // of fixing it. Therefore, letting this be a NOP seems appropriate.
12091 } 12767 }
12092 12768
12093 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12769 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
12094 { 12770 {
12095 m_host.AddScriptLPS(1); 12771 m_host.AddScriptLPS(1);
12096 NotImplemented("llGodLikeRezObject"); 12772
12773 if (!World.Permissions.IsGod(m_host.OwnerID))
12774 NotImplemented("llGodLikeRezObject");
12775
12776 AssetBase rezAsset = World.AssetService.Get(inventory);
12777 if (rezAsset == null)
12778 {
12779 llSay(0, "Asset not found");
12780 return;
12781 }
12782
12783 SceneObjectGroup group = null;
12784
12785 try
12786 {
12787 string xmlData = Utils.BytesToString(rezAsset.Data);
12788 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12789 }
12790 catch
12791 {
12792 llSay(0, "Asset not found");
12793 return;
12794 }
12795
12796 if (group == null)
12797 {
12798 llSay(0, "Asset not found");
12799 return;
12800 }
12801
12802 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12803 group.RootPart.AttachOffset = group.AbsolutePosition;
12804
12805 group.ResetIDs();
12806
12807 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12808 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12809 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12810 group.ScheduleGroupForFullUpdate();
12811
12812 // objects rezzed with this method are die_at_edge by default.
12813 group.RootPart.SetDieAtEdge(true);
12814
12815 group.ResumeScripts();
12816
12817 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12818 "object_rez", new Object[] {
12819 new LSL_String(
12820 group.RootPart.UUID.ToString()) },
12821 new DetectParams[0]));
12097 } 12822 }
12098 12823
12099 public LSL_String llTransferLindenDollars(string destination, int amount) 12824 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -12144,8 +12869,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12144 return; 12869 return;
12145 } 12870 }
12146 12871
12872 string reason;
12147 bool result = money.ObjectGiveMoney( 12873 bool result = money.ObjectGiveMoney(
12148 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12874 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn, out reason);
12149 12875
12150 if (result) 12876 if (result)
12151 { 12877 {
@@ -12153,7 +12879,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12153 return; 12879 return;
12154 } 12880 }
12155 12881
12156 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS"; 12882 replydata = reason;
12157 } 12883 }
12158 finally 12884 finally
12159 { 12885 {
@@ -12170,6 +12896,610 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
12170 } 12896 }
12171 12897
12172 #endregion 12898 #endregion
12899
12900 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12901 {
12902 SceneObjectGroup group = m_host.ParentGroup;
12903
12904 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12905 return;
12906 if (group.IsAttachment)
12907 return;
12908
12909 if (frames.Data.Length > 0) // We are getting a new motion
12910 {
12911 if (group.RootPart.KeyframeMotion != null)
12912 group.RootPart.KeyframeMotion.Delete();
12913 group.RootPart.KeyframeMotion = null;
12914
12915 int idx = 0;
12916
12917 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12918 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12919
12920 while (idx < options.Data.Length)
12921 {
12922 int option = (int)options.GetLSLIntegerItem(idx++);
12923 int remain = options.Data.Length - idx;
12924
12925 switch (option)
12926 {
12927 case ScriptBaseClass.KFM_MODE:
12928 if (remain < 1)
12929 break;
12930 int modeval = (int)options.GetLSLIntegerItem(idx++);
12931 switch(modeval)
12932 {
12933 case ScriptBaseClass.KFM_FORWARD:
12934 mode = KeyframeMotion.PlayMode.Forward;
12935 break;
12936 case ScriptBaseClass.KFM_REVERSE:
12937 mode = KeyframeMotion.PlayMode.Reverse;
12938 break;
12939 case ScriptBaseClass.KFM_LOOP:
12940 mode = KeyframeMotion.PlayMode.Loop;
12941 break;
12942 case ScriptBaseClass.KFM_PING_PONG:
12943 mode = KeyframeMotion.PlayMode.PingPong;
12944 break;
12945 }
12946 break;
12947 case ScriptBaseClass.KFM_DATA:
12948 if (remain < 1)
12949 break;
12950 int dataval = (int)options.GetLSLIntegerItem(idx++);
12951 data = (KeyframeMotion.DataFormat)dataval;
12952 break;
12953 }
12954 }
12955
12956 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12957
12958 idx = 0;
12959
12960 int elemLength = 2;
12961 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12962 elemLength = 3;
12963
12964 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12965 while (idx < frames.Data.Length)
12966 {
12967 int remain = frames.Data.Length - idx;
12968
12969 if (remain < elemLength)
12970 break;
12971
12972 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12973 frame.Position = null;
12974 frame.Rotation = null;
12975
12976 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12977 {
12978 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12979 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12980 }
12981 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12982 {
12983 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12984 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12985 q.Normalize();
12986 frame.Rotation = q;
12987 }
12988
12989 float tempf = (float)frames.GetLSLFloatItem(idx++);
12990 frame.TimeMS = (int)(tempf * 1000.0f);
12991
12992 keyframes.Add(frame);
12993 }
12994
12995 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12996 group.RootPart.KeyframeMotion.Start();
12997 }
12998 else
12999 {
13000 if (group.RootPart.KeyframeMotion == null)
13001 return;
13002
13003 if (options.Data.Length == 0)
13004 {
13005 group.RootPart.KeyframeMotion.Stop();
13006 return;
13007 }
13008
13009 int code = (int)options.GetLSLIntegerItem(0);
13010
13011 int idx = 0;
13012
13013 while (idx < options.Data.Length)
13014 {
13015 int option = (int)options.GetLSLIntegerItem(idx++);
13016 int remain = options.Data.Length - idx;
13017
13018 switch (option)
13019 {
13020 case ScriptBaseClass.KFM_COMMAND:
13021 int cmd = (int)options.GetLSLIntegerItem(idx++);
13022 switch (cmd)
13023 {
13024 case ScriptBaseClass.KFM_CMD_PLAY:
13025 group.RootPart.KeyframeMotion.Start();
13026 break;
13027 case ScriptBaseClass.KFM_CMD_STOP:
13028 group.RootPart.KeyframeMotion.Stop();
13029 break;
13030 case ScriptBaseClass.KFM_CMD_PAUSE:
13031 group.RootPart.KeyframeMotion.Pause();
13032 break;
13033 }
13034 break;
13035 }
13036 }
13037 }
13038 }
13039
13040 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
13041 {
13042 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
13043
13044 int idx = 0;
13045 int idxStart = 0;
13046
13047 bool positionChanged = false;
13048 Vector3 finalPos = Vector3.Zero;
13049
13050 try
13051 {
13052 while (idx < rules.Length)
13053 {
13054 ++rulesParsed;
13055 int code = rules.GetLSLIntegerItem(idx++);
13056
13057 int remain = rules.Length - idx;
13058 idxStart = idx;
13059
13060 switch (code)
13061 {
13062 case (int)ScriptBaseClass.PRIM_POSITION:
13063 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13064 {
13065 if (remain < 1)
13066 return null;
13067
13068 LSL_Vector v;
13069 v = rules.GetVector3Item(idx++);
13070
13071 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13072 if (part == null)
13073 break;
13074
13075 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13076 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13077 if (part.LinkNum > 1)
13078 {
13079 localRot = GetPartLocalRot(part);
13080 localPos = GetPartLocalPos(part);
13081 }
13082
13083 v -= localPos;
13084 v /= localRot;
13085
13086 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
13087
13088 v = v + 2 * sitOffset;
13089
13090 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
13091 av.SendAvatarDataToAllAgents();
13092
13093 }
13094 break;
13095
13096 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13097 case (int)ScriptBaseClass.PRIM_ROTATION:
13098 {
13099 if (remain < 1)
13100 return null;
13101
13102 LSL_Rotation r;
13103 r = rules.GetQuaternionItem(idx++);
13104
13105 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
13106 if (part == null)
13107 break;
13108
13109 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13110 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13111
13112 if (part.LinkNum > 1)
13113 localRot = GetPartLocalRot(part);
13114
13115 r = r * llGetRootRotation() / localRot;
13116 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
13117 av.SendAvatarDataToAllAgents();
13118 }
13119 break;
13120
13121 // parse rest doing nothing but number of parameters error check
13122 case (int)ScriptBaseClass.PRIM_SIZE:
13123 case (int)ScriptBaseClass.PRIM_MATERIAL:
13124 case (int)ScriptBaseClass.PRIM_PHANTOM:
13125 case (int)ScriptBaseClass.PRIM_PHYSICS:
13126 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
13127 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13128 case (int)ScriptBaseClass.PRIM_NAME:
13129 case (int)ScriptBaseClass.PRIM_DESC:
13130 if (remain < 1)
13131 return null;
13132 idx++;
13133 break;
13134
13135 case (int)ScriptBaseClass.PRIM_GLOW:
13136 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13137 case (int)ScriptBaseClass.PRIM_TEXGEN:
13138 if (remain < 2)
13139 return null;
13140 idx += 2;
13141 break;
13142
13143 case (int)ScriptBaseClass.PRIM_TYPE:
13144 if (remain < 3)
13145 return null;
13146 code = (int)rules.GetLSLIntegerItem(idx++);
13147 remain = rules.Length - idx;
13148 switch (code)
13149 {
13150 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13151 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13152 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13153 if (remain < 6)
13154 return null;
13155 idx += 6;
13156 break;
13157
13158 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13159 if (remain < 5)
13160 return null;
13161 idx += 5;
13162 break;
13163
13164 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13165 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13166 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13167 if (remain < 11)
13168 return null;
13169 idx += 11;
13170 break;
13171
13172 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13173 if (remain < 2)
13174 return null;
13175 idx += 2;
13176 break;
13177 }
13178 break;
13179
13180 case (int)ScriptBaseClass.PRIM_COLOR:
13181 case (int)ScriptBaseClass.PRIM_TEXT:
13182 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13183 case (int)ScriptBaseClass.PRIM_OMEGA:
13184 if (remain < 3)
13185 return null;
13186 idx += 3;
13187 break;
13188
13189 case (int)ScriptBaseClass.PRIM_TEXTURE:
13190 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13191 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13192 if (remain < 5)
13193 return null;
13194 idx += 5;
13195 break;
13196
13197 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13198 if (remain < 7)
13199 return null;
13200
13201 idx += 7;
13202 break;
13203
13204 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13205 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13206 return null;
13207
13208 return rules.GetSublist(idx, -1);
13209 }
13210 }
13211 }
13212 catch (InvalidCastException e)
13213 {
13214 ShoutError(string.Format(
13215 "{0} error running rule #{1}: arg #{2} ",
13216 originFunc, rulesParsed, idx - idxStart) + e.Message);
13217 }
13218 finally
13219 {
13220 if (positionChanged)
13221 {
13222 av.OffsetPosition = finalPos;
13223// av.SendAvatarDataToAllAgents();
13224 av.SendTerseUpdateToAllClients();
13225 positionChanged = false;
13226 }
13227 }
13228 return null;
13229 }
13230
13231 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13232 {
13233 // avatars case
13234 // replies as SL wiki
13235
13236// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13237 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13238
13239 int idx = 0;
13240 while (idx < rules.Length)
13241 {
13242 int code = (int)rules.GetLSLIntegerItem(idx++);
13243 int remain = rules.Length - idx;
13244
13245 switch (code)
13246 {
13247 case (int)ScriptBaseClass.PRIM_MATERIAL:
13248 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13249 break;
13250
13251 case (int)ScriptBaseClass.PRIM_PHYSICS:
13252 res.Add(new LSL_Integer(0));
13253 break;
13254
13255 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13256 res.Add(new LSL_Integer(0));
13257 break;
13258
13259 case (int)ScriptBaseClass.PRIM_PHANTOM:
13260 res.Add(new LSL_Integer(0));
13261 break;
13262
13263 case (int)ScriptBaseClass.PRIM_POSITION:
13264
13265 Vector3 pos = avatar.OffsetPosition;
13266
13267 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13268 pos -= sitOffset;
13269
13270 if( sitPart != null)
13271 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13272
13273 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13274 break;
13275
13276 case (int)ScriptBaseClass.PRIM_SIZE:
13277 // as in llGetAgentSize above
13278// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13279 Vector3 s = avatar.Appearance.AvatarSize;
13280 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13281
13282 break;
13283
13284 case (int)ScriptBaseClass.PRIM_ROTATION:
13285 Quaternion rot = avatar.Rotation;
13286 if (sitPart != null)
13287 {
13288 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13289 }
13290
13291 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13292 break;
13293
13294 case (int)ScriptBaseClass.PRIM_TYPE:
13295 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13296 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13297 res.Add(new LSL_Vector(0f,1.0f,0f));
13298 res.Add(new LSL_Float(0.0f));
13299 res.Add(new LSL_Vector(0, 0, 0));
13300 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13301 res.Add(new LSL_Vector(0, 0, 0));
13302 break;
13303
13304 case (int)ScriptBaseClass.PRIM_TEXTURE:
13305 if (remain < 1)
13306 return null;
13307
13308 int face = (int)rules.GetLSLIntegerItem(idx++);
13309 if (face == ScriptBaseClass.ALL_SIDES)
13310 {
13311 for (face = 0; face < 21; face++)
13312 {
13313 res.Add(new LSL_String(""));
13314 res.Add(new LSL_Vector(0,0,0));
13315 res.Add(new LSL_Vector(0,0,0));
13316 res.Add(new LSL_Float(0.0));
13317 }
13318 }
13319 else
13320 {
13321 if (face >= 0 && face < 21)
13322 {
13323 res.Add(new LSL_String(""));
13324 res.Add(new LSL_Vector(0,0,0));
13325 res.Add(new LSL_Vector(0,0,0));
13326 res.Add(new LSL_Float(0.0));
13327 }
13328 }
13329 break;
13330
13331 case (int)ScriptBaseClass.PRIM_COLOR:
13332 if (remain < 1)
13333 return null;
13334
13335 face = (int)rules.GetLSLIntegerItem(idx++);
13336
13337 if (face == ScriptBaseClass.ALL_SIDES)
13338 {
13339 for (face = 0; face < 21; face++)
13340 {
13341 res.Add(new LSL_Vector(0,0,0));
13342 res.Add(new LSL_Float(0));
13343 }
13344 }
13345 else
13346 {
13347 res.Add(new LSL_Vector(0,0,0));
13348 res.Add(new LSL_Float(0));
13349 }
13350 break;
13351
13352 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13353 if (remain < 1)
13354 return null;
13355 face = (int)rules.GetLSLIntegerItem(idx++);
13356
13357 if (face == ScriptBaseClass.ALL_SIDES)
13358 {
13359 for (face = 0; face < 21; face++)
13360 {
13361 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13362 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13363 }
13364 }
13365 else
13366 {
13367 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13368 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13369 }
13370 break;
13371
13372 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13373 if (remain < 1)
13374 return null;
13375 face = (int)rules.GetLSLIntegerItem(idx++);
13376
13377 if (face == ScriptBaseClass.ALL_SIDES)
13378 {
13379 for (face = 0; face < 21; face++)
13380 {
13381 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13382 }
13383 }
13384 else
13385 {
13386 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13387 }
13388 break;
13389
13390 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13391 res.Add(new LSL_Integer(0));
13392 res.Add(new LSL_Integer(0));// softness
13393 res.Add(new LSL_Float(0.0f)); // gravity
13394 res.Add(new LSL_Float(0.0f)); // friction
13395 res.Add(new LSL_Float(0.0f)); // wind
13396 res.Add(new LSL_Float(0.0f)); // tension
13397 res.Add(new LSL_Vector(0f,0f,0f));
13398 break;
13399
13400 case (int)ScriptBaseClass.PRIM_TEXGEN:
13401 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13402 if (remain < 1)
13403 return null;
13404 face = (int)rules.GetLSLIntegerItem(idx++);
13405
13406 if (face == ScriptBaseClass.ALL_SIDES)
13407 {
13408 for (face = 0; face < 21; face++)
13409 {
13410 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13411 }
13412 }
13413 else
13414 {
13415 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13416 }
13417 break;
13418
13419 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13420 res.Add(new LSL_Integer(0));
13421 res.Add(new LSL_Vector(0f,0f,0f));
13422 res.Add(new LSL_Float(0f)); // intensity
13423 res.Add(new LSL_Float(0f)); // radius
13424 res.Add(new LSL_Float(0f)); // falloff
13425 break;
13426
13427 case (int)ScriptBaseClass.PRIM_GLOW:
13428 if (remain < 1)
13429 return null;
13430 face = (int)rules.GetLSLIntegerItem(idx++);
13431
13432 if (face == ScriptBaseClass.ALL_SIDES)
13433 {
13434 for (face = 0; face < 21; face++)
13435 {
13436 res.Add(new LSL_Float(0f));
13437 }
13438 }
13439 else
13440 {
13441 res.Add(new LSL_Float(0f));
13442 }
13443 break;
13444
13445 case (int)ScriptBaseClass.PRIM_TEXT:
13446 res.Add(new LSL_String(""));
13447 res.Add(new LSL_Vector(0f,0f,0f));
13448 res.Add(new LSL_Float(1.0f));
13449 break;
13450
13451 case (int)ScriptBaseClass.PRIM_NAME:
13452 res.Add(new LSL_String(avatar.Name));
13453 break;
13454
13455 case (int)ScriptBaseClass.PRIM_DESC:
13456 res.Add(new LSL_String(""));
13457 break;
13458
13459 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13460 Quaternion lrot = avatar.Rotation;
13461
13462 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13463 {
13464 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13465 }
13466 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13467 break;
13468
13469 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13470 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13471 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13472 lpos -= lsitOffset;
13473
13474 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13475 {
13476 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13477 }
13478 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13479 break;
13480
13481 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13482 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13483 return null;
13484
13485 return rules.GetSublist(idx, -1);
13486 }
13487 }
13488
13489 return null;
13490 }
13491
13492 public void llSetContentType(LSL_Key id, LSL_Integer content_type)
13493 {
13494 if (m_UrlModule != null)
13495 {
13496 string type = "text.plain";
13497 if (content_type == (int)ScriptBaseClass.CONTENT_TYPE_HTML)
13498 type = "text/html";
13499
13500 m_UrlModule.HttpContentType(new UUID(id),type);
13501 }
13502 }
12173 } 13503 }
12174 13504
12175 public class NotecardCache 13505 public class NotecardCache