Skip to content

Commit

Permalink
Merge pull request #700 from ipdae/rc-v200182-fix-raider-sort
Browse files Browse the repository at this point in the history
Rc v200182 fix raider sort
  • Loading branch information
ipdae authored Jun 27, 2024
2 parents fa704c2 + 2a7723f commit 6ca36cc
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Nekoyume.Model.EnumType;

namespace NineChronicles.DataProvider.Executable.Commands
{
using System;
Expand Down Expand Up @@ -393,7 +395,7 @@ private void ProcessTasks(Task<List<ICommittedActionEvaluation>>[] taskArray, IB
// check if address is already in _avatarCheck
if (!_avatarCheck.Contains(avatarAddress.ToString()))
{
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, hasAction.AvatarAddress, hasAction.RuneInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, hasAction.AvatarAddress, hasAction.RuneInfos, _blockTimeOffset, BattleType.Adventure));
_avatarCheck.Add(avatarAddress.ToString());
}

Expand Down Expand Up @@ -471,7 +473,7 @@ private void ProcessTasks(Task<List<ICommittedActionEvaluation>>[] taskArray, IB
if (action is HackAndSlashSweep hasSweep)
{
var start = DateTimeOffset.UtcNow;
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, hasSweep.avatarAddress, hasSweep.runeInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, hasSweep.avatarAddress, hasSweep.runeInfos, _blockTimeOffset, BattleType.Adventure));
_hackAndSlashSweepList.Add(HackAndSlashSweepData.GetHackAndSlashSweepInfo(
inputState,
outputState,
Expand Down Expand Up @@ -819,7 +821,7 @@ private void ProcessTasks(Task<List<ICommittedActionEvaluation>>[] taskArray, IB
if (action is BattleArena battleArena)
{
var start = DateTimeOffset.UtcNow;
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, battleArena.myAvatarAddress, battleArena.runeInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, battleArena.myAvatarAddress, battleArena.runeInfos, _blockTimeOffset, BattleType.Adventure));
_battleArenaList.Add(BattleArenaData.GetBattleArenaInfo(
inputState,
outputState,
Expand Down Expand Up @@ -1052,7 +1054,7 @@ private void ProcessTasks(Task<List<ICommittedActionEvaluation>>[] taskArray, IB
}
}

_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, raid.AvatarAddress, raid.RuneInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ae.InputContext.Signer, raid.AvatarAddress, raid.RuneInfos, _blockTimeOffset, BattleType.Adventure));

var worldBossListSheet = sheets.GetSheet<WorldBossListSheet>();
int raidId = worldBossListSheet.FindRaidIdByBlockIndex(ae.InputContext.BlockIndex);
Expand Down
73 changes: 73 additions & 0 deletions NineChronicles.DataProvider.Tests/WorldBossRankingQueryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,80 @@ public async Task WorldBossTotalUsers()
var result = await ExecuteAsync(query);
var count = (int)((Dictionary<string, object>) ((ExecutionNode) result.Data).ToValue())["worldBossTotalUsers"];
Assert.Equal(200, count);
}

[Fact]
public async Task WorldBossRanking_Sort()
{
var avatarAddresses = new List<Address>
{
new PrivateKey().Address,
new PrivateKey().Address,
new PrivateKey().Address,
};
var targetAvatarAddress = avatarAddresses[0];
var queryAddress = targetAvatarAddress.ToString();
var query = $@"query {{
worldBossRanking(raidId: 1, avatarAddress: ""{queryAddress}"") {{
blockIndex
rankingInfo {{
ranking
avatarName
address
}}
}}
}}";
for (int idx = 0; idx < 2; idx++)
{
for (int i = 0; i < 3; i++)
{
var avatarAddress = avatarAddresses[i];
var model = new RaiderModel(
idx + 1,
i.ToString(),
idx,
idx + 1,
i + 2,
GameConfig.DefaultAvatarArmorId,
i,
avatarAddress.ToHex(),
0
);
Context.Raiders.Add(model);
}
}

