Skip to content

feat: Bump to NGO 1.1.1 #773

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
6f05618
After this PR https://github.com/Unity-Technologies/com.unity.netcode…
SamuelBellomo Jul 26, 2022
519bd5e
Merge branch 'develop' into sam/feat/bump-NGO-to-1.1
SamuelBellomo Aug 10, 2022
c13ba78
Merge branch 'develop' into sam/feat/bump-NGO-to-1.1
SamuelBellomo Oct 13, 2022
2a69af7
basis works, still need to debug issue with client reconnecting a sec…
SamuelBellomo Oct 13, 2022
29d79b8
setting back max payload size to default value. With recent changes, …
SamuelBellomo Oct 14, 2022
2b50fd9
Increasing connection approval timeout to 5 seconds, as 1 second was …
SamuelBellomo Oct 14, 2022
59ab475
making diff clearer for review
SamuelBellomo Oct 17, 2022
d3f59da
adding better exception error
SamuelBellomo Oct 17, 2022
5bb2994
using classes instead of structs now that we have managed types avail…
SamuelBellomo Oct 17, 2022
ab1174b
Merge branch 'develop' into sam/feat/bump-NGO-to-1.1
SamuelBellomo Oct 17, 2022
2913b23
fixing null ref when doing reconnection flow
SamuelBellomo Oct 17, 2022
5f3bc3e
reverting removal of utilities
SamuelBellomo Oct 18, 2022
b84f7a7
deprecated note
SamuelBellomo Oct 18, 2022
b7e83c3
better comments, cleaner easier to read code.
SamuelBellomo Oct 19, 2022
243bdef
cleanup
SamuelBellomo Oct 19, 2022
171a936
Update changelog
SamuelBellomo Oct 19, 2022
77e8900
Merge branch 'develop' into sam/feat/bump-NGO-to-1.1
SamuelBellomo Oct 19, 2022
55d13ba
adding missing PR ID
SamuelBellomo Oct 19, 2022
e163ce1
adding missing PR ID
SamuelBellomo Oct 19, 2022
b6705f4
removing useless usings
SamuelBellomo Oct 20, 2022
864fead
Merge branch 'sam/feat/bump-NGO-to-1.1' of github.com:Unity-Technolog…
SamuelBellomo Oct 20, 2022
2fe2683
namespace adjustements
SamuelBellomo Oct 20, 2022
dfda378
updating manifest and dependencies with 1.1.0 now it's released
SamuelBellomo Oct 20, 2022
11f076e
Merge develop into sam/feat/bump-NGO-to-1.1
netcode-ci-service Oct 20, 2022
4b79d59
Merge develop into sam/feat/bump-NGO-to-1.1
netcode-ci-service Oct 20, 2022
521c019
initializing number of reconnect attempts before starting the reconne…
LPLafontaineB Oct 24, 2022
48573dd
fixing player prefab being destroyed issue
SamuelBellomo Oct 24, 2022
2cebbd2
Merge branch 'sam/feat/bump-NGO-to-1.1' of github.com:Unity-Technolog…
SamuelBellomo Oct 24, 2022
324a5ec
Removing workaround
SamuelBellomo Oct 24, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions Assets/Prefabs/NetworkingManager.prefab
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ MonoBehaviour:
SourceHashToOverride: 0
OverridingTargetPrefab: {fileID: 0}
TickRate: 30
ClientConnectionBufferTimeout: 1
ClientConnectionBufferTimeout: 5
ConnectionApproval: 1
ConnectionData:
EnableTimeResync: 0
Expand Down Expand Up @@ -136,8 +136,7 @@ MonoBehaviour:
m_EditorClassIdentifier:
m_ProtocolType: 0
m_MaxPacketQueueSize: 512
m_MaxPayloadSize: 32000
m_MaxSendQueueSize: 50000000
m_MaxPayloadSize: 6144
m_HeartbeatTimeoutMS: 500
m_ConnectTimeoutMS: 1000
m_MaxConnectAttempts: 10
Expand Down
158 changes: 158 additions & 0 deletions Assets/Scripts/ConnectionManagement/ConnectionMethod.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using System;
using System.Threading.Tasks;
using Unity.BossRoom.UnityServices.Lobbies;
using Unity.BossRoom.Utils;
using Unity.Netcode.Transports.UTP;
using Unity.Networking.Transport.Relay;
using Unity.Services.Authentication;
using Unity.Services.Core;
using Unity.Services.Relay;
using Unity.Services.Relay.Models;
using UnityEngine;

