diff --git a/ProjectLighthouse/Controllers/ScoreController.cs b/ProjectLighthouse/Controllers/ScoreController.cs index 287be62c..e71d3810 100644 --- a/ProjectLighthouse/Controllers/ScoreController.cs +++ b/ProjectLighthouse/Controllers/ScoreController.cs @@ -1,7 +1,11 @@ +using System; using System.IO; +using System.Linq; +using System.Collections.Generic; using System.Threading.Tasks; using System.Xml.Serialization; using LBPUnion.ProjectLighthouse.Types; +using LBPUnion.ProjectLighthouse.Serialization; using Microsoft.AspNetCore.Mvc; namespace LBPUnion.ProjectLighthouse.Controllers @@ -30,10 +34,58 @@ namespace LBPUnion.ProjectLighthouse.Controllers score.SlotId = id; - this.database.Scores.Add(score); + IQueryable existingScore = this.database.Scores.Where(s => s.PlayerIdCollection == score.PlayerIdCollection); + + if (existingScore.Any()) + { + Score first = existingScore.FirstOrDefault(s => s.SlotId == score.SlotId); + score.ScoreId = first.ScoreId; + score.Points = Math.Max(first.Points, score.Points); + this.database.Entry(first).CurrentValues.SetValues(score); + } + else + { + this.database.Scores.Add(score); + } await this.database.SaveChangesAsync(); return this.Ok(); } + + [HttpGet("topscores/user/{slotId:int}/{type:int}")] + public async Task TopScores(int slotId, int type, [FromQuery] int pageStart, [FromQuery] int pageSize) + { + // Get username + User user = await this.database.UserFromRequest(this.Request); + + // Find your score, even if you aren't in the top list + List myScore = this.database.Scores + .Where(s => s.SlotId == slotId && s.Type == type && s.PlayerIdCollection.Contains(user.Username)).ToList(); + + //Split this out from pagination, so we can count totalNumScores below + IQueryable allScoresOfType = this.database.Scores + .Where(s => s.SlotId == slotId && s.Type == type); + + //Paginated viewing + IQueryable pagedScores = allScoresOfType + .OrderByDescending(s => s.Points) + .Skip(pageStart - 1) + .Take(Math.Min(pageSize, 30)); + + //Calculate rank and serialize top scores + int rank = 1; + string serializedScores = Enumerable.Aggregate(pagedScores, string.Empty, (current, score) => { + score.Rank = (pageStart - 1) * pageSize + rank++; + return current + score.Serialize(); + }); + + string res = LbpSerializer.TaggedStringElement("scores", serializedScores, new Dictionary() { + {"yourScore", myScore.OrderByDescending(score => score.Points).FirstOrDefault()}, + {"yourRank", 0 }, // afaik, this is unused + {"totalNumScores", allScoresOfType.Count() } // This is shown as "Ranked 1/x" in the side menu if you have the global highscore + }); + + return this.Ok(res); + } } } \ No newline at end of file