Files
Shogi/Shogi.Api/Application/ShogiApplication.cs
2024-10-31 18:56:51 -05:00

141 lines
3.3 KiB
C#

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Shogi.Api.Controllers;
using Shogi.Api.Extensions;
using Shogi.Api.Identity;
using Shogi.Api.Repositories;
using Shogi.Api.Repositories.Dto;
using Shogi.Contracts.Api;
using Shogi.Domain.Aggregates;
using System.Data.SqlClient;
namespace Shogi.Api.Application;
public class ShogiApplication(
QueryRepository queryRepository,
SessionRepository sessionRepository,
UserManager<ShogiUser> userManager,
GameHubContext gameHubContext)
{
public async Task<IActionResult> CreateSession(string playerId)
{
var session = new Session(Guid.NewGuid(), playerId);
try
{
await sessionRepository.CreateSession(session);
return new CreatedAtActionResult(
nameof(SessionsController.GetSession),
null,
new { sessionId = session.Id.ToString() },
session.Id.ToString());
}
catch (SqlException)
{
return new ConflictResult();
}
}
public async Task<IEnumerable<SessionDto>> ReadAllSessionMetadatas(string playerId)
{
return await queryRepository.ReadSessionsMetadata(playerId);
}
public async Task<Session?> ReadSession(string id)
{
var (sessionDto, moveDtos) = await sessionRepository.ReadSessionAndMoves(id);
if (!sessionDto.HasValue)
{
return null;
}
var session = new Session(Guid.Parse(sessionDto.Value.Id), sessionDto.Value.Player1Id);
if (!string.IsNullOrWhiteSpace(sessionDto.Value.Player2Id)) session.AddPlayer2(sessionDto.Value.Player2Id);
foreach (var move in moveDtos)
{
if (move.PieceFromHand.HasValue)
{
session.Board.Move(move.PieceFromHand.Value, move.To);
}
else if (move.From != null && move.IsPromotion.HasValue)
{
session.Board.Move(move.From, move.To, move.IsPromotion.Value);
}
else
{
throw new InvalidOperationException($"Corrupt data during {nameof(ReadSession)}");
}
}
return session;
}
public async Task<IActionResult> MovePiece(string playerId, string sessionId, MovePieceCommand command)
{
var session = await this.ReadSession(sessionId);
if (session == null)
{
return new NotFoundResult();
}
if (!session.IsSeated(playerId))
{
return new ForbidResult();
}
try
{
if (command.PieceFromHand.HasValue)
{
session.Board.Move(command.PieceFromHand.Value.ToDomain(), command.To);
}
else
{
var isPromotion = command.IsPromotion ?? false;
session.Board.Move(command.From!, command.To, isPromotion);
}
}
catch (InvalidOperationException e)
{
return new ConflictObjectResult(e.Message);
}
await sessionRepository.CreateMove(sessionId, command);
await gameHubContext.Emit_PieceMoved(sessionId);
return new NoContentResult();
}
public async Task<IActionResult> JoinSession(string sessionId, string player2Id)
{
var session = await this.ReadSession(sessionId);
if (session == null) return new NotFoundResult();
if (string.IsNullOrEmpty(session.Player2))
{
session.AddPlayer2(player2Id);
await sessionRepository.SetPlayer2(sessionId, player2Id);
await gameHubContext.Emit_SessionJoined(sessionId);
return new OkResult();
}
return new ConflictObjectResult("This game already has two players.");
}
public string GetUsername(string? userId)
{
if (string.IsNullOrEmpty(userId))
{
return string.Empty;
}
return userManager.Users.FirstOrDefault(u => u.Id == userId)?.UserName!;
}
}