namespace Unity.BossRoom.ConnectionManagement
{
/// <summary>
/// ConnectionMethod contains all setup needed to setup NGO to be ready to start a connection, either host or client side.
/// Please override this abstract class to add a new transport or way of connecting.
/// </summary>
public abstract class ConnectionMethodBase
{
protected ConnectionManager m_ConnectionManager;
readonly ProfileManager m_ProfileManager;
protected readonly string m_PlayerName;

public abstract Task SetupHostConnectionAsync();

public abstract Task SetupClientConnectionAsync();

public ConnectionMethodBase(ConnectionManager connectionManager, ProfileManager profileManager, string playerName)
{
m_ConnectionManager = connectionManager;
m_ProfileManager = profileManager;
m_PlayerName = playerName;
}

protected void SetConnectionPayload(string playerId, string playerName)
{
var payload = JsonUtility.ToJson(new ConnectionPayload()
{
playerId = playerId,
playerName = playerName,
isDebug = Debug.isDebugBuild
});

var payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);

m_ConnectionManager.NetworkManager.NetworkConfig.ConnectionData = payloadBytes;
}

protected string GetPlayerId()
{
if (Services.Core.UnityServices.State != ServicesInitializationState.Initialized)
{
return ClientPrefs.GetGuid() + m_ProfileManager.Profile;
}

return AuthenticationService.Instance.IsSignedIn ? AuthenticationService.Instance.PlayerId : ClientPrefs.GetGuid() + m_ProfileManager.Profile;
}
}

/// <summary>
/// Simple IP connection setup with UTP
/// </summary>
class ConnectionMethodIP : ConnectionMethodBase
{
string m_Ipaddress;
ushort m_Port;

public ConnectionMethodIP(string ip, ushort port, ConnectionManager connectionManager, ProfileManager profileManager, string playerName)
: base(connectionManager, profileManager, playerName)
{
m_Ipaddress = ip;
m_Port = port;
m_ConnectionManager = connectionManager;
}

public override async Task SetupClientConnectionAsync()
{
SetConnectionPayload(GetPlayerId(), m_PlayerName);
var utp = (UnityTransport)m_ConnectionManager.NetworkManager.NetworkConfig.NetworkTransport;
utp.SetConnectionData(m_Ipaddress, m_Port);
}

public override async Task SetupHostConnectionAsync()
{
SetConnectionPayload(GetPlayerId(), m_PlayerName); // Need to set connection payload for host as well, as host is a client too
var utp = (UnityTransport)m_ConnectionManager.NetworkManager.NetworkConfig.NetworkTransport;
utp.SetConnectionData(m_Ipaddress, m_Port);
}
}

