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

81 lines
2.2 KiB
C#
Raw Normal View History

using System.Buffers;
using System.IO;
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;
2024-05-04 14:25:37 +02:00
internal sealed class PlayerInfoConnection
: DroppablePackageRequestConnection<IMemoryOwner<byte>>
2024-04-22 19:03:07 +02:00
{
2024-05-02 21:27:56 +02:00
private readonly Player _player;
private readonly MapEntityManager _entityManager;
2024-05-03 14:45:41 +02:00
private readonly BufferPool _bufferPool;
private readonly MemoryStream _tempStream = new();
2024-05-03 14:45:41 +02:00
private IMemoryOwner<byte>? _lastMessage = null;
2024-05-03 14:45:41 +02:00
public PlayerInfoConnection(
Player player,
2024-05-02 21:27:56 +02:00
ILogger logger,
WebSocket rawSocket,
2024-05-03 14:45:41 +02:00
MapEntityManager entityManager,
BufferPool bufferPool
) : base(logger, new ByteChannelWebSocket(rawSocket, logger, 0))
2024-05-02 21:27:56 +02:00
{
_player = player;
_entityManager = entityManager;
2024-05-03 14:45:41 +02:00
_bufferPool = bufferPool;
2024-05-02 21:27:56 +02:00
_player.IncrementConnectionCount();
}
2024-04-22 19:03:07 +02:00
2024-05-03 14:45:41 +02:00
public async Task OnGameTickAsync()
2024-04-22 19:03:07 +02:00
{
await Task.Yield();
2024-04-22 19:03:07 +02:00
var response = await GenerateMessageAsync();
2024-05-04 14:25:37 +02:00
if (response != null)
SetNextPackage(response);
}
2024-05-04 14:25:37 +02:00
public override void Dispose()
2024-05-02 21:27:56 +02:00
{
2024-05-04 14:25:37 +02:00
base.Dispose();
2024-05-02 21:27:56 +02:00
_player.DecrementConnectionCount();
}
2024-05-04 14:25:37 +02:00
private async ValueTask<IMemoryOwner<byte>?> GenerateMessageAsync()
2024-04-22 19:03:07 +02:00
{
2024-05-02 21:27:56 +02:00
var tank = _entityManager.GetCurrentTankOfPlayer(_player);
var info = new PlayerInfo(_player, _player.Controls.ToDisplayString(), tank);
2024-04-22 19:03:07 +02:00
_tempStream.Position = 0;
await JsonSerializer.SerializeAsync(_tempStream, info, AppSerializerContext.Default.PlayerInfo);
var messageLength = (int)_tempStream.Position;
2024-05-03 14:45:41 +02:00
var owner = _bufferPool.Rent(messageLength);
2024-05-04 14:25:37 +02:00
_tempStream.Position = 0;
2024-05-03 14:45:41 +02:00
await _tempStream.ReadExactlyAsync(owner.Memory);
2024-05-04 14:25:37 +02:00
if (_lastMessage == null || !owner.Memory.Span.SequenceEqual(_lastMessage.Memory.Span))
return owner;
owner.Dispose();
return null;
}
2024-04-22 19:03:07 +02:00
2024-05-04 14:25:37 +02:00
protected override async ValueTask SendPackageAsync(IMemoryOwner<byte> data)
{
await Socket.SendTextAsync(data.Memory);
2024-05-03 14:45:41 +02:00
Interlocked.Exchange(ref _lastMessage, data)?.Dispose();
2024-04-22 19:03:07 +02:00
}
}
internal record struct PlayerInfo(
Player Player,
string Controls,
Tank? Tank
);