aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs20
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs116
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs3212
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs102
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs32
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs46
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs11
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs71
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs51
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs21
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Helpers.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs86
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs39
18 files changed, 3002 insertions, 860 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
index 5b22860..693992a 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/AsyncCommandManager.cs
@@ -304,6 +304,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
304 return null; 304 return null;
305 } 305 }
306 306
307 public static void StateChange(IScriptEngine engine, uint localID, UUID itemID)
308 {
309 // Remove a specific script
310
311 // Remove dataserver events
312 m_Dataserver[engine].RemoveEvents(localID, itemID);
313
314 IWorldComm comms = engine.World.RequestModuleInterface<IWorldComm>();
315 if (comms != null)
316 comms.DeleteListener(itemID);
317
318 IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
319 xmlrpc.DeleteChannels(itemID);
320 xmlrpc.CancelSRDRequests(itemID);
321
322 // Remove Sensors
323 m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);
324
325 }
326
307 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID) 327 public static Object[] GetSerializationData(IScriptEngine engine, UUID itemID)
308 { 328 {
309 List<Object> data = new List<Object>(); 329 List<Object> data = new List<Object>();
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
new file mode 100644
index 0000000..b5fa6de
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/CM_Api.cs
@@ -0,0 +1,116 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
26 */
27
28using System;
29using System.Reflection;
30using System.Collections;
31using System.Collections.Generic;
32using System.Runtime.Remoting.Lifetime;
33using OpenMetaverse;
34using Nini.Config;
35using OpenSim;
36using OpenSim.Framework;
37using OpenSim.Region.CoreModules.World.LightShare;
38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes;
40using OpenSim.Region.ScriptEngine.Shared;
41using OpenSim.Region.ScriptEngine.Shared.Api.Plugins;
42using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
43using OpenSim.Region.ScriptEngine.Interfaces;
44using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
45using OpenSim.Services.Interfaces;
46
47using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
48using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
49using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
50using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
51using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
52using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
53using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
54
55namespace OpenSim.Region.ScriptEngine.Shared.Api
56{
57 [Serializable]
58 public class CM_Api : MarshalByRefObject, ICM_Api, IScriptApi
59 {
60 internal IScriptEngine m_ScriptEngine;
61 internal SceneObjectPart m_host;
62 internal TaskInventoryItem m_item;
63 internal bool m_CMFunctionsEnabled = false;
64
65 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
66 {
67 m_ScriptEngine = ScriptEngine;
68 m_host = host;
69 m_item = item;
70
71 if (m_ScriptEngine.Config.GetBoolean("AllowCareminsterFunctions", false))
72 m_CMFunctionsEnabled = true;
73 }
74
75 public override Object InitializeLifetimeService()
76 {
77 ILease lease = (ILease)base.InitializeLifetimeService();
78
79 if (lease.CurrentState == LeaseState.Initial)
80 {
81 lease.InitialLeaseTime = TimeSpan.FromMinutes(0);
82 // lease.RenewOnCallTime = TimeSpan.FromSeconds(10.0);
83 // lease.SponsorshipTimeout = TimeSpan.FromMinutes(1.0);
84 }
85 return lease;
86 }
87
88 public Scene World
89 {
90 get { return m_ScriptEngine.World; }
91 }
92
93 public string cmDetectedCountry(int number)
94 {
95 m_host.AddScriptLPS(1);
96 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, number);
97 if (detectedParams == null)
98 return String.Empty;
99 return detectedParams.Country;
100 }
101
102 public string cmGetAgentCountry(LSL_Key key)
103 {
104 if (!World.Permissions.IsGod(m_host.OwnerID))
105 return String.Empty;
106
107 UUID uuid;
108
109 if (!UUID.TryParse(key, out uuid))
110 return String.Empty;
111
112 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
113 return account.UserCountry;
114 }
115 }
116}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 0ebcd8d..fed3122 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -28,10 +28,12 @@
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;
@@ -65,6 +68,7 @@ using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
65using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; 68using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
66using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; 69using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
67using System.Reflection; 70using System.Reflection;
71using Timer = System.Timers.Timer;
68 72
69namespace OpenSim.Region.ScriptEngine.Shared.Api 73namespace OpenSim.Region.ScriptEngine.Shared.Api
70{ 74{
@@ -103,15 +107,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
103 protected int m_notecardLineReadCharsMax = 255; 107 protected int m_notecardLineReadCharsMax = 255;
104 protected int m_scriptConsoleChannel = 0; 108 protected int m_scriptConsoleChannel = 0;
105 protected bool m_scriptConsoleChannelEnabled = false; 109 protected bool m_scriptConsoleChannelEnabled = false;
110 protected bool m_debuggerSafe = false;
106 protected IUrlModule m_UrlModule = null; 111 protected IUrlModule m_UrlModule = null;
107 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache = new Dictionary<UUID, UserInfoCacheEntry>(); 112 protected Dictionary<UUID, UserInfoCacheEntry> m_userInfoCache =
108 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. 113 new Dictionary<UUID, UserInfoCacheEntry>();
114 protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp.
115
116// protected Timer m_ShoutSayTimer;
117 protected int m_SayShoutCount = 0;
118 DateTime m_lastSayShoutCheck;
119
120 private Dictionary<string, string> MovementAnimationsForLSL =
121 new Dictionary<string, string> {
122 {"FLY", "Flying"},
123 {"FLYSLOW", "FlyingSlow"},
124 {"HOVER_UP", "Hovering Up"},
125 {"HOVER_DOWN", "Hovering Down"},
126 {"HOVER", "Hovering"},
127 {"LAND", "Landing"},
128 {"FALLDOWN", "Falling Down"},
129 {"PREJUMP", "PreJumping"},
130 {"JUMP", "Jumping"},
131 {"STANDUP", "Standing Up"},
132 {"SOFT_LAND", "Soft Landing"},
133 {"STAND", "Standing"},
134 {"CROUCHWALK", "CrouchWalking"},
135 {"RUN", "Running"},
136 {"WALK", "Walking"},
137 {"CROUCH", "Crouching"},
138 {"TURNLEFT", "Turning Left"},
139 {"TURNRIGHT", "Turning Right"}
140 };
109 141
110 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 142 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
111 { 143 {
144/*
145 m_ShoutSayTimer = new Timer(1000);
146 m_ShoutSayTimer.Elapsed += SayShoutTimerElapsed;
147 m_ShoutSayTimer.AutoReset = true;
148 m_ShoutSayTimer.Start();
149*/
150 m_lastSayShoutCheck = DateTime.UtcNow;
151
112 m_ScriptEngine = ScriptEngine; 152 m_ScriptEngine = ScriptEngine;
113 m_host = host; 153 m_host = host;
114 m_item = item; 154 m_item = item;
155 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
115 156
116 LoadLimits(); // read script limits from config. 157 LoadLimits(); // read script limits from config.
117 158
@@ -171,6 +212,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
171 get { return m_ScriptEngine.World; } 212 get { return m_ScriptEngine.World; }
172 } 213 }
173 214
215 [DebuggerNonUserCode]
174 public void state(string newState) 216 public void state(string newState)
175 { 217 {
176 m_ScriptEngine.SetState(m_item.ItemID, newState); 218 m_ScriptEngine.SetState(m_item.ItemID, newState);
@@ -180,6 +222,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
180 /// Reset the named script. The script must be present 222 /// Reset the named script. The script must be present
181 /// in the same prim. 223 /// in the same prim.
182 /// </summary> 224 /// </summary>
225 [DebuggerNonUserCode]
183 public void llResetScript() 226 public void llResetScript()
184 { 227 {
185 m_host.AddScriptLPS(1); 228 m_host.AddScriptLPS(1);
@@ -236,9 +279,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
236 } 279 }
237 } 280 }
238 281
282 public List<ScenePresence> GetLinkAvatars(int linkType)
283 {
284 List<ScenePresence> ret = new List<ScenePresence>();
285 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
286 return ret;
287
288 List<ScenePresence> avs = m_host.ParentGroup.GetLinkedAvatars();
289
290 switch (linkType)
291 {
292 case ScriptBaseClass.LINK_SET:
293 return avs;
294
295 case ScriptBaseClass.LINK_ROOT:
296 return ret;
297
298 case ScriptBaseClass.LINK_ALL_OTHERS:
299 return avs;
300
301 case ScriptBaseClass.LINK_ALL_CHILDREN:
302 return avs;
303
304 case ScriptBaseClass.LINK_THIS:
305 return ret;
306
307 default:
308 if (linkType < 0)
309 return ret;
310
311 int partCount = m_host.ParentGroup.GetPartCount();
312
313 if (linkType <= partCount)
314 {
315 return ret;
316 }
317 else
318 {
319 linkType = linkType - partCount;
320 if (linkType > avs.Count)
321 {
322 return ret;
323 }
324 else
325 {
326 ret.Add(avs[linkType-1]);
327 return ret;
328 }
329 }
330 }
331 }
332
239 public List<SceneObjectPart> GetLinkParts(int linkType) 333 public List<SceneObjectPart> GetLinkParts(int linkType)
240 { 334 {
241 List<SceneObjectPart> ret = new List<SceneObjectPart>(); 335 List<SceneObjectPart> ret = new List<SceneObjectPart>();
336 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
337 return ret;
242 ret.Add(m_host); 338 ret.Add(m_host);
243 339
244 switch (linkType) 340 switch (linkType)
@@ -432,31 +528,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
432 528
433 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 529 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
434 530
435 /// <summary> 531 // Utility function for llRot2Euler
436 /// Convert an LSL rotation to a Euler vector. 532
437 /// </summary> 533 // normalize an angle between -PI and PI (-180 to +180 degrees)
438 /// <remarks> 534 protected double NormalizeAngle(double angle)
439 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
440 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
441 /// </remarks>
442 /// <param name="r"></param>
443 /// <returns></returns>
444 public LSL_Vector llRot2Euler(LSL_Rotation r)
445 { 535 {
446 m_host.AddScriptLPS(1); 536 if (angle > -Math.PI && angle < Math.PI)
537 return angle;
538
539 int numPis = (int)(Math.PI / angle);
540 double remainder = angle - Math.PI * numPis;
541 if (numPis % 2 == 1)
542 return Math.PI - angle;
543 return remainder;
544 }
447 545
448 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r. 546 public LSL_Vector llRot2Euler(LSL_Rotation q1)
449 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later. 547 {
450 if (m == 0.0) return new LSL_Vector(); 548 m_host.AddScriptLPS(1);
451 double x = Math.Atan2(-v.y, v.z); 549 LSL_Vector eul = new LSL_Vector();
452 double sin = v.x / m;
453 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
454 double y = Math.Asin(sin);
455 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
456 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)));
457 double z = Math.Atan2(v.y, v.x);
458 550
459 return new LSL_Vector(x, y, z); 551 double sqw = q1.s*q1.s;
552 double sqx = q1.x*q1.x;
553 double sqy = q1.z*q1.z;
554 double sqz = q1.y*q1.y;
555 double unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
556 double test = q1.x*q1.z + q1.y*q1.s;
557 if (test > 0.4999*unit) { // singularity at north pole
558 eul.z = 2 * Math.Atan2(q1.x,q1.s);
559 eul.y = Math.PI/2;
560 eul.x = 0;
561 return eul;
562 }
563 if (test < -0.4999*unit) { // singularity at south pole
564 eul.z = -2 * Math.Atan2(q1.x,q1.s);
565 eul.y = -Math.PI/2;
566 eul.x = 0;
567 return eul;
568 }
569 eul.z = Math.Atan2(2*q1.z*q1.s-2*q1.x*q1.y , sqx - sqy - sqz + sqw);
570 eul.y = Math.Asin(2*test/unit);
571 eul.x = Math.Atan2(2*q1.x*q1.s-2*q1.z*q1.y , -sqx + sqy - sqz + sqw);
572 return eul;
460 } 573 }
461 574
462 /* From wiki: 575 /* From wiki:
@@ -509,18 +622,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
509 m_host.AddScriptLPS(1); 622 m_host.AddScriptLPS(1);
510 623
511 double x,y,z,s; 624 double x,y,z,s;
512 625 v.x *= 0.5;
513 double c1 = Math.Cos(v.x * 0.5); 626 v.y *= 0.5;
514 double c2 = Math.Cos(v.y * 0.5); 627 v.z *= 0.5;
515 double c3 = Math.Cos(v.z * 0.5); 628 double c1 = Math.Cos(v.x);
516 double s1 = Math.Sin(v.x * 0.5); 629 double c2 = Math.Cos(v.y);
517 double s2 = Math.Sin(v.y * 0.5); 630 double c1c2 = c1 * c2;
518 double s3 = Math.Sin(v.z * 0.5); 631 double s1 = Math.Sin(v.x);
519 632 double s2 = Math.Sin(v.y);
520 x = s1 * c2 * c3 + c1 * s2 * s3; 633 double s1s2 = s1 * s2;
521 y = c1 * s2 * c3 - s1 * c2 * s3; 634 double c1s2 = c1 * s2;
522 z = s1 * s2 * c3 + c1 * c2 * s3; 635 double s1c2 = s1 * c2;
523 s = c1 * c2 * c3 - s1 * s2 * s3; 636 double c3 = Math.Cos(v.z);
637 double s3 = Math.Sin(v.z);
638
639 x = s1c2 * c3 + c1s2 * s3;
640 y = c1s2 * c3 - s1c2 * s3;
641 z = s1s2 * c3 + c1c2 * s3;
642 s = c1c2 * c3 - s1s2 * s3;
524 643
525 return new LSL_Rotation(x, y, z, s); 644 return new LSL_Rotation(x, y, z, s);
526 } 645 }
@@ -658,77 +777,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
658 { 777 {
659 //A and B should both be normalized 778 //A and B should both be normalized
660 m_host.AddScriptLPS(1); 779 m_host.AddScriptLPS(1);
661 LSL_Rotation rotBetween; 780 /* This method is more accurate than the SL one, and thus causes problems
662 // Check for zero vectors. If either is zero, return zero rotation. Otherwise, 781 for scripts that deal with the SL inaccuracy around 180-degrees -.- .._.
663 // continue calculation. 782
664 if (a == new LSL_Vector(0.0f, 0.0f, 0.0f) || b == new LSL_Vector(0.0f, 0.0f, 0.0f)) 783 double dotProduct = LSL_Vector.Dot(a, b);
784 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
785 double magProduct = LSL_Vector.Mag(a) * LSL_Vector.Mag(b);
786 double angle = Math.Acos(dotProduct / magProduct);
787 LSL_Vector axis = LSL_Vector.Norm(crossProduct);
788 double s = Math.Sin(angle / 2);
789
790 double x = axis.x * s;
791 double y = axis.y * s;
792 double z = axis.z * s;
793 double w = Math.Cos(angle / 2);
794
795 if (Double.IsNaN(x) || Double.IsNaN(y) || Double.IsNaN(z) || Double.IsNaN(w))
796 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
797
798 return new LSL_Rotation((float)x, (float)y, (float)z, (float)w);
799 */
800
801 // This method mimics the 180 errors found in SL
802 // See www.euclideanspace.com... angleBetween
803 LSL_Vector vec_a = a;
804 LSL_Vector vec_b = b;
805
806 // Eliminate zero length
807 LSL_Float vec_a_mag = LSL_Vector.Mag(vec_a);
808 LSL_Float vec_b_mag = LSL_Vector.Mag(vec_b);
809 if (vec_a_mag < 0.00001 ||
810 vec_b_mag < 0.00001)
665 { 811 {
666 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f); 812 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
667 } 813 }
668 else 814
815 // Normalize
816 vec_a = llVecNorm(vec_a);
817 vec_b = llVecNorm(vec_b);
818
819 // Calculate axis and rotation angle
820 LSL_Vector axis = vec_a % vec_b;
821 LSL_Float cos_theta = vec_a * vec_b;
822
823 // Check if parallel
824 if (cos_theta > 0.99999)
669 { 825 {
670 a = LSL_Vector.Norm(a); 826 return new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
671 b = LSL_Vector.Norm(b); 827 }
672 double dotProduct = LSL_Vector.Dot(a, b); 828
673 // There are two degenerate cases possible. These are for vectors 180 or 829 // Check if anti-parallel
674 // 0 degrees apart. These have to be detected and handled individually. 830 else if (cos_theta < -0.99999)
675 // 831 {
676 // Check for vectors 180 degrees apart. 832 LSL_Vector orthog_axis = new LSL_Vector(1.0, 0.0, 0.0) - (vec_a.x / (vec_a * vec_a) * vec_a);
677 // A dot product of -1 would mean the angle between vectors is 180 degrees. 833 if (LSL_Vector.Mag(orthog_axis) < 0.000001) orthog_axis = new LSL_Vector(0.0, 0.0, 1.0);
678 if (dotProduct < -0.9999999f) 834 return new LSL_Rotation((float)orthog_axis.x, (float)orthog_axis.y, (float)orthog_axis.z, 0.0);
679 { 835 }
680 // First assume X axis is orthogonal to the vectors. 836 else // other rotation
681 LSL_Vector orthoVector = new LSL_Vector(1.0f, 0.0f, 0.0f); 837 {
682 orthoVector = orthoVector - a * (a.x / LSL_Vector.Dot(a, a)); 838 LSL_Float theta = (LSL_Float)Math.Acos(cos_theta) * 0.5f;
683 // Check for near zero vector. A very small non-zero number here will create 839 axis = llVecNorm(axis);
684 // a rotation in an undesired direction. 840 double x, y, z, s, t;
685 if (LSL_Vector.Mag(orthoVector) > 0.0001) 841 s = Math.Cos(theta);
686 { 842 t = Math.Sin(theta);
687 rotBetween = new LSL_Rotation(orthoVector.x, orthoVector.y, orthoVector.z, 0.0f); 843 x = axis.x * t;
688 } 844 y = axis.y * t;
689 // If the magnitude of the vector was near zero, then assume the X axis is not 845 z = axis.z * t;
690 // orthogonal and use the Z axis instead. 846 return new LSL_Rotation(x,y,z,s);
691 else
692 {
693 // Set 180 z rotation.
694 rotBetween = new LSL_Rotation(0.0f, 0.0f, 1.0f, 0.0f);
695 }
696 }
697 // Check for parallel vectors.
698 // A dot product of 1 would mean the angle between vectors is 0 degrees.
699 else if (dotProduct > 0.9999999f)
700 {
701 // Set zero rotation.
702 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
703 }
704 else
705 {
706 // All special checks have been performed so get the axis of rotation.
707 LSL_Vector crossProduct = LSL_Vector.Cross(a, b);
708 // Quarternion s value is the length of the unit vector + dot product.
709 double qs = 1.0 + dotProduct;
710 rotBetween = new LSL_Rotation(crossProduct.x, crossProduct.y, crossProduct.z, qs);
711 // Normalize the rotation.
712 double mag = LSL_Rotation.Mag(rotBetween);
713 // We shouldn't have to worry about a divide by zero here. The qs value will be
714 // non-zero because we already know if we're here, then the dotProduct is not -1 so
715 // qs will not be zero. Also, we've already handled the input vectors being zero so the
716 // crossProduct vector should also not be zero.
717 rotBetween.x = rotBetween.x / mag;
718 rotBetween.y = rotBetween.y / mag;
719 rotBetween.z = rotBetween.z / mag;
720 rotBetween.s = rotBetween.s / mag;
721 // Check for undefined values and set zero rotation if any found. This code might not actually be required
722 // any longer since zero vectors are checked for at the top.
723 if (Double.IsNaN(rotBetween.x) || Double.IsNaN(rotBetween.y) || Double.IsNaN(rotBetween.z) || Double.IsNaN(rotBetween.s))
724 {
725 rotBetween = new LSL_Rotation(0.0f, 0.0f, 0.0f, 1.0f);
726 }
727 }
728 } 847 }
729 return rotBetween;
730 } 848 }
731 849
732 public void llWhisper(int channelID, string text) 850 public void llWhisper(int channelID, string text)
733 { 851 {
734 m_host.AddScriptLPS(1); 852 m_host.AddScriptLPS(1);
@@ -744,10 +862,29 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
744 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text); 862 wComm.DeliverMessage(ChatTypeEnum.Whisper, channelID, m_host.Name, m_host.UUID, text);
745 } 863 }
746 864
865 private void CheckSayShoutTime()
866 {
867 DateTime now = DateTime.UtcNow;
868 if ((now - m_lastSayShoutCheck).Ticks > 10000000) // 1sec
869 {
870 m_lastSayShoutCheck = now;
871 m_SayShoutCount = 0;
872 }
873 else
874 m_SayShoutCount++;
875 }
876
747 public void llSay(int channelID, string text) 877 public void llSay(int channelID, string text)
748 { 878 {
749 m_host.AddScriptLPS(1); 879 m_host.AddScriptLPS(1);
750 880
881 if (channelID == 0)
882// m_SayShoutCount++;
883 CheckSayShoutTime();
884
885 if (m_SayShoutCount >= 11)
886 ScriptSleep(2000);
887
751 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel)) 888 if (m_scriptConsoleChannelEnabled && (channelID == m_scriptConsoleChannel))
752 { 889 {
753 Console.WriteLine(text); 890 Console.WriteLine(text);
@@ -770,6 +907,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
770 { 907 {
771 m_host.AddScriptLPS(1); 908 m_host.AddScriptLPS(1);
772 909
910 if (channelID == 0)
911// m_SayShoutCount++;
912 CheckSayShoutTime();
913
914 if (m_SayShoutCount >= 11)
915 ScriptSleep(2000);
916
773 if (text.Length > 1023) 917 if (text.Length > 1023)
774 text = text.Substring(0, 1023); 918 text = text.Substring(0, 1023);
775 919
@@ -801,22 +945,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
801 945
802 public void llRegionSayTo(string target, int channel, string msg) 946 public void llRegionSayTo(string target, int channel, string msg)
803 { 947 {
948 string error = String.Empty;
949
804 if (msg.Length > 1023) 950 if (msg.Length > 1023)
805 msg = msg.Substring(0, 1023); 951 msg = msg.Substring(0, 1023);
806 952
807 m_host.AddScriptLPS(1); 953 m_host.AddScriptLPS(1);
808 954
809 if (channel == ScriptBaseClass.DEBUG_CHANNEL)
810 {
811 return;
812 }
813
814 UUID TargetID; 955 UUID TargetID;
815 UUID.TryParse(target, out TargetID); 956 UUID.TryParse(target, out TargetID);
816 957
817 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>(); 958 IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
818 if (wComm != null) 959 if (wComm != null)
819 wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg); 960 if (!wComm.DeliverMessageTo(TargetID, channel, m_host.AbsolutePosition, m_host.Name, m_host.UUID, msg, out error))
961 LSLError(error);
820 } 962 }
821 963
822 public LSL_Integer llListen(int channelID, string name, string ID, string msg) 964 public LSL_Integer llListen(int channelID, string name, string ID, string msg)
@@ -1072,10 +1214,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1072 return detectedParams.TouchUV; 1214 return detectedParams.TouchUV;
1073 } 1215 }
1074 1216
1217 [DebuggerNonUserCode]
1075 public virtual void llDie() 1218 public virtual void llDie()
1076 { 1219 {
1077 m_host.AddScriptLPS(1); 1220 m_host.AddScriptLPS(1);
1078 throw new SelfDeleteException(); 1221 if (!m_host.ParentGroup.IsAttachment) throw new SelfDeleteException();
1079 } 1222 }
1080 1223
1081 public LSL_Float llGround(LSL_Vector offset) 1224 public LSL_Float llGround(LSL_Vector offset)
@@ -1148,6 +1291,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1148 1291
1149 public void llSetStatus(int status, int value) 1292 public void llSetStatus(int status, int value)
1150 { 1293 {
1294 if (m_host == null || m_host.ParentGroup == null || m_host.ParentGroup.IsDeleted)
1295 return;
1151 m_host.AddScriptLPS(1); 1296 m_host.AddScriptLPS(1);
1152 1297
1153 int statusrotationaxis = 0; 1298 int statusrotationaxis = 0;
@@ -1171,6 +1316,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1171 if (!allow) 1316 if (!allow)
1172 return; 1317 return;
1173 1318
1319 if (m_host.ParentGroup.RootPart.PhysActor != null &&
1320 m_host.ParentGroup.RootPart.PhysActor.IsPhysical)
1321 return;
1322
1174 m_host.ScriptSetPhysicsStatus(true); 1323 m_host.ScriptSetPhysicsStatus(true);
1175 } 1324 }
1176 else 1325 else
@@ -1379,6 +1528,48 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1379 { 1528 {
1380 m_host.AddScriptLPS(1); 1529 m_host.AddScriptLPS(1);
1381 1530
1531 SetColor(m_host, color, face);
1532 }
1533
1534 protected void SetColor(SceneObjectPart part, LSL_Vector color, int face)
1535 {
1536 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1537 return;
1538
1539 Primitive.TextureEntry tex = part.Shape.Textures;
1540 Color4 texcolor;
1541 if (face >= 0 && face < GetNumberOfSides(part))
1542 {
1543 texcolor = tex.CreateFace((uint)face).RGBA;
1544 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1545 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1546 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1547 tex.FaceTextures[face].RGBA = texcolor;
1548 part.UpdateTextureEntry(tex.GetBytes());
1549 return;
1550 }
1551 else if (face == ScriptBaseClass.ALL_SIDES)
1552 {
1553 for (uint i = 0; i < GetNumberOfSides(part); i++)
1554 {
1555 if (tex.FaceTextures[i] != null)
1556 {
1557 texcolor = tex.FaceTextures[i].RGBA;
1558 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1559 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1560 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1561 tex.FaceTextures[i].RGBA = texcolor;
1562 }
1563 texcolor = tex.DefaultTexture.RGBA;
1564 texcolor.R = Util.Clip((float)color.x, 0.0f, 1.0f);
1565 texcolor.G = Util.Clip((float)color.y, 0.0f, 1.0f);
1566 texcolor.B = Util.Clip((float)color.z, 0.0f, 1.0f);
1567 tex.DefaultTexture.RGBA = texcolor;
1568 }
1569 part.UpdateTextureEntry(tex.GetBytes());
1570 return;
1571 }
1572
1382 if (face == ScriptBaseClass.ALL_SIDES) 1573 if (face == ScriptBaseClass.ALL_SIDES)
1383 face = SceneObjectPart.ALL_SIDES; 1574 face = SceneObjectPart.ALL_SIDES;
1384 1575
@@ -1387,6 +1578,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1387 1578
1388 public void SetTexGen(SceneObjectPart part, int face,int style) 1579 public void SetTexGen(SceneObjectPart part, int face,int style)
1389 { 1580 {
1581 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1582 return;
1583
1390 Primitive.TextureEntry tex = part.Shape.Textures; 1584 Primitive.TextureEntry tex = part.Shape.Textures;
1391 MappingType textype; 1585 MappingType textype;
1392 textype = MappingType.Default; 1586 textype = MappingType.Default;
@@ -1417,6 +1611,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1417 1611
1418 public void SetGlow(SceneObjectPart part, int face, float glow) 1612 public void SetGlow(SceneObjectPart part, int face, float glow)
1419 { 1613 {
1614 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return;
1616
1420 Primitive.TextureEntry tex = part.Shape.Textures; 1617 Primitive.TextureEntry tex = part.Shape.Textures;
1421 if (face >= 0 && face < GetNumberOfSides(part)) 1618 if (face >= 0 && face < GetNumberOfSides(part))
1422 { 1619 {
@@ -1442,6 +1639,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1442 1639
1443 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump) 1640 public void SetShiny(SceneObjectPart part, int face, int shiny, Bumpiness bump)
1444 { 1641 {
1642 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1643 return;
1445 1644
1446 Shininess sval = new Shininess(); 1645 Shininess sval = new Shininess();
1447 1646
@@ -1492,6 +1691,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1492 1691
1493 public void SetFullBright(SceneObjectPart part, int face, bool bright) 1692 public void SetFullBright(SceneObjectPart part, int face, bool bright)
1494 { 1693 {
1694 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1695 return;
1696
1495 Primitive.TextureEntry tex = part.Shape.Textures; 1697 Primitive.TextureEntry tex = part.Shape.Textures;
1496 if (face >= 0 && face < GetNumberOfSides(part)) 1698 if (face >= 0 && face < GetNumberOfSides(part))
1497 { 1699 {
@@ -1552,13 +1754,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1552 m_host.AddScriptLPS(1); 1754 m_host.AddScriptLPS(1);
1553 1755
1554 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1756 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1555 1757 if (parts.Count > 0)
1556 foreach (SceneObjectPart part in parts) 1758 {
1557 SetAlpha(part, alpha, face); 1759 try
1760 {
1761 parts[0].ParentGroup.areUpdatesSuspended = true;
1762 foreach (SceneObjectPart part in parts)
1763 SetAlpha(part, alpha, face);
1764 }
1765 finally
1766 {
1767 parts[0].ParentGroup.areUpdatesSuspended = false;
1768 }
1769 }
1558 } 1770 }
1559 1771
1560 protected void SetAlpha(SceneObjectPart part, double alpha, int face) 1772 protected void SetAlpha(SceneObjectPart part, double alpha, int face)
1561 { 1773 {
1774 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1775 return;
1776
1562 Primitive.TextureEntry tex = part.Shape.Textures; 1777 Primitive.TextureEntry tex = part.Shape.Textures;
1563 Color4 texcolor; 1778 Color4 texcolor;
1564 if (face >= 0 && face < GetNumberOfSides(part)) 1779 if (face >= 0 && face < GetNumberOfSides(part))
@@ -1611,7 +1826,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1611 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction, 1826 protected void SetFlexi(SceneObjectPart part, bool flexi, int softness, float gravity, float friction,
1612 float wind, float tension, LSL_Vector Force) 1827 float wind, float tension, LSL_Vector Force)
1613 { 1828 {
1614 if (part == null) 1829 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1615 return; 1830 return;
1616 1831
1617 if (flexi) 1832 if (flexi)
@@ -1645,7 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1645 /// <param name="falloff"></param> 1860 /// <param name="falloff"></param>
1646 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff) 1861 protected void SetPointLight(SceneObjectPart part, bool light, LSL_Vector color, float intensity, float radius, float falloff)
1647 { 1862 {
1648 if (part == null) 1863 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1649 return; 1864 return;
1650 1865
1651 if (light) 1866 if (light)
@@ -1678,11 +1893,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1678 Primitive.TextureEntry tex = part.Shape.Textures; 1893 Primitive.TextureEntry tex = part.Shape.Textures;
1679 Color4 texcolor; 1894 Color4 texcolor;
1680 LSL_Vector rgb = new LSL_Vector(); 1895 LSL_Vector rgb = new LSL_Vector();
1896 int nsides = GetNumberOfSides(part);
1897
1681 if (face == ScriptBaseClass.ALL_SIDES) 1898 if (face == ScriptBaseClass.ALL_SIDES)
1682 { 1899 {
1683 int i; 1900 int i;
1684 1901 for (i = 0; i < nsides; i++)
1685 for (i = 0 ; i < GetNumberOfSides(part); i++)
1686 { 1902 {
1687 texcolor = tex.GetFace((uint)i).RGBA; 1903 texcolor = tex.GetFace((uint)i).RGBA;
1688 rgb.x += texcolor.R; 1904 rgb.x += texcolor.R;
@@ -1690,14 +1906,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1690 rgb.z += texcolor.B; 1906 rgb.z += texcolor.B;
1691 } 1907 }
1692 1908
1693 rgb.x /= (float)GetNumberOfSides(part); 1909 float invnsides = 1.0f / (float)nsides;
1694 rgb.y /= (float)GetNumberOfSides(part); 1910
1695 rgb.z /= (float)GetNumberOfSides(part); 1911 rgb.x *= invnsides;
1912 rgb.y *= invnsides;
1913 rgb.z *= invnsides;
1696 1914
1697 return rgb; 1915 return rgb;
1698 } 1916 }
1699 1917 if (face >= 0 && face < nsides)
1700 if (face >= 0 && face < GetNumberOfSides(part))
1701 { 1918 {
1702 texcolor = tex.GetFace((uint)face).RGBA; 1919 texcolor = tex.GetFace((uint)face).RGBA;
1703 rgb.x = texcolor.R; 1920 rgb.x = texcolor.R;
@@ -1724,15 +1941,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1724 m_host.AddScriptLPS(1); 1941 m_host.AddScriptLPS(1);
1725 1942
1726 List<SceneObjectPart> parts = GetLinkParts(linknumber); 1943 List<SceneObjectPart> parts = GetLinkParts(linknumber);
1727 1944 if (parts.Count > 0)
1728 foreach (SceneObjectPart part in parts) 1945 {
1729 SetTexture(part, texture, face); 1946 try
1730 1947 {
1948 parts[0].ParentGroup.areUpdatesSuspended = true;
1949 foreach (SceneObjectPart part in parts)
1950 SetTexture(part, texture, face);
1951 }
1952 finally
1953 {
1954 parts[0].ParentGroup.areUpdatesSuspended = false;
1955 }
1956 }
1731 ScriptSleep(200); 1957 ScriptSleep(200);
1732 } 1958 }
1733 1959
1734 protected void SetTexture(SceneObjectPart part, string texture, int face) 1960 protected void SetTexture(SceneObjectPart part, string texture, int face)
1735 { 1961 {
1962 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
1963 return;
1964
1736 UUID textureID = new UUID(); 1965 UUID textureID = new UUID();
1737 1966
1738 textureID = InventoryKey(texture, (int)AssetType.Texture); 1967 textureID = InventoryKey(texture, (int)AssetType.Texture);
@@ -1777,6 +2006,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1777 2006
1778 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face) 2007 protected void ScaleTexture(SceneObjectPart part, double u, double v, int face)
1779 { 2008 {
2009 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2010 return;
2011
1780 Primitive.TextureEntry tex = part.Shape.Textures; 2012 Primitive.TextureEntry tex = part.Shape.Textures;
1781 if (face >= 0 && face < GetNumberOfSides(part)) 2013 if (face >= 0 && face < GetNumberOfSides(part))
1782 { 2014 {
@@ -1813,6 +2045,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1813 2045
1814 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face) 2046 protected void OffsetTexture(SceneObjectPart part, double u, double v, int face)
1815 { 2047 {
2048 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2049 return;
2050
1816 Primitive.TextureEntry tex = part.Shape.Textures; 2051 Primitive.TextureEntry tex = part.Shape.Textures;
1817 if (face >= 0 && face < GetNumberOfSides(part)) 2052 if (face >= 0 && face < GetNumberOfSides(part))
1818 { 2053 {
@@ -1849,6 +2084,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1849 2084
1850 protected void RotateTexture(SceneObjectPart part, double rotation, int face) 2085 protected void RotateTexture(SceneObjectPart part, double rotation, int face)
1851 { 2086 {
2087 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2088 return;
2089
1852 Primitive.TextureEntry tex = part.Shape.Textures; 2090 Primitive.TextureEntry tex = part.Shape.Textures;
1853 if (face >= 0 && face < GetNumberOfSides(part)) 2091 if (face >= 0 && face < GetNumberOfSides(part))
1854 { 2092 {
@@ -1953,26 +2191,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1953 return real_vec; 2191 return real_vec;
1954 } 2192 }
1955 2193
2194 public LSL_Integer llSetRegionPos(LSL_Vector pos)
2195 {
2196 return new LSL_Integer(SetRegionPos(m_host, pos));
2197 }
2198
2199 protected int SetRegionPos(SceneObjectPart part, LSL_Vector targetPos)
2200 {
2201 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2202 return 0;
2203
2204 SceneObjectGroup grp = part.ParentGroup;
2205
2206 if (grp.IsAttachment)
2207 return 0;
2208
2209 if (grp.RootPart.PhysActor != null && grp.RootPart.PhysActor.IsPhysical)
2210 return 0;
2211
2212 if (targetPos.x < -10.0f || targetPos.x >= (float)Constants.RegionSize || targetPos.y < -10.0f || targetPos.y >= (float)Constants.RegionSize || targetPos.z < 0 || targetPos.z >= 4096.0f)
2213 return 0;
2214
2215 float constrainedX = (float)targetPos.x;
2216 float constrainedY = (float)targetPos.y;
2217
2218 if (constrainedX < 0.0f)
2219 constrainedX = 0.0f;
2220 if (constrainedY < 0.0f)
2221 constrainedY = 0.0f;
2222 if (constrainedX >= (float)Constants.RegionSize)
2223 constrainedX = (float)Constants.RegionSize - 0.1f;
2224 if (constrainedY >= (float)Constants.RegionSize)
2225 constrainedY = (float)Constants.RegionSize -0.1f;
2226
2227 float ground = World.GetGroundHeight(constrainedX, constrainedY);
2228
2229 if (targetPos.z < ground)
2230 targetPos.z = ground;
2231
2232 Vector3 dest = new Vector3((float)targetPos.x, (float)targetPos.y, (float)targetPos.z);
2233
2234 if (!World.Permissions.CanObjectEntry(grp.UUID, false, dest))
2235 return 0;
2236
2237 grp.UpdateGroupPosition(dest);
2238
2239 return 1;
2240 }
2241
1956 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos) 2242 protected void SetPos(SceneObjectPart part, LSL_Vector targetPos)
1957 { 2243 {
1958 // Capped movemment if distance > 10m (http://wiki.secondlife.com/wiki/LlSetPos) 2244 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2245 return;
2246
1959 LSL_Vector currentPos = GetPartLocalPos(part); 2247 LSL_Vector currentPos = GetPartLocalPos(part);
2248 LSL_Vector toPos = GetSetPosTarget(part, targetPos, currentPos);
1960 2249
1961 float ground = World.GetGroundHeight((float)targetPos.x, (float)targetPos.y);
1962 bool disable_underground_movement = m_ScriptEngine.Config.GetBoolean("DisableUndergroundMovement", true);
1963 2250
1964 if (part.ParentGroup.RootPart == part) 2251 if (part.ParentGroup.RootPart == part)
1965 { 2252 {
1966 if ((targetPos.z < ground) && disable_underground_movement && m_host.ParentGroup.AttachmentPoint == 0)
1967 targetPos.z = ground;
1968 SceneObjectGroup parent = part.ParentGroup; 2253 SceneObjectGroup parent = part.ParentGroup;
1969 LSL_Vector real_vec = SetPosAdjust(currentPos, targetPos); 2254 Vector3 dest = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1970 parent.UpdateGroupPosition(new Vector3((float)real_vec.x, (float)real_vec.y, (float)real_vec.z)); 2255 if (!World.Permissions.CanObjectEntry(parent.UUID, false, dest))
2256 return;
2257 Util.FireAndForget(delegate(object x) {
2258 parent.UpdateGroupPosition(dest);
2259 });
1971 } 2260 }
1972 else 2261 else
1973 { 2262 {
1974 LSL_Vector rel_vec = SetPosAdjust(currentPos, targetPos); 2263 part.OffsetPosition = new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z);
1975 part.OffsetPosition = new Vector3((float)rel_vec.x, (float)rel_vec.y, (float)rel_vec.z);
1976 SceneObjectGroup parent = part.ParentGroup; 2264 SceneObjectGroup parent = part.ParentGroup;
1977 parent.HasGroupChanged = true; 2265 parent.HasGroupChanged = true;
1978 parent.ScheduleGroupForTerseUpdate(); 2266 parent.ScheduleGroupForTerseUpdate();
@@ -2005,17 +2293,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2005 else 2293 else
2006 { 2294 {
2007 if (part.ParentGroup.IsAttachment) 2295 if (part.ParentGroup.IsAttachment)
2008 {
2009 pos = part.AttachedPos; 2296 pos = part.AttachedPos;
2010 }
2011 else 2297 else
2012 {
2013 pos = part.AbsolutePosition; 2298 pos = part.AbsolutePosition;
2014 }
2015 } 2299 }
2016 2300
2017// m_log.DebugFormat("[LSL API]: Returning {0} in GetPartLocalPos()", pos);
2018
2019 return new LSL_Vector(pos.X, pos.Y, pos.Z); 2301 return new LSL_Vector(pos.X, pos.Y, pos.Z);
2020 } 2302 }
2021 2303
@@ -2024,18 +2306,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2024 m_host.AddScriptLPS(1); 2306 m_host.AddScriptLPS(1);
2025 2307
2026 // try to let this work as in SL... 2308 // try to let this work as in SL...
2027 if (m_host.ParentID == 0) 2309 if (m_host.LinkNum < 2)
2028 { 2310 {
2029 // special case: If we are root, rotate complete SOG to new rotation 2311 // Special case: If we are root, rotate complete SOG to new
2312 // rotation.
2313 // We are root if the link number is 0 (single prim) or 1
2314 // (root prim). ParentID may be nonzero in attachments and
2315 // using it would cause attachments and HUDs to rotate
2316 // to the wrong positions.
2317
2030 SetRot(m_host, Rot2Quaternion(rot)); 2318 SetRot(m_host, Rot2Quaternion(rot));
2031 } 2319 }
2032 else 2320 else
2033 { 2321 {
2034 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 2322 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
2035 SceneObjectPart rootPart = m_host.ParentGroup.RootPart; 2323 SceneObjectPart rootPart;
2036 if (rootPart != null) // better safe than sorry 2324 if (m_host.ParentGroup != null) // better safe than sorry
2037 { 2325 {
2038 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot)); 2326 rootPart = m_host.ParentGroup.RootPart;
2327 if (rootPart != null)
2328 SetRot(m_host, rootPart.RotationOffset * Rot2Quaternion(rot));
2039 } 2329 }
2040 } 2330 }
2041 2331
@@ -2045,31 +2335,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2045 public void llSetLocalRot(LSL_Rotation rot) 2335 public void llSetLocalRot(LSL_Rotation rot)
2046 { 2336 {
2047 m_host.AddScriptLPS(1); 2337 m_host.AddScriptLPS(1);
2338
2048 SetRot(m_host, Rot2Quaternion(rot)); 2339 SetRot(m_host, Rot2Quaternion(rot));
2049 ScriptSleep(200); 2340 ScriptSleep(200);
2050 } 2341 }
2051 2342
2052 protected void SetRot(SceneObjectPart part, Quaternion rot) 2343 protected void SetRot(SceneObjectPart part, Quaternion rot)
2053 { 2344 {
2054 part.UpdateRotation(rot); 2345 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
2055 // Update rotation does not move the object in the physics scene if it's a linkset. 2346 return;
2056 2347
2057//KF: Do NOT use this next line if using ODE physics engine. This need a switch based on .ini Phys Engine type 2348 bool isroot = (part == part.ParentGroup.RootPart);
2058// part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition; 2349 bool isphys;
2059 2350
2060 // So, after thinking about this for a bit, the issue with the part.ParentGroup.AbsolutePosition = part.ParentGroup.AbsolutePosition line
2061 // is it isn't compatible with vehicles because it causes the vehicle body to have to be broken down and rebuilt
2062 // It's perfectly okay when the object is not an active physical body though.
2063 // So, part.ParentGroup.ResetChildPrimPhysicsPositions(); does the thing that Kitto is warning against
2064 // but only if the object is not physial and active. This is important for rotating doors.
2065 // without the absoluteposition = absoluteposition happening, the doors do not move in the physics
2066 // scene
2067 PhysicsActor pa = part.PhysActor; 2351 PhysicsActor pa = part.PhysActor;
2068 2352
2069 if (pa != null && !pa.IsPhysical) 2353 // keep using physactor ideia of isphysical
2354 // it should be SOP ideia of that
2355 // not much of a issue with ubitODE
2356 if (pa != null && pa.IsPhysical)
2357 isphys = true;
2358 else
2359 isphys = false;
2360
2361 // SL doesn't let scripts rotate root of physical linksets
2362 if (isroot && isphys)
2363 return;
2364
2365 part.UpdateRotation(rot);
2366
2367 // Update rotation does not move the object in the physics engine if it's a non physical linkset
2368 // so do a nasty update of parts positions if is a root part rotation
2369 if (isroot && pa != null) // with if above implies non physical root part
2070 { 2370 {
2071 part.ParentGroup.ResetChildPrimPhysicsPositions(); 2371 part.ParentGroup.ResetChildPrimPhysicsPositions();
2072 } 2372 }
2373 else // fix sitting avatars. This is only needed bc of how we link avas to child parts, not root part
2374 {
2375 List<ScenePresence> sittingavas = part.ParentGroup.GetLinkedAvatars();
2376 if (sittingavas.Count > 0)
2377 {
2378 foreach (ScenePresence av in sittingavas)
2379 {
2380 if (isroot || part.LocalId == av.ParentID)
2381 av.SendTerseUpdateToAllClients();
2382 }
2383 }
2384 }
2073 } 2385 }
2074 2386
2075 /// <summary> 2387 /// <summary>
@@ -2118,7 +2430,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2118 public LSL_Rotation llGetLocalRot() 2430 public LSL_Rotation llGetLocalRot()
2119 { 2431 {
2120 m_host.AddScriptLPS(1); 2432 m_host.AddScriptLPS(1);
2121 return new LSL_Rotation(m_host.RotationOffset.X, m_host.RotationOffset.Y, m_host.RotationOffset.Z, m_host.RotationOffset.W); 2433 Quaternion rot = m_host.RotationOffset;
2434 return new LSL_Rotation(rot.X, rot.Y, rot.Z, rot.W);
2122 } 2435 }
2123 2436
2124 public void llSetForce(LSL_Vector force, int local) 2437 public void llSetForce(LSL_Vector force, int local)
@@ -2202,16 +2515,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2202 m_host.ApplyImpulse(v, local != 0); 2515 m_host.ApplyImpulse(v, local != 0);
2203 } 2516 }
2204 2517
2518
2205 public void llApplyRotationalImpulse(LSL_Vector force, int local) 2519 public void llApplyRotationalImpulse(LSL_Vector force, int local)
2206 { 2520 {
2207 m_host.AddScriptLPS(1); 2521 m_host.AddScriptLPS(1);
2208 m_host.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0); 2522 m_host.ParentGroup.RootPart.ApplyAngularImpulse(new Vector3((float)force.x, (float)force.y, (float)force.z), local != 0);
2209 } 2523 }
2210 2524
2211 public void llSetTorque(LSL_Vector torque, int local) 2525 public void llSetTorque(LSL_Vector torque, int local)
2212 { 2526 {
2213 m_host.AddScriptLPS(1); 2527 m_host.AddScriptLPS(1);
2214 m_host.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0); 2528 m_host.ParentGroup.RootPart.SetAngularImpulse(new Vector3((float)torque.x, (float)torque.y, (float)torque.z), local != 0);
2215 } 2529 }
2216 2530
2217 public LSL_Vector llGetTorque() 2531 public LSL_Vector llGetTorque()
@@ -2228,20 +2542,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2228 llSetTorque(torque, local); 2542 llSetTorque(torque, local);
2229 } 2543 }
2230 2544
2545 public void llSetVelocity(LSL_Vector vel, int local)
2546 {
2547 m_host.AddScriptLPS(1);
2548 m_host.SetVelocity(new Vector3((float)vel.x, (float)vel.y, (float)vel.z), local != 0);
2549 }
2550
2231 public LSL_Vector llGetVel() 2551 public LSL_Vector llGetVel()
2232 { 2552 {
2233 m_host.AddScriptLPS(1); 2553 m_host.AddScriptLPS(1);
2234 2554
2235 Vector3 vel; 2555 Vector3 vel = Vector3.Zero;
2236 2556
2237 if (m_host.ParentGroup.IsAttachment) 2557 if (m_host.ParentGroup.IsAttachment)
2238 { 2558 {
2239 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar); 2559 ScenePresence avatar = m_host.ParentGroup.Scene.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
2240 vel = avatar.Velocity; 2560 if (avatar != null)
2561 vel = avatar.Velocity;
2241 } 2562 }
2242 else 2563 else
2243 { 2564 {
2244 vel = m_host.Velocity; 2565 vel = m_host.ParentGroup.RootPart.Velocity;
2245 } 2566 }
2246 2567
2247 return new LSL_Vector(vel.X, vel.Y, vel.Z); 2568 return new LSL_Vector(vel.X, vel.Y, vel.Z);
@@ -2253,10 +2574,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2253 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z); 2574 return new LSL_Vector(m_host.Acceleration.X, m_host.Acceleration.Y, m_host.Acceleration.Z);
2254 } 2575 }
2255 2576
2577 public void llSetAngularVelocity(LSL_Vector avel, int local)
2578 {
2579 m_host.AddScriptLPS(1);
2580 m_host.SetAngularVelocity(new Vector3((float)avel.x, (float)avel.y, (float)avel.z), local != 0);
2581 }
2582
2256 public LSL_Vector llGetOmega() 2583 public LSL_Vector llGetOmega()
2257 { 2584 {
2258 m_host.AddScriptLPS(1); 2585 m_host.AddScriptLPS(1);
2259 return new LSL_Vector(m_host.AngularVelocity.X, m_host.AngularVelocity.Y, m_host.AngularVelocity.Z); 2586 Vector3 avel = m_host.AngularVelocity;
2587 return new LSL_Vector(avel.X, avel.Y, avel.Z);
2260 } 2588 }
2261 2589
2262 public LSL_Float llGetTimeOfDay() 2590 public LSL_Float llGetTimeOfDay()
@@ -2785,16 +3113,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2785 new_group.RootPart.UUID.ToString()) }, 3113 new_group.RootPart.UUID.ToString()) },
2786 new DetectParams[0])); 3114 new DetectParams[0]));
2787 3115
2788 float groupmass = new_group.GetMass(); 3116 // do recoil
3117 SceneObjectGroup hostgrp = m_host.ParentGroup;
3118 if (hostgrp == null)
3119 return;
3120
3121 if (hostgrp.IsAttachment) // don't recoil avatars
3122 return;
2789 3123
2790 PhysicsActor pa = new_group.RootPart.PhysActor; 3124 PhysicsActor pa = new_group.RootPart.PhysActor;
2791 3125
2792 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero) 3126 if (pa != null && pa.IsPhysical && llvel != Vector3.Zero)
2793 { 3127 {
2794 //Recoil. 3128 float groupmass = new_group.GetMass();
2795 llApplyImpulse(new LSL_Vector(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); 3129 llvel *= -groupmass;
3130 llApplyImpulse(new LSL_Vector(llvel.X, llvel.Y,llvel.Z), 0);
2796 } 3131 }
2797 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) 3132 // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay)
3133 return;
3134
2798 }); 3135 });
2799 3136
2800 //ScriptSleep((int)((groupmass * velmag) / 10)); 3137 //ScriptSleep((int)((groupmass * velmag) / 10));
@@ -2809,35 +3146,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2809 public void llLookAt(LSL_Vector target, double strength, double damping) 3146 public void llLookAt(LSL_Vector target, double strength, double damping)
2810 { 3147 {
2811 m_host.AddScriptLPS(1); 3148 m_host.AddScriptLPS(1);
2812 // Determine where we are looking from
2813 LSL_Vector from = llGetPos();
2814 3149
2815 // Work out the normalised vector from the source to the target 3150 // Get the normalized vector to the target
2816 LSL_Vector delta = llVecNorm(target - from); 3151 LSL_Vector d1 = llVecNorm(target - llGetPos());
2817 LSL_Vector angle = new LSL_Vector(0,0,0);
2818 3152
2819 // Calculate the yaw 3153 // Get the bearing (yaw)
2820 // subtracting PI_BY_TWO is required to compensate for the odd SL co-ordinate system 3154 LSL_Vector a1 = new LSL_Vector(0,0,0);
2821 angle.x = llAtan2(delta.z, delta.y) - ScriptBaseClass.PI_BY_TWO; 3155 a1.z = llAtan2(d1.y, d1.x);
2822 3156
2823 // Calculate pitch 3157 // Get the elevation (pitch)
2824 angle.y = llAtan2(delta.x, llSqrt((delta.y * delta.y) + (delta.z * delta.z))); 3158 LSL_Vector a2 = new LSL_Vector(0,0,0);
3159 a2.y= -llAtan2(d1.z, llSqrt((d1.x * d1.x) + (d1.y * d1.y)));
2825 3160
2826 // we need to convert from a vector describing 3161 LSL_Rotation r1 = llEuler2Rot(a1);
2827 // the angles of rotation in radians into rotation value 3162 LSL_Rotation r2 = llEuler2Rot(a2);
2828 LSL_Rotation rot = llEuler2Rot(angle); 3163 LSL_Rotation r3 = new LSL_Rotation(0.000000, 0.707107, 0.000000, 0.707107);
2829
2830 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2831 // set the rotation of the object, copy that behavior
2832 PhysicsActor pa = m_host.PhysActor;
2833 3164
2834 if (strength == 0 || pa == null || !pa.IsPhysical) 3165 if (m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2835 { 3166 {
2836 llSetRot(rot); 3167 // Do nothing if either value is 0 (this has been checked in SL)
3168 if (strength <= 0.0 || damping <= 0.0)
3169 return;
3170
3171 llSetRot(r3 * r2 * r1);
2837 } 3172 }
2838 else 3173 else
2839 { 3174 {
2840 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping); 3175 if (strength == 0)
3176 {
3177 llSetRot(r3 * r2 * r1);
3178 return;
3179 }
3180
3181 m_host.StartLookAt(Rot2Quaternion(r3 * r2 * r1), (float)strength, (float)damping);
2841 } 3182 }
2842 } 3183 }
2843 3184
@@ -2883,17 +3224,24 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2883 } 3224 }
2884 else 3225 else
2885 { 3226 {
2886 if (m_host.IsRoot) 3227 // new SL always returns object mass
2887 { 3228// if (m_host.IsRoot)
3229// {
2888 return m_host.ParentGroup.GetMass(); 3230 return m_host.ParentGroup.GetMass();
2889 } 3231// }
2890 else 3232// else
2891 { 3233// {
2892 return m_host.GetMass(); 3234// return m_host.GetMass();
2893 } 3235// }
2894 } 3236 }
2895 } 3237 }
2896 3238
3239
3240 public LSL_Float llGetMassMKS()
3241 {
3242 return 100f * llGetMass();
3243 }
3244
2897 public void llCollisionFilter(string name, string id, int accept) 3245 public void llCollisionFilter(string name, string id, int accept)
2898 { 3246 {
2899 m_host.AddScriptLPS(1); 3247 m_host.AddScriptLPS(1);
@@ -2968,7 +3316,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2968 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule; 3316 IAttachmentsModule attachmentsModule = m_ScriptEngine.World.AttachmentsModule;
2969 3317
2970 if (attachmentsModule != null) 3318 if (attachmentsModule != null)
2971 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false); 3319 return attachmentsModule.AttachObject(presence, grp, (uint)attachmentPoint, false, true);
2972 else 3320 else
2973 return false; 3321 return false;
2974 } 3322 }
@@ -2998,9 +3346,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2998 { 3346 {
2999 m_host.AddScriptLPS(1); 3347 m_host.AddScriptLPS(1);
3000 3348
3001// if (m_host.ParentGroup.RootPart.AttachmentPoint == 0)
3002// return;
3003
3004 if (m_item.PermsGranter != m_host.OwnerID) 3349 if (m_item.PermsGranter != m_host.OwnerID)
3005 return; 3350 return;
3006 3351
@@ -3043,6 +3388,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3043 3388
3044 public void llInstantMessage(string user, string message) 3389 public void llInstantMessage(string user, string message)
3045 { 3390 {
3391 UUID result;
3392 if (!UUID.TryParse(user, out result))
3393 {
3394 ShoutError("An invalid key was passed to llInstantMessage");
3395 ScriptSleep(2000);
3396 return;
3397 }
3398
3399
3046 m_host.AddScriptLPS(1); 3400 m_host.AddScriptLPS(1);
3047 3401
3048 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance. 3402 // We may be able to use ClientView.SendInstantMessage here, but we need a client instance.
@@ -3057,14 +3411,34 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3057 UUID friendTransactionID = UUID.Random(); 3411 UUID friendTransactionID = UUID.Random();
3058 3412
3059 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID); 3413 //m_pendingFriendRequests.Add(friendTransactionID, fromAgentID);
3060 3414
3061 GridInstantMessage msg = new GridInstantMessage(); 3415 GridInstantMessage msg = new GridInstantMessage();
3062 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid; 3416 msg.fromAgentID = new Guid(m_host.UUID.ToString()); // fromAgentID.Guid;
3063 msg.toAgentID = new Guid(user); // toAgentID.Guid; 3417 msg.toAgentID = new Guid(user); // toAgentID.Guid;
3064 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here 3418 msg.imSessionID = new Guid(friendTransactionID.ToString()); // This is the item we're mucking with here
3065// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message); 3419// m_log.Debug("[Scripting IM]: From:" + msg.fromAgentID.ToString() + " To: " + msg.toAgentID.ToString() + " Session:" + msg.imSessionID.ToString() + " Message:" + message);
3066// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString()); 3420// m_log.Debug("[Scripting IM]: Filling Session: " + msg.imSessionID.ToString());
3067 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();// timestamp; 3421// DateTime dt = DateTime.UtcNow;
3422//
3423// // Ticks from UtcNow, but make it look like local. Evil, huh?
3424// dt = DateTime.SpecifyKind(dt, DateTimeKind.Local);
3425//
3426// try
3427// {
3428// // Convert that to the PST timezone
3429// TimeZoneInfo timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById("America/Los_Angeles");
3430// dt = TimeZoneInfo.ConvertTime(dt, timeZoneInfo);
3431// }
3432// catch
3433// {
3434// // No logging here, as it could be VERY spammy
3435// }
3436//
3437// // And make it look local again to fool the unix time util
3438// dt = DateTime.SpecifyKind(dt, DateTimeKind.Utc);
3439
3440 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
3441
3068 //if (client != null) 3442 //if (client != null)
3069 //{ 3443 //{
3070 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName; 3444 msg.fromAgentName = m_host.Name;//client.FirstName + " " + client.LastName;// fromAgentName;
@@ -3078,12 +3452,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3078 msg.message = message.Substring(0, 1024); 3452 msg.message = message.Substring(0, 1024);
3079 else 3453 else
3080 msg.message = message; 3454 msg.message = message;
3081 msg.dialog = (byte)19; // messgage from script ??? // dialog; 3455 msg.dialog = (byte)19; // MessageFromObject
3082 msg.fromGroup = false;// fromGroup; 3456 msg.fromGroup = false;// fromGroup;
3083 msg.offline = (byte)0; //offline; 3457 msg.offline = (byte)0; //offline;
3084 msg.ParentEstateID = 0; //ParentEstateID; 3458 msg.ParentEstateID = World.RegionInfo.EstateSettings.EstateID;
3085 msg.Position = new Vector3(m_host.AbsolutePosition); 3459 msg.Position = new Vector3(m_host.AbsolutePosition);
3086 msg.RegionID = World.RegionInfo.RegionID.Guid;//RegionID.Guid; 3460 msg.RegionID = World.RegionInfo.RegionID.Guid;
3087 msg.binaryBucket 3461 msg.binaryBucket
3088 = Util.StringToBytes256( 3462 = Util.StringToBytes256(
3089 "{0}/{1}/{2}/{3}", 3463 "{0}/{1}/{2}/{3}",
@@ -3111,7 +3485,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3111 } 3485 }
3112 3486
3113 emailModule.SendEmail(m_host.UUID, address, subject, message); 3487 emailModule.SendEmail(m_host.UUID, address, subject, message);
3114 llSleep(EMAIL_PAUSE_TIME); 3488 ScriptSleep(EMAIL_PAUSE_TIME * 1000);
3115 } 3489 }
3116 3490
3117 public void llGetNextEmail(string address, string subject) 3491 public void llGetNextEmail(string address, string subject)
@@ -3313,6 +3687,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3313 3687
3314 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain) 3688 protected void TargetOmega(SceneObjectPart part, LSL_Vector axis, double spinrate, double gain)
3315 { 3689 {
3690 spinrate *= gain;
3316 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate))); 3691 part.UpdateAngularVelocity(new Vector3((float)(axis.x * spinrate), (float)(axis.y * spinrate), (float)(axis.z * spinrate)));
3317 } 3692 }
3318 3693
@@ -3355,15 +3730,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3355 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS | 3730 int implicitPerms = ScriptBaseClass.PERMISSION_TAKE_CONTROLS |
3356 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3731 ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3357 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3732 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3733 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3358 ScriptBaseClass.PERMISSION_ATTACH; 3734 ScriptBaseClass.PERMISSION_ATTACH;
3359 3735
3360 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3736 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3361 { 3737 {
3362 lock (m_host.TaskInventory) 3738 m_host.TaskInventory.LockItemsForWrite(true);
3363 { 3739 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3364 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3740 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3365 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3741 m_host.TaskInventory.LockItemsForWrite(false);
3366 }
3367 3742
3368 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3743 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3369 "run_time_permissions", new Object[] { 3744 "run_time_permissions", new Object[] {
@@ -3373,28 +3748,44 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3373 return; 3748 return;
3374 } 3749 }
3375 } 3750 }
3376 else if (m_host.SitTargetAvatar == agentID) // Sitting avatar 3751 else
3377 { 3752 {
3378 // When agent is sitting, certain permissions are implicit if requested from sitting agent 3753 bool sitting = false;
3379 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION | 3754 if (m_host.SitTargetAvatar == agentID)
3380 ScriptBaseClass.PERMISSION_CONTROL_CAMERA | 3755 {
3381 ScriptBaseClass.PERMISSION_TRACK_CAMERA | 3756 sitting = true;
3382 ScriptBaseClass.PERMISSION_TAKE_CONTROLS; 3757 }
3758 else
3759 {
3760 foreach (SceneObjectPart p in m_host.ParentGroup.Parts)
3761 {
3762 if (p.SitTargetAvatar == agentID)
3763 sitting = true;
3764 }
3765 }
3383 3766
3384 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms 3767 if (sitting)
3385 { 3768 {
3386 lock (m_host.TaskInventory) 3769 // When agent is sitting, certain permissions are implicit if requested from sitting agent
3770 int implicitPerms = ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION |
3771 ScriptBaseClass.PERMISSION_CONTROL_CAMERA |
3772 ScriptBaseClass.PERMISSION_TRACK_CAMERA |
3773 ScriptBaseClass.PERMISSION_TAKE_CONTROLS;
3774
3775 if ((perm & (~implicitPerms)) == 0) // Requested only implicit perms
3387 { 3776 {
3777 m_host.TaskInventory.LockItemsForWrite(true);
3388 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3778 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3389 m_host.TaskInventory[m_item.ItemID].PermsMask = perm; 3779 m_host.TaskInventory[m_item.ItemID].PermsMask = perm;
3390 } 3780 m_host.TaskInventory.LockItemsForWrite(false);
3391 3781
3392 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( 3782 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3393 "run_time_permissions", new Object[] { 3783 "run_time_permissions", new Object[] {
3394 new LSL_Integer(perm) }, 3784 new LSL_Integer(perm) },
3395 new DetectParams[0])); 3785 new DetectParams[0]));
3396 3786
3397 return; 3787 return;
3788 }
3398 } 3789 }
3399 } 3790 }
3400 3791
@@ -3431,11 +3822,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3431 3822
3432 if (!m_waitingForScriptAnswer) 3823 if (!m_waitingForScriptAnswer)
3433 { 3824 {
3434 lock (m_host.TaskInventory) 3825 m_host.TaskInventory.LockItemsForWrite(true);
3435 { 3826 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID;
3436 m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; 3827 m_host.TaskInventory[m_item.ItemID].PermsMask = 0;
3437 m_host.TaskInventory[m_item.ItemID].PermsMask = 0; 3828 m_host.TaskInventory.LockItemsForWrite(false);
3438 }
3439 3829
3440 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer; 3830 presence.ControllingClient.OnScriptAnswer += handleScriptAnswer;
3441 m_waitingForScriptAnswer=true; 3831 m_waitingForScriptAnswer=true;
@@ -3464,14 +3854,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3464 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0) 3854 if ((answer & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) == 0)
3465 llReleaseControls(); 3855 llReleaseControls();
3466 3856
3467 lock (m_host.TaskInventory) 3857 m_host.TaskInventory.LockItemsForWrite(true);
3468 { 3858 m_host.TaskInventory[m_item.ItemID].PermsMask = answer;
3469 m_host.TaskInventory[m_item.ItemID].PermsMask = answer; 3859 m_host.TaskInventory.LockItemsForWrite(false);
3470 } 3860
3471 3861 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
3472 m_ScriptEngine.PostScriptEvent( 3862 "run_time_permissions", new Object[] {
3473 m_item.ItemID, 3863 new LSL_Integer(answer) },
3474 new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); 3864 new DetectParams[0]));
3475 } 3865 }
3476 3866
3477 public LSL_String llGetPermissionsKey() 3867 public LSL_String llGetPermissionsKey()
@@ -3510,14 +3900,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3510 public void llSetLinkColor(int linknumber, LSL_Vector color, int face) 3900 public void llSetLinkColor(int linknumber, LSL_Vector color, int face)
3511 { 3901 {
3512 List<SceneObjectPart> parts = GetLinkParts(linknumber); 3902 List<SceneObjectPart> parts = GetLinkParts(linknumber);
3513 3903 if (parts.Count > 0)
3514 foreach (SceneObjectPart part in parts) 3904 {
3515 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face); 3905 try
3906 {
3907 parts[0].ParentGroup.areUpdatesSuspended = true;
3908 foreach (SceneObjectPart part in parts)
3909 part.SetFaceColor(new Vector3((float)color.x, (float)color.y, (float)color.z), face);
3910 }
3911 finally
3912 {
3913 parts[0].ParentGroup.areUpdatesSuspended = false;
3914 }
3915 }
3516 } 3916 }
3517 3917
3518 public void llCreateLink(string target, int parent) 3918 public void llCreateLink(string target, int parent)
3519 { 3919 {
3520 m_host.AddScriptLPS(1); 3920 m_host.AddScriptLPS(1);
3921
3521 UUID targetID; 3922 UUID targetID;
3522 3923
3523 if (!UUID.TryParse(target, out targetID)) 3924 if (!UUID.TryParse(target, out targetID))
@@ -3623,10 +4024,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3623 // Restructuring Multiple Prims. 4024 // Restructuring Multiple Prims.
3624 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts); 4025 List<SceneObjectPart> parts = new List<SceneObjectPart>(parentPrim.Parts);
3625 parts.Remove(parentPrim.RootPart); 4026 parts.Remove(parentPrim.RootPart);
3626 foreach (SceneObjectPart part in parts) 4027 if (parts.Count > 0)
3627 { 4028 {
3628 parentPrim.DelinkFromGroup(part.LocalId, true); 4029 try
4030 {
4031 parts[0].ParentGroup.areUpdatesSuspended = true;
4032 foreach (SceneObjectPart part in parts)
4033 {
4034 parentPrim.DelinkFromGroup(part.LocalId, true);
4035 }
4036 }
4037 finally
4038 {
4039 parts[0].ParentGroup.areUpdatesSuspended = false;
4040 }
3629 } 4041 }
4042
3630 parentPrim.HasGroupChanged = true; 4043 parentPrim.HasGroupChanged = true;
3631 parentPrim.ScheduleGroupForFullUpdate(); 4044 parentPrim.ScheduleGroupForFullUpdate();
3632 parentPrim.TriggerScriptChangedEvent(Changed.LINK); 4045 parentPrim.TriggerScriptChangedEvent(Changed.LINK);
@@ -3635,12 +4048,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3635 { 4048 {
3636 SceneObjectPart newRoot = parts[0]; 4049 SceneObjectPart newRoot = parts[0];
3637 parts.Remove(newRoot); 4050 parts.Remove(newRoot);
3638 foreach (SceneObjectPart part in parts) 4051
4052 try
3639 { 4053 {
3640 // Required for linking 4054 parts[0].ParentGroup.areUpdatesSuspended = true;
3641 part.ClearUpdateSchedule(); 4055 foreach (SceneObjectPart part in parts)
3642 newRoot.ParentGroup.LinkToGroup(part.ParentGroup); 4056 {
4057 part.ClearUpdateSchedule();
4058 newRoot.ParentGroup.LinkToGroup(part.ParentGroup);
4059 }
3643 } 4060 }
4061 finally
4062 {
4063 parts[0].ParentGroup.areUpdatesSuspended = false;
4064 }
4065
4066
3644 newRoot.ParentGroup.HasGroupChanged = true; 4067 newRoot.ParentGroup.HasGroupChanged = true;
3645 newRoot.ParentGroup.ScheduleGroupForFullUpdate(); 4068 newRoot.ParentGroup.ScheduleGroupForFullUpdate();
3646 } 4069 }
@@ -3660,6 +4083,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3660 public void llBreakAllLinks() 4083 public void llBreakAllLinks()
3661 { 4084 {
3662 m_host.AddScriptLPS(1); 4085 m_host.AddScriptLPS(1);
4086
4087 TaskInventoryItem item = m_item;
4088
4089 if ((item.PermsMask & ScriptBaseClass.PERMISSION_CHANGE_LINKS) == 0
4090 && !m_automaticLinkPermission)
4091 {
4092 ShoutError("Script trying to link but PERMISSION_CHANGE_LINKS permission not set!");
4093 return;
4094 }
4095
3663 SceneObjectGroup parentPrim = m_host.ParentGroup; 4096 SceneObjectGroup parentPrim = m_host.ParentGroup;
3664 if (parentPrim.AttachmentPoint != 0) 4097 if (parentPrim.AttachmentPoint != 0)
3665 return; // Fail silently if attached 4098 return; // Fail silently if attached
@@ -3679,25 +4112,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3679 public LSL_String llGetLinkKey(int linknum) 4112 public LSL_String llGetLinkKey(int linknum)
3680 { 4113 {
3681 m_host.AddScriptLPS(1); 4114 m_host.AddScriptLPS(1);
3682 List<UUID> keytable = new List<UUID>();
3683 // parse for sitting avatare-uuids
3684 World.ForEachRootScenePresence(delegate(ScenePresence presence)
3685 {
3686 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
3687 keytable.Add(presence.UUID);
3688 });
3689
3690 int totalprims = m_host.ParentGroup.PrimCount + keytable.Count;
3691 if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims)
3692 {
3693 return keytable[totalprims - linknum].ToString();
3694 }
3695
3696 if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && keytable.Count == 1)
3697 {
3698 return m_host.UUID.ToString();
3699 }
3700
3701 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum); 4115 SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(linknum);
3702 if (part != null) 4116 if (part != null)
3703 { 4117 {
@@ -3705,6 +4119,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3705 } 4119 }
3706 else 4120 else
3707 { 4121 {
4122 if (linknum > m_host.ParentGroup.PrimCount || (linknum == 1 && m_host.ParentGroup.PrimCount == 1))
4123 {
4124 linknum -= (m_host.ParentGroup.PrimCount) + 1;
4125
4126 if (linknum < 0)
4127 return UUID.Zero.ToString();
4128
4129 List<ScenePresence> avatars = GetLinkAvatars(ScriptBaseClass.LINK_SET);
4130 if (avatars.Count > linknum)
4131 {
4132 return avatars[linknum].UUID.ToString();
4133 }
4134 }
3708 return UUID.Zero.ToString(); 4135 return UUID.Zero.ToString();
3709 } 4136 }
3710 } 4137 }
@@ -3804,17 +4231,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3804 m_host.AddScriptLPS(1); 4231 m_host.AddScriptLPS(1);
3805 int count = 0; 4232 int count = 0;
3806 4233
3807 lock (m_host.TaskInventory) 4234 m_host.TaskInventory.LockItemsForRead(true);
4235 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3808 { 4236 {
3809 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4237 if (inv.Value.Type == type || type == -1)
3810 { 4238 {
3811 if (inv.Value.Type == type || type == -1) 4239 count = count + 1;
3812 {
3813 count = count + 1;
3814 }
3815 } 4240 }
3816 } 4241 }
3817 4242
4243 m_host.TaskInventory.LockItemsForRead(false);
3818 return count; 4244 return count;
3819 } 4245 }
3820 4246
@@ -3823,16 +4249,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3823 m_host.AddScriptLPS(1); 4249 m_host.AddScriptLPS(1);
3824 ArrayList keys = new ArrayList(); 4250 ArrayList keys = new ArrayList();
3825 4251
3826 lock (m_host.TaskInventory) 4252 m_host.TaskInventory.LockItemsForRead(true);
4253 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
3827 { 4254 {
3828 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 4255 if (inv.Value.Type == type || type == -1)
3829 { 4256 {
3830 if (inv.Value.Type == type || type == -1) 4257 keys.Add(inv.Value.Name);
3831 {
3832 keys.Add(inv.Value.Name);
3833 }
3834 } 4258 }
3835 } 4259 }
4260 m_host.TaskInventory.LockItemsForRead(false);
3836 4261
3837 if (keys.Count == 0) 4262 if (keys.Count == 0)
3838 { 4263 {
@@ -3870,7 +4295,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3870 if (item == null) 4295 if (item == null)
3871 { 4296 {
3872 llSay(0, String.Format("Could not find object '{0}'", inventory)); 4297 llSay(0, String.Format("Could not find object '{0}'", inventory));
3873 throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory)); 4298 return;
4299// throw new Exception(String.Format("The inventory object '{0}' could not be found", inventory));
3874 } 4300 }
3875 4301
3876 UUID objId = item.ItemID; 4302 UUID objId = item.ItemID;
@@ -3898,34 +4324,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3898 return; 4324 return;
3899 } 4325 }
3900 } 4326 }
4327
3901 // destination is an avatar 4328 // destination is an avatar
3902 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId); 4329 InventoryItemBase agentItem = World.MoveTaskInventoryItem(destId, UUID.Zero, m_host, objId);
3903 4330
3904 if (agentItem == null) 4331 if (agentItem == null)
3905 return; 4332 return;
3906 4333
3907 byte[] bucket = new byte[17]; 4334 byte[] bucket = new byte[1];
3908 bucket[0] = (byte)item.Type; 4335 bucket[0] = (byte)item.Type;
3909 byte[] objBytes = agentItem.ID.GetBytes(); 4336 //byte[] objBytes = agentItem.ID.GetBytes();
3910 Array.Copy(objBytes, 0, bucket, 1, 16); 4337 //Array.Copy(objBytes, 0, bucket, 1, 16);
3911 4338
3912 GridInstantMessage msg = new GridInstantMessage(World, 4339 GridInstantMessage msg = new GridInstantMessage(World,
3913 m_host.UUID, m_host.Name + ", an object owned by " + 4340 m_host.OwnerID, m_host.Name, destId,
3914 resolveName(m_host.OwnerID) + ",", destId,
3915 (byte)InstantMessageDialog.TaskInventoryOffered, 4341 (byte)InstantMessageDialog.TaskInventoryOffered,
3916 false, item.Name + "\n" + m_host.Name + " is located at " + 4342 false, item.Name+". "+m_host.Name+" is located at "+
3917 World.RegionInfo.RegionName+" "+ 4343 World.RegionInfo.RegionName+" "+
3918 m_host.AbsolutePosition.ToString(), 4344 m_host.AbsolutePosition.ToString(),
3919 agentItem.ID, true, m_host.AbsolutePosition, 4345 agentItem.ID, true, m_host.AbsolutePosition,
3920 bucket); 4346 bucket);
3921 4347
3922 if (m_TransferModule != null) 4348 ScenePresence sp;
3923 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
3924 4349
4350 if (World.TryGetScenePresence(destId, out sp))
4351 {
4352 sp.ControllingClient.SendInstantMessage(msg);
4353 }
4354 else
4355 {
4356 if (m_TransferModule != null)
4357 m_TransferModule.SendInstantMessage(msg, delegate(bool success) {});
4358 }
4359
4360 //This delay should only occur when giving inventory to avatars.
3925 ScriptSleep(3000); 4361 ScriptSleep(3000);
3926 } 4362 }
3927 } 4363 }
3928 4364
4365 [DebuggerNonUserCode]
3929 public void llRemoveInventory(string name) 4366 public void llRemoveInventory(string name)
3930 { 4367 {
3931 m_host.AddScriptLPS(1); 4368 m_host.AddScriptLPS(1);
@@ -3971,109 +4408,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3971 { 4408 {
3972 m_host.AddScriptLPS(1); 4409 m_host.AddScriptLPS(1);
3973 4410
3974 UUID uuid = (UUID)id; 4411 UUID uuid;
3975 PresenceInfo pinfo = null; 4412 if (UUID.TryParse(id, out uuid))
3976 UserAccount account;
3977
3978 UserInfoCacheEntry ce;
3979 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3980 { 4413 {
3981 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid); 4414 PresenceInfo pinfo = null;
3982 if (account == null) 4415 UserAccount account;
4416
4417 UserInfoCacheEntry ce;
4418 if (!m_userInfoCache.TryGetValue(uuid, out ce))
3983 { 4419 {
3984 m_userInfoCache[uuid] = null; // Cache negative 4420 account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, uuid);
3985 return UUID.Zero.ToString(); 4421 if (account == null)
3986 } 4422 {
4423 m_userInfoCache[uuid] = null; // Cache negative
4424 return UUID.Zero.ToString();
4425 }
3987 4426
3988 4427
3989 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() }); 4428 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
3990 if (pinfos != null && pinfos.Length > 0) 4429 if (pinfos != null && pinfos.Length > 0)
3991 {
3992 foreach (PresenceInfo p in pinfos)
3993 { 4430 {
3994 if (p.RegionID != UUID.Zero) 4431 foreach (PresenceInfo p in pinfos)
3995 { 4432 {
3996 pinfo = p; 4433 if (p.RegionID != UUID.Zero)
4434 {
4435 pinfo = p;
4436 }
3997 } 4437 }
3998 } 4438 }
3999 }
4000 4439
4001 ce = new UserInfoCacheEntry(); 4440 ce = new UserInfoCacheEntry();
4002 ce.time = Util.EnvironmentTickCount(); 4441 ce.time = Util.EnvironmentTickCount();
4003 ce.account = account; 4442 ce.account = account;
4004 ce.pinfo = pinfo; 4443 ce.pinfo = pinfo;
4005 } 4444 m_userInfoCache[uuid] = ce;
4006 else 4445 }
4007 { 4446 else
4008 if (ce == null) 4447 {
4009 return UUID.Zero.ToString(); 4448 if (ce == null)
4449 return UUID.Zero.ToString();
4010 4450
4011 account = ce.account; 4451 account = ce.account;
4012 pinfo = ce.pinfo; 4452 pinfo = ce.pinfo;
4013 } 4453 }
4014 4454
4015 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000) 4455 if (Util.EnvironmentTickCount() < ce.time || (Util.EnvironmentTickCount() - ce.time) >= 20000)
4016 {
4017 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4018 if (pinfos != null && pinfos.Length > 0)
4019 { 4456 {
4020 foreach (PresenceInfo p in pinfos) 4457 PresenceInfo[] pinfos = World.PresenceService.GetAgents(new string[] { uuid.ToString() });
4458 if (pinfos != null && pinfos.Length > 0)
4021 { 4459 {
4022 if (p.RegionID != UUID.Zero) 4460 foreach (PresenceInfo p in pinfos)
4023 { 4461 {
4024 pinfo = p; 4462 if (p.RegionID != UUID.Zero)
4463 {
4464 pinfo = p;
4465 }
4025 } 4466 }
4026 } 4467 }
4027 } 4468 else
4028 else 4469 pinfo = null;
4029 pinfo = null;
4030 4470
4031 ce.time = Util.EnvironmentTickCount(); 4471 ce.time = Util.EnvironmentTickCount();
4032 ce.pinfo = pinfo; 4472 ce.pinfo = pinfo;
4033 } 4473 }
4034 4474
4035 string reply = String.Empty; 4475 string reply = String.Empty;
4036 4476
4037 switch (data) 4477 switch (data)
4038 { 4478 {
4039 case 1: // DATA_ONLINE (0|1) 4479 case 1: // DATA_ONLINE (0|1)
4040 if (pinfo != null && pinfo.RegionID != UUID.Zero) 4480 if (pinfo != null && pinfo.RegionID != UUID.Zero)
4041 reply = "1"; 4481 reply = "1";
4042 else 4482 else
4043 reply = "0"; 4483 reply = "0";
4044 break; 4484 break;
4045 case 2: // DATA_NAME (First Last) 4485 case 2: // DATA_NAME (First Last)
4046 reply = account.FirstName + " " + account.LastName; 4486 reply = account.FirstName + " " + account.LastName;
4047 break; 4487 break;
4048 case 3: // DATA_BORN (YYYY-MM-DD) 4488 case 3: // DATA_BORN (YYYY-MM-DD)
4049 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0); 4489 DateTime born = new DateTime(1970, 1, 1, 0, 0, 0, 0);
4050 born = born.AddSeconds(account.Created); 4490 born = born.AddSeconds(account.Created);
4051 reply = born.ToString("yyyy-MM-dd"); 4491 reply = born.ToString("yyyy-MM-dd");
4052 break; 4492 break;
4053 case 4: // DATA_RATING (0,0,0,0,0,0) 4493 case 4: // DATA_RATING (0,0,0,0,0,0)
4054 reply = "0,0,0,0,0,0"; 4494 reply = "0,0,0,0,0,0";
4055 break; 4495 break;
4056 case 7: // DATA_USERLEVEL (integer) 4496 case 8: // DATA_PAYINFO (0|1|2|3)
4057 reply = account.UserLevel.ToString(); 4497 reply = "0";
4058 break; 4498 break;
4059 case 8: // DATA_PAYINFO (0|1|2|3) 4499 default:
4060 reply = "0"; 4500 return UUID.Zero.ToString(); // Raise no event
4061 break; 4501 }
4062 default:
4063 return UUID.Zero.ToString(); // Raise no event
4064 }
4065 4502
4066 UUID rq = UUID.Random(); 4503 UUID rq = UUID.Random();
4067 4504
4068 UUID tid = AsyncCommands. 4505 UUID tid = AsyncCommands.
4069 DataserverPlugin.RegisterRequest(m_host.LocalId, 4506 DataserverPlugin.RegisterRequest(m_host.LocalId,
4070 m_item.ItemID, rq.ToString()); 4507 m_item.ItemID, rq.ToString());
4071 4508
4072 AsyncCommands. 4509 AsyncCommands.
4073 DataserverPlugin.DataserverReply(rq.ToString(), reply); 4510 DataserverPlugin.DataserverReply(rq.ToString(), reply);
4074 4511
4075 ScriptSleep(100); 4512 ScriptSleep(100);
4076 return tid.ToString(); 4513 return tid.ToString();
4514 }
4515 else
4516 {
4517 ShoutError("Invalid UUID passed to llRequestAgentData.");
4518 }
4519 return "";
4077 } 4520 }
4078 4521
4079 public LSL_String llRequestInventoryData(string name) 4522 public LSL_String llRequestInventoryData(string name)
@@ -4130,13 +4573,26 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4130 if (UUID.TryParse(agent, out agentId)) 4573 if (UUID.TryParse(agent, out agentId))
4131 { 4574 {
4132 ScenePresence presence = World.GetScenePresence(agentId); 4575 ScenePresence presence = World.GetScenePresence(agentId);
4133 if (presence != null) 4576 if (presence != null && presence.PresenceType != PresenceType.Npc)
4134 { 4577 {
4578 // agent must not be a god
4579 if (presence.UserLevel >= 200) return;
4580
4135 // agent must be over the owners land 4581 // agent must be over the owners land
4136 if (m_host.OwnerID == World.LandChannel.GetLandObject( 4582 if (m_host.OwnerID == World.LandChannel.GetLandObject(
4137 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 4583 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
4138 { 4584 {
4139 World.TeleportClientHome(agentId, presence.ControllingClient); 4585 if (!World.TeleportClientHome(agentId, presence.ControllingClient))
4586 {
4587 // They can't be teleported home for some reason
4588 GridRegion regionInfo = World.GridService.GetRegionByUUID(UUID.Zero, new UUID("2b02daac-e298-42fa-9a75-f488d37896e6"));
4589 if (regionInfo != null)
4590 {
4591 World.RequestTeleportLocation(
4592 presence.ControllingClient, regionInfo.RegionHandle, new Vector3(128, 128, 23), Vector3.Zero,
4593 (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
4594 }
4595 }
4140 } 4596 }
4141 } 4597 }
4142 } 4598 }
@@ -4248,7 +4704,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4248 UUID av = new UUID(); 4704 UUID av = new UUID();
4249 if (!UUID.TryParse(agent,out av)) 4705 if (!UUID.TryParse(agent,out av))
4250 { 4706 {
4251 LSLError("First parameter to llDialog needs to be a key"); 4707 //LSLError("First parameter to llDialog needs to be a key");
4252 return; 4708 return;
4253 } 4709 }
4254 4710
@@ -4280,7 +4736,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4280 public void llCollisionSound(string impact_sound, double impact_volume) 4736 public void llCollisionSound(string impact_sound, double impact_volume)
4281 { 4737 {
4282 m_host.AddScriptLPS(1); 4738 m_host.AddScriptLPS(1);
4283 4739
4740 if(impact_sound == "")
4741 {
4742 m_host.CollisionSoundVolume = (float)impact_volume;
4743 m_host.CollisionSound = m_host.invalidCollisionSoundUUID;
4744 m_host.CollisionSoundType = 0;
4745 return;
4746 }
4284 // TODO: Parameter check logic required. 4747 // TODO: Parameter check logic required.
4285 UUID soundId = UUID.Zero; 4748 UUID soundId = UUID.Zero;
4286 if (!UUID.TryParse(impact_sound, out soundId)) 4749 if (!UUID.TryParse(impact_sound, out soundId))
@@ -4293,6 +4756,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4293 4756
4294 m_host.CollisionSound = soundId; 4757 m_host.CollisionSound = soundId;
4295 m_host.CollisionSoundVolume = (float)impact_volume; 4758 m_host.CollisionSoundVolume = (float)impact_volume;
4759 m_host.CollisionSoundType = 1;
4296 } 4760 }
4297 4761
4298 public LSL_String llGetAnimation(string id) 4762 public LSL_String llGetAnimation(string id)
@@ -4306,14 +4770,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4306 4770
4307 if (m_host.RegionHandle == presence.RegionHandle) 4771 if (m_host.RegionHandle == presence.RegionHandle)
4308 { 4772 {
4309 Dictionary<UUID, string> animationstateNames = DefaultAvatarAnimations.AnimStateNames;
4310
4311 if (presence != null) 4773 if (presence != null)
4312 { 4774 {
4313 AnimationSet currentAnims = presence.Animator.Animations; 4775 if (presence.SitGround)
4314 string currentAnimationState = String.Empty; 4776 return "Sitting on Ground";
4315 if (animationstateNames.TryGetValue(currentAnims.DefaultAnimation.AnimID, out currentAnimationState)) 4777 if (presence.ParentID != 0 || presence.ParentUUID != UUID.Zero)
4316 return currentAnimationState; 4778 return "Sitting";
4779
4780 string movementAnimation = presence.Animator.CurrentMovementAnimation;
4781 string lslMovementAnimation;
4782
4783 if (MovementAnimationsForLSL.TryGetValue(movementAnimation, out lslMovementAnimation))
4784 return lslMovementAnimation;
4317 } 4785 }
4318 } 4786 }
4319 4787
@@ -4460,7 +4928,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4460 { 4928 {
4461 float distance = (PusheePos - m_host.AbsolutePosition).Length(); 4929 float distance = (PusheePos - m_host.AbsolutePosition).Length();
4462 float distance_term = distance * distance * distance; // Script Energy 4930 float distance_term = distance * distance * distance; // Script Energy
4463 float pusher_mass = m_host.GetMass(); 4931 // use total object mass and not part
4932 float pusher_mass = m_host.ParentGroup.GetMass();
4464 4933
4465 float PUSH_ATTENUATION_DISTANCE = 17f; 4934 float PUSH_ATTENUATION_DISTANCE = 17f;
4466 float PUSH_ATTENUATION_SCALE = 5f; 4935 float PUSH_ATTENUATION_SCALE = 5f;
@@ -4710,6 +5179,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4710 { 5179 {
4711 return item.AssetID.ToString(); 5180 return item.AssetID.ToString();
4712 } 5181 }
5182 m_host.TaskInventory.LockItemsForRead(false);
4713 5183
4714 return UUID.Zero.ToString(); 5184 return UUID.Zero.ToString();
4715 } 5185 }
@@ -4843,7 +5313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4843 public LSL_Vector llGetCenterOfMass() 5313 public LSL_Vector llGetCenterOfMass()
4844 { 5314 {
4845 m_host.AddScriptLPS(1); 5315 m_host.AddScriptLPS(1);
4846 Vector3 center = m_host.GetGeometricCenter(); 5316 Vector3 center = m_host.GetCenterOfMass();
4847 return new LSL_Vector(center.X,center.Y,center.Z); 5317 return new LSL_Vector(center.X,center.Y,center.Z);
4848 } 5318 }
4849 5319
@@ -4862,14 +5332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4862 { 5332 {
4863 m_host.AddScriptLPS(1); 5333 m_host.AddScriptLPS(1);
4864 5334
4865 if (src == null) 5335 return src.Length;
4866 {
4867 return 0;
4868 }
4869 else
4870 {
4871 return src.Length;
4872 }
4873 } 5336 }
4874 5337
4875 public LSL_Integer llList2Integer(LSL_List src, int index) 5338 public LSL_Integer llList2Integer(LSL_List src, int index)
@@ -4915,7 +5378,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4915 else if (src.Data[index] is LSL_Float) 5378 else if (src.Data[index] is LSL_Float)
4916 return Convert.ToDouble(((LSL_Float) src.Data[index]).value); 5379 return Convert.ToDouble(((LSL_Float) src.Data[index]).value);
4917 else if (src.Data[index] is LSL_String) 5380 else if (src.Data[index] is LSL_String)
4918 return Convert.ToDouble(((LSL_String) src.Data[index]).m_string); 5381 {
5382 string str = ((LSL_String) src.Data[index]).m_string;
5383 Match m = Regex.Match(str, "^\\s*(-?\\+?[,0-9]+\\.?[0-9]*)");
5384 if (m != Match.Empty)
5385 {
5386 str = m.Value;
5387 double d = 0.0;
5388 if (!Double.TryParse(str, out d))
5389 return 0.0;
5390
5391 return d;
5392 }
5393 return 0.0;
5394 }
4919 return Convert.ToDouble(src.Data[index]); 5395 return Convert.ToDouble(src.Data[index]);
4920 } 5396 }
4921 catch (FormatException) 5397 catch (FormatException)
@@ -5188,7 +5664,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5188 } 5664 }
5189 } 5665 }
5190 } 5666 }
5191 else { 5667 else
5668 {
5192 object[] array = new object[src.Length]; 5669 object[] array = new object[src.Length];
5193 Array.Copy(src.Data, 0, array, 0, src.Length); 5670 Array.Copy(src.Data, 0, array, 0, src.Length);
5194 result = new LSL_List(array); 5671 result = new LSL_List(array);
@@ -5295,7 +5772,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5295 public LSL_Integer llGetRegionAgentCount() 5772 public LSL_Integer llGetRegionAgentCount()
5296 { 5773 {
5297 m_host.AddScriptLPS(1); 5774 m_host.AddScriptLPS(1);
5298 return new LSL_Integer(World.GetRootAgentCount()); 5775
5776 int count = 0;
5777 World.ForEachRootScenePresence(delegate(ScenePresence sp) {
5778 count++;
5779 });
5780
5781 return new LSL_Integer(count);
5299 } 5782 }
5300 5783
5301 public LSL_Vector llGetRegionCorner() 5784 public LSL_Vector llGetRegionCorner()
@@ -5575,6 +6058,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5575 flags |= ScriptBaseClass.AGENT_SITTING; 6058 flags |= ScriptBaseClass.AGENT_SITTING;
5576 } 6059 }
5577 6060
6061 if (agent.Appearance.VisualParams[(int)AvatarAppearance.VPElement.SHAPE_MALE] > 0)
6062 {
6063 flags |= ScriptBaseClass.AGENT_MALE;
6064 }
6065
5578 return flags; 6066 return flags;
5579 } 6067 }
5580 6068
@@ -5721,10 +6209,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5721 m_host.AddScriptLPS(1); 6209 m_host.AddScriptLPS(1);
5722 6210
5723 List<SceneObjectPart> parts = GetLinkParts(linknumber); 6211 List<SceneObjectPart> parts = GetLinkParts(linknumber);
5724 6212 if (parts.Count > 0)
5725 foreach (var part in parts)
5726 { 6213 {
5727 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate); 6214 try
6215 {
6216 parts[0].ParentGroup.areUpdatesSuspended = true;
6217 foreach (var part in parts)
6218 {
6219 SetTextureAnim(part, mode, face, sizex, sizey, start, length, rate);
6220 }
6221 }
6222 finally
6223 {
6224 parts[0].ParentGroup.areUpdatesSuspended = false;
6225 }
5728 } 6226 }
5729 } 6227 }
5730 6228
@@ -5776,13 +6274,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5776 6274
5777 if (m_host.OwnerID == land.LandData.OwnerID) 6275 if (m_host.OwnerID == land.LandData.OwnerID)
5778 { 6276 {
5779 World.TeleportClientHome(agentID, presence.ControllingClient); 6277 Vector3 pos = World.GetNearestAllowedPosition(presence, land);
6278 presence.TeleportWithMomentum(pos, null);
6279 presence.ControllingClient.SendAlertMessage("You have been ejected from this land");
5780 } 6280 }
5781 } 6281 }
5782 } 6282 }
5783 ScriptSleep(5000); 6283 ScriptSleep(5000);
5784 } 6284 }
5785 6285
6286 public LSL_List llParseString2List(string str, LSL_List separators, LSL_List in_spacers)
6287 {
6288 return ParseString2List(str, separators, in_spacers, false);
6289 }
6290
5786 public LSL_Integer llOverMyLand(string id) 6291 public LSL_Integer llOverMyLand(string id)
5787 { 6292 {
5788 m_host.AddScriptLPS(1); 6293 m_host.AddScriptLPS(1);
@@ -5847,8 +6352,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5847 UUID agentId = new UUID(); 6352 UUID agentId = new UUID();
5848 if (!UUID.TryParse(agent, out agentId)) 6353 if (!UUID.TryParse(agent, out agentId))
5849 return new LSL_Integer(0); 6354 return new LSL_Integer(0);
6355 if (agentId == m_host.GroupID)
6356 return new LSL_Integer(1);
5850 ScenePresence presence = World.GetScenePresence(agentId); 6357 ScenePresence presence = World.GetScenePresence(agentId);
5851 if (presence == null || presence.IsChildAgent) // Return flase for child agents 6358 if (presence == null || presence.IsChildAgent) // Return false for child agents
5852 return new LSL_Integer(0); 6359 return new LSL_Integer(0);
5853 IClientAPI client = presence.ControllingClient; 6360 IClientAPI client = presence.ControllingClient;
5854 if (m_host.GroupID == client.ActiveGroupId) 6361 if (m_host.GroupID == client.ActiveGroupId)
@@ -5983,7 +6490,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5983 return m_host.ParentGroup.AttachmentPoint; 6490 return m_host.ParentGroup.AttachmentPoint;
5984 } 6491 }
5985 6492
5986 public LSL_Integer llGetFreeMemory() 6493 public virtual LSL_Integer llGetFreeMemory()
5987 { 6494 {
5988 m_host.AddScriptLPS(1); 6495 m_host.AddScriptLPS(1);
5989 // Make scripts designed for LSO happy 6496 // Make scripts designed for LSO happy
@@ -6100,7 +6607,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6100 SetParticleSystem(m_host, rules); 6607 SetParticleSystem(m_host, rules);
6101 } 6608 }
6102 6609
6103 private void SetParticleSystem(SceneObjectPart part, LSL_List rules) { 6610 private void SetParticleSystem(SceneObjectPart part, LSL_List rules)
6611 {
6104 6612
6105 6613
6106 if (rules.Length == 0) 6614 if (rules.Length == 0)
@@ -6328,17 +6836,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6328 if (folderID == UUID.Zero) 6836 if (folderID == UUID.Zero)
6329 return; 6837 return;
6330 6838
6331 byte[] bucket = new byte[17]; 6839 byte[] bucket = new byte[1];
6332 bucket[0] = (byte)AssetType.Folder; 6840 bucket[0] = (byte)AssetType.Folder;
6333 byte[] objBytes = folderID.GetBytes(); 6841 //byte[] objBytes = folderID.GetBytes();
6334 Array.Copy(objBytes, 0, bucket, 1, 16); 6842 //Array.Copy(objBytes, 0, bucket, 1, 16);
6335 6843
6336 GridInstantMessage msg = new GridInstantMessage(World, 6844 GridInstantMessage msg = new GridInstantMessage(World,
6337 m_host.UUID, m_host.Name + ", an object owned by " + 6845 m_host.OwnerID, m_host.Name, destID,
6338 resolveName(m_host.OwnerID) + ",", destID, 6846 (byte)InstantMessageDialog.TaskInventoryOffered,
6339 (byte)InstantMessageDialog.InventoryOffered, 6847 false, category+". "+m_host.Name+" is located at "+
6340 false, category + "\n" + m_host.Name + " is located at " + 6848 World.RegionInfo.RegionName+" "+
6341 World.RegionInfo.RegionName + " " +
6342 m_host.AbsolutePosition.ToString(), 6849 m_host.AbsolutePosition.ToString(),
6343 folderID, true, m_host.AbsolutePosition, 6850 folderID, true, m_host.AbsolutePosition,
6344 bucket); 6851 bucket);
@@ -6418,7 +6925,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6418 { 6925 {
6419 // LSL quaternions can normalize to 0, normal Quaternions can't. 6926 // LSL quaternions can normalize to 0, normal Quaternions can't.
6420 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) 6927 if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0)
6421 rot.z = 1; // ZERO_ROTATION = 0,0,0,1 6928 rot.s = 1; // ZERO_ROTATION = 0,0,0,1
6422 6929
6423 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z); 6930 part.SitTargetPosition = new Vector3((float)offset.x, (float)offset.y, (float)offset.z);
6424 part.SitTargetOrientation = Rot2Quaternion(rot); 6931 part.SitTargetOrientation = Rot2Quaternion(rot);
@@ -6575,13 +7082,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6575 UUID av = new UUID(); 7082 UUID av = new UUID();
6576 if (!UUID.TryParse(avatar,out av)) 7083 if (!UUID.TryParse(avatar,out av))
6577 { 7084 {
6578 LSLError("First parameter to llDialog needs to be a key"); 7085 //LSLError("First parameter to llDialog needs to be a key");
6579 return; 7086 return;
6580 } 7087 }
6581 if (buttons.Length < 1) 7088 if (buttons.Length < 1)
6582 { 7089 {
6583 LSLError("No less than 1 button can be shown"); 7090 buttons.Add("OK");
6584 return;
6585 } 7091 }
6586 if (buttons.Length > 12) 7092 if (buttons.Length > 12)
6587 { 7093 {
@@ -6598,7 +7104,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6598 } 7104 }
6599 if (buttons.Data[i].ToString().Length > 24) 7105 if (buttons.Data[i].ToString().Length > 24)
6600 { 7106 {
6601 LSLError("button label cannot be longer than 24 characters"); 7107 llWhisper(ScriptBaseClass.DEBUG_CHANNEL, "button label cannot be longer than 24 characters");
6602 return; 7108 return;
6603 } 7109 }
6604 buts[i] = buttons.Data[i].ToString(); 7110 buts[i] = buttons.Data[i].ToString();
@@ -6665,9 +7171,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6665 return; 7171 return;
6666 } 7172 }
6667 7173
6668 // the rest of the permission checks are done in RezScript, so check the pin there as well 7174 SceneObjectPart dest = World.GetSceneObjectPart(destId);
6669 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param); 7175 if (dest != null)
7176 {
7177 if ((item.BasePermissions & (uint)PermissionMask.Transfer) != 0 || dest.ParentGroup.RootPart.OwnerID == m_host.ParentGroup.RootPart.OwnerID)
7178 {
7179 // the rest of the permission checks are done in RezScript, so check the pin there as well
7180 World.RezScriptFromPrim(item.ItemID, m_host, destId, pin, running, start_param);
6670 7181
7182 if ((item.BasePermissions & (uint)PermissionMask.Copy) == 0)
7183 m_host.Inventory.RemoveInventoryItem(item.ItemID);
7184 }
7185 }
6671 // this will cause the delay even if the script pin or permissions were wrong - seems ok 7186 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6672 ScriptSleep(3000); 7187 ScriptSleep(3000);
6673 } 7188 }
@@ -6730,19 +7245,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6730 public LSL_String llMD5String(string src, int nonce) 7245 public LSL_String llMD5String(string src, int nonce)
6731 { 7246 {
6732 m_host.AddScriptLPS(1); 7247 m_host.AddScriptLPS(1);
6733 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString())); 7248 return Util.Md5Hash(String.Format("{0}:{1}", src, nonce.ToString()), Encoding.UTF8);
6734 } 7249 }
6735 7250
6736 public LSL_String llSHA1String(string src) 7251 public LSL_String llSHA1String(string src)
6737 { 7252 {
6738 m_host.AddScriptLPS(1); 7253 m_host.AddScriptLPS(1);
6739 return Util.SHA1Hash(src).ToLower(); 7254 return Util.SHA1Hash(src, Encoding.UTF8).ToLower();
6740 } 7255 }
6741 7256
6742 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve) 7257 protected ObjectShapePacket.ObjectDataBlock SetPrimitiveBlockShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, byte profileshape, byte pathcurve)
6743 { 7258 {
6744 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7259 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6745 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7260 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7261 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7262 return shapeBlock;
6746 7263
6747 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT && 7264 if (holeshape != (int)ScriptBaseClass.PRIM_HOLE_DEFAULT &&
6748 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE && 7265 holeshape != (int)ScriptBaseClass.PRIM_HOLE_CIRCLE &&
@@ -6847,6 +7364,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6847 // Prim type box, cylinder and prism. 7364 // Prim type box, cylinder and prism.
6848 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) 7365 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)
6849 { 7366 {
7367 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7368 return;
7369
6850 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7370 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6851 ObjectShapePacket.ObjectDataBlock shapeBlock; 7371 ObjectShapePacket.ObjectDataBlock shapeBlock;
6852 7372
@@ -6900,6 +7420,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6900 // Prim type sphere. 7420 // Prim type sphere.
6901 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve) 7421 protected void SetPrimitiveShapeParams(SceneObjectPart part, int holeshape, LSL_Vector cut, float hollow, LSL_Vector twist, LSL_Vector dimple, byte profileshape, byte pathcurve)
6902 { 7422 {
7423 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7424 return;
7425
6903 ObjectShapePacket.ObjectDataBlock shapeBlock; 7426 ObjectShapePacket.ObjectDataBlock shapeBlock;
6904 7427
6905 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve); 7428 shapeBlock = SetPrimitiveBlockShapeParams(part, holeshape, cut, hollow, twist, profileshape, pathcurve);
@@ -6941,6 +7464,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6941 // Prim type torus, tube and ring. 7464 // Prim type torus, tube and ring.
6942 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) 7465 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)
6943 { 7466 {
7467 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7468 return;
7469
6944 float tempFloat; // Use in float expressions below to avoid byte cast precision issues. 7470 float tempFloat; // Use in float expressions below to avoid byte cast precision issues.
6945 ObjectShapePacket.ObjectDataBlock shapeBlock; 7471 ObjectShapePacket.ObjectDataBlock shapeBlock;
6946 7472
@@ -7076,6 +7602,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7076 // Prim type sculpt. 7602 // Prim type sculpt.
7077 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve) 7603 protected void SetPrimitiveShapeParams(SceneObjectPart part, string map, int type, byte pathcurve)
7078 { 7604 {
7605 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7606 return;
7607
7079 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock(); 7608 ObjectShapePacket.ObjectDataBlock shapeBlock = new ObjectShapePacket.ObjectDataBlock();
7080 UUID sculptId; 7609 UUID sculptId;
7081 7610
@@ -7100,7 +7629,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7100 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag)) 7629 type != (ScriptBaseClass.PRIM_SCULPT_TYPE_TORUS | flag))
7101 { 7630 {
7102 // default 7631 // default
7103 type = (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE; 7632 type = type | (int)ScriptBaseClass.PRIM_SCULPT_TYPE_SPHERE;
7104 } 7633 }
7105 7634
7106 part.Shape.SetSculptProperties((byte)type, sculptId); 7635 part.Shape.SetSculptProperties((byte)type, sculptId);
@@ -7116,34 +7645,315 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7116 ScriptSleep(200); 7645 ScriptSleep(200);
7117 } 7646 }
7118 7647
7119 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules) 7648 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules)
7120 { 7649 {
7121 m_host.AddScriptLPS(1); 7650 m_host.AddScriptLPS(1);
7122 7651
7123 setLinkPrimParams(linknumber, rules); 7652 setLinkPrimParams(linknumber, rules);
7653 }
7654
7655 private void setLinkPrimParams(int linknumber, LSL_List rules)
7656 {
7657 List<SceneObjectPart> parts = GetLinkParts(linknumber);
7658 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7659 if (parts.Count>0)
7660 {
7661 try
7662 {
7663 parts[0].ParentGroup.areUpdatesSuspended = true;
7664 foreach (SceneObjectPart part in parts)
7665 SetPrimParams(part, rules);
7666 }
7667 finally
7668 {
7669 parts[0].ParentGroup.areUpdatesSuspended = false;
7670 }
7671 }
7672 if (avatars.Count > 0)
7673 {
7674 foreach (ScenePresence avatar in avatars)
7675 SetPrimParams(avatar, rules);
7676 }
7677 }
7678
7679 private void SetPhysicsMaterial(SceneObjectPart part, int material_bits,
7680 float material_density, float material_friction,
7681 float material_restitution, float material_gravity_modifier)
7682 {
7683 ExtraPhysicsData physdata = new ExtraPhysicsData();
7684 physdata.PhysShapeType = (PhysShapeType)part.PhysicsShapeType;
7685 physdata.Density = part.Density;
7686 physdata.Friction = part.Friction;
7687 physdata.Bounce = part.Bounciness;
7688 physdata.GravitationModifier = part.GravityModifier;
7124 7689
7690 if ((material_bits & (int)ScriptBaseClass.DENSITY) != 0)
7691 physdata.Density = material_density;
7692 if ((material_bits & (int)ScriptBaseClass.FRICTION) != 0)
7693 physdata.Friction = material_friction;
7694 if ((material_bits & (int)ScriptBaseClass.RESTITUTION) != 0)
7695 physdata.Bounce = material_restitution;
7696 if ((material_bits & (int)ScriptBaseClass.GRAVITY_MULTIPLIER) != 0)
7697 physdata.GravitationModifier = material_gravity_modifier;
7698
7699 part.UpdateExtraPhysics(physdata);
7700 }
7701
7702 public void llSetPhysicsMaterial(int material_bits,
7703 float material_gravity_modifier, float material_restitution,
7704 float material_friction, float material_density)
7705 {
7706 SetPhysicsMaterial(m_host, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
7707 }
7708
7709 public void llSetLinkPrimitiveParams(int linknumber, LSL_List rules)
7710 {
7711 llSetLinkPrimitiveParamsFast(linknumber, rules);
7125 ScriptSleep(200); 7712 ScriptSleep(200);
7126 } 7713 }
7127 7714
7128 public void llSetLinkPrimitiveParamsFast(int linknumber, LSL_List rules) 7715 // vector up using libomv (c&p from sop )
7716 // vector up rotated by r
7717 private Vector3 Zrot(Quaternion r)
7129 { 7718 {
7130 m_host.AddScriptLPS(1); 7719 double x, y, z, m;
7131 7720
7132 setLinkPrimParams(linknumber, rules); 7721 m = r.X * r.X + r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7722 if (Math.Abs(1.0 - m) > 0.000001)
7723 {
7724 m = 1.0 / Math.Sqrt(m);
7725 r.X *= (float)m;
7726 r.Y *= (float)m;
7727 r.Z *= (float)m;
7728 r.W *= (float)m;
7729 }
7730
7731 x = 2 * (r.X * r.Z + r.Y * r.W);
7732 y = 2 * (-r.X * r.W + r.Y * r.Z);
7733 z = -r.X * r.X - r.Y * r.Y + r.Z * r.Z + r.W * r.W;
7734
7735 return new Vector3((float)x, (float)y, (float)z);
7133 } 7736 }
7134 7737
7135 protected void setLinkPrimParams(int linknumber, LSL_List rules) 7738 protected void SetPrimParams(ScenePresence av, LSL_List rules)
7136 { 7739 {
7137 List<SceneObjectPart> parts = GetLinkParts(linknumber); 7740 //This is a special version of SetPrimParams to deal with avatars which are sat on the linkset.
7138 7741
7139 foreach (SceneObjectPart part in parts) 7742 int idx = 0;
7140 SetPrimParams(part, rules); 7743 SceneObjectPart sitpart = World.GetSceneObjectPart(av.ParentID); // betting this will be used
7744
7745 bool positionChanged = false;
7746 Vector3 finalPos = Vector3.Zero;
7747
7748 try
7749 {
7750 while (idx < rules.Length)
7751 {
7752 int code = rules.GetLSLIntegerItem(idx++);
7753
7754 int remain = rules.Length - idx;
7755
7756 switch (code)
7757 {
7758 // a avatar is a child
7759 case (int)ScriptBaseClass.PRIM_POSITION:
7760 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
7761 {
7762 if (remain < 1)
7763 return;
7764 LSL_Vector v;
7765 v = rules.GetVector3Item(idx++);
7766
7767 if (sitpart == null)
7768 break;
7769
7770 Vector3 pos = new Vector3((float)v.x, (float)v.y, (float)v.z); // requested absolute position
7771
7772 if (sitpart != sitpart.ParentGroup.RootPart)
7773 {
7774 pos -= sitpart.OffsetPosition; // remove sit part offset
7775 Quaternion rot = sitpart.RotationOffset;
7776 pos *= Quaternion.Conjugate(rot); // removed sit part rotation
7777 }
7778 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f * 2.0f);
7779 pos += sitOffset;
7780
7781 finalPos = pos;
7782 positionChanged = true;
7783 }
7784 break;
7785
7786 case (int)ScriptBaseClass.PRIM_ROTATION:
7787 {
7788 if (remain < 1)
7789 return;
7790
7791 if (sitpart == null)
7792 break;
7793
7794 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7795 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested world rotation
7796
7797// need to replicate SL bug
7798 SceneObjectGroup sitgrp = sitpart.ParentGroup;
7799 if (sitgrp != null && sitgrp.RootPart != sitpart)
7800 {
7801 rot = sitgrp.RootPart.RotationOffset * rot;
7802 }
7803
7804 Quaternion srot = sitpart.RotationOffset;
7805 rot = Quaternion.Conjugate(srot) * rot; // removed sit part offset rotation
7806 av.Rotation = rot;
7807// av.SendAvatarDataToAllAgents();
7808 av.SendTerseUpdateToAllClients();
7809 }
7810 break;
7811
7812 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7813 {
7814 if (remain < 1)
7815 return;
7816
7817 if (sitpart == null)
7818 break;
7819
7820 LSL_Rotation r = rules.GetQuaternionItem(idx++);
7821 Quaternion rot = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); // requested offset rotation
7822 if (sitpart != sitpart.ParentGroup.RootPart)
7823 {
7824 Quaternion srot = sitpart.RotationOffset;
7825 rot = Quaternion.Conjugate(srot) * rot; // remove sit part offset rotation
7826 }
7827 av.Rotation = rot;
7828// av.SendAvatarDataToAllAgents();
7829 av.SendTerseUpdateToAllClients();
7830 }
7831 break;
7832
7833 // parse rest doing nothing but number of parameters error check
7834 case (int)ScriptBaseClass.PRIM_SIZE:
7835 case (int)ScriptBaseClass.PRIM_MATERIAL:
7836 case (int)ScriptBaseClass.PRIM_PHANTOM:
7837 case (int)ScriptBaseClass.PRIM_PHYSICS:
7838 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
7839 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7840 case (int)ScriptBaseClass.PRIM_NAME:
7841 case (int)ScriptBaseClass.PRIM_DESC:
7842 if (remain < 1)
7843 return;
7844 idx++;
7845 break;
7846
7847 case (int)ScriptBaseClass.PRIM_GLOW:
7848 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
7849 case (int)ScriptBaseClass.PRIM_TEXGEN:
7850 if (remain < 2)
7851 return;
7852 idx += 2;
7853 break;
7854
7855 case (int)ScriptBaseClass.PRIM_TYPE:
7856 if (remain < 3)
7857 return;
7858 code = (int)rules.GetLSLIntegerItem(idx++);
7859 remain = rules.Length - idx;
7860 switch (code)
7861 {
7862 case (int)ScriptBaseClass.PRIM_TYPE_BOX:
7863 case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER:
7864 case (int)ScriptBaseClass.PRIM_TYPE_PRISM:
7865 if (remain < 6)
7866 return;
7867 idx += 6;
7868 break;
7869
7870 case (int)ScriptBaseClass.PRIM_TYPE_SPHERE:
7871 if (remain < 5)
7872 return;
7873 idx += 5;
7874 break;
7875
7876 case (int)ScriptBaseClass.PRIM_TYPE_TORUS:
7877 case (int)ScriptBaseClass.PRIM_TYPE_TUBE:
7878 case (int)ScriptBaseClass.PRIM_TYPE_RING:
7879 if (remain < 11)
7880 return;
7881 idx += 11;
7882 break;
7883
7884 case (int)ScriptBaseClass.PRIM_TYPE_SCULPT:
7885 if (remain < 2)
7886 return;
7887 idx += 2;
7888 break;
7889 }
7890 break;
7891
7892 case (int)ScriptBaseClass.PRIM_COLOR:
7893 case (int)ScriptBaseClass.PRIM_TEXT:
7894 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
7895 case (int)ScriptBaseClass.PRIM_OMEGA:
7896 if (remain < 3)
7897 return;
7898 idx += 3;
7899 break;
7900
7901 case (int)ScriptBaseClass.PRIM_TEXTURE:
7902 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
7903 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
7904 if (remain < 5)
7905 return;
7906 idx += 5;
7907 break;
7908
7909 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
7910 if (remain < 7)
7911 return;
7912
7913 idx += 7;
7914 break;
7915
7916 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7917 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7918 return;
7919
7920 if (positionChanged)
7921 {
7922 positionChanged = false;
7923 av.OffsetPosition = finalPos;
7924// av.SendAvatarDataToAllAgents();
7925 av.SendTerseUpdateToAllClients();
7926 }
7927
7928 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7929 LSL_List new_rules = rules.GetSublist(idx, -1);
7930 setLinkPrimParams((int)new_linknumber, new_rules);
7931 return;
7932 }
7933 }
7934 }
7935
7936 finally
7937 {
7938 if (positionChanged)
7939 {
7940 av.OffsetPosition = finalPos;
7941// av.SendAvatarDataToAllAgents();
7942 av.SendTerseUpdateToAllClients();
7943 positionChanged = false;
7944 }
7945 }
7141 } 7946 }
7142 7947
7143 protected void SetPrimParams(SceneObjectPart part, LSL_List rules) 7948 protected void SetPrimParams(SceneObjectPart part, LSL_List rules)
7144 { 7949 {
7950 if (part == null || part.ParentGroup == null || part.ParentGroup.IsDeleted)
7951 return;
7952
7145 int idx = 0; 7953 int idx = 0;
7146 7954
7955 SceneObjectGroup parentgrp = part.ParentGroup;
7956
7147 bool positionChanged = false; 7957 bool positionChanged = false;
7148 LSL_Vector currentPosition = GetPartLocalPos(part); 7958 LSL_Vector currentPosition = GetPartLocalPos(part);
7149 7959
@@ -7166,8 +7976,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7166 return; 7976 return;
7167 7977
7168 v=rules.GetVector3Item(idx++); 7978 v=rules.GetVector3Item(idx++);
7169 positionChanged = true;
7170 currentPosition = GetSetPosTarget(part, v, currentPosition); 7979 currentPosition = GetSetPosTarget(part, v, currentPosition);
7980 positionChanged = true;
7171 7981
7172 break; 7982 break;
7173 case (int)ScriptBaseClass.PRIM_SIZE: 7983 case (int)ScriptBaseClass.PRIM_SIZE:
@@ -7183,8 +7993,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7183 return; 7993 return;
7184 7994
7185 LSL_Rotation q = rules.GetQuaternionItem(idx++); 7995 LSL_Rotation q = rules.GetQuaternionItem(idx++);
7996 SceneObjectPart rootPart = parentgrp.RootPart;
7186 // try to let this work as in SL... 7997 // try to let this work as in SL...
7187 if (part.ParentID == 0) 7998 if (rootPart == part)
7188 { 7999 {
7189 // special case: If we are root, rotate complete SOG to new rotation 8000 // special case: If we are root, rotate complete SOG to new rotation
7190 SetRot(part, Rot2Quaternion(q)); 8001 SetRot(part, Rot2Quaternion(q));
@@ -7192,7 +8003,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7192 else 8003 else
7193 { 8004 {
7194 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask. 8005 // we are a child. The rotation values will be set to the one of root modified by rot, as in SL. Don't ask.
7195 SceneObjectPart rootPart = part.ParentGroup.RootPart; 8006 // sounds like sl bug that we need to replicate
7196 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q)); 8007 SetRot(part, rootPart.RotationOffset * Rot2Quaternion(q));
7197 } 8008 }
7198 8009
@@ -7445,7 +8256,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7445 return; 8256 return;
7446 8257
7447 string ph = rules.Data[idx++].ToString(); 8258 string ph = rules.Data[idx++].ToString();
7448 m_host.ParentGroup.ScriptSetPhantomStatus(ph.Equals("1")); 8259 parentgrp.ScriptSetPhantomStatus(ph.Equals("1"));
7449 8260
7450 break; 8261 break;
7451 8262
@@ -7463,12 +8274,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7463 part.ScriptSetPhysicsStatus(physics); 8274 part.ScriptSetPhysicsStatus(physics);
7464 break; 8275 break;
7465 8276
8277 case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE:
8278 if (remain < 1)
8279 return;
8280
8281 int shape_type = rules.GetLSLIntegerItem(idx++);
8282
8283 ExtraPhysicsData physdata = new ExtraPhysicsData();
8284 physdata.Density = part.Density;
8285 physdata.Bounce = part.Bounciness;
8286 physdata.GravitationModifier = part.GravityModifier;
8287 physdata.PhysShapeType = (PhysShapeType)shape_type;
8288
8289 part.UpdateExtraPhysics(physdata);
8290
8291 break;
8292
8293 case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL:
8294 if (remain < 5)
8295 return;
8296
8297 int material_bits = rules.GetLSLIntegerItem(idx++);
8298 float material_density = (float)rules.GetLSLFloatItem(idx++);
8299 float material_friction = (float)rules.GetLSLFloatItem(idx++);
8300 float material_restitution = (float)rules.GetLSLFloatItem(idx++);
8301 float material_gravity_modifier = (float)rules.GetLSLFloatItem(idx++);
8302
8303 SetPhysicsMaterial(part, material_bits, material_density, material_friction, material_restitution, material_gravity_modifier);
8304
8305 break;
8306
7466 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: 8307 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
7467 if (remain < 1) 8308 if (remain < 1)
7468 return; 8309 return;
7469 string temp = rules.Data[idx++].ToString(); 8310 string temp = rules.Data[idx++].ToString();
7470 8311
7471 m_host.ParentGroup.ScriptSetTemporaryStatus(temp.Equals("1")); 8312 parentgrp.ScriptSetTemporaryStatus(temp.Equals("1"));
7472 8313
7473 break; 8314 break;
7474 8315
@@ -7507,6 +8348,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7507 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 8348 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
7508 if (remain < 1) 8349 if (remain < 1)
7509 return; 8350 return;
8351
7510 LSL_Rotation lr = rules.GetQuaternionItem(idx++); 8352 LSL_Rotation lr = rules.GetQuaternionItem(idx++);
7511 SetRot(part, Rot2Quaternion(lr)); 8353 SetRot(part, Rot2Quaternion(lr));
7512 break; 8354 break;
@@ -7518,13 +8360,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7518 LSL_Float gain = rules.GetLSLFloatItem(idx++); 8360 LSL_Float gain = rules.GetLSLFloatItem(idx++);
7519 TargetOmega(part, axis, (double)spinrate, (double)gain); 8361 TargetOmega(part, axis, (double)spinrate, (double)gain);
7520 break; 8362 break;
8363
7521 case (int)ScriptBaseClass.PRIM_LINK_TARGET: 8364 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
7522 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. 8365 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
7523 return; 8366 return;
8367
8368 // do a pending position change before jumping to other part/avatar
8369 if (positionChanged)
8370 {
8371 positionChanged = false;
8372 if (parentgrp == null)
8373 return;
8374
8375 if (parentgrp.RootPart == part)
8376 {
8377
8378 Util.FireAndForget(delegate(object x)
8379 {
8380 parentgrp.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8381 });
8382 }
8383 else
8384 {
8385 part.OffsetPosition = new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z);
8386 parentgrp.HasGroupChanged = true;
8387 parentgrp.ScheduleGroupForTerseUpdate();
8388 }
8389 }
8390
7524 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); 8391 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
7525 LSL_List new_rules = rules.GetSublist(idx, -1); 8392 LSL_List new_rules = rules.GetSublist(idx, -1);
7526 setLinkPrimParams((int)new_linknumber, new_rules); 8393 setLinkPrimParams((int)new_linknumber, new_rules);
7527
7528 return; 8394 return;
7529 } 8395 }
7530 } 8396 }
@@ -7536,7 +8402,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7536 if (part.ParentGroup.RootPart == part) 8402 if (part.ParentGroup.RootPart == part)
7537 { 8403 {
7538 SceneObjectGroup parent = part.ParentGroup; 8404 SceneObjectGroup parent = part.ParentGroup;
7539 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 8405 Util.FireAndForget(delegate(object x) {
8406 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
8407 });
7540 } 8408 }
7541 else 8409 else
7542 { 8410 {
@@ -7580,10 +8448,91 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7580 8448
7581 public LSL_String llXorBase64Strings(string str1, string str2) 8449 public LSL_String llXorBase64Strings(string str1, string str2)
7582 { 8450 {
7583 m_host.AddScriptLPS(1); 8451 string b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
7584 Deprecated("llXorBase64Strings"); 8452
7585 ScriptSleep(300); 8453 ScriptSleep(300);
7586 return String.Empty; 8454 m_host.AddScriptLPS(1);
8455
8456 if (str1 == String.Empty)
8457 return String.Empty;
8458 if (str2 == String.Empty)
8459 return str1;
8460
8461 int len = str2.Length;
8462 if ((len % 4) != 0) // LL is EVIL!!!!
8463 {
8464 while (str2.EndsWith("="))
8465 str2 = str2.Substring(0, str2.Length - 1);
8466
8467 len = str2.Length;
8468 int mod = len % 4;
8469
8470 if (mod == 1)
8471 str2 = str2.Substring(0, str2.Length - 1);
8472 else if (mod == 2)
8473 str2 += "==";
8474 else if (mod == 3)
8475 str2 += "=";
8476 }
8477
8478 byte[] data1;
8479 byte[] data2;
8480 try
8481 {
8482 data1 = Convert.FromBase64String(str1);
8483 data2 = Convert.FromBase64String(str2);
8484 }
8485 catch (Exception)
8486 {
8487 return new LSL_String(String.Empty);
8488 }
8489
8490 // For cases where the decoded length of s2 is greater
8491 // than the decoded length of s1, simply perform a normal
8492 // decode and XOR
8493 //
8494 if (data2.Length >= data1.Length)
8495 {
8496 for (int pos = 0 ; pos < data1.Length ; pos++ )
8497 data1[pos] ^= data2[pos];
8498
8499 return Convert.ToBase64String(data1);
8500 }
8501
8502 // Remove padding
8503 while (str1.EndsWith("="))
8504 str1 = str1.Substring(0, str1.Length - 1);
8505 while (str2.EndsWith("="))
8506 str2 = str2.Substring(0, str2.Length - 1);
8507
8508 byte[] d1 = new byte[str1.Length];
8509 byte[] d2 = new byte[str2.Length];
8510
8511 for (int i = 0 ; i < str1.Length ; i++)
8512 {
8513 int idx = b64.IndexOf(str1.Substring(i, 1));
8514 if (idx == -1)
8515 idx = 0;
8516 d1[i] = (byte)idx;
8517 }
8518
8519 for (int i = 0 ; i < str2.Length ; i++)
8520 {
8521 int idx = b64.IndexOf(str2.Substring(i, 1));
8522 if (idx == -1)
8523 idx = 0;
8524 d2[i] = (byte)idx;
8525 }
8526
8527 string output = String.Empty;
8528
8529 for (int pos = 0 ; pos < d1.Length ; pos++)
8530 output += b64[d1[pos] ^ d2[pos % d2.Length]];
8531
8532 while (output.Length % 3 > 0)
8533 output += "=";
8534
8535 return output;
7587 } 8536 }
7588 8537
7589 public void llRemoteDataSetRegion() 8538 public void llRemoteDataSetRegion()
@@ -7707,13 +8656,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7707 public LSL_Integer llGetNumberOfPrims() 8656 public LSL_Integer llGetNumberOfPrims()
7708 { 8657 {
7709 m_host.AddScriptLPS(1); 8658 m_host.AddScriptLPS(1);
7710 int avatarCount = 0; 8659 int avatarCount = m_host.ParentGroup.GetLinkedAvatars().Count;
7711 World.ForEachRootScenePresence(delegate(ScenePresence presence) 8660
7712 {
7713 if (presence.ParentID != 0 && m_host.ParentGroup.ContainsPart(presence.ParentID))
7714 avatarCount++;
7715 });
7716
7717 return m_host.ParentGroup.PrimCount + avatarCount; 8661 return m_host.ParentGroup.PrimCount + avatarCount;
7718 } 8662 }
7719 8663
@@ -7729,55 +8673,98 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7729 m_host.AddScriptLPS(1); 8673 m_host.AddScriptLPS(1);
7730 UUID objID = UUID.Zero; 8674 UUID objID = UUID.Zero;
7731 LSL_List result = new LSL_List(); 8675 LSL_List result = new LSL_List();
8676
8677 // If the ID is not valid, return null result
7732 if (!UUID.TryParse(obj, out objID)) 8678 if (!UUID.TryParse(obj, out objID))
7733 { 8679 {
7734 result.Add(new LSL_Vector()); 8680 result.Add(new LSL_Vector());
7735 result.Add(new LSL_Vector()); 8681 result.Add(new LSL_Vector());
7736 return result; 8682 return result;
7737 } 8683 }
8684
8685 // Check if this is an attached prim. If so, replace
8686 // the UUID with the avatar UUID and report it's bounding box
8687 SceneObjectPart part = World.GetSceneObjectPart(objID);
8688 if (part != null && part.ParentGroup.IsAttachment)
8689 objID = part.ParentGroup.AttachedAvatar;
8690
8691 // Find out if this is an avatar ID. If so, return it's box
7738 ScenePresence presence = World.GetScenePresence(objID); 8692 ScenePresence presence = World.GetScenePresence(objID);
7739 if (presence != null) 8693 if (presence != null)
7740 { 8694 {
7741 if (presence.ParentID == 0) // not sat on an object 8695 // As per LSL Wiki, there is no difference between sitting
8696 // and standing avatar since server 1.36
8697 LSL_Vector lower;
8698 LSL_Vector upper;
8699 if (presence.Animator.Animations.DefaultAnimation.AnimID
8700 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
7742 { 8701 {
7743 LSL_Vector lower; 8702 // This is for ground sitting avatars
7744 LSL_Vector upper; 8703 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7745 if (presence.Animator.Animations.DefaultAnimation.AnimID 8704 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7746 == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) 8705 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7747 {
7748 // This is for ground sitting avatars
7749 float height = presence.Appearance.AvatarHeight / 2.66666667f;
7750 lower = new LSL_Vector(-0.3375f, -0.45f, height * -1.0f);
7751 upper = new LSL_Vector(0.3375f, 0.45f, 0.0f);
7752 }
7753 else
7754 {
7755 // This is for standing/flying avatars
7756 float height = presence.Appearance.AvatarHeight / 2.0f;
7757 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7758 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7759 }
7760 result.Add(lower);
7761 result.Add(upper);
7762 return result;
7763 } 8706 }
7764 else 8707 else
7765 { 8708 {
7766 // sitting on an object so we need the bounding box of that 8709 // This is for standing/flying avatars
7767 // which should include the avatar so set the UUID to the 8710 float height = presence.Appearance.AvatarHeight / 2.0f;
7768 // UUID of the object the avatar is sat on and allow it to fall through 8711 lower = new LSL_Vector(-0.225f, -0.3f, height * -1.0f);
7769 // to processing an object 8712 upper = new LSL_Vector(0.225f, 0.3f, height + 0.05f);
7770 SceneObjectPart p = World.GetSceneObjectPart(presence.ParentID);
7771 objID = p.UUID;
7772 } 8713 }
8714
8715 // Adjust to the documented error offsets (see LSL Wiki)
8716 lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
8717 upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
8718
8719 if (lower.x > upper.x)
8720 lower.x = upper.x;
8721 if (lower.y > upper.y)
8722 lower.y = upper.y;
8723 if (lower.z > upper.z)
8724 lower.z = upper.z;
8725
8726 result.Add(lower);
8727 result.Add(upper);
8728 return result;
7773 } 8729 }
7774 SceneObjectPart part = World.GetSceneObjectPart(objID); 8730
8731 part = World.GetSceneObjectPart(objID);
7775 // Currently only works for single prims without a sitting avatar 8732 // Currently only works for single prims without a sitting avatar
7776 if (part != null) 8733 if (part != null)
7777 { 8734 {
7778 Vector3 halfSize = part.Scale / 2.0f; 8735 float minX;
7779 LSL_Vector lower = new LSL_Vector(halfSize.X * -1.0f, halfSize.Y * -1.0f, halfSize.Z * -1.0f); 8736 float maxX;
7780 LSL_Vector upper = new LSL_Vector(halfSize.X, halfSize.Y, halfSize.Z); 8737 float minY;
8738 float maxY;
8739 float minZ;
8740 float maxZ;
8741
8742 // This BBox is in sim coordinates, with the offset being
8743 // a contained point.
8744 Vector3[] offsets = Scene.GetCombinedBoundingBox(new List<SceneObjectGroup> { part.ParentGroup },
8745 out minX, out maxX, out minY, out maxY, out minZ, out maxZ);
8746
8747 minX -= offsets[0].X;
8748 maxX -= offsets[0].X;
8749 minY -= offsets[0].Y;
8750 maxY -= offsets[0].Y;
8751 minZ -= offsets[0].Z;
8752 maxZ -= offsets[0].Z;
8753
8754 LSL_Vector lower;
8755 LSL_Vector upper;
8756
8757 // Adjust to the documented error offsets (see LSL Wiki)
8758 lower = new LSL_Vector(minX + 0.05f, minY + 0.05f, minZ + 0.05f);
8759 upper = new LSL_Vector(maxX - 0.05f, maxY - 0.05f, maxZ - 0.05f);
8760
8761 if (lower.x > upper.x)
8762 lower.x = upper.x;
8763 if (lower.y > upper.y)
8764 lower.y = upper.y;
8765 if (lower.z > upper.z)
8766 lower.z = upper.z;
8767
7781 result.Add(lower); 8768 result.Add(lower);
7782 result.Add(upper); 8769 result.Add(upper);
7783 return result; 8770 return result;
@@ -7791,7 +8778,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7791 8778
7792 public LSL_Vector llGetGeometricCenter() 8779 public LSL_Vector llGetGeometricCenter()
7793 { 8780 {
7794 return new LSL_Vector(m_host.GetGeometricCenter().X, m_host.GetGeometricCenter().Y, m_host.GetGeometricCenter().Z); 8781 Vector3 tmp = m_host.GetGeometricCenter();
8782 return new LSL_Vector(tmp.X, tmp.Y, tmp.Z);
7795 } 8783 }
7796 8784
7797 public LSL_List llGetPrimitiveParams(LSL_List rules) 8785 public LSL_List llGetPrimitiveParams(LSL_List rules)
@@ -7804,16 +8792,291 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7804 { 8792 {
7805 m_host.AddScriptLPS(1); 8793 m_host.AddScriptLPS(1);
7806 8794
8795 // acording to SL wiki this must indicate a single link number or link_root or link_this.
8796 // keep other options as before
8797
7807 List<SceneObjectPart> parts = GetLinkParts(linknumber); 8798 List<SceneObjectPart> parts = GetLinkParts(linknumber);
8799 List<ScenePresence> avatars = GetLinkAvatars(linknumber);
7808 8800
7809 LSL_List res = new LSL_List(); 8801 LSL_List res = new LSL_List();
7810 8802
7811 foreach (var part in parts) 8803 if (parts.Count > 0)
7812 { 8804 {
7813 LSL_List partRes = GetLinkPrimitiveParams(part, rules); 8805 foreach (var part in parts)
7814 res += partRes; 8806 {
8807 LSL_List partRes = GetLinkPrimitiveParams(part, rules);
8808 res += partRes;
8809 }
7815 } 8810 }
8811 if (avatars.Count > 0)
8812 {
8813 foreach (ScenePresence avatar in avatars)
8814 {
8815 LSL_List avaRes = GetLinkPrimitiveParams(avatar, rules);
8816 res += avaRes;
8817 }
8818 }
8819 return res;
8820 }
8821
8822 public LSL_List GetLinkPrimitiveParams(ScenePresence avatar, LSL_List rules)
8823 {
8824 // avatars case
8825 // replies as SL wiki
8826
8827 LSL_List res = new LSL_List();
8828// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed
8829 SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone??
8830
8831 int idx = 0;
8832 while (idx < rules.Length)
8833 {
8834 int code = (int)rules.GetLSLIntegerItem(idx++);
8835 int remain = rules.Length - idx;
8836
8837 switch (code)
8838 {
8839 case (int)ScriptBaseClass.PRIM_MATERIAL:
8840 res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh));
8841 break;
8842
8843 case (int)ScriptBaseClass.PRIM_PHYSICS:
8844 res.Add(new LSL_Integer(0));
8845 break;
8846
8847 case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ:
8848 res.Add(new LSL_Integer(0));
8849 break;
8850
8851 case (int)ScriptBaseClass.PRIM_PHANTOM:
8852 res.Add(new LSL_Integer(0));
8853 break;
8854
8855 case (int)ScriptBaseClass.PRIM_POSITION:
8856
8857 Vector3 pos = avatar.OffsetPosition;
8858
8859 Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f);
8860 pos -= sitOffset;
8861
8862 if( sitPart != null)
8863 pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation();
8864
8865 res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z));
8866 break;
7816 8867
8868 case (int)ScriptBaseClass.PRIM_SIZE:
8869 // as in llGetAgentSize above
8870 res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
8871 break;
8872
8873 case (int)ScriptBaseClass.PRIM_ROTATION:
8874 Quaternion rot = avatar.Rotation;
8875 if (sitPart != null)
8876 {
8877 rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation
8878 }
8879
8880 res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W));
8881 break;
8882
8883 case (int)ScriptBaseClass.PRIM_TYPE:
8884 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX));
8885 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT));
8886 res.Add(new LSL_Vector(0f,1.0f,0f));
8887 res.Add(new LSL_Float(0.0f));
8888 res.Add(new LSL_Vector(0, 0, 0));
8889 res.Add(new LSL_Vector(1.0f,1.0f,0f));
8890 res.Add(new LSL_Vector(0, 0, 0));
8891 break;
8892
8893 case (int)ScriptBaseClass.PRIM_TEXTURE:
8894 if (remain < 1)
8895 return res;
8896
8897 int face = (int)rules.GetLSLIntegerItem(idx++);
8898 if (face == ScriptBaseClass.ALL_SIDES)
8899 {
8900 for (face = 0; face < 21; face++)
8901 {
8902 res.Add(new LSL_String(""));
8903 res.Add(new LSL_Vector(0,0,0));
8904 res.Add(new LSL_Vector(0,0,0));
8905 res.Add(new LSL_Float(0.0));
8906 }
8907 }
8908 else
8909 {
8910 if (face >= 0 && face < 21)
8911 {
8912 res.Add(new LSL_String(""));
8913 res.Add(new LSL_Vector(0,0,0));
8914 res.Add(new LSL_Vector(0,0,0));
8915 res.Add(new LSL_Float(0.0));
8916 }
8917 }
8918 break;
8919
8920 case (int)ScriptBaseClass.PRIM_COLOR:
8921 if (remain < 1)
8922 return res;
8923
8924 face = (int)rules.GetLSLIntegerItem(idx++);
8925
8926 if (face == ScriptBaseClass.ALL_SIDES)
8927 {
8928 for (face = 0; face < 21; face++)
8929 {
8930 res.Add(new LSL_Vector(0,0,0));
8931 res.Add(new LSL_Float(0));
8932 }
8933 }
8934 else
8935 {
8936 res.Add(new LSL_Vector(0,0,0));
8937 res.Add(new LSL_Float(0));
8938 }
8939 break;
8940
8941 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8942 if (remain < 1)
8943 return res;
8944 face = (int)rules.GetLSLIntegerItem(idx++);
8945
8946 if (face == ScriptBaseClass.ALL_SIDES)
8947 {
8948 for (face = 0; face < 21; face++)
8949 {
8950 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8951 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8952 }
8953 }
8954 else
8955 {
8956 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE));
8957 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE));
8958 }
8959 break;
8960
8961 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8962 if (remain < 1)
8963 return res;
8964 face = (int)rules.GetLSLIntegerItem(idx++);
8965
8966 if (face == ScriptBaseClass.ALL_SIDES)
8967 {
8968 for (face = 0; face < 21; face++)
8969 {
8970 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8971 }
8972 }
8973 else
8974 {
8975 res.Add(new LSL_Integer(ScriptBaseClass.FALSE));
8976 }
8977 break;
8978
8979 case (int)ScriptBaseClass.PRIM_FLEXIBLE:
8980 res.Add(new LSL_Integer(0));
8981 res.Add(new LSL_Integer(0));// softness
8982 res.Add(new LSL_Float(0.0f)); // gravity
8983 res.Add(new LSL_Float(0.0f)); // friction
8984 res.Add(new LSL_Float(0.0f)); // wind
8985 res.Add(new LSL_Float(0.0f)); // tension
8986 res.Add(new LSL_Vector(0f,0f,0f));
8987 break;
8988
8989 case (int)ScriptBaseClass.PRIM_TEXGEN:
8990 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8991 if (remain < 1)
8992 return res;
8993 face = (int)rules.GetLSLIntegerItem(idx++);
8994
8995 if (face == ScriptBaseClass.ALL_SIDES)
8996 {
8997 for (face = 0; face < 21; face++)
8998 {
8999 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9000 }
9001 }
9002 else
9003 {
9004 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9005 }
9006 break;
9007
9008 case (int)ScriptBaseClass.PRIM_POINT_LIGHT:
9009 res.Add(new LSL_Integer(0));
9010 res.Add(new LSL_Vector(0f,0f,0f));
9011 res.Add(new LSL_Float(0f)); // intensity
9012 res.Add(new LSL_Float(0f)); // radius
9013 res.Add(new LSL_Float(0f)); // falloff
9014 break;
9015
9016 case (int)ScriptBaseClass.PRIM_GLOW:
9017 if (remain < 1)
9018 return res;
9019 face = (int)rules.GetLSLIntegerItem(idx++);
9020
9021 if (face == ScriptBaseClass.ALL_SIDES)
9022 {
9023 for (face = 0; face < 21; face++)
9024 {
9025 res.Add(new LSL_Float(0f));
9026 }
9027 }
9028 else
9029 {
9030 res.Add(new LSL_Float(0f));
9031 }
9032 break;
9033
9034 case (int)ScriptBaseClass.PRIM_TEXT:
9035 res.Add(new LSL_String(""));
9036 res.Add(new LSL_Vector(0f,0f,0f));
9037 res.Add(new LSL_Float(1.0f));
9038 break;
9039
9040 case (int)ScriptBaseClass.PRIM_NAME:
9041 res.Add(new LSL_String(avatar.Name));
9042 break;
9043
9044 case (int)ScriptBaseClass.PRIM_DESC:
9045 res.Add(new LSL_String(""));
9046 break;
9047
9048 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
9049 Quaternion lrot = avatar.Rotation;
9050
9051 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9052 {
9053 lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset
9054 }
9055 res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W));
9056 break;
9057
9058 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
9059 Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part
9060 Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f);
9061 lpos -= lsitOffset;
9062
9063 if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart)
9064 {
9065 lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim
9066 }
9067 res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z));
9068 break;
9069
9070 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9071 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9072 return res;
9073 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9074 LSL_List new_rules = rules.GetSublist(idx, -1);
9075
9076 res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9077 return res;
9078 }
9079 }
7817 return res; 9080 return res;
7818 } 9081 }
7819 9082
@@ -7857,13 +9120,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7857 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, 9120 LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
7858 part.AbsolutePosition.Y, 9121 part.AbsolutePosition.Y,
7859 part.AbsolutePosition.Z); 9122 part.AbsolutePosition.Z);
7860 // For some reason, the part.AbsolutePosition.* values do not change if the
7861 // linkset is rotated; they always reflect the child prim's world position
7862 // as though the linkset is unrotated. This is incompatible behavior with SL's
7863 // implementation, so will break scripts imported from there (not to mention it
7864 // makes it more difficult to determine a child prim's actual inworld position).
7865 if (part.ParentID != 0)
7866 v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
7867 res.Add(v); 9123 res.Add(v);
7868 break; 9124 break;
7869 9125
@@ -8034,56 +9290,92 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8034 case (int)ScriptBaseClass.PRIM_BUMP_SHINY: 9290 case (int)ScriptBaseClass.PRIM_BUMP_SHINY:
8035 if (remain < 1) 9291 if (remain < 1)
8036 return res; 9292 return res;
8037 9293 face = (int)rules.GetLSLIntegerItem(idx++);
8038 face=(int)rules.GetLSLIntegerItem(idx++);
8039 9294
8040 tex = part.Shape.Textures; 9295 tex = part.Shape.Textures;
9296 int shiny;
8041 if (face == ScriptBaseClass.ALL_SIDES) 9297 if (face == ScriptBaseClass.ALL_SIDES)
8042 { 9298 {
8043 for (face = 0; face < GetNumberOfSides(part); face++) 9299 for (face = 0; face < GetNumberOfSides(part); face++)
8044 { 9300 {
8045 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9301 Shininess shinyness = tex.GetFace((uint)face).Shiny;
8046 // Convert Shininess to PRIM_SHINY_* 9302 if (shinyness == Shininess.High)
8047 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9303 {
8048 // PRIM_BUMP_* 9304 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8049 res.Add(new LSL_Integer((int)texface.Bump)); 9305 }
9306 else if (shinyness == Shininess.Medium)
9307 {
9308 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
9309 }
9310 else if (shinyness == Shininess.Low)
9311 {
9312 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9313 }
9314 else
9315 {
9316 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9317 }
9318 res.Add(new LSL_Integer(shiny));
9319 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8050 } 9320 }
8051 } 9321 }
8052 else 9322 else
8053 { 9323 {
8054 if (face >= 0 && face < GetNumberOfSides(part)) 9324 Shininess shinyness = tex.GetFace((uint)face).Shiny;
9325 if (shinyness == Shininess.High)
8055 { 9326 {
8056 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9327 shiny = ScriptBaseClass.PRIM_SHINY_HIGH;
8057 // Convert Shininess to PRIM_SHINY_* 9328 }
8058 res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); 9329 else if (shinyness == Shininess.Medium)
8059 // PRIM_BUMP_* 9330 {
8060 res.Add(new LSL_Integer((int)texface.Bump)); 9331 shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM;
8061 } 9332 }
9333 else if (shinyness == Shininess.Low)
9334 {
9335 shiny = ScriptBaseClass.PRIM_SHINY_LOW;
9336 }
9337 else
9338 {
9339 shiny = ScriptBaseClass.PRIM_SHINY_NONE;
9340 }
9341 res.Add(new LSL_Integer(shiny));
9342 res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump));
8062 } 9343 }
8063 break; 9344 break;
8064 9345
8065 case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 9346 case (int)ScriptBaseClass.PRIM_FULLBRIGHT:
8066 if (remain < 1) 9347 if (remain < 1)
8067 return res; 9348 return res;
8068 9349 face = (int)rules.GetLSLIntegerItem(idx++);
8069 face=(int)rules.GetLSLIntegerItem(idx++);
8070 9350
8071 tex = part.Shape.Textures; 9351 tex = part.Shape.Textures;
9352 int fullbright;
8072 if (face == ScriptBaseClass.ALL_SIDES) 9353 if (face == ScriptBaseClass.ALL_SIDES)
8073 { 9354 {
8074 for (face = 0; face < GetNumberOfSides(part); face++) 9355 for (face = 0; face < GetNumberOfSides(part); face++)
8075 { 9356 {
8076 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9357 if (tex.GetFace((uint)face).Fullbright == true)
8077 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9358 {
9359 fullbright = ScriptBaseClass.TRUE;
9360 }
9361 else
9362 {
9363 fullbright = ScriptBaseClass.FALSE;
9364 }
9365 res.Add(new LSL_Integer(fullbright));
8078 } 9366 }
8079 } 9367 }
8080 else 9368 else
8081 { 9369 {
8082 if (face >= 0 && face < GetNumberOfSides(part)) 9370 if (tex.GetFace((uint)face).Fullbright == true)
8083 { 9371 {
8084 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9372 fullbright = ScriptBaseClass.TRUE;
8085 res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); 9373 }
9374 else
9375 {
9376 fullbright = ScriptBaseClass.FALSE;
8086 } 9377 }
9378 res.Add(new LSL_Integer(fullbright));
8087 } 9379 }
8088 break; 9380 break;
8089 9381
@@ -8105,27 +9397,35 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8105 break; 9397 break;
8106 9398
8107 case (int)ScriptBaseClass.PRIM_TEXGEN: 9399 case (int)ScriptBaseClass.PRIM_TEXGEN:
9400 // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR)
8108 if (remain < 1) 9401 if (remain < 1)
8109 return res; 9402 return res;
8110 9403 face = (int)rules.GetLSLIntegerItem(idx++);
8111 face=(int)rules.GetLSLIntegerItem(idx++);
8112 9404
8113 tex = part.Shape.Textures; 9405 tex = part.Shape.Textures;
8114 if (face == ScriptBaseClass.ALL_SIDES) 9406 if (face == ScriptBaseClass.ALL_SIDES)
8115 { 9407 {
8116 for (face = 0; face < GetNumberOfSides(part); face++) 9408 for (face = 0; face < GetNumberOfSides(part); face++)
8117 { 9409 {
8118 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9410 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8119 // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. 9411 {
8120 res.Add(new LSL_Integer((uint)texgen >> 1)); 9412 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
9413 }
9414 else
9415 {
9416 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
9417 }
8121 } 9418 }
8122 } 9419 }
8123 else 9420 else
8124 { 9421 {
8125 if (face >= 0 && face < GetNumberOfSides(part)) 9422 if (tex.GetFace((uint)face).TexMapType == MappingType.Planar)
8126 { 9423 {
8127 MappingType texgen = tex.GetFace((uint)face).TexMapType; 9424 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR));
8128 res.Add(new LSL_Integer((uint)texgen >> 1)); 9425 }
9426 else
9427 {
9428 res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT));
8129 } 9429 }
8130 } 9430 }
8131 break; 9431 break;
@@ -8148,25 +9448,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8148 case (int)ScriptBaseClass.PRIM_GLOW: 9448 case (int)ScriptBaseClass.PRIM_GLOW:
8149 if (remain < 1) 9449 if (remain < 1)
8150 return res; 9450 return res;
8151 9451 face = (int)rules.GetLSLIntegerItem(idx++);
8152 face=(int)rules.GetLSLIntegerItem(idx++);
8153 9452
8154 tex = part.Shape.Textures; 9453 tex = part.Shape.Textures;
9454 float primglow;
8155 if (face == ScriptBaseClass.ALL_SIDES) 9455 if (face == ScriptBaseClass.ALL_SIDES)
8156 { 9456 {
8157 for (face = 0; face < GetNumberOfSides(part); face++) 9457 for (face = 0; face < GetNumberOfSides(part); face++)
8158 { 9458 {
8159 Primitive.TextureEntryFace texface = tex.GetFace((uint)face); 9459 primglow = tex.GetFace((uint)face).Glow;
8160 res.Add(new LSL_Float(texface.Glow)); 9460 res.Add(new LSL_Float(primglow));
8161 } 9461 }
8162 } 9462 }
8163 else 9463 else
8164 { 9464 {
8165 if (face >= 0 && face < GetNumberOfSides(part)) 9465 primglow = tex.GetFace((uint)face).Glow;
8166 { 9466 res.Add(new LSL_Float(primglow));
8167 Primitive.TextureEntryFace texface = tex.GetFace((uint)face);
8168 res.Add(new LSL_Float(texface.Glow));
8169 }
8170 } 9467 }
8171 break; 9468 break;
8172 9469
@@ -8178,18 +9475,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8178 textColor.B)); 9475 textColor.B));
8179 res.Add(new LSL_Float(textColor.A)); 9476 res.Add(new LSL_Float(textColor.A));
8180 break; 9477 break;
9478
8181 case (int)ScriptBaseClass.PRIM_NAME: 9479 case (int)ScriptBaseClass.PRIM_NAME:
8182 res.Add(new LSL_String(part.Name)); 9480 res.Add(new LSL_String(part.Name));
8183 break; 9481 break;
9482
8184 case (int)ScriptBaseClass.PRIM_DESC: 9483 case (int)ScriptBaseClass.PRIM_DESC:
8185 res.Add(new LSL_String(part.Description)); 9484 res.Add(new LSL_String(part.Description));
8186 break; 9485 break;
9486
8187 case (int)ScriptBaseClass.PRIM_ROT_LOCAL: 9487 case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
8188 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); 9488 res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W));
8189 break; 9489 break;
9490
8190 case (int)ScriptBaseClass.PRIM_POS_LOCAL: 9491 case (int)ScriptBaseClass.PRIM_POS_LOCAL:
8191 res.Add(new LSL_Vector(GetPartLocalPos(part))); 9492 res.Add(new LSL_Vector(GetPartLocalPos(part)));
8192 break; 9493 break;
9494
9495 case (int)ScriptBaseClass.PRIM_LINK_TARGET:
9496 if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless.
9497 return res;
9498 LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++);
9499 LSL_List new_rules = rules.GetSublist(idx, -1);
9500 LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules);
9501 res += tres;
9502 return res;
8193 } 9503 }
8194 } 9504 }
8195 return res; 9505 return res;
@@ -8782,8 +10092,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8782 // The function returns an ordered list 10092 // The function returns an ordered list
8783 // representing the tokens found in the supplied 10093 // representing the tokens found in the supplied
8784 // sources string. If two successive tokenizers 10094 // sources string. If two successive tokenizers
8785 // are encountered, then a NULL entry is added 10095 // are encountered, then a null-string entry is
8786 // to the list. 10096 // added to the list.
8787 // 10097 //
8788 // It is a precondition that the source and 10098 // It is a precondition that the source and
8789 // toekizer lisst are non-null. If they are null, 10099 // toekizer lisst are non-null. If they are null,
@@ -8791,7 +10101,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8791 // while their lengths are being determined. 10101 // while their lengths are being determined.
8792 // 10102 //
8793 // A small amount of working memoryis required 10103 // A small amount of working memoryis required
8794 // of approximately 8*#tokenizers. 10104 // of approximately 8*#tokenizers + 8*srcstrlen.
8795 // 10105 //
8796 // There are many ways in which this function 10106 // There are many ways in which this function
8797 // can be implemented, this implementation is 10107 // can be implemented, this implementation is
@@ -8807,155 +10117,124 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
8807 // and eliminates redundant tokenizers as soon 10117 // and eliminates redundant tokenizers as soon
8808 // as is possible. 10118 // as is possible.
8809 // 10119 //
8810 // The implementation tries to avoid any copying 10120 // The implementation tries to minimize temporary
8811 // of arrays or other objects. 10121 // garbage generation.
8812 // </remarks> 10122 // </remarks>
8813 10123
8814 private LSL_List ParseString(string src, LSL_List separators, LSL_List spacers, bool keepNulls) 10124 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8815 { 10125 {
8816 int beginning = 0; 10126 return ParseString2List(src, separators, spacers, true);
8817 int srclen = src.Length; 10127 }
8818 int seplen = separators.Length;
8819 object[] separray = separators.Data;
8820 int spclen = spacers.Length;
8821 object[] spcarray = spacers.Data;
8822 int mlen = seplen+spclen;
8823
8824 int[] offset = new int[mlen+1];
8825 bool[] active = new bool[mlen];
8826
8827 int best;
8828 int j;
8829
8830 // Initial capacity reduces resize cost
8831 10128
8832 LSL_List tokens = new LSL_List(); 10129 private LSL_List ParseString2List(string src, LSL_List separators, LSL_List spacers, bool keepNulls)
10130 {
10131 int srclen = src.Length;
10132 int seplen = separators.Length;
10133 object[] separray = separators.Data;
10134 int spclen = spacers.Length;
10135 object[] spcarray = spacers.Data;
10136 int dellen = 0;
10137 string[] delarray = new string[seplen+spclen];
8833 10138
8834 // All entries are initially valid 10139 int outlen = 0;
10140 string[] outarray = new string[srclen*2+1];
8835 10141
8836 for (int i = 0; i < mlen; i++) 10142 int i, j;
8837 active[i] = true; 10143 string d;
8838 10144
8839 offset[mlen] = srclen; 10145 m_host.AddScriptLPS(1);
8840 10146
8841 while (beginning < srclen) 10147 /*
10148 * Convert separator and spacer lists to C# strings.
10149 * Also filter out null strings so we don't hang.
10150 */
10151 for (i = 0; i < seplen; i ++)
8842 { 10152 {
10153 d = separray[i].ToString();
10154 if (d.Length > 0)
10155 {
10156 delarray[dellen++] = d;
10157 }
10158 }
10159 seplen = dellen;
8843 10160
8844 best = mlen; // as bad as it gets 10161 for (i = 0; i < spclen; i ++)
10162 {
10163 d = spcarray[i].ToString();
10164 if (d.Length > 0)
10165 {
10166 delarray[dellen++] = d;
10167 }
10168 }
8845 10169
8846 // Scan for separators 10170 /*
10171 * Scan through source string from beginning to end.
10172 */
10173 for (i = 0;;)
10174 {
8847 10175
8848 for (j = 0; j < seplen; j++) 10176 /*
10177 * Find earliest delimeter in src starting at i (if any).
10178 */
10179 int earliestDel = -1;
10180 int earliestSrc = srclen;
10181 string earliestStr = null;
10182 for (j = 0; j < dellen; j ++)
8849 { 10183 {
8850 if (separray[j].ToString() == String.Empty) 10184 d = delarray[j];
8851 active[j] = false; 10185 if (d != null)
8852
8853 if (active[j])
8854 { 10186 {
8855 // scan all of the markers 10187 int index = src.IndexOf(d, i);
8856 if ((offset[j] = src.IndexOf(separray[j].ToString(), beginning)) == -1) 10188 if (index < 0)
8857 { 10189 {
8858 // not present at all 10190 delarray[j] = null; // delim nowhere in src, don't check it anymore
8859 active[j] = false;
8860 } 10191 }
8861 else 10192 else if (index < earliestSrc)
8862 { 10193 {
8863 // present and correct 10194 earliestSrc = index; // where delimeter starts in source string
8864 if (offset[j] < offset[best]) 10195 earliestDel = j; // where delimeter is in delarray[]
8865 { 10196 earliestStr = d; // the delimeter string from delarray[]
8866 // closest so far 10197 if (index == i) break; // can't do any better than found at beg of string
8867 best = j;
8868 if (offset[best] == beginning)
8869 break;
8870 }
8871 } 10198 }
8872 } 10199 }
8873 } 10200 }
8874 10201
8875 // Scan for spacers 10202 /*
8876 10203 * Output source string starting at i through start of earliest delimeter.
8877 if (offset[best] != beginning) 10204 */
10205 if (keepNulls || (earliestSrc > i))
8878 { 10206 {
8879 for (j = seplen; (j < mlen) && (offset[best] > beginning); j++) 10207 outarray[outlen++] = src.Substring(i, earliestSrc - i);
8880 {
8881 if (spcarray[j-seplen].ToString() == String.Empty)
8882 active[j] = false;
8883
8884 if (active[j])
8885 {
8886 // scan all of the markers
8887 if ((offset[j] = src.IndexOf(spcarray[j-seplen].ToString(), beginning)) == -1)
8888 {
8889 // not present at all
8890 active[j] = false;
8891 }
8892 else
8893 {
8894 // present and correct
8895 if (offset[j] < offset[best])
8896 {
8897 // closest so far
8898 best = j;
8899 }
8900 }
8901 }
8902 }
8903 } 10208 }
8904 10209
8905 // This is the normal exit from the scanning loop 10210 /*
10211 * If no delimeter found at or after i, we're done scanning.
10212 */
10213 if (earliestDel < 0) break;
8906 10214
8907 if (best == mlen) 10215 /*
10216 * If delimeter was a spacer, output the spacer.
10217 */
10218 if (earliestDel >= seplen)
8908 { 10219 {
8909 // no markers were found on this pass 10220 outarray[outlen++] = earliestStr;
8910 // so we're pretty much done
8911 if ((keepNulls) || ((!keepNulls) && (srclen - beginning) > 0))
8912 tokens.Add(new LSL_String(src.Substring(beginning, srclen - beginning)));
8913 break;
8914 } 10221 }
8915 10222
8916 // Otherwise we just add the newly delimited token 10223 /*
8917 // and recalculate where the search should continue. 10224 * Look at rest of src string following delimeter.
8918 if ((keepNulls) || ((!keepNulls) && (offset[best] - beginning) > 0)) 10225 */
8919 tokens.Add(new LSL_String(src.Substring(beginning,offset[best]-beginning))); 10226 i = earliestSrc + earliestStr.Length;
8920
8921 if (best < seplen)
8922 {
8923 beginning = offset[best] + (separray[best].ToString()).Length;
8924 }
8925 else
8926 {
8927 beginning = offset[best] + (spcarray[best - seplen].ToString()).Length;
8928 string str = spcarray[best - seplen].ToString();
8929 if ((keepNulls) || ((!keepNulls) && (str.Length > 0)))
8930 tokens.Add(new LSL_String(str));
8931 }
8932 } 10227 }
8933 10228
8934 // This an awkward an not very intuitive boundary case. If the 10229 /*
8935 // last substring is a tokenizer, then there is an implied trailing 10230 * Make up an exact-sized output array suitable for an LSL_List object.
8936 // null list entry. Hopefully the single comparison will not be too 10231 */
8937 // arduous. Alternatively the 'break' could be replced with a return 10232 object[] outlist = new object[outlen];
8938 // but that's shabby programming. 10233 for (i = 0; i < outlen; i ++)
8939
8940 if ((beginning == srclen) && (keepNulls))
8941 { 10234 {
8942 if (srclen != 0) 10235 outlist[i] = new LSL_String(outarray[i]);
8943 tokens.Add(new LSL_String(""));
8944 } 10236 }
8945 10237 return new LSL_List(outlist);
8946 return tokens;
8947 }
8948
8949 public LSL_List llParseString2List(string src, LSL_List separators, LSL_List spacers)
8950 {
8951 m_host.AddScriptLPS(1);
8952 return this.ParseString(src, separators, spacers, false);
8953 }
8954
8955 public LSL_List llParseStringKeepNulls(string src, LSL_List separators, LSL_List spacers)
8956 {
8957 m_host.AddScriptLPS(1);
8958 return this.ParseString(src, separators, spacers, true);
8959 } 10238 }
8960 10239
8961 public LSL_Integer llGetObjectPermMask(int mask) 10240 public LSL_Integer llGetObjectPermMask(int mask)
@@ -9050,6 +10329,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9050 case 4: 10329 case 4:
9051 return (int)item.NextPermissions; 10330 return (int)item.NextPermissions;
9052 } 10331 }
10332 m_host.TaskInventory.LockItemsForRead(false);
9053 10333
9054 return -1; 10334 return -1;
9055 } 10335 }
@@ -9240,9 +10520,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9240 { 10520 {
9241 try 10521 try
9242 { 10522 {
10523 /*
9243 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId); 10524 SceneObjectPart obj = World.GetSceneObjectPart(World.Entities[key].LocalId);
9244 if (obj != null) 10525 if (obj != null)
9245 return (double)obj.GetMass(); 10526 return (double)obj.GetMass();
10527 */
10528 // return total object mass
10529 SceneObjectGroup obj = World.GetGroupByPrim(World.Entities[key].LocalId);
10530 if (obj != null)
10531 return obj.GetMass();
10532
9246 // the object is null so the key is for an avatar 10533 // the object is null so the key is for an avatar
9247 ScenePresence avatar = World.GetScenePresence(key); 10534 ScenePresence avatar = World.GetScenePresence(key);
9248 if (avatar != null) 10535 if (avatar != null)
@@ -9262,7 +10549,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9262 } 10549 }
9263 10550
9264 /// <summary> 10551 /// <summary>
9265 /// illListReplaceList removes the sub-list defined by the inclusive indices 10552 /// llListReplaceList removes the sub-list defined by the inclusive indices
9266 /// start and end and inserts the src list in its place. The inclusive 10553 /// start and end and inserts the src list in its place. The inclusive
9267 /// nature of the indices means that at least one element must be deleted 10554 /// nature of the indices means that at least one element must be deleted
9268 /// if the indices are within the bounds of the existing list. I.e. 2,2 10555 /// if the indices are within the bounds of the existing list. I.e. 2,2
@@ -9319,16 +10606,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9319 // based upon end. Note that if end exceeds the upper 10606 // based upon end. Note that if end exceeds the upper
9320 // bound in this case, the entire destination list 10607 // bound in this case, the entire destination list
9321 // is removed. 10608 // is removed.
9322 else 10609 else if (start == 0)
9323 { 10610 {
9324 if (end + 1 < dest.Length) 10611 if (end + 1 < dest.Length)
9325 {
9326 return src + dest.GetSublist(end + 1, -1); 10612 return src + dest.GetSublist(end + 1, -1);
9327 }
9328 else 10613 else
9329 {
9330 return src; 10614 return src;
9331 } 10615 }
10616 else // Start < 0
10617 {
10618 if (end + 1 < dest.Length)
10619 return dest.GetSublist(end + 1, -1);
10620 else
10621 return new LSL_List();
9332 } 10622 }
9333 } 10623 }
9334 // Finally, if start > end, we strip away a prefix and 10624 // Finally, if start > end, we strip away a prefix and
@@ -9379,17 +10669,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9379 int width = 0; 10669 int width = 0;
9380 int height = 0; 10670 int height = 0;
9381 10671
9382 ParcelMediaCommandEnum? commandToSend = null; 10672 uint commandToSend = 0;
9383 float time = 0.0f; // default is from start 10673 float time = 0.0f; // default is from start
9384 10674
9385 ScenePresence presence = null; 10675 ScenePresence presence = null;
9386 10676
9387 for (int i = 0; i < commandList.Data.Length; i++) 10677 for (int i = 0; i < commandList.Data.Length; i++)
9388 { 10678 {
9389 ParcelMediaCommandEnum command = (ParcelMediaCommandEnum)commandList.Data[i]; 10679 uint command = (uint)(commandList.GetLSLIntegerItem(i));
9390 switch (command) 10680 switch (command)
9391 { 10681 {
9392 case ParcelMediaCommandEnum.Agent: 10682 case (uint)ParcelMediaCommandEnum.Agent:
9393 // we send only to one agent 10683 // we send only to one agent
9394 if ((i + 1) < commandList.Length) 10684 if ((i + 1) < commandList.Length)
9395 { 10685 {
@@ -9406,25 +10696,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9406 } 10696 }
9407 break; 10697 break;
9408 10698
9409 case ParcelMediaCommandEnum.Loop: 10699 case (uint)ParcelMediaCommandEnum.Loop:
9410 loop = 1; 10700 loop = 1;
9411 commandToSend = command; 10701 commandToSend = command;
9412 update = true; //need to send the media update packet to set looping 10702 update = true; //need to send the media update packet to set looping
9413 break; 10703 break;
9414 10704
9415 case ParcelMediaCommandEnum.Play: 10705 case (uint)ParcelMediaCommandEnum.Play:
9416 loop = 0; 10706 loop = 0;
9417 commandToSend = command; 10707 commandToSend = command;
9418 update = true; //need to send the media update packet to make sure it doesn't loop 10708 update = true; //need to send the media update packet to make sure it doesn't loop
9419 break; 10709 break;
9420 10710
9421 case ParcelMediaCommandEnum.Pause: 10711 case (uint)ParcelMediaCommandEnum.Pause:
9422 case ParcelMediaCommandEnum.Stop: 10712 case (uint)ParcelMediaCommandEnum.Stop:
9423 case ParcelMediaCommandEnum.Unload: 10713 case (uint)ParcelMediaCommandEnum.Unload:
9424 commandToSend = command; 10714 commandToSend = command;
9425 break; 10715 break;
9426 10716
9427 case ParcelMediaCommandEnum.Url: 10717 case (uint)ParcelMediaCommandEnum.Url:
9428 if ((i + 1) < commandList.Length) 10718 if ((i + 1) < commandList.Length)
9429 { 10719 {
9430 if (commandList.Data[i + 1] is LSL_String) 10720 if (commandList.Data[i + 1] is LSL_String)
@@ -9437,7 +10727,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9437 } 10727 }
9438 break; 10728 break;
9439 10729
9440 case ParcelMediaCommandEnum.Texture: 10730 case (uint)ParcelMediaCommandEnum.Texture:
9441 if ((i + 1) < commandList.Length) 10731 if ((i + 1) < commandList.Length)
9442 { 10732 {
9443 if (commandList.Data[i + 1] is LSL_String) 10733 if (commandList.Data[i + 1] is LSL_String)
@@ -9450,7 +10740,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9450 } 10740 }
9451 break; 10741 break;
9452 10742
9453 case ParcelMediaCommandEnum.Time: 10743 case (uint)ParcelMediaCommandEnum.Time:
9454 if ((i + 1) < commandList.Length) 10744 if ((i + 1) < commandList.Length)
9455 { 10745 {
9456 if (commandList.Data[i + 1] is LSL_Float) 10746 if (commandList.Data[i + 1] is LSL_Float)
@@ -9462,7 +10752,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9462 } 10752 }
9463 break; 10753 break;
9464 10754
9465 case ParcelMediaCommandEnum.AutoAlign: 10755 case (uint)ParcelMediaCommandEnum.AutoAlign:
9466 if ((i + 1) < commandList.Length) 10756 if ((i + 1) < commandList.Length)
9467 { 10757 {
9468 if (commandList.Data[i + 1] is LSL_Integer) 10758 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9476,7 +10766,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9476 } 10766 }
9477 break; 10767 break;
9478 10768
9479 case ParcelMediaCommandEnum.Type: 10769 case (uint)ParcelMediaCommandEnum.Type:
9480 if ((i + 1) < commandList.Length) 10770 if ((i + 1) < commandList.Length)
9481 { 10771 {
9482 if (commandList.Data[i + 1] is LSL_String) 10772 if (commandList.Data[i + 1] is LSL_String)
@@ -9489,7 +10779,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9489 } 10779 }
9490 break; 10780 break;
9491 10781
9492 case ParcelMediaCommandEnum.Desc: 10782 case (uint)ParcelMediaCommandEnum.Desc:
9493 if ((i + 1) < commandList.Length) 10783 if ((i + 1) < commandList.Length)
9494 { 10784 {
9495 if (commandList.Data[i + 1] is LSL_String) 10785 if (commandList.Data[i + 1] is LSL_String)
@@ -9502,7 +10792,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9502 } 10792 }
9503 break; 10793 break;
9504 10794
9505 case ParcelMediaCommandEnum.Size: 10795 case (uint)ParcelMediaCommandEnum.Size:
9506 if ((i + 2) < commandList.Length) 10796 if ((i + 2) < commandList.Length)
9507 { 10797 {
9508 if (commandList.Data[i + 1] is LSL_Integer) 10798 if (commandList.Data[i + 1] is LSL_Integer)
@@ -9572,7 +10862,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9572 } 10862 }
9573 } 10863 }
9574 10864
9575 if (commandToSend != null) 10865 if (commandToSend != 0)
9576 { 10866 {
9577 // the commandList contained a start/stop/... command, too 10867 // the commandList contained a start/stop/... command, too
9578 if (presence == null) 10868 if (presence == null)
@@ -9609,7 +10899,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9609 10899
9610 if (aList.Data[i] != null) 10900 if (aList.Data[i] != null)
9611 { 10901 {
9612 switch ((ParcelMediaCommandEnum) aList.Data[i]) 10902 switch ((ParcelMediaCommandEnum) Convert.ToInt32(aList.Data[i].ToString()))
9613 { 10903 {
9614 case ParcelMediaCommandEnum.Url: 10904 case ParcelMediaCommandEnum.Url:
9615 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL)); 10905 list.Add(new LSL_String(World.GetLandData(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y).MediaURL));
@@ -9666,15 +10956,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9666 10956
9667 if (quick_pay_buttons.Data.Length < 4) 10957 if (quick_pay_buttons.Data.Length < 4)
9668 { 10958 {
9669 LSLError("List must have at least 4 elements"); 10959 int x;
9670 return; 10960 for (x=quick_pay_buttons.Data.Length; x<= 4; x++)
10961 {
10962 quick_pay_buttons.Add(ScriptBaseClass.PAY_HIDE);
10963 }
9671 } 10964 }
9672 m_host.ParentGroup.RootPart.PayPrice[0]=price; 10965 int[] nPrice = new int[5];
9673 10966 nPrice[0] = price;
9674 m_host.ParentGroup.RootPart.PayPrice[1]=(LSL_Integer)quick_pay_buttons.Data[0]; 10967 nPrice[1] = quick_pay_buttons.GetLSLIntegerItem(0);
9675 m_host.ParentGroup.RootPart.PayPrice[2]=(LSL_Integer)quick_pay_buttons.Data[1]; 10968 nPrice[2] = quick_pay_buttons.GetLSLIntegerItem(1);
9676 m_host.ParentGroup.RootPart.PayPrice[3]=(LSL_Integer)quick_pay_buttons.Data[2]; 10969 nPrice[3] = quick_pay_buttons.GetLSLIntegerItem(2);
9677 m_host.ParentGroup.RootPart.PayPrice[4]=(LSL_Integer)quick_pay_buttons.Data[3]; 10970 nPrice[4] = quick_pay_buttons.GetLSLIntegerItem(3);
10971 m_host.ParentGroup.RootPart.PayPrice = nPrice;
9678 m_host.ParentGroup.HasGroupChanged = true; 10972 m_host.ParentGroup.HasGroupChanged = true;
9679 } 10973 }
9680 10974
@@ -9691,7 +10985,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9691 return new LSL_Vector(); 10985 return new LSL_Vector();
9692 } 10986 }
9693 10987
9694 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 10988// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
10989 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9695 if (presence != null) 10990 if (presence != null)
9696 { 10991 {
9697 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z); 10992 LSL_Vector pos = new LSL_Vector(presence.CameraPosition.X, presence.CameraPosition.Y, presence.CameraPosition.Z);
@@ -9713,7 +11008,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9713 return new LSL_Rotation(); 11008 return new LSL_Rotation();
9714 } 11009 }
9715 11010
9716 ScenePresence presence = World.GetScenePresence(m_host.OwnerID); 11011// ScenePresence presence = World.GetScenePresence(m_host.OwnerID);
11012 ScenePresence presence = World.GetScenePresence(m_item.PermsGranter);
9717 if (presence != null) 11013 if (presence != null)
9718 { 11014 {
9719 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W); 11015 return new LSL_Rotation(presence.CameraRotation.X, presence.CameraRotation.Y, presence.CameraRotation.Z, presence.CameraRotation.W);
@@ -9773,8 +11069,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9773 { 11069 {
9774 m_host.AddScriptLPS(1); 11070 m_host.AddScriptLPS(1);
9775 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0); 11071 DetectParams detectedParams = m_ScriptEngine.GetDetectParams(m_item.ItemID, 0);
9776 if (detectedParams == null) return; // only works on the first detected avatar 11072 if (detectedParams == null)
9777 11073 {
11074 if (m_host.ParentGroup.IsAttachment == true)
11075 {
11076 detectedParams = new DetectParams();
11077 detectedParams.Key = m_host.OwnerID;
11078 }
11079 else
11080 {
11081 return;
11082 }
11083 }
11084
9778 ScenePresence avatar = World.GetScenePresence(detectedParams.Key); 11085 ScenePresence avatar = World.GetScenePresence(detectedParams.Key);
9779 if (avatar != null) 11086 if (avatar != null)
9780 { 11087 {
@@ -9782,6 +11089,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9782 new Vector3((float)pos.x, (float)pos.y, (float)pos.z), 11089 new Vector3((float)pos.x, (float)pos.y, (float)pos.z),
9783 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z)); 11090 new Vector3((float)lookAt.x, (float)lookAt.y, (float)lookAt.z));
9784 } 11091 }
11092
9785 ScriptSleep(1000); 11093 ScriptSleep(1000);
9786 } 11094 }
9787 11095
@@ -9905,12 +11213,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
9905 11213
9906 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>(); 11214 SortedDictionary<int, float> parameters = new SortedDictionary<int, float>();
9907 object[] data = rules.Data; 11215 object[] data = rules.Data;
9908 for (int i = 0; i < data.Length; ++i) { 11216 for (int i = 0; i < data.Length; ++i)
11217 {
9909 int type = Convert.ToInt32(data[i++].ToString()); 11218 int type = Convert.ToInt32(data[i++].ToString());
9910 if (i >= data.Length) break; // odd number of entries => ignore the last 11219 if (i >= data.Length) break; // odd number of entries => ignore the last
9911 11220
9912 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3) 11221 // some special cases: Vector parameters are split into 3 float parameters (with type+1, type+2, type+3)
9913 switch (type) { 11222 switch (type)
11223 {
9914 case ScriptBaseClass.CAMERA_FOCUS: 11224 case ScriptBaseClass.CAMERA_FOCUS:
9915 case ScriptBaseClass.CAMERA_FOCUS_OFFSET: 11225 case ScriptBaseClass.CAMERA_FOCUS_OFFSET:
9916 case ScriptBaseClass.CAMERA_POSITION: 11226 case ScriptBaseClass.CAMERA_POSITION:
@@ -10016,19 +11326,65 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10016 public LSL_String llXorBase64StringsCorrect(string str1, string str2) 11326 public LSL_String llXorBase64StringsCorrect(string str1, string str2)
10017 { 11327 {
10018 m_host.AddScriptLPS(1); 11328 m_host.AddScriptLPS(1);
10019 string ret = String.Empty; 11329
10020 string src1 = llBase64ToString(str1); 11330 if (str1 == String.Empty)
10021 string src2 = llBase64ToString(str2); 11331 return String.Empty;
10022 int c = 0; 11332 if (str2 == String.Empty)
10023 for (int i = 0; i < src1.Length; i++) 11333 return str1;
11334
11335 int len = str2.Length;
11336 if ((len % 4) != 0) // LL is EVIL!!!!
10024 { 11337 {
10025 ret += (char) (src1[i] ^ src2[c]); 11338 while (str2.EndsWith("="))
11339 str2 = str2.Substring(0, str2.Length - 1);
11340
11341 len = str2.Length;
11342 int mod = len % 4;
11343
11344 if (mod == 1)
11345 str2 = str2.Substring(0, str2.Length - 1);
11346 else if (mod == 2)
11347 str2 += "==";
11348 else if (mod == 3)
11349 str2 += "=";
11350 }
10026 11351
10027 c++; 11352 byte[] data1;
10028 if (c >= src2.Length) 11353 byte[] data2;
10029 c = 0; 11354 try
11355 {
11356 data1 = Convert.FromBase64String(str1);
11357 data2 = Convert.FromBase64String(str2);
10030 } 11358 }
10031 return llStringToBase64(ret); 11359 catch (Exception)
11360 {
11361 return new LSL_String(String.Empty);
11362 }
11363
11364 byte[] d2 = new Byte[data1.Length];
11365 int pos = 0;
11366
11367 if (data1.Length <= data2.Length)
11368 {
11369 Array.Copy(data2, 0, d2, 0, data1.Length);
11370 }
11371 else
11372 {
11373 while (pos < data1.Length)
11374 {
11375 len = data1.Length - pos;
11376 if (len > data2.Length)
11377 len = data2.Length;
11378
11379 Array.Copy(data2, 0, d2, pos, len);
11380 pos += len;
11381 }
11382 }
11383
11384 for (pos = 0 ; pos < data1.Length ; pos++ )
11385 data1[pos] ^= d2[pos];
11386
11387 return Convert.ToBase64String(data1);
10032 } 11388 }
10033 11389
10034 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body) 11390 public LSL_String llHTTPRequest(string url, LSL_List parameters, string body)
@@ -10085,12 +11441,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10085 Regex r = new Regex(authregex); 11441 Regex r = new Regex(authregex);
10086 int[] gnums = r.GetGroupNumbers(); 11442 int[] gnums = r.GetGroupNumbers();
10087 Match m = r.Match(url); 11443 Match m = r.Match(url);
10088 if (m.Success) { 11444 if (m.Success)
10089 for (int i = 1; i < gnums.Length; i++) { 11445 {
11446 for (int i = 1; i < gnums.Length; i++)
11447 {
10090 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]]; 11448 //System.Text.RegularExpressions.Group g = m.Groups[gnums[i]];
10091 //CaptureCollection cc = g.Captures; 11449 //CaptureCollection cc = g.Captures;
10092 } 11450 }
10093 if (m.Groups.Count == 5) { 11451 if (m.Groups.Count == 5)
11452 {
10094 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString()))); 11453 httpHeaders["Authorization"] = String.Format("Basic {0}", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(m.Groups[2].ToString() + ":" + m.Groups[3].ToString())));
10095 url = m.Groups[1].ToString() + m.Groups[4].ToString(); 11454 url = m.Groups[1].ToString() + m.Groups[4].ToString();
10096 } 11455 }
@@ -10293,6 +11652,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10293 11652
10294 LSL_List ret = new LSL_List(); 11653 LSL_List ret = new LSL_List();
10295 UUID key = new UUID(); 11654 UUID key = new UUID();
11655
11656
10296 if (UUID.TryParse(id, out key)) 11657 if (UUID.TryParse(id, out key))
10297 { 11658 {
10298 ScenePresence av = World.GetScenePresence(key); 11659 ScenePresence av = World.GetScenePresence(key);
@@ -10310,13 +11671,33 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10310 ret.Add(new LSL_String("")); 11671 ret.Add(new LSL_String(""));
10311 break; 11672 break;
10312 case ScriptBaseClass.OBJECT_POS: 11673 case ScriptBaseClass.OBJECT_POS:
10313 ret.Add(new LSL_Vector((double)av.AbsolutePosition.X, (double)av.AbsolutePosition.Y, (double)av.AbsolutePosition.Z)); 11674 Vector3 avpos;
11675
11676 if (av.ParentID != 0 && av.ParentPart != null)
11677 {
11678 avpos = av.OffsetPosition;
11679
11680 Vector3 sitOffset = (Zrot(av.Rotation)) * (av.Appearance.AvatarHeight * 0.02638f *2.0f);
11681 avpos -= sitOffset;
11682
11683 avpos = av.ParentPart.GetWorldPosition() + avpos * av.ParentPart.GetWorldRotation();
11684 }
11685 else
11686 avpos = av.AbsolutePosition;
11687
11688 ret.Add(new LSL_Vector((double)avpos.X, (double)avpos.Y, (double)avpos.Z));
10314 break; 11689 break;
10315 case ScriptBaseClass.OBJECT_ROT: 11690 case ScriptBaseClass.OBJECT_ROT:
10316 ret.Add(new LSL_Rotation((double)av.Rotation.X, (double)av.Rotation.Y, (double)av.Rotation.Z, (double)av.Rotation.W)); 11691 Quaternion avrot = av.Rotation;
11692 if (av.ParentID != 0 && av.ParentPart != null)
11693 {
11694 avrot = av.ParentPart.GetWorldRotation() * avrot;
11695 }
11696 ret.Add(new LSL_Rotation((double)avrot.X, (double)avrot.Y, (double)avrot.Z, (double)avrot.W));
10317 break; 11697 break;
10318 case ScriptBaseClass.OBJECT_VELOCITY: 11698 case ScriptBaseClass.OBJECT_VELOCITY:
10319 ret.Add(new LSL_Vector(av.Velocity.X, av.Velocity.Y, av.Velocity.Z)); 11699 Vector3 avvel = av.Velocity;
11700 ret.Add(new LSL_Vector((double)avvel.X, (double)avvel.Y, (double)avvel.Z));
10320 break; 11701 break;
10321 case ScriptBaseClass.OBJECT_OWNER: 11702 case ScriptBaseClass.OBJECT_OWNER:
10322 ret.Add(new LSL_String(id)); 11703 ret.Add(new LSL_String(id));
@@ -10372,17 +11753,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10372 case ScriptBaseClass.OBJECT_NAME: 11753 case ScriptBaseClass.OBJECT_NAME:
10373 ret.Add(new LSL_String(obj.Name)); 11754 ret.Add(new LSL_String(obj.Name));
10374 break; 11755 break;
10375 case ScriptBaseClass.OBJECT_DESC: 11756 case ScriptBaseClass.OBJECT_DESC:
10376 ret.Add(new LSL_String(obj.Description)); 11757 ret.Add(new LSL_String(obj.Description));
10377 break; 11758 break;
10378 case ScriptBaseClass.OBJECT_POS: 11759 case ScriptBaseClass.OBJECT_POS:
10379 ret.Add(new LSL_Vector(obj.AbsolutePosition.X, obj.AbsolutePosition.Y, obj.AbsolutePosition.Z)); 11760 Vector3 opos = obj.AbsolutePosition;
11761 ret.Add(new LSL_Vector(opos.X, opos.Y, opos.Z));
10380 break; 11762 break;
10381 case ScriptBaseClass.OBJECT_ROT: 11763 case ScriptBaseClass.OBJECT_ROT:
10382 ret.Add(new LSL_Rotation(obj.RotationOffset.X, obj.RotationOffset.Y, obj.RotationOffset.Z, obj.RotationOffset.W)); 11764// Quaternion orot = obj.RotationOffset;
11765// ret.Add(new LSL_Rotation(orot.X, orot.Y, orot.Z, orot.W));
11766
11767 LSL_Rotation objrot = GetPartRot(obj);
11768 ret.Add(objrot);
10383 break; 11769 break;
10384 case ScriptBaseClass.OBJECT_VELOCITY: 11770 case ScriptBaseClass.OBJECT_VELOCITY:
10385 ret.Add(new LSL_Vector(obj.Velocity.X, obj.Velocity.Y, obj.Velocity.Z)); 11771 Vector3 ovel = obj.Velocity;
11772 ret.Add(new LSL_Vector(ovel.X, ovel.Y, ovel.Z));
10386 break; 11773 break;
10387 case ScriptBaseClass.OBJECT_OWNER: 11774 case ScriptBaseClass.OBJECT_OWNER:
10388 ret.Add(new LSL_String(obj.OwnerID.ToString())); 11775 ret.Add(new LSL_String(obj.OwnerID.ToString()));
@@ -10416,9 +11803,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10416 // The value returned in SL for normal prims is prim count 11803 // The value returned in SL for normal prims is prim count
10417 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount)); 11804 ret.Add(new LSL_Integer(obj.ParentGroup.PrimCount));
10418 break; 11805 break;
10419 // The following 3 costs I have intentionaly coded to return zero. They are part of 11806
10420 // "Land Impact" calculations. These calculations are probably not applicable 11807 // costs below may need to be diferent for root parts, need to check
10421 // to OpenSim and are not yet complete in SL
10422 case ScriptBaseClass.OBJECT_SERVER_COST: 11808 case ScriptBaseClass.OBJECT_SERVER_COST:
10423 // The linden calculation is here 11809 // The linden calculation is here
10424 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight 11810 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Server_Weight
@@ -10426,16 +11812,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10426 ret.Add(new LSL_Float(0)); 11812 ret.Add(new LSL_Float(0));
10427 break; 11813 break;
10428 case ScriptBaseClass.OBJECT_STREAMING_COST: 11814 case ScriptBaseClass.OBJECT_STREAMING_COST:
10429 // The linden calculation is here 11815 // The value returned in SL for normal prims is prim count * 0.06
10430 // http://wiki.secondlife.com/wiki/Mesh/Mesh_Streaming_Cost 11816 ret.Add(new LSL_Float(obj.StreamingCost));
10431 // The value returned in SL for normal prims looks like the prim count * 0.06
10432 ret.Add(new LSL_Float(0));
10433 break; 11817 break;
10434 case ScriptBaseClass.OBJECT_PHYSICS_COST: 11818 case ScriptBaseClass.OBJECT_PHYSICS_COST:
10435 // The linden calculation is here 11819 // The value returned in SL for normal prims is prim count
10436 // http://wiki.secondlife.com/wiki/Mesh/Mesh_physics 11820 ret.Add(new LSL_Float(obj.PhysicsCost));
10437 // The value returned in SL for normal prims looks like the prim count
10438 ret.Add(new LSL_Float(0));
10439 break; 11821 break;
10440 default: 11822 default:
10441 // Invalid or unhandled constant. 11823 // Invalid or unhandled constant.
@@ -10624,15 +12006,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10624 return GetLinkPrimitiveParams(obj, rules); 12006 return GetLinkPrimitiveParams(obj, rules);
10625 } 12007 }
10626 12008
10627 public void print(string str) 12009 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
10628 { 12010 {
10629 // yes, this is a real LSL function. See: http://wiki.secondlife.com/wiki/Print 12011 List<SceneObjectPart> parts = GetLinkParts(link);
10630 IOSSL_Api ossl = (IOSSL_Api)m_ScriptEngine.GetApi(m_item.ItemID, "OSSL"); 12012 if (parts.Count < 1)
10631 if (ossl != null) 12013 return 0;
10632 { 12014
10633 ossl.CheckThreatLevel(ThreatLevel.High, "print"); 12015 return GetNumberOfSides(parts[0]);
10634 m_log.Info("LSL print():" + str);
10635 }
10636 } 12016 }
10637 12017
10638 private string Name2Username(string name) 12018 private string Name2Username(string name)
@@ -10677,7 +12057,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10677 12057
10678 return rq.ToString(); 12058 return rq.ToString();
10679 } 12059 }
10680 12060/*
12061 private void SayShoutTimerElapsed(Object sender, ElapsedEventArgs args)
12062 {
12063 m_SayShoutCount = 0;
12064 }
12065*/
10681 private struct Tri 12066 private struct Tri
10682 { 12067 {
10683 public Vector3 p1; 12068 public Vector3 p1;
@@ -10817,9 +12202,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10817 12202
10818 ContactResult result = new ContactResult (); 12203 ContactResult result = new ContactResult ();
10819 result.ConsumerID = group.LocalId; 12204 result.ConsumerID = group.LocalId;
10820 result.Depth = intersection.distance; 12205// result.Depth = intersection.distance;
10821 result.Normal = intersection.normal; 12206 result.Normal = intersection.normal;
10822 result.Pos = intersection.ipoint; 12207 result.Pos = intersection.ipoint;
12208 result.Depth = Vector3.Mag(rayStart - result.Pos);
10823 12209
10824 contacts.Add(result); 12210 contacts.Add(result);
10825 }); 12211 });
@@ -10952,6 +12338,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10952 12338
10953 return contacts[0]; 12339 return contacts[0];
10954 } 12340 }
12341/*
12342 // not done:
12343 private ContactResult[] testRay2NonPhysicalPhantom(Vector3 rayStart, Vector3 raydir, float raylenght)
12344 {
12345 ContactResult[] contacts = null;
12346 World.ForEachSOG(delegate(SceneObjectGroup group)
12347 {
12348 if (m_host.ParentGroup == group)
12349 return;
12350
12351 if (group.IsAttachment)
12352 return;
12353
12354 if(group.RootPart.PhysActor != null)
12355 return;
12356
12357 contacts = group.RayCastGroupPartsOBBNonPhysicalPhantom(rayStart, raydir, raylenght);
12358 });
12359 return contacts;
12360 }
12361*/
10955 12362
10956 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options) 12363 public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
10957 { 12364 {
@@ -10993,32 +12400,96 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10993 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL); 12400 bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);
10994 12401
10995 12402
10996 if (checkTerrain) 12403 if (World.SuportsRayCastFiltered())
10997 { 12404 {
10998 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd); 12405 if (dist == 0)
10999 if (groundContact != null) 12406 return list;
11000 results.Add((ContactResult)groundContact);
11001 }
11002 12407
11003 if (checkAgents) 12408 RayFilterFlags rayfilter = RayFilterFlags.ClosestAndBackCull;
11004 { 12409 if (checkTerrain)
11005 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd); 12410 rayfilter |= RayFilterFlags.land;
11006 foreach (ContactResult r in agentHits) 12411// if (checkAgents)
11007 results.Add(r); 12412// rayfilter |= RayFilterFlags.agent;
11008 } 12413 if (checkPhysical)
12414 rayfilter |= RayFilterFlags.physical;
12415 if (checkNonPhysical)
12416 rayfilter |= RayFilterFlags.nonphysical;
12417 if (detectPhantom)
12418 rayfilter |= RayFilterFlags.LSLPhanton;
12419
12420 Vector3 direction = dir * ( 1/dist);
12421
12422 if(rayfilter == 0)
12423 {
12424 list.Add(new LSL_Integer(0));
12425 return list;
12426 }
12427
12428 // get some more contacts to sort ???
12429 int physcount = 4 * count;
12430 if (physcount > 20)
12431 physcount = 20;
12432
12433 object physresults;
12434 physresults = World.RayCastFiltered(rayStart, direction, dist, physcount, rayfilter);
11009 12435
11010 if (checkPhysical || checkNonPhysical || detectPhantom) 12436 if (physresults == null)
12437 {
12438 list.Add(new LSL_Integer(-3)); // timeout error
12439 return list;
12440 }
12441
12442 results = (List<ContactResult>)physresults;
12443
12444 // for now physics doesn't detect sitted avatars so do it outside physics
12445 if (checkAgents)
12446 {
12447 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12448 foreach (ContactResult r in agentHits)
12449 results.Add(r);
12450 }
12451
12452 // TODO: Replace this with a better solution. ObjectIntersection can only
12453 // detect nonphysical phantoms. They are detected by virtue of being
12454 // nonphysical (e.g. no PhysActor) so will not conflict with detecting
12455 // physicsl phantoms as done by the physics scene
12456 // We don't want anything else but phantoms here.
12457 if (detectPhantom)
12458 {
12459 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, false, false, true);
12460 foreach (ContactResult r in objectHits)
12461 results.Add(r);
12462 }
12463 }
12464 else
11011 { 12465 {
11012 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom); 12466 if (checkTerrain)
11013 foreach (ContactResult r in objectHits) 12467 {
11014 results.Add(r); 12468 ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
12469 if (groundContact != null)
12470 results.Add((ContactResult)groundContact);
12471 }
12472
12473 if (checkAgents)
12474 {
12475 ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
12476 foreach (ContactResult r in agentHits)
12477 results.Add(r);
12478 }
12479
12480 if (checkPhysical || checkNonPhysical || detectPhantom)
12481 {
12482 ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom);
12483 foreach (ContactResult r in objectHits)
12484 results.Add(r);
12485 }
11015 } 12486 }
11016 12487
11017 results.Sort(delegate(ContactResult a, ContactResult b) 12488 results.Sort(delegate(ContactResult a, ContactResult b)
11018 { 12489 {
11019 return a.Depth.CompareTo(b.Depth); 12490 return a.Depth.CompareTo(b.Depth);
11020 }); 12491 });
11021 12492
11022 int values = 0; 12493 int values = 0;
11023 SceneObjectGroup thisgrp = m_host.ParentGroup; 12494 SceneObjectGroup thisgrp = m_host.ParentGroup;
11024 12495
@@ -11111,7 +12582,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11111 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD: 12582 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
11112 if (!isAccount) return 0; 12583 if (!isAccount) return 0;
11113 if (estate.HasAccess(id)) return 1; 12584 if (estate.HasAccess(id)) return 1;
11114 if (estate.IsBanned(id)) 12585 if (estate.IsBanned(id, World.GetUserFlags(id)))
11115 estate.RemoveBan(id); 12586 estate.RemoveBan(id);
11116 estate.AddEstateUser(id); 12587 estate.AddEstateUser(id);
11117 break; 12588 break;
@@ -11130,14 +12601,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11130 break; 12601 break;
11131 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD: 12602 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
11132 if (!isAccount) return 0; 12603 if (!isAccount) return 0;
11133 if (estate.IsBanned(id)) return 1; 12604 if (estate.IsBanned(id, World.GetUserFlags(id))) return 1;
11134 EstateBan ban = new EstateBan(); 12605 EstateBan ban = new EstateBan();
11135 ban.EstateID = estate.EstateID; 12606 ban.EstateID = estate.EstateID;
11136 ban.BannedUserID = id; 12607 ban.BannedUserID = id;
11137 estate.AddBan(ban); 12608 estate.AddBan(ban);
11138 break; 12609 break;
11139 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE: 12610 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
11140 if (!isAccount || !estate.IsBanned(id)) return 0; 12611 if (!isAccount || !estate.IsBanned(id, World.GetUserFlags(id))) return 0;
11141 estate.RemoveBan(id); 12612 estate.RemoveBan(id);
11142 break; 12613 break;
11143 default: return 0; 12614 default: return 0;
@@ -11166,7 +12637,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11166 return 16384; 12637 return 16384;
11167 } 12638 }
11168 12639
11169 public LSL_Integer llGetUsedMemory() 12640 public virtual LSL_Integer llGetUsedMemory()
11170 { 12641 {
11171 m_host.AddScriptLPS(1); 12642 m_host.AddScriptLPS(1);
11172 // The value returned for LSO scripts in SL 12643 // The value returned for LSO scripts in SL
@@ -11194,7 +12665,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11194 public void llSetSoundQueueing(int queue) 12665 public void llSetSoundQueueing(int queue)
11195 { 12666 {
11196 m_host.AddScriptLPS(1); 12667 m_host.AddScriptLPS(1);
11197 NotImplemented("llSetSoundQueueing");
11198 } 12668 }
11199 12669
11200 public void llCollisionSprite(string impact_sprite) 12670 public void llCollisionSprite(string impact_sprite)
@@ -11206,10 +12676,270 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
11206 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 12676 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
11207 { 12677 {
11208 m_host.AddScriptLPS(1); 12678 m_host.AddScriptLPS(1);
11209 NotImplemented("llGodLikeRezObject"); 12679
12680 if (!World.Permissions.IsGod(m_host.OwnerID))
12681 NotImplemented("llGodLikeRezObject");
12682
12683 AssetBase rezAsset = World.AssetService.Get(inventory);
12684 if (rezAsset == null)
12685 {
12686 llSay(0, "Asset not found");
12687 return;
12688 }
12689
12690 SceneObjectGroup group = null;
12691
12692 try
12693 {
12694 string xmlData = Utils.BytesToString(rezAsset.Data);
12695 group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
12696 }
12697 catch
12698 {
12699 llSay(0, "Asset not found");
12700 return;
12701 }
12702
12703 if (group == null)
12704 {
12705 llSay(0, "Asset not found");
12706 return;
12707 }
12708
12709 group.RootPart.AttachPoint = group.RootPart.Shape.State;
12710 group.RootPart.AttachOffset = group.AbsolutePosition;
12711
12712 group.ResetIDs();
12713
12714 Vector3 llpos = new Vector3((float)pos.x, (float)pos.y, (float)pos.z);
12715 World.AddNewSceneObject(group, true, llpos, Quaternion.Identity, Vector3.Zero);
12716 group.CreateScriptInstances(0, true, World.DefaultScriptEngine, 3);
12717 group.ScheduleGroupForFullUpdate();
12718
12719 // objects rezzed with this method are die_at_edge by default.
12720 group.RootPart.SetDieAtEdge(true);
12721
12722 group.ResumeScripts();
12723
12724 m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams(
12725 "object_rez", new Object[] {
12726 new LSL_String(
12727 group.RootPart.UUID.ToString()) },
12728 new DetectParams[0]));
12729 }
12730
12731 public LSL_String llTransferLindenDollars(string destination, int amount)
12732 {
12733 UUID txn = UUID.Random();
12734
12735 Util.FireAndForget(delegate(object x)
12736 {
12737 int replycode = 0;
12738 string replydata = destination + "," + amount.ToString();
12739
12740 try
12741 {
12742 TaskInventoryItem item = m_item;
12743 if (item == null)
12744 {
12745 replydata = "SERVICE_ERROR";
12746 return;
12747 }
12748
12749 m_host.AddScriptLPS(1);
12750
12751 if (item.PermsGranter == UUID.Zero)
12752 {
12753 replydata = "MISSING_PERMISSION_DEBIT";
12754 return;
12755 }
12756
12757 if ((item.PermsMask & ScriptBaseClass.PERMISSION_DEBIT) == 0)
12758 {
12759 replydata = "MISSING_PERMISSION_DEBIT";
12760 return;
12761 }
12762
12763 UUID toID = new UUID();
12764
12765 if (!UUID.TryParse(destination, out toID))
12766 {
12767 replydata = "INVALID_AGENT";
12768 return;
12769 }
12770
12771 IMoneyModule money = World.RequestModuleInterface<IMoneyModule>();
12772
12773 if (money == null)
12774 {
12775 replydata = "TRANSFERS_DISABLED";
12776 return;
12777 }
12778
12779 bool result = money.ObjectGiveMoney(
12780 m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount);
12781
12782 if (result)
12783 {
12784 replycode = 1;
12785 return;
12786 }
12787
12788 replydata = "LINDENDOLLAR_INSUFFICIENTFUNDS";
12789 }
12790 finally
12791 {
12792 m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams(
12793 "transaction_result", new Object[] {
12794 new LSL_String(txn.ToString()),
12795 new LSL_Integer(replycode),
12796 new LSL_String(replydata) },
12797 new DetectParams[0]));
12798 }
12799 });
12800
12801 return txn.ToString();
11210 } 12802 }
11211 12803
11212 #endregion 12804 #endregion
12805
12806 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
12807 {
12808 SceneObjectGroup group = m_host.ParentGroup;
12809
12810 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
12811 return;
12812 if (group.IsAttachment)
12813 return;
12814
12815 if (frames.Data.Length > 0) // We are getting a new motion
12816 {
12817 if (group.RootPart.KeyframeMotion != null)
12818 group.RootPart.KeyframeMotion.Stop();
12819 group.RootPart.KeyframeMotion = null;
12820
12821 int idx = 0;
12822
12823 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
12824 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
12825
12826 while (idx < options.Data.Length)
12827 {
12828 int option = (int)options.GetLSLIntegerItem(idx++);
12829 int remain = options.Data.Length - idx;
12830
12831 switch (option)
12832 {
12833 case ScriptBaseClass.KFM_MODE:
12834 if (remain < 1)
12835 break;
12836 int modeval = (int)options.GetLSLIntegerItem(idx++);
12837 switch(modeval)
12838 {
12839 case ScriptBaseClass.KFM_FORWARD:
12840 mode = KeyframeMotion.PlayMode.Forward;
12841 break;
12842 case ScriptBaseClass.KFM_REVERSE:
12843 mode = KeyframeMotion.PlayMode.Reverse;
12844 break;
12845 case ScriptBaseClass.KFM_LOOP:
12846 mode = KeyframeMotion.PlayMode.Loop;
12847 break;
12848 case ScriptBaseClass.KFM_PING_PONG:
12849 mode = KeyframeMotion.PlayMode.PingPong;
12850 break;
12851 }
12852 break;
12853 case ScriptBaseClass.KFM_DATA:
12854 if (remain < 1)
12855 break;
12856 int dataval = (int)options.GetLSLIntegerItem(idx++);
12857 data = (KeyframeMotion.DataFormat)dataval;
12858 break;
12859 }
12860 }
12861
12862 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
12863
12864 idx = 0;
12865
12866 int elemLength = 2;
12867 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
12868 elemLength = 3;
12869
12870 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
12871 while (idx < frames.Data.Length)
12872 {
12873 int remain = frames.Data.Length - idx;
12874
12875 if (remain < elemLength)
12876 break;
12877
12878 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
12879 frame.Position = null;
12880 frame.Rotation = null;
12881
12882 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
12883 {
12884 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
12885 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
12886 }
12887 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
12888 {
12889 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
12890 frame.Rotation = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
12891 }
12892
12893 float tempf = (float)frames.GetLSLFloatItem(idx++);
12894 frame.TimeMS = (int)(tempf * 1000.0f);
12895
12896 keyframes.Add(frame);
12897 }
12898
12899 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
12900 group.RootPart.KeyframeMotion.Start();
12901 }
12902 else
12903 {
12904 if (group.RootPart.KeyframeMotion == null)
12905 return;
12906
12907 if (options.Data.Length == 0)
12908 {
12909 group.RootPart.KeyframeMotion.Stop();
12910 return;
12911 }
12912
12913 int code = (int)options.GetLSLIntegerItem(0);
12914
12915 int idx = 0;
12916
12917 while (idx < options.Data.Length)
12918 {
12919 int option = (int)options.GetLSLIntegerItem(idx++);
12920 int remain = options.Data.Length - idx;
12921
12922 switch (option)
12923 {
12924 case ScriptBaseClass.KFM_COMMAND:
12925 int cmd = (int)options.GetLSLIntegerItem(idx++);
12926 switch (cmd)
12927 {
12928 case ScriptBaseClass.KFM_CMD_PLAY:
12929 group.RootPart.KeyframeMotion.Start();
12930 break;
12931 case ScriptBaseClass.KFM_CMD_STOP:
12932 group.RootPart.KeyframeMotion.Stop();
12933 break;
12934 case ScriptBaseClass.KFM_CMD_PAUSE:
12935 group.RootPart.KeyframeMotion.Pause();
12936 break;
12937 }
12938 break;
12939 }
12940 }
12941 }
12942 }
11213 } 12943 }
11214 12944
11215 public class NotecardCache 12945 public class NotecardCache
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 3654106..bc20f71 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -138,6 +138,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow; 138 internal ThreatLevel m_MaxThreatLevel = ThreatLevel.VeryLow;
139 internal float m_ScriptDelayFactor = 1.0f; 139 internal float m_ScriptDelayFactor = 1.0f;
140 internal float m_ScriptDistanceFactor = 1.0f; 140 internal float m_ScriptDistanceFactor = 1.0f;
141 internal bool m_debuggerSafe = false;
141 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >(); 142 internal Dictionary<string, FunctionPerms > m_FunctionPerms = new Dictionary<string, FunctionPerms >();
142 143
143 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) 144 public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item)
@@ -145,6 +146,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
145 m_ScriptEngine = ScriptEngine; 146 m_ScriptEngine = ScriptEngine;
146 m_host = host; 147 m_host = host;
147 m_item = item; 148 m_item = item;
149 m_debuggerSafe = m_ScriptEngine.Config.GetBoolean("DebuggerSafe", false);
148 150
149 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false)) 151 if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
150 m_OSFunctionsEnabled = true; 152 m_OSFunctionsEnabled = true;
@@ -206,7 +208,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
206 208
207 internal void OSSLError(string msg) 209 internal void OSSLError(string msg)
208 { 210 {
209 throw new Exception("OSSL Runtime Error: " + msg); 211 if (m_debuggerSafe)
212 {
213 OSSLShoutError(msg);
214 }
215 else
216 {
217 throw new Exception("OSSL Runtime Error: " + msg);
218 }
210 } 219 }
211 220
212 /// <summary> 221 /// <summary>
@@ -916,18 +925,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
916 if (target != null) 925 if (target != null)
917 { 926 {
918 UUID animID=UUID.Zero; 927 UUID animID=UUID.Zero;
919 lock (m_host.TaskInventory) 928 m_host.TaskInventory.LockItemsForRead(true);
929 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
920 { 930 {
921 foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory) 931 if (inv.Value.Name == animation)
922 { 932 {
923 if (inv.Value.Name == animation) 933 if (inv.Value.Type == (int)AssetType.Animation)
924 { 934 animID = inv.Value.AssetID;
925 if (inv.Value.Type == (int)AssetType.Animation) 935 continue;
926 animID = inv.Value.AssetID;
927 continue;
928 }
929 } 936 }
930 } 937 }
938 m_host.TaskInventory.LockItemsForRead(false);
931 if (animID == UUID.Zero) 939 if (animID == UUID.Zero)
932 target.Animator.AddAnimation(animation, m_host.UUID); 940 target.Animator.AddAnimation(animation, m_host.UUID);
933 else 941 else
@@ -968,6 +976,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
968 else 976 else
969 animID = UUID.Zero; 977 animID = UUID.Zero;
970 } 978 }
979 m_host.TaskInventory.LockItemsForRead(false);
971 980
972 if (animID == UUID.Zero) 981 if (animID == UUID.Zero)
973 target.Animator.RemoveAnimation(animation); 982 target.Animator.RemoveAnimation(animation);
@@ -1788,6 +1797,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1788 1797
1789 if (!UUID.TryParse(notecardNameOrUuid, out assetID)) 1798 if (!UUID.TryParse(notecardNameOrUuid, out assetID))
1790 { 1799 {
1800 m_host.TaskInventory.LockItemsForRead(true);
1791 foreach (TaskInventoryItem item in m_host.TaskInventory.Values) 1801 foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
1792 { 1802 {
1793 if (item.Type == 7 && item.Name == notecardNameOrUuid) 1803 if (item.Type == 7 && item.Name == notecardNameOrUuid)
@@ -1795,6 +1805,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1795 assetID = item.AssetID; 1805 assetID = item.AssetID;
1796 } 1806 }
1797 } 1807 }
1808 m_host.TaskInventory.LockItemsForRead(false);
1798 } 1809 }
1799 1810
1800 if (assetID == UUID.Zero) 1811 if (assetID == UUID.Zero)
@@ -2266,7 +2277,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2266 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2277 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2267 m_host.AddScriptLPS(1); 2278 m_host.AddScriptLPS(1);
2268 2279
2269 return NpcCreate(firstname, lastname, position, notecard, false, false); 2280 return NpcCreate(firstname, lastname, position, notecard, true, false);
2270 } 2281 }
2271 2282
2272 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) 2283 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2277,24 +2288,39 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2277 return NpcCreate( 2288 return NpcCreate(
2278 firstname, lastname, position, notecard, 2289 firstname, lastname, position, notecard,
2279 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, 2290 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2280 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); 2291 false);
2292// (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0);
2281 } 2293 }
2282 2294
2283 private LSL_Key NpcCreate( 2295 private LSL_Key NpcCreate(
2284 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) 2296 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2285 { 2297 {
2298 if (!owned)
2299 OSSLError("Unowned NPCs are unsupported");
2300
2301 string groupTitle = String.Empty;
2302
2303 if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
2304 return new LSL_Key(UUID.Zero.ToString());
2305
2306 if (firstname != String.Empty || lastname != String.Empty)
2307 {
2308 if (firstname != "Shown outfit:")
2309 groupTitle = "- NPC -";
2310 }
2311
2286 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2312 INPCModule module = World.RequestModuleInterface<INPCModule>();
2287 if (module != null) 2313 if (module != null)
2288 { 2314 {
2289 AvatarAppearance appearance = null; 2315 AvatarAppearance appearance = null;
2290 2316
2291 UUID id; 2317// UUID id;
2292 if (UUID.TryParse(notecard, out id)) 2318// if (UUID.TryParse(notecard, out id))
2293 { 2319// {
2294 ScenePresence clonePresence = World.GetScenePresence(id); 2320// ScenePresence clonePresence = World.GetScenePresence(id);
2295 if (clonePresence != null) 2321// if (clonePresence != null)
2296 appearance = clonePresence.Appearance; 2322// appearance = clonePresence.Appearance;
2297 } 2323// }
2298 2324
2299 if (appearance == null) 2325 if (appearance == null)
2300 { 2326 {
@@ -2322,6 +2348,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2322 World, 2348 World,
2323 appearance); 2349 appearance);
2324 2350
2351 ScenePresence sp;
2352 if (World.TryGetScenePresence(x, out sp))
2353 {
2354 sp.Grouptitle = groupTitle;
2355 sp.SendAvatarDataToAllAgents();
2356 }
2325 return new LSL_Key(x.ToString()); 2357 return new LSL_Key(x.ToString());
2326 } 2358 }
2327 2359
@@ -2613,16 +2645,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2613 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2645 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2614 m_host.AddScriptLPS(1); 2646 m_host.AddScriptLPS(1);
2615 2647
2616 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2648 ManualResetEvent ev = new ManualResetEvent(false);
2617 if (module != null)
2618 {
2619 UUID npcId = new UUID(npc.m_string);
2620 2649
2621 if (!module.CheckPermissions(npcId, m_host.OwnerID)) 2650 Util.FireAndForget(delegate(object x) {
2622 return; 2651 try
2652 {
2653 INPCModule module = World.RequestModuleInterface<INPCModule>();
2654 if (module != null)
2655 {
2656 UUID npcId = new UUID(npc.m_string);
2623 2657
2624 module.DeleteNPC(npcId, World); 2658 ILandObject l = World.LandChannel.GetLandObject(m_host.GroupPosition.X, m_host.GroupPosition.Y);
2625 } 2659 if (l == null || m_host.OwnerID != l.LandData.OwnerID)
2660 {
2661 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2662 return;
2663 }
2664
2665 module.DeleteNPC(npcId, World);
2666 }
2667 }
2668 finally
2669 {
2670 ev.Set();
2671 }
2672 });
2673 ev.WaitOne();
2626 } 2674 }
2627 2675
2628 public void osNpcPlayAnimation(LSL_Key npc, string animation) 2676 public void osNpcPlayAnimation(LSL_Key npc, string animation)
@@ -3262,4 +3310,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3262 ((LSL_Api)m_LSL_Api).DetachFromAvatar(); 3310 ((LSL_Api)m_LSL_Api).DetachFromAvatar();
3263 } 3311 }
3264 } 3312 }
3265} \ No newline at end of file 3313}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3844753..19f3ce1 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -319,7 +319,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
319 float dy; 319 float dy;
320 float dz; 320 float dz;
321 321
322 Quaternion q = SensePoint.GetWorldRotation(); 322// Quaternion q = SensePoint.RotationOffset;
323 Quaternion q = SensePoint.GetWorldRotation(); // non-attached prim Sensor *always* uses World rotation!
323 if (SensePoint.ParentGroup.IsAttachment) 324 if (SensePoint.ParentGroup.IsAttachment)
324 { 325 {
325 // In attachments, rotate the sensor cone with the 326 // In attachments, rotate the sensor cone with the
@@ -333,7 +334,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
333 // Position of a sensor in a child prim attached to an avatar 334 // Position of a sensor in a child prim attached to an avatar
334 // will be still wrong. 335 // will be still wrong.
335 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 336 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
336 q = avatar.Rotation * q; 337 fromRegionPos = avatar.AbsolutePosition;
338 q = avatar.Rotation;
337 } 339 }
338 340
339 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 341 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
@@ -463,7 +465,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
463 // Position of a sensor in a child prim attached to an avatar 465 // Position of a sensor in a child prim attached to an avatar
464 // will be still wrong. 466 // will be still wrong.
465 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar); 467 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
466 q = avatar.Rotation * q; 468 if (avatar == null)
469 return sensedEntities;
470 fromRegionPos = avatar.AbsolutePosition;
471 q = avatar.Rotation;
467 } 472 }
468 473
469 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W); 474 LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
index bc63030..9ee6946 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/Timer.cs
@@ -118,25 +118,27 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
118 if (Timers.Count == 0) 118 if (Timers.Count == 0)
119 return; 119 return;
120 120
121 Dictionary<string, TimerClass>.ValueCollection tvals;
121 lock (TimerListLock) 122 lock (TimerListLock)
122 { 123 {
123 // Go through all timers 124 // Go through all timers
124 Dictionary<string, TimerClass>.ValueCollection tvals = Timers.Values; 125 tvals = Timers.Values;
125 foreach (TimerClass ts in tvals) 126 }
127
128 foreach (TimerClass ts in tvals)
129 {
130 // Time has passed?
131 if (ts.next < DateTime.Now.Ticks)
126 { 132 {
127 // Time has passed? 133 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
128 if (ts.next < DateTime.Now.Ticks) 134 // Add it to queue
129 { 135 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
130 //m_log.Debug("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next); 136 new EventParams("timer", new Object[0],
131 // Add it to queue 137 new DetectParams[0]));
132 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID, 138 // set next interval
133 new EventParams("timer", new Object[0], 139
134 new DetectParams[0])); 140 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
135 // set next interval 141 ts.next = DateTime.Now.Ticks + ts.interval;
136
137 //ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
138 ts.next = DateTime.Now.Ticks + ts.interval;
139 }
140 } 142 }
141 } 143 }
142 } 144 }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
new file mode 100644
index 0000000..ab215f3
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ICM_Api.cs
@@ -0,0 +1,46 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
26 */
27
28using System.Collections;
29using OpenSim.Region.ScriptEngine.Interfaces;
30
31using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
32using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
33using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
34using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
35using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
36using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
37using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
38
39namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
40{
41 public interface ICM_Api
42 {
43 string cmDetectedCountry(int num);
44 string cmGetAgentCountry(key key);
45 }
46}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index d39b204..af35258 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -126,6 +126,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
126 LSL_Float llGetEnergy(); 126 LSL_Float llGetEnergy();
127 LSL_Vector llGetForce(); 127 LSL_Vector llGetForce();
128 LSL_Integer llGetFreeMemory(); 128 LSL_Integer llGetFreeMemory();
129 LSL_Integer llGetUsedMemory();
129 LSL_Integer llGetFreeURLs(); 130 LSL_Integer llGetFreeURLs();
130 LSL_Vector llGetGeometricCenter(); 131 LSL_Vector llGetGeometricCenter();
131 LSL_Float llGetGMTclock(); 132 LSL_Float llGetGMTclock();
@@ -149,6 +150,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
149 LSL_Vector llGetLocalPos(); 150 LSL_Vector llGetLocalPos();
150 LSL_Rotation llGetLocalRot(); 151 LSL_Rotation llGetLocalRot();
151 LSL_Float llGetMass(); 152 LSL_Float llGetMass();
153 LSL_Float llGetMassMKS();
152 LSL_Integer llGetMemoryLimit(); 154 LSL_Integer llGetMemoryLimit();
153 void llGetNextEmail(string address, string subject); 155 void llGetNextEmail(string address, string subject);
154 LSL_String llGetNotecardLine(string name, int line); 156 LSL_String llGetNotecardLine(string name, int line);
@@ -202,12 +204,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
202 LSL_String llGetTimestamp(); 204 LSL_String llGetTimestamp();
203 LSL_Vector llGetTorque(); 205 LSL_Vector llGetTorque();
204 LSL_Integer llGetUnixTime(); 206 LSL_Integer llGetUnixTime();
205 LSL_Integer llGetUsedMemory();
206 LSL_Vector llGetVel(); 207 LSL_Vector llGetVel();
207 LSL_Float llGetWallclock(); 208 LSL_Float llGetWallclock();
208 void llGiveInventory(string destination, string inventory); 209 void llGiveInventory(string destination, string inventory);
209 void llGiveInventoryList(string destination, string category, LSL_List inventory); 210 void llGiveInventoryList(string destination, string category, LSL_List inventory);
210 LSL_Integer llGiveMoney(string destination, int amount); 211 LSL_Integer llGiveMoney(string destination, int amount);
212 LSL_String llTransferLindenDollars(string destination, int amount);
211 void llGodLikeRezObject(string inventory, LSL_Vector pos); 213 void llGodLikeRezObject(string inventory, LSL_Vector pos);
212 LSL_Float llGround(LSL_Vector offset); 214 LSL_Float llGround(LSL_Vector offset);
213 LSL_Vector llGroundContour(LSL_Vector offset); 215 LSL_Vector llGroundContour(LSL_Vector offset);
@@ -330,6 +332,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
330 void llSensorRemove(); 332 void llSensorRemove();
331 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate); 333 void llSensorRepeat(string name, string id, int type, double range, double arc, double rate);
332 void llSetAlpha(double alpha, int face); 334 void llSetAlpha(double alpha, int face);
335 void llSetAngularVelocity(LSL_Vector angvelocity, int local);
333 void llSetBuoyancy(double buoyancy); 336 void llSetBuoyancy(double buoyancy);
334 void llSetCameraAtOffset(LSL_Vector offset); 337 void llSetCameraAtOffset(LSL_Vector offset);
335 void llSetCameraEyeOffset(LSL_Vector offset); 338 void llSetCameraEyeOffset(LSL_Vector offset);
@@ -355,6 +358,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
355 void llSetParcelMusicURL(string url); 358 void llSetParcelMusicURL(string url);
356 void llSetPayPrice(int price, LSL_List quick_pay_buttons); 359 void llSetPayPrice(int price, LSL_List quick_pay_buttons);
357 void llSetPos(LSL_Vector pos); 360 void llSetPos(LSL_Vector pos);
361 LSL_Integer llSetRegionPos(LSL_Vector pos);
358 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules); 362 LSL_Integer llSetPrimMediaParams(LSL_Integer face, LSL_List rules);
359 void llSetPrimitiveParams(LSL_List rules); 363 void llSetPrimitiveParams(LSL_List rules);
360 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules); 364 void llSetLinkPrimitiveParamsFast(int linknum, LSL_List rules);
@@ -378,6 +382,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
378 void llSetVehicleRotationParam(int param, LSL_Rotation rot); 382 void llSetVehicleRotationParam(int param, LSL_Rotation rot);
379 void llSetVehicleType(int type); 383 void llSetVehicleType(int type);
380 void llSetVehicleVectorParam(int param, LSL_Vector vec); 384 void llSetVehicleVectorParam(int param, LSL_Vector vec);
385 void llSetVelocity(LSL_Vector velocity, int local);
381 void llShout(int channelID, string text); 386 void llShout(int channelID, string text);
382 LSL_Float llSin(double f); 387 LSL_Float llSin(double f);
383 void llSitTarget(LSL_Vector offset, LSL_Rotation rot); 388 void llSitTarget(LSL_Vector offset, LSL_Rotation rot);
@@ -421,9 +426,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
421 LSL_Vector llWind(LSL_Vector offset); 426 LSL_Vector llWind(LSL_Vector offset);
422 LSL_String llXorBase64Strings(string str1, string str2); 427 LSL_String llXorBase64Strings(string str1, string str2);
423 LSL_String llXorBase64StringsCorrect(string str1, string str2); 428 LSL_String llXorBase64StringsCorrect(string str1, string str2);
424 void print(string str); 429 LSL_Integer llGetLinkNumberOfSides(LSL_Integer link);
430 void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density);
425 431
426 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 432 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
427 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 433 LSL_List GetLinkPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
434 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
428 } 435 }
429} 436}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index b5416c8..1facc96 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -85,7 +85,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
85 // Avatar Info Commands 85 // Avatar Info Commands
86 string osGetAgentIP(string agent); 86 string osGetAgentIP(string agent);
87 LSL_List osGetAgents(); 87 LSL_List osGetAgents();
88 88
89 // Teleport commands 89 // Teleport commands
90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 90 void osTeleportAgent(string agent, string regionName, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat); 91 void osTeleportAgent(string agent, int regionX, int regionY, LSL_Types.Vector3 position, LSL_Types.Vector3 lookat);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
new file mode 100644
index 0000000..4132dfa
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/CM_Stub.cs
@@ -0,0 +1,71 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
26 */
27
28using System;
29using System.Runtime.Remoting.Lifetime;
30using System.Threading;
31using System.Reflection;
32using System.Collections;
33using System.Collections.Generic;
34using OpenSim.Framework;
35using OpenSim.Region.Framework.Interfaces;
36using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared.Api.Interfaces;
38using integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
39using vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3;
40using rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion;
41using key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
42using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list;
43using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString;
44using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat;
45using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger;
46
47namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
48{
49 public partial class ScriptBaseClass : MarshalByRefObject
50 {
51 public ICM_Api m_CM_Functions;
52
53 public void ApiTypeCM(IScriptApi api)
54 {
55 if (!(api is ICM_Api))
56 return;
57
58 m_CM_Functions = (ICM_Api)api;
59 }
60
61 public string cmDetectedCountry(int num)
62 {
63 return m_CM_Functions.cmDetectedCountry(num);
64 }
65
66 public string cmGetAgentCountry(key key)
67 {
68 return m_CM_Functions.cmGetAgentCountry(key);
69 }
70 }
71}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
index 9615315..943d7a2 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/Executor.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics; //for [DebuggerNonUserCode]
30using System.Reflection; 31using System.Reflection;
31using System.Runtime.Remoting.Lifetime; 32using System.Runtime.Remoting.Lifetime;
32using OpenSim.Region.ScriptEngine.Shared; 33using OpenSim.Region.ScriptEngine.Shared;
@@ -132,6 +133,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
132 return (eventFlags); 133 return (eventFlags);
133 } 134 }
134 135
136 [DebuggerNonUserCode]
135 public void ExecuteEvent(string state, string FunctionName, object[] args) 137 public void ExecuteEvent(string state, string FunctionName, object[] args)
136 { 138 {
137 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory. 139 // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index b6c21e6..a08cc42 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -94,6 +94,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
94 public const int AGENT_CROUCHING = 1024; 94 public const int AGENT_CROUCHING = 1024;
95 public const int AGENT_BUSY = 2048; 95 public const int AGENT_BUSY = 2048;
96 public const int AGENT_ALWAYS_RUN = 4096; 96 public const int AGENT_ALWAYS_RUN = 4096;
97 public const int AGENT_MALE = 8192;
97 98
98 //Particle Systems 99 //Particle Systems
99 public const int PSYS_PART_INTERP_COLOR_MASK = 1; 100 public const int PSYS_PART_INTERP_COLOR_MASK = 1;
@@ -282,6 +283,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
282 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART 283 public const int CHANGED_REGION_START = 1024; //LL Changed the constant from CHANGED_REGION_RESTART
283 public const int CHANGED_MEDIA = 2048; 284 public const int CHANGED_MEDIA = 2048;
284 public const int CHANGED_ANIMATION = 16384; 285 public const int CHANGED_ANIMATION = 16384;
286 public const int CHANGED_POSITION = 32768;
285 public const int TYPE_INVALID = 0; 287 public const int TYPE_INVALID = 0;
286 public const int TYPE_INTEGER = 1; 288 public const int TYPE_INTEGER = 1;
287 public const int TYPE_FLOAT = 2; 289 public const int TYPE_FLOAT = 2;
@@ -586,6 +588,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
586 public const int PRIM_MEDIA_PERM_OWNER = 1; 588 public const int PRIM_MEDIA_PERM_OWNER = 1;
587 public const int PRIM_MEDIA_PERM_GROUP = 2; 589 public const int PRIM_MEDIA_PERM_GROUP = 2;
588 public const int PRIM_MEDIA_PERM_ANYONE = 4; 590 public const int PRIM_MEDIA_PERM_ANYONE = 4;
591
592 public const int PRIM_PHYSICS_SHAPE_TYPE = 30;
593 public const int PRIM_PHYSICS_SHAPE_PRIM = 0;
594 public const int PRIM_PHYSICS_SHAPE_CONVEX = 2;
595 public const int PRIM_PHYSICS_SHAPE_NONE = 1;
596
597 public const int PRIM_PHYSICS_MATERIAL = 31;
598 public const int DENSITY = 1;
599 public const int FRICTION = 2;
600 public const int RESTITUTION = 4;
601 public const int GRAVITY_MULTIPLIER = 8;
589 602
590 // extra constants for llSetPrimMediaParams 603 // extra constants for llSetPrimMediaParams
591 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0); 604 public static readonly LSLInteger LSL_STATUS_OK = new LSLInteger(0);
@@ -658,6 +671,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
658 671
659 public static readonly LSLInteger RCERR_UNKNOWN = -1; 672 public static readonly LSLInteger RCERR_UNKNOWN = -1;
660 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 673 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
661 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 674 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = -3;
675
676 public const int KFM_MODE = 1;
677 public const int KFM_LOOP = 1;
678 public const int KFM_REVERSE = 3;
679 public const int KFM_FORWARD = 0;
680 public const int KFM_PING_PONG = 2;
681 public const int KFM_DATA = 2;
682 public const int KFM_TRANSLATION = 2;
683 public const int KFM_ROTATION = 1;
684 public const int KFM_COMMAND = 0;
685 public const int KFM_CMD_PLAY = 0;
686 public const int KFM_CMD_STOP = 1;
687 public const int KFM_CMD_PAUSE = 2;
662 } 688 }
663} 689}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index a0b3bc8..89b6eff 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Diagnostics; //for [DebuggerNonUserCode]
29using System.Runtime.Remoting.Lifetime; 30using System.Runtime.Remoting.Lifetime;
30using System.Threading; 31using System.Threading;
31using System.Reflection; 32using System.Reflection;
@@ -314,6 +315,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
314 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel); 315 m_LSL_Functions.llDialog(avatar, message, buttons, chat_channel);
315 } 316 }
316 317
318 [DebuggerNonUserCode]
317 public void llDie() 319 public void llDie()
318 { 320 {
319 m_LSL_Functions.llDie(); 321 m_LSL_Functions.llDie();
@@ -474,6 +476,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
474 return m_LSL_Functions.llGetFreeMemory(); 476 return m_LSL_Functions.llGetFreeMemory();
475 } 477 }
476 478
479 public LSL_Integer llGetUsedMemory()
480 {
481 return m_LSL_Functions.llGetUsedMemory();
482 }
483
477 public LSL_Integer llGetFreeURLs() 484 public LSL_Integer llGetFreeURLs()
478 { 485 {
479 return m_LSL_Functions.llGetFreeURLs(); 486 return m_LSL_Functions.llGetFreeURLs();
@@ -579,6 +586,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
579 return m_LSL_Functions.llGetMass(); 586 return m_LSL_Functions.llGetMass();
580 } 587 }
581 588
589 public LSL_Float llGetMassMKS()
590 {
591 return m_LSL_Functions.llGetMassMKS();
592 }
593
582 public LSL_Integer llGetMemoryLimit() 594 public LSL_Integer llGetMemoryLimit()
583 { 595 {
584 return m_LSL_Functions.llGetMemoryLimit(); 596 return m_LSL_Functions.llGetMemoryLimit();
@@ -844,11 +856,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
844 return m_LSL_Functions.llGetUnixTime(); 856 return m_LSL_Functions.llGetUnixTime();
845 } 857 }
846 858
847 public LSL_Integer llGetUsedMemory()
848 {
849 return m_LSL_Functions.llGetUsedMemory();
850 }
851
852 public LSL_Vector llGetVel() 859 public LSL_Vector llGetVel()
853 { 860 {
854 return m_LSL_Functions.llGetVel(); 861 return m_LSL_Functions.llGetVel();
@@ -874,6 +881,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
874 return m_LSL_Functions.llGiveMoney(destination, amount); 881 return m_LSL_Functions.llGiveMoney(destination, amount);
875 } 882 }
876 883
884 public LSL_String llTransferLindenDollars(string destination, int amount)
885 {
886 return m_LSL_Functions.llTransferLindenDollars(destination, amount);
887 }
888
877 public void llGodLikeRezObject(string inventory, LSL_Vector pos) 889 public void llGodLikeRezObject(string inventory, LSL_Vector pos)
878 { 890 {
879 m_LSL_Functions.llGodLikeRezObject(inventory, pos); 891 m_LSL_Functions.llGodLikeRezObject(inventory, pos);
@@ -1483,6 +1495,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1483 m_LSL_Functions.llSetAlpha(alpha, face); 1495 m_LSL_Functions.llSetAlpha(alpha, face);
1484 } 1496 }
1485 1497
1498 public void llSetAngularVelocity(LSL_Vector angvelocity, int local)
1499 {
1500 m_LSL_Functions.llSetAngularVelocity(angvelocity, local);
1501 }
1502
1486 public void llSetBuoyancy(double buoyancy) 1503 public void llSetBuoyancy(double buoyancy)
1487 { 1504 {
1488 m_LSL_Functions.llSetBuoyancy(buoyancy); 1505 m_LSL_Functions.llSetBuoyancy(buoyancy);
@@ -1603,6 +1620,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1603 m_LSL_Functions.llSetPos(pos); 1620 m_LSL_Functions.llSetPos(pos);
1604 } 1621 }
1605 1622
1623 public LSL_Integer llSetRegionPos(LSL_Vector pos)
1624 {
1625 return m_LSL_Functions.llSetRegionPos(pos);
1626 }
1627
1606 public void llSetPrimitiveParams(LSL_List rules) 1628 public void llSetPrimitiveParams(LSL_List rules)
1607 { 1629 {
1608 m_LSL_Functions.llSetPrimitiveParams(rules); 1630 m_LSL_Functions.llSetPrimitiveParams(rules);
@@ -1713,6 +1735,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1713 m_LSL_Functions.llSetVehicleVectorParam(param, vec); 1735 m_LSL_Functions.llSetVehicleVectorParam(param, vec);
1714 } 1736 }
1715 1737
1738 public void llSetVelocity(LSL_Vector velocity, int local)
1739 {
1740 m_LSL_Functions.llSetVelocity(velocity, local);
1741 }
1742
1716 public void llShout(int channelID, string text) 1743 public void llShout(int channelID, string text)
1717 { 1744 {
1718 m_LSL_Functions.llShout(channelID, text); 1745 m_LSL_Functions.llShout(channelID, text);
@@ -1963,9 +1990,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1963 return m_LSL_Functions.llClearLinkMedia(link, face); 1990 return m_LSL_Functions.llClearLinkMedia(link, face);
1964 } 1991 }
1965 1992
1966 public void print(string str) 1993 public LSL_Integer llGetLinkNumberOfSides(LSL_Integer link)
1994 {
1995 return m_LSL_Functions.llGetLinkNumberOfSides(link);
1996 }
1997
1998 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
1999 {
2000 m_LSL_Functions.llSetKeyframedMotion(frames, options);
2001 }
2002
2003 public void llSetPhysicsMaterial(int material_bits, float material_gravity_modifier, float material_restitution, float material_friction, float material_density)
1967 { 2004 {
1968 m_LSL_Functions.print(str); 2005 m_LSL_Functions.llSetPhysicsMaterial(material_bits, material_gravity_modifier, material_restitution, material_friction, material_density);
1969 } 2006 }
1970 } 2007 }
1971} 2008}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
index 143b497..2e27f16 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LS_Stub.cs
@@ -72,9 +72,30 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
72 { 72 {
73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target); 73 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
74 } 74 }
75
75 public void lsClearWindlightScene() 76 public void lsClearWindlightScene()
76 { 77 {
77 m_LS_Functions.lsClearWindlightScene(); 78 m_LS_Functions.lsClearWindlightScene();
78 } 79 }
80
81 public LSL_List cmGetWindlightScene(LSL_List rules)
82 {
83 return m_LS_Functions.lsGetWindlightScene(rules);
84 }
85
86 public int cmSetWindlightScene(LSL_List rules)
87 {
88 return m_LS_Functions.lsSetWindlightScene(rules);
89 }
90
91 public int cmSetWindlightSceneTargeted(LSL_List rules, key target)
92 {
93 return m_LS_Functions.lsSetWindlightSceneTargeted(rules, target);
94 }
95
96 public void cmClearWindlightScene()
97 {
98 m_LS_Functions.lsClearWindlightScene();
99 }
79 } 100 }
80} 101}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
index edbbc2a..b138da3 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/ScriptBase.cs
@@ -33,6 +33,7 @@ using System.Threading;
33using System.Reflection; 33using System.Reflection;
34using System.Collections; 34using System.Collections;
35using System.Collections.Generic; 35using System.Collections.Generic;
36using System.Diagnostics; //for [DebuggerNonUserCode]
36using OpenSim.Region.ScriptEngine.Interfaces; 37using OpenSim.Region.ScriptEngine.Interfaces;
37using OpenSim.Region.ScriptEngine.Shared; 38using OpenSim.Region.ScriptEngine.Shared;
38using OpenSim.Region.ScriptEngine.Shared.Api.Runtime; 39using OpenSim.Region.ScriptEngine.Shared.Api.Runtime;
@@ -90,6 +91,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
90 return (int)m_Executor.GetStateEventFlags(state); 91 return (int)m_Executor.GetStateEventFlags(state);
91 } 92 }
92 93
94 [DebuggerNonUserCode]
93 public void ExecuteEvent(string state, string FunctionName, object[] args) 95 public void ExecuteEvent(string state, string FunctionName, object[] args)
94 { 96 {
95 m_Executor.ExecuteEvent(state, FunctionName, args); 97 m_Executor.ExecuteEvent(state, FunctionName, args);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
index 8cebb4a..5c9d30f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Helpers.cs
@@ -35,6 +35,7 @@ using OpenMetaverse;
35using OpenSim.Framework; 35using OpenSim.Framework;
36using OpenSim.Region.CoreModules; 36using OpenSim.Region.CoreModules;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Services.Interfaces;
38 39
39namespace OpenSim.Region.ScriptEngine.Shared 40namespace OpenSim.Region.ScriptEngine.Shared
40{ 41{
@@ -95,6 +96,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
95 Type = 0; 96 Type = 0;
96 Velocity = new LSL_Types.Vector3(); 97 Velocity = new LSL_Types.Vector3();
97 initializeSurfaceTouch(); 98 initializeSurfaceTouch();
99 Country = String.Empty;
98 } 100 }
99 101
100 public UUID Key; 102 public UUID Key;
@@ -126,6 +128,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
126 private int touchFace; 128 private int touchFace;
127 public int TouchFace { get { return touchFace; } } 129 public int TouchFace { get { return touchFace; } }
128 130
131 public string Country;
132
129 // This can be done in two places including the constructor 133 // This can be done in two places including the constructor
130 // so be carefull what gets added here 134 // so be carefull what gets added here
131 private void initializeSurfaceTouch() 135 private void initializeSurfaceTouch()
@@ -173,6 +177,10 @@ namespace OpenSim.Region.ScriptEngine.Shared
173 return; 177 return;
174 178
175 Name = presence.Firstname + " " + presence.Lastname; 179 Name = presence.Firstname + " " + presence.Lastname;
180 UserAccount account = scene.UserAccountService.GetUserAccount(scene.RegionInfo.ScopeID, Key);
181 if (account != null)
182 Country = account.UserCountry;
183
176 Owner = Key; 184 Owner = Key;
177 Position = new LSL_Types.Vector3( 185 Position = new LSL_Types.Vector3(
178 presence.AbsolutePosition.X, 186 presence.AbsolutePosition.X,
@@ -189,6 +197,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
189 presence.Velocity.Z); 197 presence.Velocity.Z);
190 198
191 Type = 0x01; // Avatar 199 Type = 0x01; // Avatar
200 if (presence.PresenceType == PresenceType.Npc)
201 Type = 0x20;
192 if (presence.Velocity != Vector3.Zero) 202 if (presence.Velocity != Vector3.Zero)
193 Type |= 0x02; // Active 203 Type |= 0x02; // Active
194 204
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index f1abd4b..8d92ba5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -30,6 +30,7 @@ using System.Collections;
30using System.Collections.Generic; 30using System.Collections.Generic;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Diagnostics; //for [DebuggerNonUserCode]
33using System.Reflection; 34using System.Reflection;
34using System.Runtime.Remoting; 35using System.Runtime.Remoting;
35using System.Runtime.Remoting.Lifetime; 36using System.Runtime.Remoting.Lifetime;
@@ -222,13 +223,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
222 223
223 if (part != null) 224 if (part != null)
224 { 225 {
225 lock (part.TaskInventory) 226 part.TaskInventory.LockItemsForRead(true);
227 if (part.TaskInventory.ContainsKey(ItemID))
226 { 228 {
227 if (part.TaskInventory.ContainsKey(ItemID)) 229 ScriptTask = part.TaskInventory[ItemID];
228 {
229 ScriptTask = part.TaskInventory[ItemID];
230 }
231 } 230 }
231 part.TaskInventory.LockItemsForRead(false);
232 } 232 }
233 233
234 ApiManager am = new ApiManager(); 234 ApiManager am = new ApiManager();
@@ -424,14 +424,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
424 { 424 {
425 int permsMask; 425 int permsMask;
426 UUID permsGranter; 426 UUID permsGranter;
427 lock (part.TaskInventory) 427 part.TaskInventory.LockItemsForRead(true);
428 if (!part.TaskInventory.ContainsKey(ItemID))
428 { 429 {
429 if (!part.TaskInventory.ContainsKey(ItemID)) 430 part.TaskInventory.LockItemsForRead(false);
430 return; 431 return;
431
432 permsGranter = part.TaskInventory[ItemID].PermsGranter;
433 permsMask = part.TaskInventory[ItemID].PermsMask;
434 } 432 }
433 permsGranter = part.TaskInventory[ItemID].PermsGranter;
434 permsMask = part.TaskInventory[ItemID].PermsMask;
435 part.TaskInventory.LockItemsForRead(false);
435 436
436 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0) 437 if ((permsMask & ScriptBaseClass.PERMISSION_TAKE_CONTROLS) != 0)
437 { 438 {
@@ -559,6 +560,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
559 return true; 560 return true;
560 } 561 }
561 562
563 [DebuggerNonUserCode] //Prevents the debugger from farting in this function
562 public void SetState(string state) 564 public void SetState(string state)
563 { 565 {
564 if (state == State) 566 if (state == State)
@@ -570,7 +572,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
570 new DetectParams[0])); 572 new DetectParams[0]));
571 PostEvent(new EventParams("state_entry", new Object[0], 573 PostEvent(new EventParams("state_entry", new Object[0],
572 new DetectParams[0])); 574 new DetectParams[0]));
573 575
574 throw new EventAbortException(); 576 throw new EventAbortException();
575 } 577 }
576 578
@@ -660,45 +662,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
660 /// <returns></returns> 662 /// <returns></returns>
661 public object EventProcessor() 663 public object EventProcessor()
662 { 664 {
665 EventParams data = null;
663 // We check here as the thread stopping this instance from running may itself hold the m_Script lock. 666 // We check here as the thread stopping this instance from running may itself hold the m_Script lock.
664 if (!Running) 667 if (!Running)
665 return 0; 668 return 0;
666 669
667 lock (m_Script)
668 {
669// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName); 670// m_log.DebugFormat("[XEngine]: EventProcessor() invoked for {0}.{1}", PrimName, ScriptName);
670 671
671 if (Suspended) 672 if (Suspended)
672 return 0; 673 return 0;
673
674 EventParams data = null;
675 674
676 lock (EventQueue) 675 lock (EventQueue)
676 {
677 data = (EventParams) EventQueue.Dequeue();
678 if (data == null) // Shouldn't happen
677 { 679 {
678 data = (EventParams)EventQueue.Dequeue(); 680 if (EventQueue.Count > 0 && Running && !ShuttingDown)
679 if (data == null) // Shouldn't happen
680 { 681 {
681 if (EventQueue.Count > 0 && Running && !ShuttingDown) 682 m_CurrentWorkItem = Engine.QueueEventHandler(this);
682 {
683 m_CurrentWorkItem = Engine.QueueEventHandler(this);
684 }
685 else
686 {
687 m_CurrentWorkItem = null;
688 }
689 return 0;
690 } 683 }
691 684 else
692 if (data.EventName == "timer")
693 m_TimerQueued = false;
694 if (data.EventName == "control")
695 { 685 {
696 if (m_ControlEventsInQueue > 0) 686 m_CurrentWorkItem = null;
697 m_ControlEventsInQueue--;
698 } 687 }
699 if (data.EventName == "collision") 688 return 0;
700 m_CollisionInQueue = false;
701 } 689 }
690
691 if (data.EventName == "timer")
692 m_TimerQueued = false;
693 if (data.EventName == "control")
694 {
695 if (m_ControlEventsInQueue > 0)
696 m_ControlEventsInQueue--;
697 }
698 if (data.EventName == "collision")
699 m_CollisionInQueue = false;
700 }
701
702 lock(m_Script)
703 {
702 704
703// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this); 705// m_log.DebugFormat("[XEngine]: Processing event {0} for {1}", data.EventName, this);
704 706
@@ -853,6 +855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
853 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 855 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
854 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 856 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
855 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 857 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
858 part.CollisionSound = UUID.Zero;
856 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 859 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
857 EventQueue.Clear(); 860 EventQueue.Clear();
858 m_Script.ResetVars(); 861 m_Script.ResetVars();
@@ -867,6 +870,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
867 new Object[0], new DetectParams[0])); 870 new Object[0], new DetectParams[0]));
868 } 871 }
869 872
873 [DebuggerNonUserCode] //Stops the VS debugger from farting in this function
870 public void ApiResetScript() 874 public void ApiResetScript()
871 { 875 {
872 // bool running = Running; 876 // bool running = Running;
@@ -878,6 +882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
878 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID); 882 SceneObjectPart part = Engine.World.GetSceneObjectPart(LocalID);
879 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0; 883 part.Inventory.GetInventoryItem(ItemID).PermsMask = 0;
880 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero; 884 part.Inventory.GetInventoryItem(ItemID).PermsGranter = UUID.Zero;
885 part.CollisionSound = UUID.Zero;
881 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID); 886 AsyncCommandManager.RemoveScript(Engine, LocalID, ItemID);
882 887
883 EventQueue.Clear(); 888 EventQueue.Clear();
@@ -898,10 +903,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
898 903
899 public Dictionary<string, object> GetVars() 904 public Dictionary<string, object> GetVars()
900 { 905 {
901 if (m_Script != null) 906 return m_Script.GetVars();
902 return m_Script.GetVars();
903 else
904 return new Dictionary<string, object>();
905 } 907 }
906 908
907 public void SetVars(Dictionary<string, object> vars) 909 public void SetVars(Dictionary<string, object> vars)
diff --git a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
index d848b2a..8adf4c5 100644
--- a/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/LSL_Types.cs
@@ -83,19 +83,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
83 83
84 public override string ToString() 84 public override string ToString()
85 { 85 {
86 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", x, y, z); 86 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", x, y, z);
87 return s; 87 return s;
88 } 88 }
89 89
90 public static explicit operator LSLString(Vector3 vec) 90 public static explicit operator LSLString(Vector3 vec)
91 { 91 {
92 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 92 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
93 return new LSLString(s); 93 return new LSLString(s);
94 } 94 }
95 95
96 public static explicit operator string(Vector3 vec) 96 public static explicit operator string(Vector3 vec)
97 { 97 {
98 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000}>", vec.x, vec.y, vec.z); 98 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}>", vec.x, vec.y, vec.z);
99 return s; 99 return s;
100 } 100 }
101 101
@@ -342,19 +342,19 @@ namespace OpenSim.Region.ScriptEngine.Shared
342 342
343 public override string ToString() 343 public override string ToString()
344 { 344 {
345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", x, y, z, s); 345 string st=String.Format(Culture.FormatProvider, "<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", x, y, z, s);
346 return st; 346 return st;
347 } 347 }
348 348
349 public static explicit operator string(Quaternion r) 349 public static explicit operator string(Quaternion r)
350 { 350 {
351 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 351 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
352 return s; 352 return s;
353 } 353 }
354 354
355 public static explicit operator LSLString(Quaternion r) 355 public static explicit operator LSLString(Quaternion r)
356 { 356 {
357 string s=String.Format("<{0:0.000000},{1:0.000000},{2:0.000000},{3:0.000000}>", r.x, r.y, r.z, r.s); 357 string s=String.Format("<{0:0.000000}, {1:0.000000}, {2:0.000000}, {3:0.000000}>", r.x, r.y, r.z, r.s);
358 return new LSLString(s); 358 return new LSLString(s);
359 } 359 }
360 360
@@ -459,6 +459,8 @@ namespace OpenSim.Region.ScriptEngine.Shared
459 size += 64; 459 size += 64;
460 else if (o is int) 460 else if (o is int)
461 size += 4; 461 size += 4;
462 else if (o is uint)
463 size += 4;
462 else if (o is string) 464 else if (o is string)
463 size += ((string)o).Length; 465 size += ((string)o).Length;
464 else if (o is float) 466 else if (o is float)
@@ -613,24 +615,16 @@ namespace OpenSim.Region.ScriptEngine.Shared
613 615
614 public static bool operator ==(list a, list b) 616 public static bool operator ==(list a, list b)
615 { 617 {
616 int la = -1; 618 int la = a.Length;
617 int lb = -1; 619 int lb = b.Length;
618 try { la = a.Length; }
619 catch (NullReferenceException) { }
620 try { lb = b.Length; }
621 catch (NullReferenceException) { }
622 620
623 return la == lb; 621 return la == lb;
624 } 622 }
625 623
626 public static bool operator !=(list a, list b) 624 public static bool operator !=(list a, list b)
627 { 625 {
628 int la = -1; 626 int la = a.Length;
629 int lb = -1; 627 int lb = b.Length;
630 try { la = a.Length; }
631 catch (NullReferenceException) { }
632 try {lb = b.Length;}
633 catch (NullReferenceException) { }
634 628
635 return la != lb; 629 return la != lb;
636 } 630 }
@@ -864,7 +858,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
864 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r)); 858 ret = Math.Sign(Quaternion.Mag(l) - Quaternion.Mag(r));
865 } 859 }
866 860
867 if (ascending == 0) 861 if (ascending != 1)
868 { 862 {
869 ret = 0 - ret; 863 ret = 0 - ret;
870 } 864 }
@@ -897,6 +891,9 @@ namespace OpenSim.Region.ScriptEngine.Shared
897 stride = 1; 891 stride = 1;
898 } 892 }
899 893
894 if ((Data.Length % stride) != 0)
895 return new list(ret);
896
900 // we can optimize here in the case where stride == 1 and the list 897 // we can optimize here in the case where stride == 1 and the list
901 // consists of homogeneous types 898 // consists of homogeneous types
902 899
@@ -916,7 +913,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
916 if (homogeneous) 913 if (homogeneous)
917 { 914 {
918 Array.Sort(ret, new HomogeneousComparer()); 915 Array.Sort(ret, new HomogeneousComparer());
919 if (ascending == 0) 916 if (ascending != 1)
920 { 917 {
921 Array.Reverse(ret); 918 Array.Reverse(ret);
922 } 919 }
@@ -1064,7 +1061,7 @@ namespace OpenSim.Region.ScriptEngine.Shared
1064 { 1061 {
1065 list ret = new list(); 1062 list ret = new list();
1066 double entry; 1063 double entry;
1067 for (int i = 0; i < src.Data.Length - 1; i++) 1064 for (int i = 0; i < src.Data.Length; i++)
1068 { 1065 {
1069 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry)) 1066 if (double.TryParse(src.Data[i].ToString(), NumberStyles.Float, Culture.NumberFormatInfo, out entry))
1070 { 1067 {