From 3dcee8c437635802001099bd3a38eb23d83345a8 Mon Sep 17 00:00:00 2001 From: Ac_K Date: Wed, 24 Nov 2021 22:11:50 +0100 Subject: [PATCH] account/ns: Implement 13.0.0+ service calls (#2820) This PR implements/stubs some missing calls introduced in recent firmware (13.0.0). - `acc:u0 InitializeApplicationInfoV2` needed by ACNH. - `aoc:u NotifyMountAddOnContent/NotifyUnmountAddOnContent/CheckAddOnContentMountStatus` checked by RE. Needed by ACNH. - `IPurchaseEventManager PopPurchasedProductInfo` needed by Dying Light. Now ACNH 2.0 update is fully playable, and Dying Light can boot further: --- .../Acc/IAccountServiceForApplication.cs | 1 + .../Services/Ns/Aoc/IAddOnContentManager.cs | 49 +++++++++++++++++++ .../Services/Ns/Aoc/IPurchaseEventManager.cs | 19 ++++++- 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs index 2fbf950c..c29ed570 100644 --- a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs +++ b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs @@ -81,6 +81,7 @@ namespace Ryujinx.HLE.HOS.Services.Account.Acc [CommandHipc(100)] [CommandHipc(140)] // 6.0.0+ + [CommandHipc(160)] // 13.0.0+ // InitializeApplicationInfo(u64 pid_placeholder, pid) public ResultCode InitializeApplicationInfo(ServiceCtx context) { diff --git a/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs b/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs index 2f35a8b8..18e371da 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/Aoc/IAddOnContentManager.cs @@ -15,6 +15,8 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc private ulong _addOnContentBaseId; + private List _mountedAocTitleIds = new List(); + public IAddOnContentManager(ServiceCtx context) { _addOnContentListChangedEvent = new KEvent(context.Device.System.KernelContext); @@ -136,6 +138,53 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc return GetAddOnContentListChangedEventImpl(context); } + [CommandHipc(11)] // 13.0.0+ + // NotifyMountAddOnContent(pid, u64 title_id) + public ResultCode NotifyMountAddOnContent(ServiceCtx context) + { + long pid = context.Request.HandleDesc.PId; + + // NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId. + + ulong aocTitleId = context.RequestData.ReadUInt64(); + + if (_mountedAocTitleIds.Count <= 0x7F) + { + _mountedAocTitleIds.Add(aocTitleId); + } + + return ResultCode.Success; + } + + [CommandHipc(12)] // 13.0.0+ + // NotifyUnmountAddOnContent(pid, u64 title_id) + public ResultCode NotifyUnmountAddOnContent(ServiceCtx context) + { + long pid = context.Request.HandleDesc.PId; + + // NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId. + + ulong aocTitleId = context.RequestData.ReadUInt64(); + + _mountedAocTitleIds.Remove(aocTitleId); + + return ResultCode.Success; + } + + [CommandHipc(50)] // 13.0.0+ + // CheckAddOnContentMountStatus(pid) + public ResultCode CheckAddOnContentMountStatus(ServiceCtx context) + { + long pid = context.Request.HandleDesc.PId; + + // NOTE: Service call arp:r GetApplicationLaunchProperty to get TitleId using the PId. + // Then it does some internal checks and returns InvalidBufferSize if they fail. + + Logger.Stub?.PrintStub(LogClass.ServiceNs); + + return ResultCode.Success; + } + [CommandHipc(100)] // 7.0.0+ // CreateEcPurchasedEventManager() -> object public ResultCode CreateEcPurchasedEventManager(ServiceCtx context) diff --git a/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs b/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs index eb2b0320..9b65e0f9 100644 --- a/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs +++ b/Ryujinx.HLE/HOS/Services/Ns/Aoc/IPurchaseEventManager.cs @@ -25,7 +25,7 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc context.Memory.Read(inBufferPosition, buffer); - // NOTE: Service use the pid to call arp:r GetApplicationLaunchProperty and store it in internal field. + // NOTE: Service uses the pid to call arp:r GetApplicationLaunchProperty and store it in internal field. // Then it seems to use the buffer content and compare it with a stored linked instrusive list. // Since we don't support purchase from eShop, we can stub it. @@ -47,5 +47,22 @@ namespace Ryujinx.HLE.HOS.Services.Ns.Aoc return ResultCode.Success; } + + [CommandHipc(3)] + // PopPurchasedProductInfo(nn::ec::detail::PurchasedProductInfo) + public ResultCode PopPurchasedProductInfo(ServiceCtx context) + { + byte[] purchasedProductInfo = new byte[0x80]; + + context.ResponseData.Write(purchasedProductInfo); + + // NOTE: Service finds info using internal array then convert it into nn::ec::detail::PurchasedProductInfo. + // Returns 0x320A4 if the internal array size is null. + // Since we don't support purchase from eShop, we can stub it. + + Logger.Debug?.PrintStub(LogClass.ServiceNs); // NOTE: Uses Debug to avoid spamming. + + return ResultCode.Success; + } } } \ No newline at end of file