diff options
Major changes in interregion communications. This breaks compatibility with older versions, and may result is all sorts of weirdnesses when interacting with sims in older versions. Changes:
- Introducing synchronous Teleports. Now the receiving region calls back the sending region after the client has been made a root agent there, that is, after client sends CompleteMovement to the destination.
- SendCloseAgent moved from OGS1 Remoting to RESTComms.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | 106 |
1 files changed, 74 insertions, 32 deletions
diff --git a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs index 2bf81d8..da3a9d3 100644 --- a/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Environment/Scenes/SceneCommunicationService.cs | |||
@@ -55,6 +55,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
55 | 55 | ||
56 | protected RegionCommsListener regionCommsHost; | 56 | protected RegionCommsListener regionCommsHost; |
57 | 57 | ||
58 | protected List<UUID> m_agentsInTransit; | ||
59 | |||
58 | public event AgentCrossing OnAvatarCrossingIntoRegion; | 60 | public event AgentCrossing OnAvatarCrossingIntoRegion; |
59 | public event ExpectUserDelegate OnExpectUser; | 61 | public event ExpectUserDelegate OnExpectUser; |
60 | public event ExpectPrimDelegate OnExpectPrim; | 62 | public event ExpectPrimDelegate OnExpectPrim; |
@@ -82,6 +84,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
82 | public SceneCommunicationService(CommunicationsManager commsMan) | 84 | public SceneCommunicationService(CommunicationsManager commsMan) |
83 | { | 85 | { |
84 | m_commsProvider = commsMan; | 86 | m_commsProvider = commsMan; |
87 | m_agentsInTransit = new List<UUID>(); | ||
85 | } | 88 | } |
86 | 89 | ||
87 | /// <summary> | 90 | /// <summary> |
@@ -546,8 +549,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
546 | /// </summary> | 549 | /// </summary> |
547 | private void SendChildAgentDataUpdateAsync(AgentData cAgentData, ulong regionHandle) | 550 | private void SendChildAgentDataUpdateAsync(AgentData cAgentData, ulong regionHandle) |
548 | { | 551 | { |
549 | m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); | 552 | //m_log.Info("[INTERGRID]: Informing neighbors about my agent in " + m_regionInfo.RegionName); |
550 | //bool regionAccepted = m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); | ||
551 | try | 553 | try |
552 | { | 554 | { |
553 | //m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); | 555 | //m_commsProvider.InterRegion.ChildAgentUpdate(regionHandle, cAgentData); |
@@ -608,29 +610,10 @@ namespace OpenSim.Region.Environment.Scenes | |||
608 | { | 610 | { |
609 | 611 | ||
610 | m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); | 612 | m_log.Debug("[INTERGRID]: Sending close agent to " + regionHandle); |
611 | //bool regionAccepted = m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); | ||
612 | // let's do our best, but there's not much we can do if the neighbour doesn't accept. | 613 | // let's do our best, but there's not much we can do if the neighbour doesn't accept. |
613 | m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); | ||
614 | |||
615 | //if (regionAccepted) | ||
616 | //{ | ||
617 | // m_log.Info("[INTERGRID]: Completed sending agent Close agent Request to neighbor"); | ||
618 | |||
619 | //} | ||
620 | //else | ||
621 | //{ | ||
622 | // m_log.Info("[INTERGRID]: Failed sending agent Close agent Request to neighbor"); | ||
623 | 614 | ||
624 | //} | 615 | //m_commsProvider.InterRegion.TellRegionToCloseChildConnection(regionHandle, agentID); |
625 | 616 | m_interregionCommsOut.SendCloseAgent(regionHandle, agentID); | |
626 | //// We remove the list of known regions from the agent's known region list through an event | ||
627 | //// to scene, because, if an agent logged of, it's likely that there will be no scene presence | ||
628 | //// by the time we get to this part of the method. | ||
629 | //handlerRemoveKnownRegionFromAvatar = OnRemoveKnownRegionFromAvatar; | ||
630 | //if (handlerRemoveKnownRegionFromAvatar != null) | ||
631 | //{ | ||
632 | // handlerRemoveKnownRegionFromAvatar(agentID, regionlst); | ||
633 | //} | ||
634 | } | 617 | } |
635 | 618 | ||
636 | private void SendCloseChildAgentCompleted(IAsyncResult iar) | 619 | private void SendCloseChildAgentCompleted(IAsyncResult iar) |
@@ -860,15 +843,16 @@ namespace OpenSim.Region.Environment.Scenes | |||
860 | // return; | 843 | // return; |
861 | //} | 844 | //} |
862 | 845 | ||
846 | SetInTransit(avatar.UUID); | ||
863 | // Let's send a full update of the agent. This is a synchronous call. | 847 | // Let's send a full update of the agent. This is a synchronous call. |
864 | AgentData agent = new AgentData(); | 848 | AgentData agent = new AgentData(); |
865 | avatar.CopyTo(agent); | 849 | avatar.CopyTo(agent); |
866 | agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!! | 850 | agent.Position = new Vector3(-1, -1, -1); // this means ignore position info; UGH!!!! |
851 | agent.CallbackURI = "http://" + m_regionInfo.ExternalHostName + ":" + m_regionInfo.HttpPort + | ||
852 | "/agent/" + avatar.UUID.ToString() + "/" + avatar.Scene.RegionInfo.RegionHandle.ToString() + "/release/"; | ||
867 | 853 | ||
868 | m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); | 854 | m_interregionCommsOut.SendChildAgentUpdate(reg.RegionHandle, agent); |
869 | 855 | ||
870 | avatar.MakeChildAgent(); | ||
871 | |||
872 | m_log.DebugFormat( | 856 | m_log.DebugFormat( |
873 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); | 857 | "[CAPS]: Sending new CAPS seed url {0} to client {1}", capsPath, avatar.UUID); |
874 | 858 | ||
@@ -885,17 +869,32 @@ namespace OpenSim.Region.Environment.Scenes | |||
885 | teleportFlags, capsPath); | 869 | teleportFlags, capsPath); |
886 | } | 870 | } |
887 | 871 | ||
872 | |||
873 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | ||
874 | // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation | ||
875 | // that the client contacted the destination before we send the attachments and close things here. | ||
876 | if (!WaitForCallback(avatar.UUID)) | ||
877 | { | ||
878 | // Client never contacted destination. Let's restore everything back | ||
879 | avatar.ControllingClient.SendTeleportFailed("Problems connecting to destination."); | ||
880 | |||
881 | ResetFromTransit(avatar.UUID); | ||
882 | // Yikes! We should just have a ref to scene here. | ||
883 | avatar.Scene.InformClientOfNeighbours(avatar); | ||
884 | |||
885 | // Finally, kill the agent we just created at the destination. | ||
886 | m_interregionCommsOut.SendCloseAgent(reg.RegionHandle, avatar.UUID); | ||
887 | |||
888 | return; | ||
889 | } | ||
890 | |||
891 | // Can't go back from here | ||
888 | if (KiPrimitive != null) | 892 | if (KiPrimitive != null) |
889 | { | 893 | { |
890 | KiPrimitive(avatar.LocalId); | 894 | KiPrimitive(avatar.LocalId); |
891 | } | 895 | } |
892 | 896 | ||
893 | // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which | 897 | avatar.MakeChildAgent(); |
894 | // trigers a whole shebang of things there, including MakeRoot. So let's wait plenty before | ||
895 | // we send the attachments and close things here. | ||
896 | // We need to change this part of the protocol. The receiving region should tell this region | ||
897 | // when it's ok to continue. | ||
898 | Thread.Sleep(4000); | ||
899 | 898 | ||
900 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it | 899 | // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it |
901 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); | 900 | avatar.CrossAttachmentsIntoNewRegion(reg.RegionHandle, true); |
@@ -904,7 +903,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
904 | 903 | ||
905 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) | 904 | if (Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY)) |
906 | { | 905 | { |
907 | Thread.Sleep(8000); | 906 | Thread.Sleep(5000); |
908 | avatar.Close(); | 907 | avatar.Close(); |
909 | CloseConnection(avatar.UUID); | 908 | CloseConnection(avatar.UUID); |
910 | } | 909 | } |
@@ -947,6 +946,49 @@ namespace OpenSim.Region.Environment.Scenes | |||
947 | } | 946 | } |
948 | } | 947 | } |
949 | 948 | ||
949 | protected bool WaitForCallback(UUID id) | ||
950 | { | ||
951 | int count = 20; | ||
952 | while (m_agentsInTransit.Contains(id) && count-- > 0) | ||
953 | { | ||
954 | //Console.WriteLine(" >>> Waiting... " + count); | ||
955 | Thread.Sleep(1000); | ||
956 | } | ||
957 | |||
958 | if (count > 0) | ||
959 | return true; | ||
960 | else | ||
961 | return false; | ||
962 | } | ||
963 | |||
964 | public bool ReleaseAgent(UUID id) | ||
965 | { | ||
966 | //Console.WriteLine(" >>> ReleaseAgent called <<< "); | ||
967 | return ResetFromTransit(id); | ||
968 | } | ||
969 | |||
970 | protected void SetInTransit(UUID id) | ||
971 | { | ||
972 | lock (m_agentsInTransit) | ||
973 | { | ||
974 | if (!m_agentsInTransit.Contains(id)) | ||
975 | m_agentsInTransit.Add(id); | ||
976 | } | ||
977 | } | ||
978 | |||
979 | protected bool ResetFromTransit(UUID id) | ||
980 | { | ||
981 | lock (m_agentsInTransit) | ||
982 | { | ||
983 | if (m_agentsInTransit.Contains(id)) | ||
984 | { | ||
985 | m_agentsInTransit.Remove(id); | ||
986 | return true; | ||
987 | } | ||
988 | } | ||
989 | return false; | ||
990 | } | ||
991 | |||
950 | private List<ulong> NeighbourHandles(List<SimpleRegionInfo> neighbours) | 992 | private List<ulong> NeighbourHandles(List<SimpleRegionInfo> neighbours) |
951 | { | 993 | { |
952 | List<ulong> handles = new List<ulong>(); | 994 | List<ulong> handles = new List<ulong>(); |