diff --git a/NineChronicles.DataProvider.Tests/WorldBossRankingRewardQueryTest.cs b/NineChronicles.DataProvider.Tests/WorldBossRankingRewardQueryTest.cs
index 54f7ec9c..26d99433 100644
--- a/NineChronicles.DataProvider.Tests/WorldBossRankingRewardQueryTest.cs
+++ b/NineChronicles.DataProvider.Tests/WorldBossRankingRewardQueryTest.cs
@@ -128,6 +128,11 @@ public async Task WorldBossRankingReward(int rank, long blockIndex, bool canRece
[InlineData(11L, false, 100, 2, 100, 2)]
public async Task WorldBossRankingRewards(long blockIndex, bool canReceive, int offset, int limit, int expectedRank, int expectedCount)
{
+ if (canReceive)
+ {
+ Context.WorldBossSeasonMigrationModels.Add(new WorldBossSeasonMigrationModel { RaidId = 1 });
+ }
+
for (int i = 0; i < 200; i++)
{
var avatarAddress = new PrivateKey().ToAddress();
@@ -203,6 +208,8 @@ public async Task WorldBossRankingRewards(long blockIndex, bool canReceive, int
[InlineData(2, 198, 199, "15000")]
public async Task WorldBossRankingRewards_Rate(int raidId, int offset, int expectedRank, string expectedCrystal)
{
+ Context.WorldBossSeasonMigrationModels.Add(new WorldBossSeasonMigrationModel { RaidId = raidId });
+
for (int i = 0; i < 200; i++)
{
var avatarAddress = new PrivateKey().ToAddress();
diff --git a/NineChronicles.DataProvider/Queries/NineChroniclesSummaryQuery.cs b/NineChronicles.DataProvider/Queries/NineChroniclesSummaryQuery.cs
index e95d0d43..42af92f8 100644
--- a/NineChronicles.DataProvider/Queries/NineChroniclesSummaryQuery.cs
+++ b/NineChronicles.DataProvider/Queries/NineChroniclesSummaryQuery.cs
@@ -288,36 +288,18 @@ public NineChroniclesSummaryQuery(MySqlStore store, StandaloneContext standalone
var avatarAddress = context.GetArgument
("avatarAddress");
// Use database block tip because sync db & store delay.
+ var (sheet, runeSheet, rankingRewardSheet) = GetWorldBossSheets(Store, stateContext, raidId);
var blockIndex = Store.GetTip();
- var worldBossListSheetAddress = Addresses.GetSheetAddress();
- var runeSheetAddress = Addresses.GetSheetAddress();
- var rewardSheetAddress = Addresses.GetSheetAddress();
- var values = stateContext.GetStates(new[] { worldBossListSheetAddress, runeSheetAddress, rewardSheetAddress });
- if (values[0] is Text wbs && values[1] is Text rs && values[2] is Text wrs)
+ var bossRow = sheet.OrderedList!.First(r => r.Id == raidId);
+ if (bossRow.EndedBlockIndex <= blockIndex)
{
- var sheet = new WorldBossListSheet();
- sheet.Set(wbs);
- var runeSheet = new RuneSheet();
- runeSheet.Set(rs);
- var rankingRewardSheet = new WorldBossRankingRewardSheet();
- rankingRewardSheet.Set(wrs);
- var bossRow = sheet.OrderedList!.First(r => r.Id == raidId);
- if (bossRow.EndedBlockIndex <= blockIndex && Store.MigrationExists(raidId))
- {
- // Check ranking.
- var raiders = Store.GetWorldBossRanking(raidId, null, null);
- var raider = raiders.First(r => r.Address == avatarAddress.ToHex());
- var ranking = raider.Ranking;
-
- // backward compatibility for season 1. because season 1 reward already distributed.
- var rate = raidId == 1
- ? ranking / raiders.Count * 100
- : ranking * 100 / raiders.Count;
+ // Check ranking.
+ var raiders = Store.GetWorldBossRanking(raidId, null, null);
+ var totalCount = raiders.Count;
+ var raider = raiders.First(r => r.Address == avatarAddress.ToHex());
- // calculate rewards.
- var row = FindRow(rankingRewardSheet, bossRow.BossId, ranking, rate);
- return (raider, row.GetRewards(runeSheet));
- }
+ // calculate rewards.
+ return GetWorldBossRankingReward(raidId, totalCount, raider, rankingRewardSheet, bossRow, runeSheet);
}
throw new ExecutionError("can't receive");
@@ -351,40 +333,21 @@ public NineChroniclesSummaryQuery(MySqlStore store, StandaloneContext standalone
// Check calculate state end.
// Use database block tip because sync db & store delay.
+ var (sheet, runeSheet, rankingRewardSheet) = GetWorldBossSheets(Store, stateContext, raidId);
var blockIndex = Store.GetTip();
- var worldBossListSheetAddress = Addresses.GetSheetAddress();
- var runeSheetAddress = Addresses.GetSheetAddress();
- var rewardSheetAddress = Addresses.GetSheetAddress();
- var values = stateContext.GetStates(new[] { worldBossListSheetAddress, runeSheetAddress, rewardSheetAddress });
- if (values[0] is Text wbs && values[1] is Text rs && values[2] is Text wrs)
+ var bossRow = sheet.OrderedList!.First(r => r.Id == raidId);
+ if (bossRow.EndedBlockIndex <= blockIndex)
{
- var sheet = new WorldBossListSheet();
- sheet.Set(wbs);
- var runeSheet = new RuneSheet();
- runeSheet.Set(rs);
- var rankingRewardSheet = new WorldBossRankingRewardSheet();
- rankingRewardSheet.Set(wrs);
- var bossRow = sheet.OrderedList!.First(r => r.Id == raidId);
- if (bossRow.EndedBlockIndex <= blockIndex)
+ // Check ranking.
+ var raiders = Store.GetWorldBossRanking(raidId, offset, limit);
+ int totalCount = Store.GetTotalRaiders(raidId);
+ var result = new List<(WorldBossRankingModel, List)>();
+ foreach (var raider in raiders)
{
- // Check ranking.
- var raiders = Store.GetWorldBossRanking(raidId, offset, limit);
- int totalCount = Store.GetTotalRaiders(raidId);
- var result = new List<(WorldBossRankingModel, List)>();
- foreach (var raider in raiders)
- {
- var ranking = raider.Ranking;
-
- // backward compatibility for season 1. because season 1 reward already distributed.
- var rate = raidId == 1
- ? ranking / totalCount * 100
- : ranking * 100 / totalCount;
- var row = FindRow(rankingRewardSheet, bossRow.BossId, ranking, rate);
- result.Add((raider, row.GetRewards(runeSheet)));
- }
-
- return result;
+ result.Add(GetWorldBossRankingReward(raidId, totalCount, raider, rankingRewardSheet, bossRow, runeSheet));
}
+
+ return result;
}
throw new ExecutionError("can't receive");
@@ -410,5 +373,45 @@ private static WorldBossRankingRewardSheet.Row FindRow(WorldBossRankingRewardShe
return (sheet.OrderedList?.LastOrDefault(r => r.BossId == bossId && r.RankingMin <= ranking && ranking <= r.RankingMax)
?? sheet.OrderedList?.LastOrDefault(r => r.BossId == bossId && r.RateMin <= rate && rate <= r.RateMax))!;
}
+
+ private static (WorldBossListSheet, RuneSheet, WorldBossRankingRewardSheet) GetWorldBossSheets(MySqlStore store, StateContext stateContext, int raidId)
+ {
+ if (store.MigrationExists(raidId))
+ {
+ var worldBossListSheetAddress = Addresses.GetSheetAddress();
+ var runeSheetAddress = Addresses.GetSheetAddress();
+ var rewardSheetAddress = Addresses.GetSheetAddress();
+ var values = stateContext.GetStates(new[] { worldBossListSheetAddress, runeSheetAddress, rewardSheetAddress });
+ if (values[0] is Text wbs && values[1] is Text rs && values[2] is Text wrs)
+ {
+ var sheet = new WorldBossListSheet();
+ sheet.Set(wbs);
+ var runeSheet = new RuneSheet();
+ runeSheet.Set(rs);
+ var rankingRewardSheet = new WorldBossRankingRewardSheet();
+ rankingRewardSheet.Set(wrs);
+ return (sheet, runeSheet, rankingRewardSheet);
+ }
+ }
+
+ throw new ExecutionError("can't receive");
+ }
+
+ private static int GetRankingRate(int raidId, int ranking, int totalCount)
+ {
+ // backward compatibility for season 1. because season 1 reward already distributed.
+ var rate = raidId == 1
+ ? ranking / totalCount * 100
+ : ranking * 100 / totalCount;
+ return rate;
+ }
+
+ private static (WorldBossRankingModel, List) GetWorldBossRankingReward(int raidId, int totalCount, WorldBossRankingModel raider, WorldBossRankingRewardSheet rankingRewardSheet, WorldBossListSheet.Row bossRow, RuneSheet runeSheet)
+ {
+ var ranking = raider.Ranking;
+ var rate = GetRankingRate(raidId, ranking, totalCount);
+ var row = FindRow(rankingRewardSheet, bossRow.BossId, ranking, rate);
+ return (raider, row.GetRewards(runeSheet));
+ }
}
}