From 7c0bfa15b1c4bee4ad4d7f2169d62811f483cfd3 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Mon, 30 Jan 2023 16:09:38 -0500 Subject: [PATCH 01/11] Simplifying reconnection (cherry picked from commit f9d5ad952b99c9e2bc1cc502c5f643ffd306c1f6) --- .../ConnectionManagement/ConnectionMethod.cs | 18 ++++++++ .../ConnectionState/ClientConnectingState.cs | 6 +-- .../ClientReconnectingState.cs | 42 +++++++------------ 3 files changed, 34 insertions(+), 32 deletions(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs index 11f78decb..b2bbf7885 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs @@ -27,6 +27,8 @@ public abstract class ConnectionMethodBase public abstract Task SetupClientConnectionAsync(); + public abstract Task SetupClientReconnectionAsync(); + public ConnectionMethodBase(ConnectionManager connectionManager, ProfileManager profileManager, string playerName) { m_ConnectionManager = connectionManager; @@ -82,6 +84,12 @@ public override async Task SetupClientConnectionAsync() utp.SetConnectionData(m_Ipaddress, m_Port); } + public override Task SetupClientReconnectionAsync() + { + // Nothing to do here + return Task.FromResult(true); + } + public override async Task SetupHostConnectionAsync() { SetConnectionPayload(GetPlayerId(), m_PlayerName); // Need to set connection payload for host as well, as host is a client too @@ -132,6 +140,16 @@ public override async Task SetupClientConnectionAsync() utp.SetRelayServerData(new RelayServerData(joinedAllocation, k_DtlsConnType)); } + public override async Task SetupClientReconnectionAsync() + { + // When using Lobby with Relay, if a user is disconnected from the Relay server, the server will notify the + // Lobby service and mark the user as disconnected, but will not remove them from the lobby. They then have + // some time to attempt to reconnect (defined by the "Disconnect removal time" parameter on the dashboard), + // after which they will be removed from the lobby completely. + // See https://docs.unity.com/lobby/reconnect-to-lobby.html + return await m_LobbyServiceFacade.ReconnectToLobbyAsync(m_LocalLobby.LobbyID) != null; // return a success if reconnecting to lobby returns a lobby + } + public override async Task SetupHostConnectionAsync() { Debug.Log("Setting up Unity Relay host"); diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs index d8b7106db..36a885bdc 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs @@ -13,11 +13,7 @@ namespace Unity.BossRoom.ConnectionManagement /// class ClientConnectingState : OnlineState { - [Inject] - protected LobbyServiceFacade m_LobbyServiceFacade; - [Inject] - protected LocalLobby m_LocalLobby; - ConnectionMethodBase m_ConnectionMethod; + protected ConnectionMethodBase m_ConnectionMethod; public ClientConnectingState Configure(ConnectionMethodBase baseConnectionMethod) { diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs index e6e47ff42..43ceb5228 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using Unity.BossRoom.Infrastructure; +using Unity.BossRoom.UnityServices.Lobbies; using UnityEngine; using VContainer; @@ -17,6 +18,8 @@ class ClientReconnectingState : ClientConnectingState { [Inject] IPublisher m_ReconnectMessagePublisher; + [Inject] + LobbyServiceFacade m_LobbyServiceFacade; Coroutine m_ReconnectCoroutine; string m_LobbyCode = ""; @@ -108,36 +111,21 @@ IEnumerator ReconnectCoroutine() Debug.Log($"Reconnecting attempt {m_NbAttempts + 1}/{m_ConnectionManager.NbReconnectAttempts}..."); m_ReconnectMessagePublisher.Publish(new ReconnectMessage(m_NbAttempts, m_ConnectionManager.NbReconnectAttempts)); m_NbAttempts++; - if (!string.IsNullOrEmpty(m_LobbyCode)) // Attempting to reconnect to lobby. - { - // When using Lobby with Relay, if a user is disconnected from the Relay server, the server will notify - // the Lobby service and mark the user as disconnected, but will not remove them from the lobby. They - // then have some time to attempt to reconnect (defined by the "Disconnect removal time" parameter on - // the dashboard), after which they will be removed from the lobby completely. - // See https://docs.unity.com/lobby/reconnect-to-lobby.html - var reconnectingToLobby = m_LobbyServiceFacade.ReconnectToLobbyAsync(m_LocalLobby?.LobbyID); - yield return new WaitUntil(() => reconnectingToLobby.IsCompleted); + var reconnectingSetupTask = m_ConnectionMethod.SetupClientReconnectionAsync(); + yield return new WaitUntil(() => reconnectingSetupTask.IsCompleted); - // If succeeded, attempt to connect to Relay - if (!reconnectingToLobby.IsFaulted && reconnectingToLobby.Result != null) - { - // If this fails, the OnClientDisconnect callback will be invoked by Netcode - var connectingToRelay = ConnectClientAsync(); - yield return new WaitUntil(() => connectingToRelay.IsCompleted); - } - else - { - Debug.Log("Failed reconnecting to lobby."); - // Calling OnClientDisconnect to mark this attempt as failed and either start a new one or give up - // and return to the Offline state - OnClientDisconnect(0); - } - } - else // If not using Lobby, simply try to reconnect to the server directly + if (!reconnectingSetupTask.IsFaulted && reconnectingSetupTask.Result) { // If this fails, the OnClientDisconnect callback will be invoked by Netcode - var connectingClient = ConnectClientAsync(); - yield return new WaitUntil(() => connectingClient.IsCompleted); + var connectingToRelay = ConnectClientAsync(); + yield return new WaitUntil(() => connectingToRelay.IsCompleted); + } + else + { + Debug.Log("Failed reconnecting to lobby."); + // Calling OnClientDisconnect to mark this attempt as failed and either start a new one or give up + // and return to the Offline state + OnClientDisconnect(0); } } } From 8e2409959acf47972591d798a8e6b6cfdcc3f188 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Mon, 30 Jan 2023 17:07:09 -0500 Subject: [PATCH 02/11] Adding possibility of early failure when reconnecting if lobby no longer exists --- .../ConnectionManagement/ConnectionMethod.cs | 18 ++++++++++++------ .../ConnectionState/ClientReconnectingState.cs | 15 +++++++++------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs index b2bbf7885..3f2b03d30 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs @@ -27,7 +27,7 @@ public abstract class ConnectionMethodBase public abstract Task SetupClientConnectionAsync(); - public abstract Task SetupClientReconnectionAsync(); + public abstract Task<(bool, bool)> SetupClientReconnectionAsync(); public ConnectionMethodBase(ConnectionManager connectionManager, ProfileManager profileManager, string playerName) { @@ -84,10 +84,10 @@ public override async Task SetupClientConnectionAsync() utp.SetConnectionData(m_Ipaddress, m_Port); } - public override Task SetupClientReconnectionAsync() + public override async Task<(bool, bool)> SetupClientReconnectionAsync() { // Nothing to do here - return Task.FromResult(true); + return (true,true); } public override async Task SetupHostConnectionAsync() @@ -140,14 +140,20 @@ public override async Task SetupClientConnectionAsync() utp.SetRelayServerData(new RelayServerData(joinedAllocation, k_DtlsConnType)); } - public override async Task SetupClientReconnectionAsync() + public override async Task<(bool, bool)> SetupClientReconnectionAsync() { - // When using Lobby with Relay, if a user is disconnected from the Relay server, the server will notify the + if (m_LobbyServiceFacade.CurrentUnityLobby == null) + { + return (false, false); + } + + // When using Lobby with Relay, if a user is disconnected from the Relay server, the server will notify the // Lobby service and mark the user as disconnected, but will not remove them from the lobby. They then have // some time to attempt to reconnect (defined by the "Disconnect removal time" parameter on the dashboard), // after which they will be removed from the lobby completely. // See https://docs.unity.com/lobby/reconnect-to-lobby.html - return await m_LobbyServiceFacade.ReconnectToLobbyAsync(m_LocalLobby.LobbyID) != null; // return a success if reconnecting to lobby returns a lobby + var lobby = await m_LobbyServiceFacade.ReconnectToLobbyAsync(m_LocalLobby.LobbyID); + return (lobby != null, true); // return a success if reconnecting to lobby returns a lobby } public override async Task SetupHostConnectionAsync() diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs index 43ceb5228..7fe136bef 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs @@ -18,11 +18,8 @@ class ClientReconnectingState : ClientConnectingState { [Inject] IPublisher m_ReconnectMessagePublisher; - [Inject] - LobbyServiceFacade m_LobbyServiceFacade; Coroutine m_ReconnectCoroutine; - string m_LobbyCode = ""; int m_NbAttempts; const float k_TimeBetweenAttempts = 5; @@ -30,7 +27,6 @@ class ClientReconnectingState : ClientConnectingState public override void Enter() { m_NbAttempts = 0; - m_LobbyCode = m_LobbyServiceFacade.CurrentUnityLobby != null ? m_LobbyServiceFacade.CurrentUnityLobby.LobbyCode : ""; m_ReconnectCoroutine = m_ConnectionManager.StartCoroutine(ReconnectCoroutine()); } @@ -114,7 +110,9 @@ IEnumerator ReconnectCoroutine() var reconnectingSetupTask = m_ConnectionMethod.SetupClientReconnectionAsync(); yield return new WaitUntil(() => reconnectingSetupTask.IsCompleted); - if (!reconnectingSetupTask.IsFaulted && reconnectingSetupTask.Result) + var (success, shouldRetry) = reconnectingSetupTask.Result; + + if (!reconnectingSetupTask.IsFaulted && success) { // If this fails, the OnClientDisconnect callback will be invoked by Netcode var connectingToRelay = ConnectClientAsync(); @@ -122,7 +120,12 @@ IEnumerator ReconnectCoroutine() } else { - Debug.Log("Failed reconnecting to lobby."); + if (!shouldRetry) + { + // setting number of attempts to max so no new attempts are made + m_NbAttempts = m_ConnectionManager.NbReconnectAttempts; + } + Debug.Log("Failed setting up reconnection."); // Calling OnClientDisconnect to mark this attempt as failed and either start a new one or give up // and return to the Offline state OnClientDisconnect(0); From bf2fe2304972d604154c13a418c989c546caab81 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 13:47:13 -0500 Subject: [PATCH 03/11] Adding comments and debug logs --- .../ConnectionManagement/ConnectionMethod.cs | 34 +++++++++++++++---- .../ClientReconnectingState.cs | 7 ++-- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs index 3f2b03d30..988bebd71 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs @@ -23,11 +23,27 @@ public abstract class ConnectionMethodBase protected readonly string m_PlayerName; protected const string k_DtlsConnType = "dtls"; + /// + /// Setup the host connection prior to starting the NetworkManager + /// + /// public abstract Task SetupHostConnectionAsync(); + + /// + /// Setup the client connection prior to starting the NetworkManager + /// + /// public abstract Task SetupClientConnectionAsync(); - public abstract Task<(bool, bool)> SetupClientReconnectionAsync(); + /// + /// Setup the client for reconnection prior to reconnecting + /// + /// + /// success = true if succeeded in setting up reconnection, false if failed. + /// shouldTryAgain = true if we should try again after failing, false if not. + /// + public abstract Task<(bool success, bool shouldTryAgain)> SetupClientReconnectionAsync(); public ConnectionMethodBase(ConnectionManager connectionManager, ProfileManager profileManager, string playerName) { @@ -84,7 +100,7 @@ public override async Task SetupClientConnectionAsync() utp.SetConnectionData(m_Ipaddress, m_Port); } - public override async Task<(bool, bool)> SetupClientReconnectionAsync() + public override async Task<(bool success, bool shouldTryAgain)> SetupClientReconnectionAsync() { // Nothing to do here return (true,true); @@ -99,7 +115,7 @@ public override async Task SetupHostConnectionAsync() } /// - /// UTP's Relay connection setup + /// UTP's Relay connection setup using the Lobby integration /// class ConnectionMethodRelay : ConnectionMethodBase { @@ -140,20 +156,26 @@ public override async Task SetupClientConnectionAsync() utp.SetRelayServerData(new RelayServerData(joinedAllocation, k_DtlsConnType)); } - public override async Task<(bool, bool)> SetupClientReconnectionAsync() + public override async Task<(bool success, bool shouldTryAgain)> SetupClientReconnectionAsync() { if (m_LobbyServiceFacade.CurrentUnityLobby == null) { + Debug.Log("Lobby does not exist anymore, stopping reconnection attempts."); return (false, false); } - // When using Lobby with Relay, if a user is disconnected from the Relay server, the server will notify the + // When using Lobby with Relay, if a user is disconnected from the Relay server, the server will notify the // Lobby service and mark the user as disconnected, but will not remove them from the lobby. They then have // some time to attempt to reconnect (defined by the "Disconnect removal time" parameter on the dashboard), // after which they will be removed from the lobby completely. // See https://docs.unity.com/lobby/reconnect-to-lobby.html var lobby = await m_LobbyServiceFacade.ReconnectToLobbyAsync(m_LocalLobby.LobbyID); - return (lobby != null, true); // return a success if reconnecting to lobby returns a lobby + var success = lobby != null; + if (!success) + { + Debug.Log("Failed to reconnect to Lobby."); + } + return (success, true); // return a success if reconnecting to lobby returns a lobby } public override async Task SetupHostConnectionAsync() diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs index 7fe136bef..a9555dd29 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs @@ -110,9 +110,7 @@ IEnumerator ReconnectCoroutine() var reconnectingSetupTask = m_ConnectionMethod.SetupClientReconnectionAsync(); yield return new WaitUntil(() => reconnectingSetupTask.IsCompleted); - var (success, shouldRetry) = reconnectingSetupTask.Result; - - if (!reconnectingSetupTask.IsFaulted && success) + if (!reconnectingSetupTask.IsFaulted && reconnectingSetupTask.Result.success) { // If this fails, the OnClientDisconnect callback will be invoked by Netcode var connectingToRelay = ConnectClientAsync(); @@ -120,12 +118,11 @@ IEnumerator ReconnectCoroutine() } else { - if (!shouldRetry) + if (!reconnectingSetupTask.Result.shouldTryAgain) { // setting number of attempts to max so no new attempts are made m_NbAttempts = m_ConnectionManager.NbReconnectAttempts; } - Debug.Log("Failed setting up reconnection."); // Calling OnClientDisconnect to mark this attempt as failed and either start a new one or give up // and return to the Offline state OnClientDisconnect(0); From f53dd251cda10379e867174331328b4ccc95b087 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 13:53:54 -0500 Subject: [PATCH 04/11] removing unneeded using directives --- .../ConnectionState/ClientConnectingState.cs | 2 -- .../ConnectionState/ClientReconnectingState.cs | 1 - 2 files changed, 3 deletions(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs index 36a885bdc..be9a0512c 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs @@ -1,9 +1,7 @@ using System; using System.Threading.Tasks; -using Unity.BossRoom.UnityServices.Lobbies; using Unity.Multiplayer.Samples.Utilities; using UnityEngine; -using VContainer; namespace Unity.BossRoom.ConnectionManagement { diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs index a9555dd29..2977b67a3 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs @@ -1,7 +1,6 @@ using System; using System.Collections; using Unity.BossRoom.Infrastructure; -using Unity.BossRoom.UnityServices.Lobbies; using UnityEngine; using VContainer; From d5095f3834f7f236bb6a3442c7091fb2c5e1af9a Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 14:10:28 -0500 Subject: [PATCH 05/11] Moving ConnectionMethod responsibility to ConnectionManager --- .../ConnectionManagement/ConnectionManager.cs | 22 +++++++++++--- .../ConnectionState/ClientConnectingState.cs | 10 +------ .../ClientReconnectingState.cs | 2 +- .../ConnectionState/ConnectionState.cs | 8 ++--- .../ConnectionState/OfflineState.cs | 29 +++---------------- .../ConnectionState/StartingHostState.cs | 9 +----- 6 files changed, 27 insertions(+), 53 deletions(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionManager.cs b/Assets/Scripts/ConnectionManagement/ConnectionManager.cs index b2b2fa42c..1de57ccb5 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionManager.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionManager.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using Unity.BossRoom.UnityServices.Lobbies; using Unity.BossRoom.Utils; using Unity.Collections; using Unity.Netcode; @@ -69,6 +70,12 @@ public class ConnectionManager : MonoBehaviour [Inject] IObjectResolver m_Resolver; + [Inject] + LobbyServiceFacade m_LobbyServiceFacade; + [Inject] + ProfileManager m_ProfileManager; + [Inject] + LocalLobby m_LocalLobby; public int MaxConnectedPlayers = 8; @@ -79,6 +86,9 @@ public class ConnectionManager : MonoBehaviour internal readonly StartingHostState m_StartingHost = new StartingHostState(); internal readonly HostingState m_Hosting = new HostingState(); + ConnectionMethodBase m_ConnectionMethod; + public ConnectionMethodBase ConnectionMethod => m_ConnectionMethod; + void Awake() { DontDestroyOnLoad(gameObject); @@ -149,22 +159,26 @@ void OnTransportFailure() public void StartClientLobby(string playerName) { - m_CurrentState.StartClientLobby(playerName); + m_ConnectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, this, m_ProfileManager, playerName); + m_CurrentState.StartClient(); } public void StartClientIp(string playerName, string ipaddress, int port) { - m_CurrentState.StartClientIP(playerName, ipaddress, port); + m_ConnectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, this, m_ProfileManager, playerName); + m_CurrentState.StartClient(); } public void StartHostLobby(string playerName) { - m_CurrentState.StartHostLobby(playerName); + m_ConnectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, this, m_ProfileManager, playerName); + m_CurrentState.StartHost(); } public void StartHostIp(string playerName, string ipaddress, int port) { - m_CurrentState.StartHostIP(playerName, ipaddress, port); + m_ConnectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, this, m_ProfileManager, playerName); + m_CurrentState.StartHost(); } public void RequestShutdown() diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs index be9a0512c..a02be95b1 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs @@ -11,14 +11,6 @@ namespace Unity.BossRoom.ConnectionManagement /// class ClientConnectingState : OnlineState { - protected ConnectionMethodBase m_ConnectionMethod; - - public ClientConnectingState Configure(ConnectionMethodBase baseConnectionMethod) - { - m_ConnectionMethod = baseConnectionMethod; - return this; - } - public override void Enter() { #pragma warning disable 4014 @@ -61,7 +53,7 @@ internal async Task ConnectClientAsync() try { // Setup NGO with current connection method - await m_ConnectionMethod.SetupClientConnectionAsync(); + await m_ConnectionManager.ConnectionMethod.SetupClientConnectionAsync(); // NGO's StartClient launches everything if (!m_ConnectionManager.NetworkManager.StartClient()) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs index 2977b67a3..d88c4ae9d 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs @@ -106,7 +106,7 @@ IEnumerator ReconnectCoroutine() Debug.Log($"Reconnecting attempt {m_NbAttempts + 1}/{m_ConnectionManager.NbReconnectAttempts}..."); m_ReconnectMessagePublisher.Publish(new ReconnectMessage(m_NbAttempts, m_ConnectionManager.NbReconnectAttempts)); m_NbAttempts++; - var reconnectingSetupTask = m_ConnectionMethod.SetupClientReconnectionAsync(); + var reconnectingSetupTask = m_ConnectionManager.ConnectionMethod.SetupClientReconnectionAsync(); yield return new WaitUntil(() => reconnectingSetupTask.IsCompleted); if (!reconnectingSetupTask.IsFaulted && reconnectingSetupTask.Result.success) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs index 44251e45a..6d308d0b5 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs @@ -26,13 +26,9 @@ public virtual void OnClientDisconnect(ulong clientId) { } public virtual void OnServerStarted() { } - public virtual void StartClientIP(string playerName, string ipaddress, int port) { } + public virtual void StartClient() { } - public virtual void StartClientLobby(string playerName) { } - - public virtual void StartHostIP(string playerName, string ipaddress, int port) { } - - public virtual void StartHostLobby(string playerName) { } + public virtual void StartHost() { } public virtual void OnUserRequestedShutdown() { } diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs index 34dc047df..9049ff81c 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs @@ -1,7 +1,6 @@ using System; using Unity.BossRoom.ConnectionManagement; using Unity.BossRoom.UnityServices.Lobbies; -using Unity.BossRoom.Utils; using Unity.Multiplayer.Samples.Utilities; using UnityEngine; using UnityEngine.SceneManagement; @@ -17,10 +16,6 @@ class OfflineState : ConnectionState { [Inject] LobbyServiceFacade m_LobbyServiceFacade; - [Inject] - ProfileManager m_ProfileManager; - [Inject] - LocalLobby m_LocalLobby; const string k_MainMenuSceneName = "MainMenu"; @@ -36,30 +31,14 @@ public override void Enter() public override void Exit() { } - public override void StartClientIP(string playerName, string ipaddress, int port) - { - var connectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, m_ConnectionManager, m_ProfileManager, playerName); - m_ConnectionManager.m_ClientReconnecting.Configure(connectionMethod); - m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting.Configure(connectionMethod)); - } - - public override void StartClientLobby(string playerName) - { - var connectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, m_ConnectionManager, m_ProfileManager, playerName); - m_ConnectionManager.m_ClientReconnecting.Configure(connectionMethod); - m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting.Configure(connectionMethod)); - } - - public override void StartHostIP(string playerName, string ipaddress, int port) + public override void StartClient() { - var connectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, m_ConnectionManager, m_ProfileManager, playerName); - m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost.Configure(connectionMethod)); + m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting); } - public override void StartHostLobby(string playerName) + public override void StartHost() { - var connectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, m_ConnectionManager, m_ProfileManager, playerName); - m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost.Configure(connectionMethod)); + m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost); } } } diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs index eca47b3b6..83c1a8699 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs @@ -18,13 +18,6 @@ class StartingHostState : OnlineState LobbyServiceFacade m_LobbyServiceFacade; [Inject] LocalLobby m_LocalLobby; - ConnectionMethodBase m_ConnectionMethod; - - public StartingHostState Configure(ConnectionMethodBase baseConnectionMethod) - { - m_ConnectionMethod = baseConnectionMethod; - return this; - } public override void Enter() { @@ -76,7 +69,7 @@ async void StartHost() { try { - await m_ConnectionMethod.SetupHostConnectionAsync(); + await m_ConnectionManager.ConnectionMethod.SetupHostConnectionAsync(); Debug.Log($"Created relay allocation with join code {m_LocalLobby.RelayJoinCode}"); // NGO's StartHost launches everything From d32ff9a14c20769a3c1dec1c44e979eb65b8360b Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 14:24:55 -0500 Subject: [PATCH 06/11] Revert "Moving ConnectionMethod responsibility to ConnectionManager" This reverts commit d5095f3834f7f236bb6a3442c7091fb2c5e1af9a. --- .../ConnectionManagement/ConnectionManager.cs | 22 +++----------- .../ConnectionState/ClientConnectingState.cs | 10 ++++++- .../ClientReconnectingState.cs | 2 +- .../ConnectionState/ConnectionState.cs | 8 +++-- .../ConnectionState/OfflineState.cs | 29 ++++++++++++++++--- .../ConnectionState/StartingHostState.cs | 9 +++++- 6 files changed, 53 insertions(+), 27 deletions(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionManager.cs b/Assets/Scripts/ConnectionManagement/ConnectionManager.cs index 1de57ccb5..b2b2fa42c 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionManager.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using Unity.BossRoom.UnityServices.Lobbies; using Unity.BossRoom.Utils; using Unity.Collections; using Unity.Netcode; @@ -70,12 +69,6 @@ public class ConnectionManager : MonoBehaviour [Inject] IObjectResolver m_Resolver; - [Inject] - LobbyServiceFacade m_LobbyServiceFacade; - [Inject] - ProfileManager m_ProfileManager; - [Inject] - LocalLobby m_LocalLobby; public int MaxConnectedPlayers = 8; @@ -86,9 +79,6 @@ public class ConnectionManager : MonoBehaviour internal readonly StartingHostState m_StartingHost = new StartingHostState(); internal readonly HostingState m_Hosting = new HostingState(); - ConnectionMethodBase m_ConnectionMethod; - public ConnectionMethodBase ConnectionMethod => m_ConnectionMethod; - void Awake() { DontDestroyOnLoad(gameObject); @@ -159,26 +149,22 @@ void OnTransportFailure() public void StartClientLobby(string playerName) { - m_ConnectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, this, m_ProfileManager, playerName); - m_CurrentState.StartClient(); + m_CurrentState.StartClientLobby(playerName); } public void StartClientIp(string playerName, string ipaddress, int port) { - m_ConnectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, this, m_ProfileManager, playerName); - m_CurrentState.StartClient(); + m_CurrentState.StartClientIP(playerName, ipaddress, port); } public void StartHostLobby(string playerName) { - m_ConnectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, this, m_ProfileManager, playerName); - m_CurrentState.StartHost(); + m_CurrentState.StartHostLobby(playerName); } public void StartHostIp(string playerName, string ipaddress, int port) { - m_ConnectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, this, m_ProfileManager, playerName); - m_CurrentState.StartHost(); + m_CurrentState.StartHostIP(playerName, ipaddress, port); } public void RequestShutdown() diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs index a02be95b1..be9a0512c 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientConnectingState.cs @@ -11,6 +11,14 @@ namespace Unity.BossRoom.ConnectionManagement /// class ClientConnectingState : OnlineState { + protected ConnectionMethodBase m_ConnectionMethod; + + public ClientConnectingState Configure(ConnectionMethodBase baseConnectionMethod) + { + m_ConnectionMethod = baseConnectionMethod; + return this; + } + public override void Enter() { #pragma warning disable 4014 @@ -53,7 +61,7 @@ internal async Task ConnectClientAsync() try { // Setup NGO with current connection method - await m_ConnectionManager.ConnectionMethod.SetupClientConnectionAsync(); + await m_ConnectionMethod.SetupClientConnectionAsync(); // NGO's StartClient launches everything if (!m_ConnectionManager.NetworkManager.StartClient()) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs index d88c4ae9d..2977b67a3 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ClientReconnectingState.cs @@ -106,7 +106,7 @@ IEnumerator ReconnectCoroutine() Debug.Log($"Reconnecting attempt {m_NbAttempts + 1}/{m_ConnectionManager.NbReconnectAttempts}..."); m_ReconnectMessagePublisher.Publish(new ReconnectMessage(m_NbAttempts, m_ConnectionManager.NbReconnectAttempts)); m_NbAttempts++; - var reconnectingSetupTask = m_ConnectionManager.ConnectionMethod.SetupClientReconnectionAsync(); + var reconnectingSetupTask = m_ConnectionMethod.SetupClientReconnectionAsync(); yield return new WaitUntil(() => reconnectingSetupTask.IsCompleted); if (!reconnectingSetupTask.IsFaulted && reconnectingSetupTask.Result.success) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs index 6d308d0b5..44251e45a 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/ConnectionState.cs @@ -26,9 +26,13 @@ public virtual void OnClientDisconnect(ulong clientId) { } public virtual void OnServerStarted() { } - public virtual void StartClient() { } + public virtual void StartClientIP(string playerName, string ipaddress, int port) { } - public virtual void StartHost() { } + public virtual void StartClientLobby(string playerName) { } + + public virtual void StartHostIP(string playerName, string ipaddress, int port) { } + + public virtual void StartHostLobby(string playerName) { } public virtual void OnUserRequestedShutdown() { } diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs index 9049ff81c..34dc047df 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/OfflineState.cs @@ -1,6 +1,7 @@ using System; using Unity.BossRoom.ConnectionManagement; using Unity.BossRoom.UnityServices.Lobbies; +using Unity.BossRoom.Utils; using Unity.Multiplayer.Samples.Utilities; using UnityEngine; using UnityEngine.SceneManagement; @@ -16,6 +17,10 @@ class OfflineState : ConnectionState { [Inject] LobbyServiceFacade m_LobbyServiceFacade; + [Inject] + ProfileManager m_ProfileManager; + [Inject] + LocalLobby m_LocalLobby; const string k_MainMenuSceneName = "MainMenu"; @@ -31,14 +36,30 @@ public override void Enter() public override void Exit() { } - public override void StartClient() + public override void StartClientIP(string playerName, string ipaddress, int port) + { + var connectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, m_ConnectionManager, m_ProfileManager, playerName); + m_ConnectionManager.m_ClientReconnecting.Configure(connectionMethod); + m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting.Configure(connectionMethod)); + } + + public override void StartClientLobby(string playerName) + { + var connectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, m_ConnectionManager, m_ProfileManager, playerName); + m_ConnectionManager.m_ClientReconnecting.Configure(connectionMethod); + m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting.Configure(connectionMethod)); + } + + public override void StartHostIP(string playerName, string ipaddress, int port) { - m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting); + var connectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, m_ConnectionManager, m_ProfileManager, playerName); + m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost.Configure(connectionMethod)); } - public override void StartHost() + public override void StartHostLobby(string playerName) { - m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost); + var connectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, m_ConnectionManager, m_ProfileManager, playerName); + m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost.Configure(connectionMethod)); } } } diff --git a/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs b/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs index 83c1a8699..eca47b3b6 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionState/StartingHostState.cs @@ -18,6 +18,13 @@ class StartingHostState : OnlineState LobbyServiceFacade m_LobbyServiceFacade; [Inject] LocalLobby m_LocalLobby; + ConnectionMethodBase m_ConnectionMethod; + + public StartingHostState Configure(ConnectionMethodBase baseConnectionMethod) + { + m_ConnectionMethod = baseConnectionMethod; + return this; + } public override void Enter() { @@ -69,7 +76,7 @@ async void StartHost() { try { - await m_ConnectionManager.ConnectionMethod.SetupHostConnectionAsync(); + await m_ConnectionMethod.SetupHostConnectionAsync(); Debug.Log($"Created relay allocation with join code {m_LocalLobby.RelayJoinCode}"); // NGO's StartHost launches everything From 61c74af73877e89b3a602686e260433f56b48af5 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 14:28:22 -0500 Subject: [PATCH 07/11] more debug log --- Assets/Scripts/ConnectionManagement/ConnectionMethod.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs index 988bebd71..3c1d7c0e3 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs @@ -171,7 +171,11 @@ public override async Task SetupClientConnectionAsync() // See https://docs.unity.com/lobby/reconnect-to-lobby.html var lobby = await m_LobbyServiceFacade.ReconnectToLobbyAsync(m_LocalLobby.LobbyID); var success = lobby != null; - if (!success) + if (success) + { + Debug.Log("Successfully reconnected to Lobby."); + } + else { Debug.Log("Failed to reconnect to Lobby."); } From 8d6130aaa9587b9e5797e6c39e4dad96509278f9 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 14:29:44 -0500 Subject: [PATCH 08/11] removing another unneeded using directive --- Assets/Scripts/ConnectionManagement/ConnectionManager.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionManager.cs b/Assets/Scripts/ConnectionManagement/ConnectionManager.cs index b2b2fa42c..3932807c8 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionManager.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionManager.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using Unity.BossRoom.Utils; -using Unity.Collections; using Unity.Netcode; using UnityEngine; using UUnity.BossRoom.ConnectionManagement; From 3c235a22af2383c1c94ea9e9c164673f06d5b194 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 14:37:47 -0500 Subject: [PATCH 09/11] Adding changelog entry --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fdbd3e7f..0a19f1f02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ Additional documentation and release notes are available at [Multiplayer Documen * Clarified a TODO comment inside ClientCharacter, detailing how anticipation should only be executed on owning client players (#786) * Removed now unnecessary cached NetworkBehaviour status on some components, since they now do not allocate memory (#799) +### Changed +* Simplified reconnection flow by offloading responsibility to ConnectionMethod (#804). Now the ClientReconnectingState uses the ConnectionMethod it is configured with to handle setting up reconnection (i.e. reconnecting to the Lobby before trying to reconnect to the Relay server if it is using Relay and Lobby). It can now also fail early and stop retrying if the lobby doesn't exist anymore. + ### Fixed * EnemyPortals' VFX get disabled and re-enabled once the breakable crystals are broken (#784) * Elements inside the Tank's and Rogue's AnimatorTriggeredSpecialFX list have been revised to not loop AudioSource clips, ending the logging of multiple warnings to the console (#785) From 7d110dcb7895b6b70a2a969edd01ff2022c94f58 Mon Sep 17 00:00:00 2001 From: LPLafontaineB Date: Tue, 31 Jan 2023 15:07:18 -0500 Subject: [PATCH 10/11] coding standards --- Assets/Scripts/ConnectionManagement/ConnectionMethod.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs index 3c1d7c0e3..c70e155ed 100644 --- a/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs +++ b/Assets/Scripts/ConnectionManagement/ConnectionMethod.cs @@ -103,7 +103,7 @@ public override async Task SetupClientConnectionAsync() public override async Task<(bool success, bool shouldTryAgain)> SetupClientReconnectionAsync() { // Nothing to do here - return (true,true); + return (true, true); } public override async Task SetupHostConnectionAsync() From e50b6c1516c5b3a61a5fe11d9021a3191fed68da Mon Sep 17 00:00:00 2001 From: Sam Bellomo <71790295+SamuelBellomo@users.noreply.github.com> Date: Wed, 1 Mar 2023 16:21:07 -0500 Subject: [PATCH 11/11] trying a fix for the CLI issue on mobile (cherry picked from commit 1e97c05273556621638f95a83985b468a0c57aab) --- .yamato/mobile-build-and-run.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.yamato/mobile-build-and-run.yml b/.yamato/mobile-build-and-run.yml index 3733e0131..a52461345 100644 --- a/.yamato/mobile-build-and-run.yml +++ b/.yamato/mobile-build-and-run.yml @@ -13,7 +13,7 @@ Build_Player_With_Tests_iOS_{{ project.name }}_{{ editor }}: flavor: b1.large commands: - - pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade + - pip install unity-downloader-cli==1.2.0 --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade - unity-downloader-cli -c Editor -c iOS -u {{ editor }} --fast --wait - curl -s https://artifactory.prd.it.unity3d.com/artifactory/unity-tools-local/utr-standalone/utr --output utr - chmod +x ./utr @@ -42,7 +42,7 @@ Build_Player_With_Tests_Android_{{ project.name }}_{{ editor }}: commands: # Download unity-downloader-cli - - pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade + - pip install unity-downloader-cli==1.2.0 --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade - curl -s https://artifactory.prd.it.unity3d.com/artifactory/unity-tools/utr-standalone/utr.bat --output utr.bat - python .yamato/disable-burst-if-requested.py --project-path {{ project.path }} --platform Android - unity-downloader-cli -c Editor -c Android -u {{ editor }} --fast --wait