more commands, change display communication to new lib
This commit is contained in:
parent
38463ac109
commit
7213318838
31 changed files with 240 additions and 417 deletions
|
@ -7,15 +7,15 @@ namespace TanksServer.Interactivity;
|
|||
/// <summary>
|
||||
/// Hacky class for easier semantics
|
||||
/// </summary>
|
||||
internal sealed class ByteChannelWebSocket : Channel<byte[]>
|
||||
internal sealed class ByteChannelWebSocket : Channel<Memory<byte>>
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly WebSocket _socket;
|
||||
private readonly Task _backgroundDone;
|
||||
private readonly byte[] _buffer;
|
||||
|
||||
private readonly Channel<byte[]> _outgoing = Channel.CreateUnbounded<byte[]>();
|
||||
private readonly Channel<byte[]> _incoming = Channel.CreateUnbounded<byte[]>();
|
||||
private readonly Channel<Memory<byte>> _outgoing = Channel.CreateUnbounded<Memory<byte>>();
|
||||
private readonly Channel<Memory<byte>> _incoming = Channel.CreateUnbounded<Memory<byte>>();
|
||||
|
||||
public ByteChannelWebSocket(WebSocket socket, ILogger logger, int messageSize)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
using System.Diagnostics;
|
||||
using System.Net.WebSockets;
|
||||
using System.Threading.Channels;
|
||||
using DisplayCommands;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using TanksServer.ServicePointDisplay;
|
||||
|
||||
namespace TanksServer.Interactivity;
|
||||
|
||||
|
@ -44,10 +44,10 @@ internal sealed class ClientScreenServer(
|
|||
public Task StoppedAsync(CancellationToken cancellationToken) => Task.CompletedTask;
|
||||
|
||||
private void Remove(ClientScreenServerConnection connection) => _connections.TryRemove(connection, out _);
|
||||
|
||||
|
||||
public IEnumerable<ClientScreenServerConnection> GetConnections() => _connections.Keys;
|
||||
|
||||
internal sealed class ClientScreenServerConnection: IDisposable
|
||||
internal sealed class ClientScreenServerConnection : IDisposable
|
||||
{
|
||||
private readonly ByteChannelWebSocket _channel;
|
||||
private readonly SemaphoreSlim _wantedFrames = new(1);
|
||||
|
@ -64,7 +64,7 @@ internal sealed class ClientScreenServer(
|
|||
Done = ReceiveAsync();
|
||||
}
|
||||
|
||||
public async Task SendAsync(PixelDisplayBufferView buf)
|
||||
public async Task SendAsync(PixelGrid buf)
|
||||
{
|
||||
if (!await _wantedFrames.WaitAsync(TimeSpan.Zero))
|
||||
{
|
||||
|
@ -85,9 +85,9 @@ internal sealed class ClientScreenServer(
|
|||
|
||||
private async Task ReceiveAsync()
|
||||
{
|
||||
await foreach (var _ in _channel.Reader.ReadAllAsync())
|
||||
await foreach (var _ in _channel.Reader.ReadAllAsync())
|
||||
_wantedFrames.Release();
|
||||
|
||||
|
||||
_logger.LogTrace("done receiving");
|
||||
_server.Remove(this);
|
||||
}
|
||||
|
@ -106,4 +106,4 @@ internal sealed class ClientScreenServer(
|
|||
Done.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -71,8 +71,8 @@ internal sealed class ControlsServer(ILogger<ControlsServer> logger, ILoggerFact
|
|||
{
|
||||
await foreach (var buffer in _binaryWebSocket.Reader.ReadAllAsync())
|
||||
{
|
||||
var type = (MessageType)buffer[0];
|
||||
var control = (InputType)buffer[1];
|
||||
var type = (MessageType)buffer.Span[0];
|
||||
var control = (InputType)buffer.Span[1];
|
||||
|
||||
_logger.LogTrace("player input {} {} {}", _player.Id, type, control);
|
||||
|
||||
|
|
87
TanksServer/Interactivity/SendToServicePointDisplay.cs
Normal file
87
TanksServer/Interactivity/SendToServicePointDisplay.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
using System.Diagnostics;
|
||||
using System.Net.Sockets;
|
||||
using DisplayCommands;
|
||||
using TanksServer.GameLogic;
|
||||
using TanksServer.Graphics;
|
||||
|
||||
namespace TanksServer.Interactivity;
|
||||
|
||||
internal sealed class SendToServicePointDisplay : ITickStep
|
||||
{
|
||||
private readonly LastFinishedFrameProvider _lastFinishedFrameProvider;
|
||||
private readonly Cp437Grid _scoresBuffer;
|
||||
private readonly PlayerServer _players;
|
||||
private readonly ILogger<SendToServicePointDisplay> _logger;
|
||||
private readonly IDisplayConnection _displayConnection;
|
||||
|
||||
private DateTime _nextFailLog = DateTime.Now;
|
||||
|
||||
private const int ScoresWidth = 12;
|
||||
private const int ScoresHeight = 20;
|
||||
private const int ScoresPlayerRows = ScoresHeight - 5;
|
||||
|
||||
public SendToServicePointDisplay(
|
||||
LastFinishedFrameProvider lastFinishedFrameProvider,
|
||||
PlayerServer players,
|
||||
ILogger<SendToServicePointDisplay> logger,
|
||||
IDisplayConnection displayConnection
|
||||
)
|
||||
{
|
||||
_lastFinishedFrameProvider = lastFinishedFrameProvider;
|
||||
_players = players;
|
||||
_logger = logger;
|
||||
_displayConnection = displayConnection;
|
||||
|
||||
var localIp = _displayConnection.GetLocalIPv4().Split('.');
|
||||
Debug.Assert(localIp.Length == 4);
|
||||
_scoresBuffer = new Cp437Grid(12, 20)
|
||||
{
|
||||
[00] = "== TANKS! ==",
|
||||
[01] = "-- scores --",
|
||||
[17] = "-- join --",
|
||||
[18] = string.Join('.', localIp[..2]),
|
||||
[19] = string.Join('.', localIp[2..])
|
||||
};
|
||||
}
|
||||
|
||||
public async Task TickAsync()
|
||||
{
|
||||
RefreshScores();
|
||||
try
|
||||
{
|
||||
await _displayConnection.SendCp437DataAsync(MapService.TilesPerRow, 0, _scoresBuffer);
|
||||
await _displayConnection.SendBitmapLinearWindowAsync(0, 0, _lastFinishedFrameProvider.LastFrame);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
if (DateTime.Now > _nextFailLog)
|
||||
{
|
||||
_logger.LogWarning("could not send data to service point display: {}", ex.Message);
|
||||
_nextFailLog = DateTime.Now + TimeSpan.FromSeconds(5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshScores()
|
||||
{
|
||||
var playersToDisplay = _players.GetAll()
|
||||
.OrderByDescending(p => p.Kills)
|
||||
.Take(ScoresPlayerRows);
|
||||
|
||||
ushort row = 2;
|
||||
foreach (var p in playersToDisplay)
|
||||
{
|
||||
var score = p.Kills.ToString();
|
||||
var nameLength = Math.Min(p.Name.Length, ScoresWidth - score.Length - 1);
|
||||
|
||||
var name = p.Name[..nameLength];
|
||||
var spaces = new string(' ', ScoresWidth - score.Length - nameLength);
|
||||
|
||||
_scoresBuffer[row] = name + spaces + score;
|
||||
row++;
|
||||
}
|
||||
|
||||
for (; row < 17; row++)
|
||||
_scoresBuffer[row] = string.Empty;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue