From 81452a12c6d5fd5928f2167518375479dc156b3c Mon Sep 17 00:00:00 2001 From: Yang Chun Ung Date: Wed, 16 Oct 2024 22:19:05 +0900 Subject: [PATCH] Unification calculate ranking by arena --- .../WorldBossRankingQueryTest.cs | 8 +- .../Store/MySqlStore.cs | 77 +++++++++++++++++-- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/NineChronicles.DataProvider.Tests/WorldBossRankingQueryTest.cs b/NineChronicles.DataProvider.Tests/WorldBossRankingQueryTest.cs index 49a0eb7..9e2b8e9 100644 --- a/NineChronicles.DataProvider.Tests/WorldBossRankingQueryTest.cs +++ b/NineChronicles.DataProvider.Tests/WorldBossRankingQueryTest.cs @@ -189,10 +189,10 @@ public async Task WorldBossRanking_Sort() { [0] = 2, [1] = 2, - [2] = 3, - [3] = 3, - [4] = 4, - [5] = 5, + [2] = 4, + [3] = 4, + [4] = 5, + [5] = 6, }; for (int j = 0; j < 6; j++) { diff --git a/NineChronicles.DataProvider/Store/MySqlStore.cs b/NineChronicles.DataProvider/Store/MySqlStore.cs index 5c84817..d8b429d 100644 --- a/NineChronicles.DataProvider/Store/MySqlStore.cs +++ b/NineChronicles.DataProvider/Store/MySqlStore.cs @@ -2310,21 +2310,86 @@ public void StoreWorldBossMigration(int raidId) public List GetWorldBossRanking(int raidId, int? queryOffset, int? queryLimit) { using NineChroniclesContext? ctx = _dbContextFactory.CreateDbContext(); + List query = ctx + .Raiders + .Where(i => i.RaidId == raidId) + .OrderByDescending(i => i.TotalScore) + .Select(i => new WorldBossRankingModel + { + Ranking = 0, + AvatarName = i.AvatarName, + HighScore = (int)i.HighScore, + TotalScore = (int)i.TotalScore, + Cp = i.Cp, + Level = i.Level, + Address = i.Address, + IconId = i.IconId, + }) + .ToList(); + int? currentScore = null; + var currentRank = 1; + var trunk = new List(); + var result = new List(); + for (int i = 0; i < query.Count; i++) + { + var model = query[i]; + if (!currentScore.HasValue) + { + currentScore = model.TotalScore; + trunk.Add(model); + continue; + } + + if (currentScore.Value == model.TotalScore) + { + trunk.Add(model); + currentRank++; + if (i < query.Count - 1) + { + continue; + } + + foreach (var modelInTrunk in trunk) + { + modelInTrunk.Ranking = currentRank; + result.Add(modelInTrunk); + } + + trunk.Clear(); + + continue; + } + + foreach (var modelInTrunk in trunk) + { + modelInTrunk.Ranking = currentRank; + result.Add(modelInTrunk); + } + + trunk.Clear(); + if (i < query.Count - 1) + { + trunk.Add(model); + currentScore = model.TotalScore; + currentRank++; + continue; + } + + model.Ranking = currentRank + 1; + result.Add(model); + } - // Call ToList for convert query result from IQueryable - IEnumerable query = ctx.Set() - .FromSqlRaw("SET @prev_score = (SELECT max(`TotalScore`) FROM `Raiders` WHERE `RaidId` = {0}); SET @rank = (SELECT count(*) FROM `Raiders` WHERE `RaidId` = {0} AND `TotalScore` = @prev_score); SELECT `AvatarName`, `HighScore`, `TotalScore`, `Cp`, `Level`, `Address`, `IconId`, @rank := IF(@prev_score = TotalScore, @rank, @rank + 1) as `Ranking`, @prev_score := `TotalScore` FROM `Raiders` WHERE `RaidId` = {0} ORDER BY `TotalScore` DESC", raidId).ToList(); if (queryOffset.HasValue) { - query = query.Skip(queryOffset.Value); + result = result.Skip(queryOffset.Value).ToList(); } if (queryLimit.HasValue) { - query = query.Take(queryLimit.Value); + result = result.Take(queryLimit.Value).ToList(); } - return query.OrderBy(i => i.Ranking).ToList(); + return result.OrderBy(i => i.Ranking).ToList(); } public int GetTotalRaiders(int raidId)