Skip to content

Commit cbe0985

Browse files
committed
update sample peerId logic
1 parent 3834fbd commit cbe0985

File tree

4 files changed

+61
-44
lines changed

4 files changed

+61
-44
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<component name="ProjectRunConfigurationManager">
2+
<configuration default="false" name="SpaceWar.Lobby (local 9101) " type="DotNetProject" factoryName=".NET Project">
3+
<option name="EXE_PATH" value="$PROJECT_DIR$/SpaceWar.Lobby/bin/Debug/net8.0/SpaceWar.exe" />
4+
<option name="PROGRAM_PARAMETERS" value="-LocalPort 9101 -ServerUrl &quot;http://localhost:9999&quot;" />
5+
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/SpaceWar.Lobby/bin/Debug/net8.0" />
6+
<option name="PASS_PARENT_ENVS" value="1" />
7+
<option name="ENV_FILE_PATHS" value="" />
8+
<option name="REDIRECT_INPUT_PATH" value="" />
9+
<option name="MIXED_MODE_DEBUG" value="0" />
10+
<option name="USE_MONO" value="0" />
11+
<option name="RUNTIME_ARGUMENTS" value="" />
12+
<option name="AUTO_ATTACH_CHILDREN" value="0" />
13+
<option name="PROJECT_PATH" value="$PROJECT_DIR$/SpaceWar.Lobby/SpaceWar.Lobby.csproj" />
14+
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
15+
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
16+
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
17+
<option name="PROJECT_KIND" value="DotNetCore" />
18+
<option name="PROJECT_TFM" value="net8.0" />
19+
<method v="2">
20+
<option name="Build" />
21+
</method>
22+
</configuration>
23+
</component>

samples/SpaceWar.Lobby/Models/Peer.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Diagnostics.CodeAnalysis;
12
using System.Net;
23

34
namespace SpaceWar.Models;
@@ -10,4 +11,9 @@ public sealed class Peer
1011
public IPEndPoint? LocalEndpoint { get; init; }
1112
public bool Connected { get; init; }
1213
public bool Ready { get; init; }
14+
15+
[MemberNotNullWhen(true, nameof(LocalEndpoint))]
16+
public bool InSameNetwork(User user) => LocalEndpoint is not null && Equals(Endpoint.Address, user.IP);
17+
18+
public IPEndPoint GetEndpointForUser(User user) => InSameNetwork(user) ? LocalEndpoint : Endpoint;
1319
}

samples/SpaceWar.Lobby/Scenes/LobbyScene.cs

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -357,28 +357,21 @@ void StartPlayerBattleScene()
357357
if (lobbyInfo is null) return;
358358

359359
currentState = LobbyState.Starting;
360-
List<NetcodePlayer> players = [];
361-
362-
for (var i = 0; i < lobbyInfo.Players.Length; i++)
363-
{
364-
var player = lobbyInfo.Players[i];
365-
366-
players.Add(
360+
var players = lobbyInfo.Players
361+
.Select(player =>
367362
player.PeerId == user.PeerId
368363
? NetcodePlayer.CreateLocal()
369-
: NetcodePlayer.CreateRemote(LobbyUdpClient.GetFallbackEndpoint(user, player))
370-
);
371-
}
364+
: NetcodePlayer.CreateRemote(player.GetEndpointForUser(user)))
365+
.ToList();
372366

373367
if (lobbyInfo.SpectatorMapping.SingleOrDefault(m => m.Host == user.PeerId)
374-
is { Watchers: { } spectatorIds })
368+
is { Watchers: { Length: > 0 } spectatorIds })
375369
{
376-
var spectators = lobbyInfo.Spectators.Where(s => spectatorIds.Contains(s.PeerId));
377-
foreach (var spectator in spectators)
378-
{
379-
var spectatorEndpoint = LobbyUdpClient.GetFallbackEndpoint(user, spectator);
380-
players.Add(NetcodePlayer.CreateSpectator(spectatorEndpoint));
381-
}
370+
var spectators = lobbyInfo.Spectators
371+
.Where(s => spectatorIds.Contains(s.PeerId))
372+
.Select(s => NetcodePlayer.CreateSpectator(s.GetEndpointForUser(user)));
373+
374+
players.AddRange(spectators);
382375
}
383376

384377
var netcodeSession = NetcodeSessionBuilder()
@@ -391,12 +384,10 @@ void StartPlayerBattleScene()
391384

