From dcaeef9ab7271c8e25081b484f9cb0be34294ecd Mon Sep 17 00:00:00 2001 From: Noel Stephens Date: Tue, 19 Nov 2024 15:43:02 -0600 Subject: [PATCH] fix: provide users ability to get client endpoint backport (#3131) * fix Adding method so users can obtain endpoint information about a client's connection. * test Validation test for the GetEndpoint method to assure it returns valid endpoint information. * fix Fixing missed issue with NetworkManagerTests * update adding changelog entry. * style removing white spaces --- com.unity.netcode.gameobjects/CHANGELOG.md | 1 + .../Runtime/Transports/UTP/UnityTransport.cs | 24 +++++++++ .../Runtime/NetworkManagerTransportTests.cs | 50 +++++++++++++++++++ .../Tests/Runtime/NetworkManagerTests.cs | 5 +- 4 files changed, 77 insertions(+), 3 deletions(-) diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index b6e524f537..e47ac97fc3 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -10,6 +10,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Added +- Added `UnityTransport.GetEndpoint` method to provide a way to obtain `NetworkEndpoint` information of a connection via client identifier. (#3131) - Added a static `NetworkManager.OnInstantiated` event notification to be able to track when a new `NetworkManager` instance has been instantiated. (#3089) - Added a static `NetworkManager.OnDestroying` event notification to be able to track when an existing `NetworkManager` instance is being destroyed. (#3089) - Added message size validation to named and unnamed message sending functions for better error messages. (#3043) diff --git a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs index fec165bf4e..420bad1460 100644 --- a/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs +++ b/com.unity.netcode.gameobjects/Runtime/Transports/UTP/UnityTransport.cs @@ -1209,6 +1209,30 @@ public override ulong GetCurrentRtt(ulong clientId) return (ulong)ExtractRtt(ParseClientId(clientId)); } + /// + /// Provides the for the NGO client identifier specified. + /// + /// + /// - This is only really useful for direct connections. + /// - Relay connections and clients connected using a distributed authority network topology will not provide the client's actual endpoint information. + /// - For LAN topologies this should work as long as it is a direct connection and not a relay connection. + /// + /// NGO client identifier to get endpoint information about. + /// + public NetworkEndpoint GetEndpoint(ulong clientId) + { + if (m_Driver.IsCreated && NetworkManager != null && NetworkManager.IsListening) + { + var transportId = NetworkManager.ConnectionManager.ClientIdToTransportId(clientId); + var networkConnection = ParseClientId(transportId); + if (m_Driver.GetConnectionState(networkConnection) == NetworkConnection.State.Connected) + { + return m_Driver.RemoteEndPoint(networkConnection); + } + } + return new NetworkEndpoint(); + } + /// /// Initializes the transport /// diff --git a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs index fa1fbdaf3d..a9d8e3ae52 100644 --- a/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs +++ b/com.unity.netcode.gameobjects/Tests/Runtime/NetworkManagerTransportTests.cs @@ -1,6 +1,9 @@ using System; using System.Collections; using NUnit.Framework; +using Unity.Netcode.TestHelpers.Runtime; +using Unity.Netcode.Transports.UTP; +using Unity.Networking.Transport; using UnityEngine; using UnityEngine.TestTools; @@ -157,4 +160,51 @@ public override void DisconnectLocalClient() } } } + + /// + /// Verifies the UnityTransport.GetEndpoint method returns + /// valid NetworkEndPoint information. + /// + internal class TransportEndpointTests : NetcodeIntegrationTest + { + protected override int NumberOfClients => 2; + + [UnityTest] + public IEnumerator GetEndpointReportedCorrectly() + { + var serverUnityTransport = m_ServerNetworkManager.NetworkConfig.NetworkTransport as UnityTransport; + var serverEndpoint = new NetworkEndPoint(); + var clientEndpoint = new NetworkEndPoint(); + foreach (var client in m_ClientNetworkManagers) + { + var unityTransport = client.NetworkConfig.NetworkTransport as UnityTransport; + serverEndpoint = unityTransport.GetEndpoint(m_ServerNetworkManager.LocalClientId); + clientEndpoint = serverUnityTransport.GetEndpoint(client.LocalClientId); + Assert.IsTrue(serverEndpoint.IsValid); + Assert.IsTrue(clientEndpoint.IsValid); + Assert.IsTrue(clientEndpoint.Address.Split(":")[0] == unityTransport.ConnectionData.Address); + Assert.IsTrue(serverEndpoint.Address.Split(":")[0] == serverUnityTransport.ConnectionData.Address); + Assert.IsTrue(serverEndpoint.Port == unityTransport.ConnectionData.Port); + Assert.IsTrue(clientEndpoint.Port >= serverUnityTransport.ConnectionData.Port); + } + + // Now validate that when disconnected it returns a non-valid NetworkEndPoint + var clientId = m_ClientNetworkManagers[0].LocalClientId; + m_ClientNetworkManagers[0].Shutdown(); + yield return s_DefaultWaitForTick; + + serverEndpoint = (m_ClientNetworkManagers[0].NetworkConfig.NetworkTransport as UnityTransport).GetEndpoint(m_ServerNetworkManager.LocalClientId); + clientEndpoint = serverUnityTransport.GetEndpoint(clientId); + Assert.IsFalse(serverEndpoint.IsValid); + Assert.IsFalse(clientEndpoint.IsValid); + + // Validate that invalid client identifiers return an invalid NetworkEndPoint + serverEndpoint = (m_ClientNetworkManagers[0].NetworkConfig.NetworkTransport as UnityTransport).GetEndpoint((ulong)UnityEngine.Random.Range(NumberOfClients + 1, 30)); + clientEndpoint = serverUnityTransport.GetEndpoint((ulong)UnityEngine.Random.Range(NumberOfClients + 1, 30)); + Assert.IsFalse(serverEndpoint.IsValid); + Assert.IsFalse(clientEndpoint.IsValid); + } + } + + } diff --git a/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs b/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs index 277e8f8836..b09dd5e291 100644 --- a/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs +++ b/testproject/Assets/Tests/Runtime/NetworkManagerTests.cs @@ -22,7 +22,6 @@ public enum UseSceneManagement SceneManagementDisabled } - private bool m_EnableSceneManagement; private NetworkObject m_NetworkObject; private bool m_NetworkObjectWasSpawned; private bool m_NetworkBehaviourIsHostWasSet; @@ -85,7 +84,7 @@ protected override IEnumerator OnTearDown() protected override void OnServerAndClientsCreated() { - m_ServerNetworkManager.NetworkConfig.EnableSceneManagement = m_EnableSceneManagement; + m_ServerNetworkManager.NetworkConfig.EnableSceneManagement = m_UseSceneManagement; m_NetworkObjectTestComponent.ConfigureClientConnected(m_ServerNetworkManager, OnClientConnectedCallback); } @@ -108,7 +107,7 @@ public enum ShutdownChecks protected override void OnNewClientCreated(NetworkManager networkManager) { - networkManager.NetworkConfig.EnableSceneManagement = m_EnableSceneManagement; + networkManager.NetworkConfig.EnableSceneManagement = m_UseSceneManagement; foreach (var prefab in m_ServerNetworkManager.NetworkConfig.Prefabs.Prefabs) { networkManager.NetworkConfig.Prefabs.Add(prefab);