using Ryujinx.Common.Logging; using Ryujinx.Cpu; using Ryujinx.HLE.HOS.Kernel.Threading; using Ryujinx.HLE.HOS.Services.Account.Acc.AsyncContext; using System.Threading; using System.Threading.Tasks; namespace Ryujinx.HLE.HOS.Services.Account.Acc.AccountService { class ManagerServer { // TODO: Determine where and how NetworkServiceAccountId is set. private const long NetworkServiceAccountId = 0xcafe; private UserId _userId; public ManagerServer(UserId userId) { _userId = userId; } public ResultCode CheckAvailability(ServiceCtx context) { // NOTE: This opens the file at "su/baas/USERID_IN_UUID_STRING.dat" where USERID_IN_UUID_STRING is formatted as "%08x-%04x-%04x-%02x%02x-%08x%04x". // Then it searches the Availability of Online Services related to the UserId in this file and returns it. Logger.Stub?.PrintStub(LogClass.ServiceAcc); // NOTE: Even if we try to return different error codes here, the guest still needs other calls. return ResultCode.Success; } public ResultCode GetAccountId(ServiceCtx context) { // NOTE: This opens the file at "su/baas/USERID_IN_UUID_STRING.dat" (where USERID_IN_UUID_STRING is formatted // as "%08x-%04x-%04x-%02x%02x-%08x%04x") in the account:/ savedata. // Then it searches the NetworkServiceAccountId related to the UserId in this file and returns it. Logger.Stub?.PrintStub(LogClass.ServiceAcc, new { NetworkServiceAccountId }); context.ResponseData.Write(NetworkServiceAccountId); return ResultCode.Success; } public ResultCode EnsureIdTokenCacheAsync(ServiceCtx context, out IAsyncContext asyncContext) { KEvent asyncEvent = new KEvent(context.Device.System.KernelContext); AsyncExecution asyncExecution = new AsyncExecution(asyncEvent); asyncExecution.Initialize(1000, EnsureIdTokenCacheAsyncImpl); asyncContext = new IAsyncContext(asyncExecution); // return ResultCode.NullObject if the IAsyncContext pointer is null. Doesn't occur in our case. return ResultCode.Success; } private async Task EnsureIdTokenCacheAsyncImpl(CancellationToken token) { // NOTE: This open the file at "su/baas/USERID_IN_UUID_STRING.dat" (where USERID_IN_UUID_STRING is formatted as "%08x-%04x-%04x-%02x%02x-%08x%04x") // in the "account:/" savedata. // Then its read data, use dauth API with this data to get the Token Id and probably store the dauth response // in "su/cache/USERID_IN_UUID_STRING.dat" (where USERID_IN_UUID_STRING is formatted as "%08x-%04x-%04x-%02x%02x-%08x%04x") in the "account:/" savedata. // Since we don't support online services, we can stub it. Logger.Stub?.PrintStub(LogClass.ServiceAcc); // TODO: Use a real function instead, with the CancellationToken. await Task.CompletedTask; } public ResultCode LoadIdTokenCache(ServiceCtx context) { long bufferPosition = context.Request.ReceiveBuff[0].Position; long bufferSize = context.Request.ReceiveBuff[0].Size; // NOTE: This opens the file at "su/cache/USERID_IN_UUID_STRING.dat" (where USERID_IN_UUID_STRING is formatted as "%08x-%04x-%04x-%02x%02x-%08x%04x") // in the "account:/" savedata and writes some data in the buffer. // Since we don't support online services, we can stub it. Logger.Stub?.PrintStub(LogClass.ServiceAcc); /* if (internal_object != null) { if (bufferSize > 0xC00) { return ResultCode.InvalidIdTokenCacheBufferSize; } } */ int idTokenCacheSize = 0; MemoryHelper.FillWithZeros(context.Memory, bufferPosition, (int)bufferSize); context.ResponseData.Write(idTokenCacheSize); return ResultCode.Success; } public ResultCode GetNintendoAccountUserResourceCacheForApplication(ServiceCtx context) { Logger.Stub?.PrintStub(LogClass.ServiceAcc, new { NetworkServiceAccountId }); context.ResponseData.Write(NetworkServiceAccountId); // TODO: determine and fill the output IPC buffer. return ResultCode.Success; } public ResultCode StoreOpenContext(ServiceCtx context) { Logger.Stub?.PrintStub(LogClass.ServiceAcc); return ResultCode.Success; } } }