react frontend app (display screen, join)

This commit is contained in:
Vinzenz Schroeter 2024-04-07 00:33:54 +02:00
parent 1a20fa1fb6
commit abdfdf2ec0
23 changed files with 3917 additions and 5 deletions

View file

@ -0,0 +1,6 @@
namespace TanksServer;
public class ControlsServer
{
}

View file

@ -21,7 +21,7 @@ public class GameTickService(IEnumerable<ITickStep> steps) : IHostedService
{
foreach (var step in _steps)
await step.TickAsync();
await Task.Delay(1000 / 250);
await Task.Delay(1000);
}
}

View file

@ -0,0 +1,18 @@
using System.Collections.Concurrent;
using Microsoft.Extensions.Logging;
namespace TanksServer;
internal sealed class PlayerService(ILogger<PlayerService> logger)
{
private readonly ConcurrentDictionary<string, Player> _players = new();
public Player GetOrAdd(string name) => _players.GetOrAdd(name, _ => new Player(name));
}
internal class Player(string name)
{
public string Name => name;
public Guid Id => Guid.NewGuid();
}

View file

@ -1,6 +1,8 @@
using System.IO;
using System.Text.Json.Serialization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
@ -12,13 +14,18 @@ internal static class Program
{
var app = Configure(args);
app.UseCors();
app.UseWebSockets();
var clientScreenServer = app.Services.GetRequiredService<ClientScreenServer>();
var playerService = app.Services.GetRequiredService<PlayerService>();
var clientFileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "client"));
app.UseDefaultFiles(new DefaultFilesOptions { FileProvider = clientFileProvider });
app.UseStaticFiles(new StaticFileOptions { FileProvider = clientFileProvider });
app.UseWebSockets();
app.MapGet("/player", playerService.GetOrAdd);
app.Map("/screen", async context =>
{
if (!context.WebSockets.IsWebSocketRequest)
@ -31,6 +38,19 @@ internal static class Program
await clientScreenServer.HandleClient(ws);
});
app.Map("/controls", async (HttpContext context, [FromQuery] string playerId) =>
{
if (!context.WebSockets.IsWebSocketRequest)
{
context.Response.StatusCode = StatusCodes.Status400BadRequest;
return;
}
using var ws = await context.WebSockets.AcceptWebSocketAsync();
await clientScreenServer.HandleClient(ws);
});
await app.RunAsync();
}
@ -38,18 +58,35 @@ internal static class Program
{
var builder = WebApplication.CreateSlimBuilder(args);
builder.Services.AddCors(options => options
.AddDefaultPolicy(policy => policy
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin())
);
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, new AppSerializerContext());
});
builder.Services.AddSingleton<ServicePointDisplay>();
builder.Services.AddSingleton<MapService>();
builder.Services.AddSingleton<MapDrawer>();
builder.Services.AddSingleton<ITickStep, MapDrawer>(sp => sp.GetRequiredService<MapDrawer>());
builder.Services.AddSingleton<ClientScreenServer>();
builder.Services.AddHostedService<ClientScreenServer>(sp => sp.GetRequiredService<ClientScreenServer>());
builder.Services.AddSingleton<ITickStep, ClientScreenServer>(sp => sp.GetRequiredService<ClientScreenServer>());
builder.Services.AddHostedService<GameTickService>();
builder.Services.AddSingleton<PlayerService>();
return builder.Build();
}
}
[JsonSerializable(typeof(Player))]
internal partial class AppSerializerContext: JsonSerializerContext;