aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Framework/EntityTransfer
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/EntityTransfer')
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs1011
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs4
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs31
3 files changed, 560 insertions, 486 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index e4bc113..ed93f05 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -147,13 +147,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
147 // Add this agent in this region as a banned person 147 // Add this agent in this region as a banned person
148 public void Add(ulong pRegionHandle, UUID pAgentID) 148 public void Add(ulong pRegionHandle, UUID pAgentID)
149 { 149 {
150 this.Add(pRegionHandle, pAgentID, 45, 15);
151 }
152
153 public void Add(ulong pRegionHandle, UUID pAgentID, double newTime, double extendTime)
154 {
150 if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache)) 155 if (!m_bannedRegions.TryGetValue(pAgentID, out m_idCache))
151 { 156 {
152 m_idCache = new ExpiringCache<ulong, DateTime>(); 157 m_idCache = new ExpiringCache<ulong, DateTime>();
153 m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(45)); 158 m_bannedRegions.Add(pAgentID, m_idCache, TimeSpan.FromSeconds(newTime));
154 } 159 }
155 m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); 160 m_idCache.Add(pRegionHandle, DateTime.Now + TimeSpan.FromSeconds(extendTime), TimeSpan.FromSeconds(extendTime));
156 } 161 }
162
157 // Remove the agent from the region's banned list 163 // Remove the agent from the region's banned list
158 public void Remove(ulong pRegionHandle, UUID pAgentID) 164 public void Remove(ulong pRegionHandle, UUID pAgentID)
159 { 165 {
@@ -163,6 +169,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
163 } 169 }
164 } 170 }
165 } 171 }
172
166 private BannedRegionCache m_bannedRegionCache = new BannedRegionCache(); 173 private BannedRegionCache m_bannedRegionCache = new BannedRegionCache();
167 174
168 private IEventQueue m_eqModule; 175 private IEventQueue m_eqModule;
@@ -451,16 +458,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
451 } 458 }
452 459
453 // TODO: Get proper AVG Height 460 // TODO: Get proper AVG Height
454 float localAVHeight = 1.56f; 461 float localHalfAVHeight = 0.8f;
462 if (sp.Appearance != null)
463 localHalfAVHeight = sp.Appearance.AvatarHeight / 2;
464
455 float posZLimit = 22; 465 float posZLimit = 22;
456 466
457 // TODO: Check other Scene HeightField 467 // TODO: Check other Scene HeightField
458 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; 468 posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y];
459 469
460 float newPosZ = posZLimit + localAVHeight; 470 posZLimit += localHalfAVHeight + 0.1f;
461 if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) 471
472 if ((position.Z < posZLimit) && !(Single.IsInfinity(posZLimit) || Single.IsNaN(posZLimit)))
462 { 473 {
463 position.Z = newPosZ; 474 position.Z = posZLimit;
464 } 475 }
465 476
466 if (sp.Flying) 477 if (sp.Flying)
@@ -559,9 +570,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
559 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY); 570 Util.RegionHandleToRegionLoc(regionHandle, out regX, out regY);
560 571
561 MapBlockData block = new MapBlockData(); 572 MapBlockData block = new MapBlockData();
562 block.X = (ushort)regX; 573 block.X = (ushort)(regX);
563 block.Y = (ushort)regY; 574 block.Y = (ushort)(regY);
564 block.Access = (byte)SimAccess.Down; 575 block.Access = (byte)SimAccess.Down; // == not there
565 576
566 List<MapBlockData> blocks = new List<MapBlockData>(); 577 List<MapBlockData> blocks = new List<MapBlockData>();
567 blocks.Add(block); 578 blocks.Add(block);
@@ -696,10 +707,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
696 return; 707 return;
697 } 708 }
698 709
699 uint newRegionX, newRegionY, oldRegionX, oldRegionY;
700 Util.RegionHandleToRegionLoc(reg.RegionHandle, out newRegionX, out newRegionY);
701 Util.RegionHandleToRegionLoc(sp.Scene.RegionInfo.RegionHandle, out oldRegionX, out oldRegionY);
702
703 ulong destinationHandle = finalDestination.RegionHandle; 710 ulong destinationHandle = finalDestination.RegionHandle;
704 711
705 // Let's do DNS resolution only once in this process, please! 712 // Let's do DNS resolution only once in this process, please!
@@ -768,7 +775,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
768 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); 775 AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo();
769 agentCircuit.startpos = position; 776 agentCircuit.startpos = position;
770 agentCircuit.child = true; 777 agentCircuit.child = true;
771 agentCircuit.Appearance = sp.Appearance; 778
779// agentCircuit.Appearance = sp.Appearance;
780// agentCircuit.Appearance = new AvatarAppearance(sp.Appearance, true, false);
781 agentCircuit.Appearance = new AvatarAppearance();
782 agentCircuit.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
783
772 if (currentAgentCircuit != null) 784 if (currentAgentCircuit != null)
773 { 785 {
774 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; 786 agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs;
@@ -779,24 +791,51 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
779 agentCircuit.Id0 = currentAgentCircuit.Id0; 791 agentCircuit.Id0 = currentAgentCircuit.Id0;
780 } 792 }
781 793
782 // if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 794 IClientIPEndpoint ipepClient;
783 float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance, 795
784 (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY)); 796 uint newRegionX, newRegionY, oldRegionX, oldRegionY;
785 if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY)) 797 Util.RegionHandleToRegionLoc(destinationHandle, out newRegionX, out newRegionY);
798 Util.RegionHandleToRegionLoc(sourceRegion.RegionHandle, out oldRegionX, out oldRegionY);
799 int oldSizeX = (int)sourceRegion.RegionSizeX;
800 int oldSizeY = (int)sourceRegion.RegionSizeY;
801 int newSizeX = finalDestination.RegionSizeX;
802 int newSizeY = finalDestination.RegionSizeY;
803
804 bool OutSideViewRange = NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY,
805 oldSizeX, oldSizeY, newSizeX, newSizeY);
806
807 if (OutSideViewRange)
786 { 808 {
787 // brand new agent, let's create a new caps seed 809 m_log.DebugFormat(
810 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
811 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
812
813 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
814 #region IP Translation for NAT
815 // Uses ipepClient above
816 if (sp.ClientView.TryGet(out ipepClient))
817 {
818 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
819 }
820 #endregion
788 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 821 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
789 } 822 }
823 else
824 {
825 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
826 if (agentCircuit.CapsPath == null)
827 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
828 }
790 829
791 // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 830 // We're going to fallback to V1 if the destination gives us anything smaller than 0.2
792 if (ctx.OutboundVersion >= 0.2f) 831 if (ctx.OutboundVersion >= 0.2f)
793 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason); 832 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange , ctx, out reason);
794 else 833 else
795 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, ctx, out reason); 834 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, OutSideViewRange, ctx, out reason);
796 } 835 }
797 836
798 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, 837 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
799 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason) 838 IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason)
800 { 839 {
801 ulong destinationHandle = finalDestination.RegionHandle; 840 ulong destinationHandle = finalDestination.RegionHandle;
802 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 841 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
@@ -805,10 +844,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
805 "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}", 844 "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
806 sp.Name, Scene.Name, finalDestination.RegionName); 845 sp.Name, Scene.Name, finalDestination.RegionName);
807 846
847 string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
848
808 // Let's create an agent there if one doesn't exist yet. 849 // Let's create an agent there if one doesn't exist yet.
809 // NOTE: logout will always be false for a non-HG teleport. 850 // NOTE: logout will always be false for a non-HG teleport.
810 bool logout = false; 851 bool logout = false;
811 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 852 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout))
812 { 853 {
813 m_interRegionTeleportFailures.Value++; 854 m_interRegionTeleportFailures.Value++;
814 855
@@ -846,28 +887,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
846 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 887 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
847 888
848 // OK, it got this agent. Let's close some child agents 889 // OK, it got this agent. Let's close some child agents
849 sp.CloseChildAgents(newRegionX, newRegionY);
850 890
851 IClientIPEndpoint ipepClient; 891 if (OutSideViewRange)
852 string capsPath = String.Empty;
853 float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
854 (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
855 if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
856 { 892 {
857 m_log.DebugFormat(
858 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
859 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
860
861 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
862 #region IP Translation for NAT
863 // Uses ipepClient above
864 if (sp.ClientView.TryGet(out ipepClient))
865 {
866 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
867 }
868 #endregion
869 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
870
871 if (m_eqModule != null) 893 if (m_eqModule != null)
872 { 894 {
873 // The EnableSimulator message makes the client establish a connection with the destination 895 // The EnableSimulator message makes the client establish a connection with the destination
@@ -897,15 +919,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
897 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); 919 sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint);
898 } 920 }
899 } 921 }
900 else
901 {
902 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
903 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
904 }
905 922
906 // Let's send a full update of the agent. This is a synchronous call. 923 // Let's send a full update of the agent. This is a synchronous call.
907 AgentData agent = new AgentData(); 924 AgentData agent = new AgentData();
908 sp.CopyTo(agent); 925 sp.CopyTo(agent);
926
927 if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0)
928 agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
929
909 agent.Position = agentCircuit.startpos; 930 agent.Position = agentCircuit.startpos;
910 SetCallbackURL(agent, sp.Scene.RegionInfo); 931 SetCallbackURL(agent, sp.Scene.RegionInfo);
911 932
@@ -927,7 +948,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
927 // destination region but the viewer cannot establish the connection (e.g. due to network issues between 948 // destination region but the viewer cannot establish the connection (e.g. due to network issues between
928 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then 949 // the viewer and the destination). In this case, UpdateAgent timesout after 10 seconds, although then
929 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail(). 950 // there's a further 10 second wait whilst we attempt to tell the destination to delete the agent in Fail().
930 if (!UpdateAgent(reg, finalDestination, agent, sp)) 951 if (!UpdateAgent(reg, finalDestination, agent, sp, ctx))
931 { 952 {
932 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) 953 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
933 { 954 {
@@ -1007,7 +1028,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1007 return; 1028 return;
1008 } 1029 }
1009 1030
1010 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
1011 1031
1012/* 1032/*
1013 // TODO: This may be 0.6. Check if still needed 1033 // TODO: This may be 0.6. Check if still needed
@@ -1020,18 +1040,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1020 } 1040 }
1021*/ 1041*/
1022 1042
1023 // May need to logout or other cleanup 1043 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
1024 AgentHasMovedAway(sp, logout);
1025 1044
1026 // Well, this is it. The agent is over there. 1045 sp.CloseChildAgents(logout, destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
1027 KillEntity(sp.Scene, sp.LocalId);
1028 1046
1029 // Now let's make it officially a child agent 1047 // call HG hook
1030 sp.MakeChildAgent(); 1048 AgentHasMovedAway(sp, logout);
1049
1050 sp.HasMovedAway(!(OutSideViewRange || logout));
1051
1052 // Now let's make it officially a child agent
1053 sp.MakeChildAgent(destinationHandle);
1031 1054
1032 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 1055 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1033 1056
1034 if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 1057 if (NeedsClosing(reg, OutSideViewRange))
1035 { 1058 {
1036 if (!sp.Scene.IncomingPreCloseClient(sp)) 1059 if (!sp.Scene.IncomingPreCloseClient(sp))
1037 return; 1060 return;
@@ -1043,26 +1066,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1043 // This sleep can be increased if necessary. However, whilst it's active, 1066 // This sleep can be increased if necessary. However, whilst it's active,
1044 // an agent cannot teleport back to this region if it has teleported away. 1067 // an agent cannot teleport back to this region if it has teleported away.
1045 Thread.Sleep(2000); 1068 Thread.Sleep(2000);
1046 1069 if (m_eqModule != null && !sp.DoNotCloseAfterTeleport)
1070 m_eqModule.DisableSimulator(sp.RegionHandle,sp.UUID);
1071 Thread.Sleep(500);
1047 sp.Scene.CloseAgent(sp.UUID, false); 1072 sp.Scene.CloseAgent(sp.UUID, false);
1048 } 1073 }
1049 else
1050 {
1051 // now we have a child agent in this region.
1052 sp.Reset();
1053 }
1054 } 1074 }
1055 1075
1056 private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, 1076 private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
1057 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, EntityTransferContext ctx, out string reason) 1077 IPEndPoint endPoint, uint teleportFlags, bool OutSideViewRange, EntityTransferContext ctx, out string reason)
1058 { 1078 {
1059 ulong destinationHandle = finalDestination.RegionHandle; 1079 ulong destinationHandle = finalDestination.RegionHandle;
1060 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 1080 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1061 1081
1082 string capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);;
1083
1062 // Let's create an agent there if one doesn't exist yet. 1084 // Let's create an agent there if one doesn't exist yet.
1063 // NOTE: logout will always be false for a non-HG teleport. 1085 // NOTE: logout will always be false for a non-HG teleport.
1064 bool logout = false; 1086 bool logout = false;
1065 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) 1087 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout))
1066 { 1088 {
1067 m_interRegionTeleportFailures.Value++; 1089 m_interRegionTeleportFailures.Value++;
1068 1090
@@ -1099,32 +1121,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1099 // Past this point we have to attempt clean up if the teleport fails, so update transfer state. 1121 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
1100 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); 1122 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
1101 1123
1102 IClientIPEndpoint ipepClient;
1103 string capsPath = String.Empty;
1104 float dist = (float)Math.Max(sp.Scene.DefaultDrawDistance,
1105 (float)Math.Max(sp.Scene.RegionInfo.RegionSizeX, sp.Scene.RegionInfo.RegionSizeY));
1106 if (NeedsNewAgent(dist, oldRegionX, newRegionX, oldRegionY, newRegionY))
1107 {
1108 m_log.DebugFormat(
1109 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
1110 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
1111
1112 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
1113 #region IP Translation for NAT
1114 // Uses ipepClient above
1115 if (sp.ClientView.TryGet(out ipepClient))
1116 {
1117 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
1118 }
1119 #endregion
1120 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1121 }
1122 else
1123 {
1124 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
1125 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1126 }
1127
1128 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, 1124 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
1129 // where that neighbour simulator could otherwise request a child agent create on the source which then 1125 // where that neighbour simulator could otherwise request a child agent create on the source which then
1130 // closes our existing agent which is still signalled as root. 1126 // closes our existing agent which is still signalled as root.
@@ -1146,6 +1142,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1146 AgentData agent = new AgentData(); 1142 AgentData agent = new AgentData();
1147 sp.CopyTo(agent); 1143 sp.CopyTo(agent);
1148 agent.Position = agentCircuit.startpos; 1144 agent.Position = agentCircuit.startpos;
1145
1146 if ((teleportFlags & (uint)TeleportFlags.IsFlying) != 0)
1147 agent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1148
1149 agent.SenderWantsToWaitForRoot = true; 1149 agent.SenderWantsToWaitForRoot = true;
1150 //SetCallbackURL(agent, sp.Scene.RegionInfo); 1150 //SetCallbackURL(agent, sp.Scene.RegionInfo);
1151 1151
@@ -1158,7 +1158,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1158 // Send the Update. If this returns true, we know the client has contacted the destination 1158 // Send the Update. If this returns true, we know the client has contacted the destination
1159 // via CompleteMovementIntoRegion, so we can let go. 1159 // via CompleteMovementIntoRegion, so we can let go.
1160 // If it returns false, something went wrong, and we need to abort. 1160 // If it returns false, something went wrong, and we need to abort.
1161 if (!UpdateAgent(reg, finalDestination, agent, sp)) 1161 if (!UpdateAgent(reg, finalDestination, agent, sp, ctx))
1162 { 1162 {
1163 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) 1163 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
1164 { 1164 {
@@ -1187,19 +1187,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1187 // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex 1187 // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex
1188 // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are 1188 // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are
1189 // abandoned without proper close by viewer but then re-used by an incoming connection. 1189 // abandoned without proper close by viewer but then re-used by an incoming connection.
1190 sp.CloseChildAgents(newRegionX, newRegionY); 1190 sp.CloseChildAgents(logout, destinationHandle, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
1191 1191
1192 // May need to logout or other cleanup 1192 sp.HasMovedAway(!(OutSideViewRange || logout));
1193 AgentHasMovedAway(sp, logout);
1194 1193
1195 // Well, this is it. The agent is over there. 1194 //HG hook
1196 KillEntity(sp.Scene, sp.LocalId); 1195 AgentHasMovedAway(sp, logout);
1197 1196
1198 // Now let's make it officially a child agent 1197 // Now let's make it officially a child agent
1199 sp.MakeChildAgent(); 1198 sp.MakeChildAgent(destinationHandle);
1199
1200
1200 1201
1201 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone 1202 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1202 if (NeedsClosing(sp.Scene.DefaultDrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 1203 // go by HG hook
1204 if (NeedsClosing(reg, OutSideViewRange))
1203 { 1205 {
1204 if (!sp.Scene.IncomingPreCloseClient(sp)) 1206 if (!sp.Scene.IncomingPreCloseClient(sp))
1205 return; 1207 return;
@@ -1210,8 +1212,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1210 // BEFORE THEY SETTLE IN THE NEW REGION. 1212 // BEFORE THEY SETTLE IN THE NEW REGION.
1211 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR 1213 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
1212 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. 1214 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
1213 Thread.Sleep(15000); 1215
1214 1216 Thread.Sleep(14000);
1217 if (m_eqModule != null && !sp.DoNotCloseAfterTeleport)
1218 m_eqModule.DisableSimulator(sp.RegionHandle,sp.UUID);
1219 Thread.Sleep(1000);
1220
1215 // OK, it got this agent. Let's close everything 1221 // OK, it got this agent. Let's close everything
1216 // If we shouldn't close the agent due to some other region renewing the connection 1222 // If we shouldn't close the agent due to some other region renewing the connection
1217 // then this will be handled in IncomingCloseAgent under lock conditions 1223 // then this will be handled in IncomingCloseAgent under lock conditions
@@ -1220,11 +1226,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1220 1226
1221 sp.Scene.CloseAgent(sp.UUID, false); 1227 sp.Scene.CloseAgent(sp.UUID, false);
1222 } 1228 }
1229/*
1223 else 1230 else
1224 { 1231 {
1225 // now we have a child agent in this region. 1232 // now we have a child agent in this region.
1226 sp.Reset(); 1233 sp.Reset();
1227 } 1234 }
1235 */
1228 } 1236 }
1229 1237
1230 /// <summary> 1238 /// <summary>
@@ -1272,13 +1280,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1272 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); 1280 sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout);
1273 } 1281 }
1274 1282
1275 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 1283 protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout)
1276 { 1284 {
1277 GridRegion source = new GridRegion(Scene.RegionInfo); 1285 GridRegion source = new GridRegion(Scene.RegionInfo);
1278 source.RawServerURI = m_GatekeeperURI; 1286 source.RawServerURI = m_GatekeeperURI;
1279 1287
1280 logout = false; 1288 logout = false;
1281 bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, out reason); 1289 bool success = Scene.SimulationService.CreateAgent(source, finalDestination, agentCircuit, teleportFlags, ctx, out reason);
1282 1290
1283 if (success) 1291 if (success)
1284 sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); 1292 sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout);
@@ -1286,9 +1294,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1286 return success; 1294 return success;
1287 } 1295 }
1288 1296
1289 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp) 1297 protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp, EntityTransferContext ctx)
1290 { 1298 {
1291 return Scene.SimulationService.UpdateAgent(finalDestination, agent); 1299 return Scene.SimulationService.UpdateAgent(finalDestination, agent, ctx);
1292 } 1300 }
1293 1301
1294 protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) 1302 protected virtual void SetCallbackURL(AgentData agent, RegionInfo region)
@@ -1305,10 +1313,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1305 /// </summary> 1313 /// </summary>
1306 /// <param name='sp'></param> 1314 /// <param name='sp'></param>
1307 /// <param name='logout'></param> 1315 /// <param name='logout'></param>
1316 ///
1317 /// now just a HG hook
1308 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout) 1318 protected virtual void AgentHasMovedAway(ScenePresence sp, bool logout)
1309 { 1319 {
1310 if (sp.Scene.AttachmentsModule != null) 1320// if (sp.Scene.AttachmentsModule != null)
1311 sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, true); 1321// sp.Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, logout);
1312 } 1322 }
1313 1323
1314 protected void KillEntity(Scene scene, uint localID) 1324 protected void KillEntity(Scene scene, uint localID)
@@ -1316,6 +1326,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1316 scene.SendKillObject(new List<uint> { localID }); 1326 scene.SendKillObject(new List<uint> { localID });
1317 } 1327 }
1318 1328
1329 // HG hook
1319 protected virtual GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message) 1330 protected virtual GridRegion GetFinalDestination(GridRegion region, UUID agentID, string agentHomeURI, out string message)
1320 { 1331 {
1321 message = null; 1332 message = null;
@@ -1325,7 +1336,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1325 // This returns 'true' if the new region already has a child agent for our 1336 // This returns 'true' if the new region already has a child agent for our
1326 // incoming agent. The implication is that, if 'false', we have to create the 1337 // incoming agent. The implication is that, if 'false', we have to create the
1327 // child and then teleport into the region. 1338 // child and then teleport into the region.
1328 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) 1339 protected virtual bool NeedsNewAgent(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY,
1340 int oldsizeX, int oldsizeY, int newsizeX, int newsizeY)
1329 { 1341 {
1330 if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) 1342 if (m_regionCombinerModule != null && m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
1331 { 1343 {
@@ -1338,15 +1350,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1338 1350
1339 return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y); 1351 return !(newRegionX >= swCorner.X && newRegionX <= neCorner.X && newRegionY >= swCorner.Y && newRegionY <= neCorner.Y);
1340 } 1352 }
1341 else 1353
1342 { 1354 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY,
1343 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); 1355 oldsizeX, oldsizeY, newsizeX, newsizeY);
1344 }
1345 } 1356 }
1346 1357
1347 protected virtual bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) 1358 // HG Hook
1359 protected virtual bool NeedsClosing(GridRegion reg, bool OutViewRange)
1360
1348 { 1361 {
1349 return Util.IsOutsideView(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY); 1362 return OutViewRange;
1350 } 1363 }
1351 1364
1352 #endregion 1365 #endregion
@@ -1429,105 +1442,143 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1429 1442
1430 #region Agent Crossings 1443 #region Agent Crossings
1431 1444
1432 // Given a position relative to the current region (which has previously been tested to 1445 public bool checkAgentAccessToRegion(ScenePresence agent, GridRegion destiny, Vector3 position,
1433 // see that it is actually outside the current region), find the new region that the 1446 EntityTransferContext ctx, out string reason)
1434 // point is actually in. 1447 {
1435 // Returns the coordinates and information of the new region or 'null' of it doesn't exist. 1448 reason = String.Empty;
1449
1450 UUID agentID = agent.UUID;
1451 ulong destinyHandle = destiny.RegionHandle;
1452
1453 if (m_bannedRegionCache.IfBanned(destinyHandle, agentID))
1454 {
1455 return false;
1456 }
1457
1458 Scene ascene = agent.Scene;
1459 string homeURI = ascene.GetAgentHomeURI(agentID);
1460
1461
1462 if (!ascene.SimulationService.QueryAccess(destiny, agentID, homeURI, false, position,
1463 agent.Scene.GetFormatsOffered(), ctx, out reason))
1464 {
1465 m_bannedRegionCache.Add(destinyHandle, agentID, 30.0, 30.0);
1466 return false;
1467 }
1468 return true;
1469 }
1470
1471 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, EntityTransferContext ctx, out Vector3 newpos)
1472 {
1473 string r = String.Empty;
1474 return GetDestination(scene, agentID, pos, ctx, out newpos, out r);
1475 }
1476
1477 // Given a position relative to the current region and outside of it
1478 // find the new region that the point is actually in.
1479 // returns 'null' if new region not found or if information
1480 // and new position relative to it
1481 // now only works for crossings
1482
1436 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, 1483 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos,
1437 EntityTransferContext ctx, out Vector3 newpos, out string failureReason) 1484 EntityTransferContext ctx, out Vector3 newpos, out string failureReason)
1438 { 1485 {
1439 newpos = pos; 1486 newpos = pos;
1440 failureReason = string.Empty; 1487 failureReason = string.Empty;
1441 string homeURI = scene.GetAgentHomeURI(agentID);
1442 1488
1443// m_log.DebugFormat( 1489// m_log.DebugFormat(
1444// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1490// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
1445 1491
1446 // Compute world location of the object's position 1492 // Compute world location of the agente position
1447 double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X; 1493 double presenceWorldX = (double)scene.RegionInfo.WorldLocX + pos.X;
1448 double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y; 1494 double presenceWorldY = (double)scene.RegionInfo.WorldLocY + pos.Y;
1449 1495
1450 // Call the grid service to lookup the region containing the new position. 1496 // Call the grid service to lookup the region containing the new position.
1451 GridRegion neighbourRegion = GetRegionContainingWorldLocation(scene.GridService, scene.RegionInfo.ScopeID, 1497 GridRegion neighbourRegion = GetRegionContainingWorldLocation(
1452 presenceWorldX, presenceWorldY, 1498 scene.GridService, scene.RegionInfo.ScopeID,
1453 Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY)); 1499 presenceWorldX, presenceWorldY,
1500 Math.Max(scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY));
1454 1501
1455 if (neighbourRegion != null) 1502 if (neighbourRegion == null)
1456 { 1503 {
1457 // Compute the entity's position relative to the new region 1504 return null;
1458 newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX), 1505 }
1506 if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID))
1507 {
1508 return null;
1509 }
1510
1511 m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID);
1512
1513 // Compute the entity's position relative to the new region
1514 newpos = new Vector3((float)(presenceWorldX - (double)neighbourRegion.RegionLocX),
1459 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY), 1515 (float)(presenceWorldY - (double)neighbourRegion.RegionLocY),
1460 pos.Z); 1516 pos.Z);
1461 1517
1462 if (m_bannedRegionCache.IfBanned(neighbourRegion.RegionHandle, agentID)) 1518 string homeURI = scene.GetAgentHomeURI(agentID);
1463 {
1464 failureReason = "Cannot region cross into banned parcel";
1465 neighbourRegion = null;
1466 }
1467 else
1468 {
1469 // If not banned, make sure this agent is not in the list.
1470 m_bannedRegionCache.Remove(neighbourRegion.RegionHandle, agentID);
1471 }
1472 1519
1473 // Check to see if we have access to the target region. 1520 if (!scene.SimulationService.QueryAccess(
1474 if (neighbourRegion != null 1521 neighbourRegion, agentID, homeURI, false, newpos,
1475 && !scene.SimulationService.QueryAccess(neighbourRegion, agentID, homeURI, false, newpos, scene.GetFormatsOffered(), ctx, out failureReason)) 1522 scene.GetFormatsOffered(), ctx, out failureReason))
1476 {
1477 // remember banned
1478 m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
1479 neighbourRegion = null;
1480 }
1481 }
1482 else
1483 { 1523 {
1484 // The destination region just doesn't exist 1524 // remember the fail
1485 failureReason = "Cannot cross into non-existent region"; 1525 m_bannedRegionCache.Add(neighbourRegion.RegionHandle, agentID);
1526 return null;
1486 } 1527 }
1487 1528
1488 if (neighbourRegion == null)
1489 m_log.DebugFormat("{0} GetDestination: region not found. Old region name={1} at <{2},{3}> of size <{4},{5}>. Old pos={6}",
1490 LogHeader, scene.RegionInfo.RegionName,
1491 scene.RegionInfo.RegionLocX, scene.RegionInfo.RegionLocY,
1492 scene.RegionInfo.RegionSizeX, scene.RegionInfo.RegionSizeY,
1493 pos);
1494 else
1495 m_log.DebugFormat("{0} GetDestination: new region={1} at <{2},{3}> of size <{4},{5}>, newpos=<{6},{7}>",
1496 LogHeader, neighbourRegion.RegionName,
1497 neighbourRegion.RegionLocX, neighbourRegion.RegionLocY, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY,
1498 newpos.X, newpos.Y);
1499
1500 return neighbourRegion; 1529 return neighbourRegion;
1501 } 1530 }
1502 1531
1503 public bool Cross(ScenePresence agent, bool isFlying) 1532 public bool Cross(ScenePresence agent, bool isFlying)
1504 { 1533 {
1534 agent.IsInTransit = true;
1535 CrossAsyncDelegate d = CrossAsync;
1536 d.BeginInvoke(agent, isFlying, CrossCompleted, d);
1537 return true;
1538 }
1539
1540 private void CrossCompleted(IAsyncResult iar)
1541 {
1542 CrossAsyncDelegate icon = (CrossAsyncDelegate)iar.AsyncState;
1543 ScenePresence agent = icon.EndInvoke(iar);
1544
1545 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname);
1546
1547 if(!agent.IsChildAgent)
1548 {
1549 // crossing failed
1550 agent.CrossToNewRegionFail();
1551 }
1552 agent.IsInTransit = false;
1553 }
1554
1555 public ScenePresence CrossAsync(ScenePresence agent, bool isFlying)
1556 {
1557 uint x;
1558 uint y;
1505 Vector3 newpos; 1559 Vector3 newpos;
1506 EntityTransferContext ctx = new EntityTransferContext(); 1560 EntityTransferContext ctx = new EntityTransferContext();
1507 string failureReason; 1561 string failureReason;
1508 1562
1509 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, 1563 Vector3 pos = agent.AbsolutePosition + agent.Velocity;
1564
1565 GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, pos,
1510 ctx, out newpos, out failureReason); 1566 ctx, out newpos, out failureReason);
1511 if (neighbourRegion == null) 1567 if (neighbourRegion == null)
1512 { 1568 {
1513 agent.ControllingClient.SendAlertMessage(failureReason); 1569 if (failureReason != String.Empty)
1514 return false; 1570 agent.ControllingClient.SendAlertMessage(failureReason);
1571 return agent;
1515 } 1572 }
1516 1573
1517 agent.IsInTransit = true; 1574// agent.IsInTransit = true;
1518 1575
1519 CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; 1576 CrossAgentToNewRegionAsync(agent, newpos, neighbourRegion, isFlying, ctx);
1520 d.BeginInvoke(agent, newpos, neighbourRegion, isFlying, ctx, CrossAgentToNewRegionCompleted, d); 1577 agent.IsInTransit = false;
1521 1578 return agent;
1522 Scene.EventManager.TriggerCrossAgentToNewRegion(agent, isFlying, neighbourRegion);
1523
1524 return true;
1525 } 1579 }
1526 1580
1527 1581 public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene);
1528 public delegate void InformClientToInitiateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY,
1529 Vector3 position,
1530 Scene initiatingScene);
1531 1582
1532 private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) 1583 private void InformClientToInitiateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene)
1533 { 1584 {
@@ -1628,7 +1679,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1628 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1679 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1629 } 1680 }
1630 1681
1631 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying)) 1682 if (!CrossAgentIntoNewRegionMain(agent, pos, neighbourRegion, isFlying, ctx))
1632 { 1683 {
1633 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader); 1684 m_log.DebugFormat("{0}: CrossAgentToNewRegionAsync: cross main failed. Resetting transfer state", LogHeader);
1634 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1685 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
@@ -1644,14 +1695,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1644 return agent; 1695 return agent;
1645 } 1696 }
1646 1697
1647 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying) 1698 public bool CrossAgentIntoNewRegionMain(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, bool isFlying, EntityTransferContext ctx)
1648 { 1699 {
1700 int ts = Util.EnvironmentTickCount();
1649 try 1701 try
1650 { 1702 {
1651 AgentData cAgent = new AgentData(); 1703 AgentData cAgent = new AgentData();
1652 agent.CopyTo(cAgent); 1704 agent.CopyTo(cAgent);
1705
1706// agent.Appearance.WearableCacheItems = null;
1707
1653 cAgent.Position = pos; 1708 cAgent.Position = pos;
1654 1709
1710 cAgent.ChildrenCapSeeds = agent.KnownRegions;
1711
1655 if (isFlying) 1712 if (isFlying)
1656 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; 1713 cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY;
1657 1714
@@ -1661,7 +1718,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1661 // Beyond this point, extra cleanup is needed beyond removing transit state 1718 // Beyond this point, extra cleanup is needed beyond removing transit state
1662 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring); 1719 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.Transferring);
1663 1720
1664 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) 1721 if (!agent.Scene.SimulationService.UpdateAgent(neighbourRegion, cAgent, ctx))
1665 { 1722 {
1666 // region doesn't take it 1723 // region doesn't take it
1667 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1724 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
@@ -1671,11 +1728,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1671 neighbourRegion.RegionName, agent.Name); 1728 neighbourRegion.RegionName, agent.Name);
1672 1729
1673 ReInstantiateScripts(agent); 1730 ReInstantiateScripts(agent);
1674 agent.AddToPhysicalScene(isFlying); 1731 if(agent.ParentID == 0 && agent.ParentUUID == UUID.Zero)
1732 agent.AddToPhysicalScene(isFlying);
1675 1733
1676 return false; 1734 return false;
1677 } 1735 }
1678 1736
1737 m_log.DebugFormat("[CrossAgentIntoNewRegionMain] ok, time {0}ms",Util.EnvironmentTickCountSubtract(ts));
1738
1679 } 1739 }
1680 catch (Exception e) 1740 catch (Exception e)
1681 { 1741 {
@@ -1693,7 +1753,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1693 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion, 1753 public void CrossAgentToNewRegionPost(ScenePresence agent, Vector3 pos, GridRegion neighbourRegion,
1694 bool isFlying, EntityTransferContext ctx) 1754 bool isFlying, EntityTransferContext ctx)
1695 { 1755 {
1696 agent.ControllingClient.RequestClientInfo();
1697 1756
1698 string agentcaps; 1757 string agentcaps;
1699 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) 1758 if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps))
@@ -1704,6 +1763,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1704 } 1763 }
1705 1764
1706 // No turning back 1765 // No turning back
1766
1707 agent.IsChildAgent = true; 1767 agent.IsChildAgent = true;
1708 1768
1709 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); 1769 string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps);
@@ -1715,7 +1775,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1715 if (m_eqModule != null) 1775 if (m_eqModule != null)
1716 { 1776 {
1717 m_eqModule.CrossRegion( 1777 m_eqModule.CrossRegion(
1718 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, 1778 neighbourRegion.RegionHandle, pos, vel2 /* agent.Velocity */,
1719 neighbourRegion.ExternalEndPoint, 1779 neighbourRegion.ExternalEndPoint,
1720 capsPath, agent.UUID, agent.ControllingClient.SessionId, 1780 capsPath, agent.UUID, agent.ControllingClient.SessionId,
1721 neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY); 1781 neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
@@ -1723,25 +1783,36 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1723 else 1783 else
1724 { 1784 {
1725 m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader); 1785 m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader);
1726 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, 1786 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint,
1727 capsPath); 1787 capsPath);
1728 } 1788 }
1729 1789
1790/*
1791 // Backwards compatibility. Best effort
1792 if (version == 0f)
1793 {
1794 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one...");
1795 Thread.Sleep(3000); // wait a little now that we're not waiting for the callback
1796 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1797 }
1798*/
1730 // SUCCESS! 1799 // SUCCESS!
1731 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); 1800 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination);
1732 1801
1733 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. 1802 // Unlike a teleport, here we do not wait for the destination region to confirm the receipt.
1734 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); 1803 m_entityTransferStateMachine.UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp);
1735 1804
1736 agent.MakeChildAgent(); 1805 // this may need the attachments
1806
1807 agent.HasMovedAway(true);
1808
1809 agent.MakeChildAgent(neighbourRegion.RegionHandle);
1737 1810
1738 // FIXME: Possibly this should occur lower down after other commands to close other agents, 1811 // FIXME: Possibly this should occur lower down after other commands to close other agents,
1739 // but not sure yet what the side effects would be. 1812 // but not sure yet what the side effects would be.
1740 m_entityTransferStateMachine.ResetFromTransit(agent.UUID); 1813 m_entityTransferStateMachine.ResetFromTransit(agent.UUID);
1741 1814
1742 // now we have a child agent in this region. Request all interesting data about other (root) agents 1815 agent.CloseChildAgents(false, neighbourRegion.RegionHandle, neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
1743 agent.SendOtherAgentsAvatarDataToClient();
1744 agent.SendOtherAgentsAppearanceToClient();
1745 1816
1746 // TODO: Check since what version this wasn't needed anymore. May be as old as 0.6 1817 // TODO: Check since what version this wasn't needed anymore. May be as old as 0.6
1747/* 1818/*
@@ -1753,14 +1824,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1753 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); 1824 CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true);
1754 } 1825 }
1755*/ 1826*/
1756 // Next, let's close the child agent connections that are too far away.
1757 uint neighbourx;
1758 uint neighboury;
1759 Util.RegionHandleToRegionLoc(neighbourRegion.RegionHandle, out neighbourx, out neighboury);
1760
1761 agent.CloseChildAgents(neighbourx, neighboury);
1762
1763 AgentHasMovedAway(agent, false);
1764 1827
1765 // the user may change their profile information in other region, 1828 // the user may change their profile information in other region,
1766 // so the userinfo in UserProfileCache is not reliable any more, delete it 1829 // so the userinfo in UserProfileCache is not reliable any more, delete it
@@ -1800,7 +1863,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1800 #region Enable Child Agent 1863 #region Enable Child Agent
1801 1864
1802 /// <summary> 1865 /// <summary>
1803 /// This informs a single neighbouring region about agent "avatar". 1866 /// This informs a single neighbouring region about agent "avatar", and avatar about it
1804 /// Calls an asynchronous method to do so.. so it doesn't lag the sim. 1867 /// Calls an asynchronous method to do so.. so it doesn't lag the sim.
1805 /// </summary> 1868 /// </summary>
1806 /// <param name="sp"></param> 1869 /// <param name="sp"></param>
@@ -1809,41 +1872,47 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1809 { 1872 {
1810 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName); 1873 m_log.DebugFormat("[ENTITY TRANSFER]: Enabling child agent in new neighbour {0}", region.RegionName);
1811 1874
1875 ulong currentRegionHandler = sp.Scene.RegionInfo.RegionHandle;
1876 ulong regionhandler = region.RegionHandle;
1877
1878 Dictionary<ulong, string> seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1879
1880 if (seeds.ContainsKey(regionhandler))
1881 seeds.Remove(regionhandler);
1882/*
1883 List<ulong> oldregions = new List<ulong>(seeds.Keys);
1884
1885 if (oldregions.Contains(currentRegionHandler))
1886 oldregions.Remove(currentRegionHandler);
1887*/
1888 if (!seeds.ContainsKey(currentRegionHandler))
1889 seeds.Add(currentRegionHandler, sp.ControllingClient.RequestClientInfo().CapsPath);
1890
1812 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 1891 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1813 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); 1892 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo();
1814 agent.BaseFolder = UUID.Zero; 1893 agent.BaseFolder = UUID.Zero;
1815 agent.InventoryFolder = UUID.Zero; 1894 agent.InventoryFolder = UUID.Zero;
1816 agent.startpos = new Vector3(128, 128, 70); 1895 agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, region);
1817 agent.child = true; 1896 agent.child = true;
1818 agent.Appearance = sp.Appearance; 1897 agent.Appearance = new AvatarAppearance();
1898 agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
1899
1819 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 1900 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
1820 1901
1821 agent.ChildrenCapSeeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); 1902 seeds.Add(regionhandler, agent.CapsPath);
1822 //m_log.DebugFormat("[XXX] Seeds 1 {0}", agent.ChildrenCapSeeds.Count);
1823 1903
1824 if (!agent.ChildrenCapSeeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle))
1825 agent.ChildrenCapSeeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
1826 //m_log.DebugFormat("[XXX] Seeds 2 {0}", agent.ChildrenCapSeeds.Count);
1827 1904
1828 sp.AddNeighbourRegion(region.RegionHandle, agent.CapsPath); 1905// agent.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
1829 //foreach (ulong h in agent.ChildrenCapSeeds.Keys) 1906 agent.ChildrenCapSeeds = null;
1830 // m_log.DebugFormat("[XXX] --> {0}", h);
1831 //m_log.DebugFormat("[XXX] Adding {0}", region.RegionHandle);
1832 if (agent.ChildrenCapSeeds.ContainsKey(region.RegionHandle))
1833 {
1834 m_log.WarnFormat(
1835 "[ENTITY TRANSFER]: Overwriting caps seed {0} with {1} for region {2} (handle {3}) for {4} in {5}",
1836 agent.ChildrenCapSeeds[region.RegionHandle], agent.CapsPath,
1837 region.RegionName, region.RegionHandle, sp.Name, Scene.Name);
1838 }
1839
1840 agent.ChildrenCapSeeds[region.RegionHandle] = agent.CapsPath;
1841 1907
1842 if (sp.Scene.CapsModule != null) 1908 if (sp.Scene.CapsModule != null)
1843 { 1909 {
1844 sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, agent.ChildrenCapSeeds); 1910 sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
1845 } 1911 }
1846 1912
1913 sp.KnownRegions = seeds;
1914 sp.AddNeighbourRegionSizeInfo(region);
1915
1847 if (currentAgentCircuit != null) 1916 if (currentAgentCircuit != null)
1848 { 1917 {
1849 agent.ServiceURLs = currentAgentCircuit.ServiceURLs; 1918 agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
@@ -1853,7 +1922,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1853 agent.Mac = currentAgentCircuit.Mac; 1922 agent.Mac = currentAgentCircuit.Mac;
1854 agent.Id0 = currentAgentCircuit.Id0; 1923 agent.Id0 = currentAgentCircuit.Id0;
1855 } 1924 }
1856 1925/*
1926 AgentPosition agentpos = null;
1927
1928 if (oldregions.Count > 0)
1929 {
1930 agentpos = new AgentPosition();
1931 agentpos.AgentID = new UUID(sp.UUID.Guid);
1932 agentpos.SessionID = sp.ControllingClient.SessionId;
1933 agentpos.Size = sp.Appearance.AvatarSize;
1934 agentpos.Center = sp.CameraPosition;
1935 agentpos.Far = sp.DrawDistance;
1936 agentpos.Position = sp.AbsolutePosition;
1937 agentpos.Velocity = sp.Velocity;
1938 agentpos.RegionHandle = currentRegionHandler;
1939 agentpos.Throttles = sp.ControllingClient.GetThrottlesPacked(1);
1940 agentpos.ChildrenCapSeeds = seeds;
1941 }
1942*/
1857 IPEndPoint external = region.ExternalEndPoint; 1943 IPEndPoint external = region.ExternalEndPoint;
1858 if (external != null) 1944 if (external != null)
1859 { 1945 {
@@ -1862,7 +1948,23 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1862 InformClientOfNeighbourCompleted, 1948 InformClientOfNeighbourCompleted,
1863 d); 1949 d);
1864 } 1950 }
1951/*
1952 if(oldregions.Count >0)
1953 {
1954 uint neighbourx;
1955 uint neighboury;
1956 UUID scope = sp.Scene.RegionInfo.ScopeID;
1957 foreach (ulong handler in oldregions)
1958 {
1959 // crap code
1960 Utils.LongToUInts(handler, out neighbourx, out neighboury);
1961 GridRegion neighbour = sp.Scene.GridService.GetRegionByPosition(scope, (int)neighbourx, (int)neighboury);
1962 sp.Scene.SimulationService.UpdateAgent(neighbour, agentpos);
1963 }
1964 }
1965 */
1865 } 1966 }
1967
1866 #endregion 1968 #endregion
1867 1969
1868 #region Enable Child Agents 1970 #region Enable Child Agents
@@ -1872,146 +1974,153 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1872 1974
1873 /// <summary> 1975 /// <summary>
1874 /// This informs all neighbouring regions about agent "avatar". 1976 /// This informs all neighbouring regions about agent "avatar".
1977 /// and as important informs the avatar about then
1875 /// </summary> 1978 /// </summary>
1876 /// <param name="sp"></param> 1979 /// <param name="sp"></param>
1877 public void EnableChildAgents(ScenePresence sp) 1980 public void EnableChildAgents(ScenePresence sp)
1878 { 1981 {
1982 // assumes that out of view range regions are disconnected by the previus region
1983
1879 List<GridRegion> neighbours = new List<GridRegion>(); 1984 List<GridRegion> neighbours = new List<GridRegion>();
1880 RegionInfo m_regionInfo = sp.Scene.RegionInfo; 1985 Scene spScene = sp.Scene;
1986 RegionInfo m_regionInfo = spScene.RegionInfo;
1881 1987
1882 if (m_regionInfo != null) 1988 if (m_regionInfo != null)
1883 { 1989 {
1884 neighbours = GetNeighbours(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); 1990 neighbours = GetNeighbors(sp, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY);
1885 } 1991 }
1886 else 1992 else
1887 { 1993 {
1888 m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); 1994 m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?");
1889 } 1995 }
1890 1996
1891 /// We need to find the difference between the new regions where there are no child agents 1997 ulong currentRegionHandler = m_regionInfo.RegionHandle;
1892 /// and the regions where there are already child agents. We only send notification to the former.
1893 List<ulong> neighbourHandles = NeighbourHandles(neighbours); // on this region
1894 neighbourHandles.Add(sp.Scene.RegionInfo.RegionHandle); // add this region too
1895 List<ulong> previousRegionNeighbourHandles;
1896 1998
1897 if (sp.Scene.CapsModule != null) 1999 LinkedList<ulong> previousRegionNeighbourHandles;
2000 Dictionary<ulong, string> seeds;
2001 ICapabilitiesModule capsModule = spScene.CapsModule;
2002
2003 if (capsModule != null)
1898 { 2004 {
1899 previousRegionNeighbourHandles = 2005 seeds = new Dictionary<ulong, string>(capsModule.GetChildrenSeeds(sp.UUID));
1900 new List<ulong>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID).Keys); 2006 previousRegionNeighbourHandles = new LinkedList<ulong>(seeds.Keys);
1901 } 2007 }
1902 else 2008 else
1903 { 2009 {
1904 previousRegionNeighbourHandles = new List<ulong>(); 2010 seeds = new Dictionary<ulong, string>();
2011 previousRegionNeighbourHandles = new LinkedList<ulong>();
1905 } 2012 }
1906 2013
1907 List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); 2014 IClientAPI spClient = sp.ControllingClient;
1908 List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
1909
1910// Dump("Current Neighbors", neighbourHandles);
1911// Dump("Previous Neighbours", previousRegionNeighbourHandles);
1912// Dump("New Neighbours", newRegions);
1913// Dump("Old Neighbours", oldRegions);
1914 2015
1915 /// Update the scene presence's known regions here on this region 2016 if (!seeds.ContainsKey(currentRegionHandler))
1916 sp.DropOldNeighbours(oldRegions); 2017 seeds.Add(currentRegionHandler, spClient.RequestClientInfo().CapsPath);
1917
1918 /// Collect as many seeds as possible
1919 Dictionary<ulong, string> seeds;
1920 if (sp.Scene.CapsModule != null)
1921 seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1922 else
1923 seeds = new Dictionary<ulong, string>();
1924 2018
1925 //m_log.Debug(" !!! No. of seeds: " + seeds.Count); 2019 AgentCircuitData currentAgentCircuit =
1926 if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) 2020 spScene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1927 seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath);
1928 2021
1929 /// Create the necessary child agents
1930 List<AgentCircuitData> cagents = new List<AgentCircuitData>(); 2022 List<AgentCircuitData> cagents = new List<AgentCircuitData>();
2023 List<ulong> newneighbours = new List<ulong>();
2024
1931 foreach (GridRegion neighbour in neighbours) 2025 foreach (GridRegion neighbour in neighbours)
1932 { 2026 {
1933 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) 2027 ulong handler = neighbour.RegionHandle;
2028
2029 if (previousRegionNeighbourHandles.Contains(handler))
1934 { 2030 {
1935 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); 2031 // agent already knows this region
1936 AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); 2032 previousRegionNeighbourHandles.Remove(handler);
1937 agent.BaseFolder = UUID.Zero; 2033 continue;
1938 agent.InventoryFolder = UUID.Zero; 2034 }
1939 agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
1940 agent.child = true;
1941 agent.Appearance = sp.Appearance;
1942 if (currentAgentCircuit != null)
1943 {
1944 agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
1945 agent.IPAddress = currentAgentCircuit.IPAddress;
1946 agent.Viewer = currentAgentCircuit.Viewer;
1947 agent.Channel = currentAgentCircuit.Channel;
1948 agent.Mac = currentAgentCircuit.Mac;
1949 agent.Id0 = currentAgentCircuit.Id0;
1950 }
1951 2035
1952 if (newRegions.Contains(neighbour.RegionHandle)) 2036 if (handler == currentRegionHandler)
1953 { 2037 continue;
1954 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 2038
1955 sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); 2039 // a new region to add
1956 seeds.Add(neighbour.RegionHandle, agent.CapsPath); 2040 AgentCircuitData agent = spClient.RequestClientInfo();
1957 } 2041 agent.BaseFolder = UUID.Zero;
1958 else 2042 agent.InventoryFolder = UUID.Zero;
1959 { 2043 agent.startpos = sp.AbsolutePosition + CalculateOffset(sp, neighbour);
1960 agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); 2044 agent.child = true;
1961 } 2045 agent.Appearance = new AvatarAppearance();
2046 agent.Appearance.AvatarHeight = sp.Appearance.AvatarHeight;
1962 2047
1963 cagents.Add(agent); 2048 if (currentAgentCircuit != null)
2049 {
2050 agent.ServiceURLs = currentAgentCircuit.ServiceURLs;
2051 agent.IPAddress = currentAgentCircuit.IPAddress;
2052 agent.Viewer = currentAgentCircuit.Viewer;
2053 agent.Channel = currentAgentCircuit.Channel;
2054 agent.Mac = currentAgentCircuit.Mac;
2055 agent.Id0 = currentAgentCircuit.Id0;
1964 } 2056 }
1965 }
1966 2057
1967 /// Update all child agent with everyone's seeds 2058 newneighbours.Add(handler);
1968 foreach (AgentCircuitData a in cagents) 2059 agent.CapsPath = CapsUtil.GetRandomCapsObjectPath();
1969 { 2060 seeds.Add(handler, agent.CapsPath);
1970 a.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
1971 }
1972 2061
1973 if (sp.Scene.CapsModule != null) 2062 agent.ChildrenCapSeeds = null;
1974 { 2063 cagents.Add(agent);
1975 sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds);
1976 } 2064 }
1977 sp.KnownRegions = seeds;
1978 //avatar.Scene.DumpChildrenSeeds(avatar.UUID);
1979 //avatar.DumpKnownRegions();
1980 2065
1981 bool newAgent = false; 2066 if (previousRegionNeighbourHandles.Contains(currentRegionHandler))
1982 int count = 0; 2067 previousRegionNeighbourHandles.Remove(currentRegionHandler);
1983 foreach (GridRegion neighbour in neighbours) 2068
1984 { 2069 // previousRegionNeighbourHandles now contains regions to forget
1985 //m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName); 2070 foreach (ulong handler in previousRegionNeighbourHandles)
1986 // Don't do it if there's already an agent in that region 2071 seeds.Remove(handler);
1987 if (newRegions.Contains(neighbour.RegionHandle)) 2072
1988 newAgent = true; 2073 /// Update all child agent with everyone's seeds
1989 else 2074 // foreach (AgentCircuitData a in cagents)
1990 newAgent = false; 2075 // a.ChildrenCapSeeds = new Dictionary<ulong, string>(seeds);
1991// continue; 2076
2077 if (capsModule != null)
2078 capsModule.SetChildrenSeed(sp.UUID, seeds);
1992 2079
1993 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) 2080 sp.KnownRegions = seeds;
2081 sp.SetNeighbourRegionSizeInfo(neighbours);
2082
2083 AgentPosition agentpos = new AgentPosition();
2084 agentpos.AgentID = new UUID(sp.UUID.Guid);
2085 agentpos.SessionID = spClient.SessionId;
2086 agentpos.Size = sp.Appearance.AvatarSize;
2087 agentpos.Center = sp.CameraPosition;
2088 agentpos.Far = sp.DrawDistance;
2089 agentpos.Position = sp.AbsolutePosition;
2090 agentpos.Velocity = sp.Velocity;
2091 agentpos.RegionHandle = currentRegionHandler;
2092 agentpos.Throttles = spClient.GetThrottlesPacked(1);
2093 // agentpos.ChildrenCapSeeds = seeds;
2094
2095 Util.FireAndForget(delegate
2096 {
2097 Thread.Sleep(200); // the original delay that was at InformClientOfNeighbourAsync start
2098 int count = 0;
2099
2100 foreach (GridRegion neighbour in neighbours)
1994 { 2101 {
2102 ulong handler = neighbour.RegionHandle;
1995 try 2103 try
1996 { 2104 {
1997 // Let's put this back at sync, so that it doesn't clog 2105 if (newneighbours.Contains(handler))
1998 // the network, especially for regions in the same physical server. 2106 {
1999 // We're really not in a hurry here. 2107 InformClientOfNeighbourAsync(sp, cagents[count], neighbour,
2000 InformClientOfNeighbourAsync(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent); 2108 neighbour.ExternalEndPoint, true);
2001 //InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; 2109 count++;
2002 //d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, 2110 }
2003 // InformClientOfNeighbourCompleted, 2111 else if (!previousRegionNeighbourHandles.Contains(handler))
2004 // d); 2112 {
2113 spScene.SimulationService.UpdateAgent(neighbour, agentpos);
2114 }
2005 } 2115 }
2006
2007 catch (ArgumentOutOfRangeException) 2116 catch (ArgumentOutOfRangeException)
2008 { 2117 {
2009 m_log.ErrorFormat( 2118 m_log.ErrorFormat(
2010 "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", 2119 "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbour list. The following region will not display to the client: {0} for region {1} ({2}, {3}).",
2011 neighbour.ExternalHostName, 2120 neighbour.ExternalHostName,
2012 neighbour.RegionHandle, 2121 neighbour.RegionHandle,
2013 neighbour.RegionLocX, 2122 neighbour.RegionLocX,
2014 neighbour.RegionLocY); 2123 neighbour.RegionLocY);
2015 } 2124 }
2016 catch (Exception e) 2125 catch (Exception e)
2017 { 2126 {
@@ -2028,11 +2137,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2028 2137
2029 // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. 2138 // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes.
2030 // throw e; 2139 // throw e;
2031
2032 } 2140 }
2033 } 2141 }
2034 count++; 2142 });
2035 }
2036 } 2143 }
2037 2144
2038 // Computes the difference between two region bases. 2145 // Computes the difference between two region bases.
@@ -2040,26 +2147,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2040 // The first region is the home region of the passed scene presence. 2147 // The first region is the home region of the passed scene presence.
2041 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour) 2148 Vector3 CalculateOffset(ScenePresence sp, GridRegion neighbour)
2042 { 2149 {
2043 /* 2150 return new Vector3(sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX,
2044 int rRegionX = (int)sp.Scene.RegionInfo.LegacyRegionLocX;
2045 int rRegionY = (int)sp.Scene.RegionInfo.LegacyRegionLocY;
2046 int tRegionX = neighbour.RegionLocX / (int)Constants.RegionSize;
2047 int tRegionY = neighbour.RegionLocY / (int)Constants.RegionSize;
2048 int shiftx = (rRegionX - tRegionX) * (int)Constants.RegionSize;
2049 int shifty = (rRegionY - tRegionY) * (int)Constants.RegionSize;
2050 return new Vector3(shiftx, shifty, 0f);
2051 */
2052 return new Vector3( sp.Scene.RegionInfo.WorldLocX - neighbour.RegionLocX,
2053 sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY, 2151 sp.Scene.RegionInfo.WorldLocY - neighbour.RegionLocY,
2054 0f); 2152 0f);
2055 } 2153 }
2056 2154
2057 public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
2058 {
2059 // Since we don't know how big the regions could be, we have to search a very large area
2060 // to find possible regions.
2061 return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize);
2062 }
2063 2155
2064 #region NotFoundLocationCache class 2156 #region NotFoundLocationCache class
2065 // A collection of not found locations to make future lookups 'not found' lookups quick. 2157 // A collection of not found locations to make future lookups 'not found' lookups quick.
@@ -2144,7 +2236,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2144 #endregion // NotFoundLocationCache class 2236 #endregion // NotFoundLocationCache class
2145 private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache(); 2237 private NotFoundLocationCache m_notFoundLocationCache = new NotFoundLocationCache();
2146 2238
2147 // Given a world position (fractional meter coordinate), get the GridRegion info for 2239// needed for current OSG or old grid code
2240
2241 public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, double px, double py)
2242 {
2243 // Since we don't know how big the regions could be, we have to search a very large area
2244 // to find possible regions.
2245 return GetRegionContainingWorldLocation(pGridService, pScopeID, px, py, Constants.MaximumRegionSize);
2246 }
2247
2248 // Given a world position, get the GridRegion info for
2148 // the region containing that point. 2249 // the region containing that point.
2149 // Someday this should be a method on GridService. 2250 // Someday this should be a method on GridService.
2150 // 'pSizeHint' is the size of the source region but since the destination point can be anywhere 2251 // 'pSizeHint' is the size of the source region but since the destination point can be anywhere
@@ -2153,7 +2254,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2153 public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID, 2254 public GridRegion GetRegionContainingWorldLocation(IGridService pGridService, UUID pScopeID,
2154 double px, double py, uint pSizeHint) 2255 double px, double py, uint pSizeHint)
2155 { 2256 {
2156 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: query, loc=<{1},{2}>", LogHeader, px, py); 2257 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: call, XY=<{1},{2}>", LogHeader, px, py);
2157 GridRegion ret = null; 2258 GridRegion ret = null;
2158 const double fudge = 2.0; 2259 const double fudge = 2.0;
2159 2260
@@ -2164,7 +2265,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2164 // thus re-ask the GridService about the location. 2265 // thus re-ask the GridService about the location.
2165 if (m_notFoundLocationCache.Contains(px, py)) 2266 if (m_notFoundLocationCache.Contains(px, py))
2166 { 2267 {
2167 m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py); 2268// m_log.DebugFormat("{0} GetRegionContainingWorldLocation: Not found via cache. loc=<{1},{2}>", LogHeader, px, py);
2168 return null; 2269 return null;
2169 } 2270 }
2170 2271
@@ -2246,55 +2347,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2246 private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, 2347 private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg,
2247 IPEndPoint endPoint, bool newAgent) 2348 IPEndPoint endPoint, bool newAgent)
2248 { 2349 {
2249 // Let's wait just a little to give time to originating regions to catch up with closing child agents
2250 // after a cross here
2251 Thread.Sleep(500);
2252 2350
2253 Scene scene = sp.Scene; 2351 if (newAgent)
2254 2352 {
2255 m_log.DebugFormat( 2353 Scene scene = sp.Scene;
2256 "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
2257 sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY);
2258 2354
2259 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath); 2355 m_log.DebugFormat(
2356 "[ENTITY TRANSFER MODULE]: Informing {0} {1} about neighbour {2} {3} at ({4},{5})",
2357 sp.Name, sp.UUID, reg.RegionName, endPoint, reg.RegionCoordX, reg.RegionCoordY);
2260 2358
2261 string reason = String.Empty; 2359 string capsPath = reg.ServerURI + CapsUtil.GetCapsSeedPath(a.CapsPath);
2262 2360
2263 bool regionAccepted = scene.SimulationService.CreateAgent(null, reg, a, (uint)TeleportFlags.Default, out reason); 2361 string reason = String.Empty;
2264 2362
2265 if (regionAccepted && newAgent) 2363 EntityTransferContext ctx = new EntityTransferContext();
2266 { 2364 bool regionAccepted = scene.SimulationService.CreateAgent(reg, reg, a, (uint)TeleportFlags.Default, ctx, out reason);
2267 if (m_eqModule != null) 2365
2366 if (regionAccepted)
2268 { 2367 {
2269 #region IP Translation for NAT 2368 // give time for createAgent to finish, since it is async and does grid services access
2270 IClientIPEndpoint ipepClient; 2369 Thread.Sleep(500);
2271 if (sp.ClientView.TryGet(out ipepClient)) 2370
2371 if (m_eqModule != null)
2272 { 2372 {
2273 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); 2373 #region IP Translation for NAT
2274 } 2374 IClientIPEndpoint ipepClient;
2275 #endregion 2375 if (sp.ClientView.TryGet(out ipepClient))
2376 {
2377 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
2378 }
2379 #endregion
2276 2380
2277 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " + 2381 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
2278 "and EstablishAgentCommunication with seed cap {8}", LogHeader, 2382 "and EstablishAgentCommunication with seed cap {8}", LogHeader,
2279 scene.RegionInfo.RegionName, sp.Name, 2383 scene.RegionInfo.RegionName, sp.Name,
2280 reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath); 2384 reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY, capsPath);
2281 2385
2282 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY); 2386 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY);
2283 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY); 2387 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
2284 } 2388 }
2285 else 2389 else
2286 { 2390 {
2287 sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint); 2391 sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint);
2288 // TODO: make Event Queue disablable! 2392 // TODO: make Event Queue disablable!
2393 }
2394
2395 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint);
2289 } 2396 }
2290 2397
2291 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Completed inform {0} {1} about neighbour {2}", sp.Name, sp.UUID, endPoint); 2398 if (!regionAccepted)
2399 m_log.WarnFormat(
2400 "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}",
2401 reg.RegionName, sp.Name, sp.UUID, reason);
2292 } 2402 }
2293 2403
2294 if (!regionAccepted)
2295 m_log.WarnFormat(
2296 "[ENTITY TRANSFER MODULE]: Region {0} did not accept {1} {2}: {3}",
2297 reg.RegionName, sp.Name, sp.UUID, reason);
2298 } 2404 }
2299 2405
2300 /// <summary> 2406 /// <summary>
@@ -2327,7 +2433,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2327 /// <param name="pRegionLocX"></param> 2433 /// <param name="pRegionLocX"></param>
2328 /// <param name="pRegionLocY"></param> 2434 /// <param name="pRegionLocY"></param>
2329 /// <returns></returns> 2435 /// <returns></returns>
2330 protected List<GridRegion> GetNeighbours(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY) 2436 protected List<GridRegion> GetNeighbors(ScenePresence avatar, uint pRegionLocX, uint pRegionLocY)
2331 { 2437 {
2332 Scene pScene = avatar.Scene; 2438 Scene pScene = avatar.Scene;
2333 RegionInfo m_regionInfo = pScene.RegionInfo; 2439 RegionInfo m_regionInfo = pScene.RegionInfo;
@@ -2338,18 +2444,27 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2338 // view to include everything in the megaregion 2444 // view to include everything in the megaregion
2339 if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID)) 2445 if (m_regionCombinerModule == null || !m_regionCombinerModule.IsRootForMegaregion(Scene.RegionInfo.RegionID))
2340 { 2446 {
2341 // The area to check is as big as the current region. 2447 uint dd = (uint)avatar.DrawDistance;
2342 // We presume all adjacent regions are the same size as this region.
2343 uint dd = Math.Max((uint)avatar.Scene.DefaultDrawDistance,
2344 Math.Max(Scene.RegionInfo.RegionSizeX, Scene.RegionInfo.RegionSizeY));
2345 2448
2346 uint startX = Util.RegionToWorldLoc(pRegionLocX) - dd + Constants.RegionSize/2; 2449 // until avatar movement updates client connections, we need to seend at least this current region imediate Neighbors
2347 uint startY = Util.RegionToWorldLoc(pRegionLocY) - dd + Constants.RegionSize/2; 2450 uint ddX = Math.Max(dd, Constants.RegionSize);
2451 uint ddY = Math.Max(dd, Constants.RegionSize);
2348 2452
2349 uint endX = Util.RegionToWorldLoc(pRegionLocX) + dd + Constants.RegionSize/2; 2453 ddX--;
2350 uint endY = Util.RegionToWorldLoc(pRegionLocY) + dd + Constants.RegionSize/2; 2454 ddY--;
2351 2455
2352 neighbours 2456 // reference to region edges. Should be avatar position
2457 uint startX = Util.RegionToWorldLoc(pRegionLocX);
2458 uint endX = startX + m_regionInfo.RegionSizeX;
2459 uint startY = Util.RegionToWorldLoc(pRegionLocY);
2460 uint endY = startY + m_regionInfo.RegionSizeY;
2461
2462 startX -= ddX;
2463 startY -= ddY;
2464 endX += ddX;
2465 endY += ddY;
2466
2467 neighbours
2353 = avatar.Scene.GridService.GetRegionRange( 2468 = avatar.Scene.GridService.GetRegionRange(
2354 m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY); 2469 m_regionInfo.ScopeID, (int)startX, (int)endX, (int)startY, (int)endY);
2355 } 2470 }
@@ -2365,72 +2480,70 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2365 (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y)); 2480 (int)Util.RegionToWorldLoc((uint)swCorner.Y), (int)Util.RegionToWorldLoc((uint)neCorner.Y));
2366 } 2481 }
2367 2482
2368// neighbours.ForEach(
2369// n =>
2370// m_log.DebugFormat(
2371// "[ENTITY TRANSFER MODULE]: Region flags for {0} as seen by {1} are {2}",
2372// n.RegionName, Scene.Name, n.RegionFlags != null ? n.RegionFlags.ToString() : "not present"));
2373
2374 // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1). 2483 // The r.RegionFlags == null check only needs to be made for simulators before 2015-01-14 (pre 0.8.1).
2375 neighbours.RemoveAll( 2484 neighbours.RemoveAll( r => r.RegionID == m_regionInfo.RegionID );
2376 r =>
2377 r.RegionID == m_regionInfo.RegionID
2378 || (r.RegionFlags != null && (r.RegionFlags & OpenSim.Framework.RegionFlags.RegionOnline) == 0));
2379 2485
2380 return neighbours; 2486 return neighbours;
2381 } 2487 }
2488 #endregion
2489
2490 #region Agent Arrived
2382 2491
2383 private List<ulong> NewNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) 2492 public void AgentArrivedAtDestination(UUID id)
2384 { 2493 {
2385 return currentNeighbours.FindAll(delegate(ulong handle) { return !previousNeighbours.Contains(handle); }); 2494 m_entityTransferStateMachine.SetAgentArrivedAtDestination(id);
2386 } 2495 }
2387 2496
2388 // private List<ulong> CommonNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) 2497 #endregion
2389 // {
2390 // return currentNeighbours.FindAll(delegate(ulong handle) { return previousNeighbours.Contains(handle); });
2391 // }
2392 2498
2393 private List<ulong> OldNeighbours(List<ulong> currentNeighbours, List<ulong> previousNeighbours) 2499 #region Object Transfers
2394 {
2395 return previousNeighbours.FindAll(delegate(ulong handle) { return !currentNeighbours.Contains(handle); });
2396 }
2397 2500
2398 private List<ulong> NeighbourHandles(List<GridRegion> neighbours) 2501 public GridRegion GetObjectDestination(SceneObjectGroup grp, Vector3 targetPosition,out Vector3 newpos)
2399 { 2502 {
2400 List<ulong> handles = new List<ulong>(); 2503 newpos = targetPosition;
2401 foreach (GridRegion reg in neighbours) 2504
2505 Scene scene = grp.Scene;
2506 if (scene == null)
2507 return null;
2508
2509 int x = (int)targetPosition.X + (int)scene.RegionInfo.WorldLocX;
2510 if (targetPosition.X >= 0)
2511 x++;
2512 else
2513 x--;
2514
2515 int y = (int)targetPosition.Y + (int)scene.RegionInfo.WorldLocY;
2516 if (targetPosition.Y >= 0)
2517 y++;
2518 else
2519 y--;
2520
2521 GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID,x,y);
2522 if (neighbourRegion == null)
2402 { 2523 {
2403 handles.Add(reg.RegionHandle); 2524 return null;
2404 } 2525 }
2405 return handles;
2406 }
2407 2526
2408// private void Dump(string msg, List<ulong> handles) 2527 float newRegionSizeX = neighbourRegion.RegionSizeX;
2409// { 2528 float newRegionSizeY = neighbourRegion.RegionSizeY;
2410// m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg); 2529 if (newRegionSizeX == 0)
2411// foreach (ulong handle in handles) 2530 newRegionSizeX = Constants.RegionSize;
2412// { 2531 if (newRegionSizeY == 0)
2413// uint x, y; 2532 newRegionSizeY = Constants.RegionSize;
2414// Utils.LongToUInts(handle, out x, out y);
2415// x = x / Constants.RegionSize;
2416// y = y / Constants.RegionSize;
2417// m_log.InfoFormat("({0}, {1})", x, y);
2418// }
2419// }
2420 2533
2421 #endregion
2422 2534
2423 #region Agent Arrived 2535 newpos.X = targetPosition.X - (neighbourRegion.RegionLocX - (int)scene.RegionInfo.WorldLocX);
2536 newpos.Y = targetPosition.Y - (neighbourRegion.RegionLocY - (int)scene.RegionInfo.WorldLocY);
2424 2537
2425 public void AgentArrivedAtDestination(UUID id)
2426 {
2427 m_entityTransferStateMachine.SetAgentArrivedAtDestination(id);
2428 }
2429 2538
2430 #endregion 2539 const float enterDistance = 0.2f;
2540 newpos.X = Util.Clamp(newpos.X, enterDistance, newRegionSizeX - enterDistance);
2541 newpos.Y = Util.Clamp(newpos.Y, enterDistance, newRegionSizeY - enterDistance);
2431 2542
2432 #region Object Transfers 2543 return neighbourRegion;
2544 }
2433 2545
2546/* not in use. -> CrossPrimGroupIntoNewRegion
2434 /// <summary> 2547 /// <summary>
2435 /// Move the given scene object into a new region depending on which region its absolute position has moved 2548 /// Move the given scene object into a new region depending on which region its absolute position has moved
2436 /// into. 2549 /// into.
@@ -2453,20 +2566,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2453 if (scene == null) 2566 if (scene == null)
2454 return; 2567 return;
2455 2568
2456 if (grp.RootPart.DIE_AT_EDGE)
2457 {
2458 // We remove the object here
2459 try
2460 {
2461 scene.DeleteSceneObject(grp, false);
2462 }
2463 catch (Exception)
2464 {
2465 m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border.");
2466 }
2467 return;
2468 }
2469
2470 // Remember the old group position in case the region lookup fails so position can be restored. 2569 // Remember the old group position in case the region lookup fails so position can be restored.
2471 Vector3 oldGroupPosition = grp.RootPart.GroupPosition; 2570 Vector3 oldGroupPosition = grp.RootPart.GroupPosition;
2472 2571
@@ -2509,7 +2608,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2509 grp.ScheduleGroupForFullUpdate(); 2608 grp.ScheduleGroupForFullUpdate();
2510 } 2609 }
2511 } 2610 }
2512 2611*/
2513 /// <summary> 2612 /// <summary>
2514 /// Move the given scene object into a new region 2613 /// Move the given scene object into a new region
2515 /// </summary> 2614 /// </summary>
@@ -2519,7 +2618,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2519 /// true if the crossing itself was successful, false on failure 2618 /// true if the crossing itself was successful, false on failure
2520 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region 2619 /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region
2521 /// </returns> 2620 /// </returns>
2522 protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent) 2621 public bool CrossPrimGroupIntoNewRegion(GridRegion destination, Vector3 newPosition, SceneObjectGroup grp, bool silent, bool removeScripts)
2523 { 2622 {
2524 //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); 2623 //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<");
2525 2624
@@ -2551,7 +2650,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2551 // We remove the object here 2650 // We remove the object here
2552 try 2651 try
2553 { 2652 {
2554 grp.Scene.DeleteSceneObject(grp, silent); 2653 grp.Scene.DeleteSceneObject(grp, silent, removeScripts);
2555 } 2654 }
2556 catch (Exception e) 2655 catch (Exception e)
2557 { 2656 {
@@ -2560,30 +2659,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2560 grp, e); 2659 grp, e);
2561 } 2660 }
2562 } 2661 }
2563/*
2564 * done on caller ( not in attachments crossing for now)
2565 else
2566 {
2567
2568 if (!grp.IsDeleted)
2569 {
2570 PhysicsActor pa = grp.RootPart.PhysActor;
2571 if (pa != null)
2572 {
2573 pa.CrossingFailure();
2574 if (grp.RootPart.KeyframeMotion != null)
2575 {
2576 // moved to KeyframeMotion.CrossingFailure
2577// grp.RootPart.Velocity = Vector3.Zero;
2578 grp.RootPart.KeyframeMotion.CrossingFailure();
2579// grp.SendGroupRootTerseUpdate();
2580 }
2581 }
2582 }
2583
2584 m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp);
2585 }
2586 */
2587 } 2662 }
2588 else 2663 else
2589 { 2664 {
@@ -2625,7 +2700,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2625 "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", 2700 "[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}",
2626 clone.UUID, destination.RegionName); 2701 clone.UUID, destination.RegionName);
2627 2702
2628 CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent); 2703 CrossPrimGroupIntoNewRegion(destination, Vector3.Zero, clone, silent,true);
2629 } 2704 }
2630 } 2705 }
2631 2706
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
index a3109e0..e3c6c0d 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferStateMachine.cs
@@ -299,7 +299,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
299 id, m_mod.Scene.RegionInfo.RegionName, currentState)); 299 id, m_mod.Scene.RegionInfo.RegionName, currentState));
300 } 300 }
301 301
302 int count = 200; 302 int count = 400;
303 303
304 // There should be no race condition here since no other code should be removing the agent transfer or 304 // There should be no race condition here since no other code should be removing the agent transfer or
305 // changing the state to another other than Transferring => ReceivedAtDestination. 305 // changing the state to another other than Transferring => ReceivedAtDestination.
@@ -354,4 +354,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
354 } 354 }
355 } 355 }
356 } 356 }
357} \ No newline at end of file 357}
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index fa23590..1783e0a 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -239,13 +239,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
239 return region; 239 return region;
240 } 240 }
241 241
242 protected override bool NeedsClosing(float drawdist, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) 242 protected override bool NeedsClosing(GridRegion reg, bool OutViewRange)
243 { 243 {
244 if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 244 if (OutViewRange)
245 return true; 245 return true;
246 246
247 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID); 247 int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
248 if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0) 248 if (flags == -1 || (flags & (int)OpenSim.Framework.RegionFlags.Hyperlink) != 0)
249 return true; 249 return true;
250 250
251 return false; 251 return false;
@@ -263,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
263 } 263 }
264 } 264 }
265 265
266 protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) 266 protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, EntityTransferContext ctx, out string reason, out bool logout)
267 { 267 {
268 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); 268 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI);
269 reason = string.Empty; 269 reason = string.Empty;
@@ -308,7 +308,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
308 } 308 }
309 } 309 }
310 310
311 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout); 311 return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, ctx, out reason, out logout);
312 }
313
314 public void TriggerTeleportHome(UUID id, IClientAPI client)
315 {
316 TeleportHome(id, client);
312 } 317 }
313 318
314 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason) 319 protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
@@ -328,7 +333,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
328 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance"); 333 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
329 334
330 // Check wearables 335 // Check wearables
331 for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++) 336 for (int i = 0; i < sp.Appearance.Wearables.Length ; i++)
332 { 337 {
333 for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++) 338 for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
334 { 339 {
@@ -337,7 +342,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
337 342
338 bool found = false; 343 bool found = false;
339 foreach (AvatarAppearance a in ExportedAppearance) 344 foreach (AvatarAppearance a in ExportedAppearance)
340 if (a.Wearables[i] != null) 345 if (i < a.Wearables.Length && a.Wearables[i] != null)
341 { 346 {
342 found = true; 347 found = true;
343 break; 348 break;
@@ -351,7 +356,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
351 356
352 found = false; 357 found = false;
353 foreach (AvatarAppearance a in ExportedAppearance) 358 foreach (AvatarAppearance a in ExportedAppearance)
354 if (sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID) 359 if (i < a.Wearables.Length && sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID)
355 { 360 {
356 found = true; 361 found = true;
357 break; 362 break;
@@ -429,10 +434,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
429 // return base.UpdateAgent(reg, finalDestination, agentData, sp); 434 // return base.UpdateAgent(reg, finalDestination, agentData, sp);
430 //} 435 //}
431 436
432 public override void TriggerTeleportHome(UUID id, IClientAPI client)
433 {
434 TeleportHome(id, client);
435 }
436 437
437 public override bool TeleportHome(UUID id, IClientAPI client) 438 public override bool TeleportHome(UUID id, IClientAPI client)
438 { 439 {
@@ -491,9 +492,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
491 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}", 492 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}",
492 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName); 493 aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ServerURI, homeGatekeeper.RegionName);
493 494
494 DoTeleport( 495 DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
495 sp, homeGatekeeper, finalDestination,
496 position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome));
497 return true; 496 return true;
498 } 497 }
499 498
@@ -760,4 +759,4 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
760 return region; 759 return region;
761 } 760 }
762 } 761 }
763} \ No newline at end of file 762}