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.cs3195
1 files changed, 2443 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 acf4d8c..700f538 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{
@@ -104,16 +108,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
104 protected int m_notecardLineReadCharsMax = 255; 108 protected int m_notecardLineReadCharsMax = 255;
105 protected int m_scriptConsoleChannel = 0; 109 protected int m_scriptConsoleChannel = 0;
106 protected bool m_scriptConsoleChannelEnabled = false; 110 protected bool m_scriptConsoleChannelEnabled = false;
111 protected bool m_debuggerSafe = false;
107 protected IUrlModule m_UrlModule = null; 112 protected IUrlModule m_UrlModule = null;
108 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 113 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
109 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 114 new Dictionary<UUID, UserInfoCacheEntry>();
115 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
110 protected ISoundModule m_SoundModule = null; 116 protected ISoundModule m_SoundModule = null;
111 117
118// protected Timer m_ShoutSayTimer;
119 protected int m_SayShoutCount = 0;
120 DateTime m_lastSayShoutCheck;
121
122 private Dictionary<string, string> MovementAnimationsForLSL =
123 new Dictionary<string, string> {
124 {"FLY", "Flying"},
125 {"FLYSLOW", "FlyingSlow"},
126 {"HOVER_UP", "Hovering Up"},
127 {"HOVER_DOWN", "Hovering Down"},
128 {"HOVER", "Hovering"},
129 {"LAND", "Landing"},
130 {"FALLDOWN", "Falling Down"},
131 {"PREJUMP", "PreJumping"},
132 {"JUMP", "Jumping"},
133 {"STANDUP", "Standing Up"},
134 {"SOFT_LAND", "Soft Landing"},
135 {"STAND", "Standing"},
136 {"CROUCHWALK", "CrouchWalking"},
137 {"RUN", "Running"},
138 {"WALK", "Walking"},
139 {"CROUCH", "Crouching"},
140 {"TURNLEFT", "Turning Left"},
141 {"TURNRIGHT", "Turning Right"}
142 };
143
112 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
113 { 145 {
146/*
147 m_ShoutSayTimer = new Timer(1000);
148 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
149 m_ShoutSayTimer.AutoReset = true;
150 m_ShoutSayTimer.Start();
151*/
152 m_lastSayShoutCheck = DateTime.UtcNow;
153
114 m_ScriptEngine = ScriptEngine; 154 m_ScriptEngine = ScriptEngine;
115 m_host = host; 155 m_host = host;
116 m_item = item; 156 m_item = item;
157 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
117 158
118 LoadLimits(); // read script limits from config. 159 LoadLimits(); // read script limits from config.
119 160
@@ -174,6 +215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
174 get { return m_ScriptEngine.World; } 215 get { return m_ScriptEngine.World; }
175 } 216 }
176 217
218 [DebuggerNonUserCode]
177 public void state(string newState) 219 public void state(string newState)
178 { 220 {
179 m_ScriptEngine.SetState(m_item.ItemID, newState); 221 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -183,6 +225,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
183 /// Reset the named script. The script must be present 225 /// Reset the named script. The script must be present
184 /// in the same prim. 226 /// in the same prim.
185 /// </summary> 227 /// </summary>
228 [DebuggerNonUserCode]
186 public void llResetScript() 229 public void llResetScript()
187 { 230 {
188 m_host.AddScriptLPS(1); 231 m_host.AddScriptLPS(1);
@@ -245,6 +288,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
245 } 288 }
246 } 289 }
247 290
291 public List<ScenePresence> GetLinkAvatars(int linkType)
292 {
293 List<ScenePresence> ret = new List<ScenePresence>();
294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
295 return ret;
296
297 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
298
299 switch (linkType)
300 {
301 case ScriptBaseClass.LINK_SET:
302 return avs;
303
304 case ScriptBaseClass.LINK_ROOT:
305 return ret;
306
307 case ScriptBaseClass.LINK_ALL_OTHERS:
308 return avs;
309
310 case ScriptBaseClass.LINK_ALL_CHILDREN:
311 return avs;
312
313 case ScriptBaseClass.LINK_THIS:
314 return ret;
315
316 default:
317 if (linkType < 0)
318 return ret;
319
320 int partCount = m_host.ParentGroup.GetPartCount();
321
322 if (linkType <= partCount)
323 {
324 return ret;
325 }
326 else
327 {
328 linkType = linkType - partCount;
329 if (linkType > avs.Count)
330 {
331 return ret;
332 }
333 else
334 {
335 ret.Add(avs[linkType-1]);
336 return ret;
337 }
338 }
339 }
340 }
341
248 public List<SceneObjectPart> GetLinkParts(int linkType) 342 public List<SceneObjectPart> GetLinkParts(int linkType)
249 { 343 {
250 return GetLinkParts(m_host, linkType); 344 return GetLinkParts(m_host, linkType);
@@ -253,6 +347,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
253 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType) 347 public static List<SceneObjectPart> GetLinkParts(SceneObjectPart part, int linkType)
254 { 348 {
255 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 349 List<SceneObjectPart> ret = new List<SceneObjectPart>();
350 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
351 return ret;
256 ret.Add(part); 352 ret.Add(part);
257 353
258 switch (linkType) 354 switch (linkType)
@@ -479,31 +575,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
479 575
480 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 576 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
481 577
482 /// <summary> 578 // Utility function for llRot2Euler
483 /// Convert an LSL rotation to a Euler vector. 579
484 /// </summary> 580 // normalize an angle between -PI and PI (-180 to +180 degrees)
485 /// <remarks> 581 protected double NormalizeAngle(double angle)
486 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
487 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
488 /// </remarks>
489 /// <param name="r"></param>
490 /// <returns></returns>
491 public LSL_Vector llRot2Euler(LSL_Rotation r)
492 { 582 {
493 m_host.AddScriptLPS(1); 583 if (angle > -Math.PI && angle < Math.PI)
584 return angle;
494 585
495 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 586 int numPis = (int)(Math.PI / angle);
496 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 587 double remainder = angle - Math.PI * numPis;
497 if (m == 0.0) return new LSL_Vector(); 588 if (numPis % 2 == 1)
498 double x = Math.Atan2(-v.y, v.z); 589 return Math.PI - angle;
499 double sin = v.x / m; 590 return remainder;
500 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities. 591 }
501 double y = Math.Asin(sin);
502 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
503 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)));
504 double z = Math.Atan2(v.y, v.x);
505 592
506 return new LSL_Vector(x, y, z); 593 public LSL_Vector llRot2Euler(LSL_Rotation q1)
594 {
595 m_host.AddScriptLPS(1);
596 LSL_Vector eul = new LSL_Vector();
597
598 double sqw = q1.s*q1.s;
599 double sqx = q1.x*q1.x;
600 double sqy = q1.z*q1.z;
601 double sqz = q1.y*q1.y;
602 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
603 double test = q1.x*q1.z + q1.y*q1.s;
604 if (test > 0.4999*unit) { // singularity at north pole
605 eul.z = 2 * Math.Atan2(q1.x,q1.s);
606 eul.y = Math.PI/2;
607 eul.x = 0;
608 return eul;
609 }
610 if (test < -0.4999*unit) { // singularity at south pole
611 eul.z = -2 * Math.Atan2(q1.x,q1.s);
612 eul.y = -Math.PI/2;
613 eul.x = 0;
614 return eul;
615 }
616 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
617 eul.y = Math.Asin(2*test/unit);
618 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
619 return eul;
507 } 620 }
508 621
509 /* From wiki: 622 /* From wiki:
@@ -556,18 +669,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
556 m_host.AddScriptLPS(1); 669 m_host.AddScriptLPS(1);
557 670
558 double x,y,z,s; 671 double x,y,z,s;
559 672 v.x *= 0.5;
560 double c1 = Math.Cos(v.x * 0.5); 673 v.y *= 0.5;
561 double c2 = Math.Cos(v.y * 0.5); 674 v.z *= 0.5;
562 double c3 = Math.Cos(v.z * 0.5); 675 double c1 = Math.Cos(v.x);
563 double s1 = Math.Sin(v.x * 0.5); 676 double c2 = Math.Cos(v.y);
564 double s2 = Math.Sin(v.y * 0.5); 677 double c1c2 = c1 * c2;
565 double s3 = Math.Sin(v.z * 0.5); 678 double s1 = Math.Sin(v.x);
566 679 double s2 = Math.Sin(v.y);
567 x = s1 * c2 * c3 + c1 * s2 * s3; 680 double s1s2 = s1 * s2;
568 y = c1 * s2 * c3 - s1 * c2 * s3; 681 double c1s2 = c1 * s2;
569 z = s1 * s2 * c3 + c1 * c2 * s3; 682 double s1c2 = s1 * c2;
570 s = c1 * c2 * c3 - s1 * s2 * s3; 683 double c3 = Math.Cos(v.z);
684 double s3 = Math.Sin(v.z);
685
686 x = s1c2 * c3 + c1s2 * s3;
687 y = c1s2 * c3 - s1c2 * s3;
688 z = s1s2 * c3 + c1c2 * s3;
689 s = c1c2 * c3 - s1s2 * s3;
571 690
572 return new LSL_Rotation(x, y, z, s); 691 return new LSL_Rotation(x, y, z, s);
573 } 692 }
@@ -705,77 +824,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
705 { 824 {
706 //A and B should both be normalized 825 //A and B should both be normalized
707 m_host.AddScriptLPS(1); 826 m_host.AddScriptLPS(1);
708 LSL_Rotation rotBetween; 827 /* This method is more accurate than the SL one, and thus causes problems
709 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 828 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
710 // continue calculation. 829
711 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 830 double dotProduct = LSL_Vector.Dot(a, b);
831 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
832 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
833 double angle = Math.Acos(dotProduct / magProduct);
834 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
835 double s = Math.Sin(angle / 2);
836
837 double x = axis.x * s;
838 double y = axis.y * s;
839 double z = axis.z * s;
840 double w = Math.Cos(angle / 2);
841
842 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
843 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
844
845 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
846 */
847
848 // This method mimics the 180 errors found in SL
849 // See www.euclideanspace.com... angleBetween
850 LSL_Vector vec_a = a;
851 LSL_Vector vec_b = b;
852
853 // Eliminate zero length
854 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
855 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
856 if (vec_a_mag < 0.00001 ||
857 vec_b_mag < 0.00001)
712 { 858 {
713 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 859 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
714 } 860 }
715 else 861
862 // Normalize
863 vec_a = llVecNorm(vec_a);
864 vec_b = llVecNorm(vec_b);
865
866 // Calculate axis and rotation angle
867 LSL_Vector axis = vec_a % vec_b;
868 LSL_Float cos_theta = vec_a * vec_b;
869
870 // Check if parallel
871 if (cos_theta > 0.99999)
716 { 872 {
717 a = LSL_Vector.Norm(a); 873 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
718 b = LSL_Vector.Norm(b); 874 }
719 double dotProduct = LSL_Vector.Dot(a, b); 875
720 // There are two degenerate cases possible. These are for vectors 180 or 876 // Check if anti-parallel
721 // 0 degrees apart. These have to be detected and handled individually. 877 else if (cos_theta < -0.99999)
722 // 878 {
723 // Check for vectors 180 degrees apart. 879 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
724 // A dot product of -1 would mean the angle between vectors is 180 degrees. 880 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
725 if (dotProduct < -0.9999999f) 881 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
726 { 882 }
727 // First assume X axis is orthogonal to the vectors. 883 else // other rotation
728 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 884 {
729 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 885 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
730 // Check for near zero vector. A very small non-zero number here will create 886 axis = llVecNorm(axis);
731 // a rotation in an undesired direction. 887 double x, y, z, s, t;
732 if (LSL_Vector.Mag(orthoVector) > 0.0001) 888 s = Math.Cos(theta);
733 { 889 t = Math.Sin(theta);
734 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 890 x = axis.x * t;
735 } 891 y = axis.y * t;
736 // If the magnitude of the vector was near zero, then assume the X axis is not 892 z = axis.z * t;
737 // orthogonal and use the Z axis instead. 893 return new LSL_Rotation(x,y,z,s);
738 else
739 {
740 // Set 180 z rotation.
741 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
742 }
743 }
744 // Check for parallel vectors.
745 // A dot product of 1 would mean the angle between vectors is 0 degrees.
746 else if (dotProduct > 0.9999999f)
747 {
748 // Set zero rotation.
749 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
750 }
751 else
752 {
753 // All special checks have been performed so get the axis of rotation.
754 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
755 // Quarternion s value is the length of the unit vector + dot product.
756 double qs = 1.0 + dotProduct;
757 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
758 // Normalize the rotation.
759 double mag = LSL_Rotation.Mag(rotBetween);
760 // We shouldn't have to worry about a divide by zero here. The qs value will be
761 // non-zero because we already know if we're here, then the dotProduct is not -1 so
762 // qs will not be zero. Also, we've already handled the input vectors being zero so the
763 // crossProduct vector should also not be zero.
764 rotBetween.x = rotBetween.x / mag;
765 rotBetween.y = rotBetween.y / mag;
766 rotBetween.z = rotBetween.z / mag;
767 rotBetween.s = rotBetween.s / mag;
768 // Check for undefined values and set zero rotation if any found. This code might not actually be required
769 // any longer since zero vectors are checked for at the top.
770 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
771 {
772 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
773 }
774 }
775 } 894 }
776 return rotBetween;
777 } 895 }
778 896
779 public void llWhisper(int channelID, string text) 897 public void llWhisper(int channelID, string text)
780 { 898 {
781 m_host.AddScriptLPS(1); 899 m_host.AddScriptLPS(1);
@@ -791,10 +909,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
791 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 909 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
792 } 910 }
793 911
912 private void CheckSayShoutTime()
913 {
914 DateTime now = DateTime.UtcNow;
915 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
916 {
917 m_lastSayShoutCheck = now;
918 m_SayShoutCount = 0;
919 }
920 else
921 m_SayShoutCount++;
922 }
923
794 public void llSay(int channelID, string text) 924 public void llSay(int channelID, string text)
795 { 925 {
796 m_host.AddScriptLPS(1); 926 m_host.AddScriptLPS(1);
797 927
928 if (channelID == 0)
929// m_SayShoutCount++;
930 CheckSayShoutTime();
931
932 if (m_SayShoutCount >= 11)
933 ScriptSleep(2000);
934
798 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 935 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
799 { 936 {
800 Console.WriteLine(text); 937 Console.WriteLine(text);
@@ -817,6 +954,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
817 { 954 {
818 m_host.AddScriptLPS(1); 955 m_host.AddScriptLPS(1);
819 956
957 if (channelID == 0)
958// m_SayShoutCount++;
959 CheckSayShoutTime();
960
961 if (m_SayShoutCount >= 11)
962 ScriptSleep(2000);
963
820 if (text.Length > 1023) 964 if (text.Length > 1023)
821 text = text.Substring(0, 1023); 965 text = text.Substring(0, 1023);
822 966
@@ -848,22 +992,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
848 992
849 public void llRegionSayTo(string target, int channel, string msg) 993 public void llRegionSayTo(string target, int channel, string msg)
850 { 994 {
995 string error = String.Empty;
996
851 if (msg.Length > 1023) 997 if (msg.Length > 1023)
852 msg = msg.Substring(0, 1023); 998 msg = msg.Substring(0, 1023);
853 999
854 m_host.AddScriptLPS(1); 1000 m_host.AddScriptLPS(1);
855 1001
856 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
857 {
858 return;
859 }
860
861 UUID TargetID; 1002 UUID TargetID;
862 UUID.TryParse(target, out TargetID); 1003 UUID.TryParse(target, out TargetID);
863 1004
864 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 1005 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
865 if (wComm != null) 1006 if (wComm != null)
866 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 1007 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
1008 LSLError(error);
867 } 1009 }
868 1010
869 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 1011 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1119,10 +1261,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1119 return detectedParams.TouchUV; 1261 return detectedParams.TouchUV;
1120 } 1262 }
1121 1263
1264 [DebuggerNonUserCode]
1122 public virtual void llDie() 1265 public virtual void llDie()
1123 { 1266 {
1124 m_host.AddScriptLPS(1); 1267 m_host.AddScriptLPS(1);
1125 throw new SelfDeleteException(); 1268 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1126 } 1269 }
1127 1270
1128 public LSL_Float llGround(LSL_Vector offset) 1271 public LSL_Float llGround(LSL_Vector offset)
@@ -1193,6 +1336,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1193 1336
1194 public void llSetStatus(int status, int value) 1337 public void llSetStatus(int status, int value)
1195 { 1338 {
1339 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1340 return;
1196 m_host.AddScriptLPS(1); 1341 m_host.AddScriptLPS(1);
1197 1342
1198 int statusrotationaxis = 0; 1343 int statusrotationaxis = 0;
@@ -1216,6 +1361,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1216 if (!allow) 1361 if (!allow)
1217 return; 1362 return;
1218 1363
1364 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1365 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1366 return;
1367
1219 m_host.ScriptSetPhysicsStatus(true); 1368 m_host.ScriptSetPhysicsStatus(true);
1220 } 1369 }
1221 else 1370 else
@@ -1415,6 +1564,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1415 { 1564 {
1416 m_host.AddScriptLPS(1); 1565 m_host.AddScriptLPS(1);
1417 1566
1567 SetColor(m_host, color, face);
1568 }
1569
1570 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1571 {
1572 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1573 return;
1574
1575 Primitive.TextureEntry tex = part.Shape.Textures;
1576 Color4 texcolor;
1577 if (face >= 0 && face < GetNumberOfSides(part))
1578 {
1579 texcolor = tex.CreateFace((uint)face).RGBA;
1580 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1581 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1582 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1583 tex.FaceTextures[face].RGBA = texcolor;
1584 part.UpdateTextureEntry(tex.GetBytes());
1585 return;
1586 }
1587 else if (face == ScriptBaseClass.ALL_SIDES)
1588 {
1589 for (uint i = 0; i < GetNumberOfSides(part); i++)
1590 {
1591 if (tex.FaceTextures[i] != null)
1592 {
1593 texcolor = tex.FaceTextures[i].RGBA;
1594 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1595 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1596 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1597 tex.FaceTextures[i].RGBA = texcolor;
1598 }
1599 texcolor = tex.DefaultTexture.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.DefaultTexture.RGBA = texcolor;
1604 }
1605 part.UpdateTextureEntry(tex.GetBytes());
1606 return;
1607 }
1608
1418 if (face == ScriptBaseClass.ALL_SIDES) 1609 if (face == ScriptBaseClass.ALL_SIDES)
1419 face = SceneObjectPart.ALL_SIDES; 1610 face = SceneObjectPart.ALL_SIDES;
1420 1611
@@ -1423,6 +1614,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1423 1614
1424 public void SetTexGen(SceneObjectPart part, int face,int style) 1615 public void SetTexGen(SceneObjectPart part, int face,int style)
1425 { 1616 {
1617 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1618 return;
1619
1426 Primitive.TextureEntry tex = part.Shape.Textures; 1620 Primitive.TextureEntry tex = part.Shape.Textures;
1427 MappingType textype; 1621 MappingType textype;
1428 textype = MappingType.Default; 1622 textype = MappingType.Default;
@@ -1453,6 +1647,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1453 1647
1454 public void SetGlow(SceneObjectPart part, int face, float glow) 1648 public void SetGlow(SceneObjectPart part, int face, float glow)
1455 { 1649 {
1650 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1651 return;
1652
1456 Primitive.TextureEntry tex = part.Shape.Textures; 1653 Primitive.TextureEntry tex = part.Shape.Textures;
1457 if (face >= 0 && face < GetNumberOfSides(part)) 1654 if (face >= 0 && face < GetNumberOfSides(part))
1458 { 1655 {
@@ -1478,6 +1675,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1478 1675
1479 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1676 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1480 { 1677 {
1678 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1679 return;
1481 1680
1482 Shininess sval = new Shininess(); 1681 Shininess sval = new Shininess();
1483 1682
@@ -1528,6 +1727,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1528 1727
1529 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1728 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1530 { 1729 {
1730 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1731 return;
1732
1531 Primitive.TextureEntry tex = part.Shape.Textures; 1733 Primitive.TextureEntry tex = part.Shape.Textures;
1532 if (face >= 0 && face < GetNumberOfSides(part)) 1734 if (face >= 0 && face < GetNumberOfSides(part))
1533 { 1735 {
@@ -1588,13 +1790,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1588 m_host.AddScriptLPS(1); 1790 m_host.AddScriptLPS(1);
1589 1791
1590 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1792 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1591 1793 if (parts.Count > 0)
1592 foreach (SceneObjectPart part in parts) 1794 {
1593 SetAlpha(part, alpha, face); 1795 try
1796 {
1797 foreach (SceneObjectPart part in parts)
1798 SetAlpha(part, alpha, face);
1799 }
1800 finally
1801 {
1802 }
1803 }
1594 } 1804 }
1595 1805
1596 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1806 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1597 { 1807 {
1808 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1809 return;
1810
1598 Primitive.TextureEntry tex = part.Shape.Textures; 1811 Primitive.TextureEntry tex = part.Shape.Textures;
1599 Color4 texcolor; 1812 Color4 texcolor;
1600 if (face >= 0 && face < GetNumberOfSides(part)) 1813 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1647,7 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1647 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1860 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1648 float wind, float tension, LSL_Vector Force) 1861 float wind, float tension, LSL_Vector Force)
1649 { 1862 {
1650 if (part == null) 1863 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1651 return; 1864 return;
1652 1865
1653 if (flexi) 1866 if (flexi)
@@ -1681,7 +1894,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1681 /// <param name="falloff"></param> 1894 /// <param name="falloff"></param>
1682 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1895 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1683 { 1896 {
1684 if (part == null) 1897 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1685 return; 1898 return;
1686 1899
1687 if (light) 1900 if (light)
@@ -1714,11 +1927,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1714 Primitive.TextureEntry tex = part.Shape.Textures; 1927 Primitive.TextureEntry tex = part.Shape.Textures;
1715 Color4 texcolor; 1928 Color4 texcolor;
1716 LSL_Vector rgb = new LSL_Vector(); 1929 LSL_Vector rgb = new LSL_Vector();
1930 int nsides = GetNumberOfSides(part);
1931
1717 if (face == ScriptBaseClass.ALL_SIDES) 1932 if (face == ScriptBaseClass.ALL_SIDES)
1718 { 1933 {
1719 int i; 1934 int i;
1720 1935 for (i = 0; i < nsides; i++)
1721 for (i = 0 ; i < GetNumberOfSides(part); i++)
1722 { 1936 {
1723 texcolor = tex.GetFace((uint)i).RGBA; 1937 texcolor = tex.GetFace((uint)i).RGBA;
1724 rgb.x += texcolor.R; 1938 rgb.x += texcolor.R;
@@ -1726,14 +1940,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1726 rgb.z += texcolor.B; 1940 rgb.z += texcolor.B;
1727 } 1941 }
1728 1942
1729 rgb.x /= (float)GetNumberOfSides(part); 1943 float invnsides = 1.0f / (float)nsides;
1730 rgb.y /= (float)GetNumberOfSides(part); 1944
1731 rgb.z /= (float)GetNumberOfSides(part); 1945 rgb.x *= invnsides;
1946 rgb.y *= invnsides;
1947 rgb.z *= invnsides;
1732 1948
1733 return rgb; 1949 return rgb;
1734 } 1950 }
1735 1951 if (face >= 0 && face < nsides)
1736 if (face >= 0 && face < GetNumberOfSides(part))
1737 { 1952 {
1738 texcolor = tex.GetFace((uint)face).RGBA; 1953 texcolor = tex.GetFace((uint)face).RGBA;
1739 rgb.x = texcolor.R; 1954 rgb.x = texcolor.R;
@@ -1760,15 +1975,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1760 m_host.AddScriptLPS(1); 1975 m_host.AddScriptLPS(1);
1761 1976
1762 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1977 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1763 1978 if (parts.Count > 0)
1764 foreach (SceneObjectPart part in parts) 1979 {
1765 SetTexture(part, texture, face); 1980 try
1766 1981 {
1982 foreach (SceneObjectPart part in parts)
1983 SetTexture(part, texture, face);
1984 }
1985 finally
1986 {
1987 }
1988 }
1767 ScriptSleep(200); 1989 ScriptSleep(200);
1768 } 1990 }
1769 1991
1770 protected void SetTexture(SceneObjectPart part, string texture, int face) 1992 protected void SetTexture(SceneObjectPart part, string texture, int face)
1771 { 1993 {
1994 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1995 return;
1996
1772 UUID textureID = new UUID(); 1997 UUID textureID = new UUID();
1773 1998
1774 textureID = InventoryKey(texture, (int)AssetType.Texture); 1999 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1813,6 +2038,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 2038
1814 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2039 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2040 {
2041 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2042 return;
2043
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2044 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2045 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2046 {
@@ -1849,6 +2077,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2077
1850 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2078 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1851 { 2079 {
2080 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2081 return;
2082
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2083 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2084 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2085 {
@@ -1885,6 +2116,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1885 2116
1886 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2117 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1887 { 2118 {
2119 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2120 return;
2121
1888 Primitive.TextureEntry tex = part.Shape.Textures; 2122 Primitive.TextureEntry tex = part.Shape.Textures;
1889 if (face >= 0 && face < GetNumberOfSides(part)) 2123 if (face >= 0 && face < GetNumberOfSides(part))
1890 { 2124 {
@@ -2055,24 +2289,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2055 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param> 2289 /// <param name="adjust">if TRUE, will cap the distance to 10m.</param>
2056 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust) 2290 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos, bool adjust)
2057 { 2291 {
2058 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2292 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2293 return;
2294
2059 LSL_Vector currentPos = GetPartLocalPos(part); 2295 LSL_Vector currentPos = GetPartLocalPos(part);
2296 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
2060 2297
2061 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
2062 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
2063 2298
2064 if (part.ParentGroup.RootPart == part) 2299 if (part.ParentGroup.RootPart == part)
2065 { 2300 {
2066 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
2067 targetPos.z = ground;
2068 SceneObjectGroup parent = part.ParentGroup; 2301 SceneObjectGroup parent = part.ParentGroup;
2069 parent.UpdateGroupPosition(!adjust ? targetPos : 2302 if (!World.Permissions.CanObjectEntry(parent.UUID, false, (Vector3)toPos))
2070 SetPosAdjust(currentPos, targetPos)); 2303 return;
2304 Util.FireAndForget(delegate(object x) {
2305 parent.UpdateGroupPosition((Vector3)toPos);
2306 });
2071 } 2307 }
2072 else 2308 else
2073 { 2309 {
2074 part.OffsetPosition = !adjust ? targetPos : 2310 part.OffsetPosition = (Vector3)toPos;
2075 SetPosAdjust(currentPos, targetPos);
2076 SceneObjectGroup parent = part.ParentGroup; 2311 SceneObjectGroup parent = part.ParentGroup;
2077 parent.HasGroupChanged = true; 2312 parent.HasGroupChanged = true;
2078 parent.ScheduleGroupForTerseUpdate(); 2313 parent.ScheduleGroupForTerseUpdate();
@@ -2104,13 +2339,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2104 else 2339 else
2105 { 2340 {
2106 if (part.ParentGroup.IsAttachment) 2341 if (part.ParentGroup.IsAttachment)
2107 {
2108 pos = part.AttachedPos; 2342 pos = part.AttachedPos;
2109 }
2110 else 2343 else
2111 {
2112 pos = part.AbsolutePosition; 2344 pos = part.AbsolutePosition;
2113 }
2114 } 2345 }
2115 2346
2116// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos); 2347// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
@@ -2150,25 +2381,46 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2150 2381
2151 protected void SetRot(SceneObjectPart part, Quaternion rot) 2382 protected void SetRot(SceneObjectPart part, Quaternion rot)
2152 { 2383 {
2153 part.UpdateRotation(rot); 2384 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2154 // Update rotation does not move the object in the physics scene if it's a linkset. 2385 return;
2155 2386
2156//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2387 bool isroot = (part == part.ParentGroup.RootPart);
2157// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2388 bool isphys;
2158 2389
2159 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2160 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2161 // It's perfectly okay when the object is not an active physical body though.
2162 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2163 // but only if the object is not physial and active. This is important for rotating doors.
2164 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2165 // scene
2166 PhysicsActor pa = part.PhysActor; 2390 PhysicsActor pa = part.PhysActor;
2167 2391
2168 if (pa != null && !pa.IsPhysical) 2392 // keep using physactor ideia of isphysical
2393 // it should be SOP ideia of that
2394 // not much of a issue with ubitODE
2395 if (pa != null && pa.IsPhysical)
2396 isphys = true;
2397 else
2398 isphys = false;
2399
2400 // SL doesn't let scripts rotate root of physical linksets
2401 if (isroot && isphys)
2402 return;
2403
2404 part.UpdateRotation(rot);
2405
2406 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2407 // so do a nasty update of parts positions if is a root part rotation
2408 if (isroot && pa != null) // with if above implies non physical root part
2169 { 2409 {
2170 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2410 part.ParentGroup.ResetChildPrimPhysicsPositions();
2171 } 2411 }
2412 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2413 {
2414 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2415 if (sittingavas.Count > 0)
2416 {
2417 foreach (ScenePresence av in sittingavas)
2418 {
2419 if (isroot || part.LocalId == av.ParentID)
2420 av.SendTerseUpdateToAllClients();
2421 }
2422 }
2423 }
2172 } 2424 }
2173 2425
2174 /// <summary> 2426 /// <summary>
@@ -2216,8 +2468,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2216 2468
2217 public LSL_Rotation llGetLocalRot() 2469 public LSL_Rotation llGetLocalRot()
2218 { 2470 {
2471 return GetPartLocalRot(m_host);
2472 }
2473
2474 private LSL_Rotation GetPartLocalRot(SceneObjectPart part)
2475 {
2219 m_host.AddScriptLPS(1); 2476 m_host.AddScriptLPS(1);
2220 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2477 Quaternion rot = part.RotationOffset;
2478 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2221 } 2479 }
2222 2480
2223 public void llSetForce(LSL_Vector force, int local) 2481 public void llSetForce(LSL_Vector force, int local)
@@ -2297,16 +2555,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2297 m_host.ApplyImpulse(v, local != 0); 2555 m_host.ApplyImpulse(v, local != 0);
2298 } 2556 }
2299 2557
2558
2300 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2559 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2301 { 2560 {
2302 m_host.AddScriptLPS(1); 2561 m_host.AddScriptLPS(1);
2303 m_host.ApplyAngularImpulse(force, local != 0); 2562 m_host.ParentGroup.RootPart.ApplyAngularImpulse(force, local != 0);
2304 } 2563 }
2305 2564
2306 public void llSetTorque(LSL_Vector torque, int local) 2565 public void llSetTorque(LSL_Vector torque, int local)
2307 { 2566 {
2308 m_host.AddScriptLPS(1); 2567 m_host.AddScriptLPS(1);
2309 m_host.SetAngularImpulse(torque, local != 0); 2568 m_host.ParentGroup.RootPart.SetAngularImpulse(torque, local != 0);
2310 } 2569 }
2311 2570
2312 public LSL_Vector llGetTorque() 2571 public LSL_Vector llGetTorque()
@@ -2323,20 +2582,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2323 llSetTorque(torque, local); 2582 llSetTorque(torque, local);
2324 } 2583 }
2325 2584
2585 public void llSetVelocity(LSL_Vector vel, int local)
2586 {
2587 m_host.AddScriptLPS(1);
2588 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2589 }
2590
2326 public LSL_Vector llGetVel() 2591 public LSL_Vector llGetVel()
2327 { 2592 {
2328 m_host.AddScriptLPS(1); 2593 m_host.AddScriptLPS(1);
2329 2594
2330 Vector3 vel; 2595 Vector3 vel = Vector3.Zero;
2331 2596
2332 if (m_host.ParentGroup.IsAttachment) 2597 if (m_host.ParentGroup.IsAttachment)
2333 { 2598 {
2334 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2599 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2335 vel = avatar.Velocity; 2600 if (avatar != null)
2601 vel = avatar.Velocity;
2336 } 2602 }
2337 else 2603 else
2338 { 2604 {
2339 vel = m_host.Velocity; 2605 vel = m_host.ParentGroup.RootPart.Velocity;
2340 } 2606 }
2341 2607
2342 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2608 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2348,10 +2614,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2348 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2614 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2349 } 2615 }
2350 2616
2617 public void llSetAngularVelocity(LSL_Vector avel, int local)
2618 {
2619 m_host.AddScriptLPS(1);
2620 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2621 }
2622
2351 public LSL_Vector llGetOmega() 2623 public LSL_Vector llGetOmega()
2352 { 2624 {
2353 m_host.AddScriptLPS(1); 2625 m_host.AddScriptLPS(1);
2354 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2626 Vector3 avel = m_host.AngularVelocity;
2627 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2355 } 2628 }
2356 2629
2357 public LSL_Float llGetTimeOfDay() 2630 public LSL_Float llGetTimeOfDay()
@@ -2824,16 +3097,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2824 new_group.RootPart.UUID.ToString()) }, 3097 new_group.RootPart.UUID.ToString()) },
2825 new DetectParams[0])); 3098 new DetectParams[0]));
2826 3099
2827 float groupmass = new_group.GetMass(); 3100 // do recoil
3101 SceneObjectGroup hostgrp = m_host.ParentGroup;
3102 if (hostgrp == null)
3103 return;
3104
3105 if (hostgrp.IsAttachment) // don't recoil avatars
3106 return;
2828 3107
2829 PhysicsActor pa = new_group.RootPart.PhysActor; 3108 PhysicsActor pa = new_group.RootPart.PhysActor;
2830 3109
2831 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) 3110 if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero)
2832 { 3111 {
2833 //Recoil. 3112 float groupmass = new_group.GetMass();
2834 llApplyImpulse(vel * groupmass, 0); 3113 vel *= -groupmass;
3114 llApplyImpulse(vel, 0);
2835 } 3115 }
2836 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3116 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3117 return;
3118
2837 }); 3119 });
2838 3120
2839 //ScriptSleep((int)((groupmass * velmag) / 10)); 3121 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2848,35 +3130,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2848 public void llLookAt(LSL_Vector target, double strength, double damping) 3130 public void llLookAt(LSL_Vector target, double strength, double damping)
2849 { 3131 {
2850 m_host.AddScriptLPS(1); 3132 m_host.AddScriptLPS(1);
2851 // Determine where we are looking from
2852 LSL_Vector from = llGetPos();
2853 3133
2854 // Work out the normalised vector from the source to the target 3134 // Get the normalized vector to the target
2855 LSL_Vector delta = llVecNorm(target - from); 3135 LSL_Vector d1 = llVecNorm(target - llGetPos());
2856 LSL_Vector angle = new LSL_Vector(0,0,0);
2857 3136
2858 // Calculate the yaw 3137 // Get the bearing (yaw)
2859 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3138 LSL_Vector a1 = new LSL_Vector(0,0,0);
2860 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3139 a1.z = llAtan2(d1.y, d1.x);
2861 3140
2862 // Calculate pitch 3141 // Get the elevation (pitch)
2863 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3142 LSL_Vector a2 = new LSL_Vector(0,0,0);
3143 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2864 3144
2865 // we need to convert from a vector describing 3145 LSL_Rotation r1 = llEuler2Rot(a1);
2866 // the angles of rotation in radians into rotation value 3146 LSL_Rotation r2 = llEuler2Rot(a2);
2867 LSL_Rotation rot = llEuler2Rot(angle); 3147 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2868
2869 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2870 // set the rotation of the object, copy that behavior
2871 PhysicsActor pa = m_host.PhysActor;
2872 3148
2873 if (strength == 0 || pa == null || !pa.IsPhysical) 3149 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2874 { 3150 {
2875 llSetRot(rot); 3151 // Do nothing if either value is 0 (this has been checked in SL)
3152 if (strength <= 0.0 || damping <= 0.0)
3153 return;
3154
3155 llSetRot(r3 * r2 * r1);
2876 } 3156 }
2877 else 3157 else
2878 { 3158 {
2879 m_host.StartLookAt(rot, (float)strength, (float)damping); 3159 if (strength == 0)
3160 {
3161 llSetRot(r3 * r2 * r1);
3162 return;
3163 }
3164
3165 m_host.StartLookAt((Quaternion)(r3 * r2 * r1), (float)strength, (float)damping);
2880 } 3166 }
2881 } 3167 }
2882 3168
@@ -2922,17 +3208,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2922 } 3208 }
2923 else 3209 else
2924 { 3210 {
2925 if (m_host.IsRoot) 3211 // new SL always returns object mass
2926 { 3212// if (m_host.IsRoot)
3213// {
2927 return m_host.ParentGroup.GetMass(); 3214 return m_host.ParentGroup.GetMass();
2928 } 3215// }
2929 else 3216// else
2930 { 3217// {
2931 return m_host.GetMass(); 3218// return m_host.GetMass();
2932 } 3219// }
2933 } 3220 }
2934 } 3221 }
2935 3222
3223
3224 public LSL_Float llGetMassMKS()
3225 {
3226 return 100f * llGetMass();
3227 }
3228
2936 public void llCollisionFilter(string name, string id, int accept) 3229 public void llCollisionFilter(string name, string id, int accept)
2937 { 3230 {
2938 m_host.AddScriptLPS(1); 3231 m_host.AddScriptLPS(1);
@@ -2980,8 +3273,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2980 { 3273 {
2981 // Unregister controls from Presence 3274 // Unregister controls from Presence
2982 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID); 3275 presence.UnRegisterControlEventsToScript(m_host.LocalId, m_item.ItemID);
2983 // Remove Take Control permission.
2984 m_item.PermsMask &= ~ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
2985 } 3276 }
2986 } 3277 }
2987 } 3278 }
@@ -3007,7 +3298,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3007 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3298 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
3008 3299
3009 if (attachmentsModule != null) 3300 if (attachmentsModule != null)
3010 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, false); 3301 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true, false);
3011 else 3302 else
3012 return false; 3303 return false;
3013 } 3304 }
@@ -3037,9 +3328,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3037 { 3328 {
3038 m_host.AddScriptLPS(1); 3329 m_host.AddScriptLPS(1);
3039 3330
3040// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3041// return;
3042
3043 if (m_item.PermsGranter != m_host.OwnerID) 3331 if (m_item.PermsGranter != m_host.OwnerID)
3044 return; 3332 return;
3045 3333
@@ -3082,6 +3370,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3082 3370
3083 public void llInstantMessage(string user, string message) 3371 public void llInstantMessage(string user, string message)
3084 { 3372 {
3373 UUID result;
3374 if (!UUID.TryParse(user, out result) || result == UUID.Zero)
3375 {
3376 ShoutError("An invalid key was passed to llInstantMessage");
3377 ScriptSleep(2000);
3378 return;
3379 }
3380
3381
3085 m_host.AddScriptLPS(1); 3382 m_host.AddScriptLPS(1);
3086 3383
3087 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3384 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3096,14 +3393,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3096 UUID friendTransactionID = UUID.Random(); 3393 UUID friendTransactionID = UUID.Random();
3097 3394
3098 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3395 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3099 3396
3100 GridInstantMessage msg = new GridInstantMessage(); 3397 GridInstantMessage msg = new GridInstantMessage();
3101 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3398 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3102 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3399 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3103 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3400 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3104// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3401// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3105// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3402// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3106 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3403// DateTime dt = DateTime.UtcNow;
3404//
3405// // Ticks from UtcNow, but make it look like local. Evil, huh?
3406// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3407//
3408// try
3409// {
3410// // Convert that to the PST timezone
3411// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3412// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3413// }
3414// catch
3415// {
3416// // No logging here, as it could be VERY spammy
3417// }
3418//
3419// // And make it look local again to fool the unix time util
3420// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3421
3422 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3423
3107 //if (client != null) 3424 //if (client != null)
3108 //{ 3425 //{
3109 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3426 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3117,12 +3434,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3117 msg.message = message.Substring(0, 1024); 3434 msg.message = message.Substring(0, 1024);
3118 else 3435 else
3119 msg.message = message; 3436 msg.message = message;
3120 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3437 msg.dialog = (byte)19; // MessageFromObject
3121 msg.fromGroup = false;// fromGroup; 3438 msg.fromGroup = false;// fromGroup;
3122 msg.offline = (byte)0; //offline; 3439 msg.offline = (byte)0; //offline;
3123 msg.ParentEstateID = 0; //ParentEstateID; 3440 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3124 msg.Position = new Vector3(m_host.AbsolutePosition); 3441 msg.Position = new Vector3(m_host.AbsolutePosition);
3125 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3442 msg.RegionID = World.RegionInfo.RegionID.Guid;
3126 msg.binaryBucket 3443 msg.binaryBucket
3127 = Util.StringToBytes256( 3444 = Util.StringToBytes256(
3128 "{0}/{1}/{2}/{3}", 3445 "{0}/{1}/{2}/{3}",
@@ -3150,7 +3467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3150 } 3467 }
3151 3468
3152 emailModule.SendEmail(m_host.UUID, address, subject, message); 3469 emailModule.SendEmail(m_host.UUID, address, subject, message);
3153 llSleep(EMAIL_PAUSE_TIME); 3470 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3154 } 3471 }
3155 3472
3156 public void llGetNextEmail(string address, string subject) 3473 public void llGetNextEmail(string address, string subject)
@@ -3396,7 +3713,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3396 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3713 implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3397 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3714 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3398 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3715 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3716 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3399 ScriptBaseClass.PERMISSION_ATTACH; 3717 ScriptBaseClass.PERMISSION_ATTACH;
3718
3400 } 3719 }
3401 else 3720 else
3402 { 3721 {
@@ -3427,15 +3746,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3427 if (World.GetExtraSetting("auto_grant_attach_perms") == "true") 3746 if (World.GetExtraSetting("auto_grant_attach_perms") == "true")
3428 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH; 3747 implicitPerms = ScriptBaseClass.PERMISSION_ATTACH;
3429 } 3748 }
3749 if (World.GetExtraSetting("auto_grant_all_perms") == "true")
3750 {
3751 implicitPerms = perm;
3752 }
3430 } 3753 }
3431 3754
3432 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3755 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3433 { 3756 {
3434 lock (m_host.TaskInventory) 3757 m_host.TaskInventory.LockItemsForWrite(true);
3435 { 3758 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3436 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3759 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3437 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3760 m_host.TaskInventory.LockItemsForWrite(false);
3438 }
3439 3761
3440 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3762 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3441 "run_time_permissions", new Object[] { 3763 "run_time_permissions", new Object[] {
@@ -3478,11 +3800,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3478 3800
3479 if (!m_waitingForScriptAnswer) 3801 if (!m_waitingForScriptAnswer)
3480 { 3802 {
3481 lock (m_host.TaskInventory) 3803 m_host.TaskInventory.LockItemsForWrite(true);
3482 { 3804 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3483 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3805 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3484 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3806 m_host.TaskInventory.LockItemsForWrite(false);
3485 }
3486 3807
3487 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3808 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3488 m_waitingForScriptAnswer=true; 3809 m_waitingForScriptAnswer=true;
@@ -3511,14 +3832,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3511 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3832 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3512 llReleaseControls(); 3833 llReleaseControls();
3513 3834
3514 lock (m_host.TaskInventory) 3835 m_host.TaskInventory.LockItemsForWrite(true);
3515 { 3836 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3516 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3837 m_host.TaskInventory.LockItemsForWrite(false);
3517 } 3838
3518 3839 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3519 m_ScriptEngine.PostScriptEvent( 3840 "run_time_permissions", new Object[] {
3520 m_item.ItemID, 3841 new LSL_Integer(answer) },
3521 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3842 new DetectParams[0]));
3522 } 3843 }
3523 3844
3524 public LSL_String llGetPermissionsKey() 3845 public LSL_String llGetPermissionsKey()
@@ -3557,14 +3878,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3557 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3878 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3558 { 3879 {
3559 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3880 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3560 3881 if (parts.Count > 0)
3561 foreach (SceneObjectPart part in parts) 3882 {
3562 part.SetFaceColorAlpha(face, color, null); 3883 try
3884 {
3885 foreach (SceneObjectPart part in parts)
3886 part.SetFaceColorAlpha(face, color, null);
3887 }
3888 finally
3889 {
3890 }
3891 }
3563 } 3892 }
3564 3893
3565 public void llCreateLink(string target, int parent) 3894 public void llCreateLink(string target, int parent)
3566 { 3895 {
3567 m_host.AddScriptLPS(1); 3896 m_host.AddScriptLPS(1);
3897
3568 UUID targetID; 3898 UUID targetID;
3569 3899
3570 if (!UUID.TryParse(target, out targetID)) 3900 if (!UUID.TryParse(target, out targetID))
@@ -3670,10 +4000,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3670 // Restructuring Multiple Prims. 4000 // Restructuring Multiple Prims.
3671 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4001 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3672 parts.Remove(parentPrim.RootPart); 4002 parts.Remove(parentPrim.RootPart);
3673 foreach (SceneObjectPart part in parts) 4003 if (parts.Count > 0)
3674 { 4004 {
3675 parentPrim.DelinkFromGroup(part.LocalId, true); 4005 try
4006 {
4007 foreach (SceneObjectPart part in parts)
4008 {
4009 parentPrim.DelinkFromGroup(part.LocalId, true);
4010 }
4011 }
4012 finally
4013 {
4014 }
3676 } 4015 }
4016
3677 parentPrim.HasGroupChanged = true; 4017 parentPrim.HasGroupChanged = true;
3678 parentPrim.ScheduleGroupForFullUpdate(); 4018 parentPrim.ScheduleGroupForFullUpdate();
3679 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4019 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3682,12 +4022,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3682 { 4022 {
3683 SceneObjectPart newRoot = parts[0]; 4023 SceneObjectPart newRoot = parts[0];
3684 parts.Remove(newRoot); 4024 parts.Remove(newRoot);
3685 foreach (SceneObjectPart part in parts) 4025
4026 try
3686 { 4027 {
3687 // Required for linking 4028 foreach (SceneObjectPart part in parts)
3688 part.ClearUpdateSchedule(); 4029 {
3689 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4030 part.ClearUpdateSchedule();
4031 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4032 }
3690 } 4033 }
4034 finally
4035 {
4036 }
4037
4038
3691 newRoot.ParentGroup.HasGroupChanged = true; 4039 newRoot.ParentGroup.HasGroupChanged = true;
3692 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4040 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3693 } 4041 }
@@ -3707,6 +4055,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3707 public void llBreakAllLinks() 4055 public void llBreakAllLinks()
3708 { 4056 {
3709 m_host.AddScriptLPS(1); 4057 m_host.AddScriptLPS(1);
4058
4059 TaskInventoryItem item = m_item;
4060
4061 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4062 && !m_automaticLinkPermission)
4063 {
4064 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4065 return;
4066 }
4067
3710 SceneObjectGroup parentPrim = m_host.ParentGroup; 4068 SceneObjectGroup parentPrim = m_host.ParentGroup;
3711 if (parentPrim.AttachmentPoint != 0) 4069 if (parentPrim.AttachmentPoint != 0)
3712 return; // Fail silently if attached 4070 return; // Fail silently if attached
@@ -3726,25 +4084,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3726 public LSL_String llGetLinkKey(int linknum) 4084 public LSL_String llGetLinkKey(int linknum)
3727 { 4085 {
3728 m_host.AddScriptLPS(1); 4086 m_host.AddScriptLPS(1);
3729 List<UUID> keytable = new List<UUID>();
3730 // parse for sitting avatare-uuids
3731 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3732 {
3733 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3734 keytable.Add(presence.UUID);
3735 });
3736
3737 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3738 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3739 {
3740 return keytable[totalprims - linknum].ToString();
3741 }
3742
3743 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3744 {
3745 return m_host.UUID.ToString();
3746 }
3747
3748 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4087 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3749 if (part != null) 4088 if (part != null)
3750 { 4089 {
@@ -3752,6 +4091,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3752 } 4091 }
3753 else 4092 else
3754 { 4093 {
4094 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4095 {
4096 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4097
4098 if (linknum < 0)
4099 return UUID.Zero.ToString();
4100
4101 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4102 if (avatars.Count > linknum)
4103 {
4104 return avatars[linknum].UUID.ToString();
4105 }
4106 }
3755 return UUID.Zero.ToString(); 4107 return UUID.Zero.ToString();
3756 } 4108 }
3757 } 4109 }
@@ -3861,17 +4213,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3861 m_host.AddScriptLPS(1); 4213 m_host.AddScriptLPS(1);
3862 int count = 0; 4214 int count = 0;
3863 4215
3864 lock (m_host.TaskInventory) 4216 m_host.TaskInventory.LockItemsForRead(true);
4217 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3865 { 4218 {
3866 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4219 if (inv.Value.Type == type || type == -1)
3867 { 4220 {
3868 if (inv.Value.Type == type || type == -1) 4221 count = count + 1;
3869 {
3870 count = count + 1;
3871 }
3872 } 4222 }
3873 } 4223 }
3874 4224
4225 m_host.TaskInventory.LockItemsForRead(false);
3875 return count; 4226 return count;
3876 } 4227 }
3877 4228
@@ -3880,16 +4231,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3880 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3881 ArrayList keys = new ArrayList(); 4232 ArrayList keys = new ArrayList();
3882 4233
3883 lock (m_host.TaskInventory) 4234 m_host.TaskInventory.LockItemsForRead(true);
4235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3884 { 4236 {
3885 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4237 if (inv.Value.Type == type || type == -1)
3886 { 4238 {
3887 if (inv.Value.Type == type || type == -1) 4239 keys.Add(inv.Value.Name);
3888 {
3889 keys.Add(inv.Value.Name);
3890 }
3891 } 4240 }
3892 } 4241 }
4242 m_host.TaskInventory.LockItemsForRead(false);
3893 4243
3894 if (keys.Count == 0) 4244 if (keys.Count == 0)
3895 { 4245 {
@@ -3927,7 +4277,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3927 if (item == null) 4277 if (item == null)
3928 { 4278 {
3929 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4279 llSay(0, String.Format("Could not find object '{0}'", inventory));
3930 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4280 return;
4281// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3931 } 4282 }
3932 4283
3933 UUID objId = item.ItemID; 4284 UUID objId = item.ItemID;
@@ -3955,33 +4306,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3955 return; 4306 return;
3956 } 4307 }
3957 } 4308 }
4309
3958 // destination is an avatar 4310 // destination is an avatar
3959 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4311 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3960 4312
3961 if (agentItem == null) 4313 if (agentItem == null)
3962 return; 4314 return;
3963 4315
3964 if (m_TransferModule != null) 4316 byte[] bucket = new byte[1];
3965 { 4317 bucket[0] = (byte)item.Type;
3966 byte[] bucket = new byte[1]; 4318 //byte[] objBytes = agentItem.ID.GetBytes();
3967 bucket[0] = (byte)item.Type; 4319 //Array.Copy(objBytes, 0, bucket, 1, 16);
3968 4320
3969 GridInstantMessage msg = new GridInstantMessage(World, 4321 GridInstantMessage msg = new GridInstantMessage(World,
3970 m_host.OwnerID, m_host.Name, destId, 4322 m_host.OwnerID, m_host.Name, destId,
3971 (byte)InstantMessageDialog.TaskInventoryOffered, 4323 (byte)InstantMessageDialog.TaskInventoryOffered,
3972 false, item.Name+". "+m_host.Name+" is located at "+ 4324 false, item.Name+". "+m_host.Name+" is located at "+
3973 World.RegionInfo.RegionName+" "+ 4325 World.RegionInfo.RegionName+" "+
3974 m_host.AbsolutePosition.ToString(), 4326 m_host.AbsolutePosition.ToString(),
3975 agentItem.ID, true, m_host.AbsolutePosition, 4327 agentItem.ID, true, m_host.AbsolutePosition,
3976 bucket, true); 4328 bucket, true);
3977 4329
3978 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {}); 4330 ScenePresence sp;
3979 }
3980 4331
4332 if (World.TryGetScenePresence(destId, out sp))
4333 {
4334 sp.ControllingClient.SendInstantMessage(msg);
4335 }
4336 else
4337 {
4338 if (m_TransferModule != null)
4339 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4340 }
4341
4342 //This delay should only occur when giving inventory to avatars.
3981 ScriptSleep(3000); 4343 ScriptSleep(3000);
3982 } 4344 }
3983 } 4345 }
3984 4346
4347 [DebuggerNonUserCode]
3985 public void llRemoveInventory(string name) 4348 public void llRemoveInventory(string name)
3986 { 4349 {
3987 m_host.AddScriptLPS(1); 4350 m_host.AddScriptLPS(1);
@@ -4036,109 +4399,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4036 { 4399 {
4037 m_host.AddScriptLPS(1); 4400 m_host.AddScriptLPS(1);
4038 4401
4039 UUID uuid = (UUID)id; 4402 UUID uuid;
4040 PresenceInfo pinfo = null; 4403 if (UUID.TryParse(id, out uuid))
4041 UserAccount account;
4042
4043 UserInfoCacheEntry ce;
4044 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4045 { 4404 {
4046 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4405 PresenceInfo pinfo = null;
4047 if (account == null) 4406 UserAccount account;
4407
4408 UserInfoCacheEntry ce;
4409 if (!m_userInfoCache.TryGetValue(uuid, out ce))
4048 { 4410 {
4049 m_userInfoCache[uuid] = null; // Cache negative 4411 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
4050 return UUID.Zero.ToString(); 4412 if (account == null)
4051 } 4413 {
4414 m_userInfoCache[uuid] = null; // Cache negative
4415 return UUID.Zero.ToString();
4416 }
4052 4417
4053 4418
4054 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4419 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4055 if (pinfos != null && pinfos.Length > 0) 4420 if (pinfos != null && pinfos.Length > 0)
4056 {
4057 foreach (PresenceInfo p in pinfos)
4058 { 4421 {
4059 if (p.RegionID != UUID.Zero) 4422 foreach (PresenceInfo p in pinfos)
4060 { 4423 {
4061 pinfo = p; 4424 if (p.RegionID != UUID.Zero)
4425 {
4426 pinfo = p;
4427 }
4062 } 4428 }
4063 } 4429 }
4064 }
4065 4430
4066 ce = new UserInfoCacheEntry(); 4431 ce = new UserInfoCacheEntry();
4067 ce.time = Util.EnvironmentTickCount(); 4432 ce.time = Util.EnvironmentTickCount();
4068 ce.account = account; 4433 ce.account = account;
4069 ce.pinfo = pinfo; 4434 ce.pinfo = pinfo;
4070 } 4435 m_userInfoCache[uuid] = ce;
4071 else 4436 }
4072 { 4437 else
4073 if (ce == null) 4438 {
4074 return UUID.Zero.ToString(); 4439 if (ce == null)
4440 return UUID.Zero.ToString();
4075 4441
4076 account = ce.account; 4442 account = ce.account;
4077 pinfo = ce.pinfo; 4443 pinfo = ce.pinfo;
4078 } 4444 }
4079 4445
4080 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4446 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4081 {
4082 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4083 if (pinfos != null && pinfos.Length > 0)
4084 { 4447 {
4085 foreach (PresenceInfo p in pinfos) 4448 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4449 if (pinfos != null && pinfos.Length > 0)
4086 { 4450 {
4087 if (p.RegionID != UUID.Zero) 4451 foreach (PresenceInfo p in pinfos)
4088 { 4452 {
4089 pinfo = p; 4453 if (p.RegionID != UUID.Zero)
4454 {
4455 pinfo = p;
4456 }
4090 } 4457 }
4091 } 4458 }
4092 } 4459 else
4093 else 4460 pinfo = null;
4094 pinfo = null;
4095 4461
4096 ce.time = Util.EnvironmentTickCount(); 4462 ce.time = Util.EnvironmentTickCount();
4097 ce.pinfo = pinfo; 4463 ce.pinfo = pinfo;
4098 } 4464 }
4099 4465
4100 string reply = String.Empty; 4466 string reply = String.Empty;
4101 4467
4102 switch (data) 4468 switch (data)
4103 { 4469 {
4104 case 1: // DATA_ONLINE (0|1) 4470 case 1: // DATA_ONLINE (0|1)
4105 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4471 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4106 reply = "1"; 4472 reply = "1";
4107 else 4473 else
4108 reply = "0"; 4474 reply = "0";
4109 break; 4475 break;
4110 case 2: // DATA_NAME (First Last) 4476 case 2: // DATA_NAME (First Last)
4111 reply = account.FirstName + " " + account.LastName; 4477 reply = account.FirstName + " " + account.LastName;
4112 break; 4478 break;
4113 case 3: // DATA_BORN (YYYY-MM-DD) 4479 case 3: // DATA_BORN (YYYY-MM-DD)
4114 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4480 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4115 born = born.AddSeconds(account.Created); 4481 born = born.AddSeconds(account.Created);
4116 reply = born.ToString("yyyy-MM-dd"); 4482 reply = born.ToString("yyyy-MM-dd");
4117 break; 4483 break;
4118 case 4: // DATA_RATING (0,0,0,0,0,0) 4484 case 4: // DATA_RATING (0,0,0,0,0,0)
4119 reply = "0,0,0,0,0,0"; 4485 reply = "0,0,0,0,0,0";
4120 break; 4486 break;
4121 case 7: // DATA_USERLEVEL (integer) 4487 case 8: // DATA_PAYINFO (0|1|2|3)
4122 reply = account.UserLevel.ToString(); 4488 reply = "0";
4123 break; 4489 break;
4124 case 8: // DATA_PAYINFO (0|1|2|3) 4490 default:
4125 reply = "0"; 4491 return UUID.Zero.ToString(); // Raise no event
4126 break; 4492 }
4127 default:
4128 return UUID.Zero.ToString(); // Raise no event
4129 }
4130 4493
4131 UUID rq = UUID.Random(); 4494 UUID rq = UUID.Random();
4132 4495
4133 UUID tid = AsyncCommands. 4496 UUID tid = AsyncCommands.
4134 DataserverPlugin.RegisterRequest(m_host.LocalId, 4497 DataserverPlugin.RegisterRequest(m_host.LocalId,
4135 m_item.ItemID, rq.ToString()); 4498 m_item.ItemID, rq.ToString());
4136 4499
4137 AsyncCommands. 4500 AsyncCommands.
4138 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4501 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4139 4502
4140 ScriptSleep(100); 4503 ScriptSleep(100);
4141 return tid.ToString(); 4504 return tid.ToString();
4505 }
4506 else
4507 {
4508 ShoutError("Invalid UUID passed to llRequestAgentData.");
4509 }
4510 return "";
4142 } 4511 }
4143 4512
4144 public LSL_String llRequestInventoryData(string name) 4513 public LSL_String llRequestInventoryData(string name)
@@ -4195,13 +4564,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4195 if (UUID.TryParse(agent, out agentId)) 4564 if (UUID.TryParse(agent, out agentId))
4196 { 4565 {
4197 ScenePresence presence = World.GetScenePresence(agentId); 4566 ScenePresence presence = World.GetScenePresence(agentId);
4198 if (presence != null) 4567 if (presence != null && presence.PresenceType != PresenceType.Npc)
4199 { 4568 {
4569 // agent must not be a god
4570 if (presence.UserLevel >= 200) return;
4571
4200 // agent must be over the owners land 4572 // agent must be over the owners land
4201 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4573 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4202 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4574 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4203 { 4575 {
4204 World.TeleportClientHome(agentId, presence.ControllingClient); 4576 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4577 {
4578 // They can't be teleported home for some reason
4579 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4580 if (regionInfo != null)
4581 {
4582 World.RequestTeleportLocation(
4583 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4584 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4585 }
4586 }
4205 } 4587 }
4206 } 4588 }
4207 } 4589 }
@@ -4308,7 +4690,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4308 UUID av = new UUID(); 4690 UUID av = new UUID();
4309 if (!UUID.TryParse(agent,out av)) 4691 if (!UUID.TryParse(agent,out av))
4310 { 4692 {
4311 LSLError("First parameter to llDialog needs to be a key"); 4693 //LSLError("First parameter to llDialog needs to be a key");
4312 return; 4694 return;
4313 } 4695 }
4314 4696
@@ -4340,10 +4722,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4340 public void llCollisionSound(string impact_sound, double impact_volume) 4722 public void llCollisionSound(string impact_sound, double impact_volume)
4341 { 4723 {
4342 m_host.AddScriptLPS(1); 4724 m_host.AddScriptLPS(1);
4343 4725
4726 if(impact_sound == "")
4727 {
4728 m_host.CollisionSoundVolume = (float)impact_volume;
4729 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4730 m_host.CollisionSoundType = 0;
4731 return;
4732 }
4344 // TODO: Parameter check logic required. 4733 // TODO: Parameter check logic required.
4345 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound); 4734 m_host.CollisionSound = KeyOrName(impact_sound, AssetType.Sound);
4346 m_host.CollisionSoundVolume = (float)impact_volume; 4735 m_host.CollisionSoundVolume = (float)impact_volume;
4736 m_host.CollisionSoundType = 1;
4347 } 4737 }
4348 4738
4349 public LSL_String llGetAnimation(string id) 4739 public LSL_String llGetAnimation(string id)
@@ -4357,14 +4747,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4357 4747
4358 if (m_host.RegionHandle == presence.RegionHandle) 4748 if (m_host.RegionHandle == presence.RegionHandle)
4359 { 4749 {
4360 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4361
4362 if (presence != null) 4750 if (presence != null)
4363 { 4751 {
4364 AnimationSet currentAnims = presence.Animator.Animations; 4752 if (presence.SitGround)
4365 string currentAnimationState = String.Empty; 4753 return "Sitting on Ground";
4366 if (animationstateNames.TryGetValue(currentAnims.ImplicitDefaultAnimation.AnimID, out currentAnimationState)) 4754 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4367 return currentAnimationState; 4755 return "Sitting";
4756
4757 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4758 string lslMovementAnimation;
4759
4760 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4761 return lslMovementAnimation;
4368 } 4762 }
4369 } 4763 }
4370 4764
@@ -4511,7 +4905,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4511 { 4905 {
4512 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4906 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4513 float distance_term = distance * distance * distance; // Script Energy 4907 float distance_term = distance * distance * distance; // Script Energy
4514 float pusher_mass = m_host.GetMass(); 4908 // use total object mass and not part
4909 float pusher_mass = m_host.ParentGroup.GetMass();
4515 4910
4516 float PUSH_ATTENUATION_DISTANCE = 17f; 4911 float PUSH_ATTENUATION_DISTANCE = 17f;
4517 float PUSH_ATTENUATION_SCALE = 5f; 4912 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4761,6 +5156,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4761 { 5156 {
4762 return item.AssetID.ToString(); 5157 return item.AssetID.ToString();
4763 } 5158 }
5159 m_host.TaskInventory.LockItemsForRead(false);
4764 5160
4765 return UUID.Zero.ToString(); 5161 return UUID.Zero.ToString();
4766 } 5162 }
@@ -4894,7 +5290,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4894 public LSL_Vector llGetCenterOfMass() 5290 public LSL_Vector llGetCenterOfMass()
4895 { 5291 {
4896 m_host.AddScriptLPS(1); 5292 m_host.AddScriptLPS(1);
4897 Vector3 center = m_host.GetGeometricCenter(); 5293 Vector3 center = m_host.GetCenterOfMass();
4898 return new LSL_Vector(center.X,center.Y,center.Z); 5294 return new LSL_Vector(center.X,center.Y,center.Z);
4899 } 5295 }
4900 5296
@@ -4913,14 +5309,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4913 { 5309 {
4914 m_host.AddScriptLPS(1); 5310 m_host.AddScriptLPS(1);
4915 5311
4916 if (src == null) 5312 return src.Length;
4917 {
4918 return 0;
4919 }
4920 else
4921 {
4922 return src.Length;
4923 }
4924 } 5313 }
4925 5314
4926 public LSL_Integer llList2Integer(LSL_List src, int index) 5315 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4991,7 +5380,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4991 else if (src.Data[index] is LSL_Float) 5380 else if (src.Data[index] is LSL_Float)
4992 return Convert.ToDouble(((LSL_Float)src.Data[index]).value); 5381 return Convert.ToDouble(((LSL_Float)src.Data[index]).value);
4993 else if (src.Data[index] is LSL_String) 5382 else if (src.Data[index] is LSL_String)
4994 return Convert.ToDouble(((LSL_String)src.Data[index]).m_string); 5383 {
5384 string str = ((LSL_String) src.Data[index]).m_string;
5385 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5386 if (m != Match.Empty)
5387 {
5388 str = m.Value;
5389 double d = 0.0;
5390 if (!Double.TryParse(str, out d))
5391 return 0.0;
5392
5393 return d;
5394 }
5395 return 0.0;
5396 }
4995 return Convert.ToDouble(src.Data[index]); 5397 return Convert.ToDouble(src.Data[index]);
4996 } 5398 }
4997 catch (FormatException) 5399 catch (FormatException)
@@ -5033,7 +5435,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5033 // for completion and should LSL_Key ever be implemented 5435 // for completion and should LSL_Key ever be implemented
5034 // as it's own struct 5436 // as it's own struct
5035 else if (!(src.Data[index] is LSL_String || 5437 else if (!(src.Data[index] is LSL_String ||
5036 src.Data[index] is LSL_Key)) 5438 src.Data[index] is LSL_Key ||
5439 src.Data[index] is String))
5037 { 5440 {
5038 return ""; 5441 return "";
5039 } 5442 }
@@ -5291,7 +5694,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5291 } 5694 }
5292 } 5695 }
5293 } 5696 }
5294 else { 5697 else
5698 {
5295 object[] array = new object[src.Length]; 5699 object[] array = new object[src.Length];
5296 Array.Copy(src.Data, 0, array, 0, src.Length); 5700 Array.Copy(src.Data, 0, array, 0, src.Length);
5297 result = new LSL_List(array); 5701 result = new LSL_List(array);
@@ -5398,7 +5802,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5398 public LSL_Integer llGetRegionAgentCount() 5802 public LSL_Integer llGetRegionAgentCount()
5399 { 5803 {
5400 m_host.AddScriptLPS(1); 5804 m_host.AddScriptLPS(1);
5401 return new LSL_Integer(World.GetRootAgentCount()); 5805
5806 int count = 0;
5807 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5808 count++;
5809 });
5810
5811 return new LSL_Integer(count);
5402 } 5812 }
5403 5813
5404 public LSL_Vector llGetRegionCorner() 5814 public LSL_Vector llGetRegionCorner()
@@ -5639,6 +6049,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5639 flags |= ScriptBaseClass.AGENT_AWAY; 6049 flags |= ScriptBaseClass.AGENT_AWAY;
5640 } 6050 }
5641 6051
6052 UUID busy = new UUID("efcf670c-2d18-8128-973a-034ebc806b67");
6053 UUID[] anims = agent.Animator.GetAnimationArray();
6054 if (Array.Exists<UUID>(anims, a => { return a == busy; }))
6055 {
6056 flags |= ScriptBaseClass.AGENT_BUSY;
6057 }
6058
5642 // seems to get unset, even if in mouselook, when avatar is sitting on a prim??? 6059 // seems to get unset, even if in mouselook, when avatar is sitting on a prim???
5643 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0) 6060 if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
5644 { 6061 {
@@ -5686,6 +6103,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5686 flags |= ScriptBaseClass.AGENT_SITTING; 6103 flags |= ScriptBaseClass.AGENT_SITTING;
5687 } 6104 }
5688 6105
6106 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6107 {
6108 flags |= ScriptBaseClass.AGENT_MALE;
6109 }
6110
5689 return flags; 6111 return flags;
5690 } 6112 }
5691 6113
@@ -5833,9 +6255,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5833 6255
5834 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6256 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5835 6257
5836 foreach (SceneObjectPart part in parts) 6258 try
6259 {
6260 foreach (SceneObjectPart part in parts)
6261 {
6262 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6263 }
6264 }
6265 finally
5837 { 6266 {
5838 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
5839 } 6267 }
5840 } 6268 }
5841 6269
@@ -5889,13 +6317,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5889 6317
5890 if (m_host.OwnerID == land.LandData.OwnerID) 6318 if (m_host.OwnerID == land.LandData.OwnerID)
5891 { 6319 {
5892 World.TeleportClientHome(agentID, presence.ControllingClient); 6320 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6321 presence.TeleportWithMomentum(pos, null);
6322 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5893 } 6323 }
5894 } 6324 }
5895 } 6325 }
5896 ScriptSleep(5000); 6326 ScriptSleep(5000);
5897 } 6327 }
5898 6328
6329 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6330 {
6331 return ParseString2List(str, separators, in_spacers, false);
6332 }
6333
5899 public LSL_Integer llOverMyLand(string id) 6334 public LSL_Integer llOverMyLand(string id)
5900 { 6335 {
5901 m_host.AddScriptLPS(1); 6336 m_host.AddScriptLPS(1);
@@ -5954,20 +6389,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5954 return agentSize; 6389 return agentSize;
5955 } 6390 }
5956 6391
5957 public LSL_Integer llSameGroup(string agent) 6392 public LSL_Integer llSameGroup(string id)
5958 { 6393 {
5959 m_host.AddScriptLPS(1); 6394 m_host.AddScriptLPS(1);
5960 UUID agentId = new UUID(); 6395 UUID uuid = new UUID();
5961 if (!UUID.TryParse(agent, out agentId)) 6396 if (!UUID.TryParse(id, out uuid))
5962 return new LSL_Integer(0);
5963 ScenePresence presence = World.GetScenePresence(agentId);
5964 if (presence == null || presence.IsChildAgent) // Return flase for child agents
5965 return new LSL_Integer(0); 6397 return new LSL_Integer(0);
5966 IClientAPI client = presence.ControllingClient; 6398
5967 if (m_host.GroupID == client.ActiveGroupId) 6399 // Check if it's a group key
6400 if (uuid == m_host.ParentGroup.RootPart.GroupID)
5968 return new LSL_Integer(1); 6401 return new LSL_Integer(1);
5969 else 6402
6403 // We got passed a UUID.Zero
6404 if (uuid == UUID.Zero)
5970 return new LSL_Integer(0); 6405 return new LSL_Integer(0);
6406
6407 // Handle the case where id names an avatar
6408 ScenePresence presence = World.GetScenePresence(uuid);
6409 if (presence != null)
6410 {
6411 if (presence.IsChildAgent)
6412 return new LSL_Integer(0);
6413
6414 IClientAPI client = presence.ControllingClient;
6415 if (m_host.ParentGroup.RootPart.GroupID == client.ActiveGroupId)
6416 return new LSL_Integer(1);
6417
6418 return new LSL_Integer(0);
6419 }
6420
6421 // Handle object case
6422 SceneObjectPart part = World.GetSceneObjectPart(uuid);
6423 if (part != null)
6424 {
6425 // This will handle both deed and non-deed and also the no
6426 // group case
6427 if (part.ParentGroup.RootPart.GroupID == m_host.ParentGroup.RootPart.GroupID)
6428 return new LSL_Integer(1);
6429
6430 return new LSL_Integer(0);
6431 }
6432
6433 return new LSL_Integer(0);
5971 } 6434 }
5972 6435
5973 public void llUnSit(string id) 6436 public void llUnSit(string id)
@@ -6092,7 +6555,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6092 return m_host.ParentGroup.AttachmentPoint; 6555 return m_host.ParentGroup.AttachmentPoint;
6093 } 6556 }
6094 6557
6095 public LSL_Integer llGetFreeMemory() 6558 public virtual LSL_Integer llGetFreeMemory()
6096 { 6559 {
6097 m_host.AddScriptLPS(1); 6560 m_host.AddScriptLPS(1);
6098 // Make scripts designed for LSO happy 6561 // Make scripts designed for LSO happy
@@ -6209,7 +6672,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6209 SetParticleSystem(m_host, rules); 6672 SetParticleSystem(m_host, rules);
6210 } 6673 }
6211 6674
6212 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6675 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6676 {
6213 6677
6214 6678
6215 if (rules.Length == 0) 6679 if (rules.Length == 0)
@@ -6524,6 +6988,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6524 6988
6525 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot) 6989 protected void SitTarget(SceneObjectPart part, LSL_Vector offset, LSL_Rotation rot)
6526 { 6990 {
6991 // LSL quaternions can normalize to 0, normal Quaternions can't.
6992 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6993 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6994
6527 part.SitTargetPosition = offset; 6995 part.SitTargetPosition = offset;
6528 part.SitTargetOrientation = rot; 6996 part.SitTargetOrientation = rot;
6529 part.ParentGroup.HasGroupChanged = true; 6997 part.ParentGroup.HasGroupChanged = true;
@@ -6709,13 +7177,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6709 UUID av = new UUID(); 7177 UUID av = new UUID();
6710 if (!UUID.TryParse(avatar,out av)) 7178 if (!UUID.TryParse(avatar,out av))
6711 { 7179 {
6712 LSLError("First parameter to llDialog needs to be a key"); 7180 //LSLError("First parameter to llDialog needs to be a key");
6713 return; 7181 return;
6714 } 7182 }
6715 if (buttons.Length < 1) 7183 if (buttons.Length < 1)
6716 { 7184 {
6717 LSLError("No less than 1 button can be shown"); 7185 buttons.Add("OK");
6718 return;
6719 } 7186 }
6720 if (buttons.Length > 12) 7187 if (buttons.Length > 12)
6721 { 7188 {
@@ -6732,7 +7199,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6732 } 7199 }
6733 if (buttons.Data[i].ToString().Length > 24) 7200 if (buttons.Data[i].ToString().Length > 24)
6734 { 7201 {
6735 LSLError("button label cannot be longer than 24 characters"); 7202 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6736 return; 7203 return;
6737 } 7204 }
6738 buts[i] = buttons.Data[i].ToString(); 7205 buts[i] = buttons.Data[i].ToString();
@@ -6799,9 +7266,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6799 return; 7266 return;
6800 } 7267 }
6801 7268
6802 // the rest of the permission checks are done in RezScript, so check the pin there as well 7269 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6803 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7270 if (dest != null)
7271 {
7272 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7273 {
7274 // the rest of the permission checks are done in RezScript, so check the pin there as well
7275 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6804 7276
7277 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7278 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7279 }
7280 }
6805 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7281 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6806 ScriptSleep(3000); 7282 ScriptSleep(3000);
6807 } 7283 }
@@ -6864,19 +7340,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6864 public LSL_String llMD5String(string src, int nonce) 7340 public LSL_String llMD5String(string src, int nonce)
6865 { 7341 {
6866 m_host.AddScriptLPS(1); 7342 m_host.AddScriptLPS(1);
6867 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7343 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6868 } 7344 }
6869 7345
6870 public LSL_String llSHA1String(string src) 7346 public LSL_String llSHA1String(string src)
6871 { 7347 {
6872 m_host.AddScriptLPS(1); 7348 m_host.AddScriptLPS(1);
6873 return Util.SHA1Hash(src).ToLower(); 7349 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6874 } 7350 }
6875 7351
6876 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7352 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6877 { 7353 {
6878 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7354 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6879 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7355 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7356 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7357 return shapeBlock;
6880 7358
6881 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7359 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6882 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7360 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6981,6 +7459,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6981 // Prim type box, cylinder and prism. 7459 // Prim type box, cylinder and prism.
6982 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) 7460 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)
6983 { 7461 {
7462 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7463 return;
7464
6984 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7465 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6985 ObjectShapePacket.ObjectDataBlock shapeBlock; 7466 ObjectShapePacket.ObjectDataBlock shapeBlock;
6986 7467
@@ -7034,6 +7515,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7034 // Prim type sphere. 7515 // Prim type sphere.
7035 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7516 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
7036 { 7517 {
7518 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7519 return;
7520
7037 ObjectShapePacket.ObjectDataBlock shapeBlock; 7521 ObjectShapePacket.ObjectDataBlock shapeBlock;
7038 7522
7039 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7523 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -7075,6 +7559,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7075 // Prim type torus, tube and ring. 7559 // Prim type torus, tube and ring.
7076 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) 7560 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)
7077 { 7561 {
7562 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7563 return;
7564
7078 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7565 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
7079 ObjectShapePacket.ObjectDataBlock shapeBlock; 7566 ObjectShapePacket.ObjectDataBlock shapeBlock;
7080 7567
@@ -7210,6 +7697,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7210 // Prim type sculpt. 7697 // Prim type sculpt.
7211 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7698 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7212 { 7699 {
7700 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7701 return;
7702
7213 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7703 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7214 UUID sculptId; 7704 UUID sculptId;
7215 7705
@@ -7234,7 +7724,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7234 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7724 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7235 { 7725 {
7236 // default 7726 // default
7237 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7727 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7238 } 7728 }
7239 7729
7240 part.Shape.SetSculptProperties((byte)type, sculptId); 7730 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7251,48 +7741,132 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7251 ScriptSleep(200); 7741 ScriptSleep(200);
7252 } 7742 }
7253 7743
7254 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7744 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7255 { 7745 {
7256 m_host.AddScriptLPS(1); 7746 m_host.AddScriptLPS(1);
7257 7747
7258 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams"); 7748 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast");
7259 7749
7260 ScriptSleep(200); 7750 ScriptSleep(200);
7261 } 7751 }
7262 7752
7263 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7753 private void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
7264 { 7754 {
7265 m_host.AddScriptLPS(1); 7755 List<object> parts = new List<object>();
7756 List<SceneObjectPart> prims = GetLinkParts(linknumber);
7757 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7758 foreach (SceneObjectPart p in prims)
7759 parts.Add(p);
7760 foreach (ScenePresence p in avatars)
7761 parts.Add(p);
7266 7762
7267 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParamsFast"); 7763 LSL_List remaining = null;
7764 uint rulesParsed = 0;
7765
7766 if (parts.Count > 0)
7767 {
7768 foreach (object part in parts)
7769 {
7770 if (part is SceneObjectPart)
7771 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7772 else
7773 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7774 }
7775
7776 while ((object)remaining != null && remaining.Length > 2)
7777 {
7778 linknumber = remaining.GetLSLIntegerItem(0);
7779 rules = remaining.GetSublist(1, -1);
7780 parts.Clear();
7781 prims = GetLinkParts(linknumber);
7782 avatars = GetLinkAvatars(linknumber);
7783 foreach (SceneObjectPart p in prims)
7784 parts.Add(p);
7785 foreach (ScenePresence p in avatars)
7786 parts.Add(p);
7787
7788 remaining = null;
7789 foreach (object part in parts)
7790 {
7791 if (part is SceneObjectPart)
7792 remaining = SetPrimParams((SceneObjectPart)part, rules, originFunc, ref rulesParsed);
7793 else
7794 remaining = SetPrimParams((ScenePresence)part, rules, originFunc, ref rulesParsed);
7795 }
7796 }
7797 }
7268 } 7798 }
7269 7799
7270 protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) 7800 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7801 float material_density, float material_friction,
7802 float material_restitution, float material_gravity_modifier)
7271 { 7803 {
7272 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7804 ExtraPhysicsData physdata = new ExtraPhysicsData();
7805 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7806 physdata.Density = part.Density;
7807 physdata.Friction = part.Friction;
7808 physdata.Bounce = part.Bounciness;
7809 physdata.GravitationModifier = part.GravityModifier;
7273 7810
7274 LSL_List remaining = null; 7811 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7275 uint rulesParsed = 0; 7812 physdata.Density = material_density;
7813 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7814 physdata.Friction = material_friction;
7815 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7816 physdata.Bounce = material_restitution;
7817 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7818 physdata.GravitationModifier = material_gravity_modifier;
7276 7819
7277 foreach (SceneObjectPart part in parts) 7820 part.UpdateExtraPhysics(physdata);
7278 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7821 }
7279 7822
7280 while (remaining != null && remaining.Length > 2) 7823 public void llSetPhysicsMaterial(int material_bits,
7281 { 7824 float material_gravity_modifier, float material_restitution,
7282 linknumber = remaining.GetLSLIntegerItem(0); 7825 float material_friction, float material_density)
7283 rules = remaining.GetSublist(1, -1); 7826 {
7284 parts = GetLinkParts(linknumber); 7827 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7828 }
7285 7829
7286 foreach (SceneObjectPart part in parts) 7830 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7287 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); 7831 {
7832 setLinkPrimParams(linknumber, rules, "llSetLinkPrimitiveParams");
7833 llSetLinkPrimitiveParamsFast(linknumber, rules);
7834 ScriptSleep(200);
7835 }
7836
7837 // vector up using libomv (c&p from sop )
7838 // vector up rotated by r
7839 private Vector3 Zrot(Quaternion r)
7840 {
7841 double x, y, z, m;
7842
7843 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7844 if (Math.Abs(1.0 - m) > 0.000001)
7845 {
7846 m = 1.0 / Math.Sqrt(m);
7847 r.X *= (float)m;
7848 r.Y *= (float)m;
7849 r.Z *= (float)m;
7850 r.W *= (float)m;
7288 } 7851 }
7852
7853 x = 2 * (r.X * r.Z + r.Y * r.W);
7854 y = 2 * (-r.X * r.W + r.Y * r.Z);
7855 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7856
7857 return new Vector3((float)x, (float)y, (float)z);
7289 } 7858 }
7290 7859
7291 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7860 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7292 { 7861 {
7862 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7863 return null;
7864
7293 int idx = 0; 7865 int idx = 0;
7294 int idxStart = 0; 7866 int idxStart = 0;
7295 7867
7868 SceneObjectGroup parentgrp = part.ParentGroup;
7869
7296 bool positionChanged = false; 7870 bool positionChanged = false;
7297 LSL_Vector currentPosition = GetPartLocalPos(part); 7871 LSL_Vector currentPosition = GetPartLocalPos(part);
7298 7872
@@ -7317,8 +7891,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7317 return null; 7891 return null;
7318 7892
7319 v=rules.GetVector3Item(idx++); 7893 v=rules.GetVector3Item(idx++);
7320 positionChanged = true;
7321 currentPosition = GetSetPosTarget(part, v, currentPosition); 7894 currentPosition = GetSetPosTarget(part, v, currentPosition);
7895 positionChanged = true;
7322 7896
7323 break; 7897 break;
7324 case (int)ScriptBaseClass.PRIM_SIZE: 7898 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7595,7 +8169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7595 return null; 8169 return null;
7596 8170
7597 string ph = rules.Data[idx++].ToString(); 8171 string ph = rules.Data[idx++].ToString();
7598 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8172 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7599 8173
7600 break; 8174 break;
7601 8175
@@ -7613,12 +8187,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7613 part.ScriptSetPhysicsStatus(physics); 8187 part.ScriptSetPhysicsStatus(physics);
7614 break; 8188 break;
7615 8189
8190 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8191 if (remain < 1)
8192 return null;
8193
8194 int shape_type = rules.GetLSLIntegerItem(idx++);
8195
8196 ExtraPhysicsData physdata = new ExtraPhysicsData();
8197 physdata.Density = part.Density;
8198 physdata.Bounce = part.Bounciness;
8199 physdata.GravitationModifier = part.GravityModifier;
8200 physdata.PhysShapeType = (PhysShapeType)shape_type;
8201
8202 part.UpdateExtraPhysics(physdata);
8203
8204 break;
8205
8206 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8207 if (remain < 5)
8208 return null;
8209
8210 int material_bits = rules.GetLSLIntegerItem(idx++);
8211 float material_density = (float)rules.GetLSLFloatItem(idx++);
8212 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8213 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8214 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8215
8216 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8217
8218 break;
8219
7616 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8220 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7617 if (remain < 1) 8221 if (remain < 1)
7618 return null; 8222 return null;
7619 string temp = rules.Data[idx++].ToString(); 8223 string temp = rules.Data[idx++].ToString();
7620 8224
7621 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8225 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7622 8226
7623 break; 8227 break;
7624 8228
@@ -7692,7 +8296,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7692 if (part.ParentGroup.RootPart == part) 8296 if (part.ParentGroup.RootPart == part)
7693 { 8297 {
7694 SceneObjectGroup parent = part.ParentGroup; 8298 SceneObjectGroup parent = part.ParentGroup;
7695 parent.UpdateGroupPosition(currentPosition); 8299 Util.FireAndForget(delegate(object x) {
8300 parent.UpdateGroupPosition(currentPosition);
8301 });
7696 } 8302 }
7697 else 8303 else
7698 { 8304 {
@@ -7737,10 +8343,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7737 8343
7738 public LSL_String llXorBase64Strings(string str1, string str2) 8344 public LSL_String llXorBase64Strings(string str1, string str2)
7739 { 8345 {
7740 m_host.AddScriptLPS(1); 8346 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7741 Deprecated("llXorBase64Strings"); 8347
7742 ScriptSleep(300); 8348 ScriptSleep(300);
7743 return String.Empty; 8349 m_host.AddScriptLPS(1);
8350
8351 if (str1 == String.Empty)
8352 return String.Empty;
8353 if (str2 == String.Empty)
8354 return str1;
8355
8356 int len = str2.Length;
8357 if ((len % 4) != 0) // LL is EVIL!!!!
8358 {
8359 while (str2.EndsWith("="))
8360 str2 = str2.Substring(0, str2.Length - 1);
8361
8362 len = str2.Length;
8363 int mod = len % 4;
8364
8365 if (mod == 1)
8366 str2 = str2.Substring(0, str2.Length - 1);
8367 else if (mod == 2)
8368 str2 += "==";
8369 else if (mod == 3)
8370 str2 += "=";
8371 }
8372
8373 byte[] data1;
8374 byte[] data2;
8375 try
8376 {
8377 data1 = Convert.FromBase64String(str1);
8378 data2 = Convert.FromBase64String(str2);
8379 }
8380 catch (Exception)
8381 {
8382 return new LSL_String(String.Empty);
8383 }
8384
8385 // For cases where the decoded length of s2 is greater
8386 // than the decoded length of s1, simply perform a normal
8387 // decode and XOR
8388 //
8389 if (data2.Length >= data1.Length)
8390 {
8391 for (int pos = 0 ; pos < data1.Length ; pos++ )
8392 data1[pos] ^= data2[pos];
8393
8394 return Convert.ToBase64String(data1);
8395 }
8396
8397 // Remove padding
8398 while (str1.EndsWith("="))
8399 str1 = str1.Substring(0, str1.Length - 1);
8400 while (str2.EndsWith("="))
8401 str2 = str2.Substring(0, str2.Length - 1);
8402
8403 byte[] d1 = new byte[str1.Length];
8404 byte[] d2 = new byte[str2.Length];
8405
8406 for (int i = 0 ; i < str1.Length ; i++)
8407 {
8408 int idx = b64.IndexOf(str1.Substring(i, 1));
8409 if (idx == -1)
8410 idx = 0;
8411 d1[i] = (byte)idx;
8412 }
8413
8414 for (int i = 0 ; i < str2.Length ; i++)
8415 {
8416 int idx = b64.IndexOf(str2.Substring(i, 1));
8417 if (idx == -1)
8418 idx = 0;
8419 d2[i] = (byte)idx;
8420 }
8421
8422 string output = String.Empty;
8423
8424 for (int pos = 0 ; pos < d1.Length ; pos++)
8425 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8426
8427 while (output.Length % 3 > 0)
8428 output += "=";
8429
8430 return output;
7744 } 8431 }
7745 8432
7746 public void llRemoteDataSetRegion() 8433 public void llRemoteDataSetRegion()
@@ -7864,13 +8551,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7864 public LSL_Integer llGetNumberOfPrims() 8551 public LSL_Integer llGetNumberOfPrims()
7865 { 8552 {
7866 m_host.AddScriptLPS(1); 8553 m_host.AddScriptLPS(1);
7867 int avatarCount = 0; 8554 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7868 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8555
7869 {
7870 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7871 avatarCount++;
7872 });
7873
7874 return m_host.ParentGroup.PrimCount + avatarCount; 8556 return m_host.ParentGroup.PrimCount + avatarCount;
7875 } 8557 }
7876 8558
@@ -7886,55 +8568,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7886 m_host.AddScriptLPS(1); 8568 m_host.AddScriptLPS(1);
7887 UUID objID = UUID.Zero; 8569 UUID objID = UUID.Zero;
7888 LSL_List result = new LSL_List(); 8570 LSL_List result = new LSL_List();
8571
8572 // If the ID is not valid, return null result
7889 if (!UUID.TryParse(obj, out objID)) 8573 if (!UUID.TryParse(obj, out objID))
7890 { 8574 {
7891 result.Add(new LSL_Vector()); 8575 result.Add(new LSL_Vector());
7892 result.Add(new LSL_Vector()); 8576 result.Add(new LSL_Vector());
7893 return result; 8577 return result;
7894 } 8578 }
8579
8580 // Check if this is an attached prim. If so, replace
8581 // the UUID with the avatar UUID and report it's bounding box
8582 SceneObjectPart part = World.GetSceneObjectPart(objID);
8583 if (part != null && part.ParentGroup.IsAttachment)
8584 objID = part.ParentGroup.AttachedAvatar;
8585
8586 // Find out if this is an avatar ID. If so, return it's box
7895 ScenePresence presence = World.GetScenePresence(objID); 8587 ScenePresence presence = World.GetScenePresence(objID);
7896 if (presence != null) 8588 if (presence != null)
7897 { 8589 {
7898 if (presence.ParentID == 0) // not sat on an object 8590 // As per LSL Wiki, there is no difference between sitting
8591 // and standing avatar since server 1.36
8592 LSL_Vector lower;
8593 LSL_Vector upper;
8594 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
8595 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7899 { 8596 {
7900 LSL_Vector lower; 8597 // This is for ground sitting avatars
7901 LSL_Vector upper; 8598 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7902 if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID 8599 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7903 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8600 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7904 {
7905 // This is for ground sitting avatars
7906 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7907 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7908 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7909 }
7910 else
7911 {
7912 // This is for standing/flying avatars
7913 float height = presence.Appearance.AvatarHeight / 2.0f;
7914 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7915 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7916 }
7917 result.Add(lower);
7918 result.Add(upper);
7919 return result;
7920 } 8601 }
7921 else 8602 else
7922 { 8603 {
7923 // sitting on an object so we need the bounding box of that 8604 // This is for standing/flying avatars
7924 // which should include the avatar so set the UUID to the 8605 float height = presence.Appearance.AvatarHeight / 2.0f;
7925 // UUID of the object the avatar is sat on and allow it to fall through 8606 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7926 // to processing an object 8607 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7927 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7928 objID = p.UUID;
7929 } 8608 }
8609
8610 // Adjust to the documented error offsets (see LSL Wiki)
8611 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8612 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8613
8614 if (lower.x > upper.x)
8615 lower.x = upper.x;
8616 if (lower.y > upper.y)
8617 lower.y = upper.y;
8618 if (lower.z > upper.z)
8619 lower.z = upper.z;
8620
8621 result.Add(lower);
8622 result.Add(upper);
8623 return result;
7930 } 8624 }
7931 SceneObjectPart part = World.GetSceneObjectPart(objID); 8625
8626 part = World.GetSceneObjectPart(objID);
7932 // Currently only works for single prims without a sitting avatar 8627 // Currently only works for single prims without a sitting avatar
7933 if (part != null) 8628 if (part != null)
7934 { 8629 {
7935 Vector3 halfSize = part.Scale / 2.0f; 8630 float minX;
7936 LSL_Vector lower = (new LSL_Vector(halfSize)) * -1.0f; 8631 float maxX;
7937 LSL_Vector upper = new LSL_Vector(halfSize); 8632 float minY;
8633 float maxY;
8634 float minZ;
8635 float maxZ;
8636
8637 // This BBox is in sim coordinates, with the offset being
8638 // a contained point.
8639 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8640 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8641
8642 minX -= offsets[0].X;
8643 maxX -= offsets[0].X;
8644 minY -= offsets[0].Y;
8645 maxY -= offsets[0].Y;
8646 minZ -= offsets[0].Z;
8647 maxZ -= offsets[0].Z;
8648
8649 LSL_Vector lower;
8650 LSL_Vector upper;
8651
8652 // Adjust to the documented error offsets (see LSL Wiki)
8653 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8654 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8655
8656 if (lower.x > upper.x)
8657 lower.x = upper.x;
8658 if (lower.y > upper.y)
8659 lower.y = upper.y;
8660 if (lower.z > upper.z)
8661 lower.z = upper.z;
8662
7938 result.Add(lower); 8663 result.Add(lower);
7939 result.Add(upper); 8664 result.Add(upper);
7940 return result; 8665 return result;
@@ -7948,7 +8673,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7948 8673
7949 public LSL_Vector llGetGeometricCenter() 8674 public LSL_Vector llGetGeometricCenter()
7950 { 8675 {
7951 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8676 Vector3 tmp = m_host.GetGeometricCenter();
8677 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7952 } 8678 }
7953 8679
7954 public LSL_List llGetPrimitiveParams(LSL_List rules) 8680 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7976,24 +8702,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7976 { 8702 {
7977 m_host.AddScriptLPS(1); 8703 m_host.AddScriptLPS(1);
7978 8704
7979 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8705 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8706 // keep other options as before
7980 8707
8708 List<SceneObjectPart> parts;
8709 List<ScenePresence> avatars;
8710
7981 LSL_List res = new LSL_List(); 8711 LSL_List res = new LSL_List();
7982 LSL_List remaining = null; 8712 LSL_List remaining = null;
7983 8713
7984 foreach (SceneObjectPart part in parts) 8714 while (rules.Length > 0)
7985 { 8715 {
7986 remaining = GetPrimParams(part, rules, ref res);
7987 }
7988
7989 while (remaining != null && remaining.Length > 2)
7990 {
7991 linknumber = remaining.GetLSLIntegerItem(0);
7992 rules = remaining.GetSublist(1, -1);
7993 parts = GetLinkParts(linknumber); 8716 parts = GetLinkParts(linknumber);
8717 avatars = GetLinkAvatars(linknumber);
7994 8718
8719 remaining = null;
7995 foreach (SceneObjectPart part in parts) 8720 foreach (SceneObjectPart part in parts)
8721 {
7996 remaining = GetPrimParams(part, rules, ref res); 8722 remaining = GetPrimParams(part, rules, ref res);
8723 }
8724 foreach (ScenePresence avatar in avatars)
8725 {
8726 remaining = GetPrimParams(avatar, rules, ref res);
8727 }
8728
8729 if (remaining != null && remaining.Length > 0)
8730 {
8731 linknumber = remaining.GetLSLIntegerItem(0);
8732 rules = remaining.GetSublist(1, -1);
8733 }
7997 } 8734 }
7998 8735
7999 return res; 8736 return res;
@@ -8038,13 +8775,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8038 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 8775 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
8039 part.AbsolutePosition.Y, 8776 part.AbsolutePosition.Y,
8040 part.AbsolutePosition.Z); 8777 part.AbsolutePosition.Z);
8041 // For some reason, the part.AbsolutePosition.* values do not change if the
8042 // linkset is rotated; they always reflect the child prim's world position
8043 // as though the linkset is unrotated. This is incompatible behavior with SL's
8044 // implementation, so will break scripts imported from there (not to mention it
8045 // makes it more difficult to determine a child prim's actual inworld position).
8046 if (part.ParentID != 0)
8047 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
8048 res.Add(v); 8778 res.Add(v);
8049 break; 8779 break;
8050 8780
@@ -8216,30 +8946,56 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8216 if (remain < 1) 8946 if (remain < 1)
8217 return null; 8947 return null;
8218 8948
8219 face=(int)rules.GetLSLIntegerItem(idx++); 8949 face = (int)rules.GetLSLIntegerItem(idx++);
8220 8950
8221 tex = part.Shape.Textures; 8951 tex = part.Shape.Textures;
8952 int shiny;
8222 if (face == ScriptBaseClass.ALL_SIDES) 8953 if (face == ScriptBaseClass.ALL_SIDES)
8223 { 8954 {
8224 for (face = 0; face < GetNumberOfSides(part); face++) 8955 for (face = 0; face < GetNumberOfSides(part); face++)
8225 { 8956 {
8226 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8957 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8227 // Convert Shininess to PRIM_SHINY_* 8958 if (shinyness == Shininess.High)
8228 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8959 {
8229 // PRIM_BUMP_* 8960 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8230 res.Add(new LSL_Integer((int)texface.Bump)); 8961 }
8962 else if (shinyness == Shininess.Medium)
8963 {
8964 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8965 }
8966 else if (shinyness == Shininess.Low)
8967 {
8968 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8969 }
8970 else
8971 {
8972 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8973 }
8974 res.Add(new LSL_Integer(shiny));
8975 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8231 } 8976 }
8232 } 8977 }
8233 else 8978 else
8234 { 8979 {
8235 if (face >= 0 && face < GetNumberOfSides(part)) 8980 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8981 if (shinyness == Shininess.High)
8236 { 8982 {
8237 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 8983 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8238 // Convert Shininess to PRIM_SHINY_* 8984 }
8239 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 8985 else if (shinyness == Shininess.Medium)
8240 // PRIM_BUMP_* 8986 {
8241 res.Add(new LSL_Integer((int)texface.Bump)); 8987 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8988 }
8989 else if (shinyness == Shininess.Low)
8990 {
8991 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
8992 }
8993 else
8994 {
8995 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
8242 } 8996 }
8997 res.Add(new LSL_Integer(shiny));
8998 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8243 } 8999 }
8244 break; 9000 break;
8245 9001
@@ -8247,24 +9003,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8247 if (remain < 1) 9003 if (remain < 1)
8248 return null; 9004 return null;
8249 9005
8250 face=(int)rules.GetLSLIntegerItem(idx++); 9006 face = (int)rules.GetLSLIntegerItem(idx++);
8251 9007
8252 tex = part.Shape.Textures; 9008 tex = part.Shape.Textures;
9009 int fullbright;
8253 if (face == ScriptBaseClass.ALL_SIDES) 9010 if (face == ScriptBaseClass.ALL_SIDES)
8254 { 9011 {
8255 for (face = 0; face < GetNumberOfSides(part); face++) 9012 for (face = 0; face < GetNumberOfSides(part); face++)
8256 { 9013 {
8257 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9014 if (tex.GetFace((uint)face).Fullbright == true)
8258 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9015 {
9016 fullbright = ScriptBaseClass.TRUE;
9017 }
9018 else
9019 {
9020 fullbright = ScriptBaseClass.FALSE;
9021 }
9022 res.Add(new LSL_Integer(fullbright));
8259 } 9023 }
8260 } 9024 }
8261 else 9025 else
8262 { 9026 {
8263 if (face >= 0 && face < GetNumberOfSides(part)) 9027 if (tex.GetFace((uint)face).Fullbright == true)
8264 { 9028 {
8265 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9029 fullbright = ScriptBaseClass.TRUE;
8266 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9030 }
9031 else
9032 {
9033 fullbright = ScriptBaseClass.FALSE;
8267 } 9034 }
9035 res.Add(new LSL_Integer(fullbright));
8268 } 9036 }
8269 break; 9037 break;
8270 9038
@@ -8286,27 +9054,36 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8286 break; 9054 break;
8287 9055
8288 case (int)ScriptBaseClass.PRIM_TEXGEN: 9056 case (int)ScriptBaseClass.PRIM_TEXGEN:
9057 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8289 if (remain < 1) 9058 if (remain < 1)
8290 return null; 9059 return null;
8291 9060
8292 face=(int)rules.GetLSLIntegerItem(idx++); 9061 face = (int)rules.GetLSLIntegerItem(idx++);
8293 9062
8294 tex = part.Shape.Textures; 9063 tex = part.Shape.Textures;
8295 if (face == ScriptBaseClass.ALL_SIDES) 9064 if (face == ScriptBaseClass.ALL_SIDES)
8296 { 9065 {
8297 for (face = 0; face < GetNumberOfSides(part); face++) 9066 for (face = 0; face < GetNumberOfSides(part); face++)
8298 { 9067 {
8299 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9068 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8300 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9069 {
8301 res.Add(new LSL_Integer((uint)texgen >> 1)); 9070 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9071 }
9072 else
9073 {
9074 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9075 }
8302 } 9076 }
8303 } 9077 }
8304 else 9078 else
8305 { 9079 {
8306 if (face >= 0 && face < GetNumberOfSides(part)) 9080 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8307 { 9081 {
8308 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9082 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8309 res.Add(new LSL_Integer((uint)texgen >> 1)); 9083 }
9084 else
9085 {
9086 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8310 } 9087 }
8311 } 9088 }
8312 break; 9089 break;
@@ -8330,24 +9107,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8330 if (remain < 1) 9107 if (remain < 1)
8331 return null; 9108 return null;
8332 9109
8333 face=(int)rules.GetLSLIntegerItem(idx++); 9110 face = (int)rules.GetLSLIntegerItem(idx++);
8334 9111
8335 tex = part.Shape.Textures; 9112 tex = part.Shape.Textures;
9113 float primglow;
8336 if (face == ScriptBaseClass.ALL_SIDES) 9114 if (face == ScriptBaseClass.ALL_SIDES)
8337 { 9115 {
8338 for (face = 0; face < GetNumberOfSides(part); face++) 9116 for (face = 0; face < GetNumberOfSides(part); face++)
8339 { 9117 {
8340 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9118 primglow = tex.GetFace((uint)face).Glow;
8341 res.Add(new LSL_Float(texface.Glow)); 9119 res.Add(new LSL_Float(primglow));
8342 } 9120 }
8343 } 9121 }
8344 else 9122 else
8345 { 9123 {
8346 if (face >= 0 && face < GetNumberOfSides(part)) 9124 primglow = tex.GetFace((uint)face).Glow;
8347 { 9125 res.Add(new LSL_Float(primglow));
8348 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8349 res.Add(new LSL_Float(texface.Glow));
8350 }
8351 } 9126 }
8352 break; 9127 break;
8353 9128
@@ -8359,15 +9134,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8359 textColor.B)); 9134 textColor.B));
8360 res.Add(new LSL_Float(textColor.A)); 9135 res.Add(new LSL_Float(textColor.A));
8361 break; 9136 break;
9137
8362 case (int)ScriptBaseClass.PRIM_NAME: 9138 case (int)ScriptBaseClass.PRIM_NAME:
8363 res.Add(new LSL_String(part.Name)); 9139 res.Add(new LSL_String(part.Name));
8364 break; 9140 break;
9141
8365 case (int)ScriptBaseClass.PRIM_DESC: 9142 case (int)ScriptBaseClass.PRIM_DESC:
8366 res.Add(new LSL_String(part.Description)); 9143 res.Add(new LSL_String(part.Description));
8367 break; 9144 break;
9145
8368 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9146 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8369 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9147 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8370 break; 9148 break;
9149
8371 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9150 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8372 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9151 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8373 break; 9152 break;
@@ -8978,8 +9757,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8978 // The function returns an ordered list 9757 // The function returns an ordered list
8979 // representing the tokens found in the supplied 9758 // representing the tokens found in the supplied
8980 // sources string. If two successive tokenizers 9759 // sources string. If two successive tokenizers
8981 // are encountered, then a NULL entry is added 9760 // are encountered, then a null-string entry is
8982 // to the list. 9761 // added to the list.
8983 // 9762 //
8984 // It is a precondition that the source and 9763 // It is a precondition that the source and
8985 // toekizer lisst are non-null. If they are null, 9764 // toekizer lisst are non-null. If they are null,
@@ -8987,7 +9766,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8987 // while their lengths are being determined. 9766 // while their lengths are being determined.
8988 // 9767 //
8989 // A small amount of working memoryis required 9768 // A small amount of working memoryis required
8990 // of approximately 8*#tokenizers. 9769 // of approximately 8*#tokenizers + 8*srcstrlen.
8991 // 9770 //
8992 // There are many ways in which this function 9771 // There are many ways in which this function
8993 // can be implemented, this implementation is 9772 // can be implemented, this implementation is
@@ -9003,155 +9782,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9003 // and eliminates redundant tokenizers as soon 9782 // and eliminates redundant tokenizers as soon
9004 // as is possible. 9783 // as is possible.
9005 // 9784 //
9006 // The implementation tries to avoid any copying 9785 // The implementation tries to minimize temporary
9007 // of arrays or other objects. 9786 // garbage generation.
9008 // </remarks> 9787 // </remarks>
9009 9788
9010 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 9789 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9011 { 9790 {
9012 int beginning = 0; 9791 return ParseString2List(src, separators, spacers, true);
9013 int srclen = src.Length; 9792 }
9014 int seplen = separators.Length;
9015 object[] separray = separators.Data;
9016 int spclen = spacers.Length;
9017 object[] spcarray = spacers.Data;
9018 int mlen = seplen+spclen;
9019
9020 int[] offset = new int[mlen+1];
9021 bool[] active = new bool[mlen];
9022
9023 int best;
9024 int j;
9025
9026 // Initial capacity reduces resize cost
9027 9793
9028 LSL_List tokens = new LSL_List(); 9794 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
9795 {
9796 int srclen = src.Length;
9797 int seplen = separators.Length;
9798 object[] separray = separators.Data;
9799 int spclen = spacers.Length;
9800 object[] spcarray = spacers.Data;
9801 int dellen = 0;
9802 string[] delarray = new string[seplen+spclen];
9029 9803
9030 // All entries are initially valid 9804 int outlen = 0;
9805 string[] outarray = new string[srclen*2+1];
9031 9806
9032 for (int i = 0; i < mlen; i++) 9807 int i, j;
9033 active[i] = true; 9808 string d;
9034 9809
9035 offset[mlen] = srclen; 9810 m_host.AddScriptLPS(1);
9036 9811
9037 while (beginning < srclen) 9812 /*
9813 * Convert separator and spacer lists to C# strings.
9814 * Also filter out null strings so we don't hang.
9815 */
9816 for (i = 0; i < seplen; i ++)
9038 { 9817 {
9818 d = separray[i].ToString();
9819 if (d.Length > 0)
9820 {
9821 delarray[dellen++] = d;
9822 }
9823 }
9824 seplen = dellen;
9039 9825
9040 best = mlen; // as bad as it gets 9826 for (i = 0; i < spclen; i ++)
9827 {
9828 d = spcarray[i].ToString();
9829 if (d.Length > 0)
9830 {
9831 delarray[dellen++] = d;
9832 }
9833 }
9041 9834
9042 // Scan for separators 9835 /*
9836 * Scan through source string from beginning to end.
9837 */
9838 for (i = 0;;)
9839 {
9043 9840
9044 for (j = 0; j < seplen; j++) 9841 /*
9842 * Find earliest delimeter in src starting at i (if any).
9843 */
9844 int earliestDel = -1;
9845 int earliestSrc = srclen;
9846 string earliestStr = null;
9847 for (j = 0; j < dellen; j ++)
9045 { 9848 {
9046 if (separray[j].ToString() == String.Empty) 9849 d = delarray[j];
9047 active[j] = false; 9850 if (d != null)
9048
9049 if (active[j])
9050 { 9851 {
9051 // scan all of the markers 9852 int index = src.IndexOf(d, i);
9052 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 9853 if (index < 0)
9053 { 9854 {
9054 // not present at all 9855 delarray[j] = null; // delim nowhere in src, don't check it anymore
9055 active[j] = false;
9056 } 9856 }
9057 else 9857 else if (index < earliestSrc)
9058 { 9858 {
9059 // present and correct 9859 earliestSrc = index; // where delimeter starts in source string
9060 if (offset[j] < offset[best]) 9860 earliestDel = j; // where delimeter is in delarray[]
9061 { 9861 earliestStr = d; // the delimeter string from delarray[]
9062 // closest so far 9862 if (index == i) break; // can't do any better than found at beg of string
9063 best = j;
9064 if (offset[best] == beginning)
9065 break;
9066 }
9067 } 9863 }
9068 } 9864 }
9069 } 9865 }
9070 9866
9071 // Scan for spacers 9867 /*
9072 9868 * Output source string starting at i through start of earliest delimeter.
9073 if (offset[best] != beginning) 9869 */
9870 if (keepNulls || (earliestSrc > i))
9074 { 9871 {
9075 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 9872 outarray[outlen++] = src.Substring(i, earliestSrc - i);
9076 {
9077 if (spcarray[j-seplen].ToString() == String.Empty)
9078 active[j] = false;
9079
9080 if (active[j])
9081 {
9082 // scan all of the markers
9083 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
9084 {
9085 // not present at all
9086 active[j] = false;
9087 }
9088 else
9089 {
9090 // present and correct
9091 if (offset[j] < offset[best])
9092 {
9093 // closest so far
9094 best = j;
9095 }
9096 }
9097 }
9098 }
9099 } 9873 }
9100 9874
9101 // This is the normal exit from the scanning loop 9875 /*
9876 * If no delimeter found at or after i, we're done scanning.
9877 */
9878 if (earliestDel < 0) break;
9102 9879
9103 if (best == mlen) 9880 /*
9881 * If delimeter was a spacer, output the spacer.
9882 */
9883 if (earliestDel >= seplen)
9104 { 9884 {
9105 // no markers were found on this pass 9885 outarray[outlen++] = earliestStr;
9106 // so we're pretty much done
9107 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
9108 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
9109 break;
9110 } 9886 }
9111 9887
9112 // Otherwise we just add the newly delimited token 9888 /*
9113 // and recalculate where the search should continue. 9889 * Look at rest of src string following delimeter.
9114 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 9890 */
9115 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 9891 i = earliestSrc + earliestStr.Length;
9116
9117 if (best < seplen)
9118 {
9119 beginning = offset[best] + (separray[best].ToString()).Length;
9120 }
9121 else
9122 {
9123 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
9124 string str = spcarray[best - seplen].ToString();
9125 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
9126 tokens.Add(new LSL_String(str));
9127 }
9128 } 9892 }
9129 9893
9130 // This an awkward an not very intuitive boundary case. If the 9894 /*
9131 // last substring is a tokenizer, then there is an implied trailing 9895 * Make up an exact-sized output array suitable for an LSL_List object.
9132 // null list entry. Hopefully the single comparison will not be too 9896 */
9133 // arduous. Alternatively the 'break' could be replced with a return 9897 object[] outlist = new object[outlen];
9134 // but that's shabby programming. 9898 for (i = 0; i < outlen; i ++)
9135
9136 if ((beginning == srclen) && (keepNulls))
9137 { 9899 {
9138 if (srclen != 0) 9900 outlist[i] = new LSL_String(outarray[i]);
9139 tokens.Add(new LSL_String(""));
9140 } 9901 }
9141 9902 return new LSL_List(outlist);
9142 return tokens;
9143 }
9144
9145 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
9146 {
9147 m_host.AddScriptLPS(1);
9148 return this.ParseString(src, separators, spacers, false);
9149 }
9150
9151 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
9152 {
9153 m_host.AddScriptLPS(1);
9154 return this.ParseString(src, separators, spacers, true);
9155 } 9903 }
9156 9904
9157 public LSL_Integer llGetObjectPermMask(int mask) 9905 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9246,6 +9994,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9246 case 4: 9994 case 4:
9247 return (int)item.NextPermissions; 9995 return (int)item.NextPermissions;
9248 } 9996 }
9997 m_host.TaskInventory.LockItemsForRead(false);
9249 9998
9250 return -1; 9999 return -1;
9251 } 10000 }
@@ -9448,31 +10197,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9448 UUID key = new UUID(); 10197 UUID key = new UUID();
9449 if (UUID.TryParse(id, out key)) 10198 if (UUID.TryParse(id, out key))
9450 { 10199 {
9451 try 10200 // return total object mass
9452 { 10201 SceneObjectPart part = World.GetSceneObjectPart(key);
9453 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10202 if (part != null)
9454 if (obj != null) 10203 return part.ParentGroup.GetMass();
9455 return (double)obj.GetMass(); 10204
9456 // the object is null so the key is for an avatar 10205 // the object is null so the key is for an avatar
9457 ScenePresence avatar = World.GetScenePresence(key); 10206 ScenePresence avatar = World.GetScenePresence(key);
9458 if (avatar != null) 10207 if (avatar != null)
9459 if (avatar.IsChildAgent)
9460 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
9461 // child agents have a mass of 1.0
9462 return 1;
9463 else
9464 return (double)avatar.GetMass();
9465 }
9466 catch (KeyNotFoundException)
9467 { 10208 {
9468 return 0; // The Object/Agent not in the region so just return zero 10209 if (avatar.IsChildAgent)
10210 {
10211 // reference http://www.lslwiki.net/lslwiki/wakka.php?wakka=llGetObjectMass
10212 // child agents have a mass of 1.0
10213 return 1;
10214 }
10215 else
10216 {
10217 return (double)avatar.GetMass();
10218 }
9469 } 10219 }
9470 } 10220 }
9471 return 0; 10221 return 0;
9472 } 10222 }
9473 10223
9474 /// <summary> 10224 /// <summary>
9475 /// illListReplaceList removes the sub-list defined by the inclusive indices 10225 /// llListReplaceList removes the sub-list defined by the inclusive indices
9476 /// start and end and inserts the src list in its place. The inclusive 10226 /// start and end and inserts the src list in its place. The inclusive
9477 /// nature of the indices means that at least one element must be deleted 10227 /// nature of the indices means that at least one element must be deleted
9478 /// if the indices are within the bounds of the existing list. I.e. 2,2 10228 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9529,16 +10279,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9529 // based upon end. Note that if end exceeds the upper 10279 // based upon end. Note that if end exceeds the upper
9530 // bound in this case, the entire destination list 10280 // bound in this case, the entire destination list
9531 // is removed. 10281 // is removed.
9532 else 10282 else if (start == 0)
9533 { 10283 {
9534 if (end + 1 < dest.Length) 10284 if (end + 1 < dest.Length)
9535 {
9536 return src + dest.GetSublist(end + 1, -1); 10285 return src + dest.GetSublist(end + 1, -1);
9537 }
9538 else 10286 else
9539 {
9540 return src; 10287 return src;
9541 } 10288 }
10289 else // Start < 0
10290 {
10291 if (end + 1 < dest.Length)
10292 return dest.GetSublist(end + 1, -1);
10293 else
10294 return new LSL_List();
9542 } 10295 }
9543 } 10296 }
9544 // Finally, if start > end, we strip away a prefix and 10297 // Finally, if start > end, we strip away a prefix and
@@ -9589,17 +10342,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9589 int width = 0; 10342 int width = 0;
9590 int height = 0; 10343 int height = 0;
9591 10344
9592 ParcelMediaCommandEnum? commandToSend = null; 10345 uint commandToSend = 0;
9593 float time = 0.0f; // default is from start 10346 float time = 0.0f; // default is from start
9594 10347
9595 ScenePresence presence = null; 10348 ScenePresence presence = null;
9596 10349
9597 for (int i = 0; i < commandList.Data.Length; i++) 10350 for (int i = 0; i < commandList.Data.Length; i++)
9598 { 10351 {
9599 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10352 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9600 switch (command) 10353 switch (command)
9601 { 10354 {
9602 case ParcelMediaCommandEnum.Agent: 10355 case (uint)ParcelMediaCommandEnum.Agent:
9603 // we send only to one agent 10356 // we send only to one agent
9604 if ((i + 1) < commandList.Length) 10357 if ((i + 1) < commandList.Length)
9605 { 10358 {
@@ -9616,25 +10369,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9616 } 10369 }
9617 break; 10370 break;
9618 10371
9619 case ParcelMediaCommandEnum.Loop: 10372 case (uint)ParcelMediaCommandEnum.Loop:
9620 loop = 1; 10373 loop = 1;
9621 commandToSend = command; 10374 commandToSend = command;
9622 update = true; //need to send the media update packet to set looping 10375 update = true; //need to send the media update packet to set looping
9623 break; 10376 break;
9624 10377
9625 case ParcelMediaCommandEnum.Play: 10378 case (uint)ParcelMediaCommandEnum.Play:
9626 loop = 0; 10379 loop = 0;
9627 commandToSend = command; 10380 commandToSend = command;
9628 update = true; //need to send the media update packet to make sure it doesn't loop 10381 update = true; //need to send the media update packet to make sure it doesn't loop
9629 break; 10382 break;
9630 10383
9631 case ParcelMediaCommandEnum.Pause: 10384 case (uint)ParcelMediaCommandEnum.Pause:
9632 case ParcelMediaCommandEnum.Stop: 10385 case (uint)ParcelMediaCommandEnum.Stop:
9633 case ParcelMediaCommandEnum.Unload: 10386 case (uint)ParcelMediaCommandEnum.Unload:
9634 commandToSend = command; 10387 commandToSend = command;
9635 break; 10388 break;
9636 10389
9637 case ParcelMediaCommandEnum.Url: 10390 case (uint)ParcelMediaCommandEnum.Url:
9638 if ((i + 1) < commandList.Length) 10391 if ((i + 1) < commandList.Length)
9639 { 10392 {
9640 if (commandList.Data[i + 1] is LSL_String) 10393 if (commandList.Data[i + 1] is LSL_String)
@@ -9647,7 +10400,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9647 } 10400 }
9648 break; 10401 break;
9649 10402
9650 case ParcelMediaCommandEnum.Texture: 10403 case (uint)ParcelMediaCommandEnum.Texture:
9651 if ((i + 1) < commandList.Length) 10404 if ((i + 1) < commandList.Length)
9652 { 10405 {
9653 if (commandList.Data[i + 1] is LSL_String) 10406 if (commandList.Data[i + 1] is LSL_String)
@@ -9660,7 +10413,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9660 } 10413 }
9661 break; 10414 break;
9662 10415
9663 case ParcelMediaCommandEnum.Time: 10416 case (uint)ParcelMediaCommandEnum.Time:
9664 if ((i + 1) < commandList.Length) 10417 if ((i + 1) < commandList.Length)
9665 { 10418 {
9666 if (commandList.Data[i + 1] is LSL_Float) 10419 if (commandList.Data[i + 1] is LSL_Float)
@@ -9672,7 +10425,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9672 } 10425 }
9673 break; 10426 break;
9674 10427
9675 case ParcelMediaCommandEnum.AutoAlign: 10428 case (uint)ParcelMediaCommandEnum.AutoAlign:
9676 if ((i + 1) < commandList.Length) 10429 if ((i + 1) < commandList.Length)
9677 { 10430 {
9678 if (commandList.Data[i + 1] is LSL_Integer) 10431 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9686,7 +10439,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9686 } 10439 }
9687 break; 10440 break;
9688 10441
9689 case ParcelMediaCommandEnum.Type: 10442 case (uint)ParcelMediaCommandEnum.Type:
9690 if ((i + 1) < commandList.Length) 10443 if ((i + 1) < commandList.Length)
9691 { 10444 {
9692 if (commandList.Data[i + 1] is LSL_String) 10445 if (commandList.Data[i + 1] is LSL_String)
@@ -9699,7 +10452,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9699 } 10452 }
9700 break; 10453 break;
9701 10454
9702 case ParcelMediaCommandEnum.Desc: 10455 case (uint)ParcelMediaCommandEnum.Desc:
9703 if ((i + 1) < commandList.Length) 10456 if ((i + 1) < commandList.Length)
9704 { 10457 {
9705 if (commandList.Data[i + 1] is LSL_String) 10458 if (commandList.Data[i + 1] is LSL_String)
@@ -9712,7 +10465,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9712 } 10465 }
9713 break; 10466 break;
9714 10467
9715 case ParcelMediaCommandEnum.Size: 10468 case (uint)ParcelMediaCommandEnum.Size:
9716 if ((i + 2) < commandList.Length) 10469 if ((i + 2) < commandList.Length)
9717 { 10470 {
9718 if (commandList.Data[i + 1] is LSL_Integer) 10471 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9782,7 +10535,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9782 } 10535 }
9783 } 10536 }
9784 10537
9785 if (commandToSend != null) 10538 if (commandToSend != 0)
9786 { 10539 {
9787 // the commandList contained a start/stop/... command, too 10540 // the commandList contained a start/stop/... command, too
9788 if (presence == null) 10541 if (presence == null)
@@ -9819,7 +10572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9819 10572
9820 if (aList.Data[i] != null) 10573 if (aList.Data[i] != null)
9821 { 10574 {
9822 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10575 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9823 { 10576 {
9824 case ParcelMediaCommandEnum.Url: 10577 case ParcelMediaCommandEnum.Url:
9825 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL)); 10578 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition).MediaURL));
@@ -9876,15 +10629,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9876 10629
9877 if (quick_pay_buttons.Data.Length < 4) 10630 if (quick_pay_buttons.Data.Length < 4)
9878 { 10631 {
9879 LSLError("List must have at least 4 elements"); 10632 int x;
9880 return; 10633 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10634 {
10635 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10636 }
9881 } 10637 }
9882 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10638 int[] nPrice = new int[5];
9883 10639 nPrice[0] = price;
9884 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10640 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9885 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10641 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9886 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10642 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9887 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10643 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10644 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9888 m_host.ParentGroup.HasGroupChanged = true; 10645 m_host.ParentGroup.HasGroupChanged = true;
9889 } 10646 }
9890 10647
@@ -9901,7 +10658,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9901 return new LSL_Vector(); 10658 return new LSL_Vector();
9902 } 10659 }
9903 10660
9904 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10661// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10662 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9905 if (presence != null) 10663 if (presence != null)
9906 { 10664 {
9907 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10665 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9923,7 +10681,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9923 return new LSL_Rotation(); 10681 return new LSL_Rotation();
9924 } 10682 }
9925 10683
9926 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10684// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10685 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9927 if (presence != null) 10686 if (presence != null)
9928 { 10687 {
9929 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 10688 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9983,14 +10742,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9983 { 10742 {
9984 m_host.AddScriptLPS(1); 10743 m_host.AddScriptLPS(1);
9985 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 10744 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9986 if (detectedParams == null) return; // only works on the first detected avatar 10745 if (detectedParams == null)
9987 10746 {
10747 if (m_host.ParentGroup.IsAttachment == true)
10748 {
10749 detectedParams = new DetectParams();
10750 detectedParams.Key = m_host.OwnerID;
10751 }
10752 else
10753 {
10754 return;
10755 }
10756 }
10757
9988 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 10758 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9989 if (avatar != null) 10759 if (avatar != null)
9990 { 10760 {
9991 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name, 10761 avatar.ControllingClient.SendScriptTeleportRequest(m_host.Name,
9992 simname, pos, lookAt); 10762 simname, pos, lookAt);
9993 } 10763 }
10764
9994 ScriptSleep(1000); 10765 ScriptSleep(1000);
9995 } 10766 }
9996 10767
@@ -10114,12 +10885,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10114 10885
10115 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 10886 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
10116 object[] data = rules.Data; 10887 object[] data = rules.Data;
10117 for (int i = 0; i < data.Length; ++i) { 10888 for (int i = 0; i < data.Length; ++i)
10889 {
10118 int type = Convert.ToInt32(data[i++].ToString()); 10890 int type = Convert.ToInt32(data[i++].ToString());
10119 if (i >= data.Length) break; // odd number of entries => ignore the last 10891 if (i >= data.Length) break; // odd number of entries => ignore the last
10120 10892
10121 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 10893 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
10122 switch (type) { 10894 switch (type)
10895 {
10123 case ScriptBaseClass.CAMERA_FOCUS: 10896 case ScriptBaseClass.CAMERA_FOCUS:
10124 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 10897 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
10125 case ScriptBaseClass.CAMERA_POSITION: 10898 case ScriptBaseClass.CAMERA_POSITION:
@@ -10224,19 +10997,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10224 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 10997 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10225 { 10998 {
10226 m_host.AddScriptLPS(1); 10999 m_host.AddScriptLPS(1);
10227 string ret = String.Empty; 11000
10228 string src1 = llBase64ToString(str1); 11001 if (str1 == String.Empty)
10229 string src2 = llBase64ToString(str2); 11002 return String.Empty;
10230 int c = 0; 11003 if (str2 == String.Empty)
10231 for (int i = 0; i < src1.Length; i++) 11004 return str1;
11005
11006 int len = str2.Length;
11007 if ((len % 4) != 0) // LL is EVIL!!!!
10232 { 11008 {
10233 ret += (char) (src1[i] ^ src2[c]); 11009 while (str2.EndsWith("="))
11010 str2 = str2.Substring(0, str2.Length - 1);
11011
11012 len = str2.Length;
11013 int mod = len % 4;
10234 11014
10235 c++; 11015 if (mod == 1)
10236 if (c >= src2.Length) 11016 str2 = str2.Substring(0, str2.Length - 1);
10237 c = 0; 11017 else if (mod == 2)
11018 str2 += "==";
11019 else if (mod == 3)
11020 str2 += "=";
11021 }
11022
11023 byte[] data1;
11024 byte[] data2;
11025 try
11026 {
11027 data1 = Convert.FromBase64String(str1);
11028 data2 = Convert.FromBase64String(str2);
11029 }
11030 catch (Exception)
11031 {
11032 return new LSL_String(String.Empty);
11033 }
11034
11035 byte[] d2 = new Byte[data1.Length];
11036 int pos = 0;
11037
11038 if (data1.Length <= data2.Length)
11039 {
11040 Array.Copy(data2, 0, d2, 0, data1.Length);
11041 }
11042 else
11043 {
11044 while (pos < data1.Length)
11045 {
11046 len = data1.Length - pos;
11047 if (len > data2.Length)
11048 len = data2.Length;
11049
11050 Array.Copy(data2, 0, d2, pos, len);
11051 pos += len;
11052 }
10238 } 11053 }
10239 return llStringToBase64(ret); 11054
11055 for (pos = 0 ; pos < data1.Length ; pos++ )
11056 data1[pos] ^= d2[pos];
11057
11058 return Convert.ToBase64String(data1);
10240 } 11059 }
10241 11060
10242 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11061 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10289,16 +11108,72 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10289 if (userAgent != null) 11108 if (userAgent != null)
10290 httpHeaders["User-Agent"] = userAgent; 11109 httpHeaders["User-Agent"] = userAgent;
10291 11110
11111 // See if the URL contains any header hacks
11112 string[] urlParts = url.Split(new char[] {'\n'});
11113 if (urlParts.Length > 1)
11114 {
11115 // Iterate the passed headers and parse them
11116 for (int i = 1 ; i < urlParts.Length ; i++ )
11117 {
11118 // The rest of those would be added to the body in SL.
11119 // Let's not do that.
11120 if (urlParts[i] == String.Empty)
11121 break;
11122
11123 // See if this could be a valid header
11124 string[] headerParts = urlParts[i].Split(new char[] {':'}, 2);
11125 if (headerParts.Length != 2)
11126 continue;
11127
11128 string headerName = headerParts[0].Trim();
11129 string headerValue = headerParts[1].Trim();
11130
11131 // Filter out headers that could be used to abuse
11132 // another system or cloak the request
11133 if (headerName.ToLower() == "x-secondlife-shard" ||
11134 headerName.ToLower() == "x-secondlife-object-name" ||
11135 headerName.ToLower() == "x-secondlife-object-key" ||
11136 headerName.ToLower() == "x-secondlife-region" ||
11137 headerName.ToLower() == "x-secondlife-local-position" ||
11138 headerName.ToLower() == "x-secondlife-local-velocity" ||
11139 headerName.ToLower() == "x-secondlife-local-rotation" ||
11140 headerName.ToLower() == "x-secondlife-owner-name" ||
11141 headerName.ToLower() == "x-secondlife-owner-key" ||
11142 headerName.ToLower() == "connection" ||
11143 headerName.ToLower() == "content-length" ||
11144 headerName.ToLower() == "from" ||
11145 headerName.ToLower() == "host" ||
11146 headerName.ToLower() == "proxy-authorization" ||
11147 headerName.ToLower() == "referer" ||
11148 headerName.ToLower() == "trailer" ||
11149 headerName.ToLower() == "transfer-encoding" ||
11150 headerName.ToLower() == "via" ||
11151 headerName.ToLower() == "authorization")
11152 continue;
11153
11154 httpHeaders[headerName] = headerValue;
11155 }
11156
11157 // Finally, strip any protocol specifier from the URL
11158 url = urlParts[0].Trim();
11159 int idx = url.IndexOf(" HTTP/");
11160 if (idx != -1)
11161 url = url.Substring(0, idx);
11162 }
11163
10292 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$"; 11164 string authregex = @"^(https?:\/\/)(\w+):(\w+)@(.*)$";
10293 Regex r = new Regex(authregex); 11165 Regex r = new Regex(authregex);
10294 int[] gnums = r.GetGroupNumbers(); 11166 int[] gnums = r.GetGroupNumbers();
10295 Match m = r.Match(url); 11167 Match m = r.Match(url);
10296 if (m.Success) { 11168 if (m.Success)
10297 for (int i = 1; i < gnums.Length; i++) { 11169 {
11170 for (int i = 1; i < gnums.Length; i++)
11171 {
10298 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11172 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10299 //CaptureCollection cc = g.Captures; 11173 //CaptureCollection cc = g.Captures;
10300 } 11174 }
10301 if (m.Groups.Count == 5) { 11175 if (m.Groups.Count == 5)
11176 {
10302 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11177 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10303 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11178 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10304 } 11179 }
@@ -10501,6 +11376,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10501 11376
10502 LSL_List ret = new LSL_List(); 11377 LSL_List ret = new LSL_List();
10503 UUID key = new UUID(); 11378 UUID key = new UUID();
11379
11380
10504 if (UUID.TryParse(id, out key)) 11381 if (UUID.TryParse(id, out key))
10505 { 11382 {
10506 ScenePresence av = World.GetScenePresence(key); 11383 ScenePresence av = World.GetScenePresence(key);
@@ -10518,13 +11395,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10518 ret.Add(new LSL_String("")); 11395 ret.Add(new LSL_String(""));
10519 break; 11396 break;
10520 case ScriptBaseClass.OBJECT_POS: 11397 case ScriptBaseClass.OBJECT_POS:
10521 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11398 Vector3 avpos;
11399
11400 if (av.ParentID != 0 && av.ParentPart != null)
11401 {
11402 avpos = av.OffsetPosition;
11403
11404 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11405 avpos -= sitOffset;
11406
11407 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11408 }
11409 else
11410 avpos = av.AbsolutePosition;
11411
11412 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10522 break; 11413 break;
10523 case ScriptBaseClass.OBJECT_ROT: 11414 case ScriptBaseClass.OBJECT_ROT:
10524 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11415 Quaternion avrot = av.Rotation;
11416 if (av.ParentID != 0 && av.ParentPart != null)
11417 {
11418 avrot = av.ParentPart.GetWorldRotation() * avrot;
11419 }
11420 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10525 break; 11421 break;
10526 case ScriptBaseClass.OBJECT_VELOCITY: 11422 case ScriptBaseClass.OBJECT_VELOCITY:
10527 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11423 Vector3 avvel = av.Velocity;
11424 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10528 break; 11425 break;
10529 case ScriptBaseClass.OBJECT_OWNER: 11426 case ScriptBaseClass.OBJECT_OWNER:
10530 ret.Add(new LSL_String(id)); 11427 ret.Add(new LSL_String(id));
@@ -10580,11 +11477,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10580 case ScriptBaseClass.OBJECT_NAME: 11477 case ScriptBaseClass.OBJECT_NAME:
10581 ret.Add(new LSL_String(obj.Name)); 11478 ret.Add(new LSL_String(obj.Name));
10582 break; 11479 break;
10583 case ScriptBaseClass.OBJECT_DESC: 11480 case ScriptBaseClass.OBJECT_DESC:
10584 ret.Add(new LSL_String(obj.Description)); 11481 ret.Add(new LSL_String(obj.Description));
10585 break; 11482 break;
10586 case ScriptBaseClass.OBJECT_POS: 11483 case ScriptBaseClass.OBJECT_POS:
10587 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11484 Vector3 opos = obj.AbsolutePosition;
11485 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10588 break; 11486 break;
10589 case ScriptBaseClass.OBJECT_ROT: 11487 case ScriptBaseClass.OBJECT_ROT:
10590 { 11488 {
@@ -10634,9 +11532,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10634 // The value returned in SL for normal prims is prim count 11532 // The value returned in SL for normal prims is prim count
10635 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11533 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10636 break; 11534 break;
10637 // The following 3 costs I have intentionaly coded to return zero. They are part of 11535
10638 // "Land Impact" calculations. These calculations are probably not applicable 11536 // costs below may need to be diferent for root parts, need to check
10639 // to OpenSim and are not yet complete in SL
10640 case ScriptBaseClass.OBJECT_SERVER_COST: 11537 case ScriptBaseClass.OBJECT_SERVER_COST:
10641 // The linden calculation is here 11538 // The linden calculation is here
10642 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11539 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10644,16 +11541,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10644 ret.Add(new LSL_Float(0)); 11541 ret.Add(new LSL_Float(0));
10645 break; 11542 break;
10646 case ScriptBaseClass.OBJECT_STREAMING_COST: 11543 case ScriptBaseClass.OBJECT_STREAMING_COST:
10647 // The linden calculation is here 11544 // The value returned in SL for normal prims is prim count * 0.06
10648 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11545 ret.Add(new LSL_Float(obj.StreamingCost));
10649 // The value returned in SL for normal prims looks like the prim count * 0.06
10650 ret.Add(new LSL_Float(0));
10651 break; 11546 break;
10652 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11547 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10653 // The linden calculation is here 11548 // The value returned in SL for normal prims is prim count
10654 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11549 ret.Add(new LSL_Float(obj.PhysicsCost));
10655 // The value returned in SL for normal prims looks like the prim count
10656 ret.Add(new LSL_Float(0));
10657 break; 11550 break;
10658 default: 11551 default:
10659 // Invalid or unhandled constant. 11552 // Invalid or unhandled constant.
@@ -10864,15 +11757,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10864 return result; 11757 return result;
10865 } 11758 }
10866 11759
10867 public void print(string str) 11760 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10868 { 11761 {
10869 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 11762 List<SceneObjectPart> parts = GetLinkParts(link);
10870 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 11763 if (parts.Count < 1)
10871 if (ossl != null) 11764 return 0;
10872 { 11765
10873 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 11766 return GetNumberOfSides(parts[0]);
10874 m_log.Info("LSL print():" + str);
10875 }
10876 } 11767 }
10877 11768
10878 private string Name2Username(string name) 11769 private string Name2Username(string name)
@@ -10917,7 +11808,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10917 11808
10918 return rq.ToString(); 11809 return rq.ToString();
10919 } 11810 }
10920 11811/*
11812 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
11813 {
11814 m_SayShoutCount = 0;
11815 }
11816*/
10921 private struct Tri 11817 private struct Tri
10922 { 11818 {
10923 public Vector3 p1; 11819 public Vector3 p1;
@@ -11057,9 +11953,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11057 11953
11058 ContactResult result = new ContactResult (); 11954 ContactResult result = new ContactResult ();
11059 result.ConsumerID = group.LocalId; 11955 result.ConsumerID = group.LocalId;
11060 result.Depth = intersection.distance; 11956// result.Depth = intersection.distance;
11061 result.Normal = intersection.normal; 11957 result.Normal = intersection.normal;
11062 result.Pos = intersection.ipoint; 11958 result.Pos = intersection.ipoint;
11959 result.Depth = Vector3.Mag(rayStart - result.Pos);
11063 11960
11064 contacts.Add(result); 11961 contacts.Add(result);
11065 }); 11962 });
@@ -11192,6 +12089,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11192 12089
11193 return contacts[0]; 12090 return contacts[0];
11194 } 12091 }
12092/*
12093 // not done:
12094 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12095 {
12096 ContactResult[] contacts = null;
12097 World.ForEachSOG(delegate(SceneObjectGroup group)
12098 {
12099 if (m_host.ParentGroup == group)
12100 return;
12101
12102 if (group.IsAttachment)
12103 return;
12104
12105 if(group.RootPart.PhysActor != null)
12106 return;
12107
12108 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12109 });
12110 return contacts;
12111 }
12112*/
11195 12113
11196 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12114 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
11197 { 12115 {
@@ -11233,32 +12151,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11233 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12151 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
11234 12152
11235 12153
11236 if (checkTerrain) 12154 if (World.SuportsRayCastFiltered())
11237 { 12155 {
11238 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12156 if (dist == 0)
11239 if (groundContact != null) 12157 return list;
11240 results.Add((ContactResult)groundContact);
11241 }
11242 12158
11243 if (checkAgents) 12159 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11244 { 12160 if (checkTerrain)
11245 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12161 rayfilter |= RayFilterFlags.land;
11246 foreach (ContactResult r in agentHits) 12162// if (checkAgents)
11247 results.Add(r); 12163// rayfilter |= RayFilterFlags.agent;
11248 } 12164 if (checkPhysical)
12165 rayfilter |= RayFilterFlags.physical;
12166 if (checkNonPhysical)
12167 rayfilter |= RayFilterFlags.nonphysical;
12168 if (detectPhantom)
12169 rayfilter |= RayFilterFlags.LSLPhanton;
12170
12171 Vector3 direction = dir * ( 1/dist);
12172
12173 if(rayfilter == 0)
12174 {
12175 list.Add(new LSL_Integer(0));
12176 return list;
12177 }
12178
12179 // get some more contacts to sort ???
12180 int physcount = 4 * count;
12181 if (physcount > 20)
12182 physcount = 20;
12183
12184 object physresults;
12185 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
12186
12187 if (physresults == null)
12188 {
12189 list.Add(new LSL_Integer(-3)); // timeout error
12190 return list;
12191 }
11249 12192
11250 if (checkPhysical || checkNonPhysical || detectPhantom) 12193 results = (List<ContactResult>)physresults;
12194
12195 // for now physics doesn't detect sitted avatars so do it outside physics
12196 if (checkAgents)
12197 {
12198 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12199 foreach (ContactResult r in agentHits)
12200 results.Add(r);
12201 }
12202
12203 // TODO: Replace this with a better solution. ObjectIntersection can only
12204 // detect nonphysical phantoms. They are detected by virtue of being
12205 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12206 // physicsl phantoms as done by the physics scene
12207 // We don't want anything else but phantoms here.
12208 if (detectPhantom)
12209 {
12210 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12211 foreach (ContactResult r in objectHits)
12212 results.Add(r);
12213 }
12214 }
12215 else
11251 { 12216 {
11252 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12217 if (checkTerrain)
11253 foreach (ContactResult r in objectHits) 12218 {
11254 results.Add(r); 12219 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12220 if (groundContact != null)
12221 results.Add((ContactResult)groundContact);
12222 }
12223
12224 if (checkAgents)
12225 {
12226 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12227 foreach (ContactResult r in agentHits)
12228 results.Add(r);
12229 }
12230
12231 if (checkPhysical || checkNonPhysical || detectPhantom)
12232 {
12233 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12234 foreach (ContactResult r in objectHits)
12235 results.Add(r);
12236 }
11255 } 12237 }
11256 12238
11257 results.Sort(delegate(ContactResult a, ContactResult b) 12239 results.Sort(delegate(ContactResult a, ContactResult b)
11258 { 12240 {
11259 return a.Depth.CompareTo(b.Depth); 12241 return a.Depth.CompareTo(b.Depth);
11260 }); 12242 });
11261 12243
11262 int values = 0; 12244 int values = 0;
11263 SceneObjectGroup thisgrp = m_host.ParentGroup; 12245 SceneObjectGroup thisgrp = m_host.ParentGroup;
11264 12246
@@ -11351,7 +12333,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11351 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12333 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11352 if (!isAccount) return 0; 12334 if (!isAccount) return 0;
11353 if (estate.HasAccess(id)) return 1; 12335 if (estate.HasAccess(id)) return 1;
11354 if (estate.IsBanned(id)) 12336 if (estate.IsBanned(id, World.GetUserFlags(id)))
11355 estate.RemoveBan(id); 12337 estate.RemoveBan(id);
11356 estate.AddEstateUser(id); 12338 estate.AddEstateUser(id);
11357 break; 12339 break;
@@ -11370,14 +12352,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11370 break; 12352 break;
11371 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12353 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11372 if (!isAccount) return 0; 12354 if (!isAccount) return 0;
11373 if (estate.IsBanned(id)) return 1; 12355 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11374 EstateBan ban = new EstateBan(); 12356 EstateBan ban = new EstateBan();
11375 ban.EstateID = estate.EstateID; 12357 ban.EstateID = estate.EstateID;
11376 ban.BannedUserID = id; 12358 ban.BannedUserID = id;
11377 estate.AddBan(ban); 12359 estate.AddBan(ban);
11378 break; 12360 break;
11379 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12361 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11380 if (!isAccount || !estate.IsBanned(id)) return 0; 12362 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11381 estate.RemoveBan(id); 12363 estate.RemoveBan(id);
11382 break; 12364 break;
11383 default: return 0; 12365 default: return 0;
@@ -11406,7 +12388,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11406 return 16384; 12388 return 16384;
11407 } 12389 }
11408 12390
11409 public LSL_Integer llGetUsedMemory() 12391 public virtual LSL_Integer llGetUsedMemory()
11410 { 12392 {
11411 m_host.AddScriptLPS(1); 12393 m_host.AddScriptLPS(1);
11412 // The value returned for LSO scripts in SL 12394 // The value returned for LSO scripts in SL
@@ -11434,22 +12416,731 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11434 public void llSetSoundQueueing(int queue) 12416 public void llSetSoundQueueing(int queue)
11435 { 12417 {
11436 m_host.AddScriptLPS(1); 12418 m_host.AddScriptLPS(1);
11437 NotImplemented("llSetSoundQueueing");
11438 } 12419 }
11439 12420
11440 public void llCollisionSprite(string impact_sprite) 12421 public void llCollisionSprite(string impact_sprite)
11441 { 12422 {
11442 m_host.AddScriptLPS(1); 12423 m_host.AddScriptLPS(1);
11443 NotImplemented("llCollisionSprite"); 12424 // Viewer 2.0 broke this and it's likely LL has no intention
12425 // of fixing it. Therefore, letting this be a NOP seems appropriate.
11444 } 12426 }
11445 12427
11446 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12428 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11447 { 12429 {
11448 m_host.AddScriptLPS(1); 12430 m_host.AddScriptLPS(1);
11449 NotImplemented("llGodLikeRezObject"); 12431
12432 if (!World.Permissions.IsGod(m_host.OwnerID))
12433 NotImplemented("llGodLikeRezObject");
12434
12435 AssetBase rezAsset = World.AssetService.Get(inventory);
12436 if (rezAsset == null)
12437 {
12438 llSay(0, "Asset not found");
12439 return;
12440 }
12441
12442 SceneObjectGroup group = null;
12443
12444 try
12445 {
12446 string xmlData = Utils.BytesToString(rezAsset.Data);
12447 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12448 }
12449 catch
12450 {
12451 llSay(0, "Asset not found");
12452 return;
12453 }
12454
12455 if (group == null)
12456 {
12457 llSay(0, "Asset not found");
12458 return;
12459 }
12460
12461 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12462 group.RootPart.AttachOffset = group.AbsolutePosition;
12463
12464 group.ResetIDs();
12465
12466 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12467 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12468 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12469 group.ScheduleGroupForFullUpdate();
12470
12471 // objects rezzed with this method are die_at_edge by default.
12472 group.RootPart.SetDieAtEdge(true);
12473
12474 group.ResumeScripts();
12475
12476 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12477 "object_rez", new Object[] {
12478 new LSL_String(
12479 group.RootPart.UUID.ToString()) },
12480 new DetectParams[0]));
12481 }
12482
12483 public LSL_String llTransferLindenDollars(string destination, int amount)
12484 {
12485 UUID txn = UUID.Random();
12486
12487 Util.FireAndForget(delegate(object x)
12488 {
12489 int replycode = 0;
12490 string replydata = destination + "," + amount.ToString();
12491
12492 try
12493 {
12494 TaskInventoryItem item = m_item;
12495 if (item == null)
12496 {
12497 replydata = "SERVICE_ERROR";
12498 return;
12499 }
12500
12501 m_host.AddScriptLPS(1);
12502
12503 if (item.PermsGranter == UUID.Zero)
12504 {
12505 replydata = "MISSING_PERMISSION_DEBIT";
12506 return;
12507 }
12508
12509 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12510 {
12511 replydata = "MISSING_PERMISSION_DEBIT";
12512 return;
12513 }
12514
12515 UUID toID = new UUID();
12516
12517 if (!UUID.TryParse(destination, out toID))
12518 {
12519 replydata = "INVALID_AGENT";
12520 return;
12521 }
12522
12523 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12524
12525 if (money == null)
12526 {
12527 replydata = "TRANSFERS_DISABLED";
12528 return;
12529 }
12530
12531 bool result = money.ObjectGiveMoney(
12532 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12533
12534 if (result)
12535 {
12536 replycode = 1;
12537 return;
12538 }
12539
12540 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12541 }
12542 finally
12543 {
12544 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12545 "transaction_result", new Object[] {
12546 new LSL_String(txn.ToString()),
12547 new LSL_Integer(replycode),
12548 new LSL_String(replydata) },
12549 new DetectParams[0]));
12550 }
12551 });
12552
12553 return txn.ToString();
11450 } 12554 }
11451 12555
11452 #endregion 12556 #endregion
12557
12558 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12559 {
12560 SceneObjectGroup group = m_host.ParentGroup;
12561
12562 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12563 return;
12564 if (group.IsAttachment)
12565 return;
12566
12567 if (frames.Data.Length > 0) // We are getting a new motion
12568 {
12569 if (group.RootPart.KeyframeMotion != null)
12570 group.RootPart.KeyframeMotion.Delete();
12571 group.RootPart.KeyframeMotion = null;
12572
12573 int idx = 0;
12574
12575 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12576 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12577
12578 while (idx < options.Data.Length)
12579 {
12580 int option = (int)options.GetLSLIntegerItem(idx++);
12581 int remain = options.Data.Length - idx;
12582
12583 switch (option)
12584 {
12585 case ScriptBaseClass.KFM_MODE:
12586 if (remain < 1)
12587 break;
12588 int modeval = (int)options.GetLSLIntegerItem(idx++);
12589 switch(modeval)
12590 {
12591 case ScriptBaseClass.KFM_FORWARD:
12592 mode = KeyframeMotion.PlayMode.Forward;
12593 break;
12594 case ScriptBaseClass.KFM_REVERSE:
12595 mode = KeyframeMotion.PlayMode.Reverse;
12596 break;
12597 case ScriptBaseClass.KFM_LOOP:
12598 mode = KeyframeMotion.PlayMode.Loop;
12599 break;
12600 case ScriptBaseClass.KFM_PING_PONG:
12601 mode = KeyframeMotion.PlayMode.PingPong;
12602 break;
12603 }
12604 break;
12605 case ScriptBaseClass.KFM_DATA:
12606 if (remain < 1)
12607 break;
12608 int dataval = (int)options.GetLSLIntegerItem(idx++);
12609 data = (KeyframeMotion.DataFormat)dataval;
12610 break;
12611 }
12612 }
12613
12614 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12615
12616 idx = 0;
12617
12618 int elemLength = 2;
12619 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12620 elemLength = 3;
12621
12622 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12623 while (idx < frames.Data.Length)
12624 {
12625 int remain = frames.Data.Length - idx;
12626
12627 if (remain < elemLength)
12628 break;
12629
12630 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12631 frame.Position = null;
12632 frame.Rotation = null;
12633
12634 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12635 {
12636 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12637 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12638 }
12639 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12640 {
12641 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12642 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12643 }
12644
12645 float tempf = (float)frames.GetLSLFloatItem(idx++);
12646 frame.TimeMS = (int)(tempf * 1000.0f);
12647
12648 keyframes.Add(frame);
12649 }
12650
12651 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12652 group.RootPart.KeyframeMotion.Start();
12653 }
12654 else
12655 {
12656 if (group.RootPart.KeyframeMotion == null)
12657 return;
12658
12659 if (options.Data.Length == 0)
12660 {
12661 group.RootPart.KeyframeMotion.Stop();
12662 return;
12663 }
12664
12665 int code = (int)options.GetLSLIntegerItem(0);
12666
12667 int idx = 0;
12668
12669 while (idx < options.Data.Length)
12670 {
12671 int option = (int)options.GetLSLIntegerItem(idx++);
12672 int remain = options.Data.Length - idx;
12673
12674 switch (option)
12675 {
12676 case ScriptBaseClass.KFM_COMMAND:
12677 int cmd = (int)options.GetLSLIntegerItem(idx++);
12678 switch (cmd)
12679 {
12680 case ScriptBaseClass.KFM_CMD_PLAY:
12681 group.RootPart.KeyframeMotion.Start();
12682 break;
12683 case ScriptBaseClass.KFM_CMD_STOP:
12684 group.RootPart.KeyframeMotion.Stop();
12685 break;
12686 case ScriptBaseClass.KFM_CMD_PAUSE:
12687 group.RootPart.KeyframeMotion.Pause();
12688 break;
12689 }
12690 break;
12691 }
12692 }
12693 }
12694 }
12695
12696 protected LSL_List SetPrimParams(ScenePresence av, LSL_List rules, string originFunc, ref uint rulesParsed)
12697 {
12698 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
12699
12700 int idx = 0;
12701 int idxStart = 0;
12702
12703 bool positionChanged = false;
12704 Vector3 finalPos = Vector3.Zero;
12705
12706 try
12707 {
12708 while (idx < rules.Length)
12709 {
12710 ++rulesParsed;
12711 int code = rules.GetLSLIntegerItem(idx++);
12712
12713 int remain = rules.Length - idx;
12714 idxStart = idx;
12715
12716 switch (code)
12717 {
12718 case (int)ScriptBaseClass.PRIM_POSITION:
12719 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
12720 {
12721 if (remain < 1)
12722 return null;
12723
12724 LSL_Vector v;
12725 v = rules.GetVector3Item(idx++);
12726
12727 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12728 if (part == null)
12729 break;
12730
12731 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12732 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12733 if (part.LinkNum > 1)
12734 {
12735 localRot = GetPartLocalRot(part);
12736 localPos = GetPartLocalPos(part);
12737 }
12738
12739 v -= localPos;
12740 v /= localRot;
12741
12742 LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f);
12743
12744 v = v + 2 * sitOffset;
12745
12746 av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z);
12747 av.SendAvatarDataToAllAgents();
12748
12749 }
12750 break;
12751
12752 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
12753 case (int)ScriptBaseClass.PRIM_ROTATION:
12754 {
12755 if (remain < 1)
12756 return null;
12757
12758 LSL_Rotation r;
12759 r = rules.GetQuaternionItem(idx++);
12760
12761 SceneObjectPart part = World.GetSceneObjectPart(av.ParentID);
12762 if (part == null)
12763 break;
12764
12765 LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION;
12766 LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR;
12767
12768 if (part.LinkNum > 1)
12769 localRot = GetPartLocalRot(part);
12770
12771 r = r * llGetRootRotation() / localRot;
12772 av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s);
12773 av.SendAvatarDataToAllAgents();
12774 }
12775 break;
12776
12777 // parse rest doing nothing but number of parameters error check
12778 case (int)ScriptBaseClass.PRIM_SIZE:
12779 case (int)ScriptBaseClass.PRIM_MATERIAL:
12780 case (int)ScriptBaseClass.PRIM_PHANTOM:
12781 case (int)ScriptBaseClass.PRIM_PHYSICS:
12782 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
12783 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12784 case (int)ScriptBaseClass.PRIM_NAME:
12785 case (int)ScriptBaseClass.PRIM_DESC:
12786 if (remain < 1)
12787 return null;
12788 idx++;
12789 break;
12790
12791 case (int)ScriptBaseClass.PRIM_GLOW:
12792 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
12793 case (int)ScriptBaseClass.PRIM_TEXGEN:
12794 if (remain < 2)
12795 return null;
12796 idx += 2;
12797 break;
12798
12799 case (int)ScriptBaseClass.PRIM_TYPE:
12800 if (remain < 3)
12801 return null;
12802 code = (int)rules.GetLSLIntegerItem(idx++);
12803 remain = rules.Length - idx;
12804 switch (code)
12805 {
12806 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
12807 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
12808 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
12809 if (remain < 6)
12810 return null;
12811 idx += 6;
12812 break;
12813
12814 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
12815 if (remain < 5)
12816 return null;
12817 idx += 5;
12818 break;
12819
12820 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
12821 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
12822 case (int)ScriptBaseClass.PRIM_TYPE_RING:
12823 if (remain < 11)
12824 return null;
12825 idx += 11;
12826 break;
12827
12828 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
12829 if (remain < 2)
12830 return null;
12831 idx += 2;
12832 break;
12833 }
12834 break;
12835
12836 case (int)ScriptBaseClass.PRIM_COLOR:
12837 case (int)ScriptBaseClass.PRIM_TEXT:
12838 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
12839 case (int)ScriptBaseClass.PRIM_OMEGA:
12840 if (remain < 3)
12841 return null;
12842 idx += 3;
12843 break;
12844
12845 case (int)ScriptBaseClass.PRIM_TEXTURE:
12846 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
12847 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
12848 if (remain < 5)
12849 return null;
12850 idx += 5;
12851 break;
12852
12853 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
12854 if (remain < 7)
12855 return null;
12856
12857 idx += 7;
12858 break;
12859
12860 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
12861 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
12862 return null;
12863
12864 return rules.GetSublist(idx, -1);
12865 }
12866 }
12867 }
12868 catch (InvalidCastException e)
12869 {
12870 ShoutError(string.Format(
12871 "{0} error running rule #{1}: arg #{2} ",
12872 originFunc, rulesParsed, idx - idxStart) + e.Message);
12873 }
12874 finally
12875 {
12876 if (positionChanged)
12877 {
12878 av.OffsetPosition = finalPos;
12879// av.SendAvatarDataToAllAgents();
12880 av.SendTerseUpdateToAllClients();
12881 positionChanged = false;
12882 }
12883 }
12884 return null;
12885 }
12886
12887 public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules, ref LSL_List res)
12888 {
12889 // avatars case
12890 // replies as SL wiki
12891
12892// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
12893 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
12894
12895 int idx = 0;
12896 while (idx < rules.Length)
12897 {
12898 int code = (int)rules.GetLSLIntegerItem(idx++);
12899 int remain = rules.Length - idx;
12900
12901 switch (code)
12902 {
12903 case (int)ScriptBaseClass.PRIM_MATERIAL:
12904 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
12905 break;
12906
12907 case (int)ScriptBaseClass.PRIM_PHYSICS:
12908 res.Add(new LSL_Integer(0));
12909 break;
12910
12911 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
12912 res.Add(new LSL_Integer(0));
12913 break;
12914
12915 case (int)ScriptBaseClass.PRIM_PHANTOM:
12916 res.Add(new LSL_Integer(0));
12917 break;
12918
12919 case (int)ScriptBaseClass.PRIM_POSITION:
12920
12921 Vector3 pos = avatar.OffsetPosition;
12922
12923 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
12924 pos -= sitOffset;
12925
12926 if( sitPart != null)
12927 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
12928
12929 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
12930 break;
12931
12932 case (int)ScriptBaseClass.PRIM_SIZE:
12933 // as in llGetAgentSize above
12934 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
12935 break;
12936
12937 case (int)ScriptBaseClass.PRIM_ROTATION:
12938 Quaternion rot = avatar.Rotation;
12939 if (sitPart != null)
12940 {
12941 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
12942 }
12943
12944 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
12945 break;
12946
12947 case (int)ScriptBaseClass.PRIM_TYPE:
12948 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
12949 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
12950 res.Add(new LSL_Vector(0f,1.0f,0f));
12951 res.Add(new LSL_Float(0.0f));
12952 res.Add(new LSL_Vector(0, 0, 0));
12953 res.Add(new LSL_Vector(1.0f,1.0f,0f));
12954 res.Add(new LSL_Vector(0, 0, 0));
12955 break;
12956
12957 case (int)ScriptBaseClass.PRIM_TEXTURE:
12958 if (remain < 1)
12959 return null;
12960
12961 int face = (int)rules.GetLSLIntegerItem(idx++);
12962 if (face == ScriptBaseClass.ALL_SIDES)
12963 {
12964 for (face = 0; face < 21; face++)
12965 {
12966 res.Add(new LSL_String(""));
12967 res.Add(new LSL_Vector(0,0,0));
12968 res.Add(new LSL_Vector(0,0,0));
12969 res.Add(new LSL_Float(0.0));
12970 }
12971 }
12972 else
12973 {
12974 if (face >= 0 && face < 21)
12975 {
12976 res.Add(new LSL_String(""));
12977 res.Add(new LSL_Vector(0,0,0));
12978 res.Add(new LSL_Vector(0,0,0));
12979 res.Add(new LSL_Float(0.0));
12980 }
12981 }
12982 break;
12983
12984 case (int)ScriptBaseClass.PRIM_COLOR:
12985 if (remain < 1)
12986 return null;
12987
12988 face = (int)rules.GetLSLIntegerItem(idx++);
12989
12990 if (face == ScriptBaseClass.ALL_SIDES)
12991 {
12992 for (face = 0; face < 21; face++)
12993 {
12994 res.Add(new LSL_Vector(0,0,0));
12995 res.Add(new LSL_Float(0));
12996 }
12997 }
12998 else
12999 {
13000 res.Add(new LSL_Vector(0,0,0));
13001 res.Add(new LSL_Float(0));
13002 }
13003 break;
13004
13005 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
13006 if (remain < 1)
13007 return null;
13008 face = (int)rules.GetLSLIntegerItem(idx++);
13009
13010 if (face == ScriptBaseClass.ALL_SIDES)
13011 {
13012 for (face = 0; face < 21; face++)
13013 {
13014 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13015 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13016 }
13017 }
13018 else
13019 {
13020 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
13021 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
13022 }
13023 break;
13024
13025 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
13026 if (remain < 1)
13027 return null;
13028 face = (int)rules.GetLSLIntegerItem(idx++);
13029
13030 if (face == ScriptBaseClass.ALL_SIDES)
13031 {
13032 for (face = 0; face < 21; face++)
13033 {
13034 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13035 }
13036 }
13037 else
13038 {
13039 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
13040 }
13041 break;
13042
13043 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
13044 res.Add(new LSL_Integer(0));
13045 res.Add(new LSL_Integer(0));// softness
13046 res.Add(new LSL_Float(0.0f)); // gravity
13047 res.Add(new LSL_Float(0.0f)); // friction
13048 res.Add(new LSL_Float(0.0f)); // wind
13049 res.Add(new LSL_Float(0.0f)); // tension
13050 res.Add(new LSL_Vector(0f,0f,0f));
13051 break;
13052
13053 case (int)ScriptBaseClass.PRIM_TEXGEN:
13054 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
13055 if (remain < 1)
13056 return null;
13057 face = (int)rules.GetLSLIntegerItem(idx++);
13058
13059 if (face == ScriptBaseClass.ALL_SIDES)
13060 {
13061 for (face = 0; face < 21; face++)
13062 {
13063 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13064 }
13065 }
13066 else
13067 {
13068 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
13069 }
13070 break;
13071
13072 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
13073 res.Add(new LSL_Integer(0));
13074 res.Add(new LSL_Vector(0f,0f,0f));
13075 res.Add(new LSL_Float(0f)); // intensity
13076 res.Add(new LSL_Float(0f)); // radius
13077 res.Add(new LSL_Float(0f)); // falloff
13078 break;
13079
13080 case (int)ScriptBaseClass.PRIM_GLOW:
13081 if (remain < 1)
13082 return null;
13083 face = (int)rules.GetLSLIntegerItem(idx++);
13084
13085 if (face == ScriptBaseClass.ALL_SIDES)
13086 {
13087 for (face = 0; face < 21; face++)
13088 {
13089 res.Add(new LSL_Float(0f));
13090 }
13091 }
13092 else
13093 {
13094 res.Add(new LSL_Float(0f));
13095 }
13096 break;
13097
13098 case (int)ScriptBaseClass.PRIM_TEXT:
13099 res.Add(new LSL_String(""));
13100 res.Add(new LSL_Vector(0f,0f,0f));
13101 res.Add(new LSL_Float(1.0f));
13102 break;
13103
13104 case (int)ScriptBaseClass.PRIM_NAME:
13105 res.Add(new LSL_String(avatar.Name));
13106 break;
13107
13108 case (int)ScriptBaseClass.PRIM_DESC:
13109 res.Add(new LSL_String(""));
13110 break;
13111
13112 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
13113 Quaternion lrot = avatar.Rotation;
13114
13115 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13116 {
13117 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
13118 }
13119 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
13120 break;
13121
13122 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
13123 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
13124 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
13125 lpos -= lsitOffset;
13126
13127 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
13128 {
13129 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
13130 }
13131 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
13132 break;
13133
13134 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
13135 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
13136 return null;
13137
13138 return rules.GetSublist(idx, -1);
13139 }
13140 }
13141
13142 return null;
13143 }
11453 } 13144 }
11454 13145
11455 public class NotecardCache 13146 public class NotecardCache