Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check migration ended in worldBossRankingRewards query #509

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
117 changes: 60 additions & 57 deletions NineChronicles.DataProvider/Queries/NineChroniclesSummaryQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -288,36 +288,18 @@ public NineChroniclesSummaryQuery(MySqlStore store, StandaloneContext standalone
var avatarAddress = context.GetArgument<Address>("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<WorldBossListSheet>();
var runeSheetAddress = Addresses.GetSheetAddress<RuneSheet>();
var rewardSheetAddress = Addresses.GetSheetAddress<WorldBossRankingRewardSheet>();
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");
Expand Down Expand Up @@ -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<WorldBossListSheet>();
var runeSheetAddress = Addresses.GetSheetAddress<RuneSheet>();
var rewardSheetAddress = Addresses.GetSheetAddress<WorldBossRankingRewardSheet>();
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<FungibleAssetValue>)>();
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<FungibleAssetValue>)>();
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");
Expand All @@ -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<WorldBossListSheet>();
var runeSheetAddress = Addresses.GetSheetAddress<RuneSheet>();
var rewardSheetAddress = Addresses.GetSheetAddress<WorldBossRankingRewardSheet>();
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<FungibleAssetValue>) 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));
}
}
}