392385
void StartSpectatorBattleScene()
393386
{
394-
var hostId = lobbyInfo.SpectatorMapping
395-
.SingleOrDefault(x => x.Watchers.Contains(user.PeerId))
396-
?.Host;
387+
var hostId = lobbyInfo.SpectatorMapping.SingleOrDefault(x => x.Watchers.Contains(user.PeerId))?.Host;
397388
var host = lobbyInfo.Players.Single(x => x.PeerId == hostId);
398389
var playerCount = lobbyInfo.Players.Length;
399-
var hostEndpoint = LobbyUdpClient.GetFallbackEndpoint(user, host);
390+
var hostEndpoint = host.GetEndpointForUser(user);
400391

401392
Window.Title = $"Space War {Config.LocalPort} - {user.Username} watching {host.Username}";
402393

samples/SpaceWar.Lobby/Services/LobbyUdpClient.cs

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ public sealed class LobbyUdpClient : IDisposable
1111
readonly IPEndPoint serverEndpoint;
1212
readonly UdpSocket socket;
1313
readonly CancellationTokenSource cts = new();
14-
readonly byte[] buffer = GC.AllocateArray<byte>(36, pinned: true);
15-
14+
readonly byte[] sendBuffer = GC.AllocateArray<byte>(Unsafe.SizeOf<Guid>(), pinned: true);
1615
readonly HashSet<Guid> knownClients = [];
1716
bool disposed;
1817

@@ -27,45 +26,52 @@ public LobbyUdpClient(int localPort, Uri serverUrl, int serverPort)
2726

2827
public async Task HandShake(User user, CancellationToken ct = default)
2928
{
30-
if (!user.Token.TryFormat(buffer, out var bytesWritten) || bytesWritten is 0) return;
31-
await socket.SendToAsync(buffer.AsMemory()[..bytesWritten], serverEndpoint, ct);
29+
if (!user.Token.TryWriteBytes(sendBuffer, true, out var bytesWritten) || bytesWritten is 0)
30+
return;
31+
32+
await socket.SendToAsync(sendBuffer.AsMemory()[..bytesWritten], serverEndpoint, ct);
3233
}
3334

3435
public async Task Ping(User user, Peer[] peers, CancellationToken ct = default)
3536
{
36-
if (peers.Length is 0 || !user.PeerId.TryFormat(buffer, out var bytesWritten) ||
37+
if (peers.Length is 0 || !user.PeerId.TryWriteBytes(sendBuffer, true, out var bytesWritten) ||
3738
bytesWritten is 0)
3839
return;
3940

40-
var msgBytes = buffer.AsMemory()[..bytesWritten];
41+
var msgBytes = sendBuffer.AsMemory()[..bytesWritten];
4142
for (var i = 0; i < peers.Length; i++)
4243
{
4344
var peer = peers[i];
4445
if (peer.Connected && peer.PeerId != user.PeerId)
45-
await socket.SendToAsync(msgBytes, GetFallbackEndpoint(user, peer), ct);
46+
await socket.SendToAsync(msgBytes, peer.GetEndpointForUser(user), ct);
4647
}
4748
}
4849

4950
[AsyncMethodBuilder(typeof(PoolingAsyncValueTaskMethodBuilder))]
5051
async ValueTask Receive(CancellationToken stoppingToken)
5152
{
52-
var recBuffer = GC.AllocateArray<byte>(36, pinned: true);
53+
var idSize = Unsafe.SizeOf<Guid>();
54+
var recBuffer = GC.AllocateArray<byte>(idSize, pinned: true);
5355
while (!stoppingToken.IsCancellationRequested)
5456
{
5557
try
5658
{
57-
var receiveInfo = await socket.ReceiveAsync(recBuffer, stoppingToken)
59+
var receiveInfo = await socket
60+
.ReceiveAsync(recBuffer, stoppingToken)
5861
.ConfigureAwait(false);
5962

6063
if (receiveInfo.ReceivedBytes is 0) continue;
6164

62-
var msg = Encoding.UTF8.GetString(recBuffer);
63-
Console.WriteLine($"recv: {msg} from {receiveInfo.RemoteEndPoint}");
64-
65-
if (!Guid.TryParse(msg, out var peerToken))
65+
if (receiveInfo.ReceivedBytes != idSize)
66+
{
67+
var msg = Encoding.UTF8.GetString(recBuffer.AsSpan(0, receiveInfo.ReceivedBytes));
68+
Console.WriteLine($"recv ({receiveInfo.RemoteEndPoint}): '{msg}'");
6669
continue;
70+
}
6771

68-
knownClients.Add(peerToken);
72+
Guid peerToken = new(recBuffer.AsSpan(0, receiveInfo.ReceivedBytes), true);
73+
Console.WriteLine($"recv ({receiveInfo.RemoteEndPoint}): Ping from '{peerToken}'");
74+
if (peerToken != Guid.Empty) knownClients.Add(peerToken);
6975
}
7076
catch (OperationCanceledException)
7177
{
@@ -78,15 +84,6 @@ async ValueTask Receive(CancellationToken stoppingToken)
7884
}
7985
}
8086

81-
// Use local IP when over same network
82-
public static IPEndPoint GetFallbackEndpoint(User user, Peer peer)
83-
{
84-
if (Equals(peer.Endpoint.Address, user.IP) && peer.LocalEndpoint is not null)
85-
return peer.LocalEndpoint;
86-
87-
return peer.Endpoint;
88-
}
89-
9087
public bool IsKnown(Guid id) => knownClients.Contains(id);
9188

9289
public void Stop()

0 commit comments

Comments
 (0)