From f6a7309b1459ddd0e48c726e79783d8dc7e07e3a Mon Sep 17 00:00:00 2001 From: Mary Date: Tue, 30 Aug 2022 20:52:45 +0200 Subject: [PATCH] account: Implement LoadNetworkServiceLicenseKindAsync This is needed to run Pokemon Legends Arceus 1.1.1 with guest internet enabled. The game still get stuck at loading screen. --- .../AccountService/IManagerForApplication.cs | 14 +++++++ .../Acc/AccountService/ManagerServer.cs | 17 +++++++++ .../HOS/Services/Account/Acc/IAsyncContext.cs | 2 +- .../IAsyncNetworkServiceLicenseKindContext.cs | 38 +++++++++++++++++++ .../Acc/Types/NetworkServiceLicenseKind.cs | 8 ++++ .../HOS/Services/Account/ResultCode.cs | 25 ++++++------ 6 files changed, 91 insertions(+), 13 deletions(-) create mode 100644 Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs create mode 100644 Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs index 62cf79b79b..68ed3f50a0 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/IManagerForApplication.cs @@ -57,5 +57,19 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService { return _managerServer.StoreOpenContext(context); } + + [CommandHipc(170)] // 6.0.0+ + // LoadNetworkServiceLicenseKindAsync() -> object + public ResultCode LoadNetworkServiceLicenseKindAsync(ServiceCtx context) + { + ResultCode resultCode = _managerServer.LoadNetworkServiceLicenseKindAsync(context, out IAsyncNetworkServiceLicenseKindContext asyncContext); + + if (resultCode == ResultCode.Success) + { + MakeObject(context, asyncContext); + } + + return resultCode; + } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs index 9c406a08f6..d74f5ecf2e 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/AccountService/ManagerServer.cs @@ -166,5 +166,22 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService return ResultCode.Success; } + + public ResultCode LoadNetworkServiceLicenseKindAsync(ServiceCtx context, out IAsyncNetworkServiceLicenseKindContext asyncContext) + { + KEvent asyncEvent = new KEvent(context.Device.System.KernelContext); + AsyncExecution asyncExecution = new AsyncExecution(asyncEvent); + + Logger.Stub?.PrintStub(LogClass.ServiceAcc); + + // NOTE: This is an extension of the data retrieved from the id token cache. + asyncExecution.Initialize(1000, EnsureIdTokenCacheAsyncImpl); + + asyncContext = new IAsyncNetworkServiceLicenseKindContext(asyncExecution, NetworkServiceLicenseKind.Subscribed); + + // return ResultCode.NullObject if the IAsyncNetworkServiceLicenseKindContext pointer is null. Doesn't occur in our case. + + return ResultCode.Success; + } } } \ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs index 06037f9e6b..9c7cb2e026 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncContext.cs @@ -7,7 +7,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc { class IAsyncContext : IpcService { - AsyncExecution _asyncExecution; + protected AsyncExecution _asyncExecution; public IAsyncContext(AsyncExecution asyncExecution) { diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs new file mode 100644 index 0000000000..6aab85fb2c --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/IAsyncNetworkServiceLicenseKindContext.cs @@ -0,0 +1,38 @@ +using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; + +namespace Ryujinx.HLE.HOS.Services.Account.Acc +{ + class IAsyncNetworkServiceLicenseKindContext : IAsyncContext + { + private NetworkServiceLicenseKind? _serviceLicenseKind; + + public IAsyncNetworkServiceLicenseKindContext(AsyncExecution asyncExecution, NetworkServiceLicenseKind? serviceLicenseKind) : base(asyncExecution) + { + _serviceLicenseKind = serviceLicenseKind; + } + + [CommandHipc(100)] + // GetNetworkServiceLicenseKind() -> nn::account::NetworkServiceLicenseKind + public ResultCode GetNetworkServiceLicenseKind(ServiceCtx context) + { + if (!_asyncExecution.IsInitialized) + { + return ResultCode.AsyncExecutionNotInitialized; + } + + if (!_asyncExecution.SystemEvent.ReadableEvent.IsSignaled()) + { + return ResultCode.Unknown41; + } + + if (!_serviceLicenseKind.HasValue) + { + return ResultCode.MissingNetworkServiceLicenseKind; + } + + context.ResponseData.Write((uint)_serviceLicenseKind.Value); + + return ResultCode.Success; + } + } +} diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs new file mode 100644 index 0000000000..a33e26707c --- /dev/null +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/Types/NetworkServiceLicenseKind.cs @@ -0,0 +1,8 @@ +namespace Ryujinx.HLE.HOS.Services.Account.Acc +{ + enum NetworkServiceLicenseKind : uint + { + NoSubscription, + Subscribed + } +} diff --git a/Ryujinx.HLE/HOS/Services/Account/ResultCode.cs b/Ryujinx.HLE/HOS/Services/Account/ResultCode.cs index 7c23a8b628..34114ec9f5 100644 --- a/Ryujinx.HLE/HOS/Services/Account/ResultCode.cs +++ b/Ryujinx.HLE/HOS/Services/Account/ResultCode.cs @@ -7,17 +7,18 @@ namespace Ryujinx.HLE.HOS.Services.Account Success = 0, - NullArgument = (20 << ErrorCodeShift) | ModuleId, - InvalidArgument = (22 << ErrorCodeShift) | ModuleId, - NullInputBuffer = (30 << ErrorCodeShift) | ModuleId, - InvalidBufferSize = (31 << ErrorCodeShift) | ModuleId, - InvalidBuffer = (32 << ErrorCodeShift) | ModuleId, - AsyncExecutionNotInitialized = (40 << ErrorCodeShift) | ModuleId, - Unknown41 = (41 << ErrorCodeShift) | ModuleId, - InternetRequestDenied = (59 << ErrorCodeShift) | ModuleId, - UserNotFound = (100 << ErrorCodeShift) | ModuleId, - NullObject = (302 << ErrorCodeShift) | ModuleId, - Unknown341 = (341 << ErrorCodeShift) | ModuleId, - InvalidIdTokenCacheBufferSize = (451 << ErrorCodeShift) | ModuleId + NullArgument = (20 << ErrorCodeShift) | ModuleId, + InvalidArgument = (22 << ErrorCodeShift) | ModuleId, + NullInputBuffer = (30 << ErrorCodeShift) | ModuleId, + InvalidBufferSize = (31 << ErrorCodeShift) | ModuleId, + InvalidBuffer = (32 << ErrorCodeShift) | ModuleId, + AsyncExecutionNotInitialized = (40 << ErrorCodeShift) | ModuleId, + Unknown41 = (41 << ErrorCodeShift) | ModuleId, + InternetRequestDenied = (59 << ErrorCodeShift) | ModuleId, + UserNotFound = (100 << ErrorCodeShift) | ModuleId, + NullObject = (302 << ErrorCodeShift) | ModuleId, + Unknown341 = (341 << ErrorCodeShift) | ModuleId, + MissingNetworkServiceLicenseKind = (400 << ErrorCodeShift) | ModuleId, + InvalidIdTokenCacheBufferSize = (451 << ErrorCodeShift) | ModuleId } }