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.cs3216
1 files changed, 2464 insertions, 752 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index f9b90c5..253d193 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.Physics.Manager; 51using OpenSim.Region.Physics.Manager;
49using OpenSim.Region.ScriptEngine.Shared; 52using OpenSim.Region.ScriptEngine.Shared;
@@ -66,6 +69,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
66using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 69using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
67using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 70using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
68using System.Reflection; 71using System.Reflection;
72using Timer = System.Timers.Timer;
69 73
70namespace OpenSim.Region.ScriptEngine.Shared.Api 74namespace OpenSim.Region.ScriptEngine.Shared.Api
71{ 75{
@@ -105,16 +109,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
105 protected int m_notecardLineReadCharsMax = 255; 109 protected int m_notecardLineReadCharsMax = 255;
106 protected int m_scriptConsoleChannel = 0; 110 protected int m_scriptConsoleChannel = 0;
107 protected bool m_scriptConsoleChannelEnabled = false; 111 protected bool m_scriptConsoleChannelEnabled = false;
112 protected bool m_debuggerSafe = false;
108 protected IUrlModule m_UrlModule = null; 113 protected IUrlModule m_UrlModule = null;
109 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 114 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
110 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 115 new Dictionary<UUID, UserInfoCacheEntry>();
116 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
111 protected ISoundModule m_SoundModule = null; 117 protected ISoundModule m_SoundModule = null;
112 118
119// protected Timer m_ShoutSayTimer;
120 protected int m_SayShoutCount = 0;
121 DateTime m_lastSayShoutCheck;
122
123 private Dictionary<string, string> MovementAnimationsForLSL =
124 new Dictionary<string, string> {
125 {"FLY", "Flying"},
126 {"FLYSLOW", "FlyingSlow"},
127 {"HOVER_UP", "Hovering Up"},
128 {"HOVER_DOWN", "Hovering Down"},
129 {"HOVER", "Hovering"},
130 {"LAND", "Landing"},
131 {"FALLDOWN", "Falling Down"},
132 {"PREJUMP", "PreJumping"},
133 {"JUMP", "Jumping"},
134 {"STANDUP", "Standing Up"},
135 {"SOFT_LAND", "Soft Landing"},
136 {"STAND", "Standing"},
137 {"CROUCHWALK", "CrouchWalking"},
138 {"RUN", "Running"},
139 {"WALK", "Walking"},
140 {"CROUCH", "Crouching"},
141 {"TURNLEFT", "Turning Left"},
142 {"TURNRIGHT", "Turning Right"}
143 };
144
113 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 145 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
114 { 146 {
147/*
148 m_ShoutSayTimer = new Timer(1000);
149 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
150 m_ShoutSayTimer.AutoReset = true;
151 m_ShoutSayTimer.Start();
152*/
153 m_lastSayShoutCheck = DateTime.UtcNow;
154
115 m_ScriptEngine = ScriptEngine; 155 m_ScriptEngine = ScriptEngine;
116 m_host = host; 156 m_host = host;
117 m_item = item; 157 m_item = item;
158 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
118 159
119 LoadLimits(); // read script limits from config. 160 LoadLimits(); // read script limits from config.
120 161
@@ -179,6 +220,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
179 get { return m_ScriptEngine.World; } 220 get { return m_ScriptEngine.World; }
180 } 221 }
181 222
223 [DebuggerNonUserCode]
182 public void state(string newState) 224 public void state(string newState)
183 { 225 {
184 m_ScriptEngine.SetState(m_item.ItemID, newState); 226 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -188,6 +230,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
188 /// Reset the named script. The script must be present 230 /// Reset the named script. The script must be present
189 /// in the same prim. 231 /// in the same prim.
190 /// </summary> 232 /// </summary>
233 [DebuggerNonUserCode]
191 public void llResetScript() 234 public void llResetScript()
192 { 235 {
193 m_host.AddScriptLPS(1); 236 m_host.AddScriptLPS(1);
@@ -250,6 +293,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
250 } 293 }
251 } 294 }
252 295
296 public List<ScenePresence> GetLinkAvatars(int linkType)
297 {
298 List<ScenePresence> ret = new List<ScenePresence>();
299 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
300 return ret;
301
302 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
303
304 switch (linkType)
305 {
306 case ScriptBaseClass.LINK_SET:
307 return avs;
308
309 case ScriptBaseClass.LINK_ROOT:
310 return ret;
311
312 case ScriptBaseClass.LINK_ALL_OTHERS:
313 return avs;
314
315 case ScriptBaseClass.LINK_ALL_CHILDREN:
316 return avs;
317
318 case ScriptBaseClass.LINK_THIS:
319 return ret;
320
321 default:
322 if (linkType < 0)
323 return ret;
324
325 int partCount = m_host.ParentGroup.GetPartCount();
326
327 if (linkType <= partCount)
328 {
329 return ret;
330 }
331 else
332 {
333 linkType = linkType - partCount;
334 if (linkType > avs.Count)
335 {
336 return ret;
337 }
338 else
339 {
340 ret.Add(avs[linkType-1]);
341 return ret;
342 }
343 }
344 }
345 }
346
253 public List<SceneObjectPart> GetLinkParts(int linkType) 347 public List<SceneObjectPart> GetLinkParts(int linkType)
254 { 348 {
255 return GetLinkParts(m_host, linkType); 349 return GetLinkParts(m_host, linkType);
@@ -258,6 +352,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
258 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 352 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
259 { 353 {
260 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 354 List<SceneObjectPart> ret = new List<SceneObjectPart>();
355 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
356 return ret;
261 ret.Add(part); 357 ret.Add(part);
262 358
263 switch (linkType) 359 switch (linkType)
@@ -484,31 +580,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
484 580
485 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 581 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
486 582
487 /// <summary> 583 // Utility function for llRot2Euler
488 /// Convert an LSL rotation to a Euler vector. 584
489 /// </summary> 585 // normalize an angle between -PI and PI (-180 to +180 degrees)
490 /// <remarks> 586 protected double NormalizeAngle(double angle)
491 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
492 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
493 /// </remarks>
494 /// <param name="r"></param>
495 /// <returns></returns>
496 public LSL_Vector llRot2Euler(LSL_Rotation r)
497 { 587 {
498 m_host.AddScriptLPS(1); 588 if (angle > -Math.PI && angle < Math.PI)
589 return angle;
499 590
500 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 591 int numPis = (int)(Math.PI / angle);
501 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 592 double remainder = angle - Math.PI * numPis;
502 if (m == 0.0) return new LSL_Vector(); 593 if (numPis % 2 == 1)
503 double x = Math.Atan2(-v.y, v.z); 594 return Math.PI - angle;
504 double sin = v.x / m; 595 return remainder;
505 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 596 }
506 double y = Math.Asin(sin);
507 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
508 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)));
509 double z = Math.Atan2(v.y, v.x);
510 597
511 return new LSL_Vector(x, y, z); 598 public LSL_Vector llRot2Euler(LSL_Rotation q1)
599 {
600 m_host.AddScriptLPS(1);
601 LSL_Vector eul = new LSL_Vector();
602
603 double sqw = q1.s*q1.s;
604 double sqx = q1.x*q1.x;
605 double sqy = q1.z*q1.z;
606 double sqz = q1.y*q1.y;
607 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
608 double test = q1.x*q1.z + q1.y*q1.s;
609 if (test > 0.4999*unit) { // singularity at north pole
610 eul.z = 2 * Math.Atan2(q1.x,q1.s);
611 eul.y = Math.PI/2;
612 eul.x = 0;
613 return eul;
614 }
615 if (test < -0.4999*unit) { // singularity at south pole
616 eul.z = -2 * Math.Atan2(q1.x,q1.s);
617 eul.y = -Math.PI/2;
618 eul.x = 0;
619 return eul;
620 }
621 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
622 eul.y = Math.Asin(2*test/unit);
623 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
624 return eul;
512 } 625 }
513 626
514 /* From wiki: 627 /* From wiki:
@@ -561,18 +674,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
561 m_host.AddScriptLPS(1); 674 m_host.AddScriptLPS(1);
562 675
563 double x,y,z,s; 676 double x,y,z,s;
564 677 v.x *= 0.5;
565 double c1 = Math.Cos(v.x * 0.5); 678 v.y *= 0.5;
566 double c2 = Math.Cos(v.y * 0.5); 679 v.z *= 0.5;
567 double c3 = Math.Cos(v.z * 0.5); 680 double c1 = Math.Cos(v.x);
568 double s1 = Math.Sin(v.x * 0.5); 681 double c2 = Math.Cos(v.y);
569 double s2 = Math.Sin(v.y * 0.5); 682 double c1c2 = c1 * c2;
570 double s3 = Math.Sin(v.z * 0.5); 683 double s1 = Math.Sin(v.x);
571 684 double s2 = Math.Sin(v.y);
572 x = s1 * c2 * c3 + c1 * s2 * s3; 685 double s1s2 = s1 * s2;
573 y = c1 * s2 * c3 - s1 * c2 * s3; 686 double c1s2 = c1 * s2;
574 z = s1 * s2 * c3 + c1 * c2 * s3; 687 double s1c2 = s1 * c2;
575 s = c1 * c2 * c3 - s1 * s2 * s3; 688 double c3 = Math.Cos(v.z);
689 double s3 = Math.Sin(v.z);
690
691 x = s1c2 * c3 + c1s2 * s3;
692 y = c1s2 * c3 - s1c2 * s3;
693 z = s1s2 * c3 + c1c2 * s3;
694 s = c1c2 * c3 - s1s2 * s3;
576 695
577 return new LSL_Rotation(x, y, z, s); 696 return new LSL_Rotation(x, y, z, s);
578 } 697 }
@@ -710,77 +829,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
710 { 829 {
711 //A and B should both be normalized 830 //A and B should both be normalized
712 m_host.AddScriptLPS(1); 831 m_host.AddScriptLPS(1);
713 LSL_Rotation rotBetween; 832 /* This method is more accurate than the SL one, and thus causes problems
714 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 833 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
715 // continue calculation. 834
716 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 835 double dotProduct = LSL_Vector.Dot(a, b);
836 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
837 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
838 double angle = Math.Acos(dotProduct / magProduct);
839 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
840 double s = Math.Sin(angle / 2);
841
842 double x = axis.x * s;
843 double y = axis.y * s;
844 double z = axis.z * s;
845 double w = Math.Cos(angle / 2);
846
847 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
848 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
849
850 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
851 */
852
853 // This method mimics the 180 errors found in SL
854 // See www.euclideanspace.com... angleBetween
855 LSL_Vector vec_a = a;
856 LSL_Vector vec_b = b;
857
858 // Eliminate zero length
859 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
860 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
861 if (vec_a_mag < 0.00001 ||
862 vec_b_mag < 0.00001)
717 { 863 {
718 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 864 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
719 } 865 }
720 else 866
867 // Normalize
868 vec_a = llVecNorm(vec_a);
869 vec_b = llVecNorm(vec_b);
870
871 // Calculate axis and rotation angle
872 LSL_Vector axis = vec_a % vec_b;
873 LSL_Float cos_theta = vec_a * vec_b;
874
875 // Check if parallel
876 if (cos_theta > 0.99999)
721 { 877 {
722 a = LSL_Vector.Norm(a); 878 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
723 b = LSL_Vector.Norm(b); 879 }
724 double dotProduct = LSL_Vector.Dot(a, b); 880
725 // There are two degenerate cases possible. These are for vectors 180 or 881 // Check if anti-parallel
726 // 0 degrees apart. These have to be detected and handled individually. 882 else if (cos_theta < -0.99999)
727 // 883 {
728 // Check for vectors 180 degrees apart. 884 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
729 // A dot product of -1 would mean the angle between vectors is 180 degrees. 885 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
730 if (dotProduct < -0.9999999f) 886 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
731 { 887 }
732 // First assume X axis is orthogonal to the vectors. 888 else // other rotation
733 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 889 {
734 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 890 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
735 // Check for near zero vector. A very small non-zero number here will create 891 axis = llVecNorm(axis);
736 // a rotation in an undesired direction. 892 double x, y, z, s, t;
737 if (LSL_Vector.Mag(orthoVector) > 0.0001) 893 s = Math.Cos(theta);
738 { 894 t = Math.Sin(theta);
739 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 895 x = axis.x * t;
740 } 896 y = axis.y * t;
741 // If the magnitude of the vector was near zero, then assume the X axis is not 897 z = axis.z * t;
742 // orthogonal and use the Z axis instead. 898 return new LSL_Rotation(x,y,z,s);
743 else
744 {
745 // Set 180 z rotation.
746 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
747 }
748 }
749 // Check for parallel vectors.
750 // A dot product of 1 would mean the angle between vectors is 0 degrees.
751 else if (dotProduct > 0.9999999f)
752 {
753 // Set zero rotation.
754 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
755 }
756 else
757 {
758 // All special checks have been performed so get the axis of rotation.
759 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
760 // Quarternion s value is the length of the unit vector + dot product.
761 double qs = 1.0 + dotProduct;
762 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
763 // Normalize the rotation.
764 double mag = LSL_Rotation.Mag(rotBetween);
765 // We shouldn't have to worry about a divide by zero here. The qs value will be
766 // non-zero because we already know if we're here, then the dotProduct is not -1 so
767 // qs will not be zero. Also, we've already handled the input vectors being zero so the
768 // crossProduct vector should also not be zero.
769 rotBetween.x = rotBetween.x / mag;
770 rotBetween.y = rotBetween.y / mag;
771 rotBetween.z = rotBetween.z / mag;
772 rotBetween.s = rotBetween.s / mag;
773 // Check for undefined values and set zero rotation if any found. This code might not actually be required
774 // any longer since zero vectors are checked for at the top.
775 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
776 {
777 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
778 }
779 }
780 } 899 }
781 return rotBetween;
782 } 900 }
783 901
784 public void llWhisper(int channelID, string text) 902 public void llWhisper(int channelID, string text)
785 { 903 {
786 m_host.AddScriptLPS(1); 904 m_host.AddScriptLPS(1);
@@ -796,10 +914,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
796 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 914 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
797 } 915 }
798 916
917 private void CheckSayShoutTime()
918 {
919 DateTime now = DateTime.UtcNow;
920 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
921 {
922 m_lastSayShoutCheck = now;
923 m_SayShoutCount = 0;
924 }
925 else
926 m_SayShoutCount++;
927 }
928
799 public void llSay(int channelID, string text) 929 public void llSay(int channelID, string text)
800 { 930 {
801 m_host.AddScriptLPS(1); 931 m_host.AddScriptLPS(1);
802 932
933 if (channelID == 0)
934// m_SayShoutCount++;
935 CheckSayShoutTime();
936
937 if (m_SayShoutCount >= 11)
938 ScriptSleep(2000);
939
803 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 940 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
804 { 941 {
805 Console.WriteLine(text); 942 Console.WriteLine(text);
@@ -822,6 +959,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
822 { 959 {
823 m_host.AddScriptLPS(1); 960 m_host.AddScriptLPS(1);
824 961
962 if (channelID == 0)
963// m_SayShoutCount++;
964 CheckSayShoutTime();
965
966 if (m_SayShoutCount >= 11)
967 ScriptSleep(2000);
968
825 if (text.Length > 1023) 969 if (text.Length > 1023)
826 text = text.Substring(0, 1023); 970 text = text.Substring(0, 1023);
827 971
@@ -853,22 +997,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
853 997
854 public void llRegionSayTo(string target, int channel, string msg) 998 public void llRegionSayTo(string target, int channel, string msg)
855 { 999 {
1000 string error = String.Empty;
1001
856 if (msg.Length > 1023) 1002 if (msg.Length > 1023)
857 msg = msg.Substring(0, 1023); 1003 msg = msg.Substring(0, 1023);
858 1004
859 m_host.AddScriptLPS(1); 1005 m_host.AddScriptLPS(1);
860 1006
861 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
862 {
863 return;
864 }
865
866 UUID TargetID; 1007 UUID TargetID;
867 UUID.TryParse(target, out TargetID); 1008 UUID.TryParse(target, out TargetID);
868 1009
869 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1010 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
870 if (wComm != null) 1011 if (wComm != null)
871 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1012 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1013 LSLError(error);
872 } 1014 }
873 1015
874 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1016 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1124,10 +1266,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1124 return detectedParams.TouchUV; 1266 return detectedParams.TouchUV;
1125 } 1267 }
1126 1268
1269 [DebuggerNonUserCode]
1127 public virtual void llDie() 1270 public virtual void llDie()
1128 { 1271 {
1129 m_host.AddScriptLPS(1); 1272 m_host.AddScriptLPS(1);
1130 throw new SelfDeleteException(); 1273 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1131 } 1274 }
1132 1275
1133 public LSL_Float llGround(LSL_Vector offset) 1276 public LSL_Float llGround(LSL_Vector offset)
@@ -1198,6 +1341,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1198 1341
1199 public void llSetStatus(int status, int value) 1342 public void llSetStatus(int status, int value)
1200 { 1343 {
1344 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1345 return;
1201 m_host.AddScriptLPS(1); 1346 m_host.AddScriptLPS(1);
1202 1347
1203 int statusrotationaxis = 0; 1348 int statusrotationaxis = 0;
@@ -1221,6 +1366,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1221 if (!allow) 1366 if (!allow)
1222 return; 1367 return;
1223 1368
1369 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1370 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1371 return;
1372
1224 m_host.ScriptSetPhysicsStatus(true); 1373 m_host.ScriptSetPhysicsStatus(true);
1225 } 1374 }
1226 else 1375 else
@@ -1421,6 +1570,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1421 { 1570 {
1422 m_host.AddScriptLPS(1); 1571 m_host.AddScriptLPS(1);
1423 1572
1573 SetColor(m_host, color, face);
1574 }
1575
1576 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1577 {
1578 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1579 return;
1580
1581 Primitive.TextureEntry tex = part.Shape.Textures;
1582 Color4 texcolor;
1583 if (face >= 0 && face < GetNumberOfSides(part))
1584 {
1585 texcolor = tex.CreateFace((uint)face).RGBA;
1586 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1587 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1588 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1589 tex.FaceTextures[face].RGBA = texcolor;
1590 part.UpdateTextureEntry(tex.GetBytes());
1591 return;
1592 }
1593 else if (face == ScriptBaseClass.ALL_SIDES)
1594 {
1595 for (uint i = 0; i < GetNumberOfSides(part); i++)
1596 {
1597 if (tex.FaceTextures[i] != null)
1598 {
1599 texcolor = tex.FaceTextures[i].RGBA;
1600 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1601 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1602 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1603 tex.FaceTextures[i].RGBA = texcolor;
1604 }
1605 texcolor = tex.DefaultTexture.RGBA;
1606 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1607 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1608 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1609 tex.DefaultTexture.RGBA = texcolor;
1610 }
1611 part.UpdateTextureEntry(tex.GetBytes());
1612 return;
1613 }
1614
1424 if (face == ScriptBaseClass.ALL_SIDES) 1615 if (face == ScriptBaseClass.ALL_SIDES)
1425 face = SceneObjectPart.ALL_SIDES; 1616 face = SceneObjectPart.ALL_SIDES;
1426 1617
@@ -1429,6 +1620,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1429 1620
1430 public void SetTexGen(SceneObjectPart part, int face,int style) 1621 public void SetTexGen(SceneObjectPart part, int face,int style)
1431 { 1622 {
1623 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1624 return;
1625
1432 Primitive.TextureEntry tex = part.Shape.Textures; 1626 Primitive.TextureEntry tex = part.Shape.Textures;
1433 MappingType textype; 1627 MappingType textype;
1434 textype = MappingType.Default; 1628 textype = MappingType.Default;
@@ -1459,6 +1653,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1459 1653
1460 public void SetGlow(SceneObjectPart part, int face, float glow) 1654 public void SetGlow(SceneObjectPart part, int face, float glow)
1461 { 1655 {
1656 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1657 return;
1658
1462 Primitive.TextureEntry tex = part.Shape.Textures; 1659 Primitive.TextureEntry tex = part.Shape.Textures;
1463 if (face >= 0 && face < GetNumberOfSides(part)) 1660 if (face >= 0 && face < GetNumberOfSides(part))
1464 { 1661 {
@@ -1484,6 +1681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1484 1681
1485 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1682 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1486 { 1683 {
1684 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return;
1487 1686
1488 Shininess sval = new Shininess(); 1687 Shininess sval = new Shininess();
1489 1688
@@ -1534,6 +1733,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1534 1733
1535 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1734 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1536 { 1735 {
1736 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1737 return;
1738
1537 Primitive.TextureEntry tex = part.Shape.Textures; 1739 Primitive.TextureEntry tex = part.Shape.Textures;
1538 if (face >= 0 && face < GetNumberOfSides(part)) 1740 if (face >= 0 && face < GetNumberOfSides(part))
1539 { 1741 {
@@ -1594,13 +1796,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1594 m_host.AddScriptLPS(1); 1796 m_host.AddScriptLPS(1);
1595 1797
1596 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1798 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1597 1799 if (parts.Count > 0)
1598 foreach (SceneObjectPart part in parts) 1800 {
1599 SetAlpha(part, alpha, face); 1801 try
1802 {
1803 foreach (SceneObjectPart part in parts)
1804 SetAlpha(part, alpha, face);
1805 }
1806 finally
1807 {
1808 }
1809 }
1600 } 1810 }
1601 1811
1602 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1812 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1603 { 1813 {
1814 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1815 return;
1816
1604 Primitive.TextureEntry tex = part.Shape.Textures; 1817 Primitive.TextureEntry tex = part.Shape.Textures;
1605 Color4 texcolor; 1818 Color4 texcolor;
1606 if (face >= 0 && face < GetNumberOfSides(part)) 1819 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1653,7 +1866,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1653 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1866 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1654 float wind, float tension, LSL_Vector Force) 1867 float wind, float tension, LSL_Vector Force)
1655 { 1868 {
1656 if (part == null) 1869 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1657 return; 1870 return;
1658 1871
1659 if (flexi) 1872 if (flexi)
@@ -1687,7 +1900,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1687 /// <param name="falloff"></param> 1900 /// <param name="falloff"></param>
1688 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1901 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1689 { 1902 {
1690 if (part == null) 1903 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1691 return; 1904 return;
1692 1905
1693 if (light) 1906 if (light)
@@ -1720,11 +1933,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1720 Primitive.TextureEntry tex = part.Shape.Textures; 1933 Primitive.TextureEntry tex = part.Shape.Textures;
1721 Color4 texcolor; 1934 Color4 texcolor;
1722 LSL_Vector rgb = new LSL_Vector(); 1935 LSL_Vector rgb = new LSL_Vector();
1936 int nsides = GetNumberOfSides(part);
1937
1723 if (face == ScriptBaseClass.ALL_SIDES) 1938 if (face == ScriptBaseClass.ALL_SIDES)
1724 { 1939 {
1725 int i; 1940 int i;
1726 1941 for (i = 0; i < nsides; i++)
1727 for (i = 0 ; i < GetNumberOfSides(part); i++)
1728 { 1942 {
1729 texcolor = tex.GetFace((uint)i).RGBA; 1943 texcolor = tex.GetFace((uint)i).RGBA;
1730 rgb.x += texcolor.R; 1944 rgb.x += texcolor.R;
@@ -1732,14 +1946,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1732 rgb.z += texcolor.B; 1946 rgb.z += texcolor.B;
1733 } 1947 }
1734 1948
1735 rgb.x /= (float)GetNumberOfSides(part); 1949 float invnsides = 1.0f / (float)nsides;
1736 rgb.y /= (float)GetNumberOfSides(part); 1950
1737 rgb.z /= (float)GetNumberOfSides(part); 1951 rgb.x *= invnsides;
1952 rgb.y *= invnsides;
1953 rgb.z *= invnsides;
1738 1954
1739 return rgb; 1955 return rgb;
1740 } 1956 }
1741 1957 if (face >= 0 && face < nsides)
1742 if (face >= 0 && face < GetNumberOfSides(part))
1743 { 1958 {
1744 texcolor = tex.GetFace((uint)face).RGBA; 1959 texcolor = tex.GetFace((uint)face).RGBA;
1745 rgb.x = texcolor.R; 1960 rgb.x = texcolor.R;
@@ -1766,15 +1981,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1766 m_host.AddScriptLPS(1); 1981 m_host.AddScriptLPS(1);
1767 1982
1768 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1983 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1769 1984 if (parts.Count > 0)
1770 foreach (SceneObjectPart part in parts) 1985 {
1771 SetTexture(part, texture, face); 1986 try
1772 1987 {
1988 foreach (SceneObjectPart part in parts)
1989 SetTexture(part, texture, face);
1990 }
1991 finally
1992 {
1993 }
1994 }
1773 ScriptSleep(200); 1995 ScriptSleep(200);
1774 } 1996 }
1775 1997
1776 protected void SetTexture(SceneObjectPart part, string texture, int face) 1998 protected void SetTexture(SceneObjectPart part, string texture, int face)
1777 { 1999 {
2000 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2001 return;
2002
1778 UUID textureID = new UUID(); 2003 UUID textureID = new UUID();
1779 2004
1780 textureID = InventoryKey(texture, (int)AssetType.Texture); 2005 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1819,6 +2044,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1819 2044
1820 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2045 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1821 { 2046 {
2047 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2048 return;
2049
1822 Primitive.TextureEntry tex = part.Shape.Textures; 2050 Primitive.TextureEntry tex = part.Shape.Textures;
1823 if (face >= 0 && face < GetNumberOfSides(part)) 2051 if (face >= 0 && face < GetNumberOfSides(part))
1824 { 2052 {
@@ -1855,6 +2083,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1855 2083
1856 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2084 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1857 { 2085 {
2086 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2087 return;
2088
1858 Primitive.TextureEntry tex = part.Shape.Textures; 2089 Primitive.TextureEntry tex = part.Shape.Textures;
1859 if (face >= 0 && face < GetNumberOfSides(part)) 2090 if (face >= 0 && face < GetNumberOfSides(part))
1860 { 2091 {
@@ -1891,6 +2122,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1891 2122
1892 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2123 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1893 { 2124 {
2125 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2126 return;
2127
1894 Primitive.TextureEntry tex = part.Shape.Textures; 2128 Primitive.TextureEntry tex = part.Shape.Textures;
1895 if (face >= 0 && face < GetNumberOfSides(part)) 2129 if (face >= 0 && face < GetNumberOfSides(part))
1896 { 2130 {
@@ -2061,24 +2295,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2061 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2295 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2062 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2296 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2063 { 2297 {
2064 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2298 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2299 return;
2300
2065 LSL_Vector currentPos = GetPartLocalPos(part); 2301 LSL_Vector currentPos = GetPartLocalPos(part);
2302 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2066 2303
2067 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2068 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2069 2304
2070 if (part.ParentGroup.RootPart == part) 2305 if (part.ParentGroup.RootPart == part)
2071 { 2306 {
2072 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2073 targetPos.z = ground;
2074 SceneObjectGroup parent = part.ParentGroup; 2307 SceneObjectGroup parent = part.ParentGroup;
2075 parent.UpdateGroupPosition(!adjust ? targetPos : 2308 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2076 SetPosAdjust(currentPos, targetPos)); 2309 return;
2310 Util.FireAndForget(delegate(object x) {
2311 parent.UpdateGroupPosition((Vector3)toPos);
2312 });
2077 } 2313 }
2078 else 2314 else
2079 { 2315 {
2080 part.OffsetPosition = !adjust ? targetPos : 2316 part.OffsetPosition = (Vector3)toPos;
2081 SetPosAdjust(currentPos, targetPos);
2082 SceneObjectGroup parent = part.ParentGroup; 2317 SceneObjectGroup parent = part.ParentGroup;
2083 parent.HasGroupChanged = true; 2318 parent.HasGroupChanged = true;
2084 parent.ScheduleGroupForTerseUpdate(); 2319 parent.ScheduleGroupForTerseUpdate();
@@ -2110,13 +2345,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2110 else 2345 else
2111 { 2346 {
2112 if (part.ParentGroup.IsAttachment) 2347 if (part.ParentGroup.IsAttachment)
2113 {
2114 pos = part.AttachedPos; 2348 pos = part.AttachedPos;
2115 }
2116 else 2349 else
2117 {
2118 pos = part.AbsolutePosition; 2350 pos = part.AbsolutePosition;
2119 }
2120 } 2351 }
2121 2352
2122// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2353// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2156,25 +2387,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2156 2387
2157 protected void SetRot(SceneObjectPart part, Quaternion rot) 2388 protected void SetRot(SceneObjectPart part, Quaternion rot)
2158 { 2389 {
2159 part.UpdateRotation(rot); 2390 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2160 // Update rotation does not move the object in the physics scene if it's a linkset. 2391 return;
2161 2392
2162//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2393 bool isroot = (part == part.ParentGroup.RootPart);
2163// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2394 bool isphys;
2164 2395
2165 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2166 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2167 // It's perfectly okay when the object is not an active physical body though.
2168 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2169 // but only if the object is not physial and active. This is important for rotating doors.
2170 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2171 // scene
2172 PhysicsActor pa = part.PhysActor; 2396 PhysicsActor pa = part.PhysActor;
2173 2397
2174 if (pa != null && !pa.IsPhysical) 2398 // keep using physactor ideia of isphysical
2399 // it should be SOP ideia of that
2400 // not much of a issue with ubitODE
2401 if (pa != null && pa.IsPhysical)
2402 isphys = true;
2403 else
2404 isphys = false;
2405
2406 // SL doesn't let scripts rotate root of physical linksets
2407 if (isroot && isphys)
2408 return;
2409
2410 part.UpdateRotation(rot);
2411
2412 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2413 // so do a nasty update of parts positions if is a root part rotation
2414 if (isroot && pa != null) // with if above implies non physical root part
2175 { 2415 {
2176 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2416 part.ParentGroup.ResetChildPrimPhysicsPositions();
2177 } 2417 }
2418 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2419 {
2420 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2421 if (sittingavas.Count > 0)
2422 {
2423 foreach (ScenePresence av in sittingavas)
2424 {
2425 if (isroot || part.LocalId == av.ParentID)
2426 av.SendTerseUpdateToAllClients();
2427 }
2428 }
2429 }
2178 } 2430 }
2179 2431
2180 /// <summary> 2432 /// <summary>
@@ -2222,8 +2474,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2222 2474
2223 public LSL_Rotation llGetLocalRot() 2475 public LSL_Rotation llGetLocalRot()
2224 { 2476 {
2477 return GetPartLocalRot(m_host);
2478 }
2479
2480 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2481 {
2225 m_host.AddScriptLPS(1); 2482 m_host.AddScriptLPS(1);
2226 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2483 Quaternion rot = part.RotationOffset;
2484 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2227 } 2485 }
2228 2486
2229 public void llSetForce(LSL_Vector force, int local) 2487 public void llSetForce(LSL_Vector force, int local)
@@ -2303,16 +2561,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2303 m_host.ApplyImpulse(v, local != 0); 2561 m_host.ApplyImpulse(v, local != 0);
2304 } 2562 }
2305 2563
2564
2306 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2565 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2307 { 2566 {
2308 m_host.AddScriptLPS(1); 2567 m_host.AddScriptLPS(1);
2309 m_host.ApplyAngularImpulse(force, local != 0); 2568 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2310 } 2569 }
2311 2570
2312 public void llSetTorque(LSL_Vector torque, int local) 2571 public void llSetTorque(LSL_Vector torque, int local)
2313 { 2572 {
2314 m_host.AddScriptLPS(1); 2573 m_host.AddScriptLPS(1);
2315 m_host.SetAngularImpulse(torque, local != 0); 2574 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2316 } 2575 }
2317 2576
2318 public LSL_Vector llGetTorque() 2577 public LSL_Vector llGetTorque()
@@ -2329,20 +2588,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2329 llSetTorque(torque, local); 2588 llSetTorque(torque, local);
2330 } 2589 }
2331 2590
2591 public void llSetVelocity(LSL_Vector vel, int local)
2592 {
2593 m_host.AddScriptLPS(1);
2594 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2595 }
2596
2332 public LSL_Vector llGetVel() 2597 public LSL_Vector llGetVel()
2333 { 2598 {
2334 m_host.AddScriptLPS(1); 2599 m_host.AddScriptLPS(1);
2335 2600
2336 Vector3 vel; 2601 Vector3 vel = Vector3.Zero;
2337 2602
2338 if (m_host.ParentGroup.IsAttachment) 2603 if (m_host.ParentGroup.IsAttachment)
2339 { 2604 {
2340 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2605 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2341 vel = avatar.Velocity; 2606 if (avatar != null)
2607 vel = avatar.Velocity;
2342 } 2608 }
2343 else 2609 else
2344 { 2610 {
2345 vel = m_host.Velocity; 2611 vel = m_host.ParentGroup.RootPart.Velocity;
2346 } 2612 }
2347 2613
2348 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2614 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2354,10 +2620,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2354 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2620 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2355 } 2621 }
2356 2622
2623 public void llSetAngularVelocity(LSL_Vector avel, int local)
2624 {
2625 m_host.AddScriptLPS(1);
2626 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2627 }
2628
2357 public LSL_Vector llGetOmega() 2629 public LSL_Vector llGetOmega()
2358 { 2630 {
2359 m_host.AddScriptLPS(1); 2631 m_host.AddScriptLPS(1);
2360 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2632 Vector3 avel = m_host.AngularVelocity;
2633 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2361 } 2634 }
2362 2635
2363 public LSL_Float llGetTimeOfDay() 2636 public LSL_Float llGetTimeOfDay()
@@ -2746,7 +3019,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2746 } 3019 }
2747 3020
2748 bool result = money.ObjectGiveMoney( 3021 bool result = money.ObjectGiveMoney(
2749 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount); 3022 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
2750 3023
2751 if (result) 3024 if (result)
2752 return 1; 3025 return 1;
@@ -2830,13 +3103,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2830 new_group.RootPart.UUID.ToString()) }, 3103 new_group.RootPart.UUID.ToString()) },
2831 new DetectParams[0])); 3104 new DetectParams[0]));
2832 3105
2833 float groupmass = new_group.GetMass(); 3106 // do recoil
3107 SceneObjectGroup hostgrp = m_host.ParentGroup;
3108 if (hostgrp == null)
3109 return;
3110
3111 if (hostgrp.IsAttachment) // don't recoil avatars
3112 return;
2834 3113
2835 PhysicsActor pa = new_group.RootPart.PhysActor; 3114 PhysicsActor pa = new_group.RootPart.PhysActor;
2836 3115
2837 //Recoil. 3116 //Recoil.
2838 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3117 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2839 { 3118 {
3119 float groupmass = new_group.GetMass();
2840 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; 3120 Vector3 recoil = -vel * groupmass * m_recoilScaleFactor;
2841 if (recoil != Vector3.Zero) 3121 if (recoil != Vector3.Zero)
2842 { 3122 {
@@ -2844,6 +3124,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2844 } 3124 }
2845 } 3125 }
2846 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3126 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3127 return;
3128
2847 }); 3129 });
2848 3130
2849 //ScriptSleep((int)((groupmass * velmag) / 10)); 3131 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2858,35 +3140,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2858 public void llLookAt(LSL_Vector target, double strength, double damping) 3140 public void llLookAt(LSL_Vector target, double strength, double damping)
2859 { 3141 {
2860 m_host.AddScriptLPS(1); 3142 m_host.AddScriptLPS(1);
2861 // Determine where we are looking from
2862 LSL_Vector from = llGetPos();
2863 3143
2864 // Work out the normalised vector from the source to the target 3144 // Get the normalized vector to the target
2865 LSL_Vector delta = llVecNorm(target - from); 3145 LSL_Vector d1 = llVecNorm(target - llGetPos());
2866 LSL_Vector angle = new LSL_Vector(0,0,0);
2867 3146
2868 // Calculate the yaw 3147 // Get the bearing (yaw)
2869 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3148 LSL_Vector a1 = new LSL_Vector(0,0,0);
2870 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3149 a1.z = llAtan2(d1.y, d1.x);
2871 3150
2872 // Calculate pitch 3151 // Get the elevation (pitch)
2873 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3152 LSL_Vector a2 = new LSL_Vector(0,0,0);
3153 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2874 3154
2875 // we need to convert from a vector describing 3155 LSL_Rotation r1 = llEuler2Rot(a1);
2876 // the angles of rotation in radians into rotation value 3156 LSL_Rotation r2 = llEuler2Rot(a2);
2877 LSL_Rotation rot = llEuler2Rot(angle); 3157 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2878
2879 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2880 // set the rotation of the object, copy that behavior
2881 PhysicsActor pa = m_host.PhysActor;
2882 3158
2883 if (strength == 0 || pa == null || !pa.IsPhysical) 3159 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2884 { 3160 {
2885 llSetRot(rot); 3161 // Do nothing if either value is 0 (this has been checked in SL)
3162 if (strength <= 0.0 || damping <= 0.0)
3163 return;
3164
3165 llSetRot(r3 * r2 * r1);
2886 } 3166 }
2887 else 3167 else
2888 { 3168 {
2889 m_host.StartLookAt(rot, (float)strength, (float)damping); 3169 if (strength == 0)
3170 {
3171 llSetRot(r3 * r2 * r1);
3172 return;
3173 }
3174
3175 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2890 } 3176 }
2891 } 3177 }
2892 3178
@@ -2932,17 +3218,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2932 } 3218 }
2933 else 3219 else
2934 { 3220 {
2935 if (m_host.IsRoot) 3221 // new SL always returns object mass
2936 { 3222// if (m_host.IsRoot)
3223// {
2937 return m_host.ParentGroup.GetMass(); 3224 return m_host.ParentGroup.GetMass();
2938 } 3225// }
2939 else 3226// else
2940 { 3227// {
2941 return m_host.GetMass(); 3228// return m_host.GetMass();
2942 } 3229// }
2943 } 3230 }
2944 } 3231 }
2945 3232
3233
3234 public LSL_Float llGetMassMKS()
3235 {
3236 return 100f * llGetMass();
3237 }
3238
2946 public void llCollisionFilter(string name, string id, int accept) 3239 public void llCollisionFilter(string name, string id, int accept)
2947 { 3240 {
2948 m_host.AddScriptLPS(1); 3241 m_host.AddScriptLPS(1);
@@ -2990,8 +3283,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2990 { 3283 {
2991 // Unregister controls from Presence 3284 // Unregister controls from Presence
2992 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3285 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2993 // Remove Take Control permission.
2994 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2995 } 3286 }
2996 } 3287 }
2997 } 3288 }
@@ -3017,7 +3308,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3017 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3308 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3018 3309
3019 if (attachmentsModule != null) 3310 if (attachmentsModule != null)
3020 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3311 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3021 else 3312 else
3022 return false; 3313 return false;
3023 } 3314 }
@@ -3047,9 +3338,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3047 { 3338 {
3048 m_host.AddScriptLPS(1); 3339 m_host.AddScriptLPS(1);
3049 3340
3050// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3051// return;
3052
3053 if (m_item.PermsGranter != m_host.OwnerID) 3341 if (m_item.PermsGranter != m_host.OwnerID)
3054 return; 3342 return;
3055 3343
@@ -3092,6 +3380,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3092 3380
3093 public void llInstantMessage(string user, string message) 3381 public void llInstantMessage(string user, string message)
3094 { 3382 {
3383 UUID result;
3384 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3385 {
3386 ShoutError("An invalid key was passed to llInstantMessage");
3387 ScriptSleep(2000);
3388 return;
3389 }
3390
3391
3095 m_host.AddScriptLPS(1); 3392 m_host.AddScriptLPS(1);
3096 3393
3097 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3394 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3106,14 +3403,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3106 UUID friendTransactionID = UUID.Random(); 3403 UUID friendTransactionID = UUID.Random();
3107 3404
3108 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3405 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3109 3406
3110 GridInstantMessage msg = new GridInstantMessage(); 3407 GridInstantMessage msg = new GridInstantMessage();
3111 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3408 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3112 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3409 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3113 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3410 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3114// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3411// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3115// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3412// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3116 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3413// DateTime dt = DateTime.UtcNow;
3414//
3415// // Ticks from UtcNow, but make it look like local. Evil, huh?
3416// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3417//
3418// try
3419// {
3420// // Convert that to the PST timezone
3421// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3422// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3423// }
3424// catch
3425// {
3426// // No logging here, as it could be VERY spammy
3427// }
3428//
3429// // And make it look local again to fool the unix time util
3430// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3431
3432 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3433
3117 //if (client != null) 3434 //if (client != null)
3118 //{ 3435 //{
3119 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3436 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3127,12 +3444,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3127 msg.message = message.Substring(0, 1024); 3444 msg.message = message.Substring(0, 1024);
3128 else 3445 else
3129 msg.message = message; 3446 msg.message = message;
3130 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3447 msg.dialog = (byte)19; // MessageFromObject
3131 msg.fromGroup = false;// fromGroup; 3448 msg.fromGroup = false;// fromGroup;
3132 msg.offline = (byte)0; //offline; 3449 msg.offline = (byte)0; //offline;
3133 msg.ParentEstateID = 0; //ParentEstateID; 3450 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3134 msg.Position = new Vector3(m_host.AbsolutePosition); 3451 msg.Position = new Vector3(m_host.AbsolutePosition);
3135 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3452 msg.RegionID = World.RegionInfo.RegionID.Guid;
3136 msg.binaryBucket 3453 msg.binaryBucket
3137 = Util.StringToBytes256( 3454 = Util.StringToBytes256(
3138 "{0}/{1}/{2}/{3}", 3455 "{0}/{1}/{2}/{3}",
@@ -3160,7 +3477,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3160 } 3477 }
3161 3478
3162 emailModule.SendEmail(m_host.UUID, address, subject, message); 3479 emailModule.SendEmail(m_host.UUID, address, subject, message);
3163 llSleep(EMAIL_PAUSE_TIME); 3480 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3164 } 3481 }
3165 3482
3166 public void llGetNextEmail(string address, string subject) 3483 public void llGetNextEmail(string address, string subject)
@@ -3406,7 +3723,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3406 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3723 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3407 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3724 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3408 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3725 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3726 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3409 ScriptBaseClass.PERMISSION_ATTACH; 3727 ScriptBaseClass.PERMISSION_ATTACH;
3728
3410 } 3729 }
3411 else 3730 else
3412 { 3731 {
@@ -3437,15 +3756,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3437 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3756 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3438 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3757 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3439 } 3758 }
3759 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3760 {
3761 implicitPerms = perm;
3762 }
3440 } 3763 }
3441 3764
3442 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3765 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3443 { 3766 {
3444 lock (m_host.TaskInventory) 3767 m_host.TaskInventory.LockItemsForWrite(true);
3445 { 3768 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3446 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3769 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3447 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3770 m_host.TaskInventory.LockItemsForWrite(false);
3448 }
3449 3771
3450 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3772 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3451 "run_time_permissions", new Object[] { 3773 "run_time_permissions", new Object[] {
@@ -3488,11 +3810,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3488 3810
3489 if (!m_waitingForScriptAnswer) 3811 if (!m_waitingForScriptAnswer)
3490 { 3812 {
3491 lock (m_host.TaskInventory) 3813 m_host.TaskInventory.LockItemsForWrite(true);
3492 { 3814 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3493 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3815 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3494 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3816 m_host.TaskInventory.LockItemsForWrite(false);
3495 }
3496 3817
3497 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3818 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3498 m_waitingForScriptAnswer=true; 3819 m_waitingForScriptAnswer=true;
@@ -3521,14 +3842,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3521 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3842 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3522 llReleaseControls(); 3843 llReleaseControls();
3523 3844
3524 lock (m_host.TaskInventory) 3845 m_host.TaskInventory.LockItemsForWrite(true);
3525 { 3846 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3526 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3847 m_host.TaskInventory.LockItemsForWrite(false);
3527 } 3848
3528 3849 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3529 m_ScriptEngine.PostScriptEvent( 3850 "run_time_permissions", new Object[] {
3530 m_item.ItemID, 3851 new LSL_Integer(answer) },
3531 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3852 new DetectParams[0]));
3532 } 3853 }
3533 3854
3534 public LSL_String llGetPermissionsKey() 3855 public LSL_String llGetPermissionsKey()
@@ -3567,14 +3888,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3567 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3888 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3568 { 3889 {
3569 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3890 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3570 3891 if (parts.Count > 0)
3571 foreach (SceneObjectPart part in parts) 3892 {
3572 part.SetFaceColorAlpha(face, color, null); 3893 try
3894 {
3895 foreach (SceneObjectPart part in parts)
3896 part.SetFaceColorAlpha(face, color, null);
3897 }
3898 finally
3899 {
3900 }
3901 }
3573 } 3902 }
3574 3903
3575 public void llCreateLink(string target, int parent) 3904 public void llCreateLink(string target, int parent)
3576 { 3905 {
3577 m_host.AddScriptLPS(1); 3906 m_host.AddScriptLPS(1);
3907
3578 UUID targetID; 3908 UUID targetID;
3579 3909
3580 if (!UUID.TryParse(target, out targetID)) 3910 if (!UUID.TryParse(target, out targetID))
@@ -3680,10 +4010,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3680 // Restructuring Multiple Prims. 4010 // Restructuring Multiple Prims.
3681 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4011 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3682 parts.Remove(parentPrim.RootPart); 4012 parts.Remove(parentPrim.RootPart);
3683 foreach (SceneObjectPart part in parts) 4013 if (parts.Count > 0)
3684 { 4014 {
3685 parentPrim.DelinkFromGroup(part.LocalId, true); 4015 try
4016 {
4017 foreach (SceneObjectPart part in parts)
4018 {
4019 parentPrim.DelinkFromGroup(part.LocalId, true);
4020 }
4021 }
4022 finally
4023 {
4024 }
3686 } 4025 }
4026
3687 parentPrim.HasGroupChanged = true; 4027 parentPrim.HasGroupChanged = true;
3688 parentPrim.ScheduleGroupForFullUpdate(); 4028 parentPrim.ScheduleGroupForFullUpdate();
3689 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4029 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3692,12 +4032,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3692 { 4032 {
3693 SceneObjectPart newRoot = parts[0]; 4033 SceneObjectPart newRoot = parts[0];
3694 parts.Remove(newRoot); 4034 parts.Remove(newRoot);
3695 foreach (SceneObjectPart part in parts) 4035
4036 try
3696 { 4037 {
3697 // Required for linking 4038 foreach (SceneObjectPart part in parts)
3698 part.ClearUpdateSchedule(); 4039 {
3699 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4040 part.ClearUpdateSchedule();
4041 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4042 }
3700 } 4043 }
4044 finally
4045 {
4046 }
4047
4048
3701 newRoot.ParentGroup.HasGroupChanged = true; 4049 newRoot.ParentGroup.HasGroupChanged = true;
3702 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4050 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3703 } 4051 }
@@ -3717,6 +4065,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3717 public void llBreakAllLinks() 4065 public void llBreakAllLinks()
3718 { 4066 {
3719 m_host.AddScriptLPS(1); 4067 m_host.AddScriptLPS(1);
4068
4069 TaskInventoryItem item = m_item;
4070
4071 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4072 && !m_automaticLinkPermission)
4073 {
4074 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4075 return;
4076 }
4077
3720 SceneObjectGroup parentPrim = m_host.ParentGroup; 4078 SceneObjectGroup parentPrim = m_host.ParentGroup;
3721 if (parentPrim.AttachmentPoint != 0) 4079 if (parentPrim.AttachmentPoint != 0)
3722 return; // Fail silently if attached 4080 return; // Fail silently if attached
@@ -3736,25 +4094,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3736 public LSL_String llGetLinkKey(int linknum) 4094 public LSL_String llGetLinkKey(int linknum)
3737 { 4095 {
3738 m_host.AddScriptLPS(1); 4096 m_host.AddScriptLPS(1);
3739 List<UUID> keytable = new List<UUID>();
3740 // parse for sitting avatare-uuids
3741 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3742 {
3743 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3744 keytable.Add(presence.UUID);
3745 });
3746
3747 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3748 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3749 {
3750 return keytable[totalprims - linknum].ToString();
3751 }
3752
3753 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3754 {
3755 return m_host.UUID.ToString();
3756 }
3757
3758 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4097 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3759 if (part != null) 4098 if (part != null)
3760 { 4099 {
@@ -3762,6 +4101,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3762 } 4101 }
3763 else 4102 else
3764 { 4103 {
4104 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4105 {
4106 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4107
4108 if (linknum < 0)
4109 return UUID.Zero.ToString();
4110
4111 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4112 if (avatars.Count > linknum)
4113 {
4114 return avatars[linknum].UUID.ToString();
4115 }
4116 }
3765 return UUID.Zero.ToString(); 4117 return UUID.Zero.ToString();
3766 } 4118 }
3767 } 4119 }
@@ -3871,17 +4223,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3871 m_host.AddScriptLPS(1); 4223 m_host.AddScriptLPS(1);
3872 int count = 0; 4224 int count = 0;
3873 4225
3874 lock (m_host.TaskInventory) 4226 m_host.TaskInventory.LockItemsForRead(true);
4227 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3875 { 4228 {
3876 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4229 if (inv.Value.Type == type || type == -1)
3877 { 4230 {
3878 if (inv.Value.Type == type || type == -1) 4231 count = count + 1;
3879 {
3880 count = count + 1;
3881 }
3882 } 4232 }
3883 } 4233 }
3884 4234
4235 m_host.TaskInventory.LockItemsForRead(false);
3885 return count; 4236 return count;
3886 } 4237 }
3887 4238
@@ -3890,16 +4241,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3890 m_host.AddScriptLPS(1); 4241 m_host.AddScriptLPS(1);
3891 ArrayList keys = new ArrayList(); 4242 ArrayList keys = new ArrayList();
3892 4243
3893 lock (m_host.TaskInventory) 4244 m_host.TaskInventory.LockItemsForRead(true);
4245 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3894 { 4246 {
3895 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4247 if (inv.Value.Type == type || type == -1)
3896 { 4248 {
3897 if (inv.Value.Type == type || type == -1) 4249 keys.Add(inv.Value.Name);
3898 {
3899 keys.Add(inv.Value.Name);
3900 }
3901 } 4250 }
3902 } 4251 }
4252 m_host.TaskInventory.LockItemsForRead(false);
3903 4253
3904 if (keys.Count == 0) 4254 if (keys.Count == 0)
3905 { 4255 {
@@ -3937,7 +4287,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3937 if (item == null) 4287 if (item == null)
3938 { 4288 {
3939 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4289 llSay(0, String.Format("Could not find object '{0}'", inventory));
3940 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4290 return;
4291// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3941 } 4292 }
3942 4293
3943 UUID objId = item.ItemID; 4294 UUID objId = item.ItemID;
@@ -3965,33 +4316,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3965 return; 4316 return;
3966 } 4317 }
3967 } 4318 }
4319
3968 // destination is an avatar 4320 // destination is an avatar
3969 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4321 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3970 4322
3971 if (agentItem == null) 4323 if (agentItem == null)
3972 return; 4324 return;
3973 4325
3974 if (m_TransferModule != null) 4326 byte[] bucket = new byte[1];
3975 { 4327 bucket[0] = (byte)item.Type;
3976 byte[] bucket = new byte[1]; 4328 //byte[] objBytes = agentItem.ID.GetBytes();
3977 bucket[0] = (byte)item.Type; 4329 //Array.Copy(objBytes, 0, bucket, 1, 16);
3978 4330
3979 GridInstantMessage msg = new GridInstantMessage(World, 4331 GridInstantMessage msg = new GridInstantMessage(World,
3980 m_host.OwnerID, m_host.Name, destId, 4332 m_host.OwnerID, m_host.Name, destId,
3981 (byte)InstantMessageDialog.TaskInventoryOffered, 4333 (byte)InstantMessageDialog.TaskInventoryOffered,
3982 false, item.Name+". "+m_host.Name+" is located at "+ 4334 false, item.Name+". "+m_host.Name+" is located at "+
3983 World.RegionInfo.RegionName+" "+ 4335 World.RegionInfo.RegionName+" "+
3984 m_host.AbsolutePosition.ToString(), 4336 m_host.AbsolutePosition.ToString(),
3985 agentItem.ID, true, m_host.AbsolutePosition, 4337 agentItem.ID, true, m_host.AbsolutePosition,
3986 bucket, true); 4338 bucket, true);
3987 4339
3988 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4340 ScenePresence sp;
3989 }
3990 4341
4342 if (World.TryGetScenePresence(destId, out sp))
4343 {
4344 sp.ControllingClient.SendInstantMessage(msg);
4345 }
4346 else
4347 {
4348 if (m_TransferModule != null)
4349 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4350 }
4351
4352 //This delay should only occur when giving inventory to avatars.
3991 ScriptSleep(3000); 4353 ScriptSleep(3000);
3992 } 4354 }
3993 } 4355 }
3994 4356
4357 [DebuggerNonUserCode]
3995 public void llRemoveInventory(string name) 4358 public void llRemoveInventory(string name)
3996 { 4359 {
3997 m_host.AddScriptLPS(1); 4360 m_host.AddScriptLPS(1);
@@ -4046,109 +4409,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4046 { 4409 {
4047 m_host.AddScriptLPS(1); 4410 m_host.AddScriptLPS(1);
4048 4411
4049 UUID uuid = (UUID)id; 4412 UUID uuid;
4050 PresenceInfo pinfo = null; 4413 if (UUID.TryParse(id, out uuid))
4051 UserAccount account;
4052
4053 UserInfoCacheEntry ce;
4054 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4055 { 4414 {
4056 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4415 PresenceInfo pinfo = null;
4057 if (account == null) 4416 UserAccount account;
4417
4418 UserInfoCacheEntry ce;
4419 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4058 { 4420 {
4059 m_userInfoCache[uuid] = null; // Cache negative 4421 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4060 return UUID.Zero.ToString(); 4422 if (account == null)
4061 } 4423 {
4424 m_userInfoCache[uuid] = null; // Cache negative
4425 return UUID.Zero.ToString();
4426 }
4062 4427
4063 4428
4064 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4429 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4065 if (pinfos != null && pinfos.Length > 0) 4430 if (pinfos != null && pinfos.Length > 0)
4066 {
4067 foreach (PresenceInfo p in pinfos)
4068 { 4431 {
4069 if (p.RegionID != UUID.Zero) 4432 foreach (PresenceInfo p in pinfos)
4070 { 4433 {
4071 pinfo = p; 4434 if (p.RegionID != UUID.Zero)
4435 {
4436 pinfo = p;
4437 }
4072 } 4438 }
4073 } 4439 }
4074 }
4075 4440
4076 ce = new UserInfoCacheEntry(); 4441 ce = new UserInfoCacheEntry();
4077 ce.time = Util.EnvironmentTickCount(); 4442 ce.time = Util.EnvironmentTickCount();
4078 ce.account = account; 4443 ce.account = account;
4079 ce.pinfo = pinfo; 4444 ce.pinfo = pinfo;
4080 } 4445 m_userInfoCache[uuid] = ce;
4081 else 4446 }
4082 { 4447 else
4083 if (ce == null) 4448 {
4084 return UUID.Zero.ToString(); 4449 if (ce == null)
4450 return UUID.Zero.ToString();
4085 4451
4086 account = ce.account; 4452 account = ce.account;
4087 pinfo = ce.pinfo; 4453 pinfo = ce.pinfo;
4088 } 4454 }
4089 4455
4090 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4456 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4091 {
4092 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4093 if (pinfos != null && pinfos.Length > 0)
4094 { 4457 {
4095 foreach (PresenceInfo p in pinfos) 4458 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4459 if (pinfos != null && pinfos.Length > 0)
4096 { 4460 {
4097 if (p.RegionID != UUID.Zero) 4461 foreach (PresenceInfo p in pinfos)
4098 { 4462 {
4099 pinfo = p; 4463 if (p.RegionID != UUID.Zero)
4464 {
4465 pinfo = p;
4466 }
4100 } 4467 }
4101 } 4468 }
4102 } 4469 else
4103 else 4470 pinfo = null;
4104 pinfo = null;
4105 4471
4106 ce.time = Util.EnvironmentTickCount(); 4472 ce.time = Util.EnvironmentTickCount();
4107 ce.pinfo = pinfo; 4473 ce.pinfo = pinfo;
4108 } 4474 }
4109 4475
4110 string reply = String.Empty; 4476 string reply = String.Empty;
4111 4477
4112 switch (data) 4478 switch (data)
4113 { 4479 {
4114 case 1: // DATA_ONLINE (0|1) 4480 case 1: // DATA_ONLINE (0|1)
4115 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4481 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4116 reply = "1"; 4482 reply = "1";
4117 else 4483 else
4118 reply = "0"; 4484 reply = "0";
4119 break; 4485 break;
4120 case 2: // DATA_NAME (First Last) 4486 case 2: // DATA_NAME (First Last)
4121 reply = account.FirstName + " " + account.LastName; 4487 reply = account.FirstName + " " + account.LastName;
4122 break; 4488 break;
4123 case 3: // DATA_BORN (YYYY-MM-DD) 4489 case 3: // DATA_BORN (YYYY-MM-DD)
4124 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4490 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4125 born = born.AddSeconds(account.Created); 4491 born = born.AddSeconds(account.Created);
4126 reply = born.ToString("yyyy-MM-dd"); 4492 reply = born.ToString("yyyy-MM-dd");
4127 break; 4493 break;
4128 case 4: // DATA_RATING (0,0,0,0,0,0) 4494 case 4: // DATA_RATING (0,0,0,0,0,0)
4129 reply = "0,0,0,0,0,0"; 4495 reply = "0,0,0,0,0,0";
4130 break; 4496 break;
4131 case 7: // DATA_USERLEVEL (integer) 4497 case 8: // DATA_PAYINFO (0|1|2|3)
4132 reply = account.UserLevel.ToString(); 4498 reply = "0";
4133 break; 4499 break;
4134 case 8: // DATA_PAYINFO (0|1|2|3) 4500 default:
4135 reply = "0"; 4501 return UUID.Zero.ToString(); // Raise no event
4136 break; 4502 }
4137 default:
4138 return UUID.Zero.ToString(); // Raise no event
4139 }
4140 4503
4141 UUID rq = UUID.Random(); 4504 UUID rq = UUID.Random();
4142 4505
4143 UUID tid = AsyncCommands. 4506 UUID tid = AsyncCommands.
4144 DataserverPlugin.RegisterRequest(m_host.LocalId, 4507 DataserverPlugin.RegisterRequest(m_host.LocalId,
4145 m_item.ItemID, rq.ToString()); 4508 m_item.ItemID, rq.ToString());
4146 4509
4147 AsyncCommands. 4510 AsyncCommands.
4148 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4511 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4149 4512
4150 ScriptSleep(100); 4513 ScriptSleep(100);
4151 return tid.ToString(); 4514 return tid.ToString();
4515 }
4516 else
4517 {
4518 ShoutError("Invalid UUID passed to llRequestAgentData.");
4519 }
4520 return "";
4152 } 4521 }
4153 4522
4154 public LSL_String llRequestInventoryData(string name) 4523 public LSL_String llRequestInventoryData(string name)
@@ -4205,13 +4574,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4205 if (UUID.TryParse(agent, out agentId)) 4574 if (UUID.TryParse(agent, out agentId))
4206 { 4575 {
4207 ScenePresence presence = World.GetScenePresence(agentId); 4576 ScenePresence presence = World.GetScenePresence(agentId);
4208 if (presence != null) 4577 if (presence != null && presence.PresenceType != PresenceType.Npc)
4209 { 4578 {
4579 // agent must not be a god
4580 if (presence.UserLevel >= 200) return;
4581
4210 // agent must be over the owners land 4582 // agent must be over the owners land
4211 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4583 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4212 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4584 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4213 { 4585 {
4214 World.TeleportClientHome(agentId, presence.ControllingClient); 4586 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4587 {
4588 // They can't be teleported home for some reason
4589 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4590 if (regionInfo != null)
4591 {
4592 World.RequestTeleportLocation(
4593 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4594 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4595 }
4596 }
4215 } 4597 }
4216 } 4598 }
4217 } 4599 }
@@ -4318,7 +4700,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4318 UUID av = new UUID(); 4700 UUID av = new UUID();
4319 if (!UUID.TryParse(agent,out av)) 4701 if (!UUID.TryParse(agent,out av))
4320 { 4702 {
4321 LSLError("First parameter to llDialog needs to be a key"); 4703 //LSLError("First parameter to llDialog needs to be a key");
4322 return; 4704 return;
4323 } 4705 }
4324 4706
@@ -4350,10 +4732,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4350 public void llCollisionSound(string impact_sound, double impact_volume) 4732 public void llCollisionSound(string impact_sound, double impact_volume)
4351 { 4733 {
4352 m_host.AddScriptLPS(1); 4734 m_host.AddScriptLPS(1);
4353 4735
4736 if(impact_sound == "")
4737 {
4738 m_host.CollisionSoundVolume = (float)impact_volume;
4739 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4740 m_host.CollisionSoundType = 0;
4741 return;
4742 }
4354 // TODO: Parameter check logic required. 4743 // TODO: Parameter check logic required.
4355 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4744 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4356 m_host.CollisionSoundVolume = (float)impact_volume; 4745 m_host.CollisionSoundVolume = (float)impact_volume;
4746 m_host.CollisionSoundType = 1;
4357 } 4747 }
4358 4748
4359 public LSL_String llGetAnimation(string id) 4749 public LSL_String llGetAnimation(string id)
@@ -4367,14 +4757,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4367 4757
4368 if (m_host.RegionHandle == presence.RegionHandle) 4758 if (m_host.RegionHandle == presence.RegionHandle)
4369 { 4759 {
4370 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4371
4372 if (presence != null) 4760 if (presence != null)
4373 { 4761 {
4374 AnimationSet currentAnims = presence.Animator.Animations; 4762 if (presence.SitGround)
4375 string currentAnimationState = String.Empty; 4763 return "Sitting on Ground";
4376 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4764 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4377 return currentAnimationState; 4765 return "Sitting";
4766
4767 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4768 string lslMovementAnimation;
4769
4770 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4771 return lslMovementAnimation;
4378 } 4772 }
4379 } 4773 }
4380 4774
@@ -4521,7 +4915,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4521 { 4915 {
4522 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4916 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4523 float distance_term = distance * distance * distance; // Script Energy 4917 float distance_term = distance * distance * distance; // Script Energy
4524 float pusher_mass = m_host.GetMass(); 4918 // use total object mass and not part
4919 float pusher_mass = m_host.ParentGroup.GetMass();
4525 4920
4526 float PUSH_ATTENUATION_DISTANCE = 17f; 4921 float PUSH_ATTENUATION_DISTANCE = 17f;
4527 float PUSH_ATTENUATION_SCALE = 5f; 4922 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4771,6 +5166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4771 { 5166 {
4772 return item.AssetID.ToString(); 5167 return item.AssetID.ToString();
4773 } 5168 }
5169 m_host.TaskInventory.LockItemsForRead(false);
4774 5170
4775 return UUID.Zero.ToString(); 5171 return UUID.Zero.ToString();
4776 } 5172 }
@@ -4904,7 +5300,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4904 public LSL_Vector llGetCenterOfMass() 5300 public LSL_Vector llGetCenterOfMass()
4905 { 5301 {
4906 m_host.AddScriptLPS(1); 5302 m_host.AddScriptLPS(1);
4907 Vector3 center = m_host.GetGeometricCenter(); 5303 Vector3 center = m_host.GetCenterOfMass();
4908 return new LSL_Vector(center.X,center.Y,center.Z); 5304 return new LSL_Vector(center.X,center.Y,center.Z);
4909 } 5305 }
4910 5306
@@ -4923,14 +5319,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4923 { 5319 {
4924 m_host.AddScriptLPS(1); 5320 m_host.AddScriptLPS(1);
4925 5321
4926 if (src == null) 5322 return src.Length;
4927 {
4928 return 0;
4929 }
4930 else
4931 {
4932 return src.Length;
4933 }
4934 } 5323 }
4935 5324
4936 public LSL_Integer llList2Integer(LSL_List src, int index) 5325 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -5001,7 +5390,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5001 else if (src.Data[index] is LSL_Float) 5390 else if (src.Data[index] is LSL_Float)
5002 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5391 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
5003 else if (src.Data[index] is LSL_String) 5392 else if (src.Data[index] is LSL_String)
5004 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5393 {
5394 string str = ((LSL_String) src.Data[index]).m_string;
5395 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5396 if (m != Match.Empty)
5397 {
5398 str = m.Value;
5399 double d = 0.0;
5400 if (!Double.TryParse(str, out d))
5401 return 0.0;
5402
5403 return d;
5404 }
5405 return 0.0;
5406 }
5005 return Convert.ToDouble(src.Data[index]); 5407 return Convert.ToDouble(src.Data[index]);
5006 } 5408 }
5007 catch (FormatException) 5409 catch (FormatException)
@@ -5043,7 +5445,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5043 // for completion and should LSL_Key ever be implemented 5445 // for completion and should LSL_Key ever be implemented
5044 // as it's own struct 5446 // as it's own struct
5045 else if (!(src.Data[index] is LSL_String || 5447 else if (!(src.Data[index] is LSL_String ||
5046 src.Data[index] is LSL_Key)) 5448 src.Data[index] is LSL_Key ||
5449 src.Data[index] is String))
5047 { 5450 {
5048 return ""; 5451 return "";
5049 } 5452 }
@@ -5301,7 +5704,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5301 } 5704 }
5302 } 5705 }
5303 } 5706 }
5304 else { 5707 else
5708 {
5305 object[] array = new object[src.Length]; 5709 object[] array = new object[src.Length];
5306 Array.Copy(src.Data, 0, array, 0, src.Length); 5710 Array.Copy(src.Data, 0, array, 0, src.Length);
5307 result = new LSL_List(array); 5711 result = new LSL_List(array);
@@ -5408,7 +5812,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5408 public LSL_Integer llGetRegionAgentCount() 5812 public LSL_Integer llGetRegionAgentCount()
5409 { 5813 {
5410 m_host.AddScriptLPS(1); 5814 m_host.AddScriptLPS(1);
5411 return new LSL_Integer(World.GetRootAgentCount()); 5815
5816 int count = 0;
5817 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5818 count++;
5819 });
5820
5821 return new LSL_Integer(count);
5412 } 5822 }
5413 5823
5414 public LSL_Vector llGetRegionCorner() 5824 public LSL_Vector llGetRegionCorner()
@@ -5649,6 +6059,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5649 flags |= ScriptBaseClass.AGENT_AWAY; 6059 flags |= ScriptBaseClass.AGENT_AWAY;
5650 } 6060 }
5651 6061
6062 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6063 UUID[] anims = agent.Animator.GetAnimationArray();
6064 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6065 {
6066 flags |= ScriptBaseClass.AGENT_BUSY;
6067 }
6068
5652 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6069 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5653 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6070 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5654 { 6071 {
@@ -5696,6 +6113,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5696 flags |= ScriptBaseClass.AGENT_SITTING; 6113 flags |= ScriptBaseClass.AGENT_SITTING;
5697 } 6114 }
5698 6115
6116 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6117 {
6118 flags |= ScriptBaseClass.AGENT_MALE;
6119 }
6120
5699 return flags; 6121 return flags;
5700 } 6122 }
5701 6123
@@ -5843,9 +6265,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5843 6265
5844 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6266 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5845 6267
5846 foreach (SceneObjectPart part in parts) 6268 try
6269 {
6270 foreach (SceneObjectPart part in parts)
6271 {
6272 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6273 }
6274 }
6275 finally
5847 { 6276 {
5848 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5849 } 6277 }
5850 } 6278 }
5851 6279
@@ -5899,13 +6327,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5899 6327
5900 if (m_host.OwnerID == land.LandData.OwnerID) 6328 if (m_host.OwnerID == land.LandData.OwnerID)
5901 { 6329 {
5902 World.TeleportClientHome(agentID, presence.ControllingClient); 6330 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6331 presence.TeleportWithMomentum(pos, null);
6332 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5903 } 6333 }
5904 } 6334 }
5905 } 6335 }
5906 ScriptSleep(5000); 6336 ScriptSleep(5000);
5907 } 6337 }
5908 6338
6339 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6340 {
6341 return ParseString2List(str, separators, in_spacers, false);
6342 }
6343
5909 public LSL_Integer llOverMyLand(string id) 6344 public LSL_Integer llOverMyLand(string id)
5910 { 6345 {
5911 m_host.AddScriptLPS(1); 6346 m_host.AddScriptLPS(1);
@@ -5959,25 +6394,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5959 } 6394 }
5960 else 6395 else
5961 { 6396 {
5962 agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); 6397// agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
6398 Vector3 s = avatar.Appearance.AvatarSize;
6399 agentSize = new LSL_Vector(s.X, s.Y, s.Z);
5963 } 6400 }
5964 return agentSize; 6401 return agentSize;
5965 } 6402 }
5966 6403
5967 public LSL_Integer llSameGroup(string agent) 6404 public LSL_Integer llSameGroup(string id)
5968 { 6405 {
5969 m_host.AddScriptLPS(1); 6406 m_host.AddScriptLPS(1);
5970 UUID agentId = new UUID(); 6407 UUID uuid = new UUID();
5971 if (!UUID.TryParse(agent, out agentId)) 6408 if (!UUID.TryParse(id, out uuid))
5972 return new LSL_Integer(0);
5973 ScenePresence presence = World.GetScenePresence(agentId);
5974 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5975 return new LSL_Integer(0); 6409 return new LSL_Integer(0);
5976 IClientAPI client = presence.ControllingClient; 6410
5977 if (m_host.GroupID == client.ActiveGroupId) 6411 // Check if it's a group key
6412 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5978 return new LSL_Integer(1); 6413 return new LSL_Integer(1);
5979 else 6414
6415 // We got passed a UUID.Zero
6416 if (uuid == UUID.Zero)
5980 return new LSL_Integer(0); 6417 return new LSL_Integer(0);
6418
6419 // Handle the case where id names an avatar
6420 ScenePresence presence = World.GetScenePresence(uuid);
6421 if (presence != null)
6422 {
6423 if (presence.IsChildAgent)
6424 return new LSL_Integer(0);
6425
6426 IClientAPI client = presence.ControllingClient;
6427 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6428 return new LSL_Integer(1);
6429
6430 return new LSL_Integer(0);
6431 }
6432
6433 // Handle object case
6434 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6435 if (part != null)
6436 {
6437 // This will handle both deed and non-deed and also the no
6438 // group case
6439 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6440 return new LSL_Integer(1);
6441
6442 return new LSL_Integer(0);
6443 }
6444
6445 return new LSL_Integer(0);
5981 } 6446 }
5982 6447
5983 public void llUnSit(string id) 6448 public void llUnSit(string id)
@@ -6102,7 +6567,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6102 return m_host.ParentGroup.AttachmentPoint; 6567 return m_host.ParentGroup.AttachmentPoint;
6103 } 6568 }
6104 6569
6105 public LSL_Integer llGetFreeMemory() 6570 public virtual LSL_Integer llGetFreeMemory()
6106 { 6571 {
6107 m_host.AddScriptLPS(1); 6572 m_host.AddScriptLPS(1);
6108 // Make scripts designed for LSO happy 6573 // Make scripts designed for LSO happy
@@ -6219,7 +6684,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6219 SetParticleSystem(m_host, rules); 6684 SetParticleSystem(m_host, rules);
6220 } 6685 }
6221 6686
6222 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6687 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6688 {
6223 6689
6224 6690
6225 if (rules.Length == 0) 6691 if (rules.Length == 0)
@@ -6534,6 +7000,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6534 7000
6535 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 7001 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6536 { 7002 {
7003 // LSL quaternions can normalize to 0, normal Quaternions can't.
7004 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
7005 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
7006
6537 part.SitTargetPosition = offset; 7007 part.SitTargetPosition = offset;
6538 part.SitTargetOrientation = rot; 7008 part.SitTargetOrientation = rot;
6539 part.ParentGroup.HasGroupChanged = true; 7009 part.ParentGroup.HasGroupChanged = true;
@@ -6719,13 +7189,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6719 UUID av = new UUID(); 7189 UUID av = new UUID();
6720 if (!UUID.TryParse(avatar,out av)) 7190 if (!UUID.TryParse(avatar,out av))
6721 { 7191 {
6722 LSLError("First parameter to llDialog needs to be a key"); 7192 //LSLError("First parameter to llDialog needs to be a key");
6723 return; 7193 return;
6724 } 7194 }
6725 if (buttons.Length < 1) 7195 if (buttons.Length < 1)
6726 { 7196 {
6727 LSLError("No less than 1 button can be shown"); 7197 buttons.Add("OK");
6728 return;
6729 } 7198 }
6730 if (buttons.Length > 12) 7199 if (buttons.Length > 12)
6731 { 7200 {
@@ -6742,7 +7211,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6742 } 7211 }
6743 if (buttons.Data[i].ToString().Length > 24) 7212 if (buttons.Data[i].ToString().Length > 24)
6744 { 7213 {
6745 LSLError("button label cannot be longer than 24 characters"); 7214 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6746 return; 7215 return;
6747 } 7216 }
6748 buts[i] = buttons.Data[i].ToString(); 7217 buts[i] = buttons.Data[i].ToString();
@@ -6809,9 +7278,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6809 return; 7278 return;
6810 } 7279 }
6811 7280
6812 // the rest of the permission checks are done in RezScript, so check the pin there as well 7281 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6813 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7282 if (dest != null)
7283 {
7284 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7285 {
7286 // the rest of the permission checks are done in RezScript, so check the pin there as well
7287 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6814 7288
7289 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7290 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7291 }
7292 }
6815 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7293 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6816 ScriptSleep(3000); 7294 ScriptSleep(3000);
6817 } 7295 }
@@ -6881,19 +7359,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6881 public LSL_String llMD5String(string src, int nonce) 7359 public LSL_String llMD5String(string src, int nonce)
6882 { 7360 {
6883 m_host.AddScriptLPS(1); 7361 m_host.AddScriptLPS(1);
6884 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7362 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6885 } 7363 }
6886 7364
6887 public LSL_String llSHA1String(string src) 7365 public LSL_String llSHA1String(string src)
6888 { 7366 {
6889 m_host.AddScriptLPS(1); 7367 m_host.AddScriptLPS(1);
6890 return Util.SHA1Hash(src).ToLower(); 7368 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6891 } 7369 }
6892 7370
6893 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7371 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6894 { 7372 {
6895 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7373 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6896 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7374 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7375 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7376 return shapeBlock;
6897 7377
6898 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7378 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6899 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7379 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6998,6 +7478,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6998 // Prim type box, cylinder and prism. 7478 // Prim type box, cylinder and prism.
6999 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) 7479 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)
7000 { 7480 {
7481 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7482 return;
7483
7001 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7484 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7002 ObjectShapePacket.ObjectDataBlock shapeBlock; 7485 ObjectShapePacket.ObjectDataBlock shapeBlock;
7003 7486
@@ -7051,6 +7534,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7051 // Prim type sphere. 7534 // Prim type sphere.
7052 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7535 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7053 { 7536 {
7537 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7538 return;
7539
7054 ObjectShapePacket.ObjectDataBlock shapeBlock; 7540 ObjectShapePacket.ObjectDataBlock shapeBlock;
7055 7541
7056 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7542 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7092,6 +7578,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7092 // Prim type torus, tube and ring. 7578 // Prim type torus, tube and ring.
7093 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) 7579 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)
7094 { 7580 {
7581 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7582 return;
7583
7095 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7584 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7096 ObjectShapePacket.ObjectDataBlock shapeBlock; 7585 ObjectShapePacket.ObjectDataBlock shapeBlock;
7097 7586
@@ -7227,6 +7716,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7227 // Prim type sculpt. 7716 // Prim type sculpt.
7228 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7717 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7229 { 7718 {
7719 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7720 return;
7721
7230 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7722 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7231 UUID sculptId; 7723 UUID sculptId;
7232 7724
@@ -7251,7 +7743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7251 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7743 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7252 { 7744 {
7253 // default 7745 // default
7254 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7746 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7255 } 7747 }
7256 7748
7257 part.Shape.SetSculptProperties((byte)type, sculptId); 7749 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7268,48 +7760,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7268 ScriptSleep(200); 7760 ScriptSleep(200);
7269 } 7761 }
7270 7762
7271 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7763 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7272 { 7764 {
7273 m_host.AddScriptLPS(1); 7765 m_host.AddScriptLPS(1);
7274 7766
7275 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7767 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7276 7768
7277 ScriptSleep(200); 7769 ScriptSleep(200);
7278 } 7770 }
7279 7771
7280 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7772 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7281 { 7773 {
7282 m_host.AddScriptLPS(1); 7774 List<object> parts = new List<object>();
7775 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7776 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7777 foreach (SceneObjectPart p in prims)
7778 parts.Add(p);
7779 foreach (ScenePresence p in avatars)
7780 parts.Add(p);
7283 7781
7284 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7782 LSL_List remaining = null;
7783 uint rulesParsed = 0;
7784
7785 if (parts.Count > 0)
7786 {
7787 foreach (object part in parts)
7788 {
7789 if (part is SceneObjectPart)
7790 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7791 else
7792 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7793 }
7794
7795 while ((object)remaining != null && remaining.Length > 2)
7796 {
7797 linknumber = remaining.GetLSLIntegerItem(0);
7798 rules = remaining.GetSublist(1, -1);
7799 parts.Clear();
7800 prims = GetLinkParts(linknumber);
7801 avatars = GetLinkAvatars(linknumber);
7802 foreach (SceneObjectPart p in prims)
7803 parts.Add(p);
7804 foreach (ScenePresence p in avatars)
7805 parts.Add(p);
7806
7807 remaining = null;
7808 foreach (object part in parts)
7809 {
7810 if (part is SceneObjectPart)
7811 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7812 else
7813 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7814 }
7815 }
7816 }
7285 } 7817 }
7286 7818
7287 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7819 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7820 float material_density, float material_friction,
7821 float material_restitution, float material_gravity_modifier)
7288 { 7822 {
7289 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7823 ExtraPhysicsData physdata = new ExtraPhysicsData();
7824 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7825 physdata.Density = part.Density;
7826 physdata.Friction = part.Friction;
7827 physdata.Bounce = part.Bounciness;
7828 physdata.GravitationModifier = part.GravityModifier;
7290 7829
7291 LSL_List remaining = null; 7830 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7292 uint rulesParsed = 0; 7831 physdata.Density = material_density;
7832 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7833 physdata.Friction = material_friction;
7834 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7835 physdata.Bounce = material_restitution;
7836 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7837 physdata.GravitationModifier = material_gravity_modifier;
7293 7838
7294 foreach (SceneObjectPart part in parts) 7839 part.UpdateExtraPhysics(physdata);
7295 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7840 }
7296 7841
7297 while (remaining != null && remaining.Length > 2) 7842 public void llSetPhysicsMaterial(int material_bits,
7298 { 7843 float material_gravity_modifier, float material_restitution,
7299 linknumber = remaining.GetLSLIntegerItem(0); 7844 float material_friction, float material_density)
7300 rules = remaining.GetSublist(1, -1); 7845 {
7301 parts = GetLinkParts(linknumber); 7846 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7847 }
7302 7848
7303 foreach (SceneObjectPart part in parts) 7849 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7304 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7850 {
7851 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7852 llSetLinkPrimitiveParamsFast(linknumber, rules);
7853 ScriptSleep(200);
7854 }
7855
7856 // vector up using libomv (c&p from sop )
7857 // vector up rotated by r
7858 private Vector3 Zrot(Quaternion r)
7859 {
7860 double x, y, z, m;
7861
7862 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7863 if (Math.Abs(1.0 - m) > 0.000001)
7864 {
7865 m = 1.0 / Math.Sqrt(m);
7866 r.X *= (float)m;
7867 r.Y *= (float)m;
7868 r.Z *= (float)m;
7869 r.W *= (float)m;
7305 } 7870 }
7871
7872 x = 2 * (r.X * r.Z + r.Y * r.W);
7873 y = 2 * (-r.X * r.W + r.Y * r.Z);
7874 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7875
7876 return new Vector3((float)x, (float)y, (float)z);
7306 } 7877 }
7307 7878
7308 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7879 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7309 { 7880 {
7881 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7882 return null;
7883
7310 int idx = 0; 7884 int idx = 0;
7311 int idxStart = 0; 7885 int idxStart = 0;
7312 7886
7887 SceneObjectGroup parentgrp = part.ParentGroup;
7888
7313 bool positionChanged = false; 7889 bool positionChanged = false;
7314 LSL_Vector currentPosition = GetPartLocalPos(part); 7890 LSL_Vector currentPosition = GetPartLocalPos(part);
7315 7891
@@ -7334,8 +7910,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7334 return null; 7910 return null;
7335 7911
7336 v=rules.GetVector3Item(idx++); 7912 v=rules.GetVector3Item(idx++);
7337 positionChanged = true;
7338 currentPosition = GetSetPosTarget(part, v, currentPosition); 7913 currentPosition = GetSetPosTarget(part, v, currentPosition);
7914 positionChanged = true;
7339 7915
7340 break; 7916 break;
7341 case (int)ScriptBaseClass.PRIM_SIZE: 7917 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7612,7 +8188,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7612 return null; 8188 return null;
7613 8189
7614 string ph = rules.Data[idx++].ToString(); 8190 string ph = rules.Data[idx++].ToString();
7615 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8191 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7616 8192
7617 break; 8193 break;
7618 8194
@@ -7630,12 +8206,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7630 part.ScriptSetPhysicsStatus(physics); 8206 part.ScriptSetPhysicsStatus(physics);
7631 break; 8207 break;
7632 8208
8209 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8210 if (remain < 1)
8211 return null;
8212
8213 int shape_type = rules.GetLSLIntegerItem(idx++);
8214
8215 ExtraPhysicsData physdata = new ExtraPhysicsData();
8216 physdata.Density = part.Density;
8217 physdata.Bounce = part.Bounciness;
8218 physdata.GravitationModifier = part.GravityModifier;
8219 physdata.PhysShapeType = (PhysShapeType)shape_type;
8220
8221 part.UpdateExtraPhysics(physdata);
8222
8223 break;
8224
8225 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8226 if (remain < 5)
8227 return null;
8228
8229 int material_bits = rules.GetLSLIntegerItem(idx++);
8230 float material_density = (float)rules.GetLSLFloatItem(idx++);
8231 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8232 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8233 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8234
8235 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8236
8237 break;
8238
7633 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8239 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7634 if (remain < 1) 8240 if (remain < 1)
7635 return null; 8241 return null;
7636 string temp = rules.Data[idx++].ToString(); 8242 string temp = rules.Data[idx++].ToString();
7637 8243
7638 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8244 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7639 8245
7640 break; 8246 break;
7641 8247
@@ -7709,7 +8315,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7709 if (part.ParentGroup.RootPart == part) 8315 if (part.ParentGroup.RootPart == part)
7710 { 8316 {
7711 SceneObjectGroup parent = part.ParentGroup; 8317 SceneObjectGroup parent = part.ParentGroup;
7712 parent.UpdateGroupPosition(currentPosition); 8318 Util.FireAndForget(delegate(object x) {
8319 parent.UpdateGroupPosition(currentPosition);
8320 });
7713 } 8321 }
7714 else 8322 else
7715 { 8323 {
@@ -7754,10 +8362,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7754 8362
7755 public LSL_String llXorBase64Strings(string str1, string str2) 8363 public LSL_String llXorBase64Strings(string str1, string str2)
7756 { 8364 {
7757 m_host.AddScriptLPS(1); 8365 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7758 Deprecated("llXorBase64Strings"); 8366
7759 ScriptSleep(300); 8367 ScriptSleep(300);
7760 return String.Empty; 8368 m_host.AddScriptLPS(1);
8369
8370 if (str1 == String.Empty)
8371 return String.Empty;
8372 if (str2 == String.Empty)
8373 return str1;
8374
8375 int len = str2.Length;
8376 if ((len % 4) != 0) // LL is EVIL!!!!
8377 {
8378 while (str2.EndsWith("="))
8379 str2 = str2.Substring(0, str2.Length - 1);
8380
8381 len = str2.Length;
8382 int mod = len % 4;
8383
8384 if (mod == 1)
8385 str2 = str2.Substring(0, str2.Length - 1);
8386 else if (mod == 2)
8387 str2 += "==";
8388 else if (mod == 3)
8389 str2 += "=";
8390 }
8391
8392 byte[] data1;
8393 byte[] data2;
8394 try
8395 {
8396 data1 = Convert.FromBase64String(str1);
8397 data2 = Convert.FromBase64String(str2);
8398 }
8399 catch (Exception)
8400 {
8401 return new LSL_String(String.Empty);
8402 }
8403
8404 // For cases where the decoded length of s2 is greater
8405 // than the decoded length of s1, simply perform a normal
8406 // decode and XOR
8407 //
8408 if (data2.Length >= data1.Length)
8409 {
8410 for (int pos = 0 ; pos < data1.Length ; pos++ )
8411 data1[pos] ^= data2[pos];
8412
8413 return Convert.ToBase64String(data1);
8414 }
8415
8416 // Remove padding
8417 while (str1.EndsWith("="))
8418 str1 = str1.Substring(0, str1.Length - 1);
8419 while (str2.EndsWith("="))
8420 str2 = str2.Substring(0, str2.Length - 1);
8421
8422 byte[] d1 = new byte[str1.Length];
8423 byte[] d2 = new byte[str2.Length];
8424
8425 for (int i = 0 ; i < str1.Length ; i++)
8426 {
8427 int idx = b64.IndexOf(str1.Substring(i, 1));
8428 if (idx == -1)
8429 idx = 0;
8430 d1[i] = (byte)idx;
8431 }
8432
8433 for (int i = 0 ; i < str2.Length ; i++)
8434 {
8435 int idx = b64.IndexOf(str2.Substring(i, 1));
8436 if (idx == -1)
8437 idx = 0;
8438 d2[i] = (byte)idx;
8439 }
8440
8441 string output = String.Empty;
8442
8443 for (int pos = 0 ; pos < d1.Length ; pos++)
8444 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8445
8446 while (output.Length % 3 > 0)
8447 output += "=";
8448
8449 return output;
7761 } 8450 }
7762 8451
7763 public void llRemoteDataSetRegion() 8452 public void llRemoteDataSetRegion()
@@ -7881,13 +8570,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7881 public LSL_Integer llGetNumberOfPrims() 8570 public LSL_Integer llGetNumberOfPrims()
7882 { 8571 {
7883 m_host.AddScriptLPS(1); 8572 m_host.AddScriptLPS(1);
7884 int avatarCount = 0; 8573 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7885 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8574
7886 {
7887 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7888 avatarCount++;
7889 });
7890
7891 return m_host.ParentGroup.PrimCount + avatarCount; 8575 return m_host.ParentGroup.PrimCount + avatarCount;
7892 } 8576 }
7893 8577
@@ -7903,55 +8587,114 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7903 m_host.AddScriptLPS(1); 8587 m_host.AddScriptLPS(1);
7904 UUID objID = UUID.Zero; 8588 UUID objID = UUID.Zero;
7905 LSL_List result = new LSL_List(); 8589 LSL_List result = new LSL_List();
8590
8591 // If the ID is not valid, return null result
7906 if (!UUID.TryParse(obj, out objID)) 8592 if (!UUID.TryParse(obj, out objID))
7907 { 8593 {
7908 result.Add(new LSL_Vector()); 8594 result.Add(new LSL_Vector());
7909 result.Add(new LSL_Vector()); 8595 result.Add(new LSL_Vector());
7910 return result; 8596 return result;
7911 } 8597 }
8598
8599 // Check if this is an attached prim. If so, replace
8600 // the UUID with the avatar UUID and report it's bounding box
8601 SceneObjectPart part = World.GetSceneObjectPart(objID);
8602 if (part != null && part.ParentGroup.IsAttachment)
8603 objID = part.ParentGroup.AttachedAvatar;
8604
8605 // Find out if this is an avatar ID. If so, return it's box
7912 ScenePresence presence = World.GetScenePresence(objID); 8606 ScenePresence presence = World.GetScenePresence(objID);
7913 if (presence != null) 8607 if (presence != null)
7914 { 8608 {
7915 if (presence.ParentID == 0) // not sat on an object 8609 // As per LSL Wiki, there is no difference between sitting
8610 // and standing avatar since server 1.36
8611 LSL_Vector lower;
8612 LSL_Vector upper;
8613
8614 Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
8615
8616 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8617 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
8618/*
7916 { 8619 {
7917 LSL_Vector lower; 8620 // This is for ground sitting avatars
7918 LSL_Vector upper; 8621 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7919 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8622 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7920 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8623 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7921 {
7922 // This is for ground sitting avatars
7923 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7924 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7925 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7926 }
7927 else
7928 {
7929 // This is for standing/flying avatars
7930 float height = presence.Appearance.AvatarHeight / 2.0f;
7931 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7932 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7933 }
7934 result.Add(lower);
7935 result.Add(upper);
7936 return result;
7937 } 8624 }
7938 else 8625 else
7939 { 8626 {
7940 // sitting on an object so we need the bounding box of that 8627 // This is for standing/flying avatars
7941 // which should include the avatar so set the UUID to the 8628 float height = presence.Appearance.AvatarHeight / 2.0f;
7942 // UUID of the object the avatar is sat on and allow it to fall through 8629 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7943 // to processing an object 8630 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7944 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7945 objID = p.UUID;
7946 } 8631 }
8632
8633 // Adjust to the documented error offsets (see LSL Wiki)
8634 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8635 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8636*/
8637 {
8638 // This is for ground sitting avatars TODO!
8639 lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
8640 upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
8641 }
8642 else
8643 {
8644 // This is for standing/flying avatars
8645 lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
8646 upper = new LSL_Vector(box.X, box.Y, box.Z);
8647 }
8648
8649 if (lower.x > upper.x)
8650 lower.x = upper.x;
8651 if (lower.y > upper.y)
8652 lower.y = upper.y;
8653 if (lower.z > upper.z)
8654 lower.z = upper.z;
8655
8656 result.Add(lower);
8657 result.Add(upper);
8658 return result;
7947 } 8659 }
7948 SceneObjectPart part = World.GetSceneObjectPart(objID); 8660
8661 part = World.GetSceneObjectPart(objID);
7949 // Currently only works for single prims without a sitting avatar 8662 // Currently only works for single prims without a sitting avatar
7950 if (part != null) 8663 if (part != null)
7951 { 8664 {
7952 Vector3 halfSize = part.Scale / 2.0f; 8665 float minX;
7953 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8666 float maxX;
7954 LSL_Vector upper = new LSL_Vector(halfSize); 8667 float minY;
8668 float maxY;
8669 float minZ;
8670 float maxZ;
8671
8672 // This BBox is in sim coordinates, with the offset being
8673 // a contained point.
8674 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8675 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8676
8677 minX -= offsets[0].X;
8678 maxX -= offsets[0].X;
8679 minY -= offsets[0].Y;
8680 maxY -= offsets[0].Y;
8681 minZ -= offsets[0].Z;
8682 maxZ -= offsets[0].Z;
8683
8684 LSL_Vector lower;
8685 LSL_Vector upper;
8686
8687 // Adjust to the documented error offsets (see LSL Wiki)
8688 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8689 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
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
7955 result.Add(lower); 8698 result.Add(lower);
7956 result.Add(upper); 8699 result.Add(upper);
7957 return result; 8700 return result;
@@ -7965,7 +8708,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7965 8708
7966 public LSL_Vector llGetGeometricCenter() 8709 public LSL_Vector llGetGeometricCenter()
7967 { 8710 {
7968 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8711 Vector3 tmp = m_host.GetGeometricCenter();
8712 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7969 } 8713 }
7970 8714
7971 public LSL_List llGetPrimitiveParams(LSL_List rules) 8715 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7993,24 +8737,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7993 { 8737 {
7994 m_host.AddScriptLPS(1); 8738 m_host.AddScriptLPS(1);
7995 8739
7996 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8740 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8741 // keep other options as before
7997 8742
8743 List<SceneObjectPart> parts;
8744 List<ScenePresence> avatars;
8745
7998 LSL_List res = new LSL_List(); 8746 LSL_List res = new LSL_List();
7999 LSL_List remaining = null; 8747 LSL_List remaining = null;
8000 8748
8001 foreach (SceneObjectPart part in parts) 8749 while (rules.Length > 0)
8002 {
8003 remaining = GetPrimParams(part, rules, ref res);
8004 }
8005
8006 while (remaining != null && remaining.Length > 2)
8007 { 8750 {
8008 linknumber = remaining.GetLSLIntegerItem(0);
8009 rules = remaining.GetSublist(1, -1);
8010 parts = GetLinkParts(linknumber); 8751 parts = GetLinkParts(linknumber);
8752 avatars = GetLinkAvatars(linknumber);
8011 8753
8754 remaining = null;
8012 foreach (SceneObjectPart part in parts) 8755 foreach (SceneObjectPart part in parts)
8756 {
8013 remaining = GetPrimParams(part, rules, ref res); 8757 remaining = GetPrimParams(part, rules, ref res);
8758 }
8759 foreach (ScenePresence avatar in avatars)
8760 {
8761 remaining = GetPrimParams(avatar, rules, ref res);
8762 }
8763
8764 if (remaining != null && remaining.Length > 0)
8765 {
8766 linknumber = remaining.GetLSLIntegerItem(0);
8767 rules = remaining.GetSublist(1, -1);
8768 }
8014 } 8769 }
8015 8770
8016 return res; 8771 return res;
@@ -8055,13 +8810,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8055 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8810 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8056 part.AbsolutePosition.Y, 8811 part.AbsolutePosition.Y,
8057 part.AbsolutePosition.Z); 8812 part.AbsolutePosition.Z);
8058 // For some reason, the part.AbsolutePosition.* values do not change if the
8059 // linkset is rotated; they always reflect the child prim's world position
8060 // as though the linkset is unrotated. This is incompatible behavior with SL's
8061 // implementation, so will break scripts imported from there (not to mention it
8062 // makes it more difficult to determine a child prim's actual inworld position).
8063 if (part.ParentID != 0)
8064 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8065 res.Add(v); 8813 res.Add(v);
8066 break; 8814 break;
8067 8815
@@ -8233,30 +8981,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8233 if (remain < 1) 8981 if (remain < 1)
8234 return null; 8982 return null;
8235 8983
8236 face=(int)rules.GetLSLIntegerItem(idx++); 8984 face = (int)rules.GetLSLIntegerItem(idx++);
8237 8985
8238 tex = part.Shape.Textures; 8986 tex = part.Shape.Textures;
8987 int shiny;
8239 if (face == ScriptBaseClass.ALL_SIDES) 8988 if (face == ScriptBaseClass.ALL_SIDES)
8240 { 8989 {
8241 for (face = 0; face < GetNumberOfSides(part); face++) 8990 for (face = 0; face < GetNumberOfSides(part); face++)
8242 { 8991 {
8243 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8992 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8244 // Convert Shininess to PRIM_SHINY_* 8993 if (shinyness == Shininess.High)
8245 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8994 {
8246 // PRIM_BUMP_* 8995 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8247 res.Add(new LSL_Integer((int)texface.Bump)); 8996 }
8997 else if (shinyness == Shininess.Medium)
8998 {
8999 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9000 }
9001 else if (shinyness == Shininess.Low)
9002 {
9003 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9004 }
9005 else
9006 {
9007 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9008 }
9009 res.Add(new LSL_Integer(shiny));
9010 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8248 } 9011 }
8249 } 9012 }
8250 else 9013 else
8251 { 9014 {
8252 if (face >= 0 && face < GetNumberOfSides(part)) 9015 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9016 if (shinyness == Shininess.High)
8253 { 9017 {
8254 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9018 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8255 // Convert Shininess to PRIM_SHINY_* 9019 }
8256 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9020 else if (shinyness == Shininess.Medium)
8257 // PRIM_BUMP_* 9021 {
8258 res.Add(new LSL_Integer((int)texface.Bump)); 9022 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9023 }
9024 else if (shinyness == Shininess.Low)
9025 {
9026 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9027 }
9028 else
9029 {
9030 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8259 } 9031 }
9032 res.Add(new LSL_Integer(shiny));
9033 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8260 } 9034 }
8261 break; 9035 break;
8262 9036
@@ -8264,24 +9038,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8264 if (remain < 1) 9038 if (remain < 1)
8265 return null; 9039 return null;
8266 9040
8267 face=(int)rules.GetLSLIntegerItem(idx++); 9041 face = (int)rules.GetLSLIntegerItem(idx++);
8268 9042
8269 tex = part.Shape.Textures; 9043 tex = part.Shape.Textures;
9044 int fullbright;
8270 if (face == ScriptBaseClass.ALL_SIDES) 9045 if (face == ScriptBaseClass.ALL_SIDES)
8271 { 9046 {
8272 for (face = 0; face < GetNumberOfSides(part); face++) 9047 for (face = 0; face < GetNumberOfSides(part); face++)
8273 { 9048 {
8274 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9049 if (tex.GetFace((uint)face).Fullbright == true)
8275 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9050 {
9051 fullbright = ScriptBaseClass.TRUE;
9052 }
9053 else
9054 {
9055 fullbright = ScriptBaseClass.FALSE;
9056 }
9057 res.Add(new LSL_Integer(fullbright));
8276 } 9058 }
8277 } 9059 }
8278 else 9060 else
8279 { 9061 {
8280 if (face >= 0 && face < GetNumberOfSides(part)) 9062 if (tex.GetFace((uint)face).Fullbright == true)
8281 { 9063 {
8282 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9064 fullbright = ScriptBaseClass.TRUE;
8283 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9065 }
9066 else
9067 {
9068 fullbright = ScriptBaseClass.FALSE;
8284 } 9069 }
9070 res.Add(new LSL_Integer(fullbright));
8285 } 9071 }
8286 break; 9072 break;
8287 9073
@@ -8303,27 +9089,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8303 break; 9089 break;
8304 9090
8305 case (int)ScriptBaseClass.PRIM_TEXGEN: 9091 case (int)ScriptBaseClass.PRIM_TEXGEN:
9092 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8306 if (remain < 1) 9093 if (remain < 1)
8307 return null; 9094 return null;
8308 9095
8309 face=(int)rules.GetLSLIntegerItem(idx++); 9096 face = (int)rules.GetLSLIntegerItem(idx++);
8310 9097
8311 tex = part.Shape.Textures; 9098 tex = part.Shape.Textures;
8312 if (face == ScriptBaseClass.ALL_SIDES) 9099 if (face == ScriptBaseClass.ALL_SIDES)
8313 { 9100 {
8314 for (face = 0; face < GetNumberOfSides(part); face++) 9101 for (face = 0; face < GetNumberOfSides(part); face++)
8315 { 9102 {
8316 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9103 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8317 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9104 {
8318 res.Add(new LSL_Integer((uint)texgen >> 1)); 9105 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9106 }
9107 else
9108 {
9109 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9110 }
8319 } 9111 }
8320 } 9112 }
8321 else 9113 else
8322 { 9114 {
8323 if (face >= 0 && face < GetNumberOfSides(part)) 9115 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8324 { 9116 {
8325 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9117 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8326 res.Add(new LSL_Integer((uint)texgen >> 1)); 9118 }
9119 else
9120 {
9121 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8327 } 9122 }
8328 } 9123 }
8329 break; 9124 break;
@@ -8347,24 +9142,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8347 if (remain < 1) 9142 if (remain < 1)
8348 return null; 9143 return null;
8349 9144
8350 face=(int)rules.GetLSLIntegerItem(idx++); 9145 face = (int)rules.GetLSLIntegerItem(idx++);
8351 9146
8352 tex = part.Shape.Textures; 9147 tex = part.Shape.Textures;
9148 float primglow;
8353 if (face == ScriptBaseClass.ALL_SIDES) 9149 if (face == ScriptBaseClass.ALL_SIDES)
8354 { 9150 {
8355 for (face = 0; face < GetNumberOfSides(part); face++) 9151 for (face = 0; face < GetNumberOfSides(part); face++)
8356 { 9152 {
8357 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9153 primglow = tex.GetFace((uint)face).Glow;
8358 res.Add(new LSL_Float(texface.Glow)); 9154 res.Add(new LSL_Float(primglow));
8359 } 9155 }
8360 } 9156 }
8361 else 9157 else
8362 { 9158 {
8363 if (face >= 0 && face < GetNumberOfSides(part)) 9159 primglow = tex.GetFace((uint)face).Glow;
8364 { 9160 res.Add(new LSL_Float(primglow));
8365 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8366 res.Add(new LSL_Float(texface.Glow));
8367 }
8368 } 9161 }
8369 break; 9162 break;
8370 9163
@@ -8376,15 +9169,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8376 textColor.B)); 9169 textColor.B));
8377 res.Add(new LSL_Float(textColor.A)); 9170 res.Add(new LSL_Float(textColor.A));
8378 break; 9171 break;
9172
8379 case (int)ScriptBaseClass.PRIM_NAME: 9173 case (int)ScriptBaseClass.PRIM_NAME:
8380 res.Add(new LSL_String(part.Name)); 9174 res.Add(new LSL_String(part.Name));
8381 break; 9175 break;
9176
8382 case (int)ScriptBaseClass.PRIM_DESC: 9177 case (int)ScriptBaseClass.PRIM_DESC:
8383 res.Add(new LSL_String(part.Description)); 9178 res.Add(new LSL_String(part.Description));
8384 break; 9179 break;
9180
8385 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9181 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8386 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9182 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8387 break; 9183 break;
9184
8388 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9185 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8389 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9186 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8390 break; 9187 break;
@@ -8995,8 +9792,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8995 // The function returns an ordered list 9792 // The function returns an ordered list
8996 // representing the tokens found in the supplied 9793 // representing the tokens found in the supplied
8997 // sources string. If two successive tokenizers 9794 // sources string. If two successive tokenizers
8998 // are encountered, then a NULL entry is added 9795 // are encountered, then a null-string entry is
8999 // to the list. 9796 // added to the list.
9000 // 9797 //
9001 // It is a precondition that the source and 9798 // It is a precondition that the source and
9002 // toekizer lisst are non-null. If they are null, 9799 // toekizer lisst are non-null. If they are null,
@@ -9004,7 +9801,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9004 // while their lengths are being determined. 9801 // while their lengths are being determined.
9005 // 9802 //
9006 // A small amount of working memoryis required 9803 // A small amount of working memoryis required
9007 // of approximately 8*#tokenizers. 9804 // of approximately 8*#tokenizers + 8*srcstrlen.
9008 // 9805 //
9009 // There are many ways in which this function 9806 // There are many ways in which this function
9010 // can be implemented, this implementation is 9807 // can be implemented, this implementation is
@@ -9020,155 +9817,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9020 // and eliminates redundant tokenizers as soon 9817 // and eliminates redundant tokenizers as soon
9021 // as is possible. 9818 // as is possible.
9022 // 9819 //
9023 // The implementation tries to avoid any copying 9820 // The implementation tries to minimize temporary
9024 // of arrays or other objects. 9821 // garbage generation.
9025 // </remarks> 9822 // </remarks>
9026 9823
9027 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9824 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9028 { 9825 {
9029 int beginning = 0; 9826 return ParseString2List(src, separators, spacers, true);
9030 int srclen = src.Length; 9827 }
9031 int seplen = separators.Length;
9032 object[] separray = separators.Data;
9033 int spclen = spacers.Length;
9034 object[] spcarray = spacers.Data;
9035 int mlen = seplen+spclen;
9036
9037 int[] offset = new int[mlen+1];
9038 bool[] active = new bool[mlen];
9039
9040 int best;
9041 int j;
9042
9043 // Initial capacity reduces resize cost
9044 9828
9045 LSL_List tokens = new LSL_List(); 9829 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9830 {
9831 int srclen = src.Length;
9832 int seplen = separators.Length;
9833 object[] separray = separators.Data;
9834 int spclen = spacers.Length;
9835 object[] spcarray = spacers.Data;
9836 int dellen = 0;
9837 string[] delarray = new string[seplen+spclen];
9046 9838
9047 // All entries are initially valid 9839 int outlen = 0;
9840 string[] outarray = new string[srclen*2+1];
9048 9841
9049 for (int i = 0; i < mlen; i++) 9842 int i, j;
9050 active[i] = true; 9843 string d;
9051 9844
9052 offset[mlen] = srclen; 9845 m_host.AddScriptLPS(1);
9053 9846
9054 while (beginning < srclen) 9847 /*
9848 * Convert separator and spacer lists to C# strings.
9849 * Also filter out null strings so we don't hang.
9850 */
9851 for (i = 0; i < seplen; i ++)
9055 { 9852 {
9853 d = separray[i].ToString();
9854 if (d.Length > 0)
9855 {
9856 delarray[dellen++] = d;
9857 }
9858 }
9859 seplen = dellen;
9056 9860
9057 best = mlen; // as bad as it gets 9861 for (i = 0; i < spclen; i ++)
9862 {
9863 d = spcarray[i].ToString();
9864 if (d.Length > 0)
9865 {
9866 delarray[dellen++] = d;
9867 }
9868 }
9058 9869
9059 // Scan for separators 9870 /*
9871 * Scan through source string from beginning to end.
9872 */
9873 for (i = 0;;)
9874 {
9060 9875
9061 for (j = 0; j < seplen; j++) 9876 /*
9877 * Find earliest delimeter in src starting at i (if any).
9878 */
9879 int earliestDel = -1;
9880 int earliestSrc = srclen;
9881 string earliestStr = null;
9882 for (j = 0; j < dellen; j ++)
9062 { 9883 {
9063 if (separray[j].ToString() == String.Empty) 9884 d = delarray[j];
9064 active[j] = false; 9885 if (d != null)
9065
9066 if (active[j])
9067 { 9886 {
9068 // scan all of the markers 9887 int index = src.IndexOf(d, i);
9069 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9888 if (index < 0)
9070 { 9889 {
9071 // not present at all 9890 delarray[j] = null; // delim nowhere in src, don't check it anymore
9072 active[j] = false;
9073 } 9891 }
9074 else 9892 else if (index < earliestSrc)
9075 { 9893 {
9076 // present and correct 9894 earliestSrc = index; // where delimeter starts in source string
9077 if (offset[j] < offset[best]) 9895 earliestDel = j; // where delimeter is in delarray[]
9078 { 9896 earliestStr = d; // the delimeter string from delarray[]
9079 // closest so far 9897 if (index == i) break; // can't do any better than found at beg of string
9080 best = j;
9081 if (offset[best] == beginning)
9082 break;
9083 }
9084 } 9898 }
9085 } 9899 }
9086 } 9900 }
9087 9901
9088 // Scan for spacers 9902 /*
9089 9903 * Output source string starting at i through start of earliest delimeter.
9090 if (offset[best] != beginning) 9904 */
9905 if (keepNulls || (earliestSrc > i))
9091 { 9906 {
9092 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9907 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9093 {
9094 if (spcarray[j-seplen].ToString() == String.Empty)
9095 active[j] = false;
9096
9097 if (active[j])
9098 {
9099 // scan all of the markers
9100 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9101 {
9102 // not present at all
9103 active[j] = false;
9104 }
9105 else
9106 {
9107 // present and correct
9108 if (offset[j] < offset[best])
9109 {
9110 // closest so far
9111 best = j;
9112 }
9113 }
9114 }
9115 }
9116 } 9908 }
9117 9909
9118 // This is the normal exit from the scanning loop 9910 /*
9911 * If no delimeter found at or after i, we're done scanning.
9912 */
9913 if (earliestDel < 0) break;
9119 9914
9120 if (best == mlen) 9915 /*
9916 * If delimeter was a spacer, output the spacer.
9917 */
9918 if (earliestDel >= seplen)
9121 { 9919 {
9122 // no markers were found on this pass 9920 outarray[outlen++] = earliestStr;
9123 // so we're pretty much done
9124 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9125 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9126 break;
9127 } 9921 }
9128 9922
9129 // Otherwise we just add the newly delimited token 9923 /*
9130 // and recalculate where the search should continue. 9924 * Look at rest of src string following delimeter.
9131 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9925 */
9132 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9926 i = earliestSrc + earliestStr.Length;
9133
9134 if (best < seplen)
9135 {
9136 beginning = offset[best] + (separray[best].ToString()).Length;
9137 }
9138 else
9139 {
9140 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9141 string str = spcarray[best - seplen].ToString();
9142 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9143 tokens.Add(new LSL_String(str));
9144 }
9145 } 9927 }
9146 9928
9147 // This an awkward an not very intuitive boundary case. If the 9929 /*
9148 // last substring is a tokenizer, then there is an implied trailing 9930 * Make up an exact-sized output array suitable for an LSL_List object.
9149 // null list entry. Hopefully the single comparison will not be too 9931 */
9150 // arduous. Alternatively the 'break' could be replced with a return 9932 object[] outlist = new object[outlen];
9151 // but that's shabby programming. 9933 for (i = 0; i < outlen; i ++)
9152
9153 if ((beginning == srclen) && (keepNulls))
9154 { 9934 {
9155 if (srclen != 0) 9935 outlist[i] = new LSL_String(outarray[i]);
9156 tokens.Add(new LSL_String(""));
9157 } 9936 }
9158 9937 return new LSL_List(outlist);
9159 return tokens;
9160 }
9161
9162 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9163 {
9164 m_host.AddScriptLPS(1);
9165 return this.ParseString(src, separators, spacers, false);
9166 }
9167
9168 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9169 {
9170 m_host.AddScriptLPS(1);
9171 return this.ParseString(src, separators, spacers, true);
9172 } 9938 }
9173 9939
9174 public LSL_Integer llGetObjectPermMask(int mask) 9940 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9263,6 +10029,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9263 case 4: 10029 case 4:
9264 return (int)item.NextPermissions; 10030 return (int)item.NextPermissions;
9265 } 10031 }
10032 m_host.TaskInventory.LockItemsForRead(false);
9266 10033
9267 return -1; 10034 return -1;
9268 } 10035 }
@@ -9465,31 +10232,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9465 UUID key = new UUID(); 10232 UUID key = new UUID();
9466 if (UUID.TryParse(id, out key)) 10233 if (UUID.TryParse(id, out key))
9467 { 10234 {
9468 try 10235 // return total object mass
9469 { 10236 SceneObjectPart part = World.GetSceneObjectPart(key);
9470 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10237 if (part != null)
9471 if (obj != null) 10238 return part.ParentGroup.GetMass();
9472 return (double)obj.GetMass(); 10239
9473 // the object is null so the key is for an avatar 10240 // the object is null so the key is for an avatar
9474 ScenePresence avatar = World.GetScenePresence(key); 10241 ScenePresence avatar = World.GetScenePresence(key);
9475 if (avatar != null) 10242 if (avatar != null)
9476 if (avatar.IsChildAgent)
9477 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9478 // child agents have a mass of 1.0
9479 return 1;
9480 else
9481 return (double)avatar.GetMass();
9482 }
9483 catch (KeyNotFoundException)
9484 { 10243 {
9485 return 0; // The Object/Agent not in the region so just return zero 10244 if (avatar.IsChildAgent)
10245 {
10246 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10247 // child agents have a mass of 1.0
10248 return 1;
10249 }
10250 else
10251 {
10252 return (double)avatar.GetMass();
10253 }
9486 } 10254 }
9487 } 10255 }
9488 return 0; 10256 return 0;
9489 } 10257 }
9490 10258
9491 /// <summary> 10259 /// <summary>
9492 /// illListReplaceList removes the sub-list defined by the inclusive indices 10260 /// llListReplaceList removes the sub-list defined by the inclusive indices
9493 /// start and end and inserts the src list in its place. The inclusive 10261 /// start and end and inserts the src list in its place. The inclusive
9494 /// nature of the indices means that at least one element must be deleted 10262 /// nature of the indices means that at least one element must be deleted
9495 /// if the indices are within the bounds of the existing list. I.e. 2,2 10263 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9546,16 +10314,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9546 // based upon end. Note that if end exceeds the upper 10314 // based upon end. Note that if end exceeds the upper
9547 // bound in this case, the entire destination list 10315 // bound in this case, the entire destination list
9548 // is removed. 10316 // is removed.
9549 else 10317 else if (start == 0)
9550 { 10318 {
9551 if (end + 1 < dest.Length) 10319 if (end + 1 < dest.Length)
9552 {
9553 return src + dest.GetSublist(end + 1, -1); 10320 return src + dest.GetSublist(end + 1, -1);
9554 }
9555 else 10321 else
9556 {
9557 return src; 10322 return src;
9558 } 10323 }
10324 else // Start < 0
10325 {
10326 if (end + 1 < dest.Length)
10327 return dest.GetSublist(end + 1, -1);
10328 else
10329 return new LSL_List();
9559 } 10330 }
9560 } 10331 }
9561 // Finally, if start > end, we strip away a prefix and 10332 // Finally, if start > end, we strip away a prefix and
@@ -9606,17 +10377,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9606 int width = 0; 10377 int width = 0;
9607 int height = 0; 10378 int height = 0;
9608 10379
9609 ParcelMediaCommandEnum? commandToSend = null; 10380 uint commandToSend = 0;
9610 float time = 0.0f; // default is from start 10381 float time = 0.0f; // default is from start
9611 10382
9612 ScenePresence presence = null; 10383 ScenePresence presence = null;
9613 10384
9614 for (int i = 0; i < commandList.Data.Length; i++) 10385 for (int i = 0; i < commandList.Data.Length; i++)
9615 { 10386 {
9616 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10387 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9617 switch (command) 10388 switch (command)
9618 { 10389 {
9619 case ParcelMediaCommandEnum.Agent: 10390 case (uint)ParcelMediaCommandEnum.Agent:
9620 // we send only to one agent 10391 // we send only to one agent
9621 if ((i + 1) < commandList.Length) 10392 if ((i + 1) < commandList.Length)
9622 { 10393 {
@@ -9633,25 +10404,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9633 } 10404 }
9634 break; 10405 break;
9635 10406
9636 case ParcelMediaCommandEnum.Loop: 10407 case (uint)ParcelMediaCommandEnum.Loop:
9637 loop = 1; 10408 loop = 1;
9638 commandToSend = command; 10409 commandToSend = command;
9639 update = true; //need to send the media update packet to set looping 10410 update = true; //need to send the media update packet to set looping
9640 break; 10411 break;
9641 10412
9642 case ParcelMediaCommandEnum.Play: 10413 case (uint)ParcelMediaCommandEnum.Play:
9643 loop = 0; 10414 loop = 0;
9644 commandToSend = command; 10415 commandToSend = command;
9645 update = true; //need to send the media update packet to make sure it doesn't loop 10416 update = true; //need to send the media update packet to make sure it doesn't loop
9646 break; 10417 break;
9647 10418
9648 case ParcelMediaCommandEnum.Pause: 10419 case (uint)ParcelMediaCommandEnum.Pause:
9649 case ParcelMediaCommandEnum.Stop: 10420 case (uint)ParcelMediaCommandEnum.Stop:
9650 case ParcelMediaCommandEnum.Unload: 10421 case (uint)ParcelMediaCommandEnum.Unload:
9651 commandToSend = command; 10422 commandToSend = command;
9652 break; 10423 break;
9653 10424
9654 case ParcelMediaCommandEnum.Url: 10425 case (uint)ParcelMediaCommandEnum.Url:
9655 if ((i + 1) < commandList.Length) 10426 if ((i + 1) < commandList.Length)
9656 { 10427 {
9657 if (commandList.Data[i + 1] is LSL_String) 10428 if (commandList.Data[i + 1] is LSL_String)
@@ -9664,7 +10435,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9664 } 10435 }
9665 break; 10436 break;
9666 10437
9667 case ParcelMediaCommandEnum.Texture: 10438 case (uint)ParcelMediaCommandEnum.Texture:
9668 if ((i + 1) < commandList.Length) 10439 if ((i + 1) < commandList.Length)
9669 { 10440 {
9670 if (commandList.Data[i + 1] is LSL_String) 10441 if (commandList.Data[i + 1] is LSL_String)
@@ -9677,7 +10448,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9677 } 10448 }
9678 break; 10449 break;
9679 10450
9680 case ParcelMediaCommandEnum.Time: 10451 case (uint)ParcelMediaCommandEnum.Time:
9681 if ((i + 1) < commandList.Length) 10452 if ((i + 1) < commandList.Length)
9682 { 10453 {
9683 if (commandList.Data[i + 1] is LSL_Float) 10454 if (commandList.Data[i + 1] is LSL_Float)
@@ -9689,7 +10460,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9689 } 10460 }
9690 break; 10461 break;
9691 10462
9692 case ParcelMediaCommandEnum.AutoAlign: 10463 case (uint)ParcelMediaCommandEnum.AutoAlign:
9693 if ((i + 1) < commandList.Length) 10464 if ((i + 1) < commandList.Length)
9694 { 10465 {
9695 if (commandList.Data[i + 1] is LSL_Integer) 10466 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9703,7 +10474,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9703 } 10474 }
9704 break; 10475 break;
9705 10476
9706 case ParcelMediaCommandEnum.Type: 10477 case (uint)ParcelMediaCommandEnum.Type:
9707 if ((i + 1) < commandList.Length) 10478 if ((i + 1) < commandList.Length)
9708 { 10479 {
9709 if (commandList.Data[i + 1] is LSL_String) 10480 if (commandList.Data[i + 1] is LSL_String)
@@ -9716,7 +10487,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9716 } 10487 }
9717 break; 10488 break;
9718 10489
9719 case ParcelMediaCommandEnum.Desc: 10490 case (uint)ParcelMediaCommandEnum.Desc:
9720 if ((i + 1) < commandList.Length) 10491 if ((i + 1) < commandList.Length)
9721 { 10492 {
9722 if (commandList.Data[i + 1] is LSL_String) 10493 if (commandList.Data[i + 1] is LSL_String)
@@ -9729,7 +10500,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9729 } 10500 }
9730 break; 10501 break;
9731 10502
9732 case ParcelMediaCommandEnum.Size: 10503 case (uint)ParcelMediaCommandEnum.Size:
9733 if ((i + 2) < commandList.Length) 10504 if ((i + 2) < commandList.Length)
9734 { 10505 {
9735 if (commandList.Data[i + 1] is LSL_Integer) 10506 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9799,7 +10570,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9799 } 10570 }
9800 } 10571 }
9801 10572
9802 if (commandToSend != null) 10573 if (commandToSend != 0)
9803 { 10574 {
9804 // the commandList contained a start/stop/... command, too 10575 // the commandList contained a start/stop/... command, too
9805 if (presence == null) 10576 if (presence == null)
@@ -9836,7 +10607,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9836 10607
9837 if (aList.Data[i] != null) 10608 if (aList.Data[i] != null)
9838 { 10609 {
9839 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10610 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9840 { 10611 {
9841 case ParcelMediaCommandEnum.Url: 10612 case ParcelMediaCommandEnum.Url:
9842 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10613 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9893,15 +10664,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9893 10664
9894 if (quick_pay_buttons.Data.Length < 4) 10665 if (quick_pay_buttons.Data.Length < 4)
9895 { 10666 {
9896 LSLError("List must have at least 4 elements"); 10667 int x;
9897 return; 10668 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10669 {
10670 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10671 }
9898 } 10672 }
9899 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10673 int[] nPrice = new int[5];
9900 10674 nPrice[0] = price;
9901 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10675 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9902 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10676 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9903 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10677 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9904 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10678 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10679 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9905 m_host.ParentGroup.HasGroupChanged = true; 10680 m_host.ParentGroup.HasGroupChanged = true;
9906 } 10681 }
9907 10682
@@ -9918,7 +10693,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9918 return new LSL_Vector(); 10693 return new LSL_Vector();
9919 } 10694 }
9920 10695
9921 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10696// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10697 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9922 if (presence != null) 10698 if (presence != null)
9923 { 10699 {
9924 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10700 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9940,7 +10716,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9940 return new LSL_Rotation(); 10716 return new LSL_Rotation();
9941 } 10717 }
9942 10718
9943 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10719// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10720 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9944 if (presence != null) 10721 if (presence != null)
9945 { 10722 {
9946 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10723 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -10000,14 +10777,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10000 { 10777 {
10001 m_host.AddScriptLPS(1); 10778 m_host.AddScriptLPS(1);
10002 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10779 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
10003 if (detectedParams == null) return; // only works on the first detected avatar 10780 if (detectedParams == null)
10004 10781 {
10782 if (m_host.ParentGroup.IsAttachment == true)
10783 {
10784 detectedParams = new DetectParams();
10785 detectedParams.Key = m_host.OwnerID;
10786 }
10787 else
10788 {
10789 return;
10790 }
10791 }
10792
10005 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10793 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
10006 if (avatar != null) 10794 if (avatar != null)
10007 { 10795 {
10008 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10796 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
10009 simname, pos, lookAt); 10797 simname, pos, lookAt);
10010 } 10798 }
10799
10011 ScriptSleep(1000); 10800 ScriptSleep(1000);
10012 } 10801 }
10013 10802
@@ -10131,12 +10920,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10131 10920
10132 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10921 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10133 object[] data = rules.Data; 10922 object[] data = rules.Data;
10134 for (int i = 0; i < data.Length; ++i) { 10923 for (int i = 0; i < data.Length; ++i)
10924 {
10135 int type = Convert.ToInt32(data[i++].ToString()); 10925 int type = Convert.ToInt32(data[i++].ToString());
10136 if (i >= data.Length) break; // odd number of entries => ignore the last 10926 if (i >= data.Length) break; // odd number of entries => ignore the last
10137 10927
10138 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10928 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10139 switch (type) { 10929 switch (type)
10930 {
10140 case ScriptBaseClass.CAMERA_FOCUS: 10931 case ScriptBaseClass.CAMERA_FOCUS:
10141 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10932 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10142 case ScriptBaseClass.CAMERA_POSITION: 10933 case ScriptBaseClass.CAMERA_POSITION:
@@ -10241,19 +11032,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10241 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11032 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10242 { 11033 {
10243 m_host.AddScriptLPS(1); 11034 m_host.AddScriptLPS(1);
10244 string ret = String.Empty; 11035
10245 string src1 = llBase64ToString(str1); 11036 if (str1 == String.Empty)
10246 string src2 = llBase64ToString(str2); 11037 return String.Empty;
10247 int c = 0; 11038 if (str2 == String.Empty)
10248 for (int i = 0; i < src1.Length; i++) 11039 return str1;
11040
11041 int len = str2.Length;
11042 if ((len % 4) != 0) // LL is EVIL!!!!
11043 {
11044 while (str2.EndsWith("="))
11045 str2 = str2.Substring(0, str2.Length - 1);
11046
11047 len = str2.Length;
11048 int mod = len % 4;
11049
11050 if (mod == 1)
11051 str2 = str2.Substring(0, str2.Length - 1);
11052 else if (mod == 2)
11053 str2 += "==";
11054 else if (mod == 3)
11055 str2 += "=";
11056 }
11057
11058 byte[] data1;
11059 byte[] data2;
11060 try
11061 {
11062 data1 = Convert.FromBase64String(str1);
11063 data2 = Convert.FromBase64String(str2);
11064 }
11065 catch (Exception)
11066 {
11067 return new LSL_String(String.Empty);
11068 }
11069
11070 byte[] d2 = new Byte[data1.Length];
11071 int pos = 0;
11072
11073 if (data1.Length <= data2.Length)
11074 {
11075 Array.Copy(data2, 0, d2, 0, data1.Length);
11076 }
11077 else
10249 { 11078 {
10250 ret += (char) (src1[i] ^ src2[c]); 11079 while (pos < data1.Length)
11080 {
11081 len = data1.Length - pos;
11082 if (len > data2.Length)
11083 len = data2.Length;
10251 11084
10252 c++; 11085 Array.Copy(data2, 0, d2, pos, len);
10253 if (c >= src2.Length) 11086 pos += len;
10254 c = 0; 11087 }
10255 } 11088 }
10256 return llStringToBase64(ret); 11089
11090 for (pos = 0 ; pos < data1.Length ; pos++ )
11091 data1[pos] ^= d2[pos];
11092
11093 return Convert.ToBase64String(data1);
10257 } 11094 }
10258 11095
10259 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11096 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10306,16 +11143,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10306 if (userAgent != null) 11143 if (userAgent != null)
10307 httpHeaders["User-Agent"] = userAgent; 11144 httpHeaders["User-Agent"] = userAgent;
10308 11145
11146 // See if the URL contains any header hacks
11147 string[] urlParts = url.Split(new char[] {'\n'});
11148 if (urlParts.Length > 1)
11149 {
11150 // Iterate the passed headers and parse them
11151 for (int i = 1 ; i < urlParts.Length ; i++ )
11152 {
11153 // The rest of those would be added to the body in SL.
11154 // Let's not do that.
11155 if (urlParts[i] == String.Empty)
11156 break;
11157
11158 // See if this could be a valid header
11159 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11160 if (headerParts.Length != 2)
11161 continue;
11162
11163 string headerName = headerParts[0].Trim();
11164 string headerValue = headerParts[1].Trim();
11165
11166 // Filter out headers that could be used to abuse
11167 // another system or cloak the request
11168 if (headerName.ToLower() == "x-secondlife-shard" ||
11169 headerName.ToLower() == "x-secondlife-object-name" ||
11170 headerName.ToLower() == "x-secondlife-object-key" ||
11171 headerName.ToLower() == "x-secondlife-region" ||
11172 headerName.ToLower() == "x-secondlife-local-position" ||
11173 headerName.ToLower() == "x-secondlife-local-velocity" ||
11174 headerName.ToLower() == "x-secondlife-local-rotation" ||
11175 headerName.ToLower() == "x-secondlife-owner-name" ||
11176 headerName.ToLower() == "x-secondlife-owner-key" ||
11177 headerName.ToLower() == "connection" ||
11178 headerName.ToLower() == "content-length" ||
11179 headerName.ToLower() == "from" ||
11180 headerName.ToLower() == "host" ||
11181 headerName.ToLower() == "proxy-authorization" ||
11182 headerName.ToLower() == "referer" ||
11183 headerName.ToLower() == "trailer" ||
11184 headerName.ToLower() == "transfer-encoding" ||
11185 headerName.ToLower() == "via" ||
11186 headerName.ToLower() == "authorization")
11187 continue;
11188
11189 httpHeaders[headerName] = headerValue;
11190 }
11191
11192 // Finally, strip any protocol specifier from the URL
11193 url = urlParts[0].Trim();
11194 int idx = url.IndexOf(" HTTP/");
11195 if (idx != -1)
11196 url = url.Substring(0, idx);
11197 }
11198
10309 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11199 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10310 Regex r = new Regex(authregex); 11200 Regex r = new Regex(authregex);
10311 int[] gnums = r.GetGroupNumbers(); 11201 int[] gnums = r.GetGroupNumbers();
10312 Match m = r.Match(url); 11202 Match m = r.Match(url);
10313 if (m.Success) { 11203 if (m.Success)
10314 for (int i = 1; i < gnums.Length; i++) { 11204 {
11205 for (int i = 1; i < gnums.Length; i++)
11206 {
10315 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11207 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10316 //CaptureCollection cc = g.Captures; 11208 //CaptureCollection cc = g.Captures;
10317 } 11209 }
10318 if (m.Groups.Count == 5) { 11210 if (m.Groups.Count == 5)
11211 {
10319 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11212 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10320 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11213 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10321 } 11214 }
@@ -10518,6 +11411,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10518 11411
10519 LSL_List ret = new LSL_List(); 11412 LSL_List ret = new LSL_List();
10520 UUID key = new UUID(); 11413 UUID key = new UUID();
11414
11415
10521 if (UUID.TryParse(id, out key)) 11416 if (UUID.TryParse(id, out key))
10522 { 11417 {
10523 ScenePresence av = World.GetScenePresence(key); 11418 ScenePresence av = World.GetScenePresence(key);
@@ -10535,13 +11430,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10535 ret.Add(new LSL_String("")); 11430 ret.Add(new LSL_String(""));
10536 break; 11431 break;
10537 case ScriptBaseClass.OBJECT_POS: 11432 case ScriptBaseClass.OBJECT_POS:
10538 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11433 Vector3 avpos;
11434
11435 if (av.ParentID != 0 && av.ParentPart != null)
11436 {
11437 avpos = av.OffsetPosition;
11438
11439 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11440 avpos -= sitOffset;
11441
11442 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11443 }
11444 else
11445 avpos = av.AbsolutePosition;
11446
11447 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10539 break; 11448 break;
10540 case ScriptBaseClass.OBJECT_ROT: 11449 case ScriptBaseClass.OBJECT_ROT:
10541 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11450 Quaternion avrot = av.Rotation;
11451 if (av.ParentID != 0 && av.ParentPart != null)
11452 {
11453 avrot = av.ParentPart.GetWorldRotation() * avrot;
11454 }
11455 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10542 break; 11456 break;
10543 case ScriptBaseClass.OBJECT_VELOCITY: 11457 case ScriptBaseClass.OBJECT_VELOCITY:
10544 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11458 Vector3 avvel = av.Velocity;
11459 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10545 break; 11460 break;
10546 case ScriptBaseClass.OBJECT_OWNER: 11461 case ScriptBaseClass.OBJECT_OWNER:
10547 ret.Add(new LSL_String(id)); 11462 ret.Add(new LSL_String(id));
@@ -10597,11 +11512,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10597 case ScriptBaseClass.OBJECT_NAME: 11512 case ScriptBaseClass.OBJECT_NAME:
10598 ret.Add(new LSL_String(obj.Name)); 11513 ret.Add(new LSL_String(obj.Name));
10599 break; 11514 break;
10600 case ScriptBaseClass.OBJECT_DESC: 11515 case ScriptBaseClass.OBJECT_DESC:
10601 ret.Add(new LSL_String(obj.Description)); 11516 ret.Add(new LSL_String(obj.Description));
10602 break; 11517 break;
10603 case ScriptBaseClass.OBJECT_POS: 11518 case ScriptBaseClass.OBJECT_POS:
10604 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11519 Vector3 opos = obj.AbsolutePosition;
11520 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10605 break; 11521 break;
10606 case ScriptBaseClass.OBJECT_ROT: 11522 case ScriptBaseClass.OBJECT_ROT:
10607 { 11523 {
@@ -10651,9 +11567,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10651 // The value returned in SL for normal prims is prim count 11567 // The value returned in SL for normal prims is prim count
10652 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11568 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10653 break; 11569 break;
10654 // The following 3 costs I have intentionaly coded to return zero. They are part of 11570
10655 // "Land Impact" calculations. These calculations are probably not applicable 11571 // costs below may need to be diferent for root parts, need to check
10656 // to OpenSim and are not yet complete in SL
10657 case ScriptBaseClass.OBJECT_SERVER_COST: 11572 case ScriptBaseClass.OBJECT_SERVER_COST:
10658 // The linden calculation is here 11573 // The linden calculation is here
10659 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11574 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10661,16 +11576,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10661 ret.Add(new LSL_Float(0)); 11576 ret.Add(new LSL_Float(0));
10662 break; 11577 break;
10663 case ScriptBaseClass.OBJECT_STREAMING_COST: 11578 case ScriptBaseClass.OBJECT_STREAMING_COST:
10664 // The linden calculation is here 11579 // The value returned in SL for normal prims is prim count * 0.06
10665 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11580 ret.Add(new LSL_Float(obj.StreamingCost));
10666 // The value returned in SL for normal prims looks like the prim count * 0.06
10667 ret.Add(new LSL_Float(0));
10668 break; 11581 break;
10669 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11582 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10670 // The linden calculation is here 11583 // The value returned in SL for normal prims is prim count
10671 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11584 ret.Add(new LSL_Float(obj.PhysicsCost));
10672 // The value returned in SL for normal prims looks like the prim count
10673 ret.Add(new LSL_Float(0));
10674 break; 11585 break;
10675 default: 11586 default:
10676 // Invalid or unhandled constant. 11587 // Invalid or unhandled constant.
@@ -10881,15 +11792,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10881 return result; 11792 return result;
10882 } 11793 }
10883 11794
10884 public void print(string str) 11795 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10885 { 11796 {
10886 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11797 List<SceneObjectPart> parts = GetLinkParts(link);
10887 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11798 if (parts.Count < 1)
10888 if (ossl != null) 11799 return 0;
10889 { 11800
10890 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11801 return GetNumberOfSides(parts[0]);
10891 m_log.Info("LSL print():" + str);
10892 }
10893 } 11802 }
10894 11803
10895 private string Name2Username(string name) 11804 private string Name2Username(string name)
@@ -10934,7 +11843,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10934 11843
10935 return rq.ToString(); 11844 return rq.ToString();
10936 } 11845 }
10937 11846/*
11847 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11848 {
11849 m_SayShoutCount = 0;
11850 }
11851*/
10938 private struct Tri 11852 private struct Tri
10939 { 11853 {
10940 public Vector3 p1; 11854 public Vector3 p1;
@@ -11074,9 +11988,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11074 11988
11075 ContactResult result = new ContactResult (); 11989 ContactResult result = new ContactResult ();
11076 result.ConsumerID = group.LocalId; 11990 result.ConsumerID = group.LocalId;
11077 result.Depth = intersection.distance; 11991// result.Depth = intersection.distance;
11078 result.Normal = intersection.normal; 11992 result.Normal = intersection.normal;
11079 result.Pos = intersection.ipoint; 11993 result.Pos = intersection.ipoint;
11994 result.Depth = Vector3.Mag(rayStart - result.Pos);
11080 11995
11081 contacts.Add(result); 11996 contacts.Add(result);
11082 }); 11997 });
@@ -11209,6 +12124,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11209 12124
11210 return contacts[0]; 12125 return contacts[0];
11211 } 12126 }
12127/*
12128 // not done:
12129 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12130 {
12131 ContactResult[] contacts = null;
12132 World.ForEachSOG(delegate(SceneObjectGroup group)
12133 {
12134 if (m_host.ParentGroup == group)
12135 return;
12136
12137 if (group.IsAttachment)
12138 return;
12139
12140 if(group.RootPart.PhysActor != null)
12141 return;
12142
12143 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12144 });
12145 return contacts;
12146 }
12147*/
11212 12148
11213 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12149 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11214 { 12150 {
@@ -11250,32 +12186,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11250 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12186 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11251 12187
11252 12188
11253 if (checkTerrain) 12189 if (World.SuportsRayCastFiltered())
11254 { 12190 {
11255 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12191 if (dist == 0)
11256 if (groundContact != null) 12192 return list;
11257 results.Add((ContactResult)groundContact);
11258 }
11259 12193
11260 if (checkAgents) 12194 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11261 { 12195 if (checkTerrain)
11262 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12196 rayfilter |= RayFilterFlags.land;
11263 foreach (ContactResult r in agentHits) 12197// if (checkAgents)
11264 results.Add(r); 12198// rayfilter |= RayFilterFlags.agent;
11265 } 12199 if (checkPhysical)
12200 rayfilter |= RayFilterFlags.physical;
12201 if (checkNonPhysical)
12202 rayfilter |= RayFilterFlags.nonphysical;
12203 if (detectPhantom)
12204 rayfilter |= RayFilterFlags.LSLPhanton;
12205
12206 Vector3 direction = dir * ( 1/dist);
11266 12207
11267 if (checkPhysical || checkNonPhysical || detectPhantom) 12208 if(rayfilter == 0)
12209 {
12210 list.Add(new LSL_Integer(0));
12211 return list;
12212 }
12213
12214 // get some more contacts to sort ???
12215 int physcount = 4 * count;
12216 if (physcount > 20)
12217 physcount = 20;
12218
12219 object physresults;
12220 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12221
12222 if (physresults == null)
12223 {
12224 list.Add(new LSL_Integer(-3)); // timeout error
12225 return list;
12226 }
12227
12228 results = (List<ContactResult>)physresults;
12229
12230 // for now physics doesn't detect sitted avatars so do it outside physics
12231 if (checkAgents)
12232 {
12233 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12234 foreach (ContactResult r in agentHits)
12235 results.Add(r);
12236 }
12237
12238 // TODO: Replace this with a better solution. ObjectIntersection can only
12239 // detect nonphysical phantoms. They are detected by virtue of being
12240 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12241 // physicsl phantoms as done by the physics scene
12242 // We don't want anything else but phantoms here.
12243 if (detectPhantom)
12244 {
12245 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12246 foreach (ContactResult r in objectHits)
12247 results.Add(r);
12248 }
12249 }
12250 else
11268 { 12251 {
11269 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12252 if (checkTerrain)
11270 foreach (ContactResult r in objectHits) 12253 {
11271 results.Add(r); 12254 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12255 if (groundContact != null)
12256 results.Add((ContactResult)groundContact);
12257 }
12258
12259 if (checkAgents)
12260 {
12261 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12262 foreach (ContactResult r in agentHits)
12263 results.Add(r);
12264 }
12265
12266 if (checkPhysical || checkNonPhysical || detectPhantom)
12267 {
12268 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12269 foreach (ContactResult r in objectHits)
12270 results.Add(r);
12271 }
11272 } 12272 }
11273 12273
11274 results.Sort(delegate(ContactResult a, ContactResult b) 12274 results.Sort(delegate(ContactResult a, ContactResult b)
11275 { 12275 {
11276 return a.Depth.CompareTo(b.Depth); 12276 return a.Depth.CompareTo(b.Depth);
11277 }); 12277 });
11278 12278
11279 int values = 0; 12279 int values = 0;
11280 SceneObjectGroup thisgrp = m_host.ParentGroup; 12280 SceneObjectGroup thisgrp = m_host.ParentGroup;
11281 12281
@@ -11368,7 +12368,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11368 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12368 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11369 if (!isAccount) return 0; 12369 if (!isAccount) return 0;
11370 if (estate.HasAccess(id)) return 1; 12370 if (estate.HasAccess(id)) return 1;
11371 if (estate.IsBanned(id)) 12371 if (estate.IsBanned(id, World.GetUserFlags(id)))
11372 estate.RemoveBan(id); 12372 estate.RemoveBan(id);
11373 estate.AddEstateUser(id); 12373 estate.AddEstateUser(id);
11374 break; 12374 break;
@@ -11387,14 +12387,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11387 break; 12387 break;
11388 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12388 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11389 if (!isAccount) return 0; 12389 if (!isAccount) return 0;
11390 if (estate.IsBanned(id)) return 1; 12390 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11391 EstateBan ban = new EstateBan(); 12391 EstateBan ban = new EstateBan();
11392 ban.EstateID = estate.EstateID; 12392 ban.EstateID = estate.EstateID;
11393 ban.BannedUserID = id; 12393 ban.BannedUserID = id;
11394 estate.AddBan(ban); 12394 estate.AddBan(ban);
11395 break; 12395 break;
11396 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12396 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11397 if (!isAccount || !estate.IsBanned(id)) return 0; 12397 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11398 estate.RemoveBan(id); 12398 estate.RemoveBan(id);
11399 break; 12399 break;
11400 default: return 0; 12400 default: return 0;
@@ -11423,7 +12423,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11423 return 16384; 12423 return 16384;
11424 } 12424 }
11425 12425
11426 public LSL_Integer llGetUsedMemory() 12426 public virtual LSL_Integer llGetUsedMemory()
11427 { 12427 {
11428 m_host.AddScriptLPS(1); 12428 m_host.AddScriptLPS(1);
11429 // The value returned for LSO scripts in SL 12429 // The value returned for LSO scripts in SL
@@ -11451,22 +12451,734 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11451 public void llSetSoundQueueing(int queue) 12451 public void llSetSoundQueueing(int queue)
11452 { 12452 {
11453 m_host.AddScriptLPS(1); 12453 m_host.AddScriptLPS(1);
11454 NotImplemented("llSetSoundQueueing");
11455 } 12454 }
11456 12455
11457 public void llCollisionSprite(string impact_sprite) 12456 public void llCollisionSprite(string impact_sprite)
11458 { 12457 {
11459 m_host.AddScriptLPS(1); 12458 m_host.AddScriptLPS(1);
11460 NotImplemented("llCollisionSprite"); 12459 // Viewer 2.0 broke this and it's likely LL has no intention
12460 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11461 } 12461 }
11462 12462
11463 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12463 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11464 { 12464 {
11465 m_host.AddScriptLPS(1); 12465 m_host.AddScriptLPS(1);
11466 NotImplemented("llGodLikeRezObject"); 12466
12467 if (!World.Permissions.IsGod(m_host.OwnerID))
12468 NotImplemented("llGodLikeRezObject");
12469
12470 AssetBase rezAsset = World.AssetService.Get(inventory);
12471 if (rezAsset == null)
12472 {
12473 llSay(0, "Asset not found");
12474 return;
12475 }
12476
12477 SceneObjectGroup group = null;
12478
12479 try
12480 {
12481 string xmlData = Utils.BytesToString(rezAsset.Data);
12482 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12483 }
12484 catch
12485 {
12486 llSay(0, "Asset not found");
12487 return;
12488 }
12489
12490 if (group == null)
12491 {
12492 llSay(0, "Asset not found");
12493 return;
12494 }
12495
12496 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12497 group.RootPart.AttachOffset = group.AbsolutePosition;
12498
12499 group.ResetIDs();
12500
12501 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12502 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12503 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12504 group.ScheduleGroupForFullUpdate();
12505
12506 // objects rezzed with this method are die_at_edge by default.
12507 group.RootPart.SetDieAtEdge(true);
12508
12509 group.ResumeScripts();
12510
12511 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12512 "object_rez", new Object[] {
12513 new LSL_String(
12514 group.RootPart.UUID.ToString()) },
12515 new DetectParams[0]));
12516 }
12517
12518 public LSL_String llTransferLindenDollars(string destination, int amount)
12519 {
12520 UUID txn = UUID.Random();
12521
12522 Util.FireAndForget(delegate(object x)
12523 {
12524 int replycode = 0;
12525 string replydata = destination + "," + amount.ToString();
12526
12527 try
12528 {
12529 TaskInventoryItem item = m_item;
12530 if (item == null)
12531 {
12532 replydata = "SERVICE_ERROR";
12533 return;
12534 }
12535
12536 m_host.AddScriptLPS(1);
12537
12538 if (item.PermsGranter == UUID.Zero)
12539 {
12540 replydata = "MISSING_PERMISSION_DEBIT";
12541 return;
12542 }
12543
12544 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12545 {
12546 replydata = "MISSING_PERMISSION_DEBIT";
12547 return;
12548 }
12549
12550 UUID toID = new UUID();
12551
12552 if (!UUID.TryParse(destination, out toID))
12553 {
12554 replydata = "INVALID_AGENT";
12555 return;
12556 }
12557
12558 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12559
12560 if (money == null)
12561 {
12562 replydata = "TRANSFERS_DISABLED";
12563 return;
12564 }
12565
12566 bool result = money.ObjectGiveMoney(
12567 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
12568
12569 if (result)
12570 {
12571 replycode = 1;
12572 return;
12573 }
12574
12575 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12576 }
12577 finally
12578 {
12579 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12580 "transaction_result", new Object[] {
12581 new LSL_String(txn.ToString()),
12582 new LSL_Integer(replycode),
12583 new LSL_String(replydata) },
12584 new DetectParams[0]));
12585 }
12586 });
12587
12588 return txn.ToString();
11467 } 12589 }
11468 12590
11469 #endregion 12591 #endregion
12592
12593 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12594 {
12595 SceneObjectGroup group = m_host.ParentGroup;
12596
12597 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12598 return;
12599 if (group.IsAttachment)
12600 return;
12601
12602 if (frames.Data.Length > 0) // We are getting a new motion
12603 {
12604 if (group.RootPart.KeyframeMotion != null)
12605 group.RootPart.KeyframeMotion.Delete();
12606 group.RootPart.KeyframeMotion = null;
12607
12608 int idx = 0;
12609
12610 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12611 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12612
12613 while (idx < options.Data.Length)
12614 {
12615 int option = (int)options.GetLSLIntegerItem(idx++);
12616 int remain = options.Data.Length - idx;
12617
12618 switch (option)
12619 {
12620 case ScriptBaseClass.KFM_MODE:
12621 if (remain < 1)
12622 break;
12623 int modeval = (int)options.GetLSLIntegerItem(idx++);
12624 switch(modeval)
12625 {
12626 case ScriptBaseClass.KFM_FORWARD:
12627 mode = KeyframeMotion.PlayMode.Forward;
12628 break;
12629 case ScriptBaseClass.KFM_REVERSE:
12630 mode = KeyframeMotion.PlayMode.Reverse;
12631 break;
12632 case ScriptBaseClass.KFM_LOOP:
12633 mode = KeyframeMotion.PlayMode.Loop;
12634 break;
12635 case ScriptBaseClass.KFM_PING_PONG:
12636 mode = KeyframeMotion.PlayMode.PingPong;
12637 break;
12638 }
12639 break;
12640 case ScriptBaseClass.KFM_DATA:
12641 if (remain < 1)
12642 break;
12643 int dataval = (int)options.GetLSLIntegerItem(idx++);
12644 data = (KeyframeMotion.DataFormat)dataval;
12645 break;
12646 }
12647 }
12648
12649 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12650
12651 idx = 0;
12652
12653 int elemLength = 2;
12654 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12655 elemLength = 3;
12656
12657 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12658 while (idx < frames.Data.Length)
12659 {
12660 int remain = frames.Data.Length - idx;
12661
12662 if (remain < elemLength)
12663 break;
12664
12665 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12666 frame.Position = null;
12667 frame.Rotation = null;
12668
12669 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12670 {
12671 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12672 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12673 }
12674 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12675 {
12676 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12677 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12678 }
12679
12680 float tempf = (float)frames.GetLSLFloatItem(idx++);
12681 frame.TimeMS = (int)(tempf * 1000.0f);
12682
12683 keyframes.Add(frame);
12684 }
12685
12686 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12687 group.RootPart.KeyframeMotion.Start();
12688 }
12689 else
12690 {
12691 if (group.RootPart.KeyframeMotion == null)
12692 return;
12693
12694 if (options.Data.Length == 0)
12695 {
12696 group.RootPart.KeyframeMotion.Stop();
12697 return;
12698 }
12699
12700 int code = (int)options.GetLSLIntegerItem(0);
12701
12702 int idx = 0;
12703
12704 while (idx < options.Data.Length)
12705 {
12706 int option = (int)options.GetLSLIntegerItem(idx++);
12707 int remain = options.Data.Length - idx;
12708
12709 switch (option)
12710 {
12711 case ScriptBaseClass.KFM_COMMAND:
12712 int cmd = (int)options.GetLSLIntegerItem(idx++);
12713 switch (cmd)
12714 {
12715 case ScriptBaseClass.KFM_CMD_PLAY:
12716 group.RootPart.KeyframeMotion.Start();
12717 break;
12718 case ScriptBaseClass.KFM_CMD_STOP:
12719 group.RootPart.KeyframeMotion.Stop();
12720 break;
12721 case ScriptBaseClass.KFM_CMD_PAUSE:
12722 group.RootPart.KeyframeMotion.Pause();
12723 break;
12724 }
12725 break;
12726 }
12727 }
12728 }
12729 }
12730
12731 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12732 {
12733 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12734
12735 int idx = 0;
12736 int idxStart = 0;
12737
12738 bool positionChanged = false;
12739 Vector3 finalPos = Vector3.Zero;
12740
12741 try
12742 {
12743 while (idx < rules.Length)
12744 {
12745 ++rulesParsed;
12746 int code = rules.GetLSLIntegerItem(idx++);
12747
12748 int remain = rules.Length - idx;
12749 idxStart = idx;
12750
12751 switch (code)
12752 {
12753 case (int)ScriptBaseClass.PRIM_POSITION:
12754 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12755 {
12756 if (remain < 1)
12757 return null;
12758
12759 LSL_Vector v;
12760 v = rules.GetVector3Item(idx++);
12761
12762 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12763 if (part == null)
12764 break;
12765
12766 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12767 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12768 if (part.LinkNum > 1)
12769 {
12770 localRot = GetPartLocalRot(part);
12771 localPos = GetPartLocalPos(part);
12772 }
12773
12774 v -= localPos;
12775 v /= localRot;
12776
12777 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12778
12779 v = v + 2 * sitOffset;
12780
12781 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12782 av.SendAvatarDataToAllAgents();
12783
12784 }
12785 break;
12786
12787 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12788 case (int)ScriptBaseClass.PRIM_ROTATION:
12789 {
12790 if (remain < 1)
12791 return null;
12792
12793 LSL_Rotation r;
12794 r = rules.GetQuaternionItem(idx++);
12795
12796 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12797 if (part == null)
12798 break;
12799
12800 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12801 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12802
12803 if (part.LinkNum > 1)
12804 localRot = GetPartLocalRot(part);
12805
12806 r = r * llGetRootRotation() / localRot;
12807 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12808 av.SendAvatarDataToAllAgents();
12809 }
12810 break;
12811
12812 // parse rest doing nothing but number of parameters error check
12813 case (int)ScriptBaseClass.PRIM_SIZE:
12814 case (int)ScriptBaseClass.PRIM_MATERIAL:
12815 case (int)ScriptBaseClass.PRIM_PHANTOM:
12816 case (int)ScriptBaseClass.PRIM_PHYSICS:
12817 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12818 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12819 case (int)ScriptBaseClass.PRIM_NAME:
12820 case (int)ScriptBaseClass.PRIM_DESC:
12821 if (remain < 1)
12822 return null;
12823 idx++;
12824 break;
12825
12826 case (int)ScriptBaseClass.PRIM_GLOW:
12827 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12828 case (int)ScriptBaseClass.PRIM_TEXGEN:
12829 if (remain < 2)
12830 return null;
12831 idx += 2;
12832 break;
12833
12834 case (int)ScriptBaseClass.PRIM_TYPE:
12835 if (remain < 3)
12836 return null;
12837 code = (int)rules.GetLSLIntegerItem(idx++);
12838 remain = rules.Length - idx;
12839 switch (code)
12840 {
12841 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12842 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12843 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12844 if (remain < 6)
12845 return null;
12846 idx += 6;
12847 break;
12848
12849 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12850 if (remain < 5)
12851 return null;
12852 idx += 5;
12853 break;
12854
12855 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12856 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12857 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12858 if (remain < 11)
12859 return null;
12860 idx += 11;
12861 break;
12862
12863 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12864 if (remain < 2)
12865 return null;
12866 idx += 2;
12867 break;
12868 }
12869 break;
12870
12871 case (int)ScriptBaseClass.PRIM_COLOR:
12872 case (int)ScriptBaseClass.PRIM_TEXT:
12873 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12874 case (int)ScriptBaseClass.PRIM_OMEGA:
12875 if (remain < 3)
12876 return null;
12877 idx += 3;
12878 break;
12879
12880 case (int)ScriptBaseClass.PRIM_TEXTURE:
12881 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12882 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12883 if (remain < 5)
12884 return null;
12885 idx += 5;
12886 break;
12887
12888 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12889 if (remain < 7)
12890 return null;
12891
12892 idx += 7;
12893 break;
12894
12895 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12896 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12897 return null;
12898
12899 return rules.GetSublist(idx, -1);
12900 }
12901 }
12902 }
12903 catch (InvalidCastException e)
12904 {
12905 ShoutError(string.Format(
12906 "{0} error running rule #{1}: arg #{2} ",
12907 originFunc, rulesParsed, idx - idxStart) + e.Message);
12908 }
12909 finally
12910 {
12911 if (positionChanged)
12912 {
12913 av.OffsetPosition = finalPos;
12914// av.SendAvatarDataToAllAgents();
12915 av.SendTerseUpdateToAllClients();
12916 positionChanged = false;
12917 }
12918 }
12919 return null;
12920 }
12921
12922 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12923 {
12924 // avatars case
12925 // replies as SL wiki
12926
12927// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12928 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12929
12930 int idx = 0;
12931 while (idx < rules.Length)
12932 {
12933 int code = (int)rules.GetLSLIntegerItem(idx++);
12934 int remain = rules.Length - idx;
12935
12936 switch (code)
12937 {
12938 case (int)ScriptBaseClass.PRIM_MATERIAL:
12939 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12940 break;
12941
12942 case (int)ScriptBaseClass.PRIM_PHYSICS:
12943 res.Add(new LSL_Integer(0));
12944 break;
12945
12946 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12947 res.Add(new LSL_Integer(0));
12948 break;
12949
12950 case (int)ScriptBaseClass.PRIM_PHANTOM:
12951 res.Add(new LSL_Integer(0));
12952 break;
12953
12954 case (int)ScriptBaseClass.PRIM_POSITION:
12955
12956 Vector3 pos = avatar.OffsetPosition;
12957
12958 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12959 pos -= sitOffset;
12960
12961 if( sitPart != null)
12962 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12963
12964 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12965 break;
12966
12967 case (int)ScriptBaseClass.PRIM_SIZE:
12968 // as in llGetAgentSize above
12969// res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12970 Vector3 s = avatar.Appearance.AvatarSize;
12971 res.Add(new LSL_Vector(s.X, s.Y, s.Z));
12972
12973 break;
12974
12975 case (int)ScriptBaseClass.PRIM_ROTATION:
12976 Quaternion rot = avatar.Rotation;
12977 if (sitPart != null)
12978 {
12979 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12980 }
12981
12982 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12983 break;
12984
12985 case (int)ScriptBaseClass.PRIM_TYPE:
12986 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12987 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12988 res.Add(new LSL_Vector(0f,1.0f,0f));
12989 res.Add(new LSL_Float(0.0f));
12990 res.Add(new LSL_Vector(0, 0, 0));
12991 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12992 res.Add(new LSL_Vector(0, 0, 0));
12993 break;
12994
12995 case (int)ScriptBaseClass.PRIM_TEXTURE:
12996 if (remain < 1)
12997 return null;
12998
12999 int face = (int)rules.GetLSLIntegerItem(idx++);
13000 if (face == ScriptBaseClass.ALL_SIDES)
13001 {
13002 for (face = 0; face < 21; face++)
13003 {
13004 res.Add(new LSL_String(""));
13005 res.Add(new LSL_Vector(0,0,0));
13006 res.Add(new LSL_Vector(0,0,0));
13007 res.Add(new LSL_Float(0.0));
13008 }
13009 }
13010 else
13011 {
13012 if (face >= 0 && face < 21)
13013 {
13014 res.Add(new LSL_String(""));
13015 res.Add(new LSL_Vector(0,0,0));
13016 res.Add(new LSL_Vector(0,0,0));
13017 res.Add(new LSL_Float(0.0));
13018 }
13019 }
13020 break;
13021
13022 case (int)ScriptBaseClass.PRIM_COLOR:
13023 if (remain < 1)
13024 return null;
13025
13026 face = (int)rules.GetLSLIntegerItem(idx++);
13027
13028 if (face == ScriptBaseClass.ALL_SIDES)
13029 {
13030 for (face = 0; face < 21; face++)
13031 {
13032 res.Add(new LSL_Vector(0,0,0));
13033 res.Add(new LSL_Float(0));
13034 }
13035 }
13036 else
13037 {
13038 res.Add(new LSL_Vector(0,0,0));
13039 res.Add(new LSL_Float(0));
13040 }
13041 break;
13042
13043 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13044 if (remain < 1)
13045 return null;
13046 face = (int)rules.GetLSLIntegerItem(idx++);
13047
13048 if (face == ScriptBaseClass.ALL_SIDES)
13049 {
13050 for (face = 0; face < 21; face++)
13051 {
13052 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13053 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13054 }
13055 }
13056 else
13057 {
13058 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13059 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13060 }
13061 break;
13062
13063 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13064 if (remain < 1)
13065 return null;
13066 face = (int)rules.GetLSLIntegerItem(idx++);
13067
13068 if (face == ScriptBaseClass.ALL_SIDES)
13069 {
13070 for (face = 0; face < 21; face++)
13071 {
13072 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13073 }
13074 }
13075 else
13076 {
13077 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13078 }
13079 break;
13080
13081 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13082 res.Add(new LSL_Integer(0));
13083 res.Add(new LSL_Integer(0));// softness
13084 res.Add(new LSL_Float(0.0f)); // gravity
13085 res.Add(new LSL_Float(0.0f)); // friction
13086 res.Add(new LSL_Float(0.0f)); // wind
13087 res.Add(new LSL_Float(0.0f)); // tension
13088 res.Add(new LSL_Vector(0f,0f,0f));
13089 break;
13090
13091 case (int)ScriptBaseClass.PRIM_TEXGEN:
13092 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13093 if (remain < 1)
13094 return null;
13095 face = (int)rules.GetLSLIntegerItem(idx++);
13096
13097 if (face == ScriptBaseClass.ALL_SIDES)
13098 {
13099 for (face = 0; face < 21; face++)
13100 {
13101 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13102 }
13103 }
13104 else
13105 {
13106 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13107 }
13108 break;
13109
13110 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13111 res.Add(new LSL_Integer(0));
13112 res.Add(new LSL_Vector(0f,0f,0f));
13113 res.Add(new LSL_Float(0f)); // intensity
13114 res.Add(new LSL_Float(0f)); // radius
13115 res.Add(new LSL_Float(0f)); // falloff
13116 break;
13117
13118 case (int)ScriptBaseClass.PRIM_GLOW:
13119 if (remain < 1)
13120 return null;
13121 face = (int)rules.GetLSLIntegerItem(idx++);
13122
13123 if (face == ScriptBaseClass.ALL_SIDES)
13124 {
13125 for (face = 0; face < 21; face++)
13126 {
13127 res.Add(new LSL_Float(0f));
13128 }
13129 }
13130 else
13131 {
13132 res.Add(new LSL_Float(0f));
13133 }
13134 break;
13135
13136 case (int)ScriptBaseClass.PRIM_TEXT:
13137 res.Add(new LSL_String(""));
13138 res.Add(new LSL_Vector(0f,0f,0f));
13139 res.Add(new LSL_Float(1.0f));
13140 break;
13141
13142 case (int)ScriptBaseClass.PRIM_NAME:
13143 res.Add(new LSL_String(avatar.Name));
13144 break;
13145
13146 case (int)ScriptBaseClass.PRIM_DESC:
13147 res.Add(new LSL_String(""));
13148 break;
13149
13150 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13151 Quaternion lrot = avatar.Rotation;
13152
13153 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13154 {
13155 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13156 }
13157 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13158 break;
13159
13160 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13161 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13162 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13163 lpos -= lsitOffset;
13164
13165 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13166 {
13167 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13168 }
13169 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13170 break;
13171
13172 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13173 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13174 return null;
13175
13176 return rules.GetSublist(idx, -1);
13177 }
13178 }
13179
13180 return null;
13181 }
11470 } 13182 }
11471 13183
11472 public class NotecardCache 13184 public class NotecardCache