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.cs3316
1 files changed, 2390 insertions, 926 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 0b4b043..0199461 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -24,14 +24,16 @@
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections; 29using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Diagnostics; //for [DebuggerNonUserCode]
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using System.Text; 33using System.Text;
33using System.Threading; 34using System.Threading;
34using System.Text.RegularExpressions; 35using System.Text.RegularExpressions;
36using System.Timers;
35using Nini.Config; 37using Nini.Config;
36using log4net; 38using log4net;
37using OpenMetaverse; 39using OpenMetaverse;
@@ -44,6 +46,7 @@ using OpenSim.Region.CoreModules.World.Land;
44using OpenSim.Region.CoreModules.World.Terrain; 46using OpenSim.Region.CoreModules.World.Terrain;
45using OpenSim.Region.Framework.Interfaces; 47using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes; 48using OpenSim.Region.Framework.Scenes;
49using OpenSim.Region.Framework.Scenes.Serialization;
47using OpenSim.Region.Framework.Scenes.Animation; 50using OpenSim.Region.Framework.Scenes.Animation;
48using OpenSim.Region.Framework.Scenes.Scripting; 51using OpenSim.Region.Framework.Scenes.Scripting;
49using OpenSim.Region.Physics.Manager; 52using OpenSim.Region.Physics.Manager;
@@ -67,6 +70,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
67using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 70using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
68using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 71using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
69using System.Reflection; 72using System.Reflection;
73using Timer = System.Timers.Timer;
70using System.Linq; 74using System.Linq;
71using PermissionMask = OpenSim.Framework.PermissionMask; 75using PermissionMask = OpenSim.Framework.PermissionMask;
72 76
@@ -115,11 +119,38 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
115 protected int m_notecardLineReadCharsMax = 255; 119 protected int m_notecardLineReadCharsMax = 255;
116 protected int m_scriptConsoleChannel = 0; 120 protected int m_scriptConsoleChannel = 0;
117 protected bool m_scriptConsoleChannelEnabled = false; 121 protected bool m_scriptConsoleChannelEnabled = false;
122 protected bool m_debuggerSafe = false;
118 protected IUrlModule m_UrlModule = null; 123 protected IUrlModule m_UrlModule = null;
119 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 124 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
120 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 125 new Dictionary<UUID, UserInfoCacheEntry>();
126 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
121 protected ISoundModule m_SoundModule = null; 127 protected ISoundModule m_SoundModule = null;
122 128
129// protected Timer m_ShoutSayTimer;
130 protected int m_SayShoutCount = 0;
131 DateTime m_lastSayShoutCheck;
132
133 private Dictionary<string, string> MovementAnimationsForLSL =
134 new Dictionary<string, string> {
135 {"FLY", "Flying"},
136 {"FLYSLOW", "FlyingSlow"},
137 {"HOVER_UP", "Hovering Up"},
138 {"HOVER_DOWN", "Hovering Down"},
139 {"HOVER", "Hovering"},
140 {"LAND", "Landing"},
141 {"FALLDOWN", "Falling Down"},
142 {"PREJUMP", "PreJumping"},
143 {"JUMP", "Jumping"},
144 {"STANDUP", "Standing Up"},
145 {"SOFT_LAND", "Soft Landing"},
146 {"STAND", "Standing"},
147 {"CROUCHWALK", "CrouchWalking"},
148 {"RUN", "Running"},
149 {"WALK", "Walking"},
150 {"CROUCH", "Crouching"},
151 {"TURNLEFT", "Turning Left"},
152 {"TURNRIGHT", "Turning Right"}
153 };
123 //An array of HTTP/1.1 headers that are not allowed to be used 154 //An array of HTTP/1.1 headers that are not allowed to be used
124 //as custom headers by llHTTPRequest. 155 //as custom headers by llHTTPRequest.
125 private string[] HttpStandardHeaders = 156 private string[] HttpStandardHeaders =
@@ -140,9 +171,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
140 public void Initialize( 171 public void Initialize(
141 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle) 172 IScriptEngine scriptEngine, SceneObjectPart host, TaskInventoryItem item, WaitHandle coopSleepHandle)
142 { 173 {
174 m_lastSayShoutCheck = DateTime.UtcNow;
175
143 m_ScriptEngine = scriptEngine; 176 m_ScriptEngine = scriptEngine;
144 m_host = host; 177 m_host = host;
145 m_item = item; 178 m_item = item;
179 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
146 m_coopSleepHandle = coopSleepHandle; 180 m_coopSleepHandle = coopSleepHandle;
147 181
148 LoadConfig(); 182 LoadConfig();
@@ -231,6 +265,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
231 get { return m_ScriptEngine.World; } 265 get { return m_ScriptEngine.World; }
232 } 266 }
233 267
268 [DebuggerNonUserCode]
234 public void state(string newState) 269 public void state(string newState)
235 { 270 {
236 m_ScriptEngine.SetState(m_item.ItemID, newState); 271 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -240,6 +275,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
240 /// Reset the named script. The script must be present 275 /// Reset the named script. The script must be present
241 /// in the same prim. 276 /// in the same prim.
242 /// </summary> 277 /// </summary>
278 [DebuggerNonUserCode]
243 public void llResetScript() 279 public void llResetScript()
244 { 280 {
245 m_host.AddScriptLPS(1); 281 m_host.AddScriptLPS(1);
@@ -302,6 +338,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
302 } 338 }
303 } 339 }
304 340
341 public List<ScenePresence> GetLinkAvatars(int linkType)
342 {
343 List<ScenePresence> ret = new List<ScenePresence>();
344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
345 return ret;
346
347 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
348
349 switch (linkType)
350 {
351 case ScriptBaseClass.LINK_SET:
352 return avs;
353
354 case ScriptBaseClass.LINK_ROOT:
355 return ret;
356
357 case ScriptBaseClass.LINK_ALL_OTHERS:
358 return avs;
359
360 case ScriptBaseClass.LINK_ALL_CHILDREN:
361 return avs;
362
363 case ScriptBaseClass.LINK_THIS:
364 return ret;
365
366 default:
367 if (linkType < 0)
368 return ret;
369
370 int partCount = m_host.ParentGroup.GetPartCount();
371
372 if (linkType <= partCount)
373 {
374 return ret;
375 }
376 else
377 {
378 linkType = linkType - partCount;
379 if (linkType > avs.Count)
380 {
381 return ret;
382 }
383 else
384 {
385 ret.Add(avs[linkType-1]);
386 return ret;
387 }
388 }
389 }
390 }
391
305 /// <summary> 392 /// <summary>
306 /// Get a given link entity from a linkset (linked objects and any sitting avatars). 393 /// Get a given link entity from a linkset (linked objects and any sitting avatars).
307 /// </summary> 394 /// </summary>
@@ -384,6 +471,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
384 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 471 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
385 { 472 {
386 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 473 List<SceneObjectPart> ret = new List<SceneObjectPart>();
474 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
475 return ret;
387 ret.Add(part); 476 ret.Add(part);
388 477
389 switch (linkType) 478 switch (linkType)
@@ -537,31 +626,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
537 626
538 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 627 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
539 628
540 /// <summary> 629 // Utility function for llRot2Euler
541 /// Convert an LSL rotation to a Euler vector. 630
542 /// </summary> 631 // normalize an angle between -PI and PI (-180 to +180 degrees)
543 /// <remarks> 632 protected double NormalizeAngle(double angle)
544 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
545 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
546 /// </remarks>
547 /// <param name="r"></param>
548 /// <returns></returns>
549 public LSL_Vector llRot2Euler(LSL_Rotation r)
550 { 633 {
551 m_host.AddScriptLPS(1); 634 if (angle > -Math.PI && angle < Math.PI)
635 return angle;
552 636
553 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 637 int numPis = (int)(Math.PI / angle);
554 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 638 double remainder = angle - Math.PI * numPis;
555 if (m == 0.0) return new LSL_Vector(); 639 if (numPis % 2 == 1)
556 double x = Math.Atan2(-v.y, v.z); 640 return Math.PI - angle;
557 double sin = v.x / m; 641 return remainder;
558 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 642 }
559 double y = Math.Asin(sin);
560 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
561 v = new LSL_Vector(1.0, 0.0, 0.0) * ((r * new LSL_Rotation(Math.Sin(-x / 2.0), 0.0, 0.0, Math.Cos(-x / 2.0))) * new LSL_Rotation(0.0, Math.Sin(-y / 2.0), 0.0, Math.Cos(-y / 2.0)));
562 double z = Math.Atan2(v.y, v.x);
563 643
564 return new LSL_Vector(x, y, z); 644 public LSL_Vector llRot2Euler(LSL_Rotation q1)
645 {
646 m_host.AddScriptLPS(1);
647 LSL_Vector eul = new LSL_Vector();
648
649 double sqw = q1.s*q1.s;
650 double sqx = q1.x*q1.x;
651 double sqy = q1.z*q1.z;
652 double sqz = q1.y*q1.y;
653 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
654 double test = q1.x*q1.z + q1.y*q1.s;
655 if (test > 0.4999*unit) { // singularity at north pole
656 eul.z = 2 * Math.Atan2(q1.x,q1.s);
657 eul.y = Math.PI/2;
658 eul.x = 0;
659 return eul;
660 }
661 if (test < -0.4999*unit) { // singularity at south pole
662 eul.z = -2 * Math.Atan2(q1.x,q1.s);
663 eul.y = -Math.PI/2;
664 eul.x = 0;
665 return eul;
666 }
667 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
668 eul.y = Math.Asin(2*test/unit);
669 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
670 return eul;
565 } 671 }
566 672
567 /* From wiki: 673 /* From wiki:
@@ -614,18 +720,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
614 m_host.AddScriptLPS(1); 720 m_host.AddScriptLPS(1);
615 721
616 double x,y,z,s; 722 double x,y,z,s;
617 723 v.x *= 0.5;
618 double c1 = Math.Cos(v.x * 0.5); 724 v.y *= 0.5;
619 double c2 = Math.Cos(v.y * 0.5); 725 v.z *= 0.5;
620 double c3 = Math.Cos(v.z * 0.5); 726 double c1 = Math.Cos(v.x);
621 double s1 = Math.Sin(v.x * 0.5); 727 double c2 = Math.Cos(v.y);
622 double s2 = Math.Sin(v.y * 0.5); 728 double c1c2 = c1 * c2;
623 double s3 = Math.Sin(v.z * 0.5); 729 double s1 = Math.Sin(v.x);
624 730 double s2 = Math.Sin(v.y);
625 x = s1 * c2 * c3 + c1 * s2 * s3; 731 double s1s2 = s1 * s2;
626 y = c1 * s2 * c3 - s1 * c2 * s3; 732 double c1s2 = c1 * s2;
627 z = s1 * s2 * c3 + c1 * c2 * s3; 733 double s1c2 = s1 * c2;
628 s = c1 * c2 * c3 - s1 * s2 * s3; 734 double c3 = Math.Cos(v.z);
735 double s3 = Math.Sin(v.z);
736
737 x = s1c2 * c3 + c1s2 * s3;
738 y = c1s2 * c3 - s1c2 * s3;
739 z = s1s2 * c3 + c1c2 * s3;
740 s = c1c2 * c3 - s1s2 * s3;
629 741
630 return new LSL_Rotation(x, y, z, s); 742 return new LSL_Rotation(x, y, z, s);
631 } 743 }
@@ -763,77 +875,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
763 { 875 {
764 //A and B should both be normalized 876 //A and B should both be normalized
765 m_host.AddScriptLPS(1); 877 m_host.AddScriptLPS(1);
766 LSL_Rotation rotBetween; 878 /* This method is more accurate than the SL one, and thus causes problems
767 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 879 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
768 // continue calculation. 880
769 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 881 double dotProduct = LSL_Vector.Dot(a, b);
770 { 882 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
771 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 883 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
772 } 884 double angle = Math.Acos(dotProduct / magProduct);
773 else 885 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
774 { 886 double s = Math.Sin(angle / 2);
775 a = LSL_Vector.Norm(a); 887
776 b = LSL_Vector.Norm(b); 888 double x = axis.x * s;
777 double dotProduct = LSL_Vector.Dot(a, b); 889 double y = axis.y * s;
778 // There are two degenerate cases possible. These are for vectors 180 or 890 double z = axis.z * s;
779 // 0 degrees apart. These have to be detected and handled individually. 891 double w = Math.Cos(angle / 2);
780 // 892
781 // Check for vectors 180 degrees apart. 893 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
782 // A dot product of -1 would mean the angle between vectors is 180 degrees. 894 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
783 if (dotProduct < -0.9999999f) 895
784 { 896 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
785 // First assume X axis is orthogonal to the vectors. 897 */
786 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 898
787 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 899 // This method mimics the 180 errors found in SL
788 // Check for near zero vector. A very small non-zero number here will create 900 // See www.euclideanspace.com... angleBetween
789 // a rotation in an undesired direction. 901 LSL_Vector vec_a = a;
790 if (LSL_Vector.Mag(orthoVector) > 0.0001) 902 LSL_Vector vec_b = b;
791 { 903
792 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 904 // Eliminate zero length
793 } 905 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
794 // If the magnitude of the vector was near zero, then assume the X axis is not 906 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
795 // orthogonal and use the Z axis instead. 907 if (vec_a_mag < 0.00001 ||
796 else 908 vec_b_mag < 0.00001)
797 { 909 {
798 // Set 180 z rotation. 910 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
799 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f); 911 }
800 } 912
801 } 913 // Normalize
802 // Check for parallel vectors. 914 vec_a = llVecNorm(vec_a);
803 // A dot product of 1 would mean the angle between vectors is 0 degrees. 915 vec_b = llVecNorm(vec_b);
804 else if (dotProduct > 0.9999999f) 916
805 { 917 // Calculate axis and rotation angle
806 // Set zero rotation. 918 LSL_Vector axis = vec_a % vec_b;
807 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 919 LSL_Float cos_theta = vec_a * vec_b;
808 } 920
809 else 921 // Check if parallel
810 { 922 if (cos_theta > 0.99999)
811 // All special checks have been performed so get the axis of rotation. 923 {
812 LSL_Vector crossProduct = LSL_Vector.Cross(a, b); 924 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
813 // Quarternion s value is the length of the unit vector + dot product. 925 }
814 double qs = 1.0 + dotProduct; 926
815 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs); 927 // Check if anti-parallel
816 // Normalize the rotation. 928 else if (cos_theta < -0.99999)
817 double mag = LSL_Rotation.Mag(rotBetween); 929 {
818 // We shouldn't have to worry about a divide by zero here. The qs value will be 930 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
819 // non-zero because we already know if we're here, then the dotProduct is not -1 so 931 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
820 // qs will not be zero. Also, we've already handled the input vectors being zero so the 932 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
821 // crossProduct vector should also not be zero. 933 }
822 rotBetween.x = rotBetween.x / mag; 934 else // other rotation
823 rotBetween.y = rotBetween.y / mag; 935 {
824 rotBetween.z = rotBetween.z / mag; 936 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
825 rotBetween.s = rotBetween.s / mag; 937 axis = llVecNorm(axis);
826 // Check for undefined values and set zero rotation if any found. This code might not actually be required 938 double x, y, z, s, t;
827 // any longer since zero vectors are checked for at the top. 939 s = Math.Cos(theta);
828 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s)) 940 t = Math.Sin(theta);
829 { 941 x = axis.x * t;
830 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 942 y = axis.y * t;
831 } 943 z = axis.z * t;
832 } 944 return new LSL_Rotation(x,y,z,s);
833 } 945 }
834 return rotBetween; 946 }
835 } 947
836
837 public void llWhisper(int channelID, string text) 948 public void llWhisper(int channelID, string text)
838 { 949 {
839 m_host.AddScriptLPS(1); 950 m_host.AddScriptLPS(1);
@@ -849,10 +960,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
849 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 960 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
850 } 961 }
851 962
963 private void CheckSayShoutTime()
964 {
965 DateTime now = DateTime.UtcNow;
966 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
967 {
968 m_lastSayShoutCheck = now;
969 m_SayShoutCount = 0;
970 }
971 else
972 m_SayShoutCount++;
973 }
974
852 public void llSay(int channelID, string text) 975 public void llSay(int channelID, string text)
853 { 976 {
854 m_host.AddScriptLPS(1); 977 m_host.AddScriptLPS(1);
855 978
979 if (channelID == 0)
980// m_SayShoutCount++;
981 CheckSayShoutTime();
982
983 if (m_SayShoutCount >= 11)
984 ScriptSleep(2000);
985
856 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 986 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
857 { 987 {
858 Console.WriteLine(text); 988 Console.WriteLine(text);
@@ -875,6 +1005,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
875 { 1005 {
876 m_host.AddScriptLPS(1); 1006 m_host.AddScriptLPS(1);
877 1007
1008 if (channelID == 0)
1009// m_SayShoutCount++;
1010 CheckSayShoutTime();
1011
1012 if (m_SayShoutCount >= 11)
1013 ScriptSleep(2000);
1014
878 if (text.Length > 1023) 1015 if (text.Length > 1023)
879 text = text.Substring(0, 1023); 1016 text = text.Substring(0, 1023);
880 1017
@@ -906,22 +1043,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
906 1043
907 public void llRegionSayTo(string target, int channel, string msg) 1044 public void llRegionSayTo(string target, int channel, string msg)
908 { 1045 {
1046 string error = String.Empty;
1047
909 if (msg.Length > 1023) 1048 if (msg.Length > 1023)
910 msg = msg.Substring(0, 1023); 1049 msg = msg.Substring(0, 1023);
911 1050
912 m_host.AddScriptLPS(1); 1051 m_host.AddScriptLPS(1);
913 1052
914 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
915 {
916 return;
917 }
918
919 UUID TargetID; 1053 UUID TargetID;
920 UUID.TryParse(target, out TargetID); 1054 UUID.TryParse(target, out TargetID);
921 1055
922 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1056 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
923 if (wComm != null) 1057 if (wComm != null)
924 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1058 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1059 LSLError(error);
925 } 1060 }
926 1061
927 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1062 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1177,10 +1312,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1177 return detectedParams.TouchUV; 1312 return detectedParams.TouchUV;
1178 } 1313 }
1179 1314
1315 [DebuggerNonUserCode]
1180 public virtual void llDie() 1316 public virtual void llDie()
1181 { 1317 {
1182 m_host.AddScriptLPS(1); 1318 m_host.AddScriptLPS(1);
1183 throw new SelfDeleteException(); 1319 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1184 } 1320 }
1185 1321
1186 public LSL_Float llGround(LSL_Vector offset) 1322 public LSL_Float llGround(LSL_Vector offset)
@@ -1251,6 +1387,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1251 1387
1252 public void llSetStatus(int status, int value) 1388 public void llSetStatus(int status, int value)
1253 { 1389 {
1390 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1391 return;
1254 m_host.AddScriptLPS(1); 1392 m_host.AddScriptLPS(1);
1255 1393
1256 int statusrotationaxis = 0; 1394 int statusrotationaxis = 0;
@@ -1274,6 +1412,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1274 if (!allow) 1412 if (!allow)
1275 return; 1413 return;
1276 1414
1415 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1416 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1417 return;
1418
1277 m_host.ScriptSetPhysicsStatus(true); 1419 m_host.ScriptSetPhysicsStatus(true);
1278 } 1420 }
1279 else 1421 else
@@ -1474,6 +1616,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1474 { 1616 {
1475 m_host.AddScriptLPS(1); 1617 m_host.AddScriptLPS(1);
1476 1618
1619 SetColor(m_host, color, face);
1620 }
1621
1622 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1623 {
1624 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1625 return;
1626
1627 Primitive.TextureEntry tex = part.Shape.Textures;
1628 Color4 texcolor;
1629 if (face >= 0 && face < GetNumberOfSides(part))
1630 {
1631 texcolor = tex.CreateFace((uint)face).RGBA;
1632 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1633 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1634 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1635 tex.FaceTextures[face].RGBA = texcolor;
1636 part.UpdateTextureEntry(tex.GetBytes());
1637 return;
1638 }
1639 else if (face == ScriptBaseClass.ALL_SIDES)
1640 {
1641 for (uint i = 0; i < GetNumberOfSides(part); i++)
1642 {
1643 if (tex.FaceTextures[i] != null)
1644 {
1645 texcolor = tex.FaceTextures[i].RGBA;
1646 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1647 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1648 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1649 tex.FaceTextures[i].RGBA = texcolor;
1650 }
1651 texcolor = tex.DefaultTexture.RGBA;
1652 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1653 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1654 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1655 tex.DefaultTexture.RGBA = texcolor;
1656 }
1657 part.UpdateTextureEntry(tex.GetBytes());
1658 return;
1659 }
1660
1477 if (face == ScriptBaseClass.ALL_SIDES) 1661 if (face == ScriptBaseClass.ALL_SIDES)
1478 face = SceneObjectPart.ALL_SIDES; 1662 face = SceneObjectPart.ALL_SIDES;
1479 1663
@@ -1482,6 +1666,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1482 1666
1483 public void SetTexGen(SceneObjectPart part, int face,int style) 1667 public void SetTexGen(SceneObjectPart part, int face,int style)
1484 { 1668 {
1669 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1670 return;
1671
1485 Primitive.TextureEntry tex = part.Shape.Textures; 1672 Primitive.TextureEntry tex = part.Shape.Textures;
1486 MappingType textype; 1673 MappingType textype;
1487 textype = MappingType.Default; 1674 textype = MappingType.Default;
@@ -1512,6 +1699,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1512 1699
1513 public void SetGlow(SceneObjectPart part, int face, float glow) 1700 public void SetGlow(SceneObjectPart part, int face, float glow)
1514 { 1701 {
1702 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1703 return;
1704
1515 Primitive.TextureEntry tex = part.Shape.Textures; 1705 Primitive.TextureEntry tex = part.Shape.Textures;
1516 if (face >= 0 && face < GetNumberOfSides(part)) 1706 if (face >= 0 && face < GetNumberOfSides(part))
1517 { 1707 {
@@ -1537,6 +1727,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1537 1727
1538 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1728 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1539 { 1729 {
1730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1731 return;
1540 1732
1541 Shininess sval = new Shininess(); 1733 Shininess sval = new Shininess();
1542 1734
@@ -1587,6 +1779,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1587 1779
1588 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1780 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1589 { 1781 {
1782 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1783 return;
1784
1590 Primitive.TextureEntry tex = part.Shape.Textures; 1785 Primitive.TextureEntry tex = part.Shape.Textures;
1591 if (face >= 0 && face < GetNumberOfSides(part)) 1786 if (face >= 0 && face < GetNumberOfSides(part))
1592 { 1787 {
@@ -1647,13 +1842,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1647 m_host.AddScriptLPS(1); 1842 m_host.AddScriptLPS(1);
1648 1843
1649 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1844 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1650 1845 if (parts.Count > 0)
1651 foreach (SceneObjectPart part in parts) 1846 {
1652 SetAlpha(part, alpha, face); 1847 try
1848 {
1849 foreach (SceneObjectPart part in parts)
1850 SetAlpha(part, alpha, face);
1851 }
1852 finally
1853 {
1854 }
1855 }
1653 } 1856 }
1654 1857
1655 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1858 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1656 { 1859 {
1860 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1861 return;
1862
1657 Primitive.TextureEntry tex = part.Shape.Textures; 1863 Primitive.TextureEntry tex = part.Shape.Textures;
1658 Color4 texcolor; 1864 Color4 texcolor;
1659 if (face >= 0 && face < GetNumberOfSides(part)) 1865 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1706,7 +1912,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1706 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1912 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1707 float wind, float tension, LSL_Vector Force) 1913 float wind, float tension, LSL_Vector Force)
1708 { 1914 {
1709 if (part == null) 1915 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1710 return; 1916 return;
1711 1917
1712 if (flexi) 1918 if (flexi)
@@ -1747,7 +1953,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1747 /// <param name="falloff"></param> 1953 /// <param name="falloff"></param>
1748 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1954 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1749 { 1955 {
1750 if (part == null) 1956 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1751 return; 1957 return;
1752 1958
1753 if (light) 1959 if (light)
@@ -1780,11 +1986,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1780 Primitive.TextureEntry tex = part.Shape.Textures; 1986 Primitive.TextureEntry tex = part.Shape.Textures;
1781 Color4 texcolor; 1987 Color4 texcolor;
1782 LSL_Vector rgb = new LSL_Vector(); 1988 LSL_Vector rgb = new LSL_Vector();
1989 int nsides = GetNumberOfSides(part);
1990
1783 if (face == ScriptBaseClass.ALL_SIDES) 1991 if (face == ScriptBaseClass.ALL_SIDES)
1784 { 1992 {
1785 int i; 1993 int i;
1786 1994 for (i = 0; i < nsides; i++)
1787 for (i = 0 ; i < GetNumberOfSides(part); i++)
1788 { 1995 {
1789 texcolor = tex.GetFace((uint)i).RGBA; 1996 texcolor = tex.GetFace((uint)i).RGBA;
1790 rgb.x += texcolor.R; 1997 rgb.x += texcolor.R;
@@ -1792,14 +1999,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1792 rgb.z += texcolor.B; 1999 rgb.z += texcolor.B;
1793 } 2000 }
1794 2001
1795 rgb.x /= (float)GetNumberOfSides(part); 2002 float invnsides = 1.0f / (float)nsides;
1796 rgb.y /= (float)GetNumberOfSides(part); 2003
1797 rgb.z /= (float)GetNumberOfSides(part); 2004 rgb.x *= invnsides;
2005 rgb.y *= invnsides;
2006 rgb.z *= invnsides;
1798 2007
1799 return rgb; 2008 return rgb;
1800 } 2009 }
1801 2010 if (face >= 0 && face < nsides)
1802 if (face >= 0 && face < GetNumberOfSides(part))
1803 { 2011 {
1804 texcolor = tex.GetFace((uint)face).RGBA; 2012 texcolor = tex.GetFace((uint)face).RGBA;
1805 rgb.x = texcolor.R; 2013 rgb.x = texcolor.R;
@@ -1826,15 +2034,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1826 m_host.AddScriptLPS(1); 2034 m_host.AddScriptLPS(1);
1827 2035
1828 List<SceneObjectPart> parts = GetLinkParts(linknumber); 2036 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1829 2037 if (parts.Count > 0)
1830 foreach (SceneObjectPart part in parts) 2038 {
1831 SetTexture(part, texture, face); 2039 try
1832 2040 {
2041 foreach (SceneObjectPart part in parts)
2042 SetTexture(part, texture, face);
2043 }
2044 finally
2045 {
2046 }
2047 }
1833 ScriptSleep(200); 2048 ScriptSleep(200);
1834 } 2049 }
1835 2050
1836 protected void SetTexture(SceneObjectPart part, string texture, int face) 2051 protected void SetTexture(SceneObjectPart part, string texture, int face)
1837 { 2052 {
2053 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2054 return;
2055
1838 UUID textureID = new UUID(); 2056 UUID textureID = new UUID();
1839 2057
1840 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture); 2058 textureID = ScriptUtils.GetAssetIdFromItemName(m_host, texture, (int)AssetType.Texture);
@@ -1879,6 +2097,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1879 2097
1880 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2098 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1881 { 2099 {
2100 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2101 return;
2102
1882 Primitive.TextureEntry tex = part.Shape.Textures; 2103 Primitive.TextureEntry tex = part.Shape.Textures;
1883 if (face >= 0 && face < GetNumberOfSides(part)) 2104 if (face >= 0 && face < GetNumberOfSides(part))
1884 { 2105 {
@@ -1915,6 +2136,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1915 2136
1916 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2137 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1917 { 2138 {
2139 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2140 return;
2141
1918 Primitive.TextureEntry tex = part.Shape.Textures; 2142 Primitive.TextureEntry tex = part.Shape.Textures;
1919 if (face >= 0 && face < GetNumberOfSides(part)) 2143 if (face >= 0 && face < GetNumberOfSides(part))
1920 { 2144 {
@@ -1951,6 +2175,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1951 2175
1952 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2176 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1953 { 2177 {
2178 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2179 return;
2180
1954 Primitive.TextureEntry tex = part.Shape.Textures; 2181 Primitive.TextureEntry tex = part.Shape.Textures;
1955 if (face >= 0 && face < GetNumberOfSides(part)) 2182 if (face >= 0 && face < GetNumberOfSides(part))
1956 { 2183 {
@@ -2092,7 +2319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2092 return end; 2319 return end;
2093 } 2320 }
2094 2321
2095 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos) 2322 protected LSL_Vector GetSetPosTarget(SceneObjectPart part, LSL_Vector targetPos, LSL_Vector fromPos, bool adjust)
2096 { 2323 {
2097 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted) 2324 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2098 return fromPos; 2325 return fromPos;
@@ -2108,9 +2335,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2108 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0) 2335 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2109 targetPos.z = ground; 2336 targetPos.z = ground;
2110 } 2337 }
2111 LSL_Vector real_vec = SetPosAdjust(fromPos, targetPos); 2338 if (adjust)
2339 return SetPosAdjust(fromPos, targetPos);
2112 2340
2113 return real_vec; 2341 return targetPos;
2114 } 2342 }
2115 2343
2116 /// <summary> 2344 /// <summary>
@@ -2121,27 +2349,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2121 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2349 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2122 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2350 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2123 { 2351 {
2124 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2352 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2353 return;
2354
2125 LSL_Vector currentPos = GetPartLocalPos(part); 2355 LSL_Vector currentPos = GetPartLocalPos(part);
2356 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos, adjust);
2126 2357
2127 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2128 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2129 2358
2130 if (part.ParentGroup.RootPart == part) 2359 if (part.ParentGroup.RootPart == part)
2131 { 2360 {
2132 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2133 targetPos.z = ground;
2134 SceneObjectGroup parent = part.ParentGroup; 2361 SceneObjectGroup parent = part.ParentGroup;
2135 parent.UpdateGroupPosition(!adjust ? targetPos : 2362 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2136 SetPosAdjust(currentPos, targetPos)); 2363 return;
2364 Util.FireAndForget(delegate(object x) {
2365 parent.UpdateGroupPosition((Vector3)toPos);
2366 });
2137 } 2367 }
2138 else 2368 else
2139 { 2369 {
2140 part.OffsetPosition = !adjust ? targetPos : 2370 part.OffsetPosition = (Vector3)toPos;
2141 SetPosAdjust(currentPos, targetPos); 2371// SceneObjectGroup parent = part.ParentGroup;
2142 SceneObjectGroup parent = part.ParentGroup; 2372// parent.HasGroupChanged = true;
2143 parent.HasGroupChanged = true; 2373// parent.ScheduleGroupForTerseUpdate();
2144 parent.ScheduleGroupForTerseUpdate(); 2374 part.ScheduleTerseUpdate();
2145 } 2375 }
2146 } 2376 }
2147 2377
@@ -2170,13 +2400,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2170 else 2400 else
2171 { 2401 {
2172 if (part.ParentGroup.IsAttachment) 2402 if (part.ParentGroup.IsAttachment)
2173 {
2174 pos = part.AttachedPos; 2403 pos = part.AttachedPos;
2175 }
2176 else 2404 else
2177 {
2178 pos = part.AbsolutePosition; 2405 pos = part.AbsolutePosition;
2179 }
2180 } 2406 }
2181 2407
2182// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2408// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2188,8 +2414,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 { 2414 {
2189 m_host.AddScriptLPS(1); 2415 m_host.AddScriptLPS(1);
2190 2416
2417
2418 // Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
2419 // which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
2420 // to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
2421 // RootPart != null should shortcircuit
2422
2191 // try to let this work as in SL... 2423 // try to let this work as in SL...
2192 if (m_host.ParentID == 0) 2424 if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
2193 { 2425 {
2194 // special case: If we are root, rotate complete SOG to new rotation 2426 // special case: If we are root, rotate complete SOG to new rotation
2195 SetRot(m_host, rot); 2427 SetRot(m_host, rot);
@@ -2216,25 +2448,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 2448
2217 protected void SetRot(SceneObjectPart part, Quaternion rot) 2449 protected void SetRot(SceneObjectPart part, Quaternion rot)
2218 { 2450 {
2219 part.UpdateRotation(rot); 2451 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2220 // Update rotation does not move the object in the physics scene if it's a linkset. 2452 return;
2221 2453
2222//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2454 bool isroot = (part == part.ParentGroup.RootPart);
2223// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2455 bool isphys;
2224 2456
2225 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2226 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2227 // It's perfectly okay when the object is not an active physical body though.
2228 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2229 // but only if the object is not physial and active. This is important for rotating doors.
2230 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2231 // scene
2232 PhysicsActor pa = part.PhysActor; 2457 PhysicsActor pa = part.PhysActor;
2233 2458
2234 if (pa != null && !pa.IsPhysical) 2459 // keep using physactor ideia of isphysical
2460 // it should be SOP ideia of that
2461 // not much of a issue with ubitODE
2462 if (pa != null && pa.IsPhysical)
2463 isphys = true;
2464 else
2465 isphys = false;
2466
2467 // SL doesn't let scripts rotate root of physical linksets
2468 if (isroot && isphys)
2469 return;
2470
2471 part.UpdateRotation(rot);
2472
2473 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2474 // so do a nasty update of parts positions if is a root part rotation
2475 if (isroot && pa != null) // with if above implies non physical root part
2235 { 2476 {
2236 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2477 part.ParentGroup.ResetChildPrimPhysicsPositions();
2237 } 2478 }
2479 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2480 {
2481 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2482 if (sittingavas.Count > 0)
2483 {
2484 foreach (ScenePresence av in sittingavas)
2485 {
2486 if (isroot || part.LocalId == av.ParentID)
2487 av.SendTerseUpdateToAllClients();
2488 }
2489 }
2490 }
2238 } 2491 }
2239 2492
2240 /// <summary> 2493 /// <summary>
@@ -2251,6 +2504,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2251 2504
2252 m_host.AddScriptLPS(1); 2505 m_host.AddScriptLPS(1);
2253 Quaternion q = m_host.GetWorldRotation(); 2506 Quaternion q = m_host.GetWorldRotation();
2507
2508 if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
2509 {
2510 ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2511 if (avatar != null)
2512 {
2513 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2514 q = avatar.CameraRotation * q; // Mouselook
2515 else
2516 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2517 }
2518 }
2519
2254 return new LSL_Rotation(q.X, q.Y, q.Z, q.W); 2520 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2255 } 2521 }
2256 2522
@@ -2278,14 +2544,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2278 return new LSL_Rotation(q); 2544 return new LSL_Rotation(q);
2279 } 2545 }
2280 2546
2281 return new LSL_Rotation(part.GetWorldRotation()); 2547 q = part.GetWorldRotation();
2548 if (part.ParentGroup.AttachmentPoint != 0)
2549 {
2550 ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
2551 if (avatar != null)
2552 {
2553 if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
2554 q = avatar.CameraRotation * q; // Mouselook
2555 else
2556 q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
2557 }
2558 }
2559
2560 return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
2282 } 2561 }
2283 2562
2284 public LSL_Rotation llGetLocalRot() 2563 public LSL_Rotation llGetLocalRot()
2285 { 2564 {
2286 m_host.AddScriptLPS(1); 2565 return GetPartLocalRot(m_host);
2566 }
2287 2567
2288 return new LSL_Rotation(m_host.RotationOffset); 2568 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2569 {
2570 m_host.AddScriptLPS(1);
2571 Quaternion rot = part.RotationOffset;
2572 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2289 } 2573 }
2290 2574
2291 public void llSetForce(LSL_Vector force, int local) 2575 public void llSetForce(LSL_Vector force, int local)
@@ -2365,16 +2649,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2365 m_host.ApplyImpulse(v, local != 0); 2649 m_host.ApplyImpulse(v, local != 0);
2366 } 2650 }
2367 2651
2652
2368 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2653 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2369 { 2654 {
2370 m_host.AddScriptLPS(1); 2655 m_host.AddScriptLPS(1);
2371 m_host.ApplyAngularImpulse(force, local != 0); 2656 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2372 } 2657 }
2373 2658
2374 public void llSetTorque(LSL_Vector torque, int local) 2659 public void llSetTorque(LSL_Vector torque, int local)
2375 { 2660 {
2376 m_host.AddScriptLPS(1); 2661 m_host.AddScriptLPS(1);
2377 m_host.SetAngularImpulse(torque, local != 0); 2662 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2378 } 2663 }
2379 2664
2380 public LSL_Vector llGetTorque() 2665 public LSL_Vector llGetTorque()
@@ -2391,20 +2676,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2391 llSetTorque(torque, local); 2676 llSetTorque(torque, local);
2392 } 2677 }
2393 2678
2679 public void llSetVelocity(LSL_Vector vel, int local)
2680 {
2681 m_host.AddScriptLPS(1);
2682 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2683 }
2684
2394 public LSL_Vector llGetVel() 2685 public LSL_Vector llGetVel()
2395 { 2686 {
2396 m_host.AddScriptLPS(1); 2687 m_host.AddScriptLPS(1);
2397 2688
2398 Vector3 vel; 2689 Vector3 vel = Vector3.Zero;
2399 2690
2400 if (m_host.ParentGroup.IsAttachment) 2691 if (m_host.ParentGroup.IsAttachment)
2401 { 2692 {
2402 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2693 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2403 vel = avatar.Velocity; 2694 if (avatar != null)
2695 vel = avatar.Velocity;
2404 } 2696 }
2405 else 2697 else
2406 { 2698 {
2407 vel = m_host.Velocity; 2699 vel = m_host.ParentGroup.RootPart.Velocity;
2408 } 2700 }
2409 2701
2410 return new LSL_Vector(vel); 2702 return new LSL_Vector(vel);
@@ -2417,11 +2709,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2417 return new LSL_Vector(m_host.Acceleration); 2709 return new LSL_Vector(m_host.Acceleration);
2418 } 2710 }
2419 2711
2420 public LSL_Vector llGetOmega() 2712 public void llSetAngularVelocity(LSL_Vector avel, int local)
2421 { 2713 {
2422 m_host.AddScriptLPS(1); 2714 m_host.AddScriptLPS(1);
2715 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2716 }
2423 2717
2424 return new LSL_Vector(m_host.AngularVelocity); 2718 public LSL_Vector llGetOmega()
2719 {
2720 m_host.AddScriptLPS(1);
2721 Vector3 avel = m_host.AngularVelocity;
2722 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2425 } 2723 }
2426 2724
2427 public LSL_Float llGetTimeOfDay() 2725 public LSL_Float llGetTimeOfDay()
@@ -2782,7 +3080,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2782 return src.ToLower(); 3080 return src.ToLower();
2783 } 3081 }
2784 3082
2785 public void llGiveMoney(string destination, int amount) 3083 public LSL_Integer llGiveMoney(string destination, int amount)
2786 { 3084 {
2787 Util.FireAndForget(x => 3085 Util.FireAndForget(x =>
2788 { 3086 {
@@ -2814,8 +3112,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2814 } 3112 }
2815 3113
2816 money.ObjectGiveMoney( 3114 money.ObjectGiveMoney(
2817 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3115 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2818 }); 3116 });
3117
3118 return 0;
2819 } 3119 }
2820 3120
2821 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 3121 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
@@ -2894,13 +3194,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2894 new_group.RootPart.UUID.ToString()) }, 3194 new_group.RootPart.UUID.ToString()) },
2895 new DetectParams[0])); 3195 new DetectParams[0]));
2896 3196
2897 float groupmass = new_group.GetMass(); 3197 // do recoil
3198 SceneObjectGroup hostgrp = m_host.ParentGroup;
3199 if (hostgrp == null)
3200 return;
3201
3202 if (hostgrp.IsAttachment) // don't recoil avatars
3203 return;
2898 3204
2899 PhysicsActor pa = new_group.RootPart.PhysActor; 3205 PhysicsActor pa = new_group.RootPart.PhysActor;
2900 3206
2901 //Recoil. 3207 //Recoil.
2902 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3208 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2903 { 3209 {
3210 float groupmass = new_group.GetMass();
2904 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3211 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2905 if (recoil != Vector3.Zero) 3212 if (recoil != Vector3.Zero)
2906 { 3213 {
@@ -2908,6 +3215,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2908 } 3215 }
2909 } 3216 }
2910 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3217 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3218 return;
3219
2911 }); 3220 });
2912 3221
2913 //ScriptSleep((int)((groupmass * velmag) / 10)); 3222 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2922,35 +3231,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2922 public void llLookAt(LSL_Vector target, double strength, double damping) 3231 public void llLookAt(LSL_Vector target, double strength, double damping)
2923 { 3232 {
2924 m_host.AddScriptLPS(1); 3233 m_host.AddScriptLPS(1);
2925 // Determine where we are looking from
2926 LSL_Vector from = llGetPos();
2927
2928 // Work out the normalised vector from the source to the target
2929 LSL_Vector delta = llVecNorm(target - from);
2930 LSL_Vector angle = new LSL_Vector(0,0,0);
2931 3234
2932 // Calculate the yaw 3235 // Get the normalized vector to the target
2933 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3236 LSL_Vector d1 = llVecNorm(target - llGetPos());
2934 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO;
2935 3237
2936 // Calculate pitch 3238 // Get the bearing (yaw)
2937 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3239 LSL_Vector a1 = new LSL_Vector(0,0,0);
3240 a1.z = llAtan2(d1.y, d1.x);
2938 3241
2939 // we need to convert from a vector describing 3242 // Get the elevation (pitch)
2940 // the angles of rotation in radians into rotation value 3243 LSL_Vector a2 = new LSL_Vector(0,0,0);
2941 LSL_Rotation rot = llEuler2Rot(angle); 3244 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2942 3245
2943 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply 3246 LSL_Rotation r1 = llEuler2Rot(a1);
2944 // set the rotation of the object, copy that behavior 3247 LSL_Rotation r2 = llEuler2Rot(a2);
2945 PhysicsActor pa = m_host.PhysActor; 3248 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2946 3249
2947 if (strength == 0 || pa == null || !pa.IsPhysical) 3250 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2948 { 3251 {
2949 llSetRot(rot); 3252 // Do nothing if either value is 0 (this has been checked in SL)
3253 if (strength <= 0.0 || damping <= 0.0)
3254 return;
3255
3256 llSetRot(r3 * r2 * r1);
2950 } 3257 }
2951 else 3258 else
2952 { 3259 {
2953 m_host.StartLookAt(rot, (float)strength, (float)damping); 3260 if (strength == 0)
3261 {
3262 llSetRot(r3 * r2 * r1);
3263 return;
3264 }
3265
3266 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2954 } 3267 }
2955 } 3268 }
2956 3269
@@ -2997,17 +3310,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2997 } 3310 }
2998 else 3311 else
2999 { 3312 {
3000 if (m_host.IsRoot) 3313 // new SL always returns object mass
3001 { 3314// if (m_host.IsRoot)
3315// {
3002 return m_host.ParentGroup.GetMass(); 3316 return m_host.ParentGroup.GetMass();
3003 } 3317// }
3004 else 3318// else
3005 { 3319// {
3006 return m_host.GetMass(); 3320// return m_host.GetMass();
3007 } 3321// }
3008 } 3322 }
3009 } 3323 }
3010 3324
3325
3326 public LSL_Float llGetMassMKS()
3327 {
3328 return 100f * llGetMass();
3329 }
3330
3011 public void llCollisionFilter(string name, string id, int accept) 3331 public void llCollisionFilter(string name, string id, int accept)
3012 { 3332 {
3013 m_host.AddScriptLPS(1); 3333 m_host.AddScriptLPS(1);
@@ -3055,8 +3375,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3055 { 3375 {
3056 // Unregister controls from Presence 3376 // Unregister controls from Presence
3057 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3377 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
3058 // Remove Take Control permission.
3059 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3060 } 3378 }
3061 } 3379 }
3062 } 3380 }
@@ -3084,7 +3402,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3084 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3402 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3085 3403
3086 if (attachmentsModule != null) 3404 if (attachmentsModule != null)
3087 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, true); 3405 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false, true);
3088 else 3406 else
3089 return false; 3407 return false;
3090 } 3408 }
@@ -3114,9 +3432,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3114 { 3432 {
3115 m_host.AddScriptLPS(1); 3433 m_host.AddScriptLPS(1);
3116 3434
3117// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3118// return;
3119
3120 if (m_item.PermsGranter != m_host.OwnerID) 3435 if (m_item.PermsGranter != m_host.OwnerID)
3121 return; 3436 return;
3122 3437
@@ -3159,6 +3474,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3159 3474
3160 public void llInstantMessage(string user, string message) 3475 public void llInstantMessage(string user, string message)
3161 { 3476 {
3477 UUID result;
3478 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3479 {
3480 ShoutError("An invalid key was passed to llInstantMessage");
3481 ScriptSleep(2000);
3482 return;
3483 }
3484
3485
3162 m_host.AddScriptLPS(1); 3486 m_host.AddScriptLPS(1);
3163 3487
3164 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3488 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3173,14 +3497,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3173 UUID friendTransactionID = UUID.Random(); 3497 UUID friendTransactionID = UUID.Random();
3174 3498
3175 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3499 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3176 3500
3177 GridInstantMessage msg = new GridInstantMessage(); 3501 GridInstantMessage msg = new GridInstantMessage();
3178 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3502 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3179 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3503 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3180 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3504 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3181// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3505// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3182// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3506// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3183 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3507// DateTime dt = DateTime.UtcNow;
3508//
3509// // Ticks from UtcNow, but make it look like local. Evil, huh?
3510// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3511//
3512// try
3513// {
3514// // Convert that to the PST timezone
3515// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3516// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3517// }
3518// catch
3519// {
3520// // No logging here, as it could be VERY spammy
3521// }
3522//
3523// // And make it look local again to fool the unix time util
3524// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3525
3526 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3527
3184 //if (client != null) 3528 //if (client != null)
3185 //{ 3529 //{
3186 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3530 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3194,10 +3538,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3194 msg.message = message.Substring(0, 1024); 3538 msg.message = message.Substring(0, 1024);
3195 else 3539 else
3196 msg.message = message; 3540 msg.message = message;
3197 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3541 msg.dialog = (byte)19; // MessageFromObject
3198 msg.fromGroup = false;// fromGroup; 3542 msg.fromGroup = false;// fromGroup;
3199 msg.offline = (byte)0; //offline; 3543 msg.offline = (byte)0; //offline;
3200 msg.ParentEstateID = 0; //ParentEstateID; 3544 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3201 msg.Position = new Vector3(m_host.AbsolutePosition); 3545 msg.Position = new Vector3(m_host.AbsolutePosition);
3202 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3546 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid;
3203 3547
@@ -3229,7 +3573,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3229 } 3573 }
3230 3574
3231 emailModule.SendEmail(m_host.UUID, address, subject, message); 3575 emailModule.SendEmail(m_host.UUID, address, subject, message);
3232 llSleep(EMAIL_PAUSE_TIME); 3576 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3233 } 3577 }
3234 3578
3235 public void llGetNextEmail(string address, string subject) 3579 public void llGetNextEmail(string address, string subject)
@@ -3475,7 +3819,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3475 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3819 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3476 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3820 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3477 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3821 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3822 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3478 ScriptBaseClass.PERMISSION_ATTACH; 3823 ScriptBaseClass.PERMISSION_ATTACH;
3824
3479 } 3825 }
3480 else 3826 else
3481 { 3827 {
@@ -3492,15 +3838,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3492 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3838 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3493 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3839 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3494 } 3840 }
3841 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3842 {
3843 implicitPerms = perm;
3844 }
3495 } 3845 }
3496 3846
3497 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3847 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3498 { 3848 {
3499 lock (m_host.TaskInventory) 3849 m_host.TaskInventory.LockItemsForWrite(true);
3500 { 3850 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3501 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3851 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3502 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3852 m_host.TaskInventory.LockItemsForWrite(false);
3503 }
3504 3853
3505 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3854 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3506 "run_time_permissions", new Object[] { 3855 "run_time_permissions", new Object[] {
@@ -3543,11 +3892,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3543 3892
3544 if (!m_waitingForScriptAnswer) 3893 if (!m_waitingForScriptAnswer)
3545 { 3894 {
3546 lock (m_host.TaskInventory) 3895 m_host.TaskInventory.LockItemsForWrite(true);
3547 { 3896 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3548 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3897 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3549 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3898 m_host.TaskInventory.LockItemsForWrite(false);
3550 }
3551 3899
3552 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3900 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3553 m_waitingForScriptAnswer=true; 3901 m_waitingForScriptAnswer=true;
@@ -3576,14 +3924,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3576 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3924 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3577 llReleaseControls(); 3925 llReleaseControls();
3578 3926
3579 lock (m_host.TaskInventory) 3927 m_host.TaskInventory.LockItemsForWrite(true);
3580 { 3928 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3581 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3929 m_host.TaskInventory.LockItemsForWrite(false);
3582 } 3930
3583 3931 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3584 m_ScriptEngine.PostScriptEvent( 3932 "run_time_permissions", new Object[] {
3585 m_item.ItemID, 3933 new LSL_Integer(answer) },
3586 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3934 new DetectParams[0]));
3587 } 3935 }
3588 3936
3589 public LSL_String llGetPermissionsKey() 3937 public LSL_String llGetPermissionsKey()
@@ -3622,14 +3970,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3622 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3970 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3623 { 3971 {
3624 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3972 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3625 3973 if (parts.Count > 0)
3626 foreach (SceneObjectPart part in parts) 3974 {
3627 part.SetFaceColorAlpha(face, color, null); 3975 try
3976 {
3977 foreach (SceneObjectPart part in parts)
3978 part.SetFaceColorAlpha(face, color, null);
3979 }
3980 finally
3981 {
3982 }
3983 }
3628 } 3984 }
3629 3985
3630 public void llCreateLink(string target, int parent) 3986 public void llCreateLink(string target, int parent)
3631 { 3987 {
3632 m_host.AddScriptLPS(1); 3988 m_host.AddScriptLPS(1);
3989
3633 UUID targetID; 3990 UUID targetID;
3634 3991
3635 if (!UUID.TryParse(target, out targetID)) 3992 if (!UUID.TryParse(target, out targetID))
@@ -3735,10 +4092,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3735 // Restructuring Multiple Prims. 4092 // Restructuring Multiple Prims.
3736 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4093 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3737 parts.Remove(parentPrim.RootPart); 4094 parts.Remove(parentPrim.RootPart);
3738 foreach (SceneObjectPart part in parts) 4095 if (parts.Count > 0)
3739 { 4096 {
3740 parentPrim.DelinkFromGroup(part.LocalId, true); 4097 try
4098 {
4099 foreach (SceneObjectPart part in parts)
4100 {
4101 parentPrim.DelinkFromGroup(part.LocalId, true);
4102 }
4103 }
4104 finally
4105 {
4106 }
3741 } 4107 }
4108
3742 parentPrim.HasGroupChanged = true; 4109 parentPrim.HasGroupChanged = true;
3743 parentPrim.ScheduleGroupForFullUpdate(); 4110 parentPrim.ScheduleGroupForFullUpdate();
3744 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4111 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3747,12 +4114,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3747 { 4114 {
3748 SceneObjectPart newRoot = parts[0]; 4115 SceneObjectPart newRoot = parts[0];
3749 parts.Remove(newRoot); 4116 parts.Remove(newRoot);
3750 foreach (SceneObjectPart part in parts) 4117
4118 try
3751 { 4119 {
3752 // Required for linking 4120 foreach (SceneObjectPart part in parts)
3753 part.ClearUpdateSchedule(); 4121 {
3754 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4122 part.ClearUpdateSchedule();
4123 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4124 }
3755 } 4125 }
4126 finally
4127 {
4128 }
4129
4130
3756 newRoot.ParentGroup.HasGroupChanged = true; 4131 newRoot.ParentGroup.HasGroupChanged = true;
3757 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4132 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3758 } 4133 }
@@ -3772,6 +4147,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3772 public void llBreakAllLinks() 4147 public void llBreakAllLinks()
3773 { 4148 {
3774 m_host.AddScriptLPS(1); 4149 m_host.AddScriptLPS(1);
4150
4151 TaskInventoryItem item = m_item;
4152
4153 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4154 && !m_automaticLinkPermission)
4155 {
4156 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4157 return;
4158 }
4159
3775 SceneObjectGroup parentPrim = m_host.ParentGroup; 4160 SceneObjectGroup parentPrim = m_host.ParentGroup;
3776 if (parentPrim.AttachmentPoint != 0) 4161 if (parentPrim.AttachmentPoint != 0)
3777 return; // Fail silently if attached 4162 return; // Fail silently if attached
@@ -3791,13 +4176,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3791 public LSL_String llGetLinkKey(int linknum) 4176 public LSL_String llGetLinkKey(int linknum)
3792 { 4177 {
3793 m_host.AddScriptLPS(1); 4178 m_host.AddScriptLPS(1);
4179 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
4180 if (part != null)
4181 {
4182 return part.UUID.ToString();
4183 }
4184 else
4185 {
4186 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4187 {
4188 linknum -= (m_host.ParentGroup.PrimCount) + 1;
3794 4189
3795 ISceneEntity entity = GetLinkEntity(linknum); 4190 if (linknum < 0)
4191 return UUID.Zero.ToString();
3796 4192
3797 if (entity != null) 4193 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
3798 return entity.UUID.ToString(); 4194 if (avatars.Count > linknum)
3799 else 4195 {
3800 return ScriptBaseClass.NULL_KEY; 4196 return avatars[linknum].UUID.ToString();
4197 }
4198 }
4199 return UUID.Zero.ToString();
4200 }
3801 } 4201 }
3802 4202
3803 /// <summary> 4203 /// <summary>
@@ -3856,17 +4256,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3856 m_host.AddScriptLPS(1); 4256 m_host.AddScriptLPS(1);
3857 int count = 0; 4257 int count = 0;
3858 4258
3859 lock (m_host.TaskInventory) 4259 m_host.TaskInventory.LockItemsForRead(true);
4260 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3860 { 4261 {
3861 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4262 if (inv.Value.Type == type || type == -1)
3862 { 4263 {
3863 if (inv.Value.Type == type || type == -1) 4264 count = count + 1;
3864 {
3865 count = count + 1;
3866 }
3867 } 4265 }
3868 } 4266 }
3869 4267
4268 m_host.TaskInventory.LockItemsForRead(false);
3870 return count; 4269 return count;
3871 } 4270 }
3872 4271
@@ -3875,16 +4274,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3875 m_host.AddScriptLPS(1); 4274 m_host.AddScriptLPS(1);
3876 ArrayList keys = new ArrayList(); 4275 ArrayList keys = new ArrayList();
3877 4276
3878 lock (m_host.TaskInventory) 4277 m_host.TaskInventory.LockItemsForRead(true);
4278 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3879 { 4279 {
3880 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4280 if (inv.Value.Type == type || type == -1)
3881 { 4281 {
3882 if (inv.Value.Type == type || type == -1) 4282 keys.Add(inv.Value.Name);
3883 {
3884 keys.Add(inv.Value.Name);
3885 }
3886 } 4283 }
3887 } 4284 }
4285 m_host.TaskInventory.LockItemsForRead(false);
3888 4286
3889 if (keys.Count == 0) 4287 if (keys.Count == 0)
3890 { 4288 {
@@ -3922,7 +4320,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3922 if (item == null) 4320 if (item == null)
3923 { 4321 {
3924 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4322 llSay(0, String.Format("Could not find object '{0}'", inventory));
3925 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4323 return;
4324// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3926 } 4325 }
3927 4326
3928 UUID objId = item.ItemID; 4327 UUID objId = item.ItemID;
@@ -3950,33 +4349,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3950 return; 4349 return;
3951 } 4350 }
3952 } 4351 }
4352
3953 // destination is an avatar 4353 // destination is an avatar
3954 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4354 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3955 4355
3956 if (agentItem == null) 4356 if (agentItem == null)
3957 return; 4357 return;
3958 4358
3959 if (m_TransferModule != null) 4359 byte[] bucket = new byte[1];
3960 { 4360 bucket[0] = (byte)item.Type;
3961 byte[] bucket = new byte[1]; 4361 //byte[] objBytes = agentItem.ID.GetBytes();
3962 bucket[0] = (byte)item.Type; 4362 //Array.Copy(objBytes, 0, bucket, 1, 16);
3963 4363
3964 GridInstantMessage msg = new GridInstantMessage(World, 4364 GridInstantMessage msg = new GridInstantMessage(World,
3965 m_host.OwnerID, m_host.Name, destId, 4365 m_host.OwnerID, m_host.Name, destId,
3966 (byte)InstantMessageDialog.TaskInventoryOffered, 4366 (byte)InstantMessageDialog.TaskInventoryOffered,
3967 false, item.Name+". "+m_host.Name+" is located at "+ 4367 false, item.Name+". "+m_host.Name+" is located at "+
3968 World.RegionInfo.RegionName+" "+ 4368 World.RegionInfo.RegionName+" "+
3969 m_host.AbsolutePosition.ToString(), 4369 m_host.AbsolutePosition.ToString(),
3970 agentItem.ID, true, m_host.AbsolutePosition, 4370 agentItem.ID, true, m_host.AbsolutePosition,
3971 bucket, true); 4371 bucket, true);
3972 4372
3973 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4373 ScenePresence sp;
3974 }
3975 4374
4375 if (World.TryGetScenePresence(destId, out sp))
4376 {
4377 sp.ControllingClient.SendInstantMessage(msg);
4378 }
4379 else
4380 {
4381 if (m_TransferModule != null)
4382 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4383 }
4384
4385 //This delay should only occur when giving inventory to avatars.
3976 ScriptSleep(3000); 4386 ScriptSleep(3000);
3977 } 4387 }
3978 } 4388 }
3979 4389
4390 [DebuggerNonUserCode]
3980 public void llRemoveInventory(string name) 4391 public void llRemoveInventory(string name)
3981 { 4392 {
3982 m_host.AddScriptLPS(1); 4393 m_host.AddScriptLPS(1);
@@ -4031,109 +4442,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4031 { 4442 {
4032 m_host.AddScriptLPS(1); 4443 m_host.AddScriptLPS(1);
4033 4444
4034 UUID uuid = (UUID)id; 4445 UUID uuid;
4035 PresenceInfo pinfo = null; 4446 if (UUID.TryParse(id, out uuid))
4036 UserAccount account;
4037
4038 UserInfoCacheEntry ce;
4039 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4040 { 4447 {
4041 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4448 PresenceInfo pinfo = null;
4042 if (account == null) 4449 UserAccount account;
4450
4451 UserInfoCacheEntry ce;
4452 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4043 { 4453 {
4044 m_userInfoCache[uuid] = null; // Cache negative 4454 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4045 return UUID.Zero.ToString(); 4455 if (account == null)
4046 } 4456 {
4457 m_userInfoCache[uuid] = null; // Cache negative
4458 return UUID.Zero.ToString();
4459 }
4047 4460
4048 4461
4049 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4462 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4050 if (pinfos != null && pinfos.Length > 0) 4463 if (pinfos != null && pinfos.Length > 0)
4051 {
4052 foreach (PresenceInfo p in pinfos)
4053 { 4464 {
4054 if (p.RegionID != UUID.Zero) 4465 foreach (PresenceInfo p in pinfos)
4055 { 4466 {
4056 pinfo = p; 4467 if (p.RegionID != UUID.Zero)
4468 {
4469 pinfo = p;
4470 }
4057 } 4471 }
4058 } 4472 }
4059 }
4060 4473
4061 ce = new UserInfoCacheEntry(); 4474 ce = new UserInfoCacheEntry();
4062 ce.time = Util.EnvironmentTickCount(); 4475 ce.time = Util.EnvironmentTickCount();
4063 ce.account = account; 4476 ce.account = account;
4064 ce.pinfo = pinfo; 4477 ce.pinfo = pinfo;
4065 } 4478 m_userInfoCache[uuid] = ce;
4066 else 4479 }
4067 { 4480 else
4068 if (ce == null) 4481 {
4069 return UUID.Zero.ToString(); 4482 if (ce == null)
4483 return UUID.Zero.ToString();
4070 4484
4071 account = ce.account; 4485 account = ce.account;
4072 pinfo = ce.pinfo; 4486 pinfo = ce.pinfo;
4073 } 4487 }
4074 4488
4075 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4489 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4076 {
4077 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4078 if (pinfos != null && pinfos.Length > 0)
4079 { 4490 {
4080 foreach (PresenceInfo p in pinfos) 4491 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4492 if (pinfos != null && pinfos.Length > 0)
4081 { 4493 {
4082 if (p.RegionID != UUID.Zero) 4494 foreach (PresenceInfo p in pinfos)
4083 { 4495 {
4084 pinfo = p; 4496 if (p.RegionID != UUID.Zero)
4497 {
4498 pinfo = p;
4499 }
4085 } 4500 }
4086 } 4501 }
4087 } 4502 else
4088 else 4503 pinfo = null;
4089 pinfo = null;
4090 4504
4091 ce.time = Util.EnvironmentTickCount(); 4505 ce.time = Util.EnvironmentTickCount();
4092 ce.pinfo = pinfo; 4506 ce.pinfo = pinfo;
4093 } 4507 }
4094 4508
4095 string reply = String.Empty; 4509 string reply = String.Empty;
4096 4510
4097 switch (data) 4511 switch (data)
4098 { 4512 {
4099 case 1: // DATA_ONLINE (0|1) 4513 case 1: // DATA_ONLINE (0|1)
4100 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4514 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4101 reply = "1"; 4515 reply = "1";
4102 else 4516 else
4103 reply = "0"; 4517 reply = "0";
4104 break; 4518 break;
4105 case 2: // DATA_NAME (First Last) 4519 case 2: // DATA_NAME (First Last)
4106 reply = account.FirstName + " " + account.LastName; 4520 reply = account.FirstName + " " + account.LastName;
4107 break; 4521 break;
4108 case 3: // DATA_BORN (YYYY-MM-DD) 4522 case 3: // DATA_BORN (YYYY-MM-DD)
4109 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4523 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4110 born = born.AddSeconds(account.Created); 4524 born = born.AddSeconds(account.Created);
4111 reply = born.ToString("yyyy-MM-dd"); 4525 reply = born.ToString("yyyy-MM-dd");
4112 break; 4526 break;
4113 case 4: // DATA_RATING (0,0,0,0,0,0) 4527 case 4: // DATA_RATING (0,0,0,0,0,0)
4114 reply = "0,0,0,0,0,0"; 4528 reply = "0,0,0,0,0,0";
4115 break; 4529 break;
4116 case 7: // DATA_USERLEVEL (integer) 4530 case 8: // DATA_PAYINFO (0|1|2|3)
4117 reply = account.UserLevel.ToString(); 4531 reply = "0";
4118 break; 4532 break;
4119 case 8: // DATA_PAYINFO (0|1|2|3) 4533 default:
4120 reply = "0"; 4534 return UUID.Zero.ToString(); // Raise no event
4121 break; 4535 }
4122 default:
4123 return UUID.Zero.ToString(); // Raise no event
4124 }
4125 4536
4126 UUID rq = UUID.Random(); 4537 UUID rq = UUID.Random();
4127 4538
4128 UUID tid = AsyncCommands. 4539 UUID tid = AsyncCommands.
4129 DataserverPlugin.RegisterRequest(m_host.LocalId, 4540 DataserverPlugin.RegisterRequest(m_host.LocalId,
4130 m_item.ItemID, rq.ToString()); 4541 m_item.ItemID, rq.ToString());
4131 4542
4132 AsyncCommands. 4543 AsyncCommands.
4133 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4544 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4134 4545
4135 ScriptSleep(100); 4546 ScriptSleep(100);
4136 return tid.ToString(); 4547 return tid.ToString();
4548 }
4549 else
4550 {
4551 ShoutError("Invalid UUID passed to llRequestAgentData.");
4552 }
4553 return "";
4137 } 4554 }
4138 4555
4139 public LSL_String llRequestInventoryData(string name) 4556 public LSL_String llRequestInventoryData(string name)
@@ -4190,12 +4607,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4190 if (UUID.TryParse(agent, out agentId)) 4607 if (UUID.TryParse(agent, out agentId))
4191 { 4608 {
4192 ScenePresence presence = World.GetScenePresence(agentId); 4609 ScenePresence presence = World.GetScenePresence(agentId);
4193 if (presence != null) 4610 if (presence != null && presence.PresenceType != PresenceType.Npc)
4194 { 4611 {
4612 // agent must not be a god
4613 if (presence.UserLevel >= 200) return;
4614
4195 // agent must be over the owners land 4615 // agent must be over the owners land
4196 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID) 4616 if (m_host.OwnerID == World.LandChannel.GetLandObject(presence.AbsolutePosition).LandData.OwnerID)
4197 { 4617 {
4198 World.TeleportClientHome(agentId, presence.ControllingClient); 4618 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4619 {
4620 // They can't be teleported home for some reason
4621 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4622 if (regionInfo != null)
4623 {
4624 World.RequestTeleportLocation(
4625 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4626 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4627 }
4628 }
4199 } 4629 }
4200 } 4630 }
4201 } 4631 }
@@ -4301,7 +4731,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4301 UUID av = new UUID(); 4731 UUID av = new UUID();
4302 if (!UUID.TryParse(agent,out av)) 4732 if (!UUID.TryParse(agent,out av))
4303 { 4733 {
4304 LSLError("First parameter to llDialog needs to be a key");
4305 return; 4734 return;
4306 } 4735 }
4307 4736
@@ -4334,9 +4763,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4334 { 4763 {
4335 m_host.AddScriptLPS(1); 4764 m_host.AddScriptLPS(1);
4336 4765
4766 if(impact_sound == "")
4767 {
4768 m_host.CollisionSoundVolume = (float)impact_volume;
4769 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4770 m_host.CollisionSoundType = 0;
4771 return;
4772 }
4337 // TODO: Parameter check logic required. 4773 // TODO: Parameter check logic required.
4338 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound); 4774 m_host.CollisionSound = ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, impact_sound, AssetType.Sound);
4339 m_host.CollisionSoundVolume = (float)impact_volume; 4775 m_host.CollisionSoundVolume = (float)impact_volume;
4776 m_host.CollisionSoundType = 1;
4340 } 4777 }
4341 4778
4342 public LSL_String llGetAnimation(string id) 4779 public LSL_String llGetAnimation(string id)
@@ -4350,14 +4787,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4350 4787
4351 if (m_host.RegionHandle == presence.RegionHandle) 4788 if (m_host.RegionHandle == presence.RegionHandle)
4352 { 4789 {
4353 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4354
4355 if (presence != null) 4790 if (presence != null)
4356 { 4791 {
4357 AnimationSet currentAnims = presence.Animator.Animations; 4792 if (presence.SitGround)
4358 string currentAnimationState = String.Empty; 4793 return "Sitting on Ground";
4359 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4794 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4360 return currentAnimationState; 4795 return "Sitting";
4796
4797 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4798 string lslMovementAnimation;
4799
4800 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4801 return lslMovementAnimation;
4361 } 4802 }
4362 } 4803 }
4363 4804
@@ -4505,7 +4946,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4505 { 4946 {
4506 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4947 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4507 float distance_term = distance * distance * distance; // Script Energy 4948 float distance_term = distance * distance * distance; // Script Energy
4508 float pusher_mass = m_host.GetMass(); 4949 // use total object mass and not part
4950 float pusher_mass = m_host.ParentGroup.GetMass();
4509 4951
4510 float PUSH_ATTENUATION_DISTANCE = 17f; 4952 float PUSH_ATTENUATION_DISTANCE = 17f;
4511 float PUSH_ATTENUATION_SCALE = 5f; 4953 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4759,6 +5201,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4759 { 5201 {
4760 return item.AssetID.ToString(); 5202 return item.AssetID.ToString();
4761 } 5203 }
5204 m_host.TaskInventory.LockItemsForRead(false);
4762 5205
4763 return UUID.Zero.ToString(); 5206 return UUID.Zero.ToString();
4764 } 5207 }
@@ -4911,14 +5354,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4911 { 5354 {
4912 m_host.AddScriptLPS(1); 5355 m_host.AddScriptLPS(1);
4913 5356
4914 if (src == null) 5357 return src.Length;
4915 {
4916 return 0;
4917 }
4918 else
4919 {
4920 return src.Length;
4921 }
4922 } 5358 }
4923 5359
4924 public LSL_Integer llList2Integer(LSL_List src, int index) 5360 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4989,7 +5425,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4989 else if (src.Data[index] is LSL_Float) 5425 else if (src.Data[index] is LSL_Float)
4990 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5426 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4991 else if (src.Data[index] is LSL_String) 5427 else if (src.Data[index] is LSL_String)
4992 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5428 {
5429 string str = ((LSL_String) src.Data[index]).m_string;
5430 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5431 if (m != Match.Empty)
5432 {
5433 str = m.Value;
5434 double d = 0.0;
5435 if (!Double.TryParse(str, out d))
5436 return 0.0;
5437
5438 return d;
5439 }
5440 return 0.0;
5441 }
4993 return Convert.ToDouble(src.Data[index]); 5442 return Convert.ToDouble(src.Data[index]);
4994 } 5443 }
4995 catch (FormatException) 5444 catch (FormatException)
@@ -5031,7 +5480,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5031 // for completion and should LSL_Key ever be implemented 5480 // for completion and should LSL_Key ever be implemented
5032 // as it's own struct 5481 // as it's own struct
5033 else if (!(src.Data[index] is LSL_String || 5482 else if (!(src.Data[index] is LSL_String ||
5034 src.Data[index] is LSL_Key)) 5483 src.Data[index] is LSL_Key ||
5484 src.Data[index] is String))
5035 { 5485 {
5036 return ""; 5486 return "";
5037 } 5487 }
@@ -5289,7 +5739,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5289 } 5739 }
5290 } 5740 }
5291 } 5741 }
5292 else { 5742 else
5743 {
5293 object[] array = new object[src.Length]; 5744 object[] array = new object[src.Length];
5294 Array.Copy(src.Data, 0, array, 0, src.Length); 5745 Array.Copy(src.Data, 0, array, 0, src.Length);
5295 result = new LSL_List(array); 5746 result = new LSL_List(array);
@@ -5396,7 +5847,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5396 public LSL_Integer llGetRegionAgentCount() 5847 public LSL_Integer llGetRegionAgentCount()
5397 { 5848 {
5398 m_host.AddScriptLPS(1); 5849 m_host.AddScriptLPS(1);
5399 return new LSL_Integer(World.GetRootAgentCount()); 5850
5851 int count = 0;
5852 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5853 count++;
5854 });
5855
5856 return new LSL_Integer(count);
5400 } 5857 }
5401 5858
5402 public LSL_Vector llGetRegionCorner() 5859 public LSL_Vector llGetRegionCorner()
@@ -5637,6 +6094,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5637 flags |= ScriptBaseClass.AGENT_AWAY; 6094 flags |= ScriptBaseClass.AGENT_AWAY;
5638 } 6095 }
5639 6096
6097 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6098 UUID[] anims = agent.Animator.GetAnimationArray();
6099 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6100 {
6101 flags |= ScriptBaseClass.AGENT_BUSY;
6102 }
6103
5640 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6104 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5641 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6105 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5642 { 6106 {
@@ -5684,6 +6148,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5684 flags |= ScriptBaseClass.AGENT_SITTING; 6148 flags |= ScriptBaseClass.AGENT_SITTING;
5685 } 6149 }
5686 6150
6151 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6152 {
6153 flags |= ScriptBaseClass.AGENT_MALE;
6154 }
6155
5687 return flags; 6156 return flags;
5688 } 6157 }
5689 6158
@@ -5829,9 +6298,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5829 6298
5830 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6299 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5831 6300
5832 foreach (SceneObjectPart part in parts) 6301 try
6302 {
6303 foreach (SceneObjectPart part in parts)
6304 {
6305 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6306 }
6307 }
6308 finally
5833 { 6309 {
5834 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5835 } 6310 }
5836 } 6311 }
5837 6312
@@ -5885,13 +6360,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5885 6360
5886 if (m_host.OwnerID == land.LandData.OwnerID) 6361 if (m_host.OwnerID == land.LandData.OwnerID)
5887 { 6362 {
5888 World.TeleportClientHome(agentID, presence.ControllingClient); 6363 Vector3 p = World.GetNearestAllowedPosition(presence, land);
6364 presence.TeleportWithMomentum(p, null);
6365 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5889 } 6366 }
5890 } 6367 }
5891 } 6368 }
5892 ScriptSleep(5000); 6369 ScriptSleep(5000);
5893 } 6370 }
5894 6371
6372 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6373 {
6374 return ParseString2List(str, separators, in_spacers, false);
6375 }
6376
5895 public LSL_Integer llOverMyLand(string id) 6377 public LSL_Integer llOverMyLand(string id)
5896 { 6378 {
5897 m_host.AddScriptLPS(1); 6379 m_host.AddScriptLPS(1);
@@ -5944,26 +6426,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5944 } 6426 }
5945 else 6427 else
5946 { 6428 {
5947 agentSize = GetAgentSize(avatar); 6429// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6430 Vector3 s = avatar.Appearance.AvatarSize;
6431 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5948 } 6432 }
5949
5950 return agentSize; 6433 return agentSize;
5951 } 6434 }
5952 6435
5953 public LSL_Integer llSameGroup(string agent) 6436 public LSL_Integer llSameGroup(string id)
5954 { 6437 {
5955 m_host.AddScriptLPS(1); 6438 m_host.AddScriptLPS(1);
5956 UUID agentId = new UUID(); 6439 UUID uuid = new UUID();
5957 if (!UUID.TryParse(agent, out agentId)) 6440 if (!UUID.TryParse(id, out uuid))
5958 return new LSL_Integer(0);
5959 ScenePresence presence = World.GetScenePresence(agentId);
5960 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5961 return new LSL_Integer(0); 6441 return new LSL_Integer(0);
5962 IClientAPI client = presence.ControllingClient; 6442
5963 if (m_host.GroupID == client.ActiveGroupId) 6443 // Check if it's a group key
6444 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5964 return new LSL_Integer(1); 6445 return new LSL_Integer(1);
5965 else 6446
6447 // We got passed a UUID.Zero
6448 if (uuid == UUID.Zero)
6449 return new LSL_Integer(0);
6450
6451 // Handle the case where id names an avatar
6452 ScenePresence presence = World.GetScenePresence(uuid);
6453 if (presence != null)
6454 {
6455 if (presence.IsChildAgent)
6456 return new LSL_Integer(0);
6457
6458 IClientAPI client = presence.ControllingClient;
6459 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6460 return new LSL_Integer(1);
6461
6462 return new LSL_Integer(0);
6463 }
6464
6465 // Handle object case
6466 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6467 if (part != null)
6468 {
6469 // This will handle both deed and non-deed and also the no
6470 // group case
6471 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6472 return new LSL_Integer(1);
6473
5966 return new LSL_Integer(0); 6474 return new LSL_Integer(0);
6475 }
6476
6477 return new LSL_Integer(0);
5967 } 6478 }
5968 6479
5969 public void llUnSit(string id) 6480 public void llUnSit(string id)
@@ -6522,6 +7033,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6522 7033
6523 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7034 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6524 { 7035 {
7036 // LSL quaternions can normalize to 0, normal Quaternions can't.
7037 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7038 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7039
6525 part.SitTargetPosition = offset; 7040 part.SitTargetPosition = offset;
6526 part.SitTargetOrientation = rot; 7041 part.SitTargetOrientation = rot;
6527 part.ParentGroup.HasGroupChanged = true; 7042 part.ParentGroup.HasGroupChanged = true;
@@ -6708,30 +7223,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6708 UUID av = new UUID(); 7223 UUID av = new UUID();
6709 if (!UUID.TryParse(avatar,out av)) 7224 if (!UUID.TryParse(avatar,out av))
6710 { 7225 {
6711 LSLError("First parameter to llDialog needs to be a key"); 7226 //LSLError("First parameter to llDialog needs to be a key");
6712 return; 7227 return;
6713 } 7228 }
6714 if (buttons.Length < 1) 7229 if (buttons.Length < 1)
6715 { 7230 {
6716 LSLError("No less than 1 button can be shown"); 7231 buttons.Add("OK");
6717 return;
6718 } 7232 }
6719 if (buttons.Length > 12) 7233 if (buttons.Length > 12)
6720 { 7234 {
6721 LSLError("No more than 12 buttons can be shown"); 7235 ShoutError("button list too long, must be 12 or fewer entries");
6722 return;
6723 } 7236 }
6724 string[] buts = new string[buttons.Length]; 7237 int length = buttons.Length;
6725 for (int i = 0; i < buttons.Length; i++) 7238 if (length > 12)
7239 length = 12;
7240
7241 string[] buts = new string[length];
7242 for (int i = 0; i < length; i++)
6726 { 7243 {
6727 if (buttons.Data[i].ToString() == String.Empty) 7244 if (buttons.Data[i].ToString() == String.Empty)
6728 { 7245 {
6729 LSLError("button label cannot be blank"); 7246 ShoutError("button label cannot be blank");
6730 return; 7247 return;
6731 } 7248 }
6732 if (buttons.Data[i].ToString().Length > 24) 7249 if (buttons.Data[i].ToString().Length > 24)
6733 { 7250 {
6734 LSLError("button label cannot be longer than 24 characters"); 7251 ShoutError("button label cannot be longer than 24 characters");
6735 return; 7252 return;
6736 } 7253 }
6737 buts[i] = buttons.Data[i].ToString(); 7254 buts[i] = buttons.Data[i].ToString();
@@ -6798,9 +7315,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6798 return; 7315 return;
6799 } 7316 }
6800 7317
6801 // the rest of the permission checks are done in RezScript, so check the pin there as well 7318 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6802 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7319 if (dest != null)
7320 {
7321 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7322 {
7323 // the rest of the permission checks are done in RezScript, so check the pin there as well
7324 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6803 7325
7326 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7327 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7328 }
7329 }
6804 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7330 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6805 ScriptSleep(3000); 7331 ScriptSleep(3000);
6806 } 7332 }
@@ -6874,19 +7400,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6874 public LSL_String llMD5String(string src, int nonce) 7400 public LSL_String llMD5String(string src, int nonce)
6875 { 7401 {
6876 m_host.AddScriptLPS(1); 7402 m_host.AddScriptLPS(1);
6877 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7403 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6878 } 7404 }
6879 7405
6880 public LSL_String llSHA1String(string src) 7406 public LSL_String llSHA1String(string src)
6881 { 7407 {
6882 m_host.AddScriptLPS(1); 7408 m_host.AddScriptLPS(1);
6883 return Util.SHA1Hash(src).ToLower(); 7409 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6884 } 7410 }
6885 7411
6886 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7412 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6887 { 7413 {
6888 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7414 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6889 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7415 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7416 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7417 return shapeBlock;
6890 7418
6891 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7419 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6892 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7420 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6991,6 +7519,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6991 // Prim type box, cylinder and prism. 7519 // Prim type box, cylinder and prism.
6992 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) 7520 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)
6993 { 7521 {
7522 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7523 return;
7524
6994 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7525 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6995 ObjectShapePacket.ObjectDataBlock shapeBlock; 7526 ObjectShapePacket.ObjectDataBlock shapeBlock;
6996 7527
@@ -7044,6 +7575,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7044 // Prim type sphere. 7575 // Prim type sphere.
7045 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7576 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7046 { 7577 {
7578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7579 return;
7580
7047 ObjectShapePacket.ObjectDataBlock shapeBlock; 7581 ObjectShapePacket.ObjectDataBlock shapeBlock;
7048 7582
7049 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7583 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7085,6 +7619,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7085 // Prim type torus, tube and ring. 7619 // Prim type torus, tube and ring.
7086 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) 7620 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)
7087 { 7621 {
7622 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7623 return;
7624
7088 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7625 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7089 ObjectShapePacket.ObjectDataBlock shapeBlock; 7626 ObjectShapePacket.ObjectDataBlock shapeBlock;
7090 7627
@@ -7220,6 +7757,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7220 // Prim type sculpt. 7757 // Prim type sculpt.
7221 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7758 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7222 { 7759 {
7760 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7761 return;
7762
7223 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7763 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7224 UUID sculptId; 7764 UUID sculptId;
7225 7765
@@ -7242,7 +7782,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7242 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7782 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7243 { 7783 {
7244 // default 7784 // default
7245 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7785 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7246 } 7786 }
7247 7787
7248 part.Shape.SetSculptProperties((byte)type, sculptId); 7788 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7259,48 +7799,130 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7259 ScriptSleep(200); 7799 ScriptSleep(200);
7260 } 7800 }
7261 7801
7262 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7802 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7263 { 7803 {
7264 m_host.AddScriptLPS(1); 7804 m_host.AddScriptLPS(1);
7265 7805
7266 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7806 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7807 }
7267 7808
7268 ScriptSleep(200); 7809 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7810 {
7811 List<object> parts = new List<object>();
7812 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7813 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7814 foreach (SceneObjectPart p in prims)
7815 parts.Add(p);
7816 foreach (ScenePresence p in avatars)
7817 parts.Add(p);
7818
7819 LSL_List remaining = null;
7820 uint rulesParsed = 0;
7821
7822 if (parts.Count > 0)
7823 {
7824 foreach (object part in parts)
7825 {
7826 if (part is SceneObjectPart)
7827 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7828 else
7829 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7830 }
7831
7832 while ((object)remaining != null && remaining.Length > 2)
7833 {
7834 linknumber = remaining.GetLSLIntegerItem(0);
7835 rules = remaining.GetSublist(1, -1);
7836 parts.Clear();
7837 prims = GetLinkParts(linknumber);
7838 avatars = GetLinkAvatars(linknumber);
7839 foreach (SceneObjectPart p in prims)
7840 parts.Add(p);
7841 foreach (ScenePresence p in avatars)
7842 parts.Add(p);
7843
7844 remaining = null;
7845 foreach (object part in parts)
7846 {
7847 if (part is SceneObjectPart)
7848 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7849 else
7850 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7851 }
7852 }
7853 }
7269 } 7854 }
7270 7855
7271 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7856 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7857 float material_density, float material_friction,
7858 float material_restitution, float material_gravity_modifier)
7272 { 7859 {
7273 m_host.AddScriptLPS(1); 7860 ExtraPhysicsData physdata = new ExtraPhysicsData();
7861 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7862 physdata.Density = part.Density;
7863 physdata.Friction = part.Friction;
7864 physdata.Bounce = part.Restitution;
7865 physdata.GravitationModifier = part.GravityModifier;
7274 7866
7275 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7867 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7868 physdata.Density = material_density;
7869 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7870 physdata.Friction = material_friction;
7871 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7872 physdata.Bounce = material_restitution;
7873 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7874 physdata.GravitationModifier = material_gravity_modifier;
7875
7876 part.UpdateExtraPhysics(physdata);
7276 } 7877 }
7277 7878
7278 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7879 public void llSetPhysicsMaterial(int material_bits,
7880 float material_gravity_modifier, float material_restitution,
7881 float material_friction, float material_density)
7279 { 7882 {
7280 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7883 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7884 }
7281 7885
7282 LSL_List remaining = null; 7886 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7283 uint rulesParsed = 0; 7887 {
7888 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7889 llSetLinkPrimitiveParamsFast(linknumber, rules);
7890 ScriptSleep(200);
7891 }
7284 7892
7285 foreach (SceneObjectPart part in parts) 7893 // vector up using libomv (c&p from sop )
7286 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7894 // vector up rotated by r
7895 private Vector3 Zrot(Quaternion r)
7896 {
7897 double x, y, z, m;
7287 7898
7288 while (remaining != null && remaining.Length > 2) 7899 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7900 if (Math.Abs(1.0 - m) > 0.000001)
7289 { 7901 {
7290 linknumber = remaining.GetLSLIntegerItem(0); 7902 m = 1.0 / Math.Sqrt(m);
7291 rules = remaining.GetSublist(1, -1); 7903 r.X *= (float)m;
7292 parts = GetLinkParts(linknumber); 7904 r.Y *= (float)m;
7293 7905 r.Z *= (float)m;
7294 foreach (SceneObjectPart part in parts) 7906 r.W *= (float)m;
7295 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
7296 } 7907 }
7908
7909 x = 2 * (r.X * r.Z + r.Y * r.W);
7910 y = 2 * (-r.X * r.W + r.Y * r.Z);
7911 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7912
7913 return new Vector3((float)x, (float)y, (float)z);
7297 } 7914 }
7298 7915
7299 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7916 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7300 { 7917 {
7918 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7919 return null;
7920
7301 int idx = 0; 7921 int idx = 0;
7302 int idxStart = 0; 7922 int idxStart = 0;
7303 7923
7924 SceneObjectGroup parentgrp = part.ParentGroup;
7925
7304 bool positionChanged = false; 7926 bool positionChanged = false;
7305 LSL_Vector currentPosition = GetPartLocalPos(part); 7927 LSL_Vector currentPosition = GetPartLocalPos(part);
7306 7928
@@ -7325,8 +7947,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7325 return null; 7947 return null;
7326 7948
7327 v=rules.GetVector3Item(idx++); 7949 v=rules.GetVector3Item(idx++);
7950 if (part.IsRoot && !part.ParentGroup.IsAttachment)
7951 currentPosition = GetSetPosTarget(part, v, currentPosition, true);
7952 else
7953 currentPosition = GetSetPosTarget(part, v, currentPosition, false);
7328 positionChanged = true; 7954 positionChanged = true;
7329 currentPosition = GetSetPosTarget(part, v, currentPosition);
7330 7955
7331 break; 7956 break;
7332 case (int)ScriptBaseClass.PRIM_SIZE: 7957 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7343,7 +7968,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7343 7968
7344 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7969 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7345 // try to let this work as in SL... 7970 // try to let this work as in SL...
7346 if (part.ParentID == 0) 7971 if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
7347 { 7972 {
7348 // special case: If we are root, rotate complete SOG to new rotation 7973 // special case: If we are root, rotate complete SOG to new rotation
7349 SetRot(part, q); 7974 SetRot(part, q);
@@ -7603,7 +8228,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7603 return null; 8228 return null;
7604 8229
7605 string ph = rules.Data[idx++].ToString(); 8230 string ph = rules.Data[idx++].ToString();
7606 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8231 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7607 8232
7608 break; 8233 break;
7609 8234
@@ -7637,12 +8262,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7637 8262
7638 break; 8263 break;
7639 8264
8265 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8266 if (remain < 5)
8267 return null;
8268
8269 int material_bits = rules.GetLSLIntegerItem(idx++);
8270 float material_density = (float)rules.GetLSLFloatItem(idx++);
8271 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8272 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8273 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8274
8275 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8276
8277 break;
8278
7640 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8279 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7641 if (remain < 1) 8280 if (remain < 1)
7642 return null; 8281 return null;
7643 string temp = rules.Data[idx++].ToString(); 8282 string temp = rules.Data[idx++].ToString();
7644 8283
7645 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8284 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7646 8285
7647 break; 8286 break;
7648 8287
@@ -7716,14 +8355,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7716 if (part.ParentGroup.RootPart == part) 8355 if (part.ParentGroup.RootPart == part)
7717 { 8356 {
7718 SceneObjectGroup parent = part.ParentGroup; 8357 SceneObjectGroup parent = part.ParentGroup;
7719 parent.UpdateGroupPosition(currentPosition); 8358 Util.FireAndForget(delegate(object x) {
8359 parent.UpdateGroupPosition(currentPosition);
8360 });
7720 } 8361 }
7721 else 8362 else
7722 { 8363 {
7723 part.OffsetPosition = currentPosition; 8364 part.OffsetPosition = currentPosition;
7724 SceneObjectGroup parent = part.ParentGroup; 8365// SceneObjectGroup parent = part.ParentGroup;
7725 parent.HasGroupChanged = true; 8366// parent.HasGroupChanged = true;
7726 parent.ScheduleGroupForTerseUpdate(); 8367// parent.ScheduleGroupForTerseUpdate();
8368 part.ScheduleTerseUpdate();
7727 } 8369 }
7728 } 8370 }
7729 } 8371 }
@@ -7761,10 +8403,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7761 8403
7762 public LSL_String llXorBase64Strings(string str1, string str2) 8404 public LSL_String llXorBase64Strings(string str1, string str2)
7763 { 8405 {
7764 m_host.AddScriptLPS(1); 8406 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7765 Deprecated("llXorBase64Strings"); 8407
7766 ScriptSleep(300); 8408 ScriptSleep(300);
7767 return String.Empty; 8409 m_host.AddScriptLPS(1);
8410
8411 if (str1 == String.Empty)
8412 return String.Empty;
8413 if (str2 == String.Empty)
8414 return str1;
8415
8416 int len = str2.Length;
8417 if ((len % 4) != 0) // LL is EVIL!!!!
8418 {
8419 while (str2.EndsWith("="))
8420 str2 = str2.Substring(0, str2.Length - 1);
8421
8422 len = str2.Length;
8423 int mod = len % 4;
8424
8425 if (mod == 1)
8426 str2 = str2.Substring(0, str2.Length - 1);
8427 else if (mod == 2)
8428 str2 += "==";
8429 else if (mod == 3)
8430 str2 += "=";
8431 }
8432
8433 byte[] data1;
8434 byte[] data2;
8435 try
8436 {
8437 data1 = Convert.FromBase64String(str1);
8438 data2 = Convert.FromBase64String(str2);
8439 }
8440 catch (Exception)
8441 {
8442 return new LSL_String(String.Empty);
8443 }
8444
8445 // For cases where the decoded length of s2 is greater
8446 // than the decoded length of s1, simply perform a normal
8447 // decode and XOR
8448 //
8449 if (data2.Length >= data1.Length)
8450 {
8451 for (int pos = 0 ; pos < data1.Length ; pos++ )
8452 data1[pos] ^= data2[pos];
8453
8454 return Convert.ToBase64String(data1);
8455 }
8456
8457 // Remove padding
8458 while (str1.EndsWith("="))
8459 str1 = str1.Substring(0, str1.Length - 1);
8460 while (str2.EndsWith("="))
8461 str2 = str2.Substring(0, str2.Length - 1);
8462
8463 byte[] d1 = new byte[str1.Length];
8464 byte[] d2 = new byte[str2.Length];
8465
8466 for (int i = 0 ; i < str1.Length ; i++)
8467 {
8468 int idx = b64.IndexOf(str1.Substring(i, 1));
8469 if (idx == -1)
8470 idx = 0;
8471 d1[i] = (byte)idx;
8472 }
8473
8474 for (int i = 0 ; i < str2.Length ; i++)
8475 {
8476 int idx = b64.IndexOf(str2.Substring(i, 1));
8477 if (idx == -1)
8478 idx = 0;
8479 d2[i] = (byte)idx;
8480 }
8481
8482 string output = String.Empty;
8483
8484 for (int pos = 0 ; pos < d1.Length ; pos++)
8485 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8486
8487 while (output.Length % 3 > 0)
8488 output += "=";
8489
8490 return output;
7768 } 8491 }
7769 8492
7770 public void llRemoteDataSetRegion() 8493 public void llRemoteDataSetRegion()
@@ -7889,8 +8612,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7889 public LSL_Integer llGetNumberOfPrims() 8612 public LSL_Integer llGetNumberOfPrims()
7890 { 8613 {
7891 m_host.AddScriptLPS(1); 8614 m_host.AddScriptLPS(1);
7892 8615 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7893 return m_host.ParentGroup.PrimCount + m_host.ParentGroup.GetSittingAvatarsCount(); 8616
8617 return m_host.ParentGroup.PrimCount + avatarCount;
7894 } 8618 }
7895 8619
7896 /// <summary> 8620 /// <summary>
@@ -7905,55 +8629,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7905 m_host.AddScriptLPS(1); 8629 m_host.AddScriptLPS(1);
7906 UUID objID = UUID.Zero; 8630 UUID objID = UUID.Zero;
7907 LSL_List result = new LSL_List(); 8631 LSL_List result = new LSL_List();
8632
8633 // If the ID is not valid, return null result
7908 if (!UUID.TryParse(obj, out objID)) 8634 if (!UUID.TryParse(obj, out objID))
7909 { 8635 {
7910 result.Add(new LSL_Vector()); 8636 result.Add(new LSL_Vector());
7911 result.Add(new LSL_Vector()); 8637 result.Add(new LSL_Vector());
7912 return result; 8638 return result;
7913 } 8639 }
8640
8641 // Check if this is an attached prim. If so, replace
8642 // the UUID with the avatar UUID and report it's bounding box
8643 SceneObjectPart part = World.GetSceneObjectPart(objID);
8644 if (part != null && part.ParentGroup.IsAttachment)
8645 objID = part.ParentGroup.AttachedAvatar;
8646
8647 // Find out if this is an avatar ID. If so, return it's box
7914 ScenePresence presence = World.GetScenePresence(objID); 8648 ScenePresence presence = World.GetScenePresence(objID);
7915 if (presence != null) 8649 if (presence != null)
7916 { 8650 {
7917 if (presence.ParentID == 0) // not sat on an object 8651 // As per LSL Wiki, there is no difference between sitting
8652 // and standing avatar since server 1.36
8653 LSL_Vector lower;
8654 LSL_Vector upper;
8655
8656 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8657
8658 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8659 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8660/*
7918 { 8661 {
7919 LSL_Vector lower; 8662 // This is for ground sitting avatars
7920 LSL_Vector upper; 8663 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7921 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8664 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7922 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8665 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7923 { 8666 }
7924 // This is for ground sitting avatars 8667 else
7925 float height = presence.Appearance.AvatarHeight / 2.66666667f; 8668 {
7926 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f); 8669 // This is for standing/flying avatars
7927 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f); 8670 float height = presence.Appearance.AvatarHeight / 2.0f;
7928 } 8671 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7929 else 8672 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7930 { 8673 }
7931 // This is for standing/flying avatars 8674
7932 float height = presence.Appearance.AvatarHeight / 2.0f; 8675 // Adjust to the documented error offsets (see LSL Wiki)
7933 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f); 8676 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
7934 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f); 8677 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
7935 } 8678*/
7936 result.Add(lower); 8679 {
7937 result.Add(upper); 8680 // This is for ground sitting avatars TODO!
7938 return result; 8681 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8682 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
7939 } 8683 }
7940 else 8684 else
7941 { 8685 {
7942 // sitting on an object so we need the bounding box of that 8686 // This is for standing/flying avatars
7943 // which should include the avatar so set the UUID to the 8687 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
7944 // UUID of the object the avatar is sat on and allow it to fall through 8688 upper = new LSL_Vector(box.X, box.Y, box.Z);
7945 // to processing an object
7946 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7947 objID = p.UUID;
7948 } 8689 }
8690
8691 if (lower.x > upper.x)
8692 lower.x = upper.x;
8693 if (lower.y > upper.y)
8694 lower.y = upper.y;
8695 if (lower.z > upper.z)
8696 lower.z = upper.z;
8697
8698 result.Add(lower);
8699 result.Add(upper);
8700 return result;
7949 } 8701 }
7950 SceneObjectPart part = World.GetSceneObjectPart(objID); 8702
8703 part = World.GetSceneObjectPart(objID);
7951 // Currently only works for single prims without a sitting avatar 8704 // Currently only works for single prims without a sitting avatar
7952 if (part != null) 8705 if (part != null)
7953 { 8706 {
7954 Vector3 halfSize = part.Scale / 2.0f; 8707 float minX;
7955 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8708 float maxX;
7956 LSL_Vector upper = new LSL_Vector(halfSize); 8709 float minY;
8710 float maxY;
8711 float minZ;
8712 float maxZ;
8713
8714 // This BBox is in sim coordinates, with the offset being
8715 // a contained point.
8716 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8717 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8718
8719 minX -= offsets[0].X;
8720 maxX -= offsets[0].X;
8721 minY -= offsets[0].Y;
8722 maxY -= offsets[0].Y;
8723 minZ -= offsets[0].Z;
8724 maxZ -= offsets[0].Z;
8725
8726 LSL_Vector lower;
8727 LSL_Vector upper;
8728
8729 // Adjust to the documented error offsets (see LSL Wiki)
8730 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8731 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8732
8733 if (lower.x > upper.x)
8734 lower.x = upper.x;
8735 if (lower.y > upper.y)
8736 lower.y = upper.y;
8737 if (lower.z > upper.z)
8738 lower.z = upper.z;
8739
7957 result.Add(lower); 8740 result.Add(lower);
7958 result.Add(upper); 8741 result.Add(upper);
7959 return result; 8742 return result;
@@ -7970,224 +8753,74 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7970 return new LSL_Vector(m_host.GetGeometricCenter()); 8753 return new LSL_Vector(m_host.GetGeometricCenter());
7971 } 8754 }
7972 8755
7973 public LSL_List GetEntityParams(ISceneEntity entity, LSL_List rules) 8756 public LSL_List llGetPrimitiveParams(LSL_List rules)
7974 { 8757 {
7975 LSL_List result = new LSL_List(); 8758 m_host.AddScriptLPS(1);
7976 LSL_List remaining = null;
7977 8759
7978 while (true) 8760 LSL_List result = new LSL_List();
7979 {
7980 if (entity is SceneObjectPart)
7981 remaining = GetPrimParams((SceneObjectPart)entity, rules, ref result);
7982 else
7983 remaining = GetAgentParams((ScenePresence)entity, rules, ref result);
7984 8761
7985 if (remaining == null || remaining.Length <= 2) 8762 LSL_List remaining = GetPrimParams(m_host, rules, ref result);
7986 return result;
7987 8763
8764 while ((object)remaining != null && remaining.Length > 2)
8765 {
7988 int linknumber = remaining.GetLSLIntegerItem(0); 8766 int linknumber = remaining.GetLSLIntegerItem(0);
7989 rules = remaining.GetSublist(1, -1); 8767 rules = remaining.GetSublist(1, -1);
7990 entity = GetLinkEntity(linknumber); 8768 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7991 }
7992 }
7993 8769
7994 public LSL_List llGetPrimitiveParams(LSL_List rules) 8770 foreach (SceneObjectPart part in parts)
7995 { 8771 remaining = GetPrimParams(part, rules, ref result);
7996 m_host.AddScriptLPS(1); 8772 }
7997 8773
7998 return GetEntityParams(m_host, rules); 8774 return result;
7999 } 8775 }
8000 8776
8001 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules) 8777 public LSL_List llGetLinkPrimitiveParams(int linknumber, LSL_List rules)
8002 { 8778 {
8003 m_host.AddScriptLPS(1); 8779 m_host.AddScriptLPS(1);
8004 8780
8005 return GetEntityParams(GetLinkEntity(linknumber), rules); 8781 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8006 } 8782 // keep other options as before
8007 8783
8008 public LSL_Vector GetAgentSize(ScenePresence sp) 8784 List<SceneObjectPart> parts;
8009 { 8785 List<ScenePresence> avatars;
8010 return new LSL_Vector(0.45, 0.6, sp.Appearance.AvatarHeight); 8786
8011 } 8787 LSL_List res = new LSL_List();
8788 LSL_List remaining = null;
8012 8789
8013 /// <summary> 8790 while (rules.Length > 0)
8014 /// Gets params for a seated avatar in a linkset.
8015 /// </summary>
8016 /// <returns></returns>
8017 /// <param name='sp'></param>
8018 /// <param name='rules'></param>
8019 /// <param name='res'></param>
8020 public LSL_List GetAgentParams(ScenePresence sp, LSL_List rules, ref LSL_List res)
8021 {
8022 int idx = 0;
8023 while (idx < rules.Length)
8024 { 8791 {
8025 int code = (int)rules.GetLSLIntegerItem(idx++); 8792 parts = GetLinkParts(linknumber);
8026 int remain = rules.Length-idx; 8793 avatars = GetLinkAvatars(linknumber);
8027 8794
8028 switch (code) 8795 remaining = null;
8796 foreach (SceneObjectPart part in parts)
8029 { 8797 {
8030 case (int)ScriptBaseClass.PRIM_MATERIAL: 8798 remaining = GetPrimParams(part, rules, ref res);
8031 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MATERIAL_FLESH)); 8799 }
8032 break; 8800 foreach (ScenePresence avatar in avatars)
8033 8801 {
8034 case (int)ScriptBaseClass.PRIM_PHYSICS: 8802 remaining = GetPrimParams(avatar, rules, ref res);
8035 res.Add(ScriptBaseClass.FALSE); 8803 }
8036 break;
8037
8038 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8039 res.Add(ScriptBaseClass.FALSE);
8040 break;
8041
8042 case (int)ScriptBaseClass.PRIM_PHANTOM:
8043 res.Add(ScriptBaseClass.FALSE);
8044 break;
8045
8046 case (int)ScriptBaseClass.PRIM_POSITION:
8047 res.Add(new LSL_Vector(sp.AbsolutePosition));
8048 break;
8049
8050 case (int)ScriptBaseClass.PRIM_SIZE:
8051 res.Add(GetAgentSize(sp));
8052 break;
8053
8054 case (int)ScriptBaseClass.PRIM_ROTATION:
8055 res.Add(sp.GetWorldRotation());
8056 break;
8057
8058 case (int)ScriptBaseClass.PRIM_TYPE:
8059 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8060 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8061 res.Add(new LSL_Vector(0, 1, 0));
8062 res.Add(new LSL_Float(0));
8063 res.Add(new LSL_Vector(0, 0, 0));
8064 res.Add(new LSL_Vector(1, 1, 0));
8065 res.Add(new LSL_Vector(0, 0, 0));
8066 break;
8067
8068 case (int)ScriptBaseClass.PRIM_TEXTURE:
8069 if (remain < 1)
8070 return null;
8071
8072 int face = (int)rules.GetLSLIntegerItem(idx++);
8073 if (face > 21)
8074 break;
8075
8076 res.Add(new LSL_String(""));
8077 res.Add(ScriptBaseClass.ZERO_VECTOR);
8078 res.Add(ScriptBaseClass.ZERO_VECTOR);
8079 res.Add(new LSL_Float(0));
8080 break;
8081
8082 case (int)ScriptBaseClass.PRIM_COLOR:
8083 if (remain < 1)
8084 return null;
8085
8086 face = (int)rules.GetLSLIntegerItem(idx++);
8087 if (face > 21)
8088 break;
8089
8090 res.Add(ScriptBaseClass.ZERO_VECTOR);
8091 res.Add(new LSL_Float(0));
8092 break;
8093
8094 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8095 if (remain < 1)
8096 return null;
8097
8098 face = (int)rules.GetLSLIntegerItem(idx++);
8099 if (face > 21)
8100 break;
8101
8102 res.Add(ScriptBaseClass.PRIM_SHINY_NONE);
8103 res.Add(ScriptBaseClass.PRIM_BUMP_NONE);
8104 break;
8105
8106 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8107 if (remain < 1)
8108 return null;
8109
8110 face = (int)rules.GetLSLIntegerItem(idx++);
8111 if (face > 21)
8112 break;
8113
8114 res.Add(ScriptBaseClass.FALSE);
8115 break;
8116
8117 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8118 res.Add(ScriptBaseClass.FALSE);
8119 res.Add(new LSL_Integer(0));
8120 res.Add(new LSL_Float(0));
8121 res.Add(new LSL_Float(0));
8122 res.Add(new LSL_Float(0));
8123 res.Add(new LSL_Float(0));
8124 res.Add(ScriptBaseClass.ZERO_VECTOR);
8125 break;
8126
8127 case (int)ScriptBaseClass.PRIM_TEXGEN:
8128 if (remain < 1)
8129 return null;
8130
8131 face = (int)rules.GetLSLIntegerItem(idx++);
8132 if (face > 21)
8133 break;
8134
8135 res.Add(ScriptBaseClass.PRIM_TEXGEN_DEFAULT);
8136 break;
8137
8138 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
8139 res.Add(ScriptBaseClass.FALSE);
8140 res.Add(ScriptBaseClass.ZERO_VECTOR);
8141 res.Add(ScriptBaseClass.ZERO_VECTOR);
8142 break;
8143
8144 case (int)ScriptBaseClass.PRIM_GLOW:
8145 if (remain < 1)
8146 return null;
8147
8148 face = (int)rules.GetLSLIntegerItem(idx++);
8149 if (face > 21)
8150 break;
8151
8152 res.Add(new LSL_Float(0));
8153 break;
8154
8155 case (int)ScriptBaseClass.PRIM_TEXT:
8156 res.Add(new LSL_String(""));
8157 res.Add(ScriptBaseClass.ZERO_VECTOR);
8158 res.Add(new LSL_Float(1));
8159 break;
8160
8161 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8162 res.Add(new LSL_Rotation(sp.Rotation));
8163 break;
8164
8165 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8166 res.Add(new LSL_Vector(sp.OffsetPosition));
8167 break;
8168
8169 case (int)ScriptBaseClass.PRIM_SLICE:
8170 res.Add(new LSL_Vector(0, 1, 0));
8171 break;
8172
8173 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
8174 if(remain < 3)
8175 return null;
8176 8804
8177 return rules.GetSublist(idx, -1); 8805 if ((object)remaining != null && remaining.Length > 0)
8806 {
8807 linknumber = remaining.GetLSLIntegerItem(0);
8808 rules = remaining.GetSublist(1, -1);
8178 } 8809 }
8810 else
8811 break;
8179 } 8812 }
8180 8813
8181 return null; 8814 return res;
8182 } 8815 }
8183 8816
8184 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) 8817 public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res)
8185 { 8818 {
8186 int idx = 0; 8819 int idx=0;
8187 while (idx < rules.Length) 8820 while (idx < rules.Length)
8188 { 8821 {
8189 int code = (int)rules.GetLSLIntegerItem(idx++); 8822 int code=(int)rules.GetLSLIntegerItem(idx++);
8190 int remain = rules.Length-idx; 8823 int remain=rules.Length-idx;
8191 8824
8192 switch (code) 8825 switch (code)
8193 { 8826 {
@@ -8217,19 +8850,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8217 break; 8850 break;
8218 8851
8219 case (int)ScriptBaseClass.PRIM_POSITION: 8852 case (int)ScriptBaseClass.PRIM_POSITION:
8220 LSL_Vector v = new LSL_Vector(part.AbsolutePosition); 8853 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8221 8854 part.AbsolutePosition.Y,
8222 // For some reason, the part.AbsolutePosition.* values do not change if the 8855 part.AbsolutePosition.Z);
8223 // linkset is rotated; they always reflect the child prim's world position
8224 // as though the linkset is unrotated. This is incompatible behavior with SL's
8225 // implementation, so will break scripts imported from there (not to mention it
8226 // makes it more difficult to determine a child prim's actual inworld position).
8227 if (!part.IsRoot)
8228 {
8229 LSL_Vector rootPos = new LSL_Vector(m_host.ParentGroup.AbsolutePosition);
8230 v = ((v - rootPos) * llGetRootRotation()) + rootPos;
8231 }
8232
8233 res.Add(v); 8856 res.Add(v);
8234 break; 8857 break;
8235 8858
@@ -8399,30 +9022,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8399 if (remain < 1) 9022 if (remain < 1)
8400 return null; 9023 return null;
8401 9024
8402 face=(int)rules.GetLSLIntegerItem(idx++); 9025 face = (int)rules.GetLSLIntegerItem(idx++);
8403 9026
8404 tex = part.Shape.Textures; 9027 tex = part.Shape.Textures;
9028 int shiny;
8405 if (face == ScriptBaseClass.ALL_SIDES) 9029 if (face == ScriptBaseClass.ALL_SIDES)
8406 { 9030 {
8407 for (face = 0; face < GetNumberOfSides(part); face++) 9031 for (face = 0; face < GetNumberOfSides(part); face++)
8408 { 9032 {
8409 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9033 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8410 // Convert Shininess to PRIM_SHINY_* 9034 if (shinyness == Shininess.High)
8411 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9035 {
8412 // PRIM_BUMP_* 9036 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8413 res.Add(new LSL_Integer((int)texface.Bump)); 9037 }
9038 else if (shinyness == Shininess.Medium)
9039 {
9040 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9041 }
9042 else if (shinyness == Shininess.Low)
9043 {
9044 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9045 }
9046 else
9047 {
9048 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9049 }
9050 res.Add(new LSL_Integer(shiny));
9051 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8414 } 9052 }
8415 } 9053 }
8416 else 9054 else
8417 { 9055 {
8418 if (face >= 0 && face < GetNumberOfSides(part)) 9056 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9057 if (shinyness == Shininess.High)
8419 { 9058 {
8420 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9059 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8421 // Convert Shininess to PRIM_SHINY_*
8422 res.Add(new LSL_Integer((uint)texface.Shiny >> 6));
8423 // PRIM_BUMP_*
8424 res.Add(new LSL_Integer((int)texface.Bump));
8425 } 9060 }
9061 else if (shinyness == Shininess.Medium)
9062 {
9063 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9064 }
9065 else if (shinyness == Shininess.Low)
9066 {
9067 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9068 }
9069 else
9070 {
9071 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9072 }
9073 res.Add(new LSL_Integer(shiny));
9074 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8426 } 9075 }
8427 break; 9076 break;
8428 9077
@@ -8433,21 +9082,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8433 face = (int)rules.GetLSLIntegerItem(idx++); 9082 face = (int)rules.GetLSLIntegerItem(idx++);
8434 9083
8435 tex = part.Shape.Textures; 9084 tex = part.Shape.Textures;
9085 int fullbright;
8436 if (face == ScriptBaseClass.ALL_SIDES) 9086 if (face == ScriptBaseClass.ALL_SIDES)
8437 { 9087 {
8438 for (face = 0; face < GetNumberOfSides(part); face++) 9088 for (face = 0; face < GetNumberOfSides(part); face++)
8439 { 9089 {
8440 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9090 if (tex.GetFace((uint)face).Fullbright == true)
8441 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9091 {
9092 fullbright = ScriptBaseClass.TRUE;
9093 }
9094 else
9095 {
9096 fullbright = ScriptBaseClass.FALSE;
9097 }
9098 res.Add(new LSL_Integer(fullbright));
8442 } 9099 }
8443 } 9100 }
8444 else 9101 else
8445 { 9102 {
8446 if (face >= 0 && face < GetNumberOfSides(part)) 9103 if (tex.GetFace((uint)face).Fullbright == true)
8447 { 9104 {
8448 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9105 fullbright = ScriptBaseClass.TRUE;
8449 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9106 }
9107 else
9108 {
9109 fullbright = ScriptBaseClass.FALSE;
8450 } 9110 }
9111 res.Add(new LSL_Integer(fullbright));
8451 } 9112 }
8452 break; 9113 break;
8453 9114
@@ -8469,27 +9130,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8469 break; 9130 break;
8470 9131
8471 case (int)ScriptBaseClass.PRIM_TEXGEN: 9132 case (int)ScriptBaseClass.PRIM_TEXGEN:
9133 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8472 if (remain < 1) 9134 if (remain < 1)
8473 return null; 9135 return null;
8474 9136
8475 face=(int)rules.GetLSLIntegerItem(idx++); 9137 face = (int)rules.GetLSLIntegerItem(idx++);
8476 9138
8477 tex = part.Shape.Textures; 9139 tex = part.Shape.Textures;
8478 if (face == ScriptBaseClass.ALL_SIDES) 9140 if (face == ScriptBaseClass.ALL_SIDES)
8479 { 9141 {
8480 for (face = 0; face < GetNumberOfSides(part); face++) 9142 for (face = 0; face < GetNumberOfSides(part); face++)
8481 { 9143 {
8482 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9144 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8483 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9145 {
8484 res.Add(new LSL_Integer((uint)texgen >> 1)); 9146 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9147 }
9148 else
9149 {
9150 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9151 }
8485 } 9152 }
8486 } 9153 }
8487 else 9154 else
8488 { 9155 {
8489 if (face >= 0 && face < GetNumberOfSides(part)) 9156 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
9157 {
9158 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9159 }
9160 else
8490 { 9161 {
8491 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9162 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8492 res.Add(new LSL_Integer((uint)texgen >> 1));
8493 } 9163 }
8494 } 9164 }
8495 break; 9165 break;
@@ -8513,24 +9183,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8513 if (remain < 1) 9183 if (remain < 1)
8514 return null; 9184 return null;
8515 9185
8516 face=(int)rules.GetLSLIntegerItem(idx++); 9186 face = (int)rules.GetLSLIntegerItem(idx++);
8517 9187
8518 tex = part.Shape.Textures; 9188 tex = part.Shape.Textures;
9189 float primglow;
8519 if (face == ScriptBaseClass.ALL_SIDES) 9190 if (face == ScriptBaseClass.ALL_SIDES)
8520 { 9191 {
8521 for (face = 0; face < GetNumberOfSides(part); face++) 9192 for (face = 0; face < GetNumberOfSides(part); face++)
8522 { 9193 {
8523 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9194 primglow = tex.GetFace((uint)face).Glow;
8524 res.Add(new LSL_Float(texface.Glow)); 9195 res.Add(new LSL_Float(primglow));
8525 } 9196 }
8526 } 9197 }
8527 else 9198 else
8528 { 9199 {
8529 if (face >= 0 && face < GetNumberOfSides(part)) 9200 primglow = tex.GetFace((uint)face).Glow;
8530 { 9201 res.Add(new LSL_Float(primglow));
8531 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8532 res.Add(new LSL_Float(texface.Glow));
8533 }
8534 } 9202 }
8535 break; 9203 break;
8536 9204
@@ -8542,15 +9210,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8542 textColor.B)); 9210 textColor.B));
8543 res.Add(new LSL_Float(textColor.A)); 9211 res.Add(new LSL_Float(textColor.A));
8544 break; 9212 break;
9213
8545 case (int)ScriptBaseClass.PRIM_NAME: 9214 case (int)ScriptBaseClass.PRIM_NAME:
8546 res.Add(new LSL_String(part.Name)); 9215 res.Add(new LSL_String(part.Name));
8547 break; 9216 break;
9217
8548 case (int)ScriptBaseClass.PRIM_DESC: 9218 case (int)ScriptBaseClass.PRIM_DESC:
8549 res.Add(new LSL_String(part.Description)); 9219 res.Add(new LSL_String(part.Description));
8550 break; 9220 break;
8551 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9221 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8552 res.Add(new LSL_Rotation(part.RotationOffset)); 9222 res.Add(new LSL_Rotation(part.RotationOffset));
8553 break; 9223 break;
9224
8554 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9225 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8555 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9226 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8556 break; 9227 break;
@@ -9161,8 +9832,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9161 // The function returns an ordered list 9832 // The function returns an ordered list
9162 // representing the tokens found in the supplied 9833 // representing the tokens found in the supplied
9163 // sources string. If two successive tokenizers 9834 // sources string. If two successive tokenizers
9164 // are encountered, then a NULL entry is added 9835 // are encountered, then a null-string entry is
9165 // to the list. 9836 // added to the list.
9166 // 9837 //
9167 // It is a precondition that the source and 9838 // It is a precondition that the source and
9168 // toekizer lisst are non-null. If they are null, 9839 // toekizer lisst are non-null. If they are null,
@@ -9170,7 +9841,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9170 // while their lengths are being determined. 9841 // while their lengths are being determined.
9171 // 9842 //
9172 // A small amount of working memoryis required 9843 // A small amount of working memoryis required
9173 // of approximately 8*#tokenizers. 9844 // of approximately 8*#tokenizers + 8*srcstrlen.
9174 // 9845 //
9175 // There are many ways in which this function 9846 // There are many ways in which this function
9176 // can be implemented, this implementation is 9847 // can be implemented, this implementation is
@@ -9186,155 +9857,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9186 // and eliminates redundant tokenizers as soon 9857 // and eliminates redundant tokenizers as soon
9187 // as is possible. 9858 // as is possible.
9188 // 9859 //
9189 // The implementation tries to avoid any copying 9860 // The implementation tries to minimize temporary
9190 // of arrays or other objects. 9861 // garbage generation.
9191 // </remarks> 9862 // </remarks>
9192 9863
9193 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9864 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9194 { 9865 {
9195 int beginning = 0; 9866 return ParseString2List(src, separators, spacers, true);
9196 int srclen = src.Length; 9867 }
9197 int seplen = separators.Length;
9198 object[] separray = separators.Data;
9199 int spclen = spacers.Length;
9200 object[] spcarray = spacers.Data;
9201 int mlen = seplen+spclen;
9202
9203 int[] offset = new int[mlen+1];
9204 bool[] active = new bool[mlen];
9205
9206 int best;
9207 int j;
9208
9209 // Initial capacity reduces resize cost
9210 9868
9211 LSL_List tokens = new LSL_List(); 9869 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9870 {
9871 int srclen = src.Length;
9872 int seplen = separators.Length;
9873 object[] separray = separators.Data;
9874 int spclen = spacers.Length;
9875 object[] spcarray = spacers.Data;
9876 int dellen = 0;
9877 string[] delarray = new string[seplen+spclen];
9212 9878
9213 // All entries are initially valid 9879 int outlen = 0;
9880 string[] outarray = new string[srclen*2+1];
9214 9881
9215 for (int i = 0; i < mlen; i++) 9882 int i, j;
9216 active[i] = true; 9883 string d;
9217 9884
9218 offset[mlen] = srclen; 9885 m_host.AddScriptLPS(1);
9219 9886
9220 while (beginning < srclen) 9887 /*
9888 * Convert separator and spacer lists to C# strings.
9889 * Also filter out null strings so we don't hang.
9890 */
9891 for (i = 0; i < seplen; i ++)
9221 { 9892 {
9893 d = separray[i].ToString();
9894 if (d.Length > 0)
9895 {
9896 delarray[dellen++] = d;
9897 }
9898 }
9899 seplen = dellen;
9222 9900
9223 best = mlen; // as bad as it gets 9901 for (i = 0; i < spclen; i ++)
9902 {
9903 d = spcarray[i].ToString();
9904 if (d.Length > 0)
9905 {
9906 delarray[dellen++] = d;
9907 }
9908 }
9224 9909
9225 // Scan for separators 9910 /*
9911 * Scan through source string from beginning to end.
9912 */
9913 for (i = 0;;)
9914 {
9226 9915
9227 for (j = 0; j < seplen; j++) 9916 /*
9917 * Find earliest delimeter in src starting at i (if any).
9918 */
9919 int earliestDel = -1;
9920 int earliestSrc = srclen;
9921 string earliestStr = null;
9922 for (j = 0; j < dellen; j ++)
9228 { 9923 {
9229 if (separray[j].ToString() == String.Empty) 9924 d = delarray[j];
9230 active[j] = false; 9925 if (d != null)
9231
9232 if (active[j])
9233 { 9926 {
9234 // scan all of the markers 9927 int index = src.IndexOf(d, i);
9235 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9928 if (index < 0)
9236 { 9929 {
9237 // not present at all 9930 delarray[j] = null; // delim nowhere in src, don't check it anymore
9238 active[j] = false;
9239 } 9931 }
9240 else 9932 else if (index < earliestSrc)
9241 { 9933 {
9242 // present and correct 9934 earliestSrc = index; // where delimeter starts in source string
9243 if (offset[j] < offset[best]) 9935 earliestDel = j; // where delimeter is in delarray[]
9244 { 9936 earliestStr = d; // the delimeter string from delarray[]
9245 // closest so far 9937 if (index == i) break; // can't do any better than found at beg of string
9246 best = j;
9247 if (offset[best] == beginning)
9248 break;
9249 }
9250 } 9938 }
9251 } 9939 }
9252 } 9940 }
9253 9941
9254 // Scan for spacers 9942 /*
9255 9943 * Output source string starting at i through start of earliest delimeter.
9256 if (offset[best] != beginning) 9944 */
9945 if (keepNulls || (earliestSrc > i))
9257 { 9946 {
9258 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9947 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9259 {
9260 if (spcarray[j-seplen].ToString() == String.Empty)
9261 active[j] = false;
9262
9263 if (active[j])
9264 {
9265 // scan all of the markers
9266 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9267 {
9268 // not present at all
9269 active[j] = false;
9270 }
9271 else
9272 {
9273 // present and correct
9274 if (offset[j] < offset[best])
9275 {
9276 // closest so far
9277 best = j;
9278 }
9279 }
9280 }
9281 }
9282 } 9948 }
9283 9949
9284 // This is the normal exit from the scanning loop 9950 /*
9951 * If no delimeter found at or after i, we're done scanning.
9952 */
9953 if (earliestDel < 0) break;
9285 9954
9286 if (best == mlen) 9955 /*
9956 * If delimeter was a spacer, output the spacer.
9957 */
9958 if (earliestDel >= seplen)
9287 { 9959 {
9288 // no markers were found on this pass 9960 outarray[outlen++] = earliestStr;
9289 // so we're pretty much done
9290 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9291 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9292 break;
9293 } 9961 }
9294 9962
9295 // Otherwise we just add the newly delimited token 9963 /*
9296 // and recalculate where the search should continue. 9964 * Look at rest of src string following delimeter.
9297 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9965 */
9298 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9966 i = earliestSrc + earliestStr.Length;
9299
9300 if (best < seplen)
9301 {
9302 beginning = offset[best] + (separray[best].ToString()).Length;
9303 }
9304 else
9305 {
9306 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9307 string str = spcarray[best - seplen].ToString();
9308 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9309 tokens.Add(new LSL_String(str));
9310 }
9311 } 9967 }
9312 9968
9313 // This an awkward an not very intuitive boundary case. If the 9969 /*
9314 // last substring is a tokenizer, then there is an implied trailing 9970 * Make up an exact-sized output array suitable for an LSL_List object.
9315 // null list entry. Hopefully the single comparison will not be too 9971 */
9316 // arduous. Alternatively the 'break' could be replced with a return 9972 object[] outlist = new object[outlen];
9317 // but that's shabby programming. 9973 for (i = 0; i < outlen; i ++)
9318
9319 if ((beginning == srclen) && (keepNulls))
9320 { 9974 {
9321 if (srclen != 0) 9975 outlist[i] = new LSL_String(outarray[i]);
9322 tokens.Add(new LSL_String(""));
9323 } 9976 }
9324 9977 return new LSL_List(outlist);
9325 return tokens;
9326 }
9327
9328 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9329 {
9330 m_host.AddScriptLPS(1);
9331 return this.ParseString(src, separators, spacers, false);
9332 }
9333
9334 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9335 {
9336 m_host.AddScriptLPS(1);
9337 return this.ParseString(src, separators, spacers, true);
9338 } 9978 }
9339 9979
9340 public LSL_Integer llGetObjectPermMask(int mask) 9980 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9429,6 +10069,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9429 case 4: 10069 case 4:
9430 return (int)item.NextPermissions; 10070 return (int)item.NextPermissions;
9431 } 10071 }
10072 m_host.TaskInventory.LockItemsForRead(false);
9432 10073
9433 return -1; 10074 return -1;
9434 } 10075 }
@@ -9632,31 +10273,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9632 UUID key = new UUID(); 10273 UUID key = new UUID();
9633 if (UUID.TryParse(id, out key)) 10274 if (UUID.TryParse(id, out key))
9634 { 10275 {
9635 try 10276 // return total object mass
9636 { 10277 SceneObjectPart part = World.GetSceneObjectPart(key);
9637 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10278 if (part != null)
9638 if (obj != null) 10279 return part.ParentGroup.GetMass();
9639 return (double)obj.GetMass(); 10280
9640 // the object is null so the key is for an avatar 10281 // the object is null so the key is for an avatar
9641 ScenePresence avatar = World.GetScenePresence(key); 10282 ScenePresence avatar = World.GetScenePresence(key);
9642 if (avatar != null) 10283 if (avatar != null)
9643 if (avatar.IsChildAgent)
9644 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9645 // child agents have a mass of 1.0
9646 return 1;
9647 else
9648 return (double)avatar.GetMass();
9649 }
9650 catch (KeyNotFoundException)
9651 { 10284 {
9652 return 0; // The Object/Agent not in the region so just return zero 10285 if (avatar.IsChildAgent)
10286 {
10287 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10288 // child agents have a mass of 1.0
10289 return 1;
10290 }
10291 else
10292 {
10293 return (double)avatar.GetMass();
10294 }
9653 } 10295 }
9654 } 10296 }
9655 return 0; 10297 return 0;
9656 } 10298 }
9657 10299
9658 /// <summary> 10300 /// <summary>
9659 /// illListReplaceList removes the sub-list defined by the inclusive indices 10301 /// llListReplaceList removes the sub-list defined by the inclusive indices
9660 /// start and end and inserts the src list in its place. The inclusive 10302 /// start and end and inserts the src list in its place. The inclusive
9661 /// nature of the indices means that at least one element must be deleted 10303 /// nature of the indices means that at least one element must be deleted
9662 /// if the indices are within the bounds of the existing list. I.e. 2,2 10304 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9713,16 +10355,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9713 // based upon end. Note that if end exceeds the upper 10355 // based upon end. Note that if end exceeds the upper
9714 // bound in this case, the entire destination list 10356 // bound in this case, the entire destination list
9715 // is removed. 10357 // is removed.
9716 else 10358 else if (start == 0)
9717 { 10359 {
9718 if (end + 1 < dest.Length) 10360 if (end + 1 < dest.Length)
9719 {
9720 return src + dest.GetSublist(end + 1, -1); 10361 return src + dest.GetSublist(end + 1, -1);
9721 }
9722 else 10362 else
9723 {
9724 return src; 10363 return src;
9725 } 10364 }
10365 else // Start < 0
10366 {
10367 if (end + 1 < dest.Length)
10368 return dest.GetSublist(end + 1, -1);
10369 else
10370 return new LSL_List();
9726 } 10371 }
9727 } 10372 }
9728 // Finally, if start > end, we strip away a prefix and 10373 // Finally, if start > end, we strip away a prefix and
@@ -9773,17 +10418,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9773 int width = 0; 10418 int width = 0;
9774 int height = 0; 10419 int height = 0;
9775 10420
9776 ParcelMediaCommandEnum? commandToSend = null; 10421 uint commandToSend = 0;
9777 float time = 0.0f; // default is from start 10422 float time = 0.0f; // default is from start
9778 10423
9779 ScenePresence presence = null; 10424 ScenePresence presence = null;
9780 10425
9781 for (int i = 0; i < commandList.Data.Length; i++) 10426 for (int i = 0; i < commandList.Data.Length; i++)
9782 { 10427 {
9783 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10428 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9784 switch (command) 10429 switch (command)
9785 { 10430 {
9786 case ParcelMediaCommandEnum.Agent: 10431 case (uint)ParcelMediaCommandEnum.Agent:
9787 // we send only to one agent 10432 // we send only to one agent
9788 if ((i + 1) < commandList.Length) 10433 if ((i + 1) < commandList.Length)
9789 { 10434 {
@@ -9800,25 +10445,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9800 } 10445 }
9801 break; 10446 break;
9802 10447
9803 case ParcelMediaCommandEnum.Loop: 10448 case (uint)ParcelMediaCommandEnum.Loop:
9804 loop = 1; 10449 loop = 1;
9805 commandToSend = command; 10450 commandToSend = command;
9806 update = true; //need to send the media update packet to set looping 10451 update = true; //need to send the media update packet to set looping
9807 break; 10452 break;
9808 10453
9809 case ParcelMediaCommandEnum.Play: 10454 case (uint)ParcelMediaCommandEnum.Play:
9810 loop = 0; 10455 loop = 0;
9811 commandToSend = command; 10456 commandToSend = command;
9812 update = true; //need to send the media update packet to make sure it doesn't loop 10457 update = true; //need to send the media update packet to make sure it doesn't loop
9813 break; 10458 break;
9814 10459
9815 case ParcelMediaCommandEnum.Pause: 10460 case (uint)ParcelMediaCommandEnum.Pause:
9816 case ParcelMediaCommandEnum.Stop: 10461 case (uint)ParcelMediaCommandEnum.Stop:
9817 case ParcelMediaCommandEnum.Unload: 10462 case (uint)ParcelMediaCommandEnum.Unload:
9818 commandToSend = command; 10463 commandToSend = command;
9819 break; 10464 break;
9820 10465
9821 case ParcelMediaCommandEnum.Url: 10466 case (uint)ParcelMediaCommandEnum.Url:
9822 if ((i + 1) < commandList.Length) 10467 if ((i + 1) < commandList.Length)
9823 { 10468 {
9824 if (commandList.Data[i + 1] is LSL_String) 10469 if (commandList.Data[i + 1] is LSL_String)
@@ -9831,7 +10476,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9831 } 10476 }
9832 break; 10477 break;
9833 10478
9834 case ParcelMediaCommandEnum.Texture: 10479 case (uint)ParcelMediaCommandEnum.Texture:
9835 if ((i + 1) < commandList.Length) 10480 if ((i + 1) < commandList.Length)
9836 { 10481 {
9837 if (commandList.Data[i + 1] is LSL_String) 10482 if (commandList.Data[i + 1] is LSL_String)
@@ -9844,7 +10489,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9844 } 10489 }
9845 break; 10490 break;
9846 10491
9847 case ParcelMediaCommandEnum.Time: 10492 case (uint)ParcelMediaCommandEnum.Time:
9848 if ((i + 1) < commandList.Length) 10493 if ((i + 1) < commandList.Length)
9849 { 10494 {
9850 if (commandList.Data[i + 1] is LSL_Float) 10495 if (commandList.Data[i + 1] is LSL_Float)
@@ -9856,7 +10501,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9856 } 10501 }
9857 break; 10502 break;
9858 10503
9859 case ParcelMediaCommandEnum.AutoAlign: 10504 case (uint)ParcelMediaCommandEnum.AutoAlign:
9860 if ((i + 1) < commandList.Length) 10505 if ((i + 1) < commandList.Length)
9861 { 10506 {
9862 if (commandList.Data[i + 1] is LSL_Integer) 10507 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9870,7 +10515,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9870 } 10515 }
9871 break; 10516 break;
9872 10517
9873 case ParcelMediaCommandEnum.Type: 10518 case (uint)ParcelMediaCommandEnum.Type:
9874 if ((i + 1) < commandList.Length) 10519 if ((i + 1) < commandList.Length)
9875 { 10520 {
9876 if (commandList.Data[i + 1] is LSL_String) 10521 if (commandList.Data[i + 1] is LSL_String)
@@ -9883,7 +10528,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9883 } 10528 }
9884 break; 10529 break;
9885 10530
9886 case ParcelMediaCommandEnum.Desc: 10531 case (uint)ParcelMediaCommandEnum.Desc:
9887 if ((i + 1) < commandList.Length) 10532 if ((i + 1) < commandList.Length)
9888 { 10533 {
9889 if (commandList.Data[i + 1] is LSL_String) 10534 if (commandList.Data[i + 1] is LSL_String)
@@ -9896,7 +10541,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9896 } 10541 }
9897 break; 10542 break;
9898 10543
9899 case ParcelMediaCommandEnum.Size: 10544 case (uint)ParcelMediaCommandEnum.Size:
9900 if ((i + 2) < commandList.Length) 10545 if ((i + 2) < commandList.Length)
9901 { 10546 {
9902 if (commandList.Data[i + 1] is LSL_Integer) 10547 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9966,7 +10611,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9966 } 10611 }
9967 } 10612 }
9968 10613
9969 if (commandToSend != null) 10614 if (commandToSend != 0)
9970 { 10615 {
9971 // the commandList contained a start/stop/... command, too 10616 // the commandList contained a start/stop/... command, too
9972 if (presence == null) 10617 if (presence == null)
@@ -10003,7 +10648,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10003 10648
10004 if (aList.Data[i] != null) 10649 if (aList.Data[i] != null)
10005 { 10650 {
10006 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10651 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
10007 { 10652 {
10008 case ParcelMediaCommandEnum.Url: 10653 case ParcelMediaCommandEnum.Url:
10009 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10654 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -10060,15 +10705,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10060 10705
10061 if (quick_pay_buttons.Data.Length < 4) 10706 if (quick_pay_buttons.Data.Length < 4)
10062 { 10707 {
10063 LSLError("List must have at least 4 elements"); 10708 int x;
10064 return; 10709 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10710 {
10711 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10712 }
10065 } 10713 }
10066 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10714 int[] nPrice = new int[5];
10067 10715 nPrice[0] = price;
10068 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10716 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
10069 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10717 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
10070 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10718 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
10071 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10719 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10720 m_host.ParentGroup.RootPart.PayPrice = nPrice;
10072 m_host.ParentGroup.HasGroupChanged = true; 10721 m_host.ParentGroup.HasGroupChanged = true;
10073 } 10722 }
10074 10723
@@ -10085,7 +10734,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10085 return Vector3.Zero; 10734 return Vector3.Zero;
10086 } 10735 }
10087 10736
10088 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10737// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10738 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10089 if (presence != null) 10739 if (presence != null)
10090 { 10740 {
10091 LSL_Vector pos = new LSL_Vector(presence.CameraPosition); 10741 LSL_Vector pos = new LSL_Vector(presence.CameraPosition);
@@ -10108,7 +10758,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10108 return Quaternion.Identity; 10758 return Quaternion.Identity;
10109 } 10759 }
10110 10760
10111 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10761// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10762 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
10112 if (presence != null) 10763 if (presence != null)
10113 { 10764 {
10114 return new LSL_Rotation(presence.CameraRotation); 10765 return new LSL_Rotation(presence.CameraRotation);
@@ -10168,14 +10819,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10168 { 10819 {
10169 m_host.AddScriptLPS(1); 10820 m_host.AddScriptLPS(1);
10170 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10821 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10171 if (detectedParams == null) return; // only works on the first detected avatar 10822 if (detectedParams == null)
10172 10823 {
10824 if (m_host.ParentGroup.IsAttachment == true)
10825 {
10826 detectedParams = new DetectParams();
10827 detectedParams.Key = m_host.OwnerID;
10828 }
10829 else
10830 {
10831 return;
10832 }
10833 }
10834
10173 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10835 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10174 if (avatar != null) 10836 if (avatar != null)
10175 { 10837 {
10176 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10838 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10177 simname, pos, lookAt); 10839 simname, pos, lookAt);
10178 } 10840 }
10841
10179 ScriptSleep(1000); 10842 ScriptSleep(1000);
10180 } 10843 }
10181 10844
@@ -10299,12 +10962,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10299 10962
10300 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10963 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10301 object[] data = rules.Data; 10964 object[] data = rules.Data;
10302 for (int i = 0; i < data.Length; ++i) { 10965 for (int i = 0; i < data.Length; ++i)
10966 {
10303 int type = Convert.ToInt32(data[i++].ToString()); 10967 int type = Convert.ToInt32(data[i++].ToString());
10304 if (i >= data.Length) break; // odd number of entries => ignore the last 10968 if (i >= data.Length) break; // odd number of entries => ignore the last
10305 10969
10306 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10970 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10307 switch (type) { 10971 switch (type)
10972 {
10308 case ScriptBaseClass.CAMERA_FOCUS: 10973 case ScriptBaseClass.CAMERA_FOCUS:
10309 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10974 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10310 case ScriptBaseClass.CAMERA_POSITION: 10975 case ScriptBaseClass.CAMERA_POSITION:
@@ -10409,19 +11074,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10409 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11074 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10410 { 11075 {
10411 m_host.AddScriptLPS(1); 11076 m_host.AddScriptLPS(1);
10412 string ret = String.Empty; 11077
10413 string src1 = llBase64ToString(str1); 11078 if (str1 == String.Empty)
10414 string src2 = llBase64ToString(str2); 11079 return String.Empty;
10415 int c = 0; 11080 if (str2 == String.Empty)
10416 for (int i = 0; i < src1.Length; i++) 11081 return str1;
11082
11083 int len = str2.Length;
11084 if ((len % 4) != 0) // LL is EVIL!!!!
10417 { 11085 {
10418 ret += (char) (src1[i] ^ src2[c]); 11086 while (str2.EndsWith("="))
11087 str2 = str2.Substring(0, str2.Length - 1);
11088
11089 len = str2.Length;
11090 int mod = len % 4;
11091
11092 if (mod == 1)
11093 str2 = str2.Substring(0, str2.Length - 1);
11094 else if (mod == 2)
11095 str2 += "==";
11096 else if (mod == 3)
11097 str2 += "=";
11098 }
10419 11099
10420 c++; 11100 byte[] data1;
10421 if (c >= src2.Length) 11101 byte[] data2;
10422 c = 0; 11102 try
11103 {
11104 data1 = Convert.FromBase64String(str1);
11105 data2 = Convert.FromBase64String(str2);
11106 }
11107 catch (Exception)
11108 {
11109 return new LSL_String(String.Empty);
10423 } 11110 }
10424 return llStringToBase64(ret); 11111
11112 byte[] d2 = new Byte[data1.Length];
11113 int pos = 0;
11114
11115 if (data1.Length <= data2.Length)
11116 {
11117 Array.Copy(data2, 0, d2, 0, data1.Length);
11118 }
11119 else
11120 {
11121 while (pos < data1.Length)
11122 {
11123 len = data1.Length - pos;
11124 if (len > data2.Length)
11125 len = data2.Length;
11126
11127 Array.Copy(data2, 0, d2, pos, len);
11128 pos += len;
11129 }
11130 }
11131
11132 for (pos = 0 ; pos < data1.Length ; pos++ )
11133 data1[pos] ^= d2[pos];
11134
11135 return Convert.ToBase64String(data1);
10425 } 11136 }
10426 11137
10427 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11138 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10525,16 +11236,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10525 if (userAgent != null) 11236 if (userAgent != null)
10526 httpHeaders["User-Agent"] = userAgent; 11237 httpHeaders["User-Agent"] = userAgent;
10527 11238
11239 // See if the URL contains any header hacks
11240 string[] urlParts = url.Split(new char[] {'\n'});
11241 if (urlParts.Length > 1)
11242 {
11243 // Iterate the passed headers and parse them
11244 for (int i = 1 ; i < urlParts.Length ; i++ )
11245 {
11246 // The rest of those would be added to the body in SL.
11247 // Let's not do that.
11248 if (urlParts[i] == String.Empty)
11249 break;
11250
11251 // See if this could be a valid header
11252 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11253 if (headerParts.Length != 2)
11254 continue;
11255
11256 string headerName = headerParts[0].Trim();
11257 string headerValue = headerParts[1].Trim();
11258
11259 // Filter out headers that could be used to abuse
11260 // another system or cloak the request
11261 if (headerName.ToLower() == "x-secondlife-shard" ||
11262 headerName.ToLower() == "x-secondlife-object-name" ||
11263 headerName.ToLower() == "x-secondlife-object-key" ||
11264 headerName.ToLower() == "x-secondlife-region" ||
11265 headerName.ToLower() == "x-secondlife-local-position" ||
11266 headerName.ToLower() == "x-secondlife-local-velocity" ||
11267 headerName.ToLower() == "x-secondlife-local-rotation" ||
11268 headerName.ToLower() == "x-secondlife-owner-name" ||
11269 headerName.ToLower() == "x-secondlife-owner-key" ||
11270 headerName.ToLower() == "connection" ||
11271 headerName.ToLower() == "content-length" ||
11272 headerName.ToLower() == "from" ||
11273 headerName.ToLower() == "host" ||
11274 headerName.ToLower() == "proxy-authorization" ||
11275 headerName.ToLower() == "referer" ||
11276 headerName.ToLower() == "trailer" ||
11277 headerName.ToLower() == "transfer-encoding" ||
11278 headerName.ToLower() == "via" ||
11279 headerName.ToLower() == "authorization")
11280 continue;
11281
11282 httpHeaders[headerName] = headerValue;
11283 }
11284
11285 // Finally, strip any protocol specifier from the URL
11286 url = urlParts[0].Trim();
11287 int idx = url.IndexOf(" HTTP/");
11288 if (idx != -1)
11289 url = url.Substring(0, idx);
11290 }
11291
10528 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11292 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10529 Regex r = new Regex(authregex); 11293 Regex r = new Regex(authregex);
10530 int[] gnums = r.GetGroupNumbers(); 11294 int[] gnums = r.GetGroupNumbers();
10531 Match m = r.Match(url); 11295 Match m = r.Match(url);
10532 if (m.Success) { 11296 if (m.Success)
10533 for (int i = 1; i < gnums.Length; i++) { 11297 {
11298 for (int i = 1; i < gnums.Length; i++)
11299 {
10534 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11300 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10535 //CaptureCollection cc = g.Captures; 11301 //CaptureCollection cc = g.Captures;
10536 } 11302 }
10537 if (m.Groups.Count == 5) { 11303 if (m.Groups.Count == 5)
11304 {
10538 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11305 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10539 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11306 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10540 } 11307 }
@@ -10737,6 +11504,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10737 11504
10738 LSL_List ret = new LSL_List(); 11505 LSL_List ret = new LSL_List();
10739 UUID key = new UUID(); 11506 UUID key = new UUID();
11507
11508
10740 if (UUID.TryParse(id, out key)) 11509 if (UUID.TryParse(id, out key))
10741 { 11510 {
10742 ScenePresence av = World.GetScenePresence(key); 11511 ScenePresence av = World.GetScenePresence(key);
@@ -10754,13 +11523,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10754 ret.Add(new LSL_String("")); 11523 ret.Add(new LSL_String(""));
10755 break; 11524 break;
10756 case ScriptBaseClass.OBJECT_POS: 11525 case ScriptBaseClass.OBJECT_POS:
10757 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11526 Vector3 avpos;
11527
11528 if (av.ParentID != 0 && av.ParentPart != null)
11529 {
11530 avpos = av.OffsetPosition;
11531
11532 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11533 avpos -= sitOffset;
11534
11535 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11536 }
11537 else
11538 avpos = av.AbsolutePosition;
11539
11540 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10758 break; 11541 break;
10759 case ScriptBaseClass.OBJECT_ROT: 11542 case ScriptBaseClass.OBJECT_ROT:
10760 ret.Add(new LSL_Rotation(av.GetWorldRotation())); 11543 Quaternion avrot = av.Rotation;
11544 if (av.ParentID != 0 && av.ParentPart != null)
11545 {
11546 avrot = av.ParentPart.GetWorldRotation() * avrot;
11547 }
11548 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10761 break; 11549 break;
10762 case ScriptBaseClass.OBJECT_VELOCITY: 11550 case ScriptBaseClass.OBJECT_VELOCITY:
10763 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11551 Vector3 avvel = av.Velocity;
11552 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10764 break; 11553 break;
10765 case ScriptBaseClass.OBJECT_OWNER: 11554 case ScriptBaseClass.OBJECT_OWNER:
10766 ret.Add(new LSL_String(id)); 11555 ret.Add(new LSL_String(id));
@@ -10845,11 +11634,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10845 case ScriptBaseClass.OBJECT_NAME: 11634 case ScriptBaseClass.OBJECT_NAME:
10846 ret.Add(new LSL_String(obj.Name)); 11635 ret.Add(new LSL_String(obj.Name));
10847 break; 11636 break;
10848 case ScriptBaseClass.OBJECT_DESC: 11637 case ScriptBaseClass.OBJECT_DESC:
10849 ret.Add(new LSL_String(obj.Description)); 11638 ret.Add(new LSL_String(obj.Description));
10850 break; 11639 break;
10851 case ScriptBaseClass.OBJECT_POS: 11640 case ScriptBaseClass.OBJECT_POS:
10852 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11641 Vector3 opos = obj.AbsolutePosition;
11642 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10853 break; 11643 break;
10854 case ScriptBaseClass.OBJECT_ROT: 11644 case ScriptBaseClass.OBJECT_ROT:
10855 { 11645 {
@@ -10899,9 +11689,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10899 // The value returned in SL for normal prims is prim count 11689 // The value returned in SL for normal prims is prim count
10900 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11690 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10901 break; 11691 break;
10902 // The following 3 costs I have intentionaly coded to return zero. They are part of 11692
10903 // "Land Impact" calculations. These calculations are probably not applicable 11693 // costs below may need to be diferent for root parts, need to check
10904 // to OpenSim and are not yet complete in SL
10905 case ScriptBaseClass.OBJECT_SERVER_COST: 11694 case ScriptBaseClass.OBJECT_SERVER_COST:
10906 // The linden calculation is here 11695 // The linden calculation is here
10907 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11696 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10909,16 +11698,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10909 ret.Add(new LSL_Float(0)); 11698 ret.Add(new LSL_Float(0));
10910 break; 11699 break;
10911 case ScriptBaseClass.OBJECT_STREAMING_COST: 11700 case ScriptBaseClass.OBJECT_STREAMING_COST:
10912 // The linden calculation is here 11701 // The value returned in SL for normal prims is prim count * 0.06
10913 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11702 ret.Add(new LSL_Float(obj.StreamingCost));
10914 // The value returned in SL for normal prims looks like the prim count * 0.06
10915 ret.Add(new LSL_Float(0));
10916 break; 11703 break;
10917 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11704 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10918 // The linden calculation is here 11705 // The value returned in SL for normal prims is prim count
10919 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11706 ret.Add(new LSL_Float(obj.PhysicsCost));
10920 // The value returned in SL for normal prims looks like the prim count
10921 ret.Add(new LSL_Float(0));
10922 break; 11707 break;
10923 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding 11708 case ScriptBaseClass.OBJECT_CHARACTER_TIME: // Pathfinding
10924 ret.Add(new LSL_Float(0)); 11709 ret.Add(new LSL_Float(0));
@@ -11177,15 +11962,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11177 return result; 11962 return result;
11178 } 11963 }
11179 11964
11180 public void print(string str) 11965 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
11181 { 11966 {
11182 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11967 List<SceneObjectPart> parts = GetLinkParts(link);
11183 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11968 if (parts.Count < 1)
11184 if (ossl != null) 11969 return 0;
11185 { 11970
11186 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11971 return GetNumberOfSides(parts[0]);
11187 m_log.Info("LSL print():" + str);
11188 }
11189 } 11972 }
11190 11973
11191 private string Name2Username(string name) 11974 private string Name2Username(string name)
@@ -11230,7 +12013,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11230 12013
11231 return rq.ToString(); 12014 return rq.ToString();
11232 } 12015 }
11233 12016/*
12017 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12018 {
12019 m_SayShoutCount = 0;
12020 }
12021*/
11234 private struct Tri 12022 private struct Tri
11235 { 12023 {
11236 public Vector3 p1; 12024 public Vector3 p1;
@@ -11379,9 +12167,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11379 12167
11380 ContactResult result = new ContactResult (); 12168 ContactResult result = new ContactResult ();
11381 result.ConsumerID = group.LocalId; 12169 result.ConsumerID = group.LocalId;
11382 result.Depth = intersection.distance; 12170// result.Depth = intersection.distance;
11383 result.Normal = intersection.normal; 12171 result.Normal = intersection.normal;
11384 result.Pos = intersection.ipoint; 12172 result.Pos = intersection.ipoint;
12173 result.Depth = Vector3.Mag(rayStart - result.Pos);
11385 12174
11386 contacts.Add(result); 12175 contacts.Add(result);
11387 }); 12176 });
@@ -11514,6 +12303,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11514 12303
11515 return contacts[0]; 12304 return contacts[0];
11516 } 12305 }
12306/*
12307 // not done:
12308 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12309 {
12310 ContactResult[] contacts = null;
12311 World.ForEachSOG(delegate(SceneObjectGroup group)
12312 {
12313 if (m_host.ParentGroup == group)
12314 return;
12315
12316 if (group.IsAttachment)
12317 return;
12318
12319 if(group.RootPart.PhysActor != null)
12320 return;
12321
12322 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12323 });
12324 return contacts;
12325 }
12326*/
11517 12327
11518 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12328 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11519 { 12329 {
@@ -11637,18 +12447,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11637 } 12447 }
11638 } 12448 }
11639 12449
12450 // Double check this
11640 if (checkTerrain) 12451 if (checkTerrain)
11641 { 12452 {
11642 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12453 bool skipGroundCheck = false;
11643 if (groundContact != null) 12454
11644 results.Add((ContactResult)groundContact); 12455 foreach (ContactResult c in results)
12456 {
12457 if (c.ConsumerID == 0) // Physics gave us a ground collision
12458 skipGroundCheck = true;
12459 }
12460
12461 if (!skipGroundCheck)
12462 {
12463 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12464 if (groundContact != null)
12465 results.Add((ContactResult)groundContact);
12466 }
11645 } 12467 }
11646 12468
11647 results.Sort(delegate(ContactResult a, ContactResult b) 12469 results.Sort(delegate(ContactResult a, ContactResult b)
11648 { 12470 {
11649 return a.Depth.CompareTo(b.Depth); 12471 return a.Depth.CompareTo(b.Depth);
11650 }); 12472 });
11651 12473
11652 int values = 0; 12474 int values = 0;
11653 SceneObjectGroup thisgrp = m_host.ParentGroup; 12475 SceneObjectGroup thisgrp = m_host.ParentGroup;
11654 12476
@@ -11741,7 +12563,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11741 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12563 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11742 if (!isAccount) return 0; 12564 if (!isAccount) return 0;
11743 if (estate.HasAccess(id)) return 1; 12565 if (estate.HasAccess(id)) return 1;
11744 if (estate.IsBanned(id)) 12566 if (estate.IsBanned(id, World.GetUserFlags(id)))
11745 estate.RemoveBan(id); 12567 estate.RemoveBan(id);
11746 estate.AddEstateUser(id); 12568 estate.AddEstateUser(id);
11747 break; 12569 break;
@@ -11760,14 +12582,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11760 break; 12582 break;
11761 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12583 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11762 if (!isAccount) return 0; 12584 if (!isAccount) return 0;
11763 if (estate.IsBanned(id)) return 1; 12585 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11764 EstateBan ban = new EstateBan(); 12586 EstateBan ban = new EstateBan();
11765 ban.EstateID = estate.EstateID; 12587 ban.EstateID = estate.EstateID;
11766 ban.BannedUserID = id; 12588 ban.BannedUserID = id;
11767 estate.AddBan(ban); 12589 estate.AddBan(ban);
11768 break; 12590 break;
11769 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12591 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11770 if (!isAccount || !estate.IsBanned(id)) return 0; 12592 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11771 estate.RemoveBan(id); 12593 estate.RemoveBan(id);
11772 break; 12594 break;
11773 default: return 0; 12595 default: return 0;
@@ -11832,13 +12654,63 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11832 public void llCollisionSprite(string impact_sprite) 12654 public void llCollisionSprite(string impact_sprite)
11833 { 12655 {
11834 m_host.AddScriptLPS(1); 12656 m_host.AddScriptLPS(1);
11835 NotImplemented("llCollisionSprite"); 12657 // Viewer 2.0 broke this and it's likely LL has no intention
12658 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11836 } 12659 }
11837 12660
11838 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12661 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11839 { 12662 {
11840 m_host.AddScriptLPS(1); 12663 m_host.AddScriptLPS(1);
11841 NotImplemented("llGodLikeRezObject"); 12664
12665 if (!World.Permissions.IsGod(m_host.OwnerID))
12666 NotImplemented("llGodLikeRezObject");
12667
12668 AssetBase rezAsset = World.AssetService.Get(inventory);
12669 if (rezAsset == null)
12670 {
12671 llSay(0, "Asset not found");
12672 return;
12673 }
12674
12675 SceneObjectGroup group = null;
12676
12677 try
12678 {
12679 string xmlData = Utils.BytesToString(rezAsset.Data);
12680 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12681 }
12682 catch
12683 {
12684 llSay(0, "Asset not found");
12685 return;
12686 }
12687
12688 if (group == null)
12689 {
12690 llSay(0, "Asset not found");
12691 return;
12692 }
12693
12694 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12695 group.RootPart.AttachOffset = group.AbsolutePosition;
12696
12697 group.ResetIDs();
12698
12699 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12700 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12701 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12702 group.ScheduleGroupForFullUpdate();
12703
12704 // objects rezzed with this method are die_at_edge by default.
12705 group.RootPart.SetDieAtEdge(true);
12706
12707 group.ResumeScripts();
12708
12709 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12710 "object_rez", new Object[] {
12711 new LSL_String(
12712 group.RootPart.UUID.ToString()) },
12713 new DetectParams[0]));
11842 } 12714 }
11843 12715
11844 public LSL_String llTransferLindenDollars(string destination, int amount) 12716 public LSL_String llTransferLindenDollars(string destination, int amount)
@@ -11890,7 +12762,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11890 } 12762 }
11891 12763
11892 bool result = money.ObjectGiveMoney( 12764 bool result = money.ObjectGiveMoney(
11893 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 12765 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn);
11894 12766
11895 if (result) 12767 if (result)
11896 { 12768 {
@@ -11915,6 +12787,598 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11915 } 12787 }
11916 12788
11917 #endregion 12789 #endregion
12790
12791 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12792 {
12793 SceneObjectGroup group = m_host.ParentGroup;
12794
12795 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12796 return;
12797 if (group.IsAttachment)
12798 return;
12799
12800 if (frames.Data.Length > 0) // We are getting a new motion
12801 {
12802 if (group.RootPart.KeyframeMotion != null)
12803 group.RootPart.KeyframeMotion.Delete();
12804 group.RootPart.KeyframeMotion = null;
12805
12806 int idx = 0;
12807
12808 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12809 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12810
12811 while (idx < options.Data.Length)
12812 {
12813 int option = (int)options.GetLSLIntegerItem(idx++);
12814 int remain = options.Data.Length - idx;
12815
12816 switch (option)
12817 {
12818 case ScriptBaseClass.KFM_MODE:
12819 if (remain < 1)
12820 break;
12821 int modeval = (int)options.GetLSLIntegerItem(idx++);
12822 switch(modeval)
12823 {
12824 case ScriptBaseClass.KFM_FORWARD:
12825 mode = KeyframeMotion.PlayMode.Forward;
12826 break;
12827 case ScriptBaseClass.KFM_REVERSE:
12828 mode = KeyframeMotion.PlayMode.Reverse;
12829 break;
12830 case ScriptBaseClass.KFM_LOOP:
12831 mode = KeyframeMotion.PlayMode.Loop;
12832 break;
12833 case ScriptBaseClass.KFM_PING_PONG:
12834 mode = KeyframeMotion.PlayMode.PingPong;
12835 break;
12836 }
12837 break;
12838 case ScriptBaseClass.KFM_DATA:
12839 if (remain < 1)
12840 break;
12841 int dataval = (int)options.GetLSLIntegerItem(idx++);
12842 data = (KeyframeMotion.DataFormat)dataval;
12843 break;
12844 }
12845 }
12846
12847 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12848
12849 idx = 0;
12850
12851 int elemLength = 2;
12852 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12853 elemLength = 3;
12854
12855 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12856 while (idx < frames.Data.Length)
12857 {
12858 int remain = frames.Data.Length - idx;
12859
12860 if (remain < elemLength)
12861 break;
12862
12863 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12864 frame.Position = null;
12865 frame.Rotation = null;
12866
12867 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12868 {
12869 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12870 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12871 }
12872 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12873 {
12874 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12875 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12876 q.Normalize();
12877 frame.Rotation = q;
12878 }
12879
12880 float tempf = (float)frames.GetLSLFloatItem(idx++);
12881 frame.TimeMS = (int)(tempf * 1000.0f);
12882
12883 keyframes.Add(frame);
12884 }
12885
12886 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12887 group.RootPart.KeyframeMotion.Start();
12888 }
12889 else
12890 {
12891 if (group.RootPart.KeyframeMotion == null)
12892 return;
12893
12894 if (options.Data.Length == 0)
12895 {
12896 group.RootPart.KeyframeMotion.Stop();
12897 return;
12898 }
12899
12900 int code = (int)options.GetLSLIntegerItem(0);
12901
12902 int idx = 0;
12903
12904 while (idx < options.Data.Length)
12905 {
12906 int option = (int)options.GetLSLIntegerItem(idx++);
12907 int remain = options.Data.Length - idx;
12908
12909 switch (option)
12910 {
12911 case ScriptBaseClass.KFM_COMMAND:
12912 int cmd = (int)options.GetLSLIntegerItem(idx++);
12913 switch (cmd)
12914 {
12915 case ScriptBaseClass.KFM_CMD_PLAY:
12916 group.RootPart.KeyframeMotion.Start();
12917 break;
12918 case ScriptBaseClass.KFM_CMD_STOP:
12919 group.RootPart.KeyframeMotion.Stop();
12920 break;
12921 case ScriptBaseClass.KFM_CMD_PAUSE:
12922 group.RootPart.KeyframeMotion.Pause();
12923 break;
12924 }
12925 break;
12926 }
12927 }
12928 }
12929 }
12930
12931 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12932 {
12933 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12934
12935 int idx = 0;
12936 int idxStart = 0;
12937
12938 bool positionChanged = false;
12939 Vector3 finalPos = Vector3.Zero;
12940
12941 try
12942 {
12943 while (idx < rules.Length)
12944 {
12945 ++rulesParsed;
12946 int code = rules.GetLSLIntegerItem(idx++);
12947
12948 int remain = rules.Length - idx;
12949 idxStart = idx;
12950
12951 switch (code)
12952 {
12953 case (int)ScriptBaseClass.PRIM_POSITION:
12954 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12955 {
12956 if (remain < 1)
12957 return null;
12958
12959 LSL_Vector v;
12960 v = rules.GetVector3Item(idx++);
12961
12962 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12963 if (part == null)
12964 break;
12965
12966 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12967 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12968 if (part.LinkNum > 1)
12969 {
12970 localRot = GetPartLocalRot(part);
12971 localPos = GetPartLocalPos(part);
12972 }
12973
12974 v -= localPos;
12975 v /= localRot;
12976
12977 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12978
12979 v = v + 2 * sitOffset;
12980
12981 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12982 av.SendAvatarDataToAllAgents();
12983
12984 }
12985 break;
12986
12987 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12988 case (int)ScriptBaseClass.PRIM_ROTATION:
12989 {
12990 if (remain < 1)
12991 return null;
12992
12993 LSL_Rotation r;
12994 r = rules.GetQuaternionItem(idx++);
12995
12996 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12997 if (part == null)
12998 break;
12999
13000 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
13001 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
13002
13003 if (part.LinkNum > 1)
13004 localRot = GetPartLocalRot(part);
13005
13006 r = r * llGetRootRotation() / localRot;
13007 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
13008 av.SendAvatarDataToAllAgents();
13009 }
13010 break;
13011
13012 // parse rest doing nothing but number of parameters error check
13013 case (int)ScriptBaseClass.PRIM_SIZE:
13014 case (int)ScriptBaseClass.PRIM_MATERIAL:
13015 case (int)ScriptBaseClass.PRIM_PHANTOM:
13016 case (int)ScriptBaseClass.PRIM_PHYSICS:
13017 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
13018 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13019 case (int)ScriptBaseClass.PRIM_NAME:
13020 case (int)ScriptBaseClass.PRIM_DESC:
13021 if (remain < 1)
13022 return null;
13023 idx++;
13024 break;
13025
13026 case (int)ScriptBaseClass.PRIM_GLOW:
13027 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13028 case (int)ScriptBaseClass.PRIM_TEXGEN:
13029 if (remain < 2)
13030 return null;
13031 idx += 2;
13032 break;
13033
13034 case (int)ScriptBaseClass.PRIM_TYPE:
13035 if (remain < 3)
13036 return null;
13037 code = (int)rules.GetLSLIntegerItem(idx++);
13038 remain = rules.Length - idx;
13039 switch (code)
13040 {
13041 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
13042 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
13043 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
13044 if (remain < 6)
13045 return null;
13046 idx += 6;
13047 break;
13048
13049 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
13050 if (remain < 5)
13051 return null;
13052 idx += 5;
13053 break;
13054
13055 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
13056 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
13057 case (int)ScriptBaseClass.PRIM_TYPE_RING:
13058 if (remain < 11)
13059 return null;
13060 idx += 11;
13061 break;
13062
13063 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
13064 if (remain < 2)
13065 return null;
13066 idx += 2;
13067 break;
13068 }
13069 break;
13070
13071 case (int)ScriptBaseClass.PRIM_COLOR:
13072 case (int)ScriptBaseClass.PRIM_TEXT:
13073 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13074 case (int)ScriptBaseClass.PRIM_OMEGA:
13075 if (remain < 3)
13076 return null;
13077 idx += 3;
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_TEXTURE:
13081 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13082 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
13083 if (remain < 5)
13084 return null;
13085 idx += 5;
13086 break;
13087
13088 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13089 if (remain < 7)
13090 return null;
13091
13092 idx += 7;
13093 break;
13094
13095 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13096 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13097 return null;
13098
13099 return rules.GetSublist(idx, -1);
13100 }
13101 }
13102 }
13103 catch (InvalidCastException e)
13104 {
13105 ShoutError(string.Format(
13106 "{0} error running rule #{1}: arg #{2} ",
13107 originFunc, rulesParsed, idx - idxStart) + e.Message);
13108 }
13109 finally
13110 {
13111 if (positionChanged)
13112 {
13113 av.OffsetPosition = finalPos;
13114// av.SendAvatarDataToAllAgents();
13115 av.SendTerseUpdateToAllClients();
13116 positionChanged = false;
13117 }
13118 }
13119 return null;
13120 }
13121
13122 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
13123 {
13124 // avatars case
13125 // replies as SL wiki
13126
13127// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
13128 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
13129
13130 int idx = 0;
13131 while (idx < rules.Length)
13132 {
13133 int code = (int)rules.GetLSLIntegerItem(idx++);
13134 int remain = rules.Length - idx;
13135
13136 switch (code)
13137 {
13138 case (int)ScriptBaseClass.PRIM_MATERIAL:
13139 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
13140 break;
13141
13142 case (int)ScriptBaseClass.PRIM_PHYSICS:
13143 res.Add(new LSL_Integer(0));
13144 break;
13145
13146 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
13147 res.Add(new LSL_Integer(0));
13148 break;
13149
13150 case (int)ScriptBaseClass.PRIM_PHANTOM:
13151 res.Add(new LSL_Integer(0));
13152 break;
13153
13154 case (int)ScriptBaseClass.PRIM_POSITION:
13155
13156 Vector3 pos = avatar.OffsetPosition;
13157
13158 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
13159 pos -= sitOffset;
13160
13161 if( sitPart != null)
13162 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
13163
13164 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
13165 break;
13166
13167 case (int)ScriptBaseClass.PRIM_SIZE:
13168 // as in llGetAgentSize above
13169// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
13170 Vector3 s = avatar.Appearance.AvatarSize;
13171 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
13172
13173 break;
13174
13175 case (int)ScriptBaseClass.PRIM_ROTATION:
13176 Quaternion rot = avatar.Rotation;
13177 if (sitPart != null)
13178 {
13179 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
13180 }
13181
13182 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
13183 break;
13184
13185 case (int)ScriptBaseClass.PRIM_TYPE:
13186 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
13187 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
13188 res.Add(new LSL_Vector(0f,1.0f,0f));
13189 res.Add(new LSL_Float(0.0f));
13190 res.Add(new LSL_Vector(0, 0, 0));
13191 res.Add(new LSL_Vector(1.0f,1.0f,0f));
13192 res.Add(new LSL_Vector(0, 0, 0));
13193 break;
13194
13195 case (int)ScriptBaseClass.PRIM_TEXTURE:
13196 if (remain < 1)
13197 return null;
13198
13199 int face = (int)rules.GetLSLIntegerItem(idx++);
13200 if (face == ScriptBaseClass.ALL_SIDES)
13201 {
13202 for (face = 0; face < 21; face++)
13203 {
13204 res.Add(new LSL_String(""));
13205 res.Add(new LSL_Vector(0,0,0));
13206 res.Add(new LSL_Vector(0,0,0));
13207 res.Add(new LSL_Float(0.0));
13208 }
13209 }
13210 else
13211 {
13212 if (face >= 0 && face < 21)
13213 {
13214 res.Add(new LSL_String(""));
13215 res.Add(new LSL_Vector(0,0,0));
13216 res.Add(new LSL_Vector(0,0,0));
13217 res.Add(new LSL_Float(0.0));
13218 }
13219 }
13220 break;
13221
13222 case (int)ScriptBaseClass.PRIM_COLOR:
13223 if (remain < 1)
13224 return null;
13225
13226 face = (int)rules.GetLSLIntegerItem(idx++);
13227
13228 if (face == ScriptBaseClass.ALL_SIDES)
13229 {
13230 for (face = 0; face < 21; face++)
13231 {
13232 res.Add(new LSL_Vector(0,0,0));
13233 res.Add(new LSL_Float(0));
13234 }
13235 }
13236 else
13237 {
13238 res.Add(new LSL_Vector(0,0,0));
13239 res.Add(new LSL_Float(0));
13240 }
13241 break;
13242
13243 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13244 if (remain < 1)
13245 return null;
13246 face = (int)rules.GetLSLIntegerItem(idx++);
13247
13248 if (face == ScriptBaseClass.ALL_SIDES)
13249 {
13250 for (face = 0; face < 21; face++)
13251 {
13252 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13253 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13254 }
13255 }
13256 else
13257 {
13258 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13259 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13260 }
13261 break;
13262
13263 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13264 if (remain < 1)
13265 return null;
13266 face = (int)rules.GetLSLIntegerItem(idx++);
13267
13268 if (face == ScriptBaseClass.ALL_SIDES)
13269 {
13270 for (face = 0; face < 21; face++)
13271 {
13272 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13273 }
13274 }
13275 else
13276 {
13277 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13278 }
13279 break;
13280
13281 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13282 res.Add(new LSL_Integer(0));
13283 res.Add(new LSL_Integer(0));// softness
13284 res.Add(new LSL_Float(0.0f)); // gravity
13285 res.Add(new LSL_Float(0.0f)); // friction
13286 res.Add(new LSL_Float(0.0f)); // wind
13287 res.Add(new LSL_Float(0.0f)); // tension
13288 res.Add(new LSL_Vector(0f,0f,0f));
13289 break;
13290
13291 case (int)ScriptBaseClass.PRIM_TEXGEN:
13292 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13293 if (remain < 1)
13294 return null;
13295 face = (int)rules.GetLSLIntegerItem(idx++);
13296
13297 if (face == ScriptBaseClass.ALL_SIDES)
13298 {
13299 for (face = 0; face < 21; face++)
13300 {
13301 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13302 }
13303 }
13304 else
13305 {
13306 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13307 }
13308 break;
13309
13310 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13311 res.Add(new LSL_Integer(0));
13312 res.Add(new LSL_Vector(0f,0f,0f));
13313 res.Add(new LSL_Float(0f)); // intensity
13314 res.Add(new LSL_Float(0f)); // radius
13315 res.Add(new LSL_Float(0f)); // falloff
13316 break;
13317
13318 case (int)ScriptBaseClass.PRIM_GLOW:
13319 if (remain < 1)
13320 return null;
13321 face = (int)rules.GetLSLIntegerItem(idx++);
13322
13323 if (face == ScriptBaseClass.ALL_SIDES)
13324 {
13325 for (face = 0; face < 21; face++)
13326 {
13327 res.Add(new LSL_Float(0f));
13328 }
13329 }
13330 else
13331 {
13332 res.Add(new LSL_Float(0f));
13333 }
13334 break;
13335
13336 case (int)ScriptBaseClass.PRIM_TEXT:
13337 res.Add(new LSL_String(""));
13338 res.Add(new LSL_Vector(0f,0f,0f));
13339 res.Add(new LSL_Float(1.0f));
13340 break;
13341
13342 case (int)ScriptBaseClass.PRIM_NAME:
13343 res.Add(new LSL_String(avatar.Name));
13344 break;
13345
13346 case (int)ScriptBaseClass.PRIM_DESC:
13347 res.Add(new LSL_String(""));
13348 break;
13349
13350 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13351 Quaternion lrot = avatar.Rotation;
13352
13353 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13354 {
13355 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13356 }
13357 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13358 break;
13359
13360 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13361 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13362 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13363 lpos -= lsitOffset;
13364
13365 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13366 {
13367 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13368 }
13369 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13370 break;
13371
13372 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13373 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13374 return null;
13375
13376 return rules.GetSublist(idx, -1);
13377 }
13378 }
13379
13380 return null;
13381 }
11918 } 13382 }
11919 13383
11920 public class NotecardCache 13384 public class NotecardCache