From 42923bc0d80438bf9b8709d7c3a65dc121a62f4c Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 23 Apr 2024 09:36:33 +0900 Subject: [PATCH 1/5] improve README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 60517d19..bf0a6f3b 100644 --- a/README.md +++ b/README.md @@ -6,5 +6,6 @@ A backend service that provides 9c-related utility APIs. ``` dotnet tool restore dotnet graphql generate NineChroniclesUtilBackend +dotnet graphql generate NineChroniclesUtilBackend.Store dotnet build -``` \ No newline at end of file +``` From 1a2cd1caa2a75dfb737c944777c2fb47f868f5a6 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 23 Apr 2024 17:33:39 +0900 Subject: [PATCH 2/5] add models --- .../Models/Arena/ArenaRanking.cs | 3 +-- NineChroniclesUtilBackend/Models/Avatar/Inventory.cs | 11 +++++++++++ NineChroniclesUtilBackend/Models/Items/Equipment.cs | 8 ++++++++ NineChroniclesUtilBackend/Models/Items/Item.cs | 9 +++++++++ .../Models/Items/NonFungibleItem.cs | 11 +++++++++++ 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 NineChroniclesUtilBackend/Models/Avatar/Inventory.cs create mode 100644 NineChroniclesUtilBackend/Models/Items/Equipment.cs create mode 100644 NineChroniclesUtilBackend/Models/Items/Item.cs create mode 100644 NineChroniclesUtilBackend/Models/Items/NonFungibleItem.cs diff --git a/NineChroniclesUtilBackend/Models/Arena/ArenaRanking.cs b/NineChroniclesUtilBackend/Models/Arena/ArenaRanking.cs index b401c768..915d130b 100644 --- a/NineChroniclesUtilBackend/Models/Arena/ArenaRanking.cs +++ b/NineChroniclesUtilBackend/Models/Arena/ArenaRanking.cs @@ -1,5 +1,4 @@ using System.Text.Json.Serialization; -using NineChroniclesUtilBackend.Models.Agent; namespace NineChroniclesUtilBackend.Models.Arena; @@ -28,5 +27,5 @@ int Score public int Score { get; set; } = Score; [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Avatar? Avatar { get; set; } + public Agent.Avatar? Avatar { get; set; } } diff --git a/NineChroniclesUtilBackend/Models/Avatar/Inventory.cs b/NineChroniclesUtilBackend/Models/Avatar/Inventory.cs new file mode 100644 index 00000000..8b2b7f76 --- /dev/null +++ b/NineChroniclesUtilBackend/Models/Avatar/Inventory.cs @@ -0,0 +1,11 @@ +using MongoDB.Bson; +using NineChroniclesUtilBackend.Models.Items; + +namespace NineChroniclesUtilBackend.Models.Avatar; + +public class Inventory(BsonValue inventory) +{ + public List Equipments { get; set; } = inventory["Equipments"].AsBsonArray + .Select(e => new Equipment(e.AsBsonDocument)) + .ToList(); +} diff --git a/NineChroniclesUtilBackend/Models/Items/Equipment.cs b/NineChroniclesUtilBackend/Models/Items/Equipment.cs new file mode 100644 index 00000000..67efac2b --- /dev/null +++ b/NineChroniclesUtilBackend/Models/Items/Equipment.cs @@ -0,0 +1,8 @@ +using MongoDB.Bson; + +namespace NineChroniclesUtilBackend.Models.Items; + +public class Equipment(BsonValue equipment) : NonFungibleItem(equipment) +{ + public int Level { get; set; } = equipment["level"].AsInt32; +} diff --git a/NineChroniclesUtilBackend/Models/Items/Item.cs b/NineChroniclesUtilBackend/Models/Items/Item.cs new file mode 100644 index 00000000..d8c0936f --- /dev/null +++ b/NineChroniclesUtilBackend/Models/Items/Item.cs @@ -0,0 +1,9 @@ +using MongoDB.Bson; +using Nekoyume.Model.Item; + +namespace NineChroniclesUtilBackend.Models.Items; + +public class Item(BsonValue item) +{ + public ItemSubType ItemSubType { get; set; } = (ItemSubType)item["ItemSubType"].AsInt32; +} diff --git a/NineChroniclesUtilBackend/Models/Items/NonFungibleItem.cs b/NineChroniclesUtilBackend/Models/Items/NonFungibleItem.cs new file mode 100644 index 00000000..c49d9fe8 --- /dev/null +++ b/NineChroniclesUtilBackend/Models/Items/NonFungibleItem.cs @@ -0,0 +1,11 @@ +using MongoDB.Bson; + +namespace NineChroniclesUtilBackend.Models.Items; + +public class NonFungibleItem(BsonValue nonFungibleItem) : Item(nonFungibleItem) +{ + public Guid NonFungibleId { get; set; } = + Guid.TryParse(nonFungibleItem["NonFungibleId"].AsString, out var nonFungibleId) + ? nonFungibleId + : Guid.Empty; +} From e5c0d2f55972ee7e3bfaf60e621956da6ad4bad7 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 23 Apr 2024 17:34:00 +0900 Subject: [PATCH 3/5] implement AvatarRepository --- NineChroniclesUtilBackend/Program.cs | 1 + .../Repositories/AvatarRepository.cs | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 NineChroniclesUtilBackend/Repositories/AvatarRepository.cs diff --git a/NineChroniclesUtilBackend/Program.cs b/NineChroniclesUtilBackend/Program.cs index 12e24871..67edd4ff 100644 --- a/NineChroniclesUtilBackend/Program.cs +++ b/NineChroniclesUtilBackend/Program.cs @@ -25,6 +25,7 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddControllers(); builder.Services.AddHeadlessGQLClient() .ConfigureHttpClient((provider, client) => diff --git a/NineChroniclesUtilBackend/Repositories/AvatarRepository.cs b/NineChroniclesUtilBackend/Repositories/AvatarRepository.cs new file mode 100644 index 00000000..48224c33 --- /dev/null +++ b/NineChroniclesUtilBackend/Repositories/AvatarRepository.cs @@ -0,0 +1,20 @@ +using MongoDB.Bson; +using MongoDB.Driver; +using NineChroniclesUtilBackend.Models.Avatar; +using NineChroniclesUtilBackend.Services; + +namespace NineChroniclesUtilBackend.Repositories; + +public class AvatarRepository(MongoDBCollectionService mongoDBCollectionService) +{ + private readonly IMongoCollection _avatarsCollection = + mongoDBCollectionService.GetCollection("avatars"); + + public Inventory GetInventory(string avatarAddress) + { + var filter = Builders.Filter.Eq(f => f["Avatar"]["address"], avatarAddress); + var projection = Builders.Projection.Include(f => f["Avatar"]["inventory"]["Equipments"]); + var document = _avatarsCollection.Find(filter).Project(projection).FirstOrDefault(); + return new Inventory(document["Avatar"]["inventory"]); + } +} From 7b86c1c44ce4f98d966c77a4001cf0370cfffb6e Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 23 Apr 2024 17:34:32 +0900 Subject: [PATCH 4/5] implement AvatarController --- .../Controllers/AvatarController.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 NineChroniclesUtilBackend/Controllers/AvatarController.cs diff --git a/NineChroniclesUtilBackend/Controllers/AvatarController.cs b/NineChroniclesUtilBackend/Controllers/AvatarController.cs new file mode 100644 index 00000000..2c44eabb --- /dev/null +++ b/NineChroniclesUtilBackend/Controllers/AvatarController.cs @@ -0,0 +1,14 @@ +using Microsoft.AspNetCore.Mvc; +using NineChroniclesUtilBackend.Models.Avatar; +using NineChroniclesUtilBackend.Repositories; + +namespace NineChroniclesUtilBackend.Controllers; + +[ApiController] +[Route("avatars")] +public class AvatarController(AvatarRepository avatarRepository) : ControllerBase +{ + [HttpGet("{avatarAddress}/inventory")] + public Inventory GetInventory(string avatarAddress) => + avatarRepository.GetInventory(avatarAddress); +} From 58b3282322099513ad7ea1f7e49d9802c7e53a85 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 23 Apr 2024 17:34:51 +0900 Subject: [PATCH 5/5] refactor AgentController --- .../Controllers/AgentController.cs | 57 +++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/NineChroniclesUtilBackend/Controllers/AgentController.cs b/NineChroniclesUtilBackend/Controllers/AgentController.cs index 964ad8e7..6e2a5bb2 100644 --- a/NineChroniclesUtilBackend/Controllers/AgentController.cs +++ b/NineChroniclesUtilBackend/Controllers/AgentController.cs @@ -22,40 +22,39 @@ public class AccountController : ControllerBase { [HttpGet("{agentAddress}/avatars")] public async Task GetAvatars(string agentAddress, IStateService stateService) + { + var avatarStates = await GetAvatarStates(new Address(agentAddress), stateService); + return new AvatarsResponse(avatarStates + .Select(a => new Avatar(a.address.ToString(), a.name, a.level)) + .ToList()); + } + + private static async Task> GetAvatarStates(Address agentAddress, IStateService stateService) { - async Task> GetAvatarsState(Address agentAddress) + var rawState = await stateService.GetState(agentAddress, Addresses.Agent) ?? + await stateService.GetState(agentAddress); + var agentState = rawState switch { - var rawState = await stateService.GetState(agentAddress, Addresses.Agent) ?? - await stateService.GetState(agentAddress); - var agentState = rawState switch - { - Dictionary agentStateDictionary => new AgentState(agentStateDictionary), - List agentStateList => new AgentState(agentStateList), - _ => throw new ArgumentException(nameof(agentAddress)), - }; - - List avatars = new List(); + Dictionary agentStateDictionary => new AgentState(agentStateDictionary), + List agentStateList => new AgentState(agentStateList), + _ => throw new ArgumentException(nameof(agentAddress)), + }; - foreach(var avatarAddressKey in agentState.avatarAddresses.Keys) + var avatars = new List(); + foreach(var avatarAddress in agentState.avatarAddresses.Values) + { + var rawAvatarState = + await stateService.GetState(avatarAddress, Addresses.Avatar) ?? + await stateService.GetState(avatarAddress); + var avatarState = rawAvatarState switch { - var avatarAddress = agentState.avatarAddresses[avatarAddressKey]; - var rawAvatarState = - await stateService.GetState(avatarAddress, Addresses.Avatar) ?? - await stateService.GetState(avatarAddress); - - var avatarState = rawAvatarState switch - { - Dictionary avatarStateDictionary => new AvatarState(avatarStateDictionary), - List avatarStateList => new AvatarState(avatarStateList), - _ => throw new ArgumentException(nameof(avatarAddress)) - }; - avatars.Add(avatarState); - } - - return avatars; + Dictionary avatarStateDictionary => new AvatarState(avatarStateDictionary), + List avatarStateList => new AvatarState(avatarStateList), + _ => throw new ArgumentException(nameof(avatarAddress)) + }; + avatars.Add(avatarState); } - var avatars = await GetAvatarsState(new Address(agentAddress)); - return new AvatarsResponse(avatars.Select(a => new Avatar(a.address.ToString(), a.name, a.level)).ToList()); + return avatars; } }