diff --git a/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll b/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll index 6a05c08..42d76e2 100644 Binary files a/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll and b/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll differ diff --git a/Assets/NetworkLobbyClient/package.json b/Assets/NetworkLobbyClient/package.json index b21672f..82c2372 100644 --- a/Assets/NetworkLobbyClient/package.json +++ b/Assets/NetworkLobbyClient/package.json @@ -1,6 +1,6 @@ { "name": "com.incobyte.lobbyclient", - "version": "1.0.0", + "version": "1.0.1", "displayName": "Game Lobby Client", "description": "Provides a client for the game lobvy server to list and join lobbies", "unity": "2022.3", diff --git a/LobbyClient/DirectConnectionResultTest.cs b/LobbyClient/DirectConnectionResultTest.cs new file mode 100644 index 0000000..407862a --- /dev/null +++ b/LobbyClient/DirectConnectionResultTest.cs @@ -0,0 +1,17 @@ +using System.Net; + +namespace Lobbies +{ + public class DirectConnectionTestResult + { + /// + /// True if a direct connection was possible + /// + public bool DirectConnectionPossible { get; internal set; } + + /// + /// The ip address the connection succeeded on + /// + public IPAddress? IPAddress { get; internal set; } + } +} diff --git a/LobbyClient/LobbyClient.cs b/LobbyClient/LobbyClient.cs index b6c42dc..47cad0e 100644 --- a/LobbyClient/LobbyClient.cs +++ b/LobbyClient/LobbyClient.cs @@ -216,16 +216,23 @@ namespace Lobbies _ = Task.Run(async () => { await tcpClient.Send(messageData, 0, len); bufferRental.Return(messageData); }); } - public async Task TryDirectConnection(IPAddress[] ipAddressesToTry, int tryPort) + public Task TryDirectConnection(IPAddress[] ipAddressesToTry, int tryPort) { - return await Task.Run(() => + return Task.Run(() => { IPAddress? ret = null; + using(var waitForIpEvent = new AutoResetEvent(false)) using (var udpEchoClient = new UdpEchoServer()) { udpEchoClient.Reached += (ep) => { ret = ep.Address; + try + { + waitForIpEvent.Set(); + udpEchoClient.Stop(); + } + catch { } }; udpEchoClient.Start(0); @@ -235,10 +242,10 @@ namespace Lobbies udpEchoClient.CheckConnectionPossible(new IPEndPoint(ip, tryPort)); } - Thread.Sleep(500); + waitForIpEvent.WaitOne(500); } - return ret; + events.Enqueue(new LobbyClientEvent { EventType = LobbyClientEventTypes.DirectConnectionTestComplete, EventData = new DirectConnectionTestResult { DirectConnectionPossible = ret != null, IPAddress = ret } }); }); } diff --git a/LobbyClient/LobbyClientEvent.cs b/LobbyClient/LobbyClientEvent.cs index b4a5770..69f78f5 100644 --- a/LobbyClient/LobbyClientEvent.cs +++ b/LobbyClient/LobbyClientEvent.cs @@ -59,6 +59,10 @@ /// /// Response to a query of our external ip and port seen by the lobby server. EventData is with the clients seen external address. /// - ExternalIpAndPort + ExternalIpAndPort, + /// + /// A direct connection test without a nat punch was testet. EventData is with information if a direct connection was possible and on what address. + /// + DirectConnectionTestComplete } } diff --git a/LobbyClientTest/Program.cs b/LobbyClientTest/Program.cs index 430252c..cb2a81f 100644 --- a/LobbyClientTest/Program.cs +++ b/LobbyClientTest/Program.cs @@ -10,7 +10,7 @@ var lobbyClient = new LobbyClient(); var cancellationTokenSource = new CancellationTokenSource(); List openLobbies = new List(); - +LobbyHostInfo? currentLobbyHostInfo = null; lobbyClient.Connect("lobby.incobyte.de" /*"localhost"*/, 8088, cancellationTokenSource.Token); FakeGameHost fakeGameHost = new FakeGameHost(); @@ -73,35 +73,53 @@ _ = Task.Run(async () => running = false; } break; - case LobbyClientEventTypes.LobbyHostInfo: + case LobbyClientEventTypes.DirectConnectionTestComplete: + var result = lobbyEvent.EventData as DirectConnectionTestResult; + if (result != null && result.DirectConnectionPossible) { - var lobbyHostInfo = lobbyEvent.EventData as LobbyHostInfo; - var p = Console.GetCursorPosition(); - Console.SetCursorPosition(0, p.Top); - Console.WriteLine($"Host info for lobby {lobbyHostInfo!.LobbyId} is {(lobbyHostInfo.HostIps != null && lobbyHostInfo.HostIps.Length > 0 ? lobbyHostInfo.HostIps[0].ToString() : "")}:{lobbyHostInfo.HostPort}!"); - - //Try direct connection - if (lobbyHostInfo.HostIps != null && lobbyHostInfo.HostIps.Length > 0) - { - Console.WriteLine($"Trying direct connection to {string.Join(",", lobbyHostInfo.HostIps)} on port {lobbyHostInfo.HostTryPort}!"); - var reachableIp = await lobbyClient.TryDirectConnection(lobbyHostInfo.HostIps, lobbyHostInfo.HostTryPort); - if(reachableIp != null) - { - Console.WriteLine($"Direct connection to {reachableIp.ToString()} possible, using direct connection!"); - Console.WriteLine($"Connecting game client!"); - fakeGameHost.Send(new IPEndPoint(reachableIp, lobbyHostInfo.HostPort), "Hello from Game Client!"); - Console.Write(">"); - continue; - } - } - + Console.WriteLine($"Direct connection to {result.IPAddress!.ToString()} possible, using direct connection!"); + Console.WriteLine($"Connecting game client!"); + fakeGameHost.Send(new IPEndPoint(result.IPAddress!, currentLobbyHostInfo!.HostPort), "Hello from Game Client!"); + Console.Write(">"); + } + else + { + Console.WriteLine($"Direct connection no route found!"); Console.WriteLine($"Requesting nat punch to me!"); - lobbyClient.RequestLobbyNatPunch(lobbyHostInfo.LobbyId, null, (remoteEndpoint, messageBuffer, messageLength) => { + + lobbyClient.RequestLobbyNatPunch(currentLobbyHostInfo!.LobbyId, null, (remoteEndpoint, messageBuffer, messageLength) => + { fakeGameHost.Send(remoteEndpoint, messageBuffer, messageLength); }); Console.Write(">"); } break; + case LobbyClientEventTypes.LobbyHostInfo: + { + var lobbyHostInfo = lobbyEvent.EventData as LobbyHostInfo; + currentLobbyHostInfo = lobbyHostInfo; + + var p = Console.GetCursorPosition(); + Console.SetCursorPosition(0, p.Top); + Console.WriteLine($"Host info for lobby {lobbyHostInfo!.LobbyId} is {(lobbyHostInfo.HostIps != null && lobbyHostInfo.HostIps.Length > 0 ? lobbyHostInfo.HostIps[0].ToString() : "")}:{lobbyHostInfo.HostPort}!"); + + //Try direct connection + if (lobbyHostInfo.HostIps != null && lobbyHostInfo.HostIps.Length > 0) + { + Console.WriteLine($"Trying direct connection to {string.Join(",", lobbyHostInfo.HostIps)} on port {lobbyHostInfo.HostTryPort}!"); + _ = lobbyClient.TryDirectConnection(lobbyHostInfo.HostIps, lobbyHostInfo.HostTryPort); + } + else + { + Console.WriteLine($"Requesting nat punch to me!"); + lobbyClient.RequestLobbyNatPunch(lobbyHostInfo.LobbyId, null, (remoteEndpoint, messageBuffer, messageLength) => + { + fakeGameHost.Send(remoteEndpoint, messageBuffer, messageLength); + }); + Console.Write(">"); + } + } + break; case LobbyClientEventTypes.ExternalIpAndPort: { var seenExternalIpAndPort = lobbyEvent.EventData as SeenExternalIpAndPort; diff --git a/LobbyServer.sln b/LobbyServer.sln index aaad659..2c6ce46 100644 --- a/LobbyServer.sln +++ b/LobbyServer.sln @@ -13,6 +13,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServerDto", "LobbyServ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LobbyServerSourceGenerator", "LobbyServerSourceGenerator\LobbyServerSourceGenerator.csproj", "{04F95131-C7EF-410B-94E5-2D9162763155}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Projektmappenelemente", "Projektmappenelemente", "{F27779F1-9CE7-4642-9111-E6B96331C2DB}" + ProjectSection(SolutionItems) = preProject + Assets\NetworkLobbyClient\package.json = Assets\NetworkLobbyClient\package.json + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU