using DatabaseModels.DataTransferObjets; using DatabaseModels.InitialObjects; using Microsoft.EntityFrameworkCore; using Server.Data; namespace Server.Services; public class ScoreboardService { private readonly ServerDbContext _dbContext; private readonly IHttpContextAccessor _httpContextAccessor; public ScoreboardService(ServerDbContext dbContext, IHttpContextAccessor httpContextAccessor) { _dbContext = dbContext; _httpContextAccessor = httpContextAccessor; } // GET public async Task<(bool success, string content, ScoreboardRecordDto[])> GetScoreboard() { var sbRecords = await _dbContext.Scoreboard .Include(sbr => sbr.User) .ToListAsync(); sbRecords.Sort((a, b) => b.Score - a.Score); sbRecords = sbRecords.DistinctBy(sbr => sbr.User.Id).ToList(); var dto = new List(sbRecords.Count); foreach (var sbr in sbRecords) { dto.Add(sbr.ToDto()); } return (true, "", dto.ToArray()); } public async Task<(bool success, string content, ScoreboardRecordDto? sbRecordDto)> GetUserHighScore(string username) { var userScoreboardRecords = await _dbContext.Scoreboard .Include(sbr => sbr.User) .Where(sbr => sbr.User.Username == username) .ToListAsync(); if (userScoreboardRecords.Count == 0) { return (false, "Username invalid or scoreboard records are absent", null); } return (true, "", userScoreboardRecords.MaxBy(sbr => sbr.Score)?.ToDto()); } // POST public async Task<(bool success, string content)> AddUserHighScore(ScoreboardRecordDto sbRecordDto) { if (sbRecordDto.User.Id != Int32.Parse(_httpContextAccessor.HttpContext!.User.Claims.First(c => c.Type == "id").Value)) { return (false, "User id is not yours"); } var sbHighScoreRecordDto = (await GetUserHighScore(sbRecordDto.User.Username)).sbRecordDto; if (sbHighScoreRecordDto != null && sbRecordDto.Score <= sbHighScoreRecordDto.Score) { return (false, $"You can not post score lower than {sbHighScoreRecordDto.Score}"); } var sbRecord = new ScoreboardRecord { Score = sbRecordDto.Score, PostTime = sbRecordDto.PostTime }; var dbUser = await _dbContext.Users.FindAsync(sbRecordDto.User.Id); sbRecord.User = dbUser!; await _dbContext.AddAsync(sbRecord); await _dbContext.SaveChangesAsync(); sbRecordDto.Id = _dbContext.ChangeTracker.Entries().Last().Entity.Id; return (true, ""); } // PUT public async Task UpdateScoreboardRecord(ScoreboardRecordDto sbRecordDto) { var sbRecord = new ScoreboardRecord { Id = sbRecordDto.Id, Score = sbRecordDto.Score, PostTime = sbRecordDto.PostTime, User = new User { Id = sbRecordDto.User.Id, Username = sbRecordDto.User.Username } }; _dbContext.Entry(sbRecord).State = EntityState.Modified; await _dbContext.SaveChangesAsync(); } public async Task ScoreboardRecordExists(int id) { return await _dbContext.Scoreboard.AnyAsync(sbr => sbr.Id == id); } // DELETE public async Task DeleteScoreboardRecord(int id) { var sbRecord = await _dbContext.Scoreboard.FindAsync(id); _dbContext.Scoreboard.Remove(sbRecord!); await _dbContext.SaveChangesAsync(); } }