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.cs353
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs42
2 files changed, 337 insertions, 58 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index ed867b8..5fea0cf 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -51,11 +51,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")] 51 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EntityTransferModule")]
52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule 52 public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule
53 { 53 {
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55 private static readonly string LogHeader = "[ENTITY TRANSFER MODULE]";
55 56
56 public const int DefaultMaxTransferDistance = 4095; 57 public const int DefaultMaxTransferDistance = 4095;
57 public const bool WaitForAgentArrivedAtDestinationDefault = true; 58 public const bool WaitForAgentArrivedAtDestinationDefault = true;
58 59
60 public string OutgoingTransferVersionName { get; set; }
61
62 /// <summary>
63 /// Determine the maximum entity transfer version we will use for teleports.
64 /// </summary>
65 public float MaxOutgoingTransferVersion { get; set; }
66
59 /// <summary> 67 /// <summary>
60 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer. 68 /// The maximum distance, in standard region units (256m) that an agent is allowed to transfer.
61 /// </summary> 69 /// </summary>
@@ -151,9 +159,39 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
151 /// <param name="source"></param> 159 /// <param name="source"></param>
152 protected virtual void InitialiseCommon(IConfigSource source) 160 protected virtual void InitialiseCommon(IConfigSource source)
153 { 161 {
162 string transferVersionName = "SIMULATION";
163 float maxTransferVersion = 0.2f;
164
154 IConfig transferConfig = source.Configs["EntityTransfer"]; 165 IConfig transferConfig = source.Configs["EntityTransfer"];
155 if (transferConfig != null) 166 if (transferConfig != null)
156 { 167 {
168 string rawVersion
169 = transferConfig.GetString(
170 "MaxOutgoingTransferVersion",
171 string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
172
173 string[] rawVersionComponents = rawVersion.Split(new char[] { '/' });
174
175 bool versionValid = false;
176
177 if (rawVersionComponents.Length >= 2)
178 versionValid = float.TryParse(rawVersionComponents[1], out maxTransferVersion);
179
180 if (!versionValid)
181 {
182 m_log.ErrorFormat(
183 "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion {0} is invalid, using {1}",
184 rawVersion, string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
185 }
186 else
187 {
188 transferVersionName = rawVersionComponents[0];
189
190 m_log.InfoFormat(
191 "[ENTITY TRANSFER MODULE]: MaxOutgoingTransferVersion set to {0}",
192 string.Format("{0}/{1}", transferVersionName, maxTransferVersion));
193 }
194
157 DisableInterRegionTeleportCancellation 195 DisableInterRegionTeleportCancellation
158 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false); 196 = transferConfig.GetBoolean("DisableInterRegionTeleportCancellation", false);
159 197
@@ -167,6 +205,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
167 MaxTransferDistance = DefaultMaxTransferDistance; 205 MaxTransferDistance = DefaultMaxTransferDistance;
168 } 206 }
169 207
208 OutgoingTransferVersionName = transferVersionName;
209 MaxOutgoingTransferVersion = maxTransferVersion;
210
170 m_entityTransferStateMachine = new EntityTransferStateMachine(this); 211 m_entityTransferStateMachine = new EntityTransferStateMachine(this);
171 212
172 m_Enabled = true; 213 m_Enabled = true;
@@ -280,10 +321,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
280 321
281 private void OnConnectionClosed(IClientAPI client) 322 private void OnConnectionClosed(IClientAPI client)
282 { 323 {
283 if (client.IsLoggingOut) 324 if (client.IsLoggingOut && m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting))
284 { 325 {
285 m_entityTransferStateMachine.UpdateInTransit(client.AgentId, AgentTransferState.Aborting);
286
287 m_log.DebugFormat( 326 m_log.DebugFormat(
288 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout", 327 "[ENTITY TRANSFER MODULE]: Aborted teleport request from {0} in {1} due to simultaneous logout",
289 client.Name, Scene.Name); 328 client.Name, Scene.Name);
@@ -318,7 +357,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
318 m_log.DebugFormat( 357 m_log.DebugFormat(
319 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.", 358 "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2}@{3} - agent is already in transit.",
320 sp.Name, sp.UUID, position, regionHandle); 359 sp.Name, sp.UUID, position, regionHandle);
321 360
361 sp.ControllingClient.SendTeleportFailed("Previous teleport process incomplete. Please retry shortly.");
362
322 return; 363 return;
323 } 364 }
324 365
@@ -522,6 +563,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
522 /// </returns> 563 /// </returns>
523 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion) 564 private bool IsWithinMaxTeleportDistance(RegionInfo sourceRegion, GridRegion destRegion)
524 { 565 {
566 if(MaxTransferDistance == 0)
567 return true;
568
525// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY); 569// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Source co-ords are x={0} y={1}", curRegionX, curRegionY);
526// 570//
527// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}", 571// m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final dest is x={0} y={1} {2}@{3}",
@@ -623,7 +667,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
623 if (!sp.ValidateAttachments()) 667 if (!sp.ValidateAttachments())
624 m_log.DebugFormat( 668 m_log.DebugFormat(
625 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", 669 "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.",
626 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); 670 sp.Name, sp.Scene.Name, finalDestination.RegionName);
627 671
628 string reason; 672 string reason;
629 string version; 673 string version;
@@ -634,7 +678,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
634 678
635 m_log.DebugFormat( 679 m_log.DebugFormat(
636 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", 680 "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}",
637 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); 681 sp.Name, sp.Scene.Name, finalDestination.RegionName, reason);
638 682
639 return; 683 return;
640 } 684 }
@@ -644,7 +688,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
644 // as server attempts. 688 // as server attempts.
645 m_interRegionTeleportAttempts.Value++; 689 m_interRegionTeleportAttempts.Value++;
646 690
647 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); 691 m_log.DebugFormat(
692 "[ENTITY TRANSFER MODULE]: {0} max transfer version is {1}/{2}, {3} max version is {4}",
693 sp.Scene.Name, OutgoingTransferVersionName, MaxOutgoingTransferVersion, finalDestination.RegionName, version);
648 694
649 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from 695 // Fixing a bug where teleporting while sitting results in the avatar ending up removed from
650 // both regions 696 // both regions
@@ -691,6 +737,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
691 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); 737 agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath();
692 } 738 }
693 739
740 // We're going to fallback to V1 if the destination gives us anything smaller than 0.2 or we're forcing
741 // use of the earlier protocol
742 float versionNumber = 0.1f;
743 string[] versionComponents = version.Split(new char[] { '/' });
744 if (versionComponents.Length >= 2)
745 float.TryParse(versionComponents[1], out versionNumber);
746
747 if (versionNumber == 0.2f && MaxOutgoingTransferVersion >= versionNumber)
748 TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
749 else
750 TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason);
751 }
752
753 private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
754 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason)
755 {
756 ulong destinationHandle = finalDestination.RegionHandle;
757 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
758
759 m_log.DebugFormat(
760 "[ENTITY TRANSFER MODULE]: Using TP V1 for {0} going from {1} to {2}",
761 sp.Name, Scene.Name, finalDestination.RegionName);
762
694 // Let's create an agent there if one doesn't exist yet. 763 // Let's create an agent there if one doesn't exist yet.
695 // NOTE: logout will always be false for a non-HG teleport. 764 // NOTE: logout will always be false for a non-HG teleport.
696 bool logout = false; 765 bool logout = false;
@@ -712,7 +781,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
712 m_interRegionTeleportCancels.Value++; 781 m_interRegionTeleportCancels.Value++;
713 782
714 m_log.DebugFormat( 783 m_log.DebugFormat(
715 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", 784 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
716 sp.Name, finalDestination.RegionName, sp.Scene.Name); 785 sp.Name, finalDestination.RegionName, sp.Scene.Name);
717 786
718 return; 787 return;
@@ -734,11 +803,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
734 // OK, it got this agent. Let's close some child agents 803 // OK, it got this agent. Let's close some child agents
735 sp.CloseChildAgents(newRegionX, newRegionY); 804 sp.CloseChildAgents(newRegionX, newRegionY);
736 805
737 IClientIPEndpoint ipepClient; 806 IClientIPEndpoint ipepClient;
807 string capsPath = String.Empty;
738 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) 808 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
739 { 809 {
740 m_log.DebugFormat( 810 m_log.DebugFormat(
741 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", 811 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}",
742 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); 812 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
743 813
744 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); 814 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
@@ -756,7 +826,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
756 // The EnableSimulator message makes the client establish a connection with the destination 826 // The EnableSimulator message makes the client establish a connection with the destination
757 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the 827 // simulator by sending the initial UseCircuitCode UDP packet to the destination containing the
758 // correct circuit code. 828 // correct circuit code.
759 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID); 829 m_eqModule.EnableSimulator(destinationHandle, endPoint, sp.UUID,
830 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
831 m_log.DebugFormat("{0} Sent EnableSimulator. regName={1}, size=<{2},{3}>", LogHeader,
832 finalDestination.RegionName, finalDestination.RegionSizeX, finalDestination.RegionSizeY);
760 833
761 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination 834 // XXX: Is this wait necessary? We will always end up waiting on UpdateAgent for the destination
762 // simulator to confirm that it has established communication with the viewer. 835 // simulator to confirm that it has established communication with the viewer.
@@ -766,7 +839,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
766 // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly 839 // unnecessary - teleport will succeed and SEED caps will be requested without it (though possibly
767 // only on TeleportFinish). This is untested for region teleport between different simulators 840 // only on TeleportFinish). This is untested for region teleport between different simulators
768 // though this probably also works. 841 // though this probably also works.
769 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 842 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, finalDestination.RegionHandle,
843 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
770 } 844 }
771 else 845 else
772 { 846 {
@@ -785,10 +859,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
785 // Let's send a full update of the agent. This is a synchronous call. 859 // Let's send a full update of the agent. This is a synchronous call.
786 AgentData agent = new AgentData(); 860 AgentData agent = new AgentData();
787 sp.CopyTo(agent); 861 sp.CopyTo(agent);
788 agent.Position = position; 862 agent.Position = agentCircuit.startpos;
789 SetCallbackURL(agent, sp.Scene.RegionInfo); 863 SetCallbackURL(agent, sp.Scene.RegionInfo);
790 864
791 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
792 865
793 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to 866 // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to
794 // establish th econnection to the destination which makes it return true. 867 // establish th econnection to the destination which makes it return true.
@@ -821,10 +894,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
821 } 894 }
822 895
823 m_log.WarnFormat( 896 m_log.WarnFormat(
824 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", 897 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
825 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 898 sp.Name, finalDestination.RegionName, sp.Scene.Name);
826 899
827 Fail(sp, finalDestination, logout, "Connection between viewer and destination region could not be established."); 900 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
828 return; 901 return;
829 } 902 }
830 903
@@ -833,10 +906,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
833 m_interRegionTeleportCancels.Value++; 906 m_interRegionTeleportCancels.Value++;
834 907
835 m_log.DebugFormat( 908 m_log.DebugFormat(
836 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", 909 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request",
837 sp.Name, finalDestination.RegionName, sp.Scene.Name); 910 sp.Name, finalDestination.RegionName, sp.Scene.Name);
838 911
839 CleanupFailedInterRegionTeleport(sp, finalDestination); 912 CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination);
840 913
841 return; 914 return;
842 } 915 }
@@ -850,9 +923,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
850 // closes our existing agent which is still signalled as root. 923 // closes our existing agent which is still signalled as root.
851 sp.IsChildAgent = true; 924 sp.IsChildAgent = true;
852 925
926 // OK, send TPFinish to the client, so that it starts the process of contacting the destination region
853 if (m_eqModule != null) 927 if (m_eqModule != null)
854 { 928 {
855 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); 929 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID,
930 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
856 } 931 }
857 else 932 else
858 { 933 {
@@ -879,8 +954,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
879 m_log.WarnFormat( 954 m_log.WarnFormat(
880 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", 955 "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.",
881 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); 956 sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName);
882 957
883 Fail(sp, finalDestination, logout, "Destination region did not signal teleport completion."); 958 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion.");
884 959
885 return; 960 return;
886 } 961 }
@@ -908,15 +983,190 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
908 983
909 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) 984 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
910 { 985 {
986 if (!sp.Scene.IncomingPreCloseClient(sp))
987 return;
988
911 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before 989 // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before
912 // they regard the new region as the current region after receiving the AgentMovementComplete 990 // they regard the new region as the current region after receiving the AgentMovementComplete
913 // response. If close is sent before then, it will cause the viewer to quit instead. 991 // response. If close is sent before then, it will cause the viewer to quit instead.
914 // 992 //
915 // This sleep can be increased if necessary. However, whilst it's active, 993 // This sleep can be increased if necessary. However, whilst it's active,
916 // an agent cannot teleport back to this region if it has teleported away. 994 // an agent cannot teleport back to this region if it has teleported away.
917 Thread.Sleep(3000); 995 Thread.Sleep(2000);
918 996
919 sp.Scene.IncomingCloseAgent(sp.UUID, false); 997 sp.Scene.CloseAgent(sp.UUID, false);
998 }
999 else
1000 {
1001 // now we have a child agent in this region.
1002 sp.Reset();
1003 }
1004 }
1005
1006 private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination,
1007 IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason)
1008 {
1009 ulong destinationHandle = finalDestination.RegionHandle;
1010 AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode);
1011
1012 // Let's create an agent there if one doesn't exist yet.
1013 // NOTE: logout will always be false for a non-HG teleport.
1014 bool logout = false;
1015 if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout))
1016 {
1017 m_interRegionTeleportFailures.Value++;
1018
1019 sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason));
1020
1021 m_log.DebugFormat(
1022 "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}",
1023 sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason);
1024
1025 return;
1026 }
1027
1028 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Cancelling)
1029 {
1030 m_interRegionTeleportCancels.Value++;
1031
1032 m_log.DebugFormat(
1033 "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request",
1034 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1035
1036 return;
1037 }
1038 else if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
1039 {
1040 m_interRegionTeleportAborts.Value++;
1041
1042 m_log.DebugFormat(
1043 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after CreateAgent due to previous client close.",
1044 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1045
1046 return;
1047 }
1048
1049 // Past this point we have to attempt clean up if the teleport fails, so update transfer state.
1050 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring);
1051
1052 IClientIPEndpoint ipepClient;
1053 string capsPath = String.Empty;
1054 if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY))
1055 {
1056 m_log.DebugFormat(
1057 "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}",
1058 finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name);
1059
1060 //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent...");
1061 #region IP Translation for NAT
1062 // Uses ipepClient above
1063 if (sp.ClientView.TryGet(out ipepClient))
1064 {
1065 endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address);
1066 }
1067 #endregion
1068 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1069 }
1070 else
1071 {
1072 agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle);
1073 capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath);
1074 }
1075
1076 // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator,
1077 // where that neighbour simulator could otherwise request a child agent create on the source which then
1078 // closes our existing agent which is still signalled as root.
1079 //sp.IsChildAgent = true;
1080
1081 // New protocol: send TP Finish directly, without prior ES or EAC. That's what happens in the Linden grid
1082 if (m_eqModule != null)
1083 m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID,
1084 finalDestination.RegionSizeX, finalDestination.RegionSizeY);
1085 else
1086 sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4,
1087 teleportFlags, capsPath);
1088
1089 m_log.DebugFormat(
1090 "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}",
1091 capsPath, sp.Scene.RegionInfo.RegionName, sp.Name);
1092
1093 // Let's send a full update of the agent.
1094 AgentData agent = new AgentData();
1095 sp.CopyTo(agent);
1096 agent.Position = agentCircuit.startpos;
1097 agent.SenderWantsToWaitForRoot = true;
1098 //SetCallbackURL(agent, sp.Scene.RegionInfo);
1099
1100 // Reset the do not close flag. This must be done before the destination opens child connections (here
1101 // triggered by UpdateAgent) to avoid race conditions. However, we also want to reset it as late as possible
1102 // to avoid a situation where an unexpectedly early call to Scene.NewUserConnection() wrongly results
1103 // in no close.
1104 sp.DoNotCloseAfterTeleport = false;
1105
1106 // Send the Update. If this returns true, we know the client has contacted the destination
1107 // via CompleteMovementIntoRegion, so we can let go.
1108 // If it returns false, something went wrong, and we need to abort.
1109 if (!UpdateAgent(reg, finalDestination, agent, sp))
1110 {
1111 if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting)
1112 {
1113 m_interRegionTeleportAborts.Value++;
1114
1115 m_log.DebugFormat(
1116 "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.",
1117 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1118
1119 return;
1120 }
1121
1122 m_log.WarnFormat(
1123 "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1}. Keeping avatar in {2}",
1124 sp.Name, finalDestination.RegionName, sp.Scene.Name);
1125
1126 Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established.");
1127 return;
1128 }
1129
1130 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
1131
1132 // Need to signal neighbours whether child agents may need closing irrespective of whether this
1133 // one needed closing. We also need to close child agents as quickly as possible to avoid complicated
1134 // race conditions with rapid agent releporting (e.g. from A1 to a non-neighbour B, back
1135 // to a neighbour A2 then off to a non-neighbour C). Closing child agents any later requires complex
1136 // distributed checks to avoid problems in rapid reteleporting scenarios and where child agents are
1137 // abandoned without proper close by viewer but then re-used by an incoming connection.
1138 sp.CloseChildAgents(newRegionX, newRegionY);
1139
1140 // May need to logout or other cleanup
1141 AgentHasMovedAway(sp, logout);
1142
1143 // Well, this is it. The agent is over there.
1144 KillEntity(sp.Scene, sp.LocalId);
1145
1146 // Now let's make it officially a child agent
1147 sp.MakeChildAgent();
1148
1149 // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone
1150 if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg))
1151 {
1152 if (!sp.Scene.IncomingPreCloseClient(sp))
1153 return;
1154
1155 // RED ALERT!!!!
1156 // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES.
1157 // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion
1158 // BEFORE THEY SETTLE IN THE NEW REGION.
1159 // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR
1160 // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS.
1161 Thread.Sleep(15000);
1162
1163 // OK, it got this agent. Let's close everything
1164 // If we shouldn't close the agent due to some other region renewing the connection
1165 // then this will be handled in IncomingCloseAgent under lock conditions
1166 m_log.DebugFormat(
1167 "[ENTITY TRANSFER MODULE]: Closing agent {0} in {1} after teleport", sp.Name, Scene.Name);
1168
1169 sp.Scene.CloseAgent(sp.UUID, false);
920 } 1170 }
921 else 1171 else
922 { 1172 {
@@ -934,17 +1184,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
934 /// <remarks> 1184 /// <remarks>
935 /// <param name='sp'> </param> 1185 /// <param name='sp'> </param>
936 /// <param name='finalDestination'></param> 1186 /// <param name='finalDestination'></param>
937 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, GridRegion finalDestination) 1187 protected virtual void CleanupFailedInterRegionTeleport(ScenePresence sp, string auth_token, GridRegion finalDestination)
938 { 1188 {
939 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); 1189 m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp);
940 1190
941 sp.IsChildAgent = false; 1191 if (sp.IsChildAgent) // We had set it to child before attempted TP (V1)
942 ReInstantiateScripts(sp); 1192 {
943 1193 sp.IsChildAgent = false;
944 EnableChildAgents(sp); 1194 ReInstantiateScripts(sp);
945 1195
1196 EnableChildAgents(sp);
1197 }
946 // Finally, kill the agent we just created at the destination. 1198 // Finally, kill the agent we just created at the destination.
947 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID); 1199 // XXX: Possibly this should be done asynchronously.
1200 Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token);
948 } 1201 }
949 1202
950 /// <summary> 1203 /// <summary>
@@ -954,9 +1207,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
954 /// <param name='finalDestination'></param> 1207 /// <param name='finalDestination'></param>
955 /// <param name='logout'></param> 1208 /// <param name='logout'></param>
956 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param> 1209 /// <param name='reason'>Human readable reason for teleport failure. Will be sent to client.</param>
957 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string reason) 1210 protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout, string auth_code, string reason)
958 { 1211 {
959 CleanupFailedInterRegionTeleport(sp, finalDestination); 1212 CleanupFailedInterRegionTeleport(sp, auth_code, finalDestination);
960 1213
961 m_interRegionTeleportFailures.Value++; 1214 m_interRegionTeleportFailures.Value++;
962 1215
@@ -1132,7 +1385,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1132 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) 1385 public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos)
1133 { 1386 {
1134 version = String.Empty; 1387 version = String.Empty;
1135 newpos = new Vector3(pos.X, pos.Y, pos.Z); 1388 newpos = pos;
1136 1389
1137// m_log.DebugFormat( 1390// m_log.DebugFormat(
1138// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name); 1391// "[ENTITY TRANSFER MODULE]: Crossing agent {0} at pos {1} in {2}", agent.Name, pos, scene.Name);
@@ -1471,11 +1724,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1471 if (m_eqModule != null) 1724 if (m_eqModule != null)
1472 { 1725 {
1473 m_eqModule.CrossRegion( 1726 m_eqModule.CrossRegion(
1474 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, 1727 neighbourRegion.RegionHandle, pos + agent.Velocity, vel2 /* agent.Velocity */,
1475 capsPath, agent.UUID, agent.ControllingClient.SessionId); 1728 neighbourRegion.ExternalEndPoint,
1729 capsPath, agent.UUID, agent.ControllingClient.SessionId,
1730 neighbourRegion.RegionSizeX, neighbourRegion.RegionSizeY);
1476 } 1731 }
1477 else 1732 else
1478 { 1733 {
1734 m_log.ErrorFormat("{0} Using old CrossRegion packet. Varregion will not work!!", LogHeader);
1479 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint, 1735 agent.ControllingClient.CrossRegion(neighbourRegion.RegionHandle, pos + agent.Velocity, agent.Velocity, neighbourRegion.ExternalEndPoint,
1480 capsPath); 1736 capsPath);
1481 } 1737 }
@@ -1654,10 +1910,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1654 List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); 1910 List<ulong> newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles);
1655 List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); 1911 List<ulong> oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles);
1656 1912
1657 //Dump("Current Neighbors", neighbourHandles); 1913// Dump("Current Neighbors", neighbourHandles);
1658 //Dump("Previous Neighbours", previousRegionNeighbourHandles); 1914// Dump("Previous Neighbours", previousRegionNeighbourHandles);
1659 //Dump("New Neighbours", newRegions); 1915// Dump("New Neighbours", newRegions);
1660 //Dump("Old Neighbours", oldRegions); 1916// Dump("Old Neighbours", oldRegions);
1661 1917
1662 /// Update the scene presence's known regions here on this region 1918 /// Update the scene presence's known regions here on this region
1663 sp.DropOldNeighbours(oldRegions); 1919 sp.DropOldNeighbours(oldRegions);
@@ -1665,8 +1921,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1665 /// Collect as many seeds as possible 1921 /// Collect as many seeds as possible
1666 Dictionary<ulong, string> seeds; 1922 Dictionary<ulong, string> seeds;
1667 if (sp.Scene.CapsModule != null) 1923 if (sp.Scene.CapsModule != null)
1668 seeds 1924 seeds = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1669 = new Dictionary<ulong, string>(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID));
1670 else 1925 else
1671 seeds = new Dictionary<ulong, string>(); 1926 seeds = new Dictionary<ulong, string>();
1672 1927
@@ -1736,6 +1991,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1736 newAgent = true; 1991 newAgent = true;
1737 else 1992 else
1738 newAgent = false; 1993 newAgent = false;
1994// continue;
1739 1995
1740 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) 1996 if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle)
1741 { 1997 {
@@ -1841,12 +2097,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
1841 } 2097 }
1842 #endregion 2098 #endregion
1843 2099
1844 m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbour region {2} @ {3} " + 2100 m_log.DebugFormat("{0} {1} is sending {2} EnableSimulator for neighbour region {3}(loc=<{4},{5}>,siz=<{6},{7}>) " +
1845 "and EstablishAgentCommunication with seed cap {4}", 2101 "and EstablishAgentCommunication with seed cap {8}", LogHeader,
1846 scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); 2102 scene.RegionInfo.RegionName, sp.Name,
2103 reg.RegionName, reg.RegionLocX, reg.RegionLocY, reg.RegionSizeX, reg.RegionSizeY , capsPath);
1847 2104
1848 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); 2105 m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID, reg.RegionSizeX, reg.RegionSizeY);
1849 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); 2106 m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath, reg.RegionHandle, reg.RegionSizeX, reg.RegionSizeY);
1850 } 2107 }
1851 else 2108 else
1852 { 2109 {
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
index d372c0e..7abdc21 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs
@@ -53,8 +53,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 53 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
54 54
55 private int m_levelHGTeleport = 0; 55 private int m_levelHGTeleport = 0;
56 private string m_ThisHomeURI;
56 57
57 private GatekeeperServiceConnector m_GatekeeperConnector; 58 private GatekeeperServiceConnector m_GatekeeperConnector;
59 private IUserAgentService m_UAS;
58 60
59 protected bool m_RestrictAppearanceAbroad; 61 protected bool m_RestrictAppearanceAbroad;
60 protected string m_AccountName; 62 protected string m_AccountName;
@@ -143,6 +145,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
143 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); 145 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
144 } 146 }
145 } 147 }
148
149 moduleConfig = source.Configs["Hypergrid"];
150 if (moduleConfig != null)
151 {
152 m_ThisHomeURI = moduleConfig.GetString("HomeURI", string.Empty);
153 if (m_ThisHomeURI != string.Empty && !m_ThisHomeURI.EndsWith("/"))
154 m_ThisHomeURI += '/';
155 }
146 } 156 }
147 157
148 public override void AddRegion(Scene scene) 158 public override void AddRegion(Scene scene)
@@ -161,22 +171,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
161 if (!so.IsAttachment) 171 if (!so.IsAttachment)
162 return; 172 return;
163 173
164 if (so.Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar)) 174 if (so.AttachedAvatar == UUID.Zero || Scene.UserManagementModule.IsLocalGridUser(so.AttachedAvatar))
165 return; 175 return;
166 176
167 // foreign user 177 // foreign user
168 AgentCircuitData aCircuit = so.Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar); 178 AgentCircuitData aCircuit = Scene.AuthenticateHandler.GetAgentCircuitData(so.AttachedAvatar);
169 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) 179 if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0)
170 { 180 {
171 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) 181 if (aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI"))
172 { 182 {
173 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString(); 183 string url = aCircuit.ServiceURLs["AssetServerURI"].ToString();
174 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachement {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url); 184 m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Incoming attachment {0} for HG user {1} with asset server {2}", so.Name, so.AttachedAvatar, url);
175 Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); 185 Dictionary<UUID, sbyte> ids = new Dictionary<UUID, sbyte>();
176 HGUuidGatherer uuidGatherer = new HGUuidGatherer(so.Scene.AssetService, url); 186 HGUuidGatherer uuidGatherer = new HGUuidGatherer(Scene.AssetService, url);
177 uuidGatherer.GatherAssetUuids(so, ids); 187 uuidGatherer.GatherAssetUuids(so, ids);
178 188
179 foreach (KeyValuePair<UUID, AssetType> kvp in ids) 189 foreach (KeyValuePair<UUID, sbyte> kvp in ids)
180 uuidGatherer.FetchAsset(kvp.Key); 190 uuidGatherer.FetchAsset(kvp.Key);
181 } 191 }
182 } 192 }
@@ -194,7 +204,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
194 base.RegionLoaded(scene); 204 base.RegionLoaded(scene);
195 205
196 if (m_Enabled) 206 if (m_Enabled)
207 {
197 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); 208 m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService);
209 m_UAS = scene.RequestModuleInterface<IUserAgentService>();
210 if (m_UAS == null)
211 m_UAS = new UserAgentServiceConnector(m_ThisHomeURI);
212
213 }
198 } 214 }
199 215
200 public override void RemoveRegion(Scene scene) 216 public override void RemoveRegion(Scene scene)
@@ -272,8 +288,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
272 if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) 288 if (agentCircuit.ServiceURLs.ContainsKey("HomeURI"))
273 { 289 {
274 string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); 290 string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString();
275 IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); 291 IUserAgentService connector;
276 bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); 292
293 if (userAgentDriver.Equals(m_ThisHomeURI) && m_UAS != null)
294 connector = m_UAS;
295 else
296 connector = new UserAgentServiceConnector(userAgentDriver);
297
298 bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, false, out reason);
277 logout = success; // flag for later logout from this grid; this is an HG TP 299 logout = success; // flag for later logout from this grid; this is an HG TP
278 300
279 if (success) 301 if (success)
@@ -552,12 +574,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
552 if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) 574 if (uMan != null && uMan.IsLocalGridUser(obj.AgentId))
553 { 575 {
554 // local grid user 576 // local grid user
577 m_UAS.LogoutAgent(obj.AgentId, obj.SessionId);
555 return; 578 return;
556 } 579 }
557 580
558 AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); 581 AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode);
559 582 if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("HomeURI"))
560 if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
561 { 583 {
562 string url = aCircuit.ServiceURLs["HomeURI"].ToString(); 584 string url = aCircuit.ServiceURLs["HomeURI"].ToString();
563 IUserAgentService security = new UserAgentServiceConnector(url); 585 IUserAgentService security = new UserAgentServiceConnector(url);