new method to query client ip
parent
38958bad95
commit
3b43758054
Binary file not shown.
|
|
@ -123,9 +123,25 @@ namespace Lobbies
|
|||
_ = Task.Run(async () => { await tcpClient.Send(messageData, 0, len); bufferRental.Return(messageData); });
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This callback is called if the nat punch requires the game server/client udp sockets sends a packet to a server so that
|
||||
/// the external mapped port by the firewall can be seen by the external point.
|
||||
/// </summary>
|
||||
/// <param name="remoteEndpoint">The endpoint to send data to</param>
|
||||
/// <param name="messageBuffer">The message byte buffer to send</param>
|
||||
/// <param name="messageLength">Length of the data to send</param>
|
||||
public delegate void SendUdpMessageCallback(IPEndPoint remoteEndpoint, byte[] messageBuffer, int messageLength);
|
||||
public void RequestLobbyNatPunch(Guid lobbyId, string? password, SendUdpMessageCallback sendUdpCallback)
|
||||
|
||||
/// <summary>
|
||||
/// This function requests a nat punch for this client from the game host. First the external port for our game client is detected by
|
||||
/// sending a udp packet to the lobby server who then forwards the nat punch request to the host with the seen external ip and port.
|
||||
/// The game host then sends a udp packet to the client to open it's nat bridge and when done sends a event to the client via the lobby server.
|
||||
/// The client receives the external port and ip seen by the lobby server for the host and can connect to the host.
|
||||
/// </summary>
|
||||
/// <param name="lobbyId">The lobby to request a nat punch for</param>
|
||||
/// <param name="password">Optional password of lobby</param>
|
||||
/// <param name="sendUdpToGetExternalPortMappingCallback">A callback to send udp data if you have a udp game client ready and bound</param>
|
||||
public void RequestLobbyNatPunch(Guid lobbyId, string? password, SendUdpMessageCallback sendUdpToGetExternalPortMappingCallback)
|
||||
{
|
||||
byte[]? passwordHash = null;
|
||||
if (!string.IsNullOrEmpty(password) && lobbyInformation.ContainsKey(lobbyId) && lobbyInformation[lobbyId].PasswordSalt != null)
|
||||
|
|
@ -133,7 +149,45 @@ namespace Lobbies
|
|||
|
||||
Task.Run(() =>
|
||||
{
|
||||
QueryExternalIpAndPort(sendUdpCallback);
|
||||
QueryExternalIpAndPort(sendUdpToGetExternalPortMappingCallback);
|
||||
var lobbyRequestNatPunch = new LobbyRequestNatPunch()
|
||||
{
|
||||
LobbyId = lobbyId,
|
||||
PasswordHash = passwordHash,
|
||||
ClientIp = externalIp,
|
||||
ClientPort = externalPort
|
||||
};
|
||||
|
||||
byte[] messageData = bufferRental.Rent();
|
||||
var len = lobbyRequestNatPunch.Serialize(messageData);
|
||||
_ = Task.Run(async () => { await tcpClient.Send(messageData, 0, len); bufferRental.Return(messageData); });
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function requests a nat punch for this client from the game host. First the external port for our game client is detected by
|
||||
/// sending a udp packet to the lobby server who then forwards the nat punch request to the host with the seen external ip and port.
|
||||
/// The game host then sends a udp packet to the client to open it's nat bridge and when done sends a event to the client via the lobby server.
|
||||
/// The client receives the external port and ip seen by the lobby server for the host and can connect to the host.
|
||||
/// </summary>
|
||||
/// <param name="lobbyId">The lobby to request a nat punch for</param>
|
||||
/// <param name="password">Optional password of lobby</param>
|
||||
/// <param name="port">The port the game client will later use. We create a udp socket on it and send a packet to the lobby server to get the firewall to map that port for a short period of time
|
||||
/// after that the udp client will be disposed</param>
|
||||
public void RequestLobbyNatPunch(Guid lobbyId, string? password, int port = 0)
|
||||
{
|
||||
byte[]? passwordHash = null;
|
||||
if (!string.IsNullOrEmpty(password) && lobbyInformation.ContainsKey(lobbyId) && lobbyInformation[lobbyId].PasswordSalt != null)
|
||||
passwordHash = PasswordHash.Hash(password, lobbyInformation[lobbyId].PasswordSalt!);
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
using (var udpEchoServer = new UdpEchoServer())
|
||||
{
|
||||
udpEchoServer.Start(port);
|
||||
QueryExternalIpAndPort(udpEchoServer.Send);
|
||||
}
|
||||
|
||||
var lobbyRequestNatPunch = new LobbyRequestNatPunch()
|
||||
{
|
||||
LobbyId = lobbyId,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,18 @@ namespace Lobbies
|
|||
serverSocketV6.Send(magicRequest, magicRequest.Length, remoteEndpoint);
|
||||
}
|
||||
|
||||
public void Send(IPEndPoint remoteEndpoint, byte[] messageData, int messageLength)
|
||||
{
|
||||
if (!running || serverSocketV4 == null || serverSocketV6 == null)
|
||||
throw new Exception("Listener not running!");
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
if (remoteEndpoint.AddressFamily == AddressFamily.InterNetwork)
|
||||
serverSocketV4.Send(messageData, messageLength, remoteEndpoint);
|
||||
else
|
||||
serverSocketV6.Send(messageData, messageLength, remoteEndpoint);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Listen to requests and fire events
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ int myExternalPort = -1;
|
|||
bool running = true;
|
||||
bool connected = false;
|
||||
|
||||
_ = Task.Run(async () =>
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
while (running)
|
||||
{
|
||||
foreach (var lobbyEvent in lobbyClient.ReadEvents(20))
|
||||
{
|
||||
{
|
||||
switch (lobbyEvent.EventType)
|
||||
{
|
||||
case LobbyClientEventTypes.Connected:
|
||||
|
|
@ -80,7 +80,7 @@ _ = Task.Run(async () =>
|
|||
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(">");
|
||||
Console.Write(">");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -130,9 +130,9 @@ _ = Task.Run(async () =>
|
|||
|
||||
var p = Console.GetCursorPosition();
|
||||
Console.SetCursorPosition(0, p.Top);
|
||||
Console.WriteLine($"Received my external ip {seenExternalIpAndPort!.Ip}:{seenExternalIpAndPort.Port}");
|
||||
Console.WriteLine($"Received my external ip {seenExternalIpAndPort!.Ip}:{seenExternalIpAndPort.Port}");
|
||||
Console.Write(">");
|
||||
|
||||
|
||||
connected = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -146,7 +146,8 @@ _ = Task.Run(async () =>
|
|||
|
||||
_ = Task.Run(() =>
|
||||
{
|
||||
lobbyClient.QueryExternalIpAndPort((remoteEndpoint, messageData, messageLength) => {
|
||||
lobbyClient.QueryExternalIpAndPort((remoteEndpoint, messageData, messageLength) =>
|
||||
{
|
||||
fakeGameHost.Send(remoteEndpoint, messageData, messageLength);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue