servicepoint-tanks/tanks-backend/TanksServer/Interactivity/PlayerInfoConnection.cs

67 lines
2 KiB
C#
Raw Normal View History

2024-04-22 19:03:07 +02:00
using System.Net.WebSockets;
using System.Text.Json;
2024-04-22 19:44:28 +02:00
using TanksServer.GameLogic;
2024-04-22 19:03:07 +02:00
namespace TanksServer.Interactivity;
internal sealed class PlayerInfoConnection(
Player player,
ILogger logger,
2024-04-22 19:44:28 +02:00
WebSocket rawSocket,
MapEntityManager entityManager
2024-04-28 15:34:32 +02:00
) : WebsocketServerConnection(logger, new ByteChannelWebSocket(rawSocket, logger, 0))
2024-04-22 19:03:07 +02:00
{
private int _wantsInfoOnTick = 1;
private byte[]? _lastMessage = null;
private byte[]? _nextMessage = null;
2024-04-22 19:03:07 +02:00
protected override ValueTask HandleMessageAsync(Memory<byte> buffer)
2024-04-22 19:03:07 +02:00
{
var next = Interlocked.Exchange(ref _nextMessage, null);
if (next != null)
return SendAndDisposeAsync(next);
2024-04-22 19:03:07 +02:00
_wantsInfoOnTick = 1;
return ValueTask.CompletedTask;
2024-04-22 19:03:07 +02:00
}
public async ValueTask OnGameTickAsync()
2024-04-22 19:03:07 +02:00
{
await Task.Yield();
2024-04-22 19:03:07 +02:00
var response = GetMessageToSend();
var wantsNow = Interlocked.Exchange(ref _wantsInfoOnTick, 0) != 0;
2024-04-22 19:03:07 +02:00
if (wantsNow)
{
await SendAndDisposeAsync(response);
return;
}
2024-04-22 19:03:07 +02:00
Interlocked.Exchange(ref _nextMessage, response);
}
private byte[] GetMessageToSend()
2024-04-22 19:03:07 +02:00
{
2024-04-22 19:44:28 +02:00
var tank = entityManager.GetCurrentTankOfPlayer(player);
2024-04-29 17:17:44 +02:00
TankInfo? tankInfo = null;
if (tank != null)
{
var magazine = tank.ReloadingUntil > DateTime.Now ? "[ RELOADING ]" : tank.Magazine.ToDisplayString();
tankInfo = new TankInfo(tank.Orientation, magazine, tank.Position.ToPixelPosition(), tank.Moving);
}
var info = new PlayerInfo(player.Name, player.Scores, player.Controls.ToDisplayString(), tankInfo);
2024-04-22 19:03:07 +02:00
// TODO: switch to async version with pre-allocated buffer / IMemoryOwner
return JsonSerializer.SerializeToUtf8Bytes(info, AppSerializerContext.Default.PlayerInfo);
}
2024-04-22 19:03:07 +02:00
private async ValueTask SendAndDisposeAsync(byte[] data)
{
await Socket.SendTextAsync(data);
Interlocked.Exchange(ref _lastMessage, data);
2024-04-22 19:03:07 +02:00
}
}