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

PDX-426: Fix items query source to database from headless api #23

Closed
wants to merge 1 commit into from
Closed
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
83 changes: 76 additions & 7 deletions NineChroniclesUtilBackend/Repositories/ArenaRankingRespository.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
using System.Collections;
using Bencodex;
using Bencodex.Types;
using Microsoft.OpenApi.Extensions;
using MongoDB.Bson;
using MongoDB.Driver;
using Nekoyume.Model.Elemental;
using Nekoyume.Model.Item;
using Nekoyume.Model.Stat;
using Nekoyume.Model.State;
using Nekoyume.TableData;
using NineChroniclesUtilBackend.Models.Agent;
using NineChroniclesUtilBackend.Models.Arena;
using NineChroniclesUtilBackend.Services;
Expand Down Expand Up @@ -48,11 +56,12 @@ public async Task<List<ArenaRanking>> GetRanking(long limit, long offset)
$@"{{ $limit: {limit} }}",
@"{ $lookup: { from: 'avatars', localField: 'AvatarAddress', foreignField: 'Avatar.address', as: 'Avatar' } }",
@"{ $unwind: { path: '$Avatar', preserveNullAndEmptyArrays: true } }",
@"{ $unset: ['Avatar.Avatar.inventory', 'Avatar.Avatar.mailBox', 'Avatar.Avatar.stageMap', 'Avatar.Avatar.monsterMap', 'Avatar.Avatar.itemMap', 'Avatar.Avatar.eventMap'] }",
@"{ $unset: ['Avatar.Avatar.mailBox', 'Avatar.Avatar.stageMap', 'Avatar.Avatar.monsterMap', 'Avatar.Avatar.itemMap', 'Avatar.Avatar.eventMap'] }",
}.Select(BsonDocument.Parse).ToArray();

var aggregation = ArenaCollection.Aggregate<BsonDocument>(pipelines).ToList();
var arenaRankings = await Task.WhenAll(aggregation.OfType<BsonDocument>().Select(BuildArenaRankingFromDocument));
var arenaRankings =
await Task.WhenAll(Enumerable.OfType<BsonDocument>(aggregation).Select(BuildArenaRankingFromDocument));

return [.. arenaRankings];
}
Expand Down Expand Up @@ -81,16 +90,76 @@ private async Task<ArenaRanking> BuildArenaRankingFromDocument(BsonDocument docu
arenaRanking.Avatar = avatar;

var characterId = document["Avatar"]["Avatar"]["characterId"].AsInt32;
var equipmentids = document["Avatar"]["ItemSlot"]["Equipments"].AsBsonArray.Select(x => x.AsString);
var costumeids = document["Avatar"]["ItemSlot"]["Costumes"].AsBsonArray.Select(x => x.AsString);
var runeSlots = document["Avatar"]["RuneSlot"].AsBsonArray.Select(rune =>
(rune["RuneId"].AsInt32, rune["Level"].AsInt32)
);

var cp = await cpRepository.CalculateCp(avatar, characterId, equipmentids, costumeids, runeSlots);
var costumes = ParseToCostumes(document["Avatar"]["Avatar"]["inventory"]["Costumes"].AsBsonArray).ToList();
var equipments = ParseToEquipments(document["Avatar"]["Avatar"]["inventory"]["Equipments"].AsBsonArray)
.ToList();

var cp = await cpRepository.CalculateCp(avatar, characterId, costumes, equipments, runeSlots);
arenaRanking.CP = cp;
Console.WriteLine($"CP Calculate {arenaRanking.ArenaAddress}");

return arenaRanking;
}
}

public static IEnumerable<Costume> ParseToCostumes(IEnumerable<BsonValue> bsonValues)
{
return bsonValues.Select(value =>
{
var itemId = new Guid(value["ItemId"].AsString);
var spineResourcePath = value["SpineResourcePath"].AsString;

var rawValue = ParseToItemRowDictionary(value);
rawValue = rawValue.Add("spine_resource_path", new Text(spineResourcePath));

var raw = new CostumeItemSheet.Row(rawValue);
return new Costume(raw, itemId);
});
}

