diff --git a/Mimir.Worker/Mimir.Worker.csproj b/Mimir.Worker/Mimir.Worker.csproj index 151f3c0a..34cebe8a 100644 --- a/Mimir.Worker/Mimir.Worker.csproj +++ b/Mimir.Worker/Mimir.Worker.csproj @@ -10,8 +10,8 @@ - - + + diff --git a/Mimir.Worker/Scrapper/StateGetter.cs b/Mimir.Worker/Scrapper/StateGetter.cs index 39bd236f..c448576e 100644 --- a/Mimir.Worker/Scrapper/StateGetter.cs +++ b/Mimir.Worker/Scrapper/StateGetter.cs @@ -98,6 +98,11 @@ public async Task GetAvatarState(Address avatarAddress) throw new ArgumentException($"Unsupported state type for address: {avatarAddress}"); } + if (await GetStateWithLegacyAccount(avatarAddress, Addresses.ActionPoint) is Integer actionPoint) + { + avatarState.actionPoint = actionPoint; + } + return avatarState; } diff --git a/Mimir/Arena/ArenaBulkSimulator.cs b/Mimir/Arena/ArenaBulkSimulator.cs index 16027405..6a691140 100644 --- a/Mimir/Arena/ArenaBulkSimulator.cs +++ b/Mimir/Arena/ArenaBulkSimulator.cs @@ -72,10 +72,10 @@ public ArenaLog SimulateBattle( } } } - + var arenaLog = simulator.Simulate( - new ArenaPlayerDigest(myAvatar.AvatarState, myAvatar.ItemSlotState.Equipments, myAvatar.ItemSlotState.Costumes, myAvatar.RuneStates), - new ArenaPlayerDigest(enemyAvatar.AvatarState, enemyAvatar.ItemSlotState.Equipments, enemyAvatar.ItemSlotState.Costumes, enemyAvatar.RuneStates), + new ArenaPlayerDigest(myAvatar.AvatarState, myAvatar.ItemSlotState.Equipments, myAvatar.ItemSlotState.Costumes, myAvatar.RuneStates, myAvatar.RuneSlotState), + new ArenaPlayerDigest(enemyAvatar.AvatarState, enemyAvatar.ItemSlotState.Equipments, enemyAvatar.ItemSlotState.Costumes, enemyAvatar.RuneStates, enemyAvatar.RuneSlotState), simulatorSheets, modifiers[myAvatar.AvatarState.address], modifiers[enemyAvatar.AvatarState.address], diff --git a/Mimir/Arena/AvatarStatesForArena.cs b/Mimir/Arena/AvatarStatesForArena.cs index 98791d7a..2ab1c7ff 100644 --- a/Mimir/Arena/AvatarStatesForArena.cs +++ b/Mimir/Arena/AvatarStatesForArena.cs @@ -6,12 +6,14 @@ public record AvatarStatesForArena { public AvatarState AvatarState { get; private set; } public ItemSlotState ItemSlotState { get; private set; } - public List RuneStates { get; private set; } + public AllRuneState RuneStates { get; private set; } + public RuneSlotState RuneSlotState { get; private set; } - public AvatarStatesForArena(AvatarState avatarState, ItemSlotState itemSlotState, List runeStates) + public AvatarStatesForArena(AvatarState avatarState, ItemSlotState itemSlotState, AllRuneState runeStates, RuneSlotState runeSlotState) { AvatarState = avatarState; ItemSlotState = itemSlotState; RuneStates = runeStates; + RuneSlotState = runeSlotState; } } diff --git a/Mimir/Controllers/AgentController.cs b/Mimir/Controllers/AgentController.cs index f4fb1dce..78b75d38 100644 --- a/Mimir/Controllers/AgentController.cs +++ b/Mimir/Controllers/AgentController.cs @@ -26,7 +26,7 @@ IStateService stateService } return new AvatarsResponse( - avatars.Select(e => new Avatar(e.address.ToString(), e.name, e.level)).ToList() + avatars.Select(e => new Avatar(e.address.ToString(), e.name, e.level, e.actionPoint)).ToList() ); } } diff --git a/Mimir/Controllers/ArenaController.cs b/Mimir/Controllers/ArenaController.cs index fa1f1589..949c97be 100644 --- a/Mimir/Controllers/ArenaController.cs +++ b/Mimir/Controllers/ArenaController.cs @@ -6,7 +6,9 @@ using Mimir.Repositories; using Mimir.Services; using Mimir.Util; +using Nekoyume.Model.EnumType; using Nekoyume.TableData; +using Nekoyume.TableData.Rune; namespace Mimir.Controllers; @@ -69,17 +71,20 @@ IStateService stateService var myAvatarState = await stateGetter.GetAvatarStateAsync(myAvatarAddress); var myAvatarItemSlotState = await stateGetter.GetItemSlotStateAsync(myAvatarAddress); var myAvatarRuneStates = await stateGetter.GetRuneStatesAsync(myAvatarAddress); + var myAvatarRuneSlotState = await stateGetter.GetRuneSlotStateAsync(myAvatarAddress, BattleType.Arena); var enemyAvatarState = await stateGetter.GetAvatarStateAsync(enemyAvatarAddress); var enemyAvatarItemSlotState = await stateGetter.GetItemSlotStateAsync(enemyAvatarAddress); var enemyAvatarRuneStates = await stateGetter.GetRuneStatesAsync(enemyAvatarAddress); + var enemyAvatarRuneSlotState = await stateGetter.GetRuneSlotStateAsync(enemyAvatarAddress, BattleType.Arena); var bulkSimulator = new ArenaBulkSimulator(); var result = await bulkSimulator.BulkSimulate( - new AvatarStatesForArena(myAvatarState, myAvatarItemSlotState, myAvatarRuneStates), + new AvatarStatesForArena(myAvatarState, myAvatarItemSlotState, myAvatarRuneStates, myAvatarRuneSlotState), new AvatarStatesForArena( enemyAvatarState, enemyAvatarItemSlotState, - enemyAvatarRuneStates + enemyAvatarRuneStates, + enemyAvatarRuneSlotState ), new ArenaSimulatorSheets( await stateGetter.GetSheetAsync(), @@ -93,7 +98,9 @@ await stateGetter.GetSheetAsync(), await stateGetter.GetSheetAsync(), await stateGetter.GetSheetAsync(), await stateGetter.GetSheetAsync(), - await stateGetter.GetSheetAsync() + await stateGetter.GetSheetAsync(), + await stateGetter.GetSheetAsync(), + await stateGetter.GetSheetAsync() ), await stateGetter.GetCollectionStatesAsync([myAvatarAddress, enemyAvatarAddress]), await stateGetter.GetSheetAsync(), diff --git a/Mimir/Mimir.csproj b/Mimir/Mimir.csproj index 7514d841..27b58dbb 100644 --- a/Mimir/Mimir.csproj +++ b/Mimir/Mimir.csproj @@ -15,8 +15,8 @@ - - + + diff --git a/Mimir/Models/Agent/Avatar.cs b/Mimir/Models/Agent/Avatar.cs index 8b77c9c2..1d9e3884 100644 --- a/Mimir/Models/Agent/Avatar.cs +++ b/Mimir/Models/Agent/Avatar.cs @@ -1,8 +1,9 @@ namespace Mimir.Models.Agent; -public class Avatar(string avatarAddress, string avatarName, int level) +public class Avatar(string avatarAddress, string avatarName, int level, int actionPoint) { public string AvatarAddress { get; set; } = avatarAddress; public string AvatarName { get; set; } = avatarName; public int Level { get; set; } = level; + public int ActionPoint { get; private set; } = actionPoint; } diff --git a/Mimir/Repositories/ArenaRankingRespository.cs b/Mimir/Repositories/ArenaRankingRespository.cs index c87db3b3..b9ff07f5 100644 --- a/Mimir/Repositories/ArenaRankingRespository.cs +++ b/Mimir/Repositories/ArenaRankingRespository.cs @@ -160,7 +160,8 @@ private async Task BuildArenaRankingFromDocument(BsonDocument docu var avatar = new Avatar( document["Avatar"]["Avatar"]["address"].AsString, document["Avatar"]["Avatar"]["name"].AsString, - document["Avatar"]["Avatar"]["level"].AsInt32 + document["Avatar"]["Avatar"]["level"].AsInt32, + document["Avatar"]["Avatar"]["actionPoint"].AsInt32 ); arenaRanking.Avatar = avatar; diff --git a/Mimir/Repositories/CpRepository.cs b/Mimir/Repositories/CpRepository.cs index eee3c429..3b774ae8 100644 --- a/Mimir/Repositories/CpRepository.cs +++ b/Mimir/Repositories/CpRepository.cs @@ -8,6 +8,9 @@ using Mimir.Models.Agent; using Mimir.Services; using Mimir.Util; +using Nekoyume; +using Nekoyume.Helper; +using Nekoyume.TableData.Rune; namespace Mimir.Repositories; @@ -61,6 +64,12 @@ public CpRepository(IStateService stateService) } } } + + var runeListSheet = await _stateGetter.GetSheetAsync(); + var runeStates = await _stateGetter.GetRuneStatesAsync(avatarAddress); + var runeLevelBonusSheet = await _stateGetter.GetSheetAsync(); + var runeLevelBonus = + RuneHelper.CalculateRuneLevelBonus(runeStates, runeListSheet, runeLevelBonusSheet); return CPHelper.TotalCP( equipments, @@ -69,7 +78,8 @@ public CpRepository(IStateService stateService) avatar.Level, characterRow, costumeStatSheet, - modifiers[avatarAddress] + modifiers[avatarAddress], + runeLevelBonus ); } catch (NullReferenceException) diff --git a/Mimir/Util/StateGetter.cs b/Mimir/Util/StateGetter.cs index 21db3ee0..b9fe54f3 100644 --- a/Mimir/Util/StateGetter.cs +++ b/Mimir/Util/StateGetter.cs @@ -1,5 +1,6 @@ using Libplanet.Crypto; using Bencodex.Types; +using Libplanet.Action.State; using Nekoyume.TableData; using Nekoyume; using Nekoyume.Action; @@ -7,6 +8,8 @@ using Nekoyume.Model.Item; using Nekoyume.Model.State; using Mimir.Services; +using Nekoyume.Model.Arena; +using Nekoyume.TableData.Rune; namespace Mimir.Util; @@ -93,7 +96,12 @@ await stateService.GetState(address, accountAddress) ?? avatarState.inventory = inventory; } } - + + if (await GetStateAsync(avatarAddress, Addresses.ActionPoint) is Integer actionPoint) + { + avatarState.actionPoint = actionPoint; + } + return avatarState; } @@ -119,29 +127,43 @@ await stateService.GetState(address, accountAddress) ?? _ => null, }; } - - public async Task> GetRuneStatesAsync(Address avatarAddress) + + public async Task GetRuneStatesAsync(Address avatarAddress) { - var state = await stateService.GetState( - RuneSlotState.DeriveAddress(avatarAddress, BattleType.Arena)); - var runeSlotState = state switch + AllRuneState allRuneState; + if (await GetStateAsync(avatarAddress, Addresses.RuneState) is List list) { - List list => new RuneSlotState(list), - null => new RuneSlotState(BattleType.Arena), - _ => null, - }; - if (runeSlotState is null) + allRuneState = new AllRuneState(list); + } + else + { + // Get legacy rune states + var runeListSheet = await GetSheetAsync(); + allRuneState = new AllRuneState(); + foreach (var rune in runeListSheet.Values) + { + var runeAddress = RuneState.DeriveAddress(avatarAddress, rune.Id); + if (await GetStateAsync(runeAddress, ReservedAddresses.LegacyAccount) is List rawState) + { + var runeState = new RuneState(rawState); + allRuneState.AddRuneState(runeState); + } + } + } + + return allRuneState; + } + + public async Task GetRuneSlotStateAsync(Address avatarAddress, BattleType battleType) + { + var runeSlotStateAddress = RuneSlotState.DeriveAddress(avatarAddress, battleType); + var serialized = await GetStateAsync(runeSlotStateAddress, ReservedAddresses.LegacyAccount); + if (serialized is List list) { - return []; + return new RuneSlotState(list); } - var runeAddresses = runeSlotState.GetEquippedRuneSlotInfos() - .Select(info => RuneState.DeriveAddress(avatarAddress, info.RuneId)) - .ToArray(); - var runeValues = await stateService.GetStates(runeAddresses); - return runeValues.OfType() - .Select(e => new RuneState(e)) - .ToList(); + return new RuneSlotState(battleType); } public async Task> GetCollectionStatesAsync(List
addresses)