/// <summary>
/// UTP's Relay connection setup
/// </summary>
class ConnectionMethodRelay : ConnectionMethodBase
{
LobbyServiceFacade m_LobbyServiceFacade;
LocalLobby m_LocalLobby;

public ConnectionMethodRelay(LobbyServiceFacade lobbyServiceFacade, LocalLobby localLobby, ConnectionManager connectionManager, ProfileManager profileManager, string playerName)
: base(connectionManager, profileManager, playerName)
{
m_LobbyServiceFacade = lobbyServiceFacade;
m_LocalLobby = localLobby;
m_ConnectionManager = connectionManager;
}

public override async Task SetupClientConnectionAsync()
{
Debug.Log("Setting up Unity Relay client");

SetConnectionPayload(GetPlayerId(), m_PlayerName);

if (m_LobbyServiceFacade.CurrentUnityLobby == null)
{
throw new Exception("Trying to start relay while Lobby isn't set");
}

Debug.Log($"Setting Unity Relay client with join code {m_LocalLobby.RelayJoinCode}");

// Create client joining allocation from join code
var joinedAllocation = await RelayService.Instance.JoinAllocationAsync(m_LocalLobby.RelayJoinCode);
Debug.Log($"client: {joinedAllocation.ConnectionData[0]} {joinedAllocation.ConnectionData[1]}, " +
$"host: {joinedAllocation.HostConnectionData[0]} {joinedAllocation.HostConnectionData[1]}, " +
$"client: {joinedAllocation.AllocationId}");

await m_LobbyServiceFacade.UpdatePlayerRelayInfoAsync(joinedAllocation.AllocationId.ToString(), m_LocalLobby.RelayJoinCode);

// Configure UTP with allocation
var utp = (UnityTransport)m_ConnectionManager.NetworkManager.NetworkConfig.NetworkTransport;
utp.SetRelayServerData(new RelayServerData(joinedAllocation, OnlineState.k_DtlsConnType));
}

public override async Task SetupHostConnectionAsync()
{
Debug.Log("Setting up Unity Relay host");

SetConnectionPayload(GetPlayerId(), m_PlayerName); // Need to set connection payload for host as well, as host is a client too

// Create relay allocation
Allocation hostAllocation = await RelayService.Instance.CreateAllocationAsync(m_ConnectionManager.MaxConnectedPlayers, region: null);
var joinCode = await RelayService.Instance.GetJoinCodeAsync(hostAllocation.AllocationId);

Debug.Log($"server: connection data: {hostAllocation.ConnectionData[0]} {hostAllocation.ConnectionData[1]}, " +
$"allocation ID:{hostAllocation.AllocationId}, region:{hostAllocation.Region}");

m_LocalLobby.RelayJoinCode = joinCode;

//next line enable lobby and relay services integration
await m_LobbyServiceFacade.UpdateLobbyDataAsync(m_LocalLobby.GetDataForUnityServices());
await m_LobbyServiceFacade.UpdatePlayerRelayInfoAsync(hostAllocation.AllocationIdBytes.ToString(), joinCode);

// Setup UTP with relay connection info
var utp = (UnityTransport)m_ConnectionManager.NetworkManager.NetworkConfig.NetworkTransport;
utp.SetRelayServerData(new RelayServerData(hostAllocation, OnlineState.k_DtlsConnType)); // This is with DTLS enabled for a secure connection
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
using System;
using System.Threading.Tasks;
using Unity.BossRoom.UnityServices.Lobbies;
using Unity.Multiplayer.Samples.BossRoom;
using Unity.Multiplayer.Samples.Utilities;
using Unity.Netcode.Transports.UTP;
using UnityEngine;
using VContainer;

Expand All @@ -20,6 +18,13 @@ class ClientConnectingState : OnlineState
protected LobbyServiceFacade m_LobbyServiceFacade;
[Inject]
protected LocalLobby m_LocalLobby;
ConnectionMethodBase m_ConnectionMethod;

public ClientConnectingState Configure(ConnectionMethodBase baseConnectionMethod)
{
m_ConnectionMethod = baseConnectionMethod;
return this;
}

public override void Enter()
{
Expand All @@ -37,6 +42,12 @@ public override void OnClientConnected(ulong _)
}

public override void OnClientDisconnect(ulong _)
{
// client ID is for sure ours here
StartingClientFailedAsync();
}

protected void StartingClientFailedAsync()
{
m_ConnectStatusPublisher.Publish(ConnectStatus.StartClientFailed);
m_ConnectionManager.ChangeState(m_ConnectionManager.m_Offline);
Expand All @@ -48,52 +59,30 @@ public override void OnDisconnectReasonReceived(ConnectStatus disconnectReason)
m_ConnectionManager.ChangeState(m_ConnectionManager.m_DisconnectingWithReason);
}

protected async Task ConnectClientAsync()

internal async Task ConnectClientAsync()
{
bool success = true;
if (m_LobbyServiceFacade.CurrentUnityLobby != null)
try
{
success = await JoinRelayServerAsync();
}
// Setup NGO with current connection method
await m_ConnectionMethod.SetupClientConnectionAsync();

if (success)
{
success = m_ConnectionManager.NetworkManager.StartClient();
}
// NGO's StartClient launches everything
if (!m_ConnectionManager.NetworkManager.StartClient())
{
throw new Exception("NetworkManager StartClient failed");
}

if (success)
{
SceneLoaderWrapper.Instance.AddOnSceneEventCallback();
m_ConnectionManager.RegisterCustomMessages();
}
else
{
OnClientDisconnect(0);
}
}

async Task<bool> JoinRelayServerAsync()
{
Debug.Log($"Setting Unity Relay client with join code {m_LocalLobby.RelayJoinCode}");

try
{
var (ipv4Address, port, allocationIdBytes, allocationId, connectionData, hostConnectionData, key) =
await UnityRelayUtilities.JoinRelayServerFromJoinCode(m_LocalLobby.RelayJoinCode);

await m_LobbyServiceFacade.UpdatePlayerRelayInfoAsync(allocationId.ToString(), m_LocalLobby.RelayJoinCode);
var utp = (UnityTransport)m_ConnectionManager.NetworkManager.NetworkConfig.NetworkTransport;
utp.SetClientRelayData(ipv4Address, port, allocationIdBytes, key, connectionData, hostConnectionData, isSecure: true);
}
catch (Exception e)
{
Debug.Log($"Relay join failed: {e.Message}");
//leave the lobby if relay failed for some reason
await m_LobbyServiceFacade.EndTracking();
return false;
Debug.LogError("Error connecting client, see following exception");
Debug.LogException(e);
StartingClientFailedAsync();
throw;
}

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ 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());
m_NbAttempts = 0;
}

public override void Exit()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@
using Unity.BossRoom.UnityServices.Lobbies;
using Unity.BossRoom.Utils;
using Unity.Multiplayer.Samples.Utilities;
using Unity.Netcode.Transports.UTP;
using Unity.Services.Authentication;
using Unity.Services.Core;
using UnityEngine;
using UnityEngine.SceneManagement;
using VContainer;
Expand All @@ -22,6 +19,8 @@ class OfflineState : ConnectionState
LobbyServiceFacade m_LobbyServiceFacade;
[Inject]
ProfileManager m_ProfileManager;
[Inject]
LocalLobby m_LocalLobby;

const string k_MainMenuSceneName = "MainMenu";

Expand All @@ -39,55 +38,28 @@ public override void Exit() { }

public override void StartClientIP(string playerName, string ipaddress, int port)
{
var utp = (UnityTransport)m_ConnectionManager.NetworkManager.NetworkConfig.NetworkTransport;
utp.SetConnectionData(ipaddress, (ushort)port);
SetConnectionPayload(GetPlayerId(), playerName);
m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting);
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)
{
SetConnectionPayload(GetPlayerId(), playerName);
m_ConnectionManager.ChangeState(m_ConnectionManager.m_ClientConnecting);
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)
{
var utp = (UnityTransport)m_ConnectionManager.NetworkManager.NetworkConfig.NetworkTransport;
utp.SetConnectionData(ipaddress, (ushort)port);

SetConnectionPayload(GetPlayerId(), playerName);
m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost);
var connectionMethod = new ConnectionMethodIP(ipaddress, (ushort)port, m_ConnectionManager, m_ProfileManager, playerName);
m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost.Configure(connectionMethod));
}

