From c1b67c721e56c6f74bbc65dbbfd573ebdafab2a1 Mon Sep 17 00:00:00 2001 From: Tomasi - Developing Date: Tue, 7 Jan 2025 09:44:06 +0100 Subject: [PATCH] player mvp calculation --- Api/Controllers/v1/PlayersController.cs | 23 +++++++++ .../Player/PlayerMvpDto.cs | 11 +++++ Application/Interfaces/IPlayerRepository.cs | 2 + Application/Repositories/PlayerRepository.cs | 47 +++++++++++++++++++ 4 files changed, 83 insertions(+) create mode 100644 Application/DataTransferObjects/Player/PlayerMvpDto.cs diff --git a/Api/Controllers/v1/PlayersController.cs b/Api/Controllers/v1/PlayersController.cs index 6487a37..004605b 100644 --- a/Api/Controllers/v1/PlayersController.cs +++ b/Api/Controllers/v1/PlayersController.cs @@ -54,6 +54,29 @@ namespace Api.Controllers.v1 } } + [AllowAnonymous] + [HttpGet("[action]/{allianceId:guid}")] + public async Task>> GetAllianceMvpPlayers(Guid allianceId, + CancellationToken cancellationToken) + { + try + { + var alliancePlayersResult = + await playerRepository.GetAlliancePlayersMvp(allianceId, cancellationToken); + + if (alliancePlayersResult.IsFailure) return BadRequest(alliancePlayersResult.Error); + + return alliancePlayersResult.Value.Count > 0 + ? Ok(alliancePlayersResult.Value) + : NoContent(); + } + catch (Exception e) + { + logger.LogError(e, e.Message); + return StatusCode(StatusCodes.Status500InternalServerError); + } + } + [HttpPost] public async Task> CreatePlayer(CreatePlayerDto createPlayerDto, CancellationToken cancellationToken) diff --git a/Application/DataTransferObjects/Player/PlayerMvpDto.cs b/Application/DataTransferObjects/Player/PlayerMvpDto.cs new file mode 100644 index 0000000..0125f7d --- /dev/null +++ b/Application/DataTransferObjects/Player/PlayerMvpDto.cs @@ -0,0 +1,11 @@ +namespace Application.DataTransferObjects.Player; + +public class PlayerMvpDto +{ + public required string PlayerName { get; set; } + public required string Rank { get; set; } + public long TotalVsDuelPoints { get; set; } + public int MarshalGuardParticipationCount { get; set; } + public int DesertStormParticipationCount { get; set; } + public decimal MvpPoints { get; set; } +} \ No newline at end of file diff --git a/Application/Interfaces/IPlayerRepository.cs b/Application/Interfaces/IPlayerRepository.cs index 6dda445..11ff7d9 100644 --- a/Application/Interfaces/IPlayerRepository.cs +++ b/Application/Interfaces/IPlayerRepository.cs @@ -9,6 +9,8 @@ public interface IPlayerRepository Task>> GetAlliancePlayersAsync(Guid allianceId, CancellationToken cancellationToken); + Task>> GetAlliancePlayersMvp(Guid allianceId, CancellationToken cancellationToken); + Task> CreatePlayerAsync(CreatePlayerDto createPlayerDto, string createdBy, CancellationToken cancellationToken); Task> UpdatePlayerAsync(UpdatePlayerDto updatePlayerDto, string modifiedBy, CancellationToken cancellationToken); diff --git a/Application/Repositories/PlayerRepository.cs b/Application/Repositories/PlayerRepository.cs index c6dff42..86bcd16 100644 --- a/Application/Repositories/PlayerRepository.cs +++ b/Application/Repositories/PlayerRepository.cs @@ -36,6 +36,53 @@ public class PlayerRepository(ApplicationContext context, IMapper mapper, ILogge return Result.Success(alliancePlayers); } + public async Task>> GetAlliancePlayersMvp(Guid allianceId, CancellationToken cancellationToken) + { + var currentDate = DateTime.Now; + var threeWeeksAgo = currentDate.AddDays(-21); + + var playerMvps = await context.Players + .Where(p => p.AllianceId == allianceId && p.Rank.Name != "R4" && p.Rank.Name != "R5") + .Select(p => new + { + p.Id, + p.PlayerName, + Rank = p.Rank.Name, + + VsDuels = context.VsDuelParticipants + .Where(vp => vp.PlayerId == p.Id && vp.VsDuel.EventDate <= currentDate && !vp.VsDuel.IsInProgress) + .OrderByDescending(vp => vp.VsDuel.EventDate) + .Take(3) + .Sum(vp => vp.WeeklyPoints), + + MarshalGuardParticipationCount = context.MarshalGuardParticipants + .Count(mpg => mpg.PlayerId == p.Id && mpg.Participated && mpg.MarshalGuard.EventDate > threeWeeksAgo), + + DessertStormParticipationCount = context.DesertStormParticipants + .Count(dsp => dsp.PlayerId == p.Id && dsp.Participated && dsp.DesertStorm.EventDate > threeWeeksAgo) + }) + .Select(p => new PlayerMvpDto() + { + PlayerName = p.PlayerName, + Rank = p.Rank, + TotalVsDuelPoints = p.VsDuels, + MarshalGuardParticipationCount = p.MarshalGuardParticipationCount, + DesertStormParticipationCount = p.DessertStormParticipationCount, + MvpPoints = Math.Round( + (decimal)((p.VsDuels / 1000000.0 * 0.7) + + (p.MarshalGuardParticipationCount * 15) + + (p.DessertStormParticipationCount * 10)) + ) + }) + .OrderByDescending(p => p.MvpPoints) + .ThenByDescending(p => p.TotalVsDuelPoints) + .ThenByDescending(p => p.MarshalGuardParticipationCount) + .ThenBy(p => p.PlayerName) + .ToListAsync(cancellationToken); + + return playerMvps; + } + public async Task> CreatePlayerAsync(CreatePlayerDto createPlayerDto, string createdBy, CancellationToken cancellationToken) { var newPlayer = mapper.Map(createPlayerDto);