public static IEnumerable<Equipment> ParseToEquipments(IEnumerable<BsonValue> bsonValues)
{
return bsonValues.Select(value =>
{
var itemId = new Guid(value["ItemId"].AsString);
var requiredBlockIndex = value["RequiredBlockIndex"].AsInt32;
var madeWithMimisbrunnrRecipe = value["MadeWithMimisbrunnrRecipe"].AsBoolean;
var setId = value["SetId"].AsInt32;
var stat = new DecimalStat(
(StatType)value["Stat"]["StatType"].AsInt32,
new decimal(value["Stat"]["BaseValue"].AsDouble),
new decimal(value["Stat"]["AdditionalValue"].AsDouble)
);
var spineResourcePath = value["SpineResourcePath"].AsString;

var rawValue = ParseToItemRowDictionary(value);
rawValue = rawValue.Add("set_id", new Integer(setId));
rawValue = rawValue.Add("stat", stat.Serialize());
rawValue = rawValue.Add("attack_range", new Text("0"));
rawValue = rawValue.Add("spine_resource_path", new Text(spineResourcePath));

var raw = new EquipmentItemSheet.Row(rawValue);
return new Equipment(raw, itemId, requiredBlockIndex, madeWithMimisbrunnrRecipe);
});
}

private static Dictionary ParseToItemRowDictionary(BsonValue value)
{
var id = value["Id"].AsInt32;
var itemSubType = Enum.GetName(typeof(ItemSubType), value["ItemSubType"].AsInt32) ??
ItemSubType.FullCostume.GetDisplayName();
var grade = value["Grade"].AsInt32;
var elementalType = Enum.GetName(typeof(ElementalType), value["ElementalType"].AsInt32) ??
ElementalType.Normal.GetDisplayName();

return new Dictionary(new[]
{
new KeyValuePair<string, IValue>("item_id", new Integer(id)),
new KeyValuePair<string, IValue>("item_sub_type", new Text(itemSubType)),
new KeyValuePair<string, IValue>("grade", new Integer(grade)),
new KeyValuePair<string, IValue>("elemental_type", new Text(elementalType)),
});
}
}
21 changes: 8 additions & 13 deletions NineChroniclesUtilBackend/Repositories/CpRepository.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Bencodex;
using Bencodex.Types;
using Libplanet.Crypto;
using Nekoyume.Battle;
Expand All @@ -13,6 +14,7 @@ namespace NineChroniclesUtilBackend.Repositories;

public class CpRepository
{
private Codec _codec = new();
private StateGetter _stateGetter;

public CpRepository(IStateService stateService)
Expand All @@ -23,8 +25,8 @@ public CpRepository(IStateService stateService)
public async Task<int?> CalculateCp(
Avatar avatar,
int characterId,
IEnumerable<string> equipmentIds,
IEnumerable<string> costumeIds,
IReadOnlyCollection<Costume> costumes,
IReadOnlyCollection<Equipment> equipments,
IEnumerable<(int id, int level)> runeOption
)
{
Expand All @@ -35,21 +37,14 @@ public CpRepository(IStateService stateService)
var characterRow = await GetCharacterRow(characterId);
var costumeStatSheet = await _stateGetter.GetSheet<CostumeStatSheet>();
var collectionSheets = await _stateGetter.GetSheet<CollectionSheet>();

var inventoryState = await _stateGetter.GetInventoryState(avatarAddress);

List<Equipment> equipments = inventoryState
.Equipments
.Where(x => x.Equipped).ToList();
List<Costume> costumes = inventoryState
.Costumes
.Where(x => x.Equipped).ToList();
List<RuneOptionSheet.Row.RuneOptionInfo> runes = runeOption.Select(x => GetRuneOptionInfo(x.id, x.level).Result).ToList();

var runes = runeOption.Select(x => GetRuneOptionInfo(x.id, x.level).Result).ToList();
var collectionStates = await _stateGetter.GetCollectionStates([avatarAddress]);
var modifiers = new Dictionary<Address, List<StatModifier>>
{
[avatarAddress] = new(),
[avatarAddress] = [],
};

if (collectionStates.Count > 0)
{
foreach (var (address, state) in collectionStates)
Expand Down