diff options
Diffstat (limited to 'OpenSim/Region/CoreModules')
3 files changed, 166 insertions, 21 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index a3c539d..29b4296 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -689,6 +689,20 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
689 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); | 689 | agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); |
690 | } | 690 | } |
691 | 691 | ||
692 | if (version.Equals("SIMULATION/0.2")) | ||
693 | TransferAgent_V2(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); | ||
694 | else | ||
695 | TransferAgent_V1(sp, agentCircuit, reg, finalDestination, endPoint, teleportFlags, oldRegionX, newRegionX, oldRegionY, newRegionY, version, out reason); | ||
696 | |||
697 | } | ||
698 | |||
699 | private void TransferAgent_V1(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, | ||
700 | IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason) | ||
701 | { | ||
702 | ulong destinationHandle = finalDestination.RegionHandle; | ||
703 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | ||
704 | |||
705 | m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Using TP V1"); | ||
692 | // Let's create an agent there if one doesn't exist yet. | 706 | // Let's create an agent there if one doesn't exist yet. |
693 | // NOTE: logout will always be false for a non-HG teleport. | 707 | // NOTE: logout will always be false for a non-HG teleport. |
694 | bool logout = false; | 708 | bool logout = false; |
@@ -710,7 +724,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
710 | m_interRegionTeleportCancels.Value++; | 724 | m_interRegionTeleportCancels.Value++; |
711 | 725 | ||
712 | m_log.DebugFormat( | 726 | m_log.DebugFormat( |
713 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", | 727 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after CreateAgent on client request", |
714 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 728 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
715 | 729 | ||
716 | return; | 730 | return; |
@@ -732,11 +746,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
732 | // OK, it got this agent. Let's close some child agents | 746 | // OK, it got this agent. Let's close some child agents |
733 | sp.CloseChildAgents(newRegionX, newRegionY); | 747 | sp.CloseChildAgents(newRegionX, newRegionY); |
734 | 748 | ||
735 | IClientIPEndpoint ipepClient; | 749 | IClientIPEndpoint ipepClient; |
750 | string capsPath = String.Empty; | ||
736 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | 751 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) |
737 | { | 752 | { |
738 | m_log.DebugFormat( | 753 | m_log.DebugFormat( |
739 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", | 754 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for incoming agent {3} from {4}", |
740 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | 755 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); |
741 | 756 | ||
742 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | 757 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); |
@@ -783,10 +798,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
783 | // Let's send a full update of the agent. This is a synchronous call. | 798 | // Let's send a full update of the agent. This is a synchronous call. |
784 | AgentData agent = new AgentData(); | 799 | AgentData agent = new AgentData(); |
785 | sp.CopyTo(agent); | 800 | sp.CopyTo(agent); |
786 | agent.Position = position; | 801 | agent.Position = agentCircuit.startpos; |
787 | SetCallbackURL(agent, sp.Scene.RegionInfo); | 802 | SetCallbackURL(agent, sp.Scene.RegionInfo); |
788 | 803 | ||
789 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); | ||
790 | 804 | ||
791 | // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to | 805 | // We will check for an abort before UpdateAgent since UpdateAgent will require an active viewer to |
792 | // establish th econnection to the destination which makes it return true. | 806 | // establish th econnection to the destination which makes it return true. |
@@ -821,7 +835,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
821 | m_log.WarnFormat( | 835 | m_log.WarnFormat( |
822 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", | 836 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", |
823 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 837 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
824 | 838 | ||
825 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); | 839 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); |
826 | return; | 840 | return; |
827 | } | 841 | } |
@@ -831,7 +845,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
831 | m_interRegionTeleportCancels.Value++; | 845 | m_interRegionTeleportCancels.Value++; |
832 | 846 | ||
833 | m_log.DebugFormat( | 847 | m_log.DebugFormat( |
834 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", | 848 | "[ENTITY TRANSFER MODULE]: Cancelled teleport of {0} to {1} from {2} after UpdateAgent on client request", |
835 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | 849 | sp.Name, finalDestination.RegionName, sp.Scene.Name); |
836 | 850 | ||
837 | CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); | 851 | CleanupFailedInterRegionTeleport(sp, currentAgentCircuit.SessionID.ToString(), finalDestination); |
@@ -848,6 +862,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
848 | // closes our existing agent which is still signalled as root. | 862 | // closes our existing agent which is still signalled as root. |
849 | sp.IsChildAgent = true; | 863 | sp.IsChildAgent = true; |
850 | 864 | ||
865 | // OK, send TPFinish to the client, so that it starts the process of contacting the destination region | ||
851 | if (m_eqModule != null) | 866 | if (m_eqModule != null) |
852 | { | 867 | { |
853 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); | 868 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); |
@@ -877,7 +892,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
877 | m_log.WarnFormat( | 892 | m_log.WarnFormat( |
878 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", | 893 | "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", |
879 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | 894 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); |
880 | 895 | ||
881 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); | 896 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Destination region did not signal teleport completion."); |
882 | 897 | ||
883 | return; | 898 | return; |
@@ -906,13 +921,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
906 | 921 | ||
907 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | 922 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) |
908 | { | 923 | { |
909 | // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before | 924 | // RED ALERT!!!! |
910 | // they regard the new region as the current region after receiving the AgentMovementComplete | 925 | // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. |
911 | // response. If close is sent before then, it will cause the viewer to quit instead. | 926 | // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion |
912 | // | 927 | // BEFORE THEY SETTLE IN THE NEW REGION. |
913 | // This sleep can be increased if necessary. However, whilst it's active, | 928 | // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR |
914 | // an agent cannot teleport back to this region if it has teleported away. | 929 | // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. |
915 | Thread.Sleep(3000); | 930 | Thread.Sleep(5000); |
916 | 931 | ||
917 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | 932 | sp.Scene.IncomingCloseAgent(sp.UUID, false); |
918 | } | 933 | } |
@@ -923,6 +938,134 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
923 | } | 938 | } |
924 | } | 939 | } |
925 | 940 | ||
941 | private void TransferAgent_V2(ScenePresence sp, AgentCircuitData agentCircuit, GridRegion reg, GridRegion finalDestination, | ||
942 | IPEndPoint endPoint, uint teleportFlags, uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, string version, out string reason) | ||
943 | { | ||
944 | ulong destinationHandle = finalDestination.RegionHandle; | ||
945 | AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | ||
946 | |||
947 | // Let's create an agent there if one doesn't exist yet. | ||
948 | // NOTE: logout will always be false for a non-HG teleport. | ||
949 | bool logout = false; | ||
950 | if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) | ||
951 | { | ||
952 | m_interRegionTeleportFailures.Value++; | ||
953 | |||
954 | sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); | ||
955 | |||
956 | m_log.DebugFormat( | ||
957 | "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", | ||
958 | sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); | ||
959 | |||
960 | return; | ||
961 | } | ||
962 | |||
963 | // Past this point we have to attempt clean up if the teleport fails, so update transfer state. | ||
964 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.Transferring); | ||
965 | |||
966 | IClientIPEndpoint ipepClient; | ||
967 | string capsPath = String.Empty; | ||
968 | if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) | ||
969 | { | ||
970 | m_log.DebugFormat( | ||
971 | "[ENTITY TRANSFER MODULE]: Determined that region {0} at {1},{2} needs new child agent for agent {3} from {4}", | ||
972 | finalDestination.RegionName, newRegionX, newRegionY, sp.Name, Scene.Name); | ||
973 | |||
974 | //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); | ||
975 | #region IP Translation for NAT | ||
976 | // Uses ipepClient above | ||
977 | if (sp.ClientView.TryGet(out ipepClient)) | ||
978 | { | ||
979 | endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); | ||
980 | } | ||
981 | #endregion | ||
982 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
983 | } | ||
984 | else | ||
985 | { | ||
986 | agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); | ||
987 | capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); | ||
988 | } | ||
989 | |||
990 | // We need to set this here to avoid an unlikely race condition when teleporting to a neighbour simulator, | ||
991 | // where that neighbour simulator could otherwise request a child agent create on the source which then | ||
992 | // closes our existing agent which is still signalled as root. | ||
993 | //sp.IsChildAgent = true; | ||
994 | |||
995 | // New protocol: send TP Finish directly, without prior ES or EAC. That's what happens in the Linden grid | ||
996 | if (m_eqModule != null) | ||
997 | m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); | ||
998 | else | ||
999 | sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, | ||
1000 | teleportFlags, capsPath); | ||
1001 | |||
1002 | m_log.DebugFormat( | ||
1003 | "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", | ||
1004 | capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); | ||
1005 | |||
1006 | // Let's send a full update of the agent. | ||
1007 | AgentData agent = new AgentData(); | ||
1008 | sp.CopyTo(agent); | ||
1009 | agent.Position = agentCircuit.startpos; | ||
1010 | agent.SenderWantsToWaitForRoot = true; | ||
1011 | //SetCallbackURL(agent, sp.Scene.RegionInfo); | ||
1012 | |||
1013 | // Send the Update. If this returns true, we know the client has contacted the destination | ||
1014 | // via CompleteMovementIntoRegion, so we can let go. | ||
1015 | // If it returns false, something went wrong, and we need to abort. | ||
1016 | if (!UpdateAgent(reg, finalDestination, agent, sp)) | ||
1017 | { | ||
1018 | if (m_entityTransferStateMachine.GetAgentTransferState(sp.UUID) == AgentTransferState.Aborting) | ||
1019 | { | ||
1020 | m_interRegionTeleportAborts.Value++; | ||
1021 | |||
1022 | m_log.DebugFormat( | ||
1023 | "[ENTITY TRANSFER MODULE]: Aborted teleport of {0} to {1} from {2} after UpdateAgent due to previous client close.", | ||
1024 | sp.Name, finalDestination.RegionName, sp.Scene.Name); | ||
1025 | |||
1026 | return; | ||
1027 | } | ||
1028 | |||
1029 | m_log.WarnFormat( | ||
1030 | "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Keeping avatar in source region.", | ||
1031 | sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); | ||
1032 | |||
1033 | Fail(sp, finalDestination, logout, currentAgentCircuit.SessionID.ToString(), "Connection between viewer and destination region could not be established."); | ||
1034 | return; | ||
1035 | } | ||
1036 | |||
1037 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | ||
1038 | |||
1039 | // May need to logout or other cleanup | ||
1040 | AgentHasMovedAway(sp, logout); | ||
1041 | |||
1042 | // Well, this is it. The agent is over there. | ||
1043 | KillEntity(sp.Scene, sp.LocalId); | ||
1044 | |||
1045 | // Now let's make it officially a child agent | ||
1046 | sp.MakeChildAgent(); | ||
1047 | |||
1048 | // OK, it got this agent. Let's close some child agents | ||
1049 | sp.CloseChildAgents(newRegionX, newRegionY); | ||
1050 | |||
1051 | // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone | ||
1052 | |||
1053 | if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) | ||
1054 | { | ||
1055 | // RED ALERT!!!! | ||
1056 | // PLEASE DO NOT DECREASE THIS WAIT TIME UNDER ANY CIRCUMSTANCES. | ||
1057 | // THE VIEWERS SEEM TO NEED SOME TIME AFTER RECEIVING MoveAgentIntoRegion | ||
1058 | // BEFORE THEY SETTLE IN THE NEW REGION. | ||
1059 | // DECREASING THE WAIT TIME HERE WILL EITHER RESULT IN A VIEWER CRASH OR | ||
1060 | // IN THE AVIE BEING PLACED IN INFINITY FOR A COUPLE OF SECONDS. | ||
1061 | Thread.Sleep(5000); | ||
1062 | sp.Scene.IncomingCloseAgent(sp.UUID, false); | ||
1063 | } | ||
1064 | else | ||
1065 | // now we have a child agent in this region. | ||
1066 | sp.Reset(); | ||
1067 | } | ||
1068 | |||
926 | /// <summary> | 1069 | /// <summary> |
927 | /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation. | 1070 | /// Clean up an inter-region teleport that did not complete, either because of simulator failure or cancellation. |
928 | /// </summary> | 1071 | /// </summary> |
@@ -936,11 +1079,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
936 | { | 1079 | { |
937 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); | 1080 | m_entityTransferStateMachine.UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); |
938 | 1081 | ||
939 | sp.IsChildAgent = false; | 1082 | if (sp.IsChildAgent) // We had set it to child before attempted TP (V1) |
940 | ReInstantiateScripts(sp); | 1083 | { |
941 | 1084 | sp.IsChildAgent = false; | |
942 | EnableChildAgents(sp); | 1085 | ReInstantiateScripts(sp); |
943 | 1086 | ||
1087 | EnableChildAgents(sp); | ||
1088 | } | ||
944 | // Finally, kill the agent we just created at the destination. | 1089 | // Finally, kill the agent we just created at the destination. |
945 | // XXX: Possibly this should be done asynchronously. | 1090 | // XXX: Possibly this should be done asynchronously. |
946 | Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token); | 1091 | Scene.SimulationService.CloseAgent(finalDestination, sp.UUID, auth_token); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs index 172bea1..516ad40 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Presence/PresenceDetector.cs | |||
@@ -79,7 +79,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Presence | |||
79 | 79 | ||
80 | public void OnConnectionClose(IClientAPI client) | 80 | public void OnConnectionClose(IClientAPI client) |
81 | { | 81 | { |
82 | if (!client.SceneAgent.IsChildAgent) | 82 | if (client != null && client.SceneAgent != null && !client.SceneAgent.IsChildAgent) |
83 | { | 83 | { |
84 | // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); | 84 | // m_log.DebugFormat("[PRESENCE DETECTOR]: Detected client logout {0} in {1}", client.AgentId, client.Scene.RegionInfo.RegionName); |
85 | m_PresenceService.LogoutAgent(client.SessionId); | 85 | m_PresenceService.LogoutAgent(client.SessionId); |
diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 8207fb9..39657a3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs | |||
@@ -48,7 +48,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation | |||
48 | /// <summary> | 48 | /// <summary> |
49 | /// Version of this service | 49 | /// Version of this service |
50 | /// </summary> | 50 | /// </summary> |
51 | private const string m_Version = "SIMULATION/0.1"; | 51 | private const string m_Version = "SIMULATION/0.2"; |
52 | 52 | ||
53 | /// <summary> | 53 | /// <summary> |
54 | /// Map region ID to scene. | 54 | /// Map region ID to scene. |