Skip to content

Commit

Permalink
Merge pull request #32 from planetarium/implment-more-api
Browse files Browse the repository at this point in the history
Implement `avatars/{address}/inventory` API
  • Loading branch information
ipdae authored Apr 24, 2024
2 parents d3fc286 + 58b3282 commit e942d33
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 32 deletions.
57 changes: 28 additions & 29 deletions NineChroniclesUtilBackend/Controllers/AgentController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,40 +22,39 @@ public class AccountController : ControllerBase
{
[HttpGet("{agentAddress}/avatars")]
public async Task<AvatarsResponse> 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<List<AvatarState>> GetAvatarStates(Address agentAddress, IStateService stateService)
{
async Task<List<AvatarState>> 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<AvatarState> avatars = new List<AvatarState>();
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<AvatarState>();
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;
}
}
14 changes: 14 additions & 0 deletions NineChroniclesUtilBackend/Controllers/AvatarController.cs
Original file line number Diff line number Diff line change
@@ -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);
}
3 changes: 1 addition & 2 deletions NineChroniclesUtilBackend/Models/Arena/ArenaRanking.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Text.Json.Serialization;
using NineChroniclesUtilBackend.Models.Agent;

namespace NineChroniclesUtilBackend.Models.Arena;

Expand Down Expand Up @@ -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; }
}
11 changes: 11 additions & 0 deletions NineChroniclesUtilBackend/Models/Avatar/Inventory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using MongoDB.Bson;
using NineChroniclesUtilBackend.Models.Items;

namespace NineChroniclesUtilBackend.Models.Avatar;

public class Inventory(BsonValue inventory)
{
public List<Equipment> Equipments { get; set; } = inventory["Equipments"].AsBsonArray
.Select(e => new Equipment(e.AsBsonDocument))
.ToList();
}
8 changes: 8 additions & 0 deletions NineChroniclesUtilBackend/Models/Items/Equipment.cs
Original file line number Diff line number Diff line change
@@ -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;
}
9 changes: 9 additions & 0 deletions NineChroniclesUtilBackend/Models/Items/Item.cs
Original file line number Diff line number Diff line change
@@ -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;
}
11 changes: 11 additions & 0 deletions NineChroniclesUtilBackend/Models/Items/NonFungibleItem.cs
Original file line number Diff line number Diff line change
@@ -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;
}
1 change: 1 addition & 0 deletions NineChroniclesUtilBackend/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
builder.Services.AddSingleton<IStateService, HeadlessStateService>();
builder.Services.AddSingleton<MongoDBCollectionService>();
builder.Services.AddSingleton<ArenaRankingRepository>();
builder.Services.AddSingleton<AvatarRepository>();
builder.Services.AddControllers();
builder.Services.AddHeadlessGQLClient()
.ConfigureHttpClient((provider, client) =>
Expand Down
20 changes: 20 additions & 0 deletions NineChroniclesUtilBackend/Repositories/AvatarRepository.cs
Original file line number Diff line number Diff line change
@@ -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<BsonDocument> _avatarsCollection =
mongoDBCollectionService.GetCollection<BsonDocument>("avatars");

public Inventory GetInventory(string avatarAddress)
{
var filter = Builders<BsonDocument>.Filter.Eq(f => f["Avatar"]["address"], avatarAddress);
var projection = Builders<BsonDocument>.Projection.Include(f => f["Avatar"]["inventory"]["Equipments"]);
var document = _avatarsCollection.Find(filter).Project(projection).FirstOrDefault();
return new Inventory(document["Avatar"]["inventory"]);
}
}
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
```

0 comments on commit e942d33

Please sign in to comment.