servicepoint-tanks/TanksServer/Program.cs

170 lines
6.5 KiB
C#
Raw Normal View History

2024-04-06 16:38:26 +02:00
using System.IO;
2024-04-12 14:29:26 +02:00
using DisplayCommands;
using Microsoft.AspNetCore.Builder;
2024-04-06 20:32:54 +02:00
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
2024-04-06 16:38:26 +02:00
using Microsoft.Extensions.FileProviders;
2024-04-10 19:25:45 +02:00
using TanksServer.GameLogic;
using TanksServer.Graphics;
using TanksServer.Interactivity;
namespace TanksServer;
internal sealed record class NameId(string Name, Guid Id);
2024-04-10 22:03:36 +02:00
public static class Program
{
2024-04-10 22:03:36 +02:00
public static void Main(string[] args)
{
var app = Configure(args);
2024-04-06 16:38:26 +02:00
var clientScreenServer = app.Services.GetRequiredService<ClientScreenServer>();
2024-04-07 11:19:14 +02:00
var playerService = app.Services.GetRequiredService<PlayerServer>();
2024-04-07 01:27:11 +02:00
var controlsServer = app.Services.GetRequiredService<ControlsServer>();
2024-04-14 23:11:00 +02:00
var mapService = app.Services.GetRequiredService<MapService>();
2024-04-06 16:38:26 +02:00
var clientFileProvider = new PhysicalFileProvider(Path.Combine(app.Environment.ContentRootPath, "client"));
app.UseDefaultFiles(new DefaultFilesOptions { FileProvider = clientFileProvider });
app.UseStaticFiles(new StaticFileOptions { FileProvider = clientFileProvider });
app.MapPost("/player", (string name, Guid? id) =>
2024-04-13 18:35:36 +02:00
{
2024-04-14 11:42:54 +02:00
name = name.Trim().ToUpperInvariant();
if (name == string.Empty)
return Results.BadRequest("name cannot be blank");
if (name.Length > 12)
return Results.BadRequest("name too long");
2024-04-14 11:42:54 +02:00
var player = playerService.GetOrAdd(name, id ?? Guid.NewGuid());
2024-04-13 18:35:36 +02:00
return player != null
2024-04-14 11:42:54 +02:00
? Results.Ok(new NameId(player.Name, player.Id))
2024-04-13 18:35:36 +02:00
: Results.Unauthorized();
});
2024-04-14 23:11:00 +02:00
2024-04-13 18:35:36 +02:00
app.MapGet("/player", ([FromQuery] Guid id) =>
playerService.TryGet(id, out var foundPlayer)
? Results.Ok((object?)foundPlayer)
: Results.NotFound()
);
2024-04-07 13:02:49 +02:00
2024-04-13 18:35:36 +02:00
app.MapGet("/scores", () => playerService.GetAll());
app.Map("/screen", async (HttpContext context, [FromQuery] Guid? player) =>
{
if (!context.WebSockets.IsWebSocketRequest)
2024-04-13 18:35:36 +02:00
return Results.BadRequest();
2024-04-06 20:32:54 +02:00
using var ws = await context.WebSockets.AcceptWebSocketAsync();
await clientScreenServer.HandleClient(ws, player);
return Results.Empty;
});
2024-04-07 01:27:11 +02:00
app.Map("/controls", async (HttpContext context, [FromQuery] Guid playerId) =>
{
if (!context.WebSockets.IsWebSocketRequest)
2024-04-07 01:27:11 +02:00
return Results.BadRequest();
2024-04-07 01:27:11 +02:00
if (!playerService.TryGet(playerId, out var player))
return Results.NotFound();
2024-04-07 13:02:49 +02:00
using var ws = await context.WebSockets.AcceptWebSocketAsync();
2024-04-07 01:27:11 +02:00
await controlsServer.HandleClient(ws, player);
return Results.Empty;
});
app.MapGet("/map", () => mapService.MapNames);
2024-04-14 23:11:00 +02:00
2024-04-16 18:55:34 +02:00
app.MapPost("/map", ([FromQuery] string name) =>
2024-04-14 23:11:00 +02:00
{
2024-04-16 18:55:34 +02:00
if (string.IsNullOrWhiteSpace(name))
return Results.BadRequest("invalid map name");
if (!mapService.TrySwitchTo(name))
return Results.NotFound("map with name not found");
2024-04-14 23:11:00 +02:00
return Results.Ok();
});
2024-04-10 22:03:36 +02:00
app.Run();
}
private static WebApplication Configure(string[] args)
{
var builder = WebApplication.CreateSlimBuilder(args);
2024-04-11 20:48:21 +02:00
builder.Logging.AddSimpleConsole(options =>
{
options.SingleLine = true;
options.IncludeScopes = true;
options.TimestampFormat = "HH:mm:ss ";
});
builder.Services.AddCors(options => options
.AddDefaultPolicy(policy => policy
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin())
);
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, new AppSerializerContext());
});
2024-04-10 22:03:36 +02:00
builder.Services.AddHttpLogging(_ => { });
2024-04-07 20:16:22 +02:00
builder.Services.Configure<HostConfiguration>(builder.Configuration.GetSection("Host"));
var hostConfiguration = builder.Configuration.GetSection("Host").Get<HostConfiguration>();
if (hostConfiguration == null)
throw new InvalidOperationException("'Host' configuration missing");
builder.Services.AddSingleton<MapService>();
builder.Services.AddSingleton<BulletManager>();
2024-04-07 17:17:11 +02:00
builder.Services.AddSingleton<TankManager>();
2024-04-07 19:52:16 +02:00
builder.Services.AddSingleton<ControlsServer>();
builder.Services.AddSingleton<PlayerServer>();
2024-04-06 16:38:26 +02:00
builder.Services.AddSingleton<ClientScreenServer>();
2024-04-11 20:48:21 +02:00
builder.Services.AddSingleton<SpawnQueue>();
2024-04-07 19:52:16 +02:00
2024-04-07 20:29:09 +02:00
builder.Services.AddHostedService<GameTickWorker>();
2024-04-07 19:52:16 +02:00
builder.Services.AddHostedService(sp => sp.GetRequiredService<ControlsServer>());
2024-04-07 13:02:49 +02:00
builder.Services.AddHostedService(sp => sp.GetRequiredService<ClientScreenServer>());
2024-04-07 19:52:16 +02:00
builder.Services.AddSingleton<ITickStep, MoveBullets>();
builder.Services.AddSingleton<ITickStep, CollideBulletsWithTanks>();
builder.Services.AddSingleton<ITickStep, CollideBulletsWithMap>();
builder.Services.AddSingleton<ITickStep, RotateTanks>();
builder.Services.AddSingleton<ITickStep, MoveTanks>();
builder.Services.AddSingleton<ITickStep, ShootFromTanks>();
2024-04-09 22:38:56 +02:00
builder.Services.AddSingleton<ITickStep, SpawnNewTanks>();
builder.Services.AddSingleton<ITickStep, GeneratePixelsTickStep>();
builder.Services.AddSingleton<IDrawStep, DrawMapStep>();
builder.Services.AddSingleton<IDrawStep, DrawTanksStep>();
builder.Services.AddSingleton<IDrawStep, DrawBulletsStep>();
builder.Services.AddSingleton<IFrameConsumer, ClientScreenServer>(sp =>
sp.GetRequiredService<ClientScreenServer>());
2024-04-11 20:48:21 +02:00
builder.Services.Configure<TanksConfiguration>(
builder.Configuration.GetSection("Tanks"));
builder.Services.Configure<PlayersConfiguration>(
builder.Configuration.GetSection("Players"));
builder.Services.Configure<GameRulesConfiguration>(builder.Configuration.GetSection("GameRules"));
if (hostConfiguration.EnableServicePointDisplay)
{
builder.Services.AddSingleton<IFrameConsumer, SendToServicePointDisplay>();
builder.Services.AddDisplay(builder.Configuration.GetSection("ServicePointDisplay"));
}
2024-04-07 20:16:22 +02:00
2024-04-10 22:03:36 +02:00
var app = builder.Build();
app.UseCors();
app.UseWebSockets();
app.UseHttpLogging();
return app;
}
2024-04-13 18:35:36 +02:00
}