From 3c17ee228b0882589900b7ba66fe71ec327e3a8d Mon Sep 17 00:00:00 2001 From: Thomas Woischnig Date: Mon, 4 Dec 2023 01:32:13 +0100 Subject: [PATCH] Fixing eventflow --- .../Runtime/LobbyClient.dll | Bin 34304 -> 34304 bytes Assets/NetworkLobbyClient/package.json | 2 +- LobbyClient/DirectConnectionResultTest.cs | 17 +++++ LobbyClient/LobbyClient.cs | 15 ++-- LobbyClient/LobbyClientEvent.cs | 6 +- LobbyClientTest/Program.cs | 64 +++++++++++------- LobbyServer.sln | 5 ++ 7 files changed, 80 insertions(+), 29 deletions(-) create mode 100644 LobbyClient/DirectConnectionResultTest.cs diff --git a/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll b/Assets/NetworkLobbyClient/Runtime/LobbyClient.dll index 6a05c08da8e68e8202da8d7d5d358ed7e45944ae..42d76e2bb3a538ab75cbf6fa948a10fd56d2aa22 100644 GIT binary patch literal 34304 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 Fe*=#GnE(I) literal 34304 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 JtPk|S{{ul5jW_@R 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