From cc580d16561e9f72c0fba5cf07d3573defcbf536 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 27 Aug 2024 20:07:26 +0900 Subject: [PATCH 01/12] introduce MimirQuery with GetMetadataBlockIndexAsync method --- .../_Scripts/ApiClient/GraphQL/Queries.meta | 3 + .../ApiClient/GraphQL/Queries/MimirQuery.cs | 75 +++++++++++++++++++ .../GraphQL/Queries/MimirQuery.cs.meta | 3 + 3 files changed, 81 insertions(+) create mode 100644 nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries.meta create mode 100644 nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs create mode 100644 nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs.meta diff --git a/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries.meta b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries.meta new file mode 100644 index 0000000000..6fe6b19f12 --- /dev/null +++ b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cad25965b4c3447993d4fc75125802a8 +timeCreated: 1724754467 \ No newline at end of file diff --git a/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs new file mode 100644 index 0000000000..680e1d3e55 --- /dev/null +++ b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs @@ -0,0 +1,75 @@ +using System; +using System.Text; +using System.Threading.Tasks; +using GraphQL; +using GraphQL.Client.Http; +using Newtonsoft.Json.Linq; + +namespace Nekoyume.GraphQL.Queries +{ + public static class MimirQuery + { + private static async Task> Query( + GraphQLHttpClient mimirClient, + string query) + { + try + { + var request = new GraphQLHttpRequest(query); + var response = await mimirClient.SendQueryAsync(request); + if (response.Data is not null || + response.Errors is not { Length: > 0 }) + { + return response; + } + + var sb = new StringBuilder(); + sb.AppendLine("GraphQL response data is null and has errors:"); + foreach (var error in response.Errors) + { + sb.AppendLine($" {error.Message}"); + } + + NcDebug.LogError(sb.ToString()); + return null; + } + catch (Exception e) + { + NcDebug.LogError($"Failed to execute GraphQL query.\n{e}"); + return null; + } + } + + public static async Task GetMetadataBlockIndexAsync( + GraphQLHttpClient mimirClient, + string collectionName) + { + if (mimirClient is null) + { + return null; + } + + var query = @$"query {{ + metadata(collectionName: ""{collectionName}"") {{ + latestBlockIndex + }} +}}"; + var response = await Query(mimirClient, query); + var data = response?.Data; + if (data is null) + { + return null; + } + + try + { + return data["metadata"]["latestBlockIndex"].Value(); + } + catch (Exception e) + { + NcDebug.LogError($"Failed to parse latestBlockIndex from metadata.\n{e}"); + return null; + } + } + } +} diff --git a/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs.meta b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs.meta new file mode 100644 index 0000000000..fb80f40396 --- /dev/null +++ b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3328b92d26904ccab3bbbf880cc87ce0 +timeCreated: 1724754496 \ No newline at end of file From 9b22117d88bfb7f1ad01b3f2c88da440eb66efc1 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 27 Aug 2024 20:07:55 +0900 Subject: [PATCH 02/12] add MimirUrl to CommandLineOptions --- .../Assets/_Scripts/Helper/CommandLineOptions.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs b/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs index 25fb15e9a4..69cb7d4ba9 100644 --- a/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs +++ b/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs @@ -122,6 +122,8 @@ public class CommandLineOptions private bool _mixpanelDebugWarning; + private string _mimirUrl; + public bool Empty { get; private set; } = true; public string genesisBlockPath; @@ -624,6 +626,17 @@ public bool EnableGuestLogin Empty = false; } } + + [Option("mimir-url", Required = false, HelpText = "mimir url")] + public string MimirUrl + { + get => _mimirUrl; + set + { + _mimirUrl = value; + Empty = false; + } + } [Option("mixpanel-debug-error", Required = false, HelpText = "mixpanel debug error")] public bool MixpanelDebugError From 46a554796d2f99b4ed1158729bcbbbd118d6143a Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 27 Aug 2024 20:08:23 +0900 Subject: [PATCH 03/12] add ApiClients.Mimir --- nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs b/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs index fac6414d42..d5fddee541 100644 --- a/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs +++ b/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs @@ -1,3 +1,5 @@ +using GraphQL.Client.Http; +using GraphQL.Client.Serializer.Newtonsoft; using Nekoyume.GraphQL; using Nekoyume.Helper; using NineChronicles.ExternalServices.IAPService.Runtime; @@ -21,6 +23,8 @@ private static class Singleton private static readonly string DccUrlJsonPath = Platform.GetStreamingAssetsPath("dccUrl.json"); + public GraphQLHttpClient Mimir { get; private set; } + public NineChroniclesAPIClient WorldBossClient { get; private set; } public NineChroniclesAPIClient RpcGraphQlClient { get; private set; } @@ -56,6 +60,13 @@ public void Initialize(CommandLineOptions clo) // NOTE: planetContext.CommandLineOptions and _commandLineOptions are same. // NOTE: Initialize several services after Agent initialized. + Mimir = string.IsNullOrEmpty(clo.MimirUrl) + ? new GraphQLHttpClient( + "https://mimir.nine-chronicles.dev/odin/graphql/", + new NewtonsoftJsonSerializer()) // Temporary + : new GraphQLHttpClient( + clo.MimirUrl, + new NewtonsoftJsonSerializer()); WorldBossClient = new NineChroniclesAPIClient(clo.ApiServerHost); RpcGraphQlClient = string.IsNullOrEmpty(clo.RpcServerHost) ? new NineChroniclesAPIClient(string.Empty) : From 3f456565694f4f3022051d20d1fc3e964c2a89ad Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 27 Aug 2024 20:08:53 +0900 Subject: [PATCH 04/12] get arena metadata block index from mimir --- nekoyume/Assets/_Scripts/State/RxProps.Arena.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs index 293223a60f..26e07bbbf3 100644 --- a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs +++ b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs @@ -8,16 +8,13 @@ using Libplanet.Crypto; using Nekoyume.Action; using Nekoyume.ApiClient; -using Nekoyume.Arena; -using Nekoyume.Game.LiveAsset; using Nekoyume.GraphQL; +using Nekoyume.GraphQL.Queries; using Nekoyume.Helper; using Nekoyume.Model.Arena; using Nekoyume.Model.EnumType; using Nekoyume.Model.State; using Nekoyume.UI.Model; -using UnityEngine; -using static Lib9c.SerializeKeys; namespace Nekoyume.State { @@ -255,6 +252,14 @@ private static async Task> var lastBattleBlockIndex = arenaAvatarState?.LastBattleBlockIndex ?? 0L; try { + // check arena metadata from mimir + var mimirClient = ApiClients.Instance.Mimir; + var mimirArenaBlockIndex = await MimirQuery.GetMetadataBlockIndexAsync(mimirClient, "arena"); + NcDebug.LogWarning($"mimirArenaBlockIndex: {mimirArenaBlockIndex}"); + + // get leaderboard from mimir + + // fallback to Headless var response = await ApiClients.Instance.ArenaServiceClient.QueryArenaInfoAsync(currentAvatarAddr); // Arrange my information so that it comes first when it's the same score. arenaInfo = response.StateQuery.ArenaParticipants.ToList(); From 5604ab644772d418f25a5757b3d8a059c1f41e85 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 27 Aug 2024 20:55:28 +0900 Subject: [PATCH 05/12] implement MimirQuery.GetArenaParticipantsAsync method --- .../ApiClient/GraphQL/Queries/MimirQuery.cs | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs index 680e1d3e55..c2d6e87861 100644 --- a/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs +++ b/nekoyume/Assets/_Scripts/ApiClient/GraphQL/Queries/MimirQuery.cs @@ -1,8 +1,14 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Text; using System.Threading.Tasks; using GraphQL; using GraphQL.Client.Http; +using Libplanet.Crypto; +using Nekoyume.Arena; +using Nekoyume.Model.Arena; +using Nekoyume.UI.Model; using Newtonsoft.Json.Linq; namespace Nekoyume.GraphQL.Queries @@ -71,5 +77,79 @@ private static async Task> Query( return null; } } + + public static async Task> GetArenaParticipantsAsync( + GraphQLHttpClient mimirClient, + Address avatarAddress) + { + if (mimirClient is null) + { + return null; + } + + var query = @$"query {{ + arena {{ + leaderboardByAvatarAddress(avatarAddress: ""{avatarAddress}"") {{ + address + simpleAvatar {{ + name + level + }} + rank + arenaScore {{ + score + }} + }} + }} +}}"; + var response = await Query(mimirClient, query); + var data = response?.Data; + if (data is null) + { + return null; + } + + try + { + var children = data["arena"]["leaderboardByAvatarAddress"].Children(); + var participants = children + .Select(e => + { + var address = new Address(e["address"].Value()); + var name = e["simpleAvatar"]["name"].Value(); + var nameWithHash = $"{name} #{address.ToHex()[..4]}"; + return new ArenaParticipantModel + { + AvatarAddr = address, + NameWithHash = nameWithHash, + PortraitId = GameConfig.DefaultAvatarArmorId, + Level = e["simpleAvatar"]["level"].Value(), + Cp = 999_999_999, + GuildName = "Guild Name Here", + Score = e["arenaScore"]["score"].Value(), + Rank = e["rank"].Value(), + WinScore = 0, + LoseScore = 0, + }; + }) + .ToList(); + var me = participants.FirstOrDefault(p => p.AvatarAddr.Equals(avatarAddress)); + var myScore = me?.Score ?? ArenaScore.ArenaScoreDefault; + foreach (var participant in participants) + { + var (myWinScore, myDefeatScore, _) = + ArenaHelper.GetScores(myScore, participant.Score); + participant.WinScore = myWinScore; + participant.LoseScore = myDefeatScore; + } + + return participants; + } + catch (Exception e) + { + NcDebug.LogError($"Failed to parse arena participants.\n{e}"); + return null; + } + } } } From 6894c8fe8543f19baef89c62f6284c0508e3917d Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 27 Aug 2024 20:56:01 +0900 Subject: [PATCH 06/12] use Mimir.GetArenaParticipantsAsync method in RxProps.Arena with fallback --- .../Assets/_Scripts/State/RxProps.Arena.cs | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs index 26e07bbbf3..7d9f903bf8 100644 --- a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs +++ b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs @@ -254,15 +254,28 @@ private static async Task> { // check arena metadata from mimir var mimirClient = ApiClients.Instance.Mimir; - var mimirArenaBlockIndex = await MimirQuery.GetMetadataBlockIndexAsync(mimirClient, "arena"); - NcDebug.LogWarning($"mimirArenaBlockIndex: {mimirArenaBlockIndex}"); + var mimirArenaBlockIndex = await MimirQuery.GetMetadataBlockIndexAsync( + mimirClient, + "arena"); + NcDebug.Log($"[Arena]mimirArenaBlockIndex: {mimirArenaBlockIndex}"); - // get leaderboard from mimir - - // fallback to Headless - var response = await ApiClients.Instance.ArenaServiceClient.QueryArenaInfoAsync(currentAvatarAddr); - // Arrange my information so that it comes first when it's the same score. - arenaInfo = response.StateQuery.ArenaParticipants.ToList(); + const long confirmedBlockGap = 5; + if (_agent.BlockIndex <= mimirArenaBlockIndex + confirmedBlockGap) + { + // get leaderboard from mimir + arenaInfo = await MimirQuery.GetArenaParticipantsAsync( + mimirClient, + currentAvatarAddr); + NcDebug.Log($"[Arena]get participants from Mimir: block gap({_agent.BlockIndex - mimirArenaBlockIndex})"); + } + else + { + // fallback to Headless + var response = await ApiClients.Instance.ArenaServiceClient.QueryArenaInfoAsync(currentAvatarAddr); + // Arrange my information so that it comes first when it's the same score. + arenaInfo = response.StateQuery.ArenaParticipants.ToList(); + NcDebug.Log($"[Arena]get participants from Headless: block gap({_agent.BlockIndex - mimirArenaBlockIndex})"); + } } catch (Exception e) { From 13c66caae02d49dff8ef514e4dba0138bcc40cda Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Tue, 27 Aug 2024 21:26:20 +0900 Subject: [PATCH 07/12] logging elapsed --- .../Assets/_Scripts/State/RxProps.Arena.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs index 7d9f903bf8..49259cf4ed 100644 --- a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs +++ b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Bencodex.Types; @@ -15,6 +16,7 @@ using Nekoyume.Model.EnumType; using Nekoyume.Model.State; using Nekoyume.UI.Model; +using Random = UnityEngine.Random; namespace Nekoyume.State { @@ -260,21 +262,32 @@ private static async Task> NcDebug.Log($"[Arena]mimirArenaBlockIndex: {mimirArenaBlockIndex}"); const long confirmedBlockGap = 5; - if (_agent.BlockIndex <= mimirArenaBlockIndex + confirmedBlockGap) + if (new System.Random().Next(0, 2) == 0 && + _agent.BlockIndex <= mimirArenaBlockIndex + confirmedBlockGap) { + var sw = new Stopwatch(); + sw.Start(); // get leaderboard from mimir arenaInfo = await MimirQuery.GetArenaParticipantsAsync( mimirClient, currentAvatarAddr); - NcDebug.Log($"[Arena]get participants from Mimir: block gap({_agent.BlockIndex - mimirArenaBlockIndex})"); + sw.Stop(); + NcDebug.Log("[Arena]get participants from Mimir:" + + $" block gap({_agent.BlockIndex - mimirArenaBlockIndex})," + + $" elapsed({sw.Elapsed})"); } else { + var sw = new Stopwatch(); + sw.Start(); // fallback to Headless var response = await ApiClients.Instance.ArenaServiceClient.QueryArenaInfoAsync(currentAvatarAddr); // Arrange my information so that it comes first when it's the same score. arenaInfo = response.StateQuery.ArenaParticipants.ToList(); - NcDebug.Log($"[Arena]get participants from Headless: block gap({_agent.BlockIndex - mimirArenaBlockIndex})"); + sw.Stop(); + NcDebug.Log("[Arena]get participants from Headless:" + + $" block gap({_agent.BlockIndex - mimirArenaBlockIndex})," + + $" elapsed({sw.Elapsed})"); } } catch (Exception e) From 56376f9674fc8d753bcdddc7cdc01232bd512677 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Wed, 28 Aug 2024 16:57:11 +0900 Subject: [PATCH 08/12] handle exception and refactor --- .../Assets/_Scripts/State/RxProps.Arena.cs | 112 ++++++++++-------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs index 49259cf4ed..bc2f0faf1d 100644 --- a/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs +++ b/nekoyume/Assets/_Scripts/State/RxProps.Arena.cs @@ -252,54 +252,7 @@ private static async Task> ? new ArenaAvatarState(iValue2) : null; var lastBattleBlockIndex = arenaAvatarState?.LastBattleBlockIndex ?? 0L; - try - { - // check arena metadata from mimir - var mimirClient = ApiClients.Instance.Mimir; - var mimirArenaBlockIndex = await MimirQuery.GetMetadataBlockIndexAsync( - mimirClient, - "arena"); - NcDebug.Log($"[Arena]mimirArenaBlockIndex: {mimirArenaBlockIndex}"); - - const long confirmedBlockGap = 5; - if (new System.Random().Next(0, 2) == 0 && - _agent.BlockIndex <= mimirArenaBlockIndex + confirmedBlockGap) - { - var sw = new Stopwatch(); - sw.Start(); - // get leaderboard from mimir - arenaInfo = await MimirQuery.GetArenaParticipantsAsync( - mimirClient, - currentAvatarAddr); - sw.Stop(); - NcDebug.Log("[Arena]get participants from Mimir:" + - $" block gap({_agent.BlockIndex - mimirArenaBlockIndex})," + - $" elapsed({sw.Elapsed})"); - } - else - { - var sw = new Stopwatch(); - sw.Start(); - // fallback to Headless - var response = await ApiClients.Instance.ArenaServiceClient.QueryArenaInfoAsync(currentAvatarAddr); - // Arrange my information so that it comes first when it's the same score. - arenaInfo = response.StateQuery.ArenaParticipants.ToList(); - sw.Stop(); - NcDebug.Log("[Arena]get participants from Headless:" + - $" block gap({_agent.BlockIndex - mimirArenaBlockIndex})," + - $" elapsed({sw.Elapsed})"); - } - } - catch (Exception e) - { - NcDebug.LogException(e); - // TODO: this is temporary code for local testing. - arenaInfo.AddRange(_states.AvatarStates.Values.Select(avatar => new ArenaParticipantModel - { - AvatarAddr = avatar.address, - NameWithHash = avatar.NameWithHash - })); - } + arenaInfo = await GetArenaParticipantsAsync(currentAvatarAddr); string playerGuildName = null; if (Game.Game.instance.GuildModels.Any()) @@ -398,5 +351,68 @@ private static async UniTask SetArenaInfoOnMainThreadAsync(ArenaParticipantModel await UniTask.SwitchToMainThread(); _playerArenaInfo.SetValueAndForceNotify(playerArenaInfo); } + + private static async Task> GetArenaParticipantsAsync(Address avatarAddr) + { + var mimirClient = ApiClients.Instance.Mimir; + if (mimirClient is null) + { + return await GetFromHeadlessAsync(); + } + + try + { + const long confirmedBlockGap = 2; + var mimirArenaBlockIndex = await MimirQuery.GetMetadataBlockIndexAsync( + mimirClient, + "arena"); + if (_agent.BlockIndex > mimirArenaBlockIndex + confirmedBlockGap) + { + return await GetFromHeadlessAsync(); + } + + try + { + return await MimirQuery.GetArenaParticipantsAsync( + mimirClient, + avatarAddr); + } + catch (Exception e) + { + NcDebug.Log("Failed to get arena participants from Mimir. Falling back to headless." + + $" Exception: {e.Message}"); + return await GetFromHeadlessAsync(); + } + } + catch (Exception e) + { + NcDebug.LogException(e); + // TODO: this is temporary code for local testing. + var result = new List(); + result.AddRange(_states.AvatarStates.Values.Select(avatar => new ArenaParticipantModel + { + AvatarAddr = avatar.address, + NameWithHash = avatar.NameWithHash + })); + + return result; + } + + async Task> GetFromHeadlessAsync() + { + try + { + // fallback to Headless + var response = await ApiClients.Instance.ArenaServiceClient.QueryArenaInfoAsync(avatarAddr); + // Arrange my information so that it comes first when it's the same score. + return response.StateQuery.ArenaParticipants.ToList(); + } + catch (Exception e) + { + NcDebug.LogError($"[Arena]failed to get participants from Headless. {e.Message}"); + return new List(); + } + } + } } } From 23834152cf3dff613ccedd57a182b0941e211d49 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Wed, 28 Aug 2024 17:23:23 +0900 Subject: [PATCH 09/12] remove CommandLineOptions.MimirUrl --- .../Assets/_Scripts/Helper/CommandLineOptions.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs b/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs index 69cb7d4ba9..25fb15e9a4 100644 --- a/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs +++ b/nekoyume/Assets/_Scripts/Helper/CommandLineOptions.cs @@ -122,8 +122,6 @@ public class CommandLineOptions private bool _mixpanelDebugWarning; - private string _mimirUrl; - public bool Empty { get; private set; } = true; public string genesisBlockPath; @@ -626,17 +624,6 @@ public bool EnableGuestLogin Empty = false; } } - - [Option("mimir-url", Required = false, HelpText = "mimir url")] - public string MimirUrl - { - get => _mimirUrl; - set - { - _mimirUrl = value; - Empty = false; - } - } [Option("mixpanel-debug-error", Required = false, HelpText = "mixpanel debug error")] public bool MixpanelDebugError From 640fd982b4051ba59ebb438baee76dfd55c692d7 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Wed, 28 Aug 2024 17:24:02 +0900 Subject: [PATCH 10/12] add PlanetId.Is(planetName) extension method --- .../Extensions/PlanetIdExtensions.cs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/nekoyume/Assets/_Scripts/Multiplanetary/Extensions/PlanetIdExtensions.cs b/nekoyume/Assets/_Scripts/Multiplanetary/Extensions/PlanetIdExtensions.cs index e2e5f59cea..bf9b7cdee6 100644 --- a/nekoyume/Assets/_Scripts/Multiplanetary/Extensions/PlanetIdExtensions.cs +++ b/nekoyume/Assets/_Scripts/Multiplanetary/Extensions/PlanetIdExtensions.cs @@ -4,6 +4,22 @@ namespace Nekoyume.Multiplanetary.Extensions { public static class PlanetIdExtensions { + public static bool Is(this PlanetId planetId, string planeName) + { + planeName = planeName.ToLowerInvariant(); + if (planetId.Equals(PlanetId.Odin)) + { + return planeName == "odin"; + } + + if (planetId.Equals(PlanetId.Heimdall)) + { + return planeName == "heimdall"; + } + + return false; + } + public static string ToLocalizedPlanetName( this PlanetId planetId, bool containsPlanetId) From e82d2e49630accbeb92226624652795efa2044ca Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Wed, 28 Aug 2024 17:24:31 +0900 Subject: [PATCH 11/12] inject Game.CurrentPlanetId to ApiClients.Initialize() --- .../Assets/_Scripts/ApiClient/ApiClients.cs | 22 ++++++++++++------- .../Assets/_Scripts/Game/Scene/LoginScene.cs | 2 +- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs b/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs index d5fddee541..3cda209f43 100644 --- a/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs +++ b/nekoyume/Assets/_Scripts/ApiClient/ApiClients.cs @@ -2,6 +2,8 @@ using GraphQL.Client.Serializer.Newtonsoft; using Nekoyume.GraphQL; using Nekoyume.Helper; +using Nekoyume.Multiplanetary; +using Nekoyume.Multiplanetary.Extensions; using NineChronicles.ExternalServices.IAPService.Runtime; using NineChronicles.ExternalServices.IAPService.Runtime.Models; @@ -50,7 +52,7 @@ public void SetDccUrl() } // TODO: 중복코드 정리, 초기화 안 된 경우 로직 정리 - public void Initialize(CommandLineOptions clo) + public void Initialize(CommandLineOptions clo, PlanetId? planetId) { if (clo == null) { @@ -60,13 +62,17 @@ public void Initialize(CommandLineOptions clo) // NOTE: planetContext.CommandLineOptions and _commandLineOptions are same. // NOTE: Initialize several services after Agent initialized. - Mimir = string.IsNullOrEmpty(clo.MimirUrl) - ? new GraphQLHttpClient( - "https://mimir.nine-chronicles.dev/odin/graphql/", - new NewtonsoftJsonSerializer()) // Temporary - : new GraphQLHttpClient( - clo.MimirUrl, - new NewtonsoftJsonSerializer()); + Mimir = planetId.HasValue + ? planetId.Value.Is("odin") + ? new GraphQLHttpClient( + "https://mimir.nine-chronicles.dev/odin/graphql/", + new NewtonsoftJsonSerializer()) + : planetId.Value.Is("heimdall") + ? new GraphQLHttpClient( + "https://mimir.nine-chronicles.dev/heimdall/graphql/", + new NewtonsoftJsonSerializer()) + : null + : null; WorldBossClient = new NineChroniclesAPIClient(clo.ApiServerHost); RpcGraphQlClient = string.IsNullOrEmpty(clo.RpcServerHost) ? new NineChroniclesAPIClient(string.Empty) : diff --git a/nekoyume/Assets/_Scripts/Game/Scene/LoginScene.cs b/nekoyume/Assets/_Scripts/Game/Scene/LoginScene.cs index 16e2d2273f..b9b8500f0f 100644 --- a/nekoyume/Assets/_Scripts/Game/Scene/LoginScene.cs +++ b/nekoyume/Assets/_Scripts/Game/Scene/LoginScene.cs @@ -246,7 +246,7 @@ CommandLineOptions.PrivateKey is null } game.SetActionManager(); - ApiClients.Instance.Initialize(CommandLineOptions); + ApiClients.Instance.Initialize(CommandLineOptions, game.CurrentPlanetId); StartCoroutine(game.InitializeIAP()); From 6519ac5b9b42da2c6fa55b5ec12f3c94c836d374 Mon Sep 17 00:00:00 2001 From: Hyun Seungmin Date: Wed, 28 Aug 2024 17:24:51 +0900 Subject: [PATCH 12/12] add heimdall word --- nekoyume/nekoyume.sln.DotSettings | 1 + 1 file changed, 1 insertion(+) diff --git a/nekoyume/nekoyume.sln.DotSettings b/nekoyume/nekoyume.sln.DotSettings index b7375d2aab..2d6793bc3e 100644 --- a/nekoyume/nekoyume.sln.DotSettings +++ b/nekoyume/nekoyume.sln.DotSettings @@ -54,6 +54,7 @@ True True True + True True True True