public override void StartHostLobby(string playerName)
{
SetConnectionPayload(GetPlayerId(), playerName);
m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost);
}

void SetConnectionPayload(string playerId, string playerName)
{
var payload = JsonUtility.ToJson(new ConnectionPayload()
{
playerId = playerId,
playerName = playerName,
isDebug = Debug.isDebugBuild
});

var payloadBytes = System.Text.Encoding.UTF8.GetBytes(payload);

m_ConnectionManager.NetworkManager.NetworkConfig.ConnectionData = payloadBytes;
}

string GetPlayerId()
{
if (UnityServices.State != ServicesInitializationState.Initialized)
{
return ClientPrefs.GetGuid() + m_ProfileManager.Profile;
}

return AuthenticationService.Instance.IsSignedIn ? AuthenticationService.Instance.PlayerId : ClientPrefs.GetGuid() + m_ProfileManager.Profile;
var connectionMethod = new ConnectionMethodRelay(m_LobbyServiceFacade, m_LocalLobby, m_ConnectionManager, m_ProfileManager, playerName);
m_ConnectionManager.ChangeState(m_ConnectionManager.m_StartingHost.Configure(connectionMethod));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ namespace Unity.BossRoom.ConnectionManagement
/// </summary>
abstract class OnlineState : ConnectionState
{
public const string k_DtlsConnType = "dtls";

public override void OnUserRequestedShutdown()
{
Expand Down
Loading