servicepoint-tanks/tanks-backend/TanksServer/Endpoints.cs

163 lines
6.1 KiB
C#
Raw Permalink Normal View History

using System.Diagnostics.CodeAnalysis;
2024-05-07 20:41:06 +02:00
using System.IO;
using System.Text;
using System.Text.Json;
2024-04-17 19:34:19 +02:00
using Microsoft.AspNetCore.Builder;
2024-05-07 20:41:06 +02:00
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
2024-04-17 19:34:19 +02:00
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
2024-04-17 19:34:19 +02:00
using Microsoft.AspNetCore.Mvc;
2024-05-07 20:41:06 +02:00
using Microsoft.Extensions.Diagnostics.HealthChecks;
2024-04-17 19:34:19 +02:00
using TanksServer.GameLogic;
using TanksServer.Interactivity;
namespace TanksServer;
internal sealed class Endpoints(
ClientScreenServer clientScreenServer,
PlayerServer playerService,
ControlsServer controlsServer,
MapService mapService,
2024-05-08 00:30:11 +02:00
ChangeToRequestedMap changeToRequestedMap,
2024-05-13 01:23:34 +02:00
Connection displayConnection
)
2024-04-17 19:34:19 +02:00
{
[RequiresUnreferencedCode("Calls Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapPost(String, Delegate)")]
[RequiresDynamicCode("Calls Microsoft.AspNetCore.Builder.EndpointRouteBuilderExtensions.MapPost(String, Delegate)")]
public void Map(WebApplication app)
2024-04-17 19:34:19 +02:00
{
app.MapPost("/player", PostPlayer);
app.MapGet("/player", GetPlayerAsync);
2024-05-03 14:45:41 +02:00
app.MapGet("/scores", () => playerService.Players);
app.Map("/screen", ConnectScreenAsync);
app.Map("/controls", ConnectControlsAsync);
app.MapGet("/map", () => mapService.MapNames);
app.MapPost("/map", PostMap);
app.MapPost("/resetDisplay", () => displayConnection.Send(Command.HardReset()));
2024-05-05 13:51:28 +02:00
app.MapGet("/map/{name}", GetMapByName);
2024-05-07 20:41:06 +02:00
app.MapHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = WriteJsonHealthCheckResponse
});
}
2024-04-22 19:03:07 +02:00
private Results<BadRequest<string>, NotFound<string>, Ok> PostMap([FromQuery] string name)
{
if (string.IsNullOrWhiteSpace(name))
return TypedResults.BadRequest("invalid map name");
2024-05-05 13:51:28 +02:00
name = name.Trim().ToUpperInvariant();
if (!mapService.TryGetPrototype(name, out var map))
return TypedResults.NotFound("map with name not found");
2024-05-05 13:51:28 +02:00
changeToRequestedMap.Request(map);
return TypedResults.Ok();
}
2024-04-22 19:03:07 +02:00
private async Task<Results<BadRequest, NotFound, EmptyHttpResult>> ConnectControlsAsync(HttpContext context,
[FromQuery] string playerName)
{
if (!context.WebSockets.IsWebSocketRequest)
return TypedResults.BadRequest();
2024-04-17 19:34:19 +02:00
if (!playerService.TryGet(playerName, out var player))
return TypedResults.NotFound();
2024-04-17 19:34:19 +02:00
using var ws = await context.WebSockets.AcceptWebSocketAsync();
await controlsServer.HandleClientAsync(ws, player);
return TypedResults.Empty;
}
2024-04-17 19:34:19 +02:00
private async Task<Results<BadRequest, EmptyHttpResult, NotFound>> ConnectScreenAsync(HttpContext context,
[FromQuery] string? playerName)
{
if (!context.WebSockets.IsWebSocketRequest)
return TypedResults.BadRequest();
2024-04-17 19:34:19 +02:00
Player? player = null;
if (!string.IsNullOrWhiteSpace(playerName) && !playerService.TryGet(playerName, out player))
return TypedResults.NotFound();
using var ws = await context.WebSockets.AcceptWebSocketAsync();
await clientScreenServer.HandleClientAsync(ws, player);
return TypedResults.Empty;
}
2024-04-17 19:34:19 +02:00
private async Task<Results<NotFound, Ok<Player>, EmptyHttpResult>> GetPlayerAsync(HttpContext context,
[FromQuery] string name)
{
if (!playerService.TryGet(name, out var foundPlayer))
return TypedResults.NotFound();
2024-04-17 19:34:19 +02:00
if (!context.WebSockets.IsWebSocketRequest)
return TypedResults.Ok(foundPlayer);
2024-04-17 19:34:19 +02:00
using var ws = await context.WebSockets.AcceptWebSocketAsync();
await playerService.HandleClientAsync(ws, foundPlayer);
return TypedResults.Empty;
}
2024-04-17 19:34:19 +02:00
private Results<BadRequest<string>, Ok<string>, UnauthorizedHttpResult> PostPlayer([FromQuery] string name)
{
name = name.Trim().ToUpperInvariant();
if (name == string.Empty) return TypedResults.BadRequest("name cannot be blank");
if (name.Length > 12) return TypedResults.BadRequest("name too long");
var player = playerService.GetOrAdd(name);
2024-04-28 15:34:32 +02:00
return TypedResults.Ok(player.Name);
2024-04-17 19:34:19 +02:00
}
2024-05-05 13:51:28 +02:00
private Results<Ok<MapInfo>, NotFound, BadRequest<string>> GetMapByName(string name)
{
name = name.Trim().ToUpperInvariant();
if (string.IsNullOrEmpty(name))
return TypedResults.BadRequest("map name cannot be empty");
if (!mapService.TryGetPrototype(name, out var prototype))
return TypedResults.NotFound();
if (!mapService.TryGetPreview(name, out var preview))
return TypedResults.NotFound();
var mapInfo = new MapInfo(prototype.Name, prototype.GetType().Name, preview.CopyRaw());
2024-05-05 13:51:28 +02:00
return TypedResults.Ok(mapInfo);
}
2024-05-07 20:41:06 +02:00
private static Task WriteJsonHealthCheckResponse(HttpContext context, HealthReport healthReport)
{
context.Response.ContentType = "application/json; charset=utf-8";
var options = new JsonWriterOptions { Indented = true };
using var memoryStream = new MemoryStream();
using (var jsonWriter = new Utf8JsonWriter(memoryStream, options))
{
jsonWriter.WriteStartObject();
jsonWriter.WriteString("status", healthReport.Status.ToString());
jsonWriter.WriteStartObject("results");
foreach (var healthReportEntry in healthReport.Entries)
{
jsonWriter.WriteStartObject(healthReportEntry.Key);
jsonWriter.WriteString("status",
healthReportEntry.Value.Status.ToString());
jsonWriter.WriteString("description",
healthReportEntry.Value.Description);
jsonWriter.WriteStartObject("data");
foreach (var item in healthReportEntry.Value.Data)
jsonWriter.WriteString(item.Key, item.Value.ToString());
jsonWriter.WriteEndObject();
jsonWriter.WriteEndObject();
}
jsonWriter.WriteEndObject();
jsonWriter.WriteEndObject();
}
return context.Response.WriteAsync(
Encoding.UTF8.GetString(memoryStream.ToArray()));
}
2024-04-17 19:34:19 +02:00
}