diff --git a/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs b/Ryujinx.HLE/HOS/Services/Account/Acc/IAccountServiceForApplication.cs index 2fbf950c9..c29ed570c 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 2f35a8b87..18e371da5 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 eb2b03208..9b65e0f9e 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