var block = new BlockModel
{
Index = 1L,
Hash = "4582250d0da33b06779a8475d283d5dd210c683b9b999d74d03fac4f58fa6bce",
Miner = "47d082a115c63e7b58b1532d20e631538eafadde",
Difficulty = 0L,
Nonce = "dff109a0abf1762673ed",
PreviousHash = "asd",
ProtocolVersion = 1,
PublicKey = ByteUtil.Hex(new PrivateKey().PublicKey.ToImmutableArray(false)),
StateRootHash = "ce667fcd0b69076d9ff7e7755daa2f35cb0488e4c47978468dfbd6b88fca8a90",
TotalDifficulty = 0L,
TxCount = 1,
TxHash = "fd47c10ffbee8ff2da8fa08cec3072de06a72f73693f5d3399b093b0877fa954",
TimeStamp = DateTimeOffset.UtcNow
};
Context.Blocks.Add(block);

await Context.SaveChangesAsync();
var result = await ExecuteAsync(query);
var data = (Dictionary<string, object>)((Dictionary<string, object>)((ExecutionNode)result.Data).ToValue())["worldBossRanking"];
Assert.Equal(1L, data["blockIndex"]);
var models = (object[]) data["rankingInfo"];
Assert.Equal(3, models.Length);
for (int j = 0; j < 3; j++)
{
var model = (Dictionary<string, object>)models[j];
Assert.Equal(j + 1, model["ranking"]);
Assert.Equal(avatarAddresses[j].ToHex(), model["address"]);

}
}

