using System.Diagnostics.CodeAnalysis; using System.Net.WebSockets; using TanksServer.GameLogic; namespace TanksServer.Interactivity; internal sealed class PlayerServer( ILogger logger, ILogger connectionLogger, TankSpawnQueue tankSpawnQueue, MapEntityManager entityManager, BufferPool bufferPool ) : WebsocketServer(logger), ITickStep { private readonly ConcurrentDictionary _players = []; public Player GetOrAdd(string name) => _players.GetOrAdd(name, Add); public bool TryGet(string name, [MaybeNullWhen(false)] out Player foundPlayer) => _players.TryGetValue(name, out foundPlayer); public IEnumerable Players => _players.Values; private Player Add(string name) { var newPlayer = new Player { Name = name }; logger.LogInformation("player {} joined", newPlayer.Name); tankSpawnQueue.EnqueueForImmediateSpawn(newPlayer); return newPlayer; } public Task HandleClientAsync(WebSocket webSocket, Player player) { var connection = new PlayerInfoConnection(player, connectionLogger, webSocket, entityManager, bufferPool); return HandleClientAsync(connection); } public async ValueTask TickAsync(TimeSpan delta) => await Connections.Select(connection => connection.OnGameTickAsync()) .WhenAll(); }