aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/Shared
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ScriptEngine/Shared')
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs180
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs352
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs2
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs55
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs10
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs37
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs28
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs156
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs170
11 files changed, 902 insertions, 129 deletions
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 443e7a5..67dee02 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -126,11 +126,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
126 m_TransferModule = 126 m_TransferModule =
127 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>(); 127 m_ScriptEngine.World.RequestModuleInterface<IMessageTransferModule>();
128 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>(); 128 m_UrlModule = m_ScriptEngine.World.RequestModuleInterface<IUrlModule>();
129 if (m_UrlModule != null)
130 {
131 m_ScriptEngine.OnScriptRemoved += m_UrlModule.ScriptRemoved;
132 m_ScriptEngine.OnObjectRemoved += m_UrlModule.ObjectRemoved;
133 }
134 129
135 AsyncCommands = new AsyncCommandManager(ScriptEngine); 130 AsyncCommands = new AsyncCommandManager(ScriptEngine);
136 } 131 }
@@ -468,26 +463,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
468 463
469 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke 464 //Now we start getting into quaternions which means sin/cos, matrices and vectors. ckrinke
470 465
471 // Old implementation of llRot2Euler. Normalization not required as Atan2 function will 466 /// <summary>
472 // only return values >= -PI (-180 degrees) and <= PI (180 degrees). 467 /// Convert an LSL rotation to a Euler vector.
473 468 /// </summary>
469 /// <remarks>
470 /// Using algorithm based off http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/quat_2_euler_paper_ver2-1.pdf
471 /// to avoid issues with singularity and rounding with Y rotation of +/- PI/2
472 /// </remarks>
473 /// <param name="r"></param>
474 /// <returns></returns>
474 public LSL_Vector llRot2Euler(LSL_Rotation r) 475 public LSL_Vector llRot2Euler(LSL_Rotation r)
475 { 476 {
476 m_host.AddScriptLPS(1); 477 m_host.AddScriptLPS(1);
477 //This implementation is from http://lslwiki.net/lslwiki/wakka.php?wakka=LibraryRotationFunctions. ckrinke 478
478 LSL_Rotation t = new LSL_Rotation(r.x * r.x, r.y * r.y, r.z * r.z, r.s * r.s); 479 LSL_Vector v = new LSL_Vector(0.0, 0.0, 1.0) * r; // Z axis unit vector unaffected by Z rotation component of r.
479 double m = (t.x + t.y + t.z + t.s); 480 double m = LSL_Vector.Mag(v); // Just in case v isn't normalized, need magnitude for Asin() operation later.
480 if (m == 0) return new LSL_Vector(); 481 if (m == 0.0) return new LSL_Vector();
481 double n = 2 * (r.y * r.s + r.x * r.z); 482 double x = Math.Atan2(-v.y, v.z);
482 double p = m * m - n * n; 483 double sin = v.x / m;
483 if (p > 0) 484 if (sin < -0.999999 || sin > 0.999999) x = 0.0; // Force X rotation to 0 at the singularities.
484 return new LSL_Vector(Math.Atan2(2.0 * (r.x * r.s - r.y * r.z), (-t.x - t.y + t.z + t.s)), 485 double y = Math.Asin(sin);
485 Math.Atan2(n, Math.Sqrt(p)), 486 // Rotate X axis unit vector by r and unwind the X and Y rotations leaving only the Z rotation
486 Math.Atan2(2.0 * (r.z * r.s - r.x * r.y), (t.x - t.y - t.z + t.s))); 487 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)));
487 else if (n > 0) 488 double z = Math.Atan2(v.y, v.x);
488 return new LSL_Vector(0.0, Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z)); 489
489 else 490 return new LSL_Vector(x, y, z);
490 return new LSL_Vector(0.0, -Math.PI * 0.5, Math.Atan2((r.z * r.s + r.x * r.y), 0.5 - t.x - t.z));
491 } 491 }
492 492
493 /* From wiki: 493 /* From wiki:
@@ -2856,11 +2856,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2856 // we need to convert from a vector describing 2856 // we need to convert from a vector describing
2857 // the angles of rotation in radians into rotation value 2857 // the angles of rotation in radians into rotation value
2858 2858
2859 LSL_Types.Quaternion rot = llEuler2Rot(angle); 2859 LSL_Rotation rot = llEuler2Rot(angle);
2860 Quaternion rotation = new Quaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s); 2860
2861 m_host.startLookAt(rotation, (float)damping, (float)strength); 2861 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
2862 // Orient the object to the angle calculated 2862 // set the rotation of the object, copy that behavior
2863 //llSetRot(rot); 2863 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
2864 {
2865 llSetRot(rot);
2866 }
2867 else
2868 {
2869 m_host.StartLookAt(Rot2Quaternion(rot), (float)strength, (float)damping);
2870 }
2864 } 2871 }
2865 2872
2866 public void llStopLookAt() 2873 public void llStopLookAt()
@@ -3236,8 +3243,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
3236 public void llRotLookAt(LSL_Rotation target, double strength, double damping) 3243 public void llRotLookAt(LSL_Rotation target, double strength, double damping)
3237 { 3244 {
3238 m_host.AddScriptLPS(1); 3245 m_host.AddScriptLPS(1);
3239 Quaternion rot = new Quaternion((float)target.x, (float)target.y, (float)target.z, (float)target.s); 3246
3240 m_host.RotLookAt(rot, (float)strength, (float)damping); 3247 // Per discussion with Melanie, for non-physical objects llLookAt appears to simply
3248 // set the rotation of the object, copy that behavior
3249 if (strength == 0 || m_host.PhysActor == null || !m_host.PhysActor.IsPhysical)
3250 {
3251 llSetLocalRot(target);
3252 }
3253 else
3254 {
3255 m_host.RotLookAt(Rot2Quaternion(target), (float)strength, (float)damping);
3256 }
3241 } 3257 }
3242 3258
3243 public LSL_Integer llStringLength(string str) 3259 public LSL_Integer llStringLength(string str)
@@ -4023,9 +4039,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4023 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f), 4039 Vector3 av3 = new Vector3(Util.Clip((float)color.x, 0.0f, 1.0f),
4024 Util.Clip((float)color.y, 0.0f, 1.0f), 4040 Util.Clip((float)color.y, 0.0f, 1.0f),
4025 Util.Clip((float)color.z, 0.0f, 1.0f)); 4041 Util.Clip((float)color.z, 0.0f, 1.0f));
4026 m_host.SetText(text, av3, Util.Clip((float)alpha, 0.0f, 1.0f)); 4042 m_host.SetText(text.Length > 254 ? text.Remove(255) : text, av3, Util.Clip((float)alpha, 0.0f, 1.0f));
4027 m_host.ParentGroup.HasGroupChanged = true; 4043 //m_host.ParentGroup.HasGroupChanged = true;
4028 m_host.ParentGroup.ScheduleGroupForFullUpdate(); 4044 //m_host.ParentGroup.ScheduleGroupForFullUpdate();
4029 } 4045 }
4030 4046
4031 public LSL_Float llWater(LSL_Vector offset) 4047 public LSL_Float llWater(LSL_Vector offset)
@@ -4693,15 +4709,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
4693 return (double)Math.Asin(val); 4709 return (double)Math.Asin(val);
4694 } 4710 }
4695 4711
4696 // Xantor 30/apr/2008 4712 // jcochran 5/jan/2012
4697 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b) 4713 public LSL_Float llAngleBetween(LSL_Rotation a, LSL_Rotation b)
4698 { 4714 {
4699 m_host.AddScriptLPS(1); 4715 m_host.AddScriptLPS(1);
4700 4716
4701 double angle = Math.Acos(a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s) * 2; 4717 double aa = (a.x * a.x + a.y * a.y + a.z * a.z + a.s * a.s);
4702 if (angle < 0) angle = -angle; 4718 double bb = (b.x * b.x + b.y * b.y + b.z * b.z + b.s * b.s);
4703 if (angle > Math.PI) return (Math.PI * 2 - angle); 4719 double aa_bb = aa * bb;
4704 return angle; 4720 if (aa_bb == 0) return 0.0;
4721 double ab = (a.x * b.x + a.y * b.y + a.z * b.z + a.s * b.s);
4722 double quotient = (ab * ab) / aa_bb;
4723 if (quotient >= 1.0) return 0.0;
4724 return Math.Acos(2 * quotient - 1);
4705 } 4725 }
4706 4726
4707 public LSL_String llGetInventoryKey(string name) 4727 public LSL_String llGetInventoryKey(string name)
@@ -5486,7 +5506,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
5486 5506
5487 foreach (GridRegion sri in neighbors) 5507 foreach (GridRegion sri in neighbors)
5488 { 5508 {
5489 if (sri.RegionLocX == neighborX && sri.RegionLocY == neighborY) 5509 if (sri.RegionCoordX == neighborX && sri.RegionCoordY == neighborY)
5490 return 0; 5510 return 0;
5491 } 5511 }
5492 5512
@@ -6583,7 +6603,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
6583 } 6603 }
6584 6604
6585 // the rest of the permission checks are done in RezScript, so check the pin there as well 6605 // the rest of the permission checks are done in RezScript, so check the pin there as well
6586 World.RezScript(srcId, m_host, destId, pin, running, start_param); 6606 World.RezScriptFromPrim(srcId, m_host, destId, pin, running, start_param);
6607
6587 // this will cause the delay even if the script pin or permissions were wrong - seems ok 6608 // this will cause the delay even if the script pin or permissions were wrong - seems ok
6588 ScriptSleep(3000); 6609 ScriptSleep(3000);
6589 } 6610 }
@@ -7546,6 +7567,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7546 ScriptSleep(2000); 7567 ScriptSleep(2000);
7547 } 7568 }
7548 7569
7570 public LSL_String llGetParcelMusicURL()
7571 {
7572 m_host.AddScriptLPS(1);
7573
7574 ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
7575
7576 if (land.LandData.OwnerID != m_host.OwnerID)
7577 return String.Empty;
7578
7579 return land.GetMusicUrl();
7580 }
7581
7549 public LSL_Vector llGetRootPosition() 7582 public LSL_Vector llGetRootPosition()
7550 { 7583 {
7551 m_host.AddScriptLPS(1); 7584 m_host.AddScriptLPS(1);
@@ -10613,6 +10646,75 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
10613 return list; 10646 return list;
10614 } 10647 }
10615 10648
10649 public LSL_Integer llManageEstateAccess(int action, string avatar)
10650 {
10651 m_host.AddScriptLPS(1);
10652 EstateSettings estate = World.RegionInfo.EstateSettings;
10653 bool isAccount = false;
10654 bool isGroup = false;
10655
10656 if (!estate.IsEstateOwner(m_host.OwnerID) || !estate.IsEstateManager(m_host.OwnerID))
10657 return 0;
10658
10659 UUID id = new UUID();
10660 if (!UUID.TryParse(avatar, out id))
10661 return 0;
10662
10663 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, id);
10664 isAccount = account != null ? true : false;
10665 if (!isAccount)
10666 {
10667 IGroupsModule groups = World.RequestModuleInterface<IGroupsModule>();
10668 if (groups != null)
10669 {
10670 GroupRecord group = groups.GetGroupRecord(id);
10671 isGroup = group != null ? true : false;
10672 if (!isGroup)
10673 return 0;
10674 }
10675 else
10676 return 0;
10677 }
10678
10679 switch (action)
10680 {
10681 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_ADD:
10682 if (!isAccount) return 0;
10683 if (estate.HasAccess(id)) return 1;
10684 if (estate.IsBanned(id))
10685 estate.RemoveBan(id);
10686 estate.AddEstateUser(id);
10687 break;
10688 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_AGENT_REMOVE:
10689 if (!isAccount || !estate.HasAccess(id)) return 0;
10690 estate.RemoveEstateUser(id);
10691 break;
10692 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_ADD:
10693 if (!isGroup) return 0;
10694 if (estate.GroupAccess(id)) return 1;
10695 estate.AddEstateGroup(id);
10696 break;
10697 case ScriptBaseClass.ESTATE_ACCESS_ALLOWED_GROUP_REMOVE:
10698 if (!isGroup || !estate.GroupAccess(id)) return 0;
10699 estate.RemoveEstateGroup(id);
10700 break;
10701 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_ADD:
10702 if (!isAccount) return 0;
10703 if (estate.IsBanned(id)) return 1;
10704 EstateBan ban = new EstateBan();
10705 ban.EstateID = estate.EstateID;
10706 ban.BannedUserID = id;
10707 estate.AddBan(ban);
10708 break;
10709 case ScriptBaseClass.ESTATE_ACCESS_BANNED_AGENT_REMOVE:
10710 if (!isAccount || !estate.IsBanned(id)) return 0;
10711 estate.RemoveBan(id);
10712 break;
10713 default: return 0;
10714 }
10715 return 1;
10716 }
10717
10616 #region Not Implemented 10718 #region Not Implemented
10617 // 10719 //
10618 // Listing the unimplemented lsl functions here, please move 10720 // Listing the unimplemented lsl functions here, please move
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 503b5d0..b1583eb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -157,6 +157,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
157 string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow"); 157 string risk = m_ScriptEngine.Config.GetString("OSFunctionThreatLevel", "VeryLow");
158 switch (risk) 158 switch (risk)
159 { 159 {
160 case "NoAccess":
161 m_MaxThreatLevel = ThreatLevel.NoAccess;
162 break;
160 case "None": 163 case "None":
161 m_MaxThreatLevel = ThreatLevel.None; 164 m_MaxThreatLevel = ThreatLevel.None;
162 break; 165 break;
@@ -413,6 +416,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
413 public LSL_Integer osSetTerrainHeight(int x, int y, double val) 416 public LSL_Integer osSetTerrainHeight(int x, int y, double val)
414 { 417 {
415 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight"); 418 CheckThreatLevel(ThreatLevel.High, "osSetTerrainHeight");
419
416 return SetTerrainHeight(x, y, val); 420 return SetTerrainHeight(x, y, val);
417 } 421 }
418 422
@@ -420,12 +424,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
420 { 424 {
421 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight"); 425 CheckThreatLevel(ThreatLevel.High, "osTerrainSetHeight");
422 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight"); 426 OSSLDeprecated("osTerrainSetHeight", "osSetTerrainHeight");
427
423 return SetTerrainHeight(x, y, val); 428 return SetTerrainHeight(x, y, val);
424 } 429 }
425 430
426 private LSL_Integer SetTerrainHeight(int x, int y, double val) 431 private LSL_Integer SetTerrainHeight(int x, int y, double val)
427 { 432 {
428 m_host.AddScriptLPS(1); 433 m_host.AddScriptLPS(1);
434
429 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0) 435 if (x > ((int)Constants.RegionSize - 1) || x < 0 || y > ((int)Constants.RegionSize - 1) || y < 0)
430 OSSLError("osSetTerrainHeight: Coordinate out of bounds"); 436 OSSLError("osSetTerrainHeight: Coordinate out of bounds");
431 437
@@ -465,6 +471,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
465 public void osTerrainFlush() 471 public void osTerrainFlush()
466 { 472 {
467 CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush"); 473 CheckThreatLevel(ThreatLevel.VeryLow, "osTerrainFlush");
474 m_host.AddScriptLPS(1);
468 475
469 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>(); 476 ITerrainModule terrainModule = World.RequestModuleInterface<ITerrainModule>();
470 if (terrainModule != null) terrainModule.TaintTerrain(); 477 if (terrainModule != null) terrainModule.TaintTerrain();
@@ -736,7 +743,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
736 { 743 {
737 // High because there is no security check. High griefer potential 744 // High because there is no security check. High griefer potential
738 // 745 //
739 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 746 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
740 747
741 TeleportAgent(agent, regionName, position, lookat, false); 748 TeleportAgent(agent, regionName, position, lookat, false);
742 } 749 }
@@ -753,11 +760,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
753 { 760 {
754 // For osTeleportAgent, agent must be over owners land to avoid abuse 761 // For osTeleportAgent, agent must be over owners land to avoid abuse
755 // For osTeleportOwner, this restriction isn't necessary 762 // For osTeleportOwner, this restriction isn't necessary
756 if (relaxRestrictions || 763
757 m_host.OwnerID 764 // commented out because its redundant and uneeded please remove eventually.
758 == World.LandChannel.GetLandObject( 765 // if (relaxRestrictions ||
759 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 766 // m_host.OwnerID
760 { 767 // == World.LandChannel.GetLandObject(
768 // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
769 // {
770
761 // We will launch the teleport on a new thread so that when the script threads are terminated 771 // We will launch the teleport on a new thread so that when the script threads are terminated
762 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 772 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
763 Util.FireAndForget( 773 Util.FireAndForget(
@@ -766,7 +776,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
766 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); 776 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
767 777
768 ScriptSleep(5000); 778 ScriptSleep(5000);
769 } 779
780 // }
781
770 } 782 }
771 } 783 }
772 } 784 }
@@ -775,7 +787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
775 { 787 {
776 // High because there is no security check. High griefer potential 788 // High because there is no security check. High griefer potential
777 // 789 //
778 CheckThreatLevel(ThreatLevel.High, "osTeleportAgent"); 790 CheckThreatLevel(ThreatLevel.Severe, "osTeleportAgent");
779 791
780 TeleportAgent(agent, regionX, regionY, position, lookat, false); 792 TeleportAgent(agent, regionX, regionY, position, lookat, false);
781 } 793 }
@@ -794,11 +806,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
794 { 806 {
795 // For osTeleportAgent, agent must be over owners land to avoid abuse 807 // For osTeleportAgent, agent must be over owners land to avoid abuse
796 // For osTeleportOwner, this restriction isn't necessary 808 // For osTeleportOwner, this restriction isn't necessary
797 if (relaxRestrictions || 809
798 m_host.OwnerID 810 // commented out because its redundant and uneeded please remove eventually.
799 == World.LandChannel.GetLandObject( 811 // if (relaxRestrictions ||
800 presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID) 812 // m_host.OwnerID
801 { 813 // == World.LandChannel.GetLandObject(
814 // presence.AbsolutePosition.X, presence.AbsolutePosition.Y).LandData.OwnerID)
815 // {
816
802 // We will launch the teleport on a new thread so that when the script threads are terminated 817 // We will launch the teleport on a new thread so that when the script threads are terminated
803 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting. 818 // before teleport in ScriptInstance.GetXMLState(), we don't end up aborting the one doing the teleporting.
804 Util.FireAndForget( 819 Util.FireAndForget(
@@ -807,7 +822,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
807 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation)); 822 new Vector3((float)lookat.x, (float)lookat.y, (float)lookat.z), (uint)TPFlags.ViaLocation));
808 823
809 ScriptSleep(5000); 824 ScriptSleep(5000);
810 } 825
826 // }
827
811 } 828 }
812 } 829 }
813 } 830 }
@@ -871,6 +888,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
871 // threat level is None as we could get this information with an 888 // threat level is None as we could get this information with an
872 // in-world script as well, just not as efficient 889 // in-world script as well, just not as efficient
873 CheckThreatLevel(ThreatLevel.None, "osGetAgents"); 890 CheckThreatLevel(ThreatLevel.None, "osGetAgents");
891 m_host.AddScriptLPS(1);
874 892
875 LSL_List result = new LSL_List(); 893 LSL_List result = new LSL_List();
876 World.ForEachRootScenePresence(delegate(ScenePresence sp) 894 World.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -885,6 +903,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
885 { 903 {
886 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation"); 904 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarPlayAnimation");
887 905
906 AvatarPlayAnimation(avatar, animation);
907 }
908
909 private void AvatarPlayAnimation(string avatar, string animation)
910 {
888 UUID avatarID = (UUID)avatar; 911 UUID avatarID = (UUID)avatar;
889 912
890 m_host.AddScriptLPS(1); 913 m_host.AddScriptLPS(1);
@@ -918,6 +941,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
918 { 941 {
919 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation"); 942 CheckThreatLevel(ThreatLevel.VeryHigh, "osAvatarStopAnimation");
920 943
944 AvatarStopAnimation(avatar, animation);
945 }
946
947 private void AvatarStopAnimation(string avatar, string animation)
948 {
921 UUID avatarID = (UUID)avatar; 949 UUID avatarID = (UUID)avatar;
922 950
923 m_host.AddScriptLPS(1); 951 m_host.AddScriptLPS(1);
@@ -1141,6 +1169,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1141 // should be removed 1169 // should be removed
1142 // 1170 //
1143 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents"); 1171 CheckThreatLevel(ThreatLevel.High, "osSetStateEvents");
1172 m_host.AddScriptLPS(1);
1144 1173
1145 m_host.SetScriptEvents(m_itemID, events); 1174 m_host.SetScriptEvents(m_itemID, events);
1146 } 1175 }
@@ -1488,7 +1517,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1488 1517
1489 m_host.AddScriptLPS(1); 1518 m_host.AddScriptLPS(1);
1490 1519
1491
1492 ILandObject land 1520 ILandObject land
1493 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); 1521 = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y);
1494 1522
@@ -1549,6 +1577,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1549 // 1577 //
1550 CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion"); 1578 CheckThreatLevel(ThreatLevel.High,"osGetSimulatorVersion");
1551 m_host.AddScriptLPS(1); 1579 m_host.AddScriptLPS(1);
1580
1552 return m_ScriptEngine.World.GetSimulatorVersion(); 1581 return m_ScriptEngine.World.GetSimulatorVersion();
1553 } 1582 }
1554 1583
@@ -1886,6 +1915,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1886 public string osAvatarName2Key(string firstname, string lastname) 1915 public string osAvatarName2Key(string firstname, string lastname)
1887 { 1916 {
1888 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key"); 1917 CheckThreatLevel(ThreatLevel.Low, "osAvatarName2Key");
1918 m_host.AddScriptLPS(1);
1889 1919
1890 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, firstname, lastname); 1920 UserAccount account = World.UserAccountService.GetUserAccount(World.RegionInfo.ScopeID, firstname, lastname);
1891 if (null == account) 1921 if (null == account)
@@ -1901,6 +1931,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1901 public string osKey2Name(string id) 1931 public string osKey2Name(string id)
1902 { 1932 {
1903 CheckThreatLevel(ThreatLevel.Low, "osKey2Name"); 1933 CheckThreatLevel(ThreatLevel.Low, "osKey2Name");
1934 m_host.AddScriptLPS(1);
1935
1904 UUID key = new UUID(); 1936 UUID key = new UUID();
1905 1937
1906 if (UUID.TryParse(id, out key)) 1938 if (UUID.TryParse(id, out key))
@@ -1921,6 +1953,69 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1921 } 1953 }
1922 } 1954 }
1923 1955
1956 private enum InfoType
1957 {
1958 Nick,
1959 Name,
1960 Login,
1961 Home,
1962 Custom
1963 };
1964
1965 private string GridUserInfo(InfoType type)
1966 {
1967 return GridUserInfo(type, "");
1968 }
1969
1970 private string GridUserInfo(InfoType type, string key)
1971 {
1972 string retval = String.Empty;
1973 IConfigSource config = m_ScriptEngine.ConfigSource;
1974 string url = config.Configs["GridInfo"].GetString("GridInfoURI", String.Empty);
1975
1976 if (String.IsNullOrEmpty(url))
1977 return "Configuration Error!";
1978
1979 string verb ="/json_grid_info";
1980 OSDMap json = new OSDMap();
1981
1982 OSDMap info = WebUtil.GetFromService(String.Format("{0}{1}",url,verb), 3000);
1983
1984 if (info["Success"] != true)
1985 return "Get GridInfo Failed!";
1986
1987 json = (OSDMap)OSDParser.DeserializeJson(info["_RawResult"].AsString());
1988
1989 switch (type)
1990 {
1991 case InfoType.Nick:
1992 retval = json["gridnick"];
1993 break;
1994
1995 case InfoType.Name:
1996 retval = json["gridname"];
1997 break;
1998
1999 case InfoType.Login:
2000 retval = json["login"];
2001 break;
2002
2003 case InfoType.Home:
2004 retval = json["home"];
2005 break;
2006
2007 case InfoType.Custom:
2008 retval = json[key];
2009 break;
2010
2011 default:
2012 retval = "error";
2013 break;
2014 }
2015
2016 return retval;
2017 }
2018
1924 /// <summary> 2019 /// <summary>
1925 /// Get the nickname of this grid, as set in the [GridInfo] config section. 2020 /// Get the nickname of this grid, as set in the [GridInfo] config section.
1926 /// </summary> 2021 /// </summary>
@@ -1934,10 +2029,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1934 { 2029 {
1935 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick"); 2030 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridNick");
1936 m_host.AddScriptLPS(1); 2031 m_host.AddScriptLPS(1);
1937 string nick = "hippogrid"; 2032
2033 string nick = String.Empty;
1938 IConfigSource config = m_ScriptEngine.ConfigSource; 2034 IConfigSource config = m_ScriptEngine.ConfigSource;
2035
1939 if (config.Configs["GridInfo"] != null) 2036 if (config.Configs["GridInfo"] != null)
1940 nick = config.Configs["GridInfo"].GetString("gridnick", nick); 2037 nick = config.Configs["GridInfo"].GetString("gridnick", nick);
2038
2039 if (String.IsNullOrEmpty(nick))
2040 nick = GridUserInfo(InfoType.Nick);
2041
1941 return nick; 2042 return nick;
1942 } 2043 }
1943 2044
@@ -1945,10 +2046,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1945 { 2046 {
1946 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridName"); 2047 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridName");
1947 m_host.AddScriptLPS(1); 2048 m_host.AddScriptLPS(1);
1948 string name = "the lost continent of hippo"; 2049
2050 string name = String.Empty;
1949 IConfigSource config = m_ScriptEngine.ConfigSource; 2051 IConfigSource config = m_ScriptEngine.ConfigSource;
2052
1950 if (config.Configs["GridInfo"] != null) 2053 if (config.Configs["GridInfo"] != null)
1951 name = config.Configs["GridInfo"].GetString("gridname", name); 2054 name = config.Configs["GridInfo"].GetString("gridname", name);
2055
2056 if (String.IsNullOrEmpty(name))
2057 name = GridUserInfo(InfoType.Name);
2058
1952 return name; 2059 return name;
1953 } 2060 }
1954 2061
@@ -1956,13 +2063,53 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
1956 { 2063 {
1957 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI"); 2064 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridLoginURI");
1958 m_host.AddScriptLPS(1); 2065 m_host.AddScriptLPS(1);
1959 string loginURI = "http://127.0.0.1:9000/"; 2066
2067 string loginURI = String.Empty;
1960 IConfigSource config = m_ScriptEngine.ConfigSource; 2068 IConfigSource config = m_ScriptEngine.ConfigSource;
2069
1961 if (config.Configs["GridInfo"] != null) 2070 if (config.Configs["GridInfo"] != null)
1962 loginURI = config.Configs["GridInfo"].GetString("login", loginURI); 2071 loginURI = config.Configs["GridInfo"].GetString("login", loginURI);
2072
2073 if (String.IsNullOrEmpty(loginURI))
2074 loginURI = GridUserInfo(InfoType.Login);
2075
1963 return loginURI; 2076 return loginURI;
1964 } 2077 }
1965 2078
2079 public string osGetGridHomeURI()
2080 {
2081 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridHomeURI");
2082 m_host.AddScriptLPS(1);
2083
2084 string HomeURI = String.Empty;
2085 IConfigSource config = m_ScriptEngine.ConfigSource;
2086
2087 if (config.Configs["LoginService"] != null)
2088 HomeURI = config.Configs["LoginService"].GetString("SRV_HomeURI", HomeURI);
2089
2090 if (String.IsNullOrEmpty(HomeURI))
2091 HomeURI = GridUserInfo(InfoType.Home);
2092
2093 return HomeURI;
2094 }
2095
2096 public string osGetGridCustom(string key)
2097 {
2098 CheckThreatLevel(ThreatLevel.Moderate, "osGetGridCustom");
2099 m_host.AddScriptLPS(1);
2100
2101 string retval = String.Empty;
2102 IConfigSource config = m_ScriptEngine.ConfigSource;
2103
2104 if (config.Configs["GridInfo"] != null)
2105 retval = config.Configs["GridInfo"].GetString(key, retval);
2106
2107 if (String.IsNullOrEmpty(retval))
2108 retval = GridUserInfo(InfoType.Custom, key);
2109
2110 return retval;
2111 }
2112
1966 public LSL_String osFormatString(string str, LSL_List strings) 2113 public LSL_String osFormatString(string str, LSL_List strings)
1967 { 2114 {
1968 CheckThreatLevel(ThreatLevel.Low, "osFormatString"); 2115 CheckThreatLevel(ThreatLevel.Low, "osFormatString");
@@ -2064,10 +2211,45 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2064 return retVal; 2211 return retVal;
2065 } 2212 }
2066 2213
2214 public LSL_Integer osIsNpc(LSL_Key npc)
2215 {
2216 CheckThreatLevel(ThreatLevel.None, "osIsNpc");
2217 m_host.AddScriptLPS(1);
2218
2219 INPCModule module = World.RequestModuleInterface<INPCModule>();
2220 if (module != null)
2221 {
2222 UUID npcId;
2223 if (UUID.TryParse(npc.m_string, out npcId))
2224 if (module.IsNPC(npcId, World))
2225 return ScriptBaseClass.TRUE;
2226 }
2227
2228 return ScriptBaseClass.FALSE;
2229 }
2230
2067 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard) 2231 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard)
2068 { 2232 {
2069 CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); 2233 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2234 m_host.AddScriptLPS(1);
2235
2236 return NpcCreate(firstname, lastname, position, notecard, false, true);
2237 }
2238
2239 public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
2240 {
2241 CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
2242 m_host.AddScriptLPS(1);
2070 2243
2244 return NpcCreate(
2245 firstname, lastname, position, notecard,
2246 (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
2247 (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) == 0);
2248 }
2249
2250 private LSL_Key NpcCreate(
2251 string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
2252 {
2071 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2253 INPCModule module = World.RequestModuleInterface<INPCModule>();
2072 if (module != null) 2254 if (module != null)
2073 { 2255 {
@@ -2096,9 +2278,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2096 if (appearance == null) 2278 if (appearance == null)
2097 return new LSL_Key(UUID.Zero.ToString()); 2279 return new LSL_Key(UUID.Zero.ToString());
2098 2280
2281 UUID ownerID = UUID.Zero;
2282 if (owned)
2283 ownerID = m_host.OwnerID;
2099 UUID x = module.CreateNPC(firstname, 2284 UUID x = module.CreateNPC(firstname,
2100 lastname, 2285 lastname,
2101 new Vector3((float) position.x, (float) position.y, (float) position.z), 2286 new Vector3((float) position.x, (float) position.y, (float) position.z),
2287 ownerID,
2288 senseAsAgent,
2102 World, 2289 World,
2103 appearance); 2290 appearance);
2104 2291
@@ -2117,6 +2304,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2117 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard) 2304 public LSL_Key osNpcSaveAppearance(LSL_Key npc, string notecard)
2118 { 2305 {
2119 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance"); 2306 CheckThreatLevel(ThreatLevel.High, "osNpcSaveAppearance");
2307 m_host.AddScriptLPS(1);
2120 2308
2121 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2309 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2122 2310
@@ -2126,7 +2314,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2126 if (!UUID.TryParse(npc.m_string, out npcId)) 2314 if (!UUID.TryParse(npc.m_string, out npcId))
2127 return new LSL_Key(UUID.Zero.ToString()); 2315 return new LSL_Key(UUID.Zero.ToString());
2128 2316
2129 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2317 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2130 return new LSL_Key(UUID.Zero.ToString()); 2318 return new LSL_Key(UUID.Zero.ToString());
2131 2319
2132 return SaveAppearanceToNotecard(npcId, notecard); 2320 return SaveAppearanceToNotecard(npcId, notecard);
@@ -2138,6 +2326,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2138 public void osNpcLoadAppearance(LSL_Key npc, string notecard) 2326 public void osNpcLoadAppearance(LSL_Key npc, string notecard)
2139 { 2327 {
2140 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance"); 2328 CheckThreatLevel(ThreatLevel.High, "osNpcLoadAppearance");
2329 m_host.AddScriptLPS(1);
2141 2330
2142 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2331 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2143 2332
@@ -2147,6 +2336,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2147 if (!UUID.TryParse(npc.m_string, out npcId)) 2336 if (!UUID.TryParse(npc.m_string, out npcId))
2148 return; 2337 return;
2149 2338
2339 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2340 return;
2341
2150 string appearanceSerialized = LoadNotecard(notecard); 2342 string appearanceSerialized = LoadNotecard(notecard);
2151 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); 2343 OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized);
2152// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized); 2344// OSD a = OSDParser.DeserializeLLSDXml(appearanceSerialized);
@@ -2159,9 +2351,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2159 } 2351 }
2160 } 2352 }
2161 2353
2354 public LSL_Key osNpcGetOwner(LSL_Key npc)
2355 {
2356 CheckThreatLevel(ThreatLevel.None, "osNpcGetOwner");
2357 m_host.AddScriptLPS(1);
2358
2359 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2360 if (npcModule != null)
2361 {
2362 UUID npcId;
2363 if (UUID.TryParse(npc.m_string, out npcId))
2364 {
2365 UUID owner = npcModule.GetOwner(npcId);
2366 if (owner != UUID.Zero)
2367 return new LSL_Key(owner.ToString());
2368 else
2369 return npc;
2370 }
2371 }
2372
2373 return new LSL_Key(UUID.Zero.ToString());
2374 }
2375
2162 public LSL_Vector osNpcGetPos(LSL_Key npc) 2376 public LSL_Vector osNpcGetPos(LSL_Key npc)
2163 { 2377 {
2164 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos"); 2378 CheckThreatLevel(ThreatLevel.High, "osNpcGetPos");
2379 m_host.AddScriptLPS(1);
2165 2380
2166 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2381 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2167 if (npcModule != null) 2382 if (npcModule != null)
@@ -2170,7 +2385,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2170 if (!UUID.TryParse(npc.m_string, out npcId)) 2385 if (!UUID.TryParse(npc.m_string, out npcId))
2171 return new LSL_Vector(0, 0, 0); 2386 return new LSL_Vector(0, 0, 0);
2172 2387
2173 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2388 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2174 return new LSL_Vector(0, 0, 0); 2389 return new LSL_Vector(0, 0, 0);
2175 2390
2176 Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition; 2391 Vector3 pos = World.GetScenePresence(npcId).AbsolutePosition;
@@ -2183,6 +2398,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2183 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position) 2398 public void osNpcMoveTo(LSL_Key npc, LSL_Vector position)
2184 { 2399 {
2185 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo"); 2400 CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo");
2401 m_host.AddScriptLPS(1);
2186 2402
2187 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2403 INPCModule module = World.RequestModuleInterface<INPCModule>();
2188 if (module != null) 2404 if (module != null)
@@ -2190,6 +2406,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2190 UUID npcId; 2406 UUID npcId;
2191 if (!UUID.TryParse(npc.m_string, out npcId)) 2407 if (!UUID.TryParse(npc.m_string, out npcId))
2192 return; 2408 return;
2409
2410 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2411 return;
2193 2412
2194 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z); 2413 Vector3 pos = new Vector3((float) position.x, (float) position.y, (float) position.z);
2195 module.MoveToTarget(npcId, World, pos, false, true); 2414 module.MoveToTarget(npcId, World, pos, false, true);
@@ -2199,6 +2418,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2199 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options) 2418 public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
2200 { 2419 {
2201 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget"); 2420 CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget");
2421 m_host.AddScriptLPS(1);
2202 2422
2203 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2423 INPCModule module = World.RequestModuleInterface<INPCModule>();
2204 if (module != null) 2424 if (module != null)
@@ -2207,6 +2427,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2207 if (!UUID.TryParse(npc.m_string, out npcId)) 2427 if (!UUID.TryParse(npc.m_string, out npcId))
2208 return; 2428 return;
2209 2429
2430 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2431 return;
2432
2210 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z); 2433 Vector3 pos = new Vector3((float)target.x, (float)target.y, (float)target.z);
2211 module.MoveToTarget( 2434 module.MoveToTarget(
2212 new UUID(npc.m_string), 2435 new UUID(npc.m_string),
@@ -2220,6 +2443,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2220 public LSL_Rotation osNpcGetRot(LSL_Key npc) 2443 public LSL_Rotation osNpcGetRot(LSL_Key npc)
2221 { 2444 {
2222 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot"); 2445 CheckThreatLevel(ThreatLevel.High, "osNpcGetRot");
2446 m_host.AddScriptLPS(1);
2223 2447
2224 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2448 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2225 if (npcModule != null) 2449 if (npcModule != null)
@@ -2228,7 +2452,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2228 if (!UUID.TryParse(npc.m_string, out npcId)) 2452 if (!UUID.TryParse(npc.m_string, out npcId))
2229 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2453 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2230 2454
2231 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2455 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2232 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W); 2456 return new LSL_Rotation(Quaternion.Identity.X, Quaternion.Identity.Y, Quaternion.Identity.Z, Quaternion.Identity.W);
2233 2457
2234 ScenePresence sp = World.GetScenePresence(npcId); 2458 ScenePresence sp = World.GetScenePresence(npcId);
@@ -2243,6 +2467,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2243 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation) 2467 public void osNpcSetRot(LSL_Key npc, LSL_Rotation rotation)
2244 { 2468 {
2245 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot"); 2469 CheckThreatLevel(ThreatLevel.High, "osNpcSetRot");
2470 m_host.AddScriptLPS(1);
2246 2471
2247 INPCModule npcModule = World.RequestModuleInterface<INPCModule>(); 2472 INPCModule npcModule = World.RequestModuleInterface<INPCModule>();
2248 if (npcModule != null) 2473 if (npcModule != null)
@@ -2251,7 +2476,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2251 if (!UUID.TryParse(npc.m_string, out npcId)) 2476 if (!UUID.TryParse(npc.m_string, out npcId))
2252 return; 2477 return;
2253 2478
2254 if (!npcModule.IsNPC(npcId, m_host.ParentGroup.Scene)) 2479 if (!npcModule.CheckPermissions(npcId, m_host.OwnerID))
2255 return; 2480 return;
2256 2481
2257 ScenePresence sp = World.GetScenePresence(npcId); 2482 ScenePresence sp = World.GetScenePresence(npcId);
@@ -2262,53 +2487,115 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2262 public void osNpcStopMoveToTarget(LSL_Key npc) 2487 public void osNpcStopMoveToTarget(LSL_Key npc)
2263 { 2488 {
2264 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo"); 2489 CheckThreatLevel(ThreatLevel.VeryLow, "osNpcStopMoveTo");
2490 m_host.AddScriptLPS(1);
2265 2491
2266 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2492 INPCModule module = World.RequestModuleInterface<INPCModule>();
2267 if (module != null) 2493 if (module != null)
2268 module.StopMoveToTarget(new UUID(npc.m_string), World); 2494 {
2495 UUID npcId = new UUID(npc.m_string);
2496
2497 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2498 return;
2499
2500 module.StopMoveToTarget(npcId, World);
2501 }
2269 } 2502 }
2270 2503
2271 public void osNpcSay(LSL_Key npc, string message) 2504 public void osNpcSay(LSL_Key npc, string message)
2272 { 2505 {
2273 CheckThreatLevel(ThreatLevel.High, "osNpcSay"); 2506 CheckThreatLevel(ThreatLevel.High, "osNpcSay");
2507 m_host.AddScriptLPS(1);
2274 2508
2275 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2509 INPCModule module = World.RequestModuleInterface<INPCModule>();
2276 if (module != null) 2510 if (module != null)
2277 { 2511 {
2278 module.Say(new UUID(npc.m_string), World, message); 2512 UUID npcId = new UUID(npc.m_string);
2513
2514 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2515 return;
2516
2517 module.Say(npcId, World, message);
2279 } 2518 }
2280 } 2519 }
2281 2520
2282 public void osNpcSit(LSL_Key npc, LSL_Key target, int options) 2521 public void osNpcSit(LSL_Key npc, LSL_Key target, int options)
2283 { 2522 {
2284 CheckThreatLevel(ThreatLevel.High, "osNpcSit"); 2523 CheckThreatLevel(ThreatLevel.High, "osNpcSit");
2524 m_host.AddScriptLPS(1);
2285 2525
2286 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2526 INPCModule module = World.RequestModuleInterface<INPCModule>();
2287 if (module != null) 2527 if (module != null)
2288 { 2528 {
2289 module.Sit(new UUID(npc.m_string), new UUID(target.m_string), World); 2529 UUID npcId = new UUID(npc.m_string);
2530
2531 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2532 return;
2533
2534 module.Sit(npcId, new UUID(target.m_string), World);
2290 } 2535 }
2291 } 2536 }
2292 2537
2293 public void osNpcStand(LSL_Key npc) 2538 public void osNpcStand(LSL_Key npc)
2294 { 2539 {
2295 CheckThreatLevel(ThreatLevel.High, "osNpcStand"); 2540 CheckThreatLevel(ThreatLevel.High, "osNpcStand");
2541 m_host.AddScriptLPS(1);
2296 2542
2297 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2543 INPCModule module = World.RequestModuleInterface<INPCModule>();
2298 if (module != null) 2544 if (module != null)
2299 { 2545 {
2300 module.Stand(new UUID(npc.m_string), World); 2546 UUID npcId = new UUID(npc.m_string);
2547
2548 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2549 return;
2550
2551 module.Stand(npcId, World);
2301 } 2552 }
2302 } 2553 }
2303 2554
2304 public void osNpcRemove(LSL_Key npc) 2555 public void osNpcRemove(LSL_Key npc)
2305 { 2556 {
2306 CheckThreatLevel(ThreatLevel.High, "osNpcRemove"); 2557 CheckThreatLevel(ThreatLevel.High, "osNpcRemove");
2558 m_host.AddScriptLPS(1);
2559
2560 INPCModule module = World.RequestModuleInterface<INPCModule>();
2561 if (module != null)
2562 {
2563 UUID npcId = new UUID(npc.m_string);
2564
2565 if (!module.CheckPermissions(npcId, m_host.OwnerID))
2566 return;
2567
2568 module.DeleteNPC(npcId, World);
2569 }
2570 }
2571
2572 public void osNpcPlayAnimation(LSL_Key npc, string animation)
2573 {
2574 CheckThreatLevel(ThreatLevel.High, "osNpcPlayAnimation");
2575 m_host.AddScriptLPS(1);
2576
2577 INPCModule module = World.RequestModuleInterface<INPCModule>();
2578 if (module != null)
2579 {
2580 UUID npcID = new UUID(npc.m_string);
2581
2582 if (module.CheckPermissions(npcID, m_host.OwnerID))
2583 AvatarPlayAnimation(npcID.ToString(), animation);
2584 }
2585 }
2586
2587 public void osNpcStopAnimation(LSL_Key npc, string animation)
2588 {
2589 CheckThreatLevel(ThreatLevel.High, "osNpcStopAnimation");
2590 m_host.AddScriptLPS(1);
2307 2591
2308 INPCModule module = World.RequestModuleInterface<INPCModule>(); 2592 INPCModule module = World.RequestModuleInterface<INPCModule>();
2309 if (module != null) 2593 if (module != null)
2310 { 2594 {
2311 module.DeleteNPC(new UUID(npc.m_string), World); 2595 UUID npcID = new UUID(npc.m_string);
2596
2597 if (module.CheckPermissions(npcID, m_host.OwnerID))
2598 AvatarPlayAnimation(npcID.ToString(), animation);
2312 } 2599 }
2313 } 2600 }
2314 2601
@@ -2320,6 +2607,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2320 public LSL_Key osOwnerSaveAppearance(string notecard) 2607 public LSL_Key osOwnerSaveAppearance(string notecard)
2321 { 2608 {
2322 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance"); 2609 CheckThreatLevel(ThreatLevel.High, "osOwnerSaveAppearance");
2610 m_host.AddScriptLPS(1);
2323 2611
2324 return SaveAppearanceToNotecard(m_host.OwnerID, notecard); 2612 return SaveAppearanceToNotecard(m_host.OwnerID, notecard);
2325 } 2613 }
@@ -2327,6 +2615,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2327 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard) 2615 public LSL_Key osAgentSaveAppearance(LSL_Key avatarId, string notecard)
2328 { 2616 {
2329 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance"); 2617 CheckThreatLevel(ThreatLevel.VeryHigh, "osAgentSaveAppearance");
2618 m_host.AddScriptLPS(1);
2330 2619
2331 return SaveAppearanceToNotecard(avatarId, notecard); 2620 return SaveAppearanceToNotecard(avatarId, notecard);
2332 } 2621 }
@@ -2377,6 +2666,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2377 public LSL_Key osGetMapTexture() 2666 public LSL_Key osGetMapTexture()
2378 { 2667 {
2379 CheckThreatLevel(ThreatLevel.None, "osGetMapTexture"); 2668 CheckThreatLevel(ThreatLevel.None, "osGetMapTexture");
2669 m_host.AddScriptLPS(1);
2670
2380 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString(); 2671 return m_ScriptEngine.World.RegionInfo.RegionSettings.TerrainImageID.ToString();
2381 } 2672 }
2382 2673
@@ -2388,6 +2679,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2388 public LSL_Key osGetRegionMapTexture(string regionName) 2679 public LSL_Key osGetRegionMapTexture(string regionName)
2389 { 2680 {
2390 CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture"); 2681 CheckThreatLevel(ThreatLevel.High, "osGetRegionMapTexture");
2682 m_host.AddScriptLPS(1);
2683
2391 Scene scene = m_ScriptEngine.World; 2684 Scene scene = m_ScriptEngine.World;
2392 UUID key = UUID.Zero; 2685 UUID key = UUID.Zero;
2393 GridRegion region; 2686 GridRegion region;
@@ -2453,6 +2746,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2453 public void osKickAvatar(string FirstName,string SurName,string alert) 2746 public void osKickAvatar(string FirstName,string SurName,string alert)
2454 { 2747 {
2455 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar"); 2748 CheckThreatLevel(ThreatLevel.Severe, "osKickAvatar");
2749 m_host.AddScriptLPS(1);
2750
2456 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID)) 2751 if (World.Permissions.CanRunConsoleCommand(m_host.OwnerID))
2457 { 2752 {
2458 World.ForEachRootScenePresence(delegate(ScenePresence sp) 2753 World.ForEachRootScenePresence(delegate(ScenePresence sp)
@@ -2587,6 +2882,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2587 public LSL_List osGetAvatarList() 2882 public LSL_List osGetAvatarList()
2588 { 2883 {
2589 CheckThreatLevel(ThreatLevel.None, "osGetAvatarList"); 2884 CheckThreatLevel(ThreatLevel.None, "osGetAvatarList");
2885 m_host.AddScriptLPS(1);
2590 2886
2591 LSL_List result = new LSL_List(); 2887 LSL_List result = new LSL_List();
2592 World.ForEachRootScenePresence(delegate (ScenePresence avatar) 2888 World.ForEachRootScenePresence(delegate (ScenePresence avatar)
@@ -2611,6 +2907,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2611 public LSL_String osUnixTimeToTimestamp(long time) 2907 public LSL_String osUnixTimeToTimestamp(long time)
2612 { 2908 {
2613 CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp"); 2909 CheckThreatLevel(ThreatLevel.VeryLow, "osUnixTimeToTimestamp");
2910 m_host.AddScriptLPS(1);
2911
2614 long baseTicks = 621355968000000000; 2912 long baseTicks = 621355968000000000;
2615 long tickResolution = 10000000; 2913 long tickResolution = 10000000;
2616 long epochTicks = (time * tickResolution) + baseTicks; 2914 long epochTicks = (time * tickResolution) + baseTicks;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 3eeb23d..3e0e452 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -26,10 +26,13 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Reflection;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31using OpenSim.Framework; 32using OpenSim.Framework;
33using log4net;
32 34
35using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes; 36using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.ScriptEngine.Shared; 37using OpenSim.Region.ScriptEngine.Shared;
35using OpenSim.Region.ScriptEngine.Shared.Api; 38using OpenSim.Region.ScriptEngine.Shared.Api;
@@ -51,6 +54,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
51 54
52 private const int AGENT = 1; 55 private const int AGENT = 1;
53 private const int AGENT_BY_USERNAME = 0x10; 56 private const int AGENT_BY_USERNAME = 0x10;
57 private const int NPC = 0x20;
54 private const int ACTIVE = 2; 58 private const int ACTIVE = 2;
55 private const int PASSIVE = 4; 59 private const int PASSIVE = 4;
56 private const int SCRIPTED = 8; 60 private const int SCRIPTED = 8;
@@ -203,7 +207,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
203 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 207 List<SensedEntity> sensedEntities = new List<SensedEntity>();
204 208
205 // Is the sensor type is AGENT and not SCRIPTED then include agents 209 // Is the sensor type is AGENT and not SCRIPTED then include agents
206 if ((ts.type & (AGENT | AGENT_BY_USERNAME)) != 0 && (ts.type & SCRIPTED) == 0) 210 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
207 { 211 {
208 sensedEntities.AddRange(doAgentSensor(ts)); 212 sensedEntities.AddRange(doAgentSensor(ts));
209 } 213 }
@@ -413,6 +417,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
413 417
414 private List<SensedEntity> doAgentSensor(SenseRepeatClass ts) 418 private List<SensedEntity> doAgentSensor(SenseRepeatClass ts)
415 { 419 {
420 INPCModule npcModule = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<INPCModule>();
421
416 List<SensedEntity> sensedEntities = new List<SensedEntity>(); 422 List<SensedEntity> sensedEntities = new List<SensedEntity>();
417 423
418 // If nobody about quit fast 424 // If nobody about quit fast
@@ -441,6 +447,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
441 447
442 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence) 448 Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence)
443 { 449 {
450 if ((ts.type & NPC) == 0
451 && presence.PresenceType == PresenceType.Npc
452 && !npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent)
453 return;
454
455 if ((ts.type & AGENT) == 0
456 && (presence.PresenceType == PresenceType.User
457 || npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent))
458 return;
459
444 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) 460 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
445 return; 461 return;
446 462
@@ -452,6 +468,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
452 toRegionPos = presence.AbsolutePosition; 468 toRegionPos = presence.AbsolutePosition;
453 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos)); 469 dis = Math.Abs(Util.GetDistanceTo(toRegionPos, fromRegionPos));
454 470
471 // Disabled for now since all osNpc* methods check for appropriate ownership permission.
472 // Perhaps could be re-enabled as an NPC setting at some point since being able to make NPCs not
473 // sensed might be useful.
474// if (presence.PresenceType == PresenceType.Npc && npcModule != null)
475// {
476// UUID npcOwner = npcModule.GetOwner(presence.UUID);
477// if (npcOwner != UUID.Zero && npcOwner != SensePoint.OwnerID)
478// return;
479// }
480
455 // are they in range 481 // are they in range
456 if (dis <= ts.range) 482 if (dis <= ts.range)
457 { 483 {
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 62e2854..b66537f 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -161,6 +161,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
161 LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param); 161 LSL_List llGetParcelDetails(LSL_Vector pos, LSL_List param);
162 LSL_Integer llGetParcelFlags(LSL_Vector pos); 162 LSL_Integer llGetParcelFlags(LSL_Vector pos);
163 LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide); 163 LSL_Integer llGetParcelMaxPrims(LSL_Vector pos, int sim_wide);
164 LSL_String llGetParcelMusicURL();
164 LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide); 165 LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide);
165 LSL_List llGetParcelPrimOwners(LSL_Vector pos); 166 LSL_List llGetParcelPrimOwners(LSL_Vector pos);
166 LSL_Integer llGetPermissions(); 167 LSL_Integer llGetPermissions();
@@ -241,6 +242,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
241 void llLoopSound(string sound, double volume); 242 void llLoopSound(string sound, double volume);
242 void llLoopSoundMaster(string sound, double volume); 243 void llLoopSoundMaster(string sound, double volume);
243 void llLoopSoundSlave(string sound, double volume); 244 void llLoopSoundSlave(string sound, double volume);
245 LSL_Integer llManageEstateAccess(int action, string avatar);
244 void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset); 246 void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset);
245 void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset); 247 void llMakeFire(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset);
246 void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset); 248 void llMakeFountain(int particles, double scale, double vel, double lifetime, double arc, int bounce, string texture, LSL_Vector offset, double bounce_offset);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
index 00ca070..dbc1dfc 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/IOSSL_Api.cs
@@ -42,6 +42,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
42{ 42{
43 public enum ThreatLevel 43 public enum ThreatLevel
44 { 44 {
45 NoAccess = -1,
45 None = 0, 46 None = 0,
46 Nuisance = 1, 47 Nuisance = 1,
47 VeryLow = 2, 48 VeryLow = 2,
@@ -159,6 +160,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
159 string osGetGridNick(); 160 string osGetGridNick();
160 string osGetGridName(); 161 string osGetGridName();
161 string osGetGridLoginURI(); 162 string osGetGridLoginURI();
163 string osGetGridHomeURI();
164 string osGetGridCustom(string key);
162 165
163 LSL_String osFormatString(string str, LSL_List strings); 166 LSL_String osFormatString(string str, LSL_List strings);
164 LSL_List osMatchString(string src, string pattern, int start); 167 LSL_List osMatchString(string src, string pattern, int start);
@@ -170,22 +173,42 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
170 173
171 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules); 174 LSL_List osGetLinkPrimitiveParams(int linknumber, LSL_List rules);
172 175
173 key osNpcCreate(string user, string name, vector position, string notecard); 176 /// <summary>
174 LSL_Key osNpcSaveAppearance(key npc, string notecard); 177 /// Check if the given key is an npc
175 void osNpcLoadAppearance(key npc, string notecard); 178 /// </summary>
176 vector osNpcGetPos(key npc); 179 /// <param name="npc"></param>
177 void osNpcMoveTo(key npc, vector position); 180 /// <returns>TRUE if the key belongs to an npc in the scene. FALSE otherwise.</returns>
178 void osNpcMoveToTarget(key npc, vector target, int options); 181 LSL_Integer osIsNpc(LSL_Key npc);
179 rotation osNpcGetRot(key npc); 182
180 void osNpcSetRot(LSL_Key npc, rotation rot); 183 key osNpcCreate(string user, string name, vector position, string notecard);
181 void osNpcStopMoveToTarget(LSL_Key npc); 184 key osNpcCreate(string user, string name, vector position, string notecard, int options);
182 void osNpcSay(key npc, string message); 185 LSL_Key osNpcSaveAppearance(key npc, string notecard);
183 void osNpcSit(key npc, key target, int options); 186 void osNpcLoadAppearance(key npc, string notecard);
184 void osNpcStand(LSL_Key npc); 187 vector osNpcGetPos(key npc);
185 void osNpcRemove(key npc); 188 void osNpcMoveTo(key npc, vector position);
186 189 void osNpcMoveToTarget(key npc, vector target, int options);
187 LSL_Key osOwnerSaveAppearance(string notecard); 190
188 LSL_Key osAgentSaveAppearance(key agentId, string notecard); 191 /// <summary>
192 /// Get the owner of the NPC
193 /// </summary>
194 /// <param name="npc"></param>
195 /// <returns>
196 /// The owner of the NPC for an owned NPC. The NPC's agent id for an unowned NPC. UUID.Zero if the key is not an npc.
197 /// </returns>
198 LSL_Key osNpcGetOwner(key npc);
199
200 rotation osNpcGetRot(key npc);
201 void osNpcSetRot(LSL_Key npc, rotation rot);
202 void osNpcStopMoveToTarget(LSL_Key npc);
203 void osNpcSay(key npc, string message);
204 void osNpcSit(key npc, key target, int options);
205 void osNpcStand(LSL_Key npc);
206 void osNpcRemove(key npc);
207 void osNpcPlayAnimation(LSL_Key npc, string animation);
208 void osNpcStopAnimation(LSL_Key npc, string animation);
209
210 LSL_Key osOwnerSaveAppearance(string notecard);
211 LSL_Key osAgentSaveAppearance(key agentId, string notecard);
189 212
190 key osGetMapTexture(); 213 key osGetMapTexture();
191 key osGetRegionMapTexture(string regionName); 214 key osGetRegionMapTexture(string regionName);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index fd08373..a69b4cb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -52,6 +52,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
52 public const int AGENT = 1; 52 public const int AGENT = 1;
53 public const int AGENT_BY_LEGACY_NAME = 1; 53 public const int AGENT_BY_LEGACY_NAME = 1;
54 public const int AGENT_BY_USERNAME = 0x10; 54 public const int AGENT_BY_USERNAME = 0x10;
55 public const int NPC = 0x20;
55 public const int ACTIVE = 2; 56 public const int ACTIVE = 2;
56 public const int PASSIVE = 4; 57 public const int PASSIVE = 4;
57 public const int SCRIPTED = 8; 58 public const int SCRIPTED = 8;
@@ -431,6 +432,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
431 public const int REGION_FLAG_ALLOW_DIRECT_TELEPORT = 0x100000; // region allows direct teleports 432 public const int REGION_FLAG_ALLOW_DIRECT_TELEPORT = 0x100000; // region allows direct teleports
432 public const int REGION_FLAG_RESTRICT_PUSHOBJECT = 0x400000; // region restricts llPushObject 433 public const int REGION_FLAG_RESTRICT_PUSHOBJECT = 0x400000; // region restricts llPushObject
433 434
435 //llManageEstateAccess
436 public const int ESTATE_ACCESS_ALLOWED_AGENT_ADD = 0;
437 public const int ESTATE_ACCESS_ALLOWED_AGENT_REMOVE = 1;
438 public const int ESTATE_ACCESS_ALLOWED_GROUP_ADD = 2;
439 public const int ESTATE_ACCESS_ALLOWED_GROUP_REMOVE = 3;
440 public const int ESTATE_ACCESS_BANNED_AGENT_ADD = 4;
441 public const int ESTATE_ACCESS_BANNED_AGENT_REMOVE = 5;
442
434 public static readonly LSLInteger PAY_HIDE = new LSLInteger(-1); 443 public static readonly LSLInteger PAY_HIDE = new LSLInteger(-1);
435 public static readonly LSLInteger PAY_DEFAULT = new LSLInteger(-2); 444 public static readonly LSLInteger PAY_DEFAULT = new LSLInteger(-2);
436 445
@@ -605,6 +614,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
605 614
606 public const int OS_NPC_SIT_NOW = 0; 615 public const int OS_NPC_SIT_NOW = 0;
607 616
617 public const int OS_NPC_CREATOR_OWNED = 0x1;
618 public const int OS_NPC_NOT_OWNED = 0x2;
619 public const int OS_NPC_SENSE_AS_AGENT = 0x4;
620
608 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; 621 public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
609 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; 622 public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
610 623
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index 508f33b..840d3a4 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -649,6 +649,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
649 return m_LSL_Functions.llGetParcelMaxPrims(pos, sim_wide); 649 return m_LSL_Functions.llGetParcelMaxPrims(pos, sim_wide);
650 } 650 }
651 651
652 public LSL_String llGetParcelMusicURL()
653 {
654 return m_LSL_Functions.llGetParcelMusicURL();
655 }
656
652 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide) 657 public LSL_Integer llGetParcelPrimCount(LSL_Vector pos, int category, int sim_wide)
653 { 658 {
654 return m_LSL_Functions.llGetParcelPrimCount(pos, category, sim_wide); 659 return m_LSL_Functions.llGetParcelPrimCount(pos, category, sim_wide);
@@ -1049,6 +1054,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
1049 m_LSL_Functions.llLoopSoundSlave(sound, volume); 1054 m_LSL_Functions.llLoopSoundSlave(sound, volume);
1050 } 1055 }
1051 1056
1057 public LSL_Integer llManageEstateAccess(int action, string avatar)
1058 {
1059 return m_LSL_Functions.llManageEstateAccess(action, avatar);
1060 }
1061
1052 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset) 1062 public void llMakeExplosion(int particles, double scale, double vel, double lifetime, double arc, string texture, LSL_Vector offset)
1053 { 1063 {
1054 m_LSL_Functions.llMakeExplosion(particles, scale, vel, lifetime, arc, texture, offset); 1064 m_LSL_Functions.llMakeExplosion(particles, scale, vel, lifetime, arc, texture, offset);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
index 0d7d5ea..cc8d417 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/OSSL_Stub.cs
@@ -452,6 +452,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
452 return m_OSSL_Functions.osGetGridLoginURI(); 452 return m_OSSL_Functions.osGetGridLoginURI();
453 } 453 }
454 454
455 public string osGetGridHomeURI()
456 {
457 return m_OSSL_Functions.osGetGridHomeURI();
458 }
459
460 public string osGetGridCustom(string key)
461 {
462 return m_OSSL_Functions.osGetGridCustom(key);
463 }
464
455 public LSL_String osFormatString(string str, LSL_List strings) 465 public LSL_String osFormatString(string str, LSL_List strings)
456 { 466 {
457 return m_OSSL_Functions.osFormatString(str, strings); 467 return m_OSSL_Functions.osFormatString(str, strings);
@@ -483,11 +493,21 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
483 return m_OSSL_Functions.osGetLinkPrimitiveParams(linknumber, rules); 493 return m_OSSL_Functions.osGetLinkPrimitiveParams(linknumber, rules);
484 } 494 }
485 495
496 public LSL_Integer osIsNpc(LSL_Key npc)
497 {
498 return m_OSSL_Functions.osIsNpc(npc);
499 }
500
486 public key osNpcCreate(string user, string name, vector position, key cloneFrom) 501 public key osNpcCreate(string user, string name, vector position, key cloneFrom)
487 { 502 {
488 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom); 503 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom);
489 } 504 }
490 505
506 public key osNpcCreate(string user, string name, vector position, key cloneFrom, int options)
507 {
508 return m_OSSL_Functions.osNpcCreate(user, name, position, cloneFrom, options);
509 }
510
491 public key osNpcSaveAppearance(key npc, string notecard) 511 public key osNpcSaveAppearance(key npc, string notecard)
492 { 512 {
493 return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard); 513 return m_OSSL_Functions.osNpcSaveAppearance(npc, notecard);
@@ -498,6 +518,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
498 m_OSSL_Functions.osNpcLoadAppearance(npc, notecard); 518 m_OSSL_Functions.osNpcLoadAppearance(npc, notecard);
499 } 519 }
500 520
521 public LSL_Key osNpcGetOwner(LSL_Key npc)
522 {
523 return m_OSSL_Functions.osNpcGetOwner(npc);
524 }
525
501 public vector osNpcGetPos(LSL_Key npc) 526 public vector osNpcGetPos(LSL_Key npc)
502 { 527 {
503 return m_OSSL_Functions.osNpcGetPos(npc); 528 return m_OSSL_Functions.osNpcGetPos(npc);
@@ -548,6 +573,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
548 m_OSSL_Functions.osNpcRemove(npc); 573 m_OSSL_Functions.osNpcRemove(npc);
549 } 574 }
550 575
576 public void osNpcPlayAnimation(LSL_Key npc, string animation)
577 {
578 m_OSSL_Functions.osNpcPlayAnimation(npc, animation);
579 }
580
581 public void osNpcStopAnimation(LSL_Key npc, string animation)
582 {
583 m_OSSL_Functions.osNpcStopAnimation(npc, animation);
584 }
585
551 public LSL_Key osOwnerSaveAppearance(string notecard) 586 public LSL_Key osOwnerSaveAppearance(string notecard)
552 { 587 {
553 return m_OSSL_Functions.osOwnerSaveAppearance(notecard); 588 return m_OSSL_Functions.osOwnerSaveAppearance(notecard);
@@ -818,4 +853,4 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
818 return m_OSSL_Functions.osUnixTimeToTimestamp(time); 853 return m_OSSL_Functions.osUnixTimeToTimestamp(time);
819 } 854 }
820 } 855 }
821} \ No newline at end of file 856}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
index f9d6eee..9b93135 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Instance/ScriptInstance.cs
@@ -55,7 +55,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
55{ 55{
56 public class ScriptInstance : MarshalByRefObject, IScriptInstance 56 public class ScriptInstance : MarshalByRefObject, IScriptInstance
57 { 57 {
58// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 58 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
59 59
60 private IScriptEngine m_Engine; 60 private IScriptEngine m_Engine;
61 private IScriptWorkItem m_CurrentResult = null; 61 private IScriptWorkItem m_CurrentResult = null;
@@ -109,7 +109,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
109 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>(); 109 private Dictionary<string,IScriptApi> m_Apis = new Dictionary<string,IScriptApi>();
110 110
111 // Script state 111 // Script state
112 private string m_State="default"; 112 private string m_State = "default";
113 113
114 public Object[] PluginData = new Object[0]; 114 public Object[] PluginData = new Object[0];
115 115
@@ -127,6 +127,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
127 m_minEventDelay = value; 127 m_minEventDelay = value;
128 else 128 else
129 m_minEventDelay = 0.0; 129 m_minEventDelay = 0.0;
130
130 m_eventDelayTicks = (long)(m_minEventDelay * 10000000L); 131 m_eventDelayTicks = (long)(m_minEventDelay * 10000000L);
131 m_nextEventTimeTicks = DateTime.Now.Ticks; 132 m_nextEventTimeTicks = DateTime.Now.Ticks;
132 } 133 }
@@ -296,9 +297,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
296 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass); 297 //RemotingServices.GetLifetimeService(m_Script as ScriptBaseClass);
297// lease.Register(this); 298// lease.Register(this);
298 } 299 }
299 catch (Exception) 300 catch (Exception e)
300 { 301 {
301 // m_log.ErrorFormat("[Script] Error loading assembly {0}\n"+e.ToString(), assembly); 302 m_log.ErrorFormat(
303 "[SCRIPT INSTANCE]: Error loading assembly {0}. Exception {1}{2}",
304 assembly, e.Message, e.StackTrace);
302 } 305 }
303 306
304 try 307 try
@@ -313,9 +316,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
313 part.SetScriptEvents(m_ItemID, 316 part.SetScriptEvents(m_ItemID,
314 (int)m_Script.GetStateEventFlags(State)); 317 (int)m_Script.GetStateEventFlags(State));
315 } 318 }
316 catch (Exception) 319 catch (Exception e)
317 { 320 {
318 // m_log.Error("[Script] Error loading script instance\n"+e.ToString()); 321 m_log.ErrorFormat(
322 "[SCRIPT INSTANCE]: Error loading script instance from assembly {0}. Exception {1}{2}",
323 assembly, e.Message, e.StackTrace);
324
319 return; 325 return;
320 } 326 }
321 327
@@ -377,12 +383,16 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
377 } 383 }
378 else 384 else
379 { 385 {
380 // m_log.Error("[Script] Unable to load script state: Memory limit exceeded"); 386 m_log.ErrorFormat(
387 "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}: Memory limit exceeded",
388 assembly);
381 } 389 }
382 } 390 }
383 catch (Exception) 391 catch (Exception e)
384 { 392 {
385 // m_log.ErrorFormat("[Script] Unable to load script state from xml: {0}\n"+e.ToString(), xml); 393 m_log.ErrorFormat(
394 "[SCRIPT INSTANCE]: Unable to load script state from assembly {0}. XML is {1}. Exception {2}{3}",
395 assembly, xml, e.Message, e.StackTrace);
386 } 396 }
387 } 397 }
388// else 398// else
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
index 0cbad41..3baa723 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/LSL_ApiTest.cs
@@ -75,32 +75,49 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
75 [Test] 75 [Test]
76 public void TestllAngleBetween() 76 public void TestllAngleBetween()
77 { 77 {
78 CheckllAngleBetween(new Vector3(1, 0, 0), 0); 78 CheckllAngleBetween(new Vector3(1, 0, 0), 0, 1, 1);
79 CheckllAngleBetween(new Vector3(1, 0, 0), 90); 79 CheckllAngleBetween(new Vector3(1, 0, 0), 90, 1, 1);
80 CheckllAngleBetween(new Vector3(1, 0, 0), 180); 80 CheckllAngleBetween(new Vector3(1, 0, 0), 180, 1, 1);
81 81
82 CheckllAngleBetween(new Vector3(0, 1, 0), 0); 82 CheckllAngleBetween(new Vector3(0, 1, 0), 0, 1, 1);
83 CheckllAngleBetween(new Vector3(0, 1, 0), 90); 83 CheckllAngleBetween(new Vector3(0, 1, 0), 90, 1, 1);
84 CheckllAngleBetween(new Vector3(0, 1, 0), 180); 84 CheckllAngleBetween(new Vector3(0, 1, 0), 180, 1, 1);
85 85
86 CheckllAngleBetween(new Vector3(0, 0, 1), 0); 86 CheckllAngleBetween(new Vector3(0, 0, 1), 0, 1, 1);
87 CheckllAngleBetween(new Vector3(0, 0, 1), 90); 87 CheckllAngleBetween(new Vector3(0, 0, 1), 90, 1, 1);
88 CheckllAngleBetween(new Vector3(0, 0, 1), 180); 88 CheckllAngleBetween(new Vector3(0, 0, 1), 180, 1, 1);
89 89
90 CheckllAngleBetween(new Vector3(1, 1, 1), 0); 90 CheckllAngleBetween(new Vector3(1, 1, 1), 0, 1, 1);
91 CheckllAngleBetween(new Vector3(1, 1, 1), 90); 91 CheckllAngleBetween(new Vector3(1, 1, 1), 90, 1, 1);
92 CheckllAngleBetween(new Vector3(1, 1, 1), 180); 92 CheckllAngleBetween(new Vector3(1, 1, 1), 180, 1, 1);
93
94 CheckllAngleBetween(new Vector3(1, 0, 0), 0, 1.6f, 1.8f);
95 CheckllAngleBetween(new Vector3(1, 0, 0), 90, 0.3f, 3.9f);
96 CheckllAngleBetween(new Vector3(1, 0, 0), 180, 8.8f, 7.4f);
97
98 CheckllAngleBetween(new Vector3(0, 1, 0), 0, 9.8f, -9.4f);
99 CheckllAngleBetween(new Vector3(0, 1, 0), 90, 8.4f, -8.2f);
100 CheckllAngleBetween(new Vector3(0, 1, 0), 180, 0.4f, -5.8f);
101
102 CheckllAngleBetween(new Vector3(0, 0, 1), 0, -6.8f, 3.4f);
103 CheckllAngleBetween(new Vector3(0, 0, 1), 90, -3.6f, 5.6f);
104 CheckllAngleBetween(new Vector3(0, 0, 1), 180, -3.8f, 1.1f);
105
106 CheckllAngleBetween(new Vector3(1, 1, 1), 0, -7.7f, -2.0f);
107 CheckllAngleBetween(new Vector3(1, 1, 1), 90, -3.0f, -9.1f);
108 CheckllAngleBetween(new Vector3(1, 1, 1), 180, -7.9f, -8.0f);
93 } 109 }
94 110
95 private void CheckllAngleBetween(Vector3 axis,float originalAngle) 111 private void CheckllAngleBetween(Vector3 axis,float originalAngle, float denorm1, float denorm2)
96 { 112 {
97 Quaternion rotation1 = Quaternion.CreateFromAxisAngle(axis, 0); 113 Quaternion rotation1 = Quaternion.CreateFromAxisAngle(axis, 0);
98 Quaternion rotation2 = Quaternion.CreateFromAxisAngle(axis, ToRadians(originalAngle)); 114 Quaternion rotation2 = Quaternion.CreateFromAxisAngle(axis, ToRadians(originalAngle));
115 rotation1 *= denorm1;
116 rotation2 *= denorm2;
99 117
100 double deducedAngle = FromLslFloat(m_lslApi.llAngleBetween(ToLslQuaternion(rotation2), ToLslQuaternion(rotation1))); 118 double deducedAngle = FromLslFloat(m_lslApi.llAngleBetween(ToLslQuaternion(rotation2), ToLslQuaternion(rotation1)));
101 119
102 Assert.Greater(deducedAngle, ToRadians(originalAngle) - ANGLE_ACCURACY_IN_RADIANS); 120 Assert.That(deducedAngle, Is.EqualTo(ToRadians(originalAngle)).Within(ANGLE_ACCURACY_IN_RADIANS), "TestllAngleBetween check fail");
103 Assert.Less(deducedAngle, ToRadians(originalAngle) + ANGLE_ACCURACY_IN_RADIANS);
104 } 121 }
105 122
106 #region Conversions to and from LSL_Types 123 #region Conversions to and from LSL_Types
@@ -142,30 +159,97 @@ namespace OpenSim.Region.ScriptEngine.Shared.Tests
142 public void TestllRot2Euler() 159 public void TestllRot2Euler()
143 { 160 {
144 // 180, 90 and zero degree rotations. 161 // 180, 90 and zero degree rotations.
145 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 0.0f, 0.0f, 0.0f), new LSL_Types.Vector3(Math.PI, 0.0f, 0.0f)); 162 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.0f, 1.0f));
146 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 1.0f, 0.0f, 0.0f), new LSL_Types.Vector3(Math.PI, 0.0f, Math.PI)); 163 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.707107f, 0.707107f));
147 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 1.0f, 0.0f), new LSL_Types.Vector3(0.0f, 0.0f, Math.PI)); 164 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 1.0f, 0.0f));
148 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.0f, 1.0f), new LSL_Types.Vector3(0.0f, 0.0f, 0.0f)); 165 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, 0.0f, 0.707107f, -0.707107f));
149 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, 0.5f, 0.5f), new LSL_Types.Vector3(0, -Math.PI / 2.0f, Math.PI / 2.0f)); 166 CheckllRot2Euler(new LSL_Types.Quaternion(0.707107f, 0.0f, 0.0f, 0.707107f));
150 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, 0.0f, 0.0f, -0.707107f), new LSL_Types.Vector3(Math.PI / 2.0f, 0.0f, 0.0f)); 167 CheckllRot2Euler(new LSL_Types.Quaternion(0.5f, -0.5f, 0.5f, 0.5f));
168 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, 0.707107f, 0.0f));
169 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, 0.5f, -0.5f));
170 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 0.0f, 0.0f, 0.0f));
171 CheckllRot2Euler(new LSL_Types.Quaternion(0.707107f, -0.707107f, 0.0f, 0.0f));
172 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -1.0f, 0.0f, 0.0f));
173 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, -0.707107f, 0.0f, 0.0f));
174 CheckllRot2Euler(new LSL_Types.Quaternion(0.707107f, 0.0f, 0.0f, -0.707107f));
175 CheckllRot2Euler(new LSL_Types.Quaternion(0.5f, -0.5f, -0.5f, -0.5f));
176 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, -0.707107f, 0.0f));
177 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, -0.5f, 0.5f));
178 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, 0.0f, 0.707107f));
179 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, 0.5f, 0.5f));
180 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, 0.0f, 0.707107f, 0.0f));
181 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, 0.5f, 0.5f, -0.5f));
182 CheckllRot2Euler(new LSL_Types.Quaternion(0.0f, -0.707107f, 0.0f, -0.707107f));
183 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, -0.5f, -0.5f, -0.5f));
184 CheckllRot2Euler(new LSL_Types.Quaternion(-0.707107f, 0.0f, -0.707107f, 0.0f));
185 CheckllRot2Euler(new LSL_Types.Quaternion(-0.5f, 0.5f, -0.5f, 0.5f));
186
151 // A couple of messy rotations. 187 // A couple of messy rotations.
152 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 5.651f, -3.1f, 67.023f), new LSL_Types.Vector3(0.037818f, 0.166447f, -0.095595f)); 188 CheckllRot2Euler(new LSL_Types.Quaternion(1.0f, 5.651f, -3.1f, 67.023f));
153 CheckllRot2Euler(new LSL_Types.Quaternion(0.719188f, -0.408934f, -0.363998f, -0.427841f), new LSL_Types.Vector3(-1.954769f, -0.174533f, 1.151917f)); 189 CheckllRot2Euler(new LSL_Types.Quaternion(0.719188f, -0.408934f, -0.363998f, -0.427841f));
190
191 // Some deliberately malicious rotations (intended on provoking singularity errors)
192 // The "f" suffexes are deliberately omitted.
193 CheckllRot2Euler(new LSL_Types.Quaternion(0.50001f, 0.50001f, 0.50001f, 0.50001f));
194 // More malice. The "f" suffixes are deliberately omitted.
195 CheckllRot2Euler(new LSL_Types.Quaternion(-0.701055, 0.092296, 0.701055, -0.092296));
196 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183005, -0.683010, 0.183005, 0.683010));
197 CheckllRot2Euler(new LSL_Types.Quaternion(-0.430460, -0.560982, 0.430460, 0.560982));
198 CheckllRot2Euler(new LSL_Types.Quaternion(-0.701066, 0.092301, -0.701066, 0.092301));
199 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183013, -0.683010, 0.183013, 0.683010));
200 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183005, -0.683014, -0.183005, -0.683014));
201 CheckllRot2Euler(new LSL_Types.Quaternion(-0.353556, 0.612375, 0.353556, -0.612375));
202 CheckllRot2Euler(new LSL_Types.Quaternion(0.353554, -0.612385, -0.353554, 0.612385));
203 CheckllRot2Euler(new LSL_Types.Quaternion(-0.560989, 0.430450, 0.560989, -0.430450));
204 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183013, 0.683009, -0.183013, 0.683009));
205 CheckllRot2Euler(new LSL_Types.Quaternion(0.430457, -0.560985, -0.430457, 0.560985));
206 CheckllRot2Euler(new LSL_Types.Quaternion(0.353552, 0.612360, -0.353552, -0.612360));
207 CheckllRot2Euler(new LSL_Types.Quaternion(-0.499991, 0.500003, 0.499991, -0.500003));
208 CheckllRot2Euler(new LSL_Types.Quaternion(-0.353555, -0.612385, -0.353555, -0.612385));
209 CheckllRot2Euler(new LSL_Types.Quaternion(0.701066, -0.092301, -0.701066, 0.092301));
210 CheckllRot2Euler(new LSL_Types.Quaternion(-0.499991, 0.500007, 0.499991, -0.500007));
211 CheckllRot2Euler(new LSL_Types.Quaternion(-0.683002, 0.183016, -0.683002, 0.183016));
212 CheckllRot2Euler(new LSL_Types.Quaternion(0.430458, 0.560982, 0.430458, 0.560982));
213 CheckllRot2Euler(new LSL_Types.Quaternion(0.499991, -0.500003, -0.499991, 0.500003));
214 CheckllRot2Euler(new LSL_Types.Quaternion(-0.183009, 0.683011, -0.183009, 0.683011));
215 CheckllRot2Euler(new LSL_Types.Quaternion(0.560975, -0.430457, 0.560975, -0.430457));
216 CheckllRot2Euler(new LSL_Types.Quaternion(0.701055, 0.092300, 0.701055, 0.092300));
217 CheckllRot2Euler(new LSL_Types.Quaternion(-0.560990, 0.430459, -0.560990, 0.430459));
218 CheckllRot2Euler(new LSL_Types.Quaternion(-0.092302, -0.701059, -0.092302, -0.701059));
154 } 219 }
155 220
156 private void CheckllRot2Euler(LSL_Types.Quaternion rot, LSL_Types.Vector3 eulerCheck) 221 /// <summary>
222 /// Check an llRot2Euler conversion.
223 /// </summary>
224 /// <remarks>
225 /// Testing Rot2Euler this way instead of comparing against expected angles because
226 /// 1. There are several ways to get to the original Quaternion. For example a rotation
227 /// of PI and -PI will give the same result. But PI and -PI aren't equal.
228 /// 2. This method checks to see if the calculated angles from a quaternion can be used
229 /// to create a new quaternion to produce the same rotation.
230 /// However, can't compare the newly calculated quaternion against the original because
231 /// once again, there are multiple quaternions that give the same result. For instance
232 /// <X, Y, Z, S> == <-X, -Y, -Z, -S>. Additionally, the magnitude of S can be changed
233 /// and will still result in the same rotation if the values for X, Y, Z are also changed
234 /// to compensate.
235 /// However, if two quaternions represent the same rotation, then multiplying the first
236 /// quaternion by the conjugate of the second, will give a third quaternion representing
237 /// a zero rotation. This can be tested for by looking at the X, Y, Z values which should
238 /// be zero.
239 /// </remarks>
240 /// <param name="rot"></param>
241 private void CheckllRot2Euler(LSL_Types.Quaternion rot)
157 { 242 {
158 // Call LSL function to convert quaternion rotaion to euler radians. 243 // Call LSL function to convert quaternion rotaion to euler radians.
159 LSL_Types.Vector3 eulerCalc = m_lslApi.llRot2Euler(rot); 244 LSL_Types.Vector3 eulerCalc = m_lslApi.llRot2Euler(rot);
160 // Check upper and lower bounds of x, y and z. 245 // Now use the euler radians to recalculate a new quaternion rotation
161 // This type of check is performed as opposed to comparing for equal numbers, in order to allow slight 246 LSL_Types.Quaternion newRot = m_lslApi.llEuler2Rot(eulerCalc);
162 // differences in accuracy. 247 // Multiple original quaternion by conjugate of quaternion calculated with angles.
163 Assert.Greater(eulerCalc.x, eulerCheck.x - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler X lower bounds check fail"); 248 LSL_Types.Quaternion check = rot * new LSL_Types.Quaternion(-newRot.x, -newRot.y, -newRot.z, newRot.s);
164 Assert.Less(eulerCalc.x, eulerCheck.x + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler X upper bounds check fail"); 249
165 Assert.Greater(eulerCalc.y, eulerCheck.y - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Y lower bounds check fail"); 250 Assert.AreEqual(0.0, check.x, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler X bounds check fail");
166 Assert.Less(eulerCalc.y, eulerCheck.y + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Y upper bounds check fail"); 251 Assert.AreEqual(0.0, check.y, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler Y bounds check fail");
167 Assert.Greater(eulerCalc.z, eulerCheck.z - ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z lower bounds check fail"); 252 Assert.AreEqual(0.0, check.z, VECTOR_COMPONENT_ACCURACY, "TestllRot2Euler Z bounds check fail");
168 Assert.Less(eulerCalc.z, eulerCheck.z + ANGLE_ACCURACY_IN_RADIANS, "TestllRot2Euler Z upper bounds check fail");
169 } 253 }
170 254
171 [Test] 255 [Test]
diff --git a/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
new file mode 100644
index 0000000..9d9fc51
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Shared/Tests/OSSL_ApiNpcTests.cs
@@ -0,0 +1,170 @@
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.Collections.Generic;
30using System.Reflection;
31using System.Text;
32using log4net;
33using Nini.Config;
34using NUnit.Framework;
35using OpenMetaverse;
36using OpenMetaverse.Assets;
37using OpenMetaverse.StructuredData;
38using OpenSim.Framework;
39using OpenSim.Region.CoreModules.Avatar.AvatarFactory;
40using OpenSim.Region.OptionalModules.World.NPC;
41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.ScriptEngine.Shared;
43using OpenSim.Region.ScriptEngine.Shared.Api;
44using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
45using OpenSim.Services.Interfaces;
46using OpenSim.Tests.Common;
47using OpenSim.Tests.Common.Mock;
48
49namespace OpenSim.Region.ScriptEngine.Shared.Tests
50{
51 /// <summary>
52 /// Tests for OSSL NPC API
53 /// </summary>
54 [TestFixture]
55 public class OSSL_NpcApiAppearanceTest
56 {
57 protected Scene m_scene;
58 protected XEngine.XEngine m_engine;
59
60 [SetUp]
61 public void SetUp()
62 {
63 IConfigSource initConfigSource = new IniConfigSource();
64 IConfig config = initConfigSource.AddConfig("XEngine");
65 config.Set("Enabled", "true");
66 config.Set("AllowOSFunctions", "true");
67 config.Set("OSFunctionThreatLevel", "Severe");
68 config = initConfigSource.AddConfig("NPC");
69 config.Set("Enabled", "true");
70
71 m_scene = SceneHelpers.SetupScene();
72 SceneHelpers.SetupSceneModules(m_scene, initConfigSource, new AvatarFactoryModule(), new NPCModule());
73
74 m_engine = new XEngine.XEngine();
75 m_engine.Initialise(initConfigSource);
76 m_engine.AddRegion(m_scene);
77 }
78
79 /// <summary>
80 /// Test removal of an owned NPC.
81 /// </summary>
82 [Test]
83 public void TestOsNpcRemoveOwned()
84 {
85 TestHelpers.InMethod();
86// log4net.Config.XmlConfigurator.Configure();
87
88 // Store an avatar with a different height from default in a notecard.
89 UUID userId = TestHelpers.ParseTail(0x1);
90 UUID otherUserId = TestHelpers.ParseTail(0x2);
91 float newHeight = 1.9f;
92
93 SceneHelpers.AddScenePresence(m_scene, otherUserId);
94
95 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
96 sp.Appearance.AvatarHeight = newHeight;
97
98 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
99 SceneObjectPart part = so.RootPart;
100 m_scene.AddSceneObject(so);
101
102 SceneObjectGroup otherSo = SceneHelpers.CreateSceneObject(1, otherUserId);
103 SceneObjectPart otherPart = otherSo.RootPart;
104 m_scene.AddSceneObject(otherSo);
105
106 OSSL_Api osslApi = new OSSL_Api();
107 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
108
109 OSSL_Api otherOsslApi = new OSSL_Api();
110 otherOsslApi.Initialize(m_engine, otherPart, otherPart.LocalId, otherPart.UUID);
111
112 string notecardName = "appearanceNc";
113 osslApi.osOwnerSaveAppearance(notecardName);
114
115 string npcRaw
116 = osslApi.osNpcCreate(
117 "Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName, ScriptBaseClass.OS_NPC_CREATOR_OWNED);
118
119 otherOsslApi.osNpcRemove(npcRaw);
120
121 // Should still be around
122 UUID npcId = new UUID(npcRaw);
123 ScenePresence npc = m_scene.GetScenePresence(npcId);
124 Assert.That(npc, Is.Not.Null);
125
126 osslApi.osNpcRemove(npcRaw);
127
128 npc = m_scene.GetScenePresence(npcId);
129
130 // Now the owner deleted it and it's gone
131 Assert.That(npc, Is.Null);
132 }
133
134 /// <summary>
135 /// Test removal of an unowned NPC.
136 /// </summary>
137 [Test]
138 public void TestOsNpcRemoveUnowned()
139 {
140 TestHelpers.InMethod();
141// log4net.Config.XmlConfigurator.Configure();
142
143 // Store an avatar with a different height from default in a notecard.
144 UUID userId = TestHelpers.ParseTail(0x1);
145 float newHeight = 1.9f;
146
147 ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, userId);
148 sp.Appearance.AvatarHeight = newHeight;
149 SceneObjectGroup so = SceneHelpers.CreateSceneObject(1, userId);
150 SceneObjectPart part = so.RootPart;
151 m_scene.AddSceneObject(so);
152
153 OSSL_Api osslApi = new OSSL_Api();
154 osslApi.Initialize(m_engine, part, part.LocalId, part.UUID);
155
156 string notecardName = "appearanceNc";
157 osslApi.osOwnerSaveAppearance(notecardName);
158
159 string npcRaw
160 = osslApi.osNpcCreate(
161 "Jane", "Doe", new LSL_Types.Vector3(128, 128, 128), notecardName, ScriptBaseClass.OS_NPC_NOT_OWNED);
162
163 osslApi.osNpcRemove(npcRaw);
164
165 UUID npcId = new UUID(npcRaw);
166 ScenePresence npc = m_scene.GetScenePresence(npcId);
167 Assert.That(npc, Is.Null);
168 }
169 }
170} \ No newline at end of file