Cemu/src/Cafe/OS/libs/nn_act/nn_act.cpp

751 lines
24 KiB
C++

#include "Cafe/OS/common/OSCommon.h"
#include "Cafe/OS/libs/coreinit/coreinit_IOS.h"
#include "Cafe/IOSU/legacy/iosu_act.h"
#include "Cafe/IOSU/legacy/iosu_ioctl.h"
#include "nn_act.h"
#include "Cafe/OS/libs/nn_common.h"
#include "Cafe/CafeSystem.h"
sint32 numAccounts = 1;
#define actPrepareRequest() \
StackAllocator<iosuActCemuRequest_t> _buf_actRequest; \
StackAllocator<ioBufferVector_t> _buf_bufferVector; \
iosuActCemuRequest_t* actRequest = _buf_actRequest.GetPointer(); \
ioBufferVector_t* actBufferVector = _buf_bufferVector.GetPointer(); \
memset(actRequest, 0, sizeof(iosuActCemuRequest_t)); \
memset(actBufferVector, 0, sizeof(ioBufferVector_t)); \
actBufferVector->buffer = (uint8*)actRequest;
#define actPrepareRequest2() \
StackAllocator<iosuActCemuRequest_t> _buf_actRequest; \
iosuActCemuRequest_t* actRequest = _buf_actRequest.GetPointer(); \
memset(actRequest, 0, sizeof(iosuActCemuRequest_t));
uint32 getNNReturnCode(uint32 iosError, iosuActCemuRequest_t* actRequest)
{
if ((iosError & 0x80000000) != 0)
return iosError;
return actRequest->returnCode;
}
uint32 _doCemuActRequest(iosuActCemuRequest_t* actRequest)
{
StackAllocator<ioBufferVector_t> _buf_bufferVector;
ioBufferVector_t* actBufferVector = _buf_bufferVector.GetPointer();
memset(actBufferVector, 0, sizeof(ioBufferVector_t));
actBufferVector->buffer = (uint8*)actRequest;
uint32 ioctlResult = __depr__IOS_Ioctlv(IOS_DEVICE_ACT, IOSU_ACT_REQUEST_CEMU, 1, 1, actBufferVector);
return getNNReturnCode(ioctlResult, actRequest);
}
namespace nn
{
namespace act
{
uint32 GetPersistentIdEx(uint8 slot)
{
actPrepareRequest();
actRequest->requestCode = IOSU_ARC_PERSISTENTID;
actRequest->accountSlot = slot;
__depr__IOS_Ioctlv(IOS_DEVICE_ACT, IOSU_ACT_REQUEST_CEMU, 1, 1, actBufferVector);
return actRequest->resultU32.u32;
}
uint32 GetMiiEx(void* miiData, uint8 slot)
{
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_MIIDATA;
actRequest->accountSlot = slot;
uint32 result = _doCemuActRequest(actRequest);
memcpy(miiData, actRequest->resultBinary.binBuffer, MII_FFL_STORAGE_SIZE);
return result;
}
uint32 GetUuidEx(uint8* uuid, uint8 slot, sint32 name)
{
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_UUID;
actRequest->accountSlot = slot;
actRequest->uuidName = name;
uint32 result = _doCemuActRequest(actRequest);
memcpy(uuid, actRequest->resultBinary.binBuffer, 16);
return result;
}
uint32 GetSimpleAddressIdEx(uint32be* simpleAddressId, uint8 slot)
{
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_SIMPLEADDRESS;
actRequest->accountSlot = slot;
uint32 result = _doCemuActRequest(actRequest);
*simpleAddressId = actRequest->resultU32.u32;
return result;
}
uint32 GetTransferableIdEx(uint64* transferableId, uint32 unique, uint8 slot)
{
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_TRANSFERABLEID;
actRequest->accountSlot = slot;
actRequest->unique = unique;
uint32 result = _doCemuActRequest(actRequest);
*transferableId = _swapEndianU64(actRequest->resultU64.u64);
return result;
}
uint32 AcquireIndependentServiceToken(independentServiceToken_t* token, const char* clientId, uint32 cacheDurationInSeconds)
{
memset(token, 0, sizeof(independentServiceToken_t));
actPrepareRequest();
actRequest->requestCode = IOSU_ARC_ACQUIREINDEPENDENTTOKEN;
actRequest->titleId = CafeSystem::GetForegroundTitleId();
actRequest->titleVersion = CafeSystem::GetForegroundTitleVersion();
actRequest->expiresIn = cacheDurationInSeconds;
strcpy(actRequest->clientId, clientId);
uint32 resultCode = __depr__IOS_Ioctlv(IOS_DEVICE_ACT, IOSU_ACT_REQUEST_CEMU, 1, 1, actBufferVector);
memcpy(token, actRequest->resultBinary.binBuffer, sizeof(independentServiceToken_t));
return getNNReturnCode(resultCode, actRequest);
}
sint64 GetUtcOffset()
{
return ((ppcCyclesSince2000 / ESPRESSO_CORE_CLOCK) - (ppcCyclesSince2000_UTC / ESPRESSO_CORE_CLOCK)) * 1'000'000;
}
sint32 GetUtcOffsetEx(sint64be* pOutOffset, uint8 slotNo)
{
if (!pOutOffset)
return 0xc0712c80;
*pOutOffset = GetUtcOffset();
return 0;
}
sint32 g_initializeCount = 0; // inc in Initialize and dec in Finalize
uint32 Initialize()
{
// usually uses a mutex which is initialized in -> global constructor keyed to'_17_act_shim_util_cpp
if (g_initializeCount == 0)
{
actPrepareRequest();
actRequest->requestCode = IOSU_ARC_INIT;
__depr__IOS_Ioctlv(IOS_DEVICE_ACT, IOSU_ACT_REQUEST_CEMU, 1, 1, actBufferVector);
}
g_initializeCount++;
return 0;
}
NN_ERROR_CODE GetErrorCode(betype<nnResult>* nnResult)
{
NN_ERROR_CODE errCode = NNResultToErrorCode(*nnResult, NN_RESULT_MODULE_NN_ACT);
return errCode;
}
}
}
void nnActExport_CreateConsoleAccount(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "CreateConsoleAccount(...)");
//numAccounts++;
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_GetNumOfAccounts(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetNumOfAccounts()");
osLib_returnFromFunction(hCPU, numAccounts); // account count
}
void nnActExport_IsSlotOccupied(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.IsSlotOccupied({})", hCPU->gpr[3]);
ppcDefineParamU8(slot, 0);
osLib_returnFromFunction(hCPU, nn::act::GetPersistentIdEx(slot) != 0 ? 1 : 0);
}
uint32 GetAccountIdEx(char* accountId, uint8 slot)
{
// returns zero for non-network accounts?
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_ACCOUNT_ID;
actRequest->accountSlot = slot;
uint32 result = _doCemuActRequest(actRequest);
strcpy(accountId, actRequest->resultString.strBuffer);
return result;
}
uint32 GetPrincipalIdEx(uint32be* principalId, uint8 slot)
{
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_PRINCIPALID;
actRequest->accountSlot = slot;
uint32 result = _doCemuActRequest(actRequest);
*principalId = actRequest->resultU32.u32;
return result;
}
uint32 GetCountryEx(char* country, uint8 slot)
{
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_COUNTRY;
actRequest->accountSlot = slot;
uint32 result = _doCemuActRequest(actRequest);
strcpy(country, actRequest->resultString.strBuffer);
return result;
}
uint32 IsNetworkAccount(uint8* isNetworkAccount, uint8 slot)
{
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_ISNETWORKACCOUNT;
actRequest->accountSlot = slot;
uint32 result = _doCemuActRequest(actRequest);
*isNetworkAccount = (actRequest->resultU32.u32 != 0) ? 1 : 0;
return result;
}
void nnActExport_IsNetworkAccount(PPCInterpreter_t* hCPU)
{
//cemuLog_logDebug(LogType::Force, "nn_act.IsNetworkAccount()");
uint8 isNetAcc = 0;
IsNetworkAccount(&isNetAcc, 0xFE);
osLib_returnFromFunction(hCPU, isNetAcc);
}
void nnActExport_IsNetworkAccountEx(PPCInterpreter_t* hCPU)
{
ppcDefineParamU8(slot, 0);
cemuLog_logDebug(LogType::Force, "nn_act.IsNetworkAccountEx({})", slot);
uint8 isNetAcc = 0;
IsNetworkAccount(&isNetAcc, slot);
osLib_returnFromFunction(hCPU, isNetAcc);
}
void nnActExport_GetSimpleAddressId(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetSimpleAddressId()");
uint32be simpleAddressId;
nn::act::GetSimpleAddressIdEx(&simpleAddressId, iosu::act::ACT_SLOT_CURRENT);
osLib_returnFromFunction(hCPU, (uint32)simpleAddressId);
}
void nnActExport_GetSimpleAddressIdEx(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetSimpleAddressIdEx(0x{:08x}, {})", hCPU->gpr[3], hCPU->gpr[4] & 0xFF);
ppcDefineParamU32BEPtr(simpleAddressId, 0);
ppcDefineParamU8(slot, 1);
nn::act::GetSimpleAddressIdEx(simpleAddressId, slot);
osLib_returnFromFunction(hCPU, 0); // ResultSuccess
}
void nnActExport_GetPrincipalId(PPCInterpreter_t* hCPU)
{
// return error for non-nnid accounts?
cemuLog_logDebug(LogType::Force, "nn_act.GetPrincipalId()");
uint32be principalId;
GetPrincipalIdEx(&principalId, iosu::act::ACT_SLOT_CURRENT);
osLib_returnFromFunction(hCPU, (uint32)principalId);
}
void nnActExport_GetPrincipalIdEx(PPCInterpreter_t* hCPU)
{
// return error for non-nnid accounts?
cemuLog_logDebug(LogType::Force, "nn_act.GetPrincipalIdEx(0x{:08x}, {})", hCPU->gpr[3], hCPU->gpr[4]&0xFF);
ppcDefineParamU32BEPtr(principalId, 0);
ppcDefineParamU8(slot, 1);
GetPrincipalIdEx(principalId, slot);
osLib_returnFromFunction(hCPU, 0); // ResultSuccess
}
void nnActExport_GetTransferableIdEx(PPCInterpreter_t* hCPU)
{
ppcDefineParamStructPtr(transferableId, uint64, 0);
ppcDefineParamU32(unique, 1);
ppcDefineParamU8(slot, 2);
cemuLog_logDebug(LogType::Force, "nn_act.GetTransferableIdEx(0x{:08x}, 0x{:08x}, {})", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5] & 0xFF);
uint32 r = nn::act::GetTransferableIdEx(transferableId, unique, slot);
osLib_returnFromFunction(hCPU, 0); // ResultSuccess
}
void nnActExport_GetPersistentId(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetPersistentId()");
uint32 persistentId = nn::act::GetPersistentIdEx(iosu::act::ACT_SLOT_CURRENT);
osLib_returnFromFunction(hCPU, persistentId);
}
void nnActExport_GetPersistentIdEx(PPCInterpreter_t* hCPU)
{
ppcDefineParamU8(slot, 0);
cemuLog_logDebug(LogType::Force, "nn_act.GetPersistentIdEx({})", slot);
uint32 persistentId = nn::act::GetPersistentIdEx(slot);
osLib_returnFromFunction(hCPU, persistentId);
}
void nnActExport_GetCountry(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetCountry(0x{:08x})", hCPU->gpr[3]);
ppcDefineParamStr(country, 0);
uint32 r = GetCountryEx(country, iosu::act::ACT_SLOT_CURRENT);
osLib_returnFromFunction(hCPU, r);
}
bool g_isParentalControlCheckEnabled = false;
void nnActExport_EnableParentalControlCheck(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.EnableParentalControlCheck({})", hCPU->gpr[3]);
ppcDefineParamU8(isEnabled, 0);
g_isParentalControlCheckEnabled = isEnabled != 0;
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_IsParentalControlCheckEnabled(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.IsParentalControlCheckEnabled() -> {}", g_isParentalControlCheckEnabled);
osLib_returnFromFunction(hCPU, g_isParentalControlCheckEnabled);
}
void nnActExport_GetHostServerSettings(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "GetHostServerSettings() - stub");
ppcDefineParamStr(ukn, 1);
strcpy(ukn, "");
osLib_returnFromFunction(hCPU, 0x00000000);
}
void nnActExport_GetMii(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetMii(...)");
ppcDefineParamUStr(miiData, 0);
uint32 r = nn::act::GetMiiEx(miiData, iosu::act::ACT_SLOT_CURRENT);
osLib_returnFromFunction(hCPU, r);
}
void nnActExport_GetMiiEx(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetMiiEx(...)");
ppcDefineParamUStr(miiData, 0);
ppcDefineParamU8(slot, 1);
uint32 r = nn::act::GetMiiEx(miiData, slot);
osLib_returnFromFunction(hCPU, r);
}
void nnActExport_GetMiiImageEx(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "GetMiiImageEx unimplemented");
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_GetMiiName(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "GetMiiName(0x{:08x})", hCPU->gpr[3]);
ppcDefineParamWStrBE(miiName, 0);
StackAllocator<FFLData_t> miiData;
uint32 r = nn::act::GetMiiEx(miiData, iosu::act::ACT_SLOT_CURRENT);
// extract name
sint32 miiNameLength = 0;
for (sint32 i = 0; i < MII_FFL_NAME_LENGTH; i++)
{
miiName[i] = miiData->miiName[i];
if (miiData->miiName[i] == (const uint16be)'\0')
break;
miiNameLength = i+1;
}
miiName[miiNameLength] = '\0';
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_GetMiiNameEx(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "GetMiiNameEx(0x{:08x}, {})", hCPU->gpr[3], hCPU->gpr[4] & 0xFF);
ppcDefineParamWStrBE(miiName, 0);
ppcDefineParamU8(slot, 1);
StackAllocator<FFLData_t> miiData;
uint32 r = nn::act::GetMiiEx(miiData, slot);
// extract name
sint32 miiNameLength = 0;
for (sint32 i = 0; i < MII_FFL_NAME_LENGTH; i++)
{
miiName[i] = miiData->miiName[i];
if (miiData->miiName[i] == (const uint16be)'\0')
break;
miiNameLength = i + 1;
}
miiName[miiNameLength] = '\0';
osLib_returnFromFunction(hCPU, 0);
}
typedef struct
{
uint32be ukn00;
uint32be ukn04; // transferable id high?
uint32be accountTransferableIdLow; //
uint32be ukn0C;
uint32be ukn10;
uint32be ukn14;
uint32be ukn18;
uint32be ukn1C;
uint32be ukn20;
uint32be ukn24;
uint32be ukn28;
uint32be ukn2C;
uint32be ukn30;
uint32be ukn34;
uint32be ukn38;
uint32be ukn3C;
uint32be ukn40;
uint32be ukn44;
uint32be ukn48;
uint32be ukn4C;
uint32be ukn50;
uint32be ukn54;
uint32be tlsModuleIndex;
uint32be ukn5C;
}FFLStoreDataDepr_t;
static_assert(sizeof(FFLStoreDataDepr_t) == 96);
void nnActExport_UpdateMii(PPCInterpreter_t* hCPU)
{
if (sizeof(FFLStoreDataDepr_t) != MII_FFL_STORAGE_SIZE)
assert_dbg();
ppcDefineParamU8(slot, 0);
ppcDefineParamStructPtr(fflStoreData, FFLStoreDataDepr_t, 1);
ppcDefineParamStructPtr(uknName, uint16, 2); // mii name
ppcDefineParamStructPtr(uknNameR6, uint8, 3);
ppcDefineParamStructPtr(uknNameR7, uint8, 4);
ppcDefineParamStructPtr(uknNameR8, uint8, 5);
ppcDefineParamStructPtr(uknNameR9, uint8, 6);
ppcDefineParamStructPtr(uknNameR10, uint8, 7);
ppcDefineParamStructPtr(uknNameSP4, uint8, 8);
cemu_assert_unimplemented();
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_GetUuid(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetUuid(0x{:08x})", hCPU->gpr[3]);
ppcDefineParamUStr(uuid, 0);
nn::act::GetUuidEx(uuid, iosu::act::ACT_SLOT_CURRENT);
osLib_returnFromFunction(hCPU, 0); // 0 -> result ok
}
void nnActExport_GetUuidEx(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetUuidEx(0x{:08x},0x{:02x})", hCPU->gpr[3], hCPU->gpr[3]&0xFF);
ppcDefineParamUStr(uuid, 0);
ppcDefineParamU8(slot, 1);
nn::act::GetUuidEx(uuid, slot);
osLib_returnFromFunction(hCPU, 0); // 0 -> result ok
}
void nnActExport_GetUuidEx2(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetUuidEx(0x{:08x},0x{:02x},0x{:08x})", hCPU->gpr[3], hCPU->gpr[4], hCPU->gpr[5]);
ppcDefineParamUStr(uuid, 0);
ppcDefineParamU8(slot, 1);
ppcDefineParamS32(name, 2);
nn::act::GetUuidEx(uuid, iosu::act::ACT_SLOT_CURRENT, name);
osLib_returnFromFunction(hCPU, 0); // 0 -> result ok
}
void nnActExport_GetAccountId(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetAccountId(0x{:08x})", hCPU->gpr[3]);
ppcDefineParamUStr(accId, 0);
GetAccountIdEx((char*)accId, iosu::act::ACT_SLOT_CURRENT);
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_GetAccountIdEx(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetAccountIdEx(0x{:08x}, 0x{:02x})", hCPU->gpr[3], hCPU->gpr[3] & 0xFF);
ppcDefineParamUStr(accId, 0);
ppcDefineParamU8(slot, 1);
GetAccountIdEx((char*)accId, slot);
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_GetParentalControlSlotNoEx(PPCInterpreter_t* hCPU)
{
// GetParentalControlSlotNoEx(uint8* output, uint8 slot)
cemuLog_logDebug(LogType::Force, "nn_act.GetParentalControlSlotNoEx(0x{:08x}, 0x{:02x})", hCPU->gpr[3], hCPU->gpr[4]);
//memory_writeU8(hCPU->gpr[3], 0x01); // returned slot no (slot indices start at 1)
memory_writeU8(hCPU->gpr[3], 1); // 0 -> No parental control for slot?
//memory_writeU8(hCPU->gpr[3], 0); // 0 -> No parental control for slot?
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_GetDefaultAccount(PPCInterpreter_t* hCPU)
{
// todo
cemuLog_logDebug(LogType::Force, "GetDefaultAccount(): Return 1?");
osLib_returnFromFunction(hCPU, 1);
}
void nnActExport_GetSlotNo(PPCInterpreter_t* hCPU)
{
// id of active account
// uint8 GetSlotNo(void);
cemuLog_logDebug(LogType::Force, "nn_act.GetSlotNo()");
osLib_returnFromFunction(hCPU, 1); // 1 is the first slot (0 is invalid)
}
void nnActExport_GetSlotNoEx(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.GetSlotNoEx(...)");
// get slot no by uuid
ppcDefineParamUStr(uuid, 0);
// get slot no for a specific uuid
for (uint8 i = 1; i < 12; i++)
{
uint8 accUuid[16]{};
nn::act::GetUuidEx(accUuid, i);
if (memcmp(uuid, accUuid, 16) == 0)
{
osLib_returnFromFunction(hCPU, i);
return;
}
}
cemu_assert_debug(false); // suspicious behavior?
osLib_returnFromFunction(hCPU, 0); // account not found
}
void nnActExport_Initialize(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "nn_act.Initialize()");
nn::act::Initialize();
osLib_returnFromFunction(hCPU, 0);
}
void nnActExport_HasNfsAccount(PPCInterpreter_t* hCPU)
{
cemuLog_logDebug(LogType::Force, "Called nn_act.HasNfsAccount");
osLib_returnFromFunction(hCPU, 1); // Nfs = Nintendo Friend System? (Splatoon tries to call nn_fp.RegisterAccount if we set this to false)
}
typedef struct
{
/* +0x000 */ char token[0x201]; // /nex_token/token
/* +0x201 */ uint8 padding201[3];
/* +0x204 */ char nexPassword[0x41]; // /nex_token/nex_password
/* +0x245 */ uint8 padding245[3];
/* +0x248 */ char host[0x10]; // /nex_token/host
/* +0x258 */ uint16be port; // /nex_token/port
/* +0x25A */ uint16be padding25A;
}nexServiceToken_t;
static_assert(sizeof(nexServiceToken_t) == 0x25C, "nexServiceToken_t has invalid size");
void nnActExport_AcquireNexServiceToken(PPCInterpreter_t* hCPU)
{
ppcDefineParamStructPtr(token, nexServiceToken_t, 0);
ppcDefineParamU32(serverId, 1);
memset(token, 0, sizeof(nexServiceToken_t));
actPrepareRequest();
actRequest->requestCode = IOSU_ARC_ACQUIRENEXTOKEN;
actRequest->titleId = CafeSystem::GetForegroundTitleId();
actRequest->titleVersion = CafeSystem::GetForegroundTitleVersion();
actRequest->serverId = serverId;
uint32 resultCode = __depr__IOS_Ioctlv(IOS_DEVICE_ACT, IOSU_ACT_REQUEST_CEMU, 1, 1, actBufferVector);
memcpy(token, actRequest->resultBinary.binBuffer, sizeof(nexServiceToken_t));
cemuLog_logDebug(LogType::Force, "Called nn_act.AcquireNexServiceToken");
osLib_returnFromFunction(hCPU, getNNReturnCode(resultCode, actRequest));
}
void nnActExport_AcquireIndependentServiceToken(PPCInterpreter_t* hCPU)
{
ppcDefineParamMEMPTR(token, independentServiceToken_t, 0);
ppcDefineParamMEMPTR(serviceToken, const char, 1);
uint32 result = nn::act::AcquireIndependentServiceToken(token.GetPtr(), serviceToken.GetPtr(), 0);
cemuLog_logDebug(LogType::Force, "nn_act.AcquireIndependentServiceToken(0x{}, {}) -> {:x}", (void*)token.GetPtr(), serviceToken.GetPtr(), result);
cemuLog_logDebug(LogType::Force, "Token: {}", serviceToken.GetPtr());
osLib_returnFromFunction(hCPU, result);
}
void nnActExport_AcquireIndependentServiceToken2(PPCInterpreter_t* hCPU)
{
ppcDefineParamStructPtr(token, independentServiceToken_t, 0);
ppcDefineParamMEMPTR(clientId, const char, 1);
ppcDefineParamU32(cacheDurationInSeconds, 2);
uint32 result = nn::act::AcquireIndependentServiceToken(token, clientId.GetPtr(), cacheDurationInSeconds);
cemuLog_logDebug(LogType::Force, "Called nn_act.AcquireIndependentServiceToken2");
osLib_returnFromFunction(hCPU, result);
}
void nnActExport_AcquireEcServiceToken(PPCInterpreter_t* hCPU)
{
ppcDefineParamMEMPTR(pEcServiceToken, independentServiceToken_t, 0);
uint32 result = nn::act::AcquireIndependentServiceToken(pEcServiceToken.GetPtr(), "71a6f5d6430ea0183e3917787d717c46", 0);
cemuLog_logDebug(LogType::Force, "Called nn_act.AcquireEcServiceToken");
osLib_returnFromFunction(hCPU, result);
}
void nnActExport_AcquirePrincipalIdByAccountId(PPCInterpreter_t* hCPU)
{
ppcDefineParamMEMPTR(principalId, uint32be, 0);
ppcDefineParamMEMPTR(nnid, char, 1);
ppcDefineParamU32(ukn, 2); // some option, can be 0 or 1 ?
cemuLog_logDebug(LogType::Force, "nn_act.AcquirePrincipalIdByAccountId(0x{:08x},\"{}\", {}) - last param unknown", principalId.GetMPTR(), nnid.GetPtr(), ukn);
actPrepareRequest2();
actRequest->requestCode = IOSU_ARC_ACQUIREPIDBYNNID;
strcpy(actRequest->clientId, nnid.GetPtr());
uint32 result = _doCemuActRequest(actRequest);
*principalId.GetPtr() = actRequest->resultU32.u32;
osLib_returnFromFunction(hCPU, result);
}
void nnAct_save(MemStreamWriter& s)
{
s.writeSection("nn_act");
s.write(nn::act::g_initializeCount);
s.write((uint32)g_isParentalControlCheckEnabled);
}
void nnAct_restore(MemStreamReader& s)
{
s.readSection("nn_act");
s.read(nn::act::g_initializeCount);
g_isParentalControlCheckEnabled = s.read<uint32>();
}
// register account functions
void nnAct_load()
{
osLib_addFunction("nn_act", "Initialize__Q2_2nn3actFv", nnActExport_Initialize);
osLib_addFunction("nn_act", "CreateConsoleAccount__Q2_2nn3actFv", nnActExport_CreateConsoleAccount);
osLib_addFunction("nn_act", "GetNumOfAccounts__Q2_2nn3actFv", nnActExport_GetNumOfAccounts);
osLib_addFunction("nn_act", "IsSlotOccupied__Q2_2nn3actFUc", nnActExport_IsSlotOccupied);
osLib_addFunction("nn_act", "GetSlotNo__Q2_2nn3actFv", nnActExport_GetSlotNo);
osLib_addFunction("nn_act", "GetSlotNoEx__Q2_2nn3actFRC7ACTUuid", nnActExport_GetSlotNoEx);
osLib_addFunction("nn_act", "IsNetworkAccount__Q2_2nn3actFv", nnActExport_IsNetworkAccount);
osLib_addFunction("nn_act", "IsNetworkAccountEx__Q2_2nn3actFUc", nnActExport_IsNetworkAccountEx);
// account id
osLib_addFunction("nn_act", "GetAccountId__Q2_2nn3actFPc", nnActExport_GetAccountId);
osLib_addFunction("nn_act", "GetAccountIdEx__Q2_2nn3actFPcUc", nnActExport_GetAccountIdEx);
// simple address
osLib_addFunction("nn_act", "GetSimpleAddressId__Q2_2nn3actFv", nnActExport_GetSimpleAddressId);
osLib_addFunction("nn_act", "GetSimpleAddressIdEx__Q2_2nn3actFPUiUc", nnActExport_GetSimpleAddressIdEx);
// principal id
osLib_addFunction("nn_act", "GetPrincipalId__Q2_2nn3actFv", nnActExport_GetPrincipalId);
osLib_addFunction("nn_act", "GetPrincipalIdEx__Q2_2nn3actFPUiUc", nnActExport_GetPrincipalIdEx);
// transferable id
osLib_addFunction("nn_act", "GetTransferableIdEx__Q2_2nn3actFPULUiUc", nnActExport_GetTransferableIdEx);
// persistent id
osLib_addFunction("nn_act", "GetPersistentId__Q2_2nn3actFv", nnActExport_GetPersistentId);
osLib_addFunction("nn_act", "GetPersistentIdEx__Q2_2nn3actFUc", nnActExport_GetPersistentIdEx);
// country
osLib_addFunction("nn_act", "GetCountry__Q2_2nn3actFPc", nnActExport_GetCountry);
// parental
osLib_addFunction("nn_act", "EnableParentalControlCheck__Q2_2nn3actFb", nnActExport_EnableParentalControlCheck);
osLib_addFunction("nn_act", "IsParentalControlCheckEnabled__Q2_2nn3actFv", nnActExport_IsParentalControlCheckEnabled);
osLib_addFunction("nn_act", "GetMii__Q2_2nn3actFP12FFLStoreData", nnActExport_GetMii);
osLib_addFunction("nn_act", "GetMiiEx__Q2_2nn3actFP12FFLStoreDataUc", nnActExport_GetMiiEx);
osLib_addFunction("nn_act", "GetMiiImageEx__Q2_2nn3actFPUiPvUi15ACTMiiImageTypeUc", nnActExport_GetMiiImageEx);
osLib_addFunction("nn_act", "GetMiiName__Q2_2nn3actFPw", nnActExport_GetMiiName);
osLib_addFunction("nn_act", "GetMiiNameEx__Q2_2nn3actFPwUc", nnActExport_GetMiiNameEx);
osLib_addFunction("nn_act", "UpdateMii__Q2_2nn3actFUcRC12FFLStoreDataPCwPCvUiT4T5T4T5T4T5T4T5T4T5T4T5T4T5T4T5", nnActExport_UpdateMii);
osLib_addFunction("nn_act", "GetUuid__Q2_2nn3actFP7ACTUuid", nnActExport_GetUuid);
osLib_addFunction("nn_act", "GetUuidEx__Q2_2nn3actFP7ACTUuidUc", nnActExport_GetUuidEx);
osLib_addFunction("nn_act", "GetUuidEx__Q2_2nn3actFP7ACTUuidUcUi", nnActExport_GetUuidEx2);
osLib_addFunction("nn_act", "GetParentalControlSlotNoEx__Q2_2nn3actFPUcUc", nnActExport_GetParentalControlSlotNoEx);
osLib_addFunction("nn_act", "GetDefaultAccount__Q2_2nn3actFv", nnActExport_GetDefaultAccount);
osLib_addFunction("nn_act", "AcquireEcServiceToken__Q2_2nn3actFPc", nnActExport_AcquireEcServiceToken);
osLib_addFunction("nn_act", "AcquireNexServiceToken__Q2_2nn3actFP26ACTNexAuthenticationResultUi", nnActExport_AcquireNexServiceToken);
osLib_addFunction("nn_act", "AcquireIndependentServiceToken__Q2_2nn3actFPcPCc", nnActExport_AcquireIndependentServiceToken);
osLib_addFunction("nn_act", "AcquireIndependentServiceToken__Q2_2nn3actFPcPCcUibT4", nnActExport_AcquireIndependentServiceToken2);
osLib_addFunction("nn_act", "AcquireIndependentServiceToken__Q2_2nn3actFPcPCcUi", nnActExport_AcquireIndependentServiceToken2);
osLib_addFunction("nn_act", "AcquirePrincipalIdByAccountId__Q2_2nn3actFPUiPA17_CcUi", nnActExport_AcquirePrincipalIdByAccountId);
cafeExportRegisterFunc(nn::act::GetErrorCode, "nn_act", "GetErrorCode__Q2_2nn3actFRCQ2_2nn6Result", LogType::Placeholder);
// placeholders / incomplete implementations
osLib_addFunction("nn_act", "HasNfsAccount__Q2_2nn3actFv", nnActExport_HasNfsAccount);
osLib_addFunction("nn_act", "GetHostServerSettings__Q2_2nn3actFPcT1Uc", nnActExport_GetHostServerSettings);
cafeExportRegisterFunc(nn::act::GetUtcOffset, "nn_act", "GetUtcOffset__Q2_2nn3actFv", LogType::Placeholder);
cafeExportRegisterFunc(nn::act::GetUtcOffsetEx, "nn_act", "GetUtcOffsetEx__Q2_2nn3actFPLUc", LogType::Placeholder);
}