public void Dispose()
Expand Down
101 changes: 84 additions & 17 deletions NineChronicles.DataProvider/DataRendering/AvatarData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ public static AvatarModel GetAvatarInfo(
Address signer,
Address avatarAddress,
List<RuneSlotInfo> runeInfos,
DateTimeOffset blockTime)
DateTimeOffset blockTime,
BattleType battleType)
{
AvatarState avatarState = outputStates.GetAvatarState(avatarAddress);
var collectionExist = outputStates.TryGetCollectionState(avatarAddress, out var collectionState);
Expand All @@ -52,29 +53,43 @@ public static AvatarModel GetAvatarInfo(
var itemSlotState = outputStates.TryGetLegacyState(itemSlotStateAddress, out List rawItemSlotState)
? new ItemSlotState(rawItemSlotState)
: new ItemSlotState(BattleType.Adventure);
var equipmentInventory = avatarState.inventory.Equipments;
var equipmentList = itemSlotState.Equipments
.Select(guid => equipmentInventory.FirstOrDefault(x => x.ItemId == guid))
.Where(item => item != null).ToList();

var costumeInventory = avatarState.inventory.Costumes;
var costumeList = itemSlotState.Costumes
.Select(guid => costumeInventory.FirstOrDefault(x => x.ItemId == guid))
.Where(item => item != null).ToList();
var runeOptionSheet = sheets.GetSheet<RuneOptionSheet>();
var runeOptions = new List<RuneOptionSheet.Row.RuneOptionInfo>();
var equipmentList = SetEquipments(avatarState, itemSlotState, battleType);
var costumeList = SetCostumes(avatarState, itemSlotState, battleType);
var runeStates = outputStates.GetRuneState(avatarAddress, out _);
var runeAddresses = RuneSlotState.DeriveAddress(avatarAddress, battleType);
var runeSlotState = outputStates.TryGetLegacyState(runeAddresses, out List rawRuneSlotState)
? new RuneSlotState(rawRuneSlotState)
: new RuneSlotState(BattleType.Adventure);
var runeSlotStates = new List<RuneSlotState>();
runeSlotStates.Add(runeSlotState);
var runes = SetRunes(runeSlotStates, battleType);

var equippedRuneStates = new List<RuneState>();
var runeIds = runes[battleType].GetRuneSlot()
.Where(slot => slot.RuneId.HasValue)
.Select(slot => slot.RuneId!.Value);

foreach (var runeId in runeIds)
{
var runeState = runeStates.Runes!.FirstOrDefault(x => x.Value.RuneId == runeId);
if (runeStates.Runes != null)
{
equippedRuneStates.Add(runeState.Value);
}
}

foreach (var runeState in runeStates.Runes.Values)
var runeOptions = new List<RuneOptionSheet.Row.RuneOptionInfo>();
var runeOptionSheet = sheets.GetSheet<RuneOptionSheet>();
foreach (var runeState in equippedRuneStates)
{
if (!runeOptionSheet.TryGetValue(runeState.RuneId, out var optionRow))
{
throw new SheetRowNotFoundException("RuneOptionSheet", runeState.RuneId);
continue;
}

if (!optionRow.LevelOptionMap.TryGetValue(runeState.Level, out var option))
{
throw new SheetRowNotFoundException("RuneOptionSheet", runeState.Level);
continue;
}

runeOptions.Add(option);
Expand Down Expand Up @@ -125,8 +140,8 @@ public static AvatarModel GetAvatarInfo(
sheets.GetSheet<RuneLevelBonusSheet>());

var avatarCp = CPHelper.TotalCP(
equipmentList,
costumeList,
equipmentList[battleType],
costumeList[battleType],
runeOptions,
avatarState.level,
characterRow,
Expand Down Expand Up @@ -158,5 +173,57 @@ public static AvatarModel GetAvatarInfo(

return avatarModel;
}

private static Dictionary<BattleType, List<Equipment>> SetEquipments(
AvatarState avatarState,
ItemSlotState itemSlotStates,
BattleType battleType)
{
Dictionary<BattleType, List<Equipment>> equipments = new ();
equipments.Add(BattleType.Adventure, new List<Equipment>());
equipments.Add(BattleType.Arena, new List<Equipment>());
equipments.Add(BattleType.Raid, new List<Equipment>());
var equipmentList = itemSlotStates.Equipments
.Select(guid =>
avatarState.inventory.Equipments.FirstOrDefault(x => x.ItemId == guid))
.Where(item => item != null).ToList();
equipments[battleType] = equipmentList!;

return equipments;
}

private static Dictionary<BattleType, List<Costume>> SetCostumes(
AvatarState avatarState,
ItemSlotState itemSlotStates,
BattleType battleType)
{
Dictionary<BattleType, List<Costume>> costumes = new ();
costumes.Add(BattleType.Adventure, new List<Costume>());
costumes.Add(BattleType.Arena, new List<Costume>());
costumes.Add(BattleType.Raid, new List<Costume>());
var costumeList = itemSlotStates.Costumes
.Select(guid =>
avatarState.inventory.Costumes.FirstOrDefault(x => x.ItemId == guid))
.Where(item => item != null).ToList();
costumes[battleType] = costumeList!;

return costumes;
}

private static Dictionary<BattleType, RuneSlotState> SetRunes(
List<RuneSlotState> runeSlotStates,
BattleType battleType)
{
Dictionary<BattleType, RuneSlotState> runes = new ();
runes.Add(BattleType.Adventure, new RuneSlotState(BattleType.Adventure));
runes.Add(BattleType.Arena, new RuneSlotState(BattleType.Arena));
runes.Add(BattleType.Raid, new RuneSlotState(BattleType.Raid));
foreach (var state in runeSlotStates)
{
runes[battleType] = state;
}

return runes;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

<PropertyGroup>
<TargetFramework>net6</TargetFramework>
<LangVersion>8.0</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand Down
10 changes: 5 additions & 5 deletions NineChronicles.DataProvider/RenderSubscriber.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken)
var start = DateTimeOffset.UtcNow;
var inputState = new World(_blockChainStates.GetWorldState(ev.PreviousState));
var outputState = new World(_blockChainStates.GetWorldState(ev.OutputState));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, has.AvatarAddress, has.RuneInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, has.AvatarAddress, has.RuneInfos, _blockTimeOffset, BattleType.Adventure));
_hasList.Add(HackAndSlashData.GetHackAndSlashInfo(inputState, outputState, ev.Signer, has.AvatarAddress, has.StageId, has.Id, ev.BlockIndex, _blockTimeOffset));
if (has.StageBuffId.HasValue)
{
Expand All @@ -435,7 +435,7 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken)
var start = DateTimeOffset.UtcNow;
var inputState = new World(_blockChainStates.GetWorldState(ev.PreviousState));
var outputState = new World(_blockChainStates.GetWorldState(ev.OutputState));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, hasSweep.avatarAddress, hasSweep.runeInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, hasSweep.avatarAddress, hasSweep.runeInfos, _blockTimeOffset, BattleType.Adventure));
_hasSweepList.Add(HackAndSlashSweepData.GetHackAndSlashSweepInfo(
inputState,
outputState,
Expand Down Expand Up @@ -992,7 +992,7 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken)
var start = DateTimeOffset.UtcNow;
var inputState = new World(_blockChainStates.GetWorldState(ev.PreviousState));
var outputState = new World(_blockChainStates.GetWorldState(ev.OutputState));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, battleArena.myAvatarAddress, battleArena.runeInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, battleArena.myAvatarAddress, battleArena.runeInfos, _blockTimeOffset, BattleType.Adventure));
_battleArenaList.Add(BattleArenaData.GetBattleArenaInfo(
inputState,
outputState,
Expand Down Expand Up @@ -1327,7 +1327,7 @@ protected override Task ExecuteAsync(CancellationToken stoppingToken)
}
}
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, ev.Action.AvatarAddress, ev.Action.RuneInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, ev.Action.AvatarAddress, ev.Action.RuneInfos, _blockTimeOffset, BattleType.Adventure));
var worldBossListSheet = sheets.GetSheet<WorldBossListSheet>();
int raidId = worldBossListSheet.FindRaidIdByBlockIndex(ev.BlockIndex);
Expand Down Expand Up @@ -1598,7 +1598,7 @@ private void ProcessAgentAvatarData(ActionEvaluation<ActionBase> ev)
: new RuneSlotState(BattleType.Adventure);
var runeSlotInfos = runeSlotState.GetEquippedRuneSlotInfos();

