aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs150
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs89
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs139
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs12
6 files changed, 237 insertions, 163 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 8ed250d..161feda 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -1549,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1549 1549
1550 public void SendKillObject(ulong regionHandle, List<uint> localIDs) 1550 public void SendKillObject(ulong regionHandle, List<uint> localIDs)
1551 { 1551 {
1552// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); 1552// foreach (uint id in localIDs)
1553// m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle);
1553 1554
1554 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); 1555 KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject);
1555 // TODO: don't create new blocks if recycling an old packet 1556 // TODO: don't create new blocks if recycling an old packet
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index f1399af..9a6dfe1 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -681,11 +681,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
681 681
682 #region Agent Crossings 682 #region Agent Crossings
683 683
684 public bool Cross(ScenePresence agent, bool isFlying) 684 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
685 { 685 {
686 Scene scene = agent.Scene; 686 version = String.Empty;
687 Vector3 pos = agent.AbsolutePosition; 687 newpos = new Vector3(pos.X, pos.Y, pos.Z);
688 Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z);
689 uint neighbourx = scene.RegionInfo.RegionLocX; 688 uint neighbourx = scene.RegionInfo.RegionLocX;
690 uint neighboury = scene.RegionInfo.RegionLocY; 689 uint neighboury = scene.RegionInfo.RegionLocY;
691 const float boundaryDistance = 1.7f; 690 const float boundaryDistance = 1.7f;
@@ -706,53 +705,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
706 } 705 }
707 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 706 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
708 { 707 {
709 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 708 neighboury--;
710 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 709 newpos.Y = Constants.RegionSize - enterDistance;
711 {
712 neighboury--;
713 newpos.Y = Constants.RegionSize - enterDistance;
714 }
715 else
716 {
717 agent.IsInTransit = true;
718
719 neighboury = b.TriggerRegionY;
720 neighbourx = b.TriggerRegionX;
721
722 Vector3 newposition = pos;
723 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
724 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
725 agent.ControllingClient.SendAgentAlertMessage(
726 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
727 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
728 return true;
729 }
730 }
731
732 Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W);
733 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0)
734 {
735 neighbourx--;
736 newpos.X = Constants.RegionSize - enterDistance;
737 } 710 }
738 else
739 {
740 agent.IsInTransit = true;
741
742 neighboury = ba.TriggerRegionY;
743 neighbourx = ba.TriggerRegionX;
744
745
746 Vector3 newposition = pos;
747 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
748 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
749 agent.ControllingClient.SendAgentAlertMessage(
750 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
751 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
752 711
753 712 neighbourx--;
754 return true; 713 newpos.X = Constants.RegionSize - enterDistance;
755 }
756 714
757 } 715 }
758 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) 716 else if (scene.TestBorderCross(pos + eastCross, Cardinals.E))
@@ -763,26 +721,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
763 721
764 if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 722 if (scene.TestBorderCross(pos + southCross, Cardinals.S))
765 { 723 {
766 Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 724 neighboury--;
767 if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) 725 newpos.Y = Constants.RegionSize - enterDistance;
768 {
769 neighboury--;
770 newpos.Y = Constants.RegionSize - enterDistance;
771 }
772 else
773 {
774 agent.IsInTransit = true;
775
776 neighboury = ba.TriggerRegionY;
777 neighbourx = ba.TriggerRegionX;
778 Vector3 newposition = pos;
779 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
780 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
781 agent.ControllingClient.SendAgentAlertMessage(
782 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
783 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
784 return true;
785 }
786 } 726 }
787 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 727 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
788 { 728 {
@@ -790,35 +730,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
790 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); 730 neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize);
791 newpos.Y = enterDistance; 731 newpos.Y = enterDistance;
792 } 732 }
793
794
795 } 733 }
796 else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) 734 else if (scene.TestBorderCross(pos + southCross, Cardinals.S))
797 { 735 {
798 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); 736 Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S);
799 if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) 737 neighboury--;
800 { 738 newpos.Y = Constants.RegionSize - enterDistance;
801 neighboury--;
802 newpos.Y = Constants.RegionSize - enterDistance;
803 }
804 else
805 {
806 agent.IsInTransit = true;
807
808 neighboury = b.TriggerRegionY;
809 neighbourx = b.TriggerRegionX;
810 Vector3 newposition = pos;
811 newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize;
812 newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize;
813 agent.ControllingClient.SendAgentAlertMessage(
814 String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false);
815 InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene);
816 return true;
817 }
818 } 739 }
819 else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) 740 else if (scene.TestBorderCross(pos + northCross, Cardinals.N))
820 { 741 {
821
822 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); 742 Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N);
823 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); 743 neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize);
824 newpos.Y = enterDistance; 744 newpos.Y = enterDistance;
@@ -849,19 +769,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
849 } 769 }
850 */ 770 */
851 771
852 ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); 772 xDest = neighbourx;
773 yDest = neighboury;
853 774
854 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); 775 int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize);
855 776
777 ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y);
778
856 ExpiringCache<ulong, DateTime> r; 779 ExpiringCache<ulong, DateTime> r;
857 DateTime banUntil; 780 DateTime banUntil;
858 781
859 if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) 782 if (m_bannedRegions.TryGetValue(agentID, out r))
860 { 783 {
861 if (r.TryGetValue(neighbourHandle, out banUntil)) 784 if (r.TryGetValue(neighbourHandle, out banUntil))
862 { 785 {
863 if (DateTime.Now < banUntil) 786 if (DateTime.Now < banUntil)
864 return false; 787 return null;
865 r.Remove(neighbourHandle); 788 r.Remove(neighbourHandle);
866 } 789 }
867 } 790 }
@@ -873,28 +796,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
873 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); 796 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y);
874 797
875 string reason; 798 string reason;
876 string version; 799 if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason))
877 if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason))
878 { 800 {
879 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
880 if (r == null) 801 if (r == null)
881 { 802 {
882 r = new ExpiringCache<ulong, DateTime>(); 803 r = new ExpiringCache<ulong, DateTime>();
883 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 804 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
884 805
885 m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); 806 m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45));
886 } 807 }
887 else 808 else
888 { 809 {
889 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 810 r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15));
890 } 811 }
812 return null;
813 }
814
815 return neighbourRegion;
816 }
817
818 public bool Cross(ScenePresence agent, bool isFlying)
819 {
820 uint x;
821 uint y;
822 Vector3 newpos;
823 string version;
824
825 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos);
826 if (neighbourRegion == null)
827 {
828 agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel");
891 return false; 829 return false;
892 } 830 }
893 831
894 agent.IsInTransit = true; 832 agent.IsInTransit = true;
895 833
896 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 834 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync;
897 d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); 835 d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d);
898 836
899 return true; 837 return true;
900 } 838 }
@@ -951,13 +889,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
951 icon.EndInvoke(iar); 889 icon.EndInvoke(iar);
952 } 890 }
953 891
954 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
955
956 /// <summary> 892 /// <summary>
957 /// This Closes child agents on neighbouring regions 893 /// This Closes child agents on neighbouring regions
958 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 894 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
959 /// </summary> 895 /// </summary>
960 protected ScenePresence CrossAgentToNewRegionAsync( 896 public ScenePresence CrossAgentToNewRegionAsync(
961 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, 897 ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion,
962 bool isFlying, string version) 898 bool isFlying, string version)
963 { 899 {
@@ -1731,17 +1667,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1731 { 1667 {
1732 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID); 1668 m_log.InfoFormat("[ENTITY TRANSFER MODULE] cross region transfer failed for object {0}",grp.UUID);
1733 1669
1670 // Need to turn off the physics flags, otherwise the object will continue to attempt to
1671 // move out of the region creating an infinite loop of failed attempts to cross
1672 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
1673
1734 // We are going to move the object back to the old position so long as the old position 1674 // We are going to move the object back to the old position so long as the old position
1735 // is in the region 1675 // is in the region
1736 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1); 1676 oldGroupPosition.X = Util.Clamp<float>(oldGroupPosition.X,1.0f,(float)Constants.RegionSize-1);
1737 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1); 1677 oldGroupPosition.Y = Util.Clamp<float>(oldGroupPosition.Y,1.0f,(float)Constants.RegionSize-1);
1738 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f); 1678 oldGroupPosition.Z = Util.Clamp<float>(oldGroupPosition.Z,1.0f,4096.0f);
1739 1679
1740 grp.RootPart.GroupPosition = oldGroupPosition; 1680 grp.AbsolutePosition = oldGroupPosition;
1741
1742 // Need to turn off the physics flags, otherwise the object will continue to attempt to
1743 // move out of the region creating an infinite loop of failed attempts to cross
1744 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
1745 1681
1746 grp.ScheduleGroupForFullUpdate(); 1682 grp.ScheduleGroupForFullUpdate();
1747 } 1683 }
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
index c38ecd9..76f1641 100644
--- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes;
35 35
36namespace OpenSim.Region.Framework.Interfaces 36namespace OpenSim.Region.Framework.Interfaces
37{ 37{
38 public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
39
38 public interface IEntityTransferModule 40 public interface IEntityTransferModule
39 { 41 {
40 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, 42 void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position,
@@ -53,7 +55,12 @@ namespace OpenSim.Region.Framework.Interfaces
53 55
54 void EnableChildAgent(ScenePresence agent, GridRegion region); 56 void EnableChildAgent(ScenePresence agent, GridRegion region);
55 57
58 GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos);
59
56 void Cross(SceneObjectGroup sog, Vector3 position, bool silent); 60 void Cross(SceneObjectGroup sog, Vector3 position, bool silent);
61
62 ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version);
63
57 } 64 }
58 65
59 public interface IUserAgentVerificationModule 66 public interface IUserAgentVerificationModule
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 683aafc..a4ca0fb 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -465,7 +465,77 @@ namespace OpenSim.Region.Framework.Scenes
465 || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) 465 || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S))
466 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) 466 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
467 { 467 {
468 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 468 IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>();
469 uint x = 0;
470 uint y = 0;
471 string version = String.Empty;
472 Vector3 newpos = Vector3.Zero;
473 OpenSim.Services.Interfaces.GridRegion destination = null;
474
475 bool canCross = true;
476 foreach (ScenePresence av in m_linkedAvatars)
477 {
478 // We need to cross these agents. First, let's find
479 // out if any of them can't cross for some reason.
480 // We have to deny the crossing entirely if any
481 // of them are banned. Alternatively, we could
482 // unsit banned agents....
483
484
485 // We set the avatar position as being the object
486 // position to get the region to send to
487 if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null)
488 {
489 canCross = false;
490 break;
491 }
492
493 m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName);
494 }
495
496 if (canCross)
497 {
498 // We unparent the SP quietly so that it won't
499 // be made to stand up
500 foreach (ScenePresence av in m_linkedAvatars)
501 {
502 SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID);
503 if (parentPart != null)
504 av.ParentUUID = parentPart.UUID;
505
506 av.ParentID = 0;
507 }
508
509 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
510
511 // Normalize
512 if (val.X >= Constants.RegionSize)
513 val.X -= Constants.RegionSize;
514 if (val.Y >= Constants.RegionSize)
515 val.Y -= Constants.RegionSize;
516 if (val.X < 0)
517 val.X += Constants.RegionSize;
518 if (val.Y < 0)
519 val.Y += Constants.RegionSize;
520
521 // If it's deleted, crossing was successful
522 if (IsDeleted)
523 {
524 foreach (ScenePresence av in m_linkedAvatars)
525 {
526 m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val);
527
528 av.IsInTransit = true;
529
530 CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync;
531 d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d);
532 }
533
534 return;
535 }
536 }
537
538 val = AbsolutePosition;
469 } 539 }
470 } 540 }
471 541
@@ -524,6 +594,23 @@ namespace OpenSim.Region.Framework.Scenes
524 } 594 }
525 } 595 }
526 596
597 private void CrossAgentToNewRegionCompleted(IAsyncResult iar)
598 {
599 CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState;
600 ScenePresence agent = icon.EndInvoke(iar);
601
602 //// If the cross was successful, this agent is a child agent
603 //if (agent.IsChildAgent)
604 // agent.Reset();
605 //else // Not successful
606 // agent.RestoreInCurrentScene();
607
608 // In any case
609 agent.IsInTransit = false;
610
611 m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
612 }
613
527 public override uint LocalId 614 public override uint LocalId
528 { 615 {
529 get { return m_rootPart.LocalId; } 616 get { return m_rootPart.LocalId; }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 13854c7..429fc06 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes
233 private bool m_collisionEventFlag = false; 233 private bool m_collisionEventFlag = false;
234 private object m_collisionEventLock = new Object(); 234 private object m_collisionEventLock = new Object();
235 235
236 private Vector3 m_prevSitOffset;
237
236 protected AvatarAppearance m_appearance; 238 protected AvatarAppearance m_appearance;
237 239
238 public AvatarAppearance Appearance 240 public AvatarAppearance Appearance
@@ -644,6 +646,13 @@ namespace OpenSim.Region.Framework.Scenes
644 } 646 }
645 private uint m_parentID; 647 private uint m_parentID;
646 648
649 public UUID ParentUUID
650 {
651 get { return m_parentUUID; }
652 set { m_parentUUID = value; }
653 }
654 private UUID m_parentUUID = UUID.Zero;
655
647 public float Health 656 public float Health
648 { 657 {
649 get { return m_health; } 658 get { return m_health; }
@@ -865,7 +874,26 @@ namespace OpenSim.Region.Framework.Scenes
865 "[SCENE]: Upgrading child to root agent for {0} in {1}", 874 "[SCENE]: Upgrading child to root agent for {0} in {1}",
866 Name, m_scene.RegionInfo.RegionName); 875 Name, m_scene.RegionInfo.RegionName);
867 876
868 //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); 877 if (ParentUUID != UUID.Zero)
878 {
879 m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID);
880 SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID);
881 if (part == null)
882 {
883 m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID);
884 }
885 else
886 {
887 part.ParentGroup.AddAvatar(UUID);
888 if (part.SitTargetPosition != Vector3.Zero)
889 part.SitTargetAvatar = UUID;
890 ParentPosition = part.GetWorldPosition();
891 ParentID = part.LocalId;
892 m_pos = m_prevSitOffset;
893 pos = ParentPosition;
894 }
895 ParentUUID = UUID.Zero;
896 }
869 897
870 bool wasChild = IsChildAgent; 898 bool wasChild = IsChildAgent;
871 IsChildAgent = false; 899 IsChildAgent = false;
@@ -878,62 +906,64 @@ namespace OpenSim.Region.Framework.Scenes
878 906
879 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); 907 m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
880 908
881 // Moved this from SendInitialData to ensure that Appearance is initialized 909 if (ParentID == 0)
882 // before the inventory is processed in MakeRootAgent. This fixes a race condition
883 // related to the handling of attachments
884 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
885 if (m_scene.TestBorderCross(pos, Cardinals.E))
886 { 910 {
887 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); 911 // Moved this from SendInitialData to ensure that Appearance is initialized
888 pos.X = crossedBorder.BorderLine.Z - 1; 912 // before the inventory is processed in MakeRootAgent. This fixes a race condition
889 } 913 // related to the handling of attachments
914 //m_scene.GetAvatarAppearance(ControllingClient, out Appearance);
915 if (m_scene.TestBorderCross(pos, Cardinals.E))
916 {
917 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E);
918 pos.X = crossedBorder.BorderLine.Z - 1;
919 }
890 920
891 if (m_scene.TestBorderCross(pos, Cardinals.N)) 921 if (m_scene.TestBorderCross(pos, Cardinals.N))
892 { 922 {
893 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); 923 Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N);
894 pos.Y = crossedBorder.BorderLine.Z - 1; 924 pos.Y = crossedBorder.BorderLine.Z - 1;
895 } 925 }
896 926
897 CheckAndAdjustLandingPoint(ref pos); 927 CheckAndAdjustLandingPoint(ref pos);
898 928
899 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) 929 if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f)
900 { 930 {
901 m_log.WarnFormat( 931 m_log.WarnFormat(
902 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", 932 "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping",
903 pos, Name, UUID); 933 pos, Name, UUID);
904 934
905 if (pos.X < 0f) pos.X = 0f; 935 if (pos.X < 0f) pos.X = 0f;
906 if (pos.Y < 0f) pos.Y = 0f; 936 if (pos.Y < 0f) pos.Y = 0f;
907 if (pos.Z < 0f) pos.Z = 0f; 937 if (pos.Z < 0f) pos.Z = 0f;
908 } 938 }
909 939
910 float localAVHeight = 1.56f; 940 float localAVHeight = 1.56f;
911 if (Appearance.AvatarHeight > 0) 941 if (Appearance.AvatarHeight > 0)
912 localAVHeight = Appearance.AvatarHeight; 942 localAVHeight = Appearance.AvatarHeight;
913 943
914 float posZLimit = 0; 944 float posZLimit = 0;
915 945
916 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) 946 if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize)
917 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; 947 posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y];
918 948
919 float newPosZ = posZLimit + localAVHeight / 2; 949 float newPosZ = posZLimit + localAVHeight / 2;
920 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 950 if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ)))
921 { 951 {
922 pos.Z = newPosZ; 952 pos.Z = newPosZ;
923 } 953 }
924 AbsolutePosition = pos; 954 AbsolutePosition = pos;
925 955
926 AddToPhysicalScene(isFlying); 956 AddToPhysicalScene(isFlying);
927 957
928 if (ForceFly) 958 if (ForceFly)
929 { 959 {
930 Flying = true; 960 Flying = true;
931 } 961 }
932 else if (FlyDisabled) 962 else if (FlyDisabled)
933 { 963 {
934 Flying = false; 964 Flying = false;
965 }
935 } 966 }
936
937 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying 967 // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying
938 // avatar to return to the standing position in mid-air. On login it looks like this is being sent 968 // avatar to return to the standing position in mid-air. On login it looks like this is being sent
939 // elsewhere anyway 969 // elsewhere anyway
@@ -951,11 +981,13 @@ namespace OpenSim.Region.Framework.Scenes
951 { 981 {
952 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); 982 m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments...");
953 // Resume scripts 983 // Resume scripts
954 foreach (SceneObjectGroup sog in m_attachments) 984 Util.FireAndForget(delegate(object x) {
955 { 985 foreach (SceneObjectGroup sog in m_attachments)
956 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); 986 {
957 sog.ResumeScripts(); 987 sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource());
958 } 988 sog.ResumeScripts();
989 }
990 });
959 } 991 }
960 } 992 }
961 993
@@ -3109,6 +3141,9 @@ namespace OpenSim.Region.Framework.Scenes
3109 cAgent.AlwaysRun = SetAlwaysRun; 3141 cAgent.AlwaysRun = SetAlwaysRun;
3110 3142
3111 cAgent.Appearance = new AvatarAppearance(Appearance); 3143 cAgent.Appearance = new AvatarAppearance(Appearance);
3144
3145 cAgent.ParentPart = ParentUUID;
3146 cAgent.SitOffset = m_pos;
3112 3147
3113 lock (scriptedcontrols) 3148 lock (scriptedcontrols)
3114 { 3149 {
@@ -3168,6 +3203,8 @@ namespace OpenSim.Region.Framework.Scenes
3168 CameraAtAxis = cAgent.AtAxis; 3203 CameraAtAxis = cAgent.AtAxis;
3169 CameraLeftAxis = cAgent.LeftAxis; 3204 CameraLeftAxis = cAgent.LeftAxis;
3170 m_CameraUpAxis = cAgent.UpAxis; 3205 m_CameraUpAxis = cAgent.UpAxis;
3206 ParentUUID = cAgent.ParentPart;
3207 m_prevSitOffset = cAgent.SitOffset;
3171 3208
3172 // When we get to the point of re-computing neighbors everytime this 3209 // When we get to the point of re-computing neighbors everytime this
3173 // changes, then start using the agent's drawdistance rather than the 3210 // changes, then start using the agent's drawdistance rather than the
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index b0b1b16..1529140 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -2188,7 +2188,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2188 if (part.ParentGroup.RootPart == part) 2188 if (part.ParentGroup.RootPart == part)
2189 { 2189 {
2190 SceneObjectGroup parent = part.ParentGroup; 2190 SceneObjectGroup parent = part.ParentGroup;
2191 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z)); 2191 Util.FireAndForget(delegate(object x) {
2192 parent.UpdateGroupPosition(new Vector3((float)toPos.x, (float)toPos.y, (float)toPos.z));
2193 });
2192 } 2194 }
2193 else 2195 else
2194 { 2196 {
@@ -7973,7 +7975,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7973 if (part.ParentGroup.RootPart == part) 7975 if (part.ParentGroup.RootPart == part)
7974 { 7976 {
7975 SceneObjectGroup parent = part.ParentGroup; 7977 SceneObjectGroup parent = part.ParentGroup;
7976 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 7978 Util.FireAndForget(delegate(object x) {
7979 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7980 });
7977 } 7981 }
7978 else 7982 else
7979 { 7983 {
@@ -7990,7 +7994,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7990 if (part.ParentGroup.RootPart == part) 7994 if (part.ParentGroup.RootPart == part)
7991 { 7995 {
7992 SceneObjectGroup parent = part.ParentGroup; 7996 SceneObjectGroup parent = part.ParentGroup;
7993 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z)); 7997 Util.FireAndForget(delegate(object x) {
7998 parent.UpdateGroupPosition(new Vector3((float)currentPosition.x, (float)currentPosition.y, (float)currentPosition.z));
7999 });
7994 } 8000 }
7995 else 8001 else
7996 { 8002 {