#include "nn_olv.h" #include "nn_olv_InitializeTypes.h" #include "nn_olv_UploadCommunityTypes.h" #include "nn_olv_DownloadCommunityTypes.h" #include "nn_olv_UploadFavoriteTypes.h" #include "nn_olv_PostTypes.h" #include "nn_olv_OfflineDB.h" #include "Cafe/OS/libs/proc_ui/proc_ui.h" #include "Cafe/OS/libs/coreinit/coreinit_Time.h" #include "Cafe/OS/libs/coreinit/coreinit_Misc.h" namespace nn { namespace olv { struct PortalAppParam_t { /* +0x1A663B */ char serviceToken[32]; // size is unknown }; void exportPortalAppParam_GetServiceToken(PPCInterpreter_t* hCPU) { // r3 = PortalAppParam ppcDefineParamTypePtr(portalAppParam, PortalAppParam_t, 0); strcpy(portalAppParam->serviceToken, "servicetoken"); // this token is probably just the act IndependentServiceToken for the Miiverse title? osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(&portalAppParam->serviceToken)); } static SysAllocator s_OlvReleaseBgThread; SysAllocator s_OlvReleaseBgThreadStack; SysAllocator s_OlvReleaseBgThreadName; void StubPostAppReleaseBackground(PPCInterpreter_t* hCPU) { coreinit::OSSleepTicks(ESPRESSO_TIMER_CLOCK * 2); // Sleep 2s coreinit::StartBackgroundForegroundTransition(); } sint32 StubPostApp(void* pAnyPostParam) { coreinit::OSCreateThreadType(s_OlvReleaseBgThread.GetPtr(), RPLLoader_MakePPCCallable(StubPostAppReleaseBackground), 0, nullptr, s_OlvReleaseBgThreadStack.GetPtr() + s_OlvReleaseBgThreadStack.GetByteSize(), (sint32)s_OlvReleaseBgThreadStack.GetByteSize(), 0, (1 << 1) | (1 << 3), OSThread_t::THREAD_TYPE::TYPE_APP); coreinit::OSResumeThread(s_OlvReleaseBgThread.GetPtr()); strcpy(s_OlvReleaseBgThreadName.GetPtr(), "StubPostApp!"); coreinit::OSSetThreadName(s_OlvReleaseBgThread.GetPtr(),s_OlvReleaseBgThreadName.GetPtr()); return OLV_RESULT_SUCCESS; } sint32 StubPostAppResult() { return OLV_RESULT_STATUS(301); // Cancelled post app } // Somehow required, MK8 doesn't even seem to care about the error codes lol char* UploadedPostData_GetPostId(char* pPostData) { pPostData[4] = '\0'; return &pPostData[4]; } // https://github.com/kinnay/NintendoClients/wiki/Wii-U-Error-Codes#act-error-codes constexpr uint32 GetErrorCodeImpl(uint32 in) { uint32_t errorCode = in; uint32_t errorVersion = (errorCode >> 27) & 3; uint32_t errorModuleMask = (errorVersion != 3) ? 0x1FF00000 : 0x7F00000; bool isCodeFailure = errorCode & 0x80000000; if (((errorCode & errorModuleMask) >> 20) == NN_RESULT_MODULE_NN_ACT) { // BANNED_ACCOUNT_IN_INDEPENDENT_SERVICE or BANNED_ACCOUNT_IN_INDEPENDENT_SERVICE_TEMPORARILY if (errorCode == OLV_ACT_RESULT_STATUS(2805) || errorCode == OLV_ACT_RESULT_STATUS(2825)) { uint32 tmpCode = OLV_RESULT_STATUS(1008); return GetErrorCodeImpl(tmpCode); } // BANNED_DEVICE_IN_INDEPENDENT_SERVICE or BANNED_DEVICE_IN_INDEPENDENT_SERVICE_TEMPORARILY else if (errorCode == OLV_ACT_RESULT_STATUS(2815) || errorCode == OLV_ACT_RESULT_STATUS(2835)) { uint32 tmpCode = OLV_RESULT_STATUS(1009); return GetErrorCodeImpl(tmpCode); } else { // Check ACT error code return 1159999; } } else { if (((errorCode & errorModuleMask) >> 20) == NN_RESULT_MODULE_NN_OLV && isCodeFailure) { uint32_t errorValueMask = (errorVersion != 3) ? 0xFFFFF : 0x3FF; return ((errorCode & errorValueMask) >> 7) + 1150000; } else { return 1159999; } } } uint32 GetErrorCode(uint32be* pResult) { return GetErrorCodeImpl(pResult->value()); } static_assert(GetErrorCodeImpl(0xa119c600) == 1155004); void load() { g_ReportTypes = 0; g_IsOnlineMode = false; g_IsInitialized = false; g_IsOfflineDBMode = false; loadOliveInitializeTypes(); loadOliveUploadCommunityTypes(); loadOliveDownloadCommunityTypes(); loadOliveUploadFavoriteTypes(); loadOlivePostAndTopicTypes(); cafeExportRegisterFunc(GetErrorCode, "nn_olv", "GetErrorCode__Q2_2nn3olvFRCQ2_2nn6Result", LogType::NN_OLV); osLib_addFunction("nn_olv", "GetServiceToken__Q4_2nn3olv6hidden14PortalAppParamCFv", exportPortalAppParam_GetServiceToken); cafeExportRegisterFunc(StubPostApp, "nn_olv", "UploadPostDataByPostApp__Q2_2nn3olvFPCQ3_2nn3olv28UploadPostDataByPostAppParam", LogType::NN_OLV); cafeExportRegisterFunc(StubPostApp, "nn_olv", "UploadCommentDataByPostApp__Q2_2nn3olvFPCQ3_2nn3olv31UploadCommentDataByPostAppParam", LogType::NN_OLV); cafeExportRegisterFunc(StubPostApp, "nn_olv", "UploadDirectMessageDataByPostApp__Q2_2nn3olvFPCQ3_2nn3olv37UploadDirectMessageDataByPostAppParam", LogType::NN_OLV); cafeExportRegisterFunc(StubPostAppResult, "nn_olv", "GetResultByPostApp__Q2_2nn3olvFv", LogType::NN_OLV); cafeExportRegisterFunc(StubPostAppResult, "nn_olv", "GetResultWithUploadedPostDataByPostApp__Q2_2nn3olvFPQ3_2nn3olv16UploadedPostData", LogType::NN_OLV); cafeExportRegisterFunc(StubPostAppResult, "nn_olv", "GetResultWithUploadedDirectMessageDataByPostApp__Q2_2nn3olvFPQ3_2nn3olv25UploadedDirectMessageData", LogType::NN_OLV); cafeExportRegisterFunc(StubPostAppResult, "nn_olv", "GetResultWithUploadedCommentDataByPostApp__Q2_2nn3olvFPQ3_2nn3olv19UploadedCommentData", LogType::NN_OLV); cafeExportRegisterFunc(UploadedPostData_GetPostId, "nn_olv", "GetPostId__Q3_2nn3olv16UploadedPostDataCFv", LogType::NN_OLV); } void unload() // not called yet { OfflineDB_Shutdown(); } } }