_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, avatarAddress, runeSlotInfos, _blockTimeOffset));
_avatarList.Add(AvatarData.GetAvatarInfo(outputState, ev.Signer, avatarAddress, runeSlotInfos, _blockTimeOffset, BattleType.Adventure));
}
catch (Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion NineChronicles.DataProvider/Store/MySqlStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2297,7 +2297,7 @@ public List<WorldBossRankingModel> GetWorldBossRanking(int raidId, int? queryOff
{
using NineChroniclesContext? ctx = _dbContextFactory.CreateDbContext();
var query = ctx.Set<WorldBossRankingModel>()
.FromSqlRaw(@"SELECT `AvatarName`, `HighScore`, `TotalScore`, `Cp`, `Level`, `Address`, `IconId`, row_number() over(ORDER BY `TotalScore` DESC) as `Ranking` FROM `Raiders` WHERE `RaidId` = {0}", raidId);
.FromSqlRaw(@"SELECT `AvatarName`, `HighScore`, `TotalScore`, `Cp`, `Level`, `Address`, `IconId`, row_number() over(ORDER BY `TotalScore` DESC, `UpdatedAt`) as `Ranking` FROM `Raiders` WHERE `RaidId` = {0}", raidId);
if (queryOffset.HasValue)
{
query = query.Skip(queryOffset.Value);
Expand Down

0 comments on commit 6ca36cc

Please sign in to comment.