From a8508c7369719563f7321e987d32931915e87a92 Mon Sep 17 00:00:00 2001 From: Arian Kordi Date: Wed, 17 Dec 2025 19:00:32 -0500 Subject: [PATCH] Miiverse applet is working with Pretendo. wave.rpx requires patching allowlist entry, or FUN_020ff398 => return 1 (li r3, 1; blr) --- src/Cafe/OS/libs/nn_olv/nn_olv.cpp | 66 ++++++++++++++----- .../OS/libs/nn_olv/nn_olv_InitializeTypes.h | 60 +++++++++-------- 2 files changed, 81 insertions(+), 45 deletions(-) diff --git a/src/Cafe/OS/libs/nn_olv/nn_olv.cpp b/src/Cafe/OS/libs/nn_olv/nn_olv.cpp index ea43775c..aabac935 100644 --- a/src/Cafe/OS/libs/nn_olv/nn_olv.cpp +++ b/src/Cafe/OS/libs/nn_olv/nn_olv.cpp @@ -15,23 +15,53 @@ namespace nn { namespace olv { + static const char* startUrlTemplate = "%s/titles/show?src=menu"; struct PortalAppParam_t { - /* +0x1A663B */ char serviceToken[32]; // size is unknown - /* +0x1A5E3C */ char startUrl[37]; // https://discovery.olv.pretendo.cc/v1/endpoint + /* +0x1A5C3C */ char paramPack[0x200]; + /* +0x1A663B */ char serviceToken[0x201]; + /* +0x1A5E3C */ char startUrl[0x7ff]; // https://portal-us.olv.nintendo.net/titles/show?src=menu }; + uint32 StubPortalApp([[maybe_unused]] void* pPortalAppParam) + { + // Response to either a size or pointer. + // In any case, it usually ignores 0 or null. + return 0; + } + + void exportPortalAppParam_GetParamPack(PPCInterpreter_t* hCPU) + { + // r3 = PortalAppParam + ppcDefineParamTypePtr(portalAppParam, PortalAppParam_t, 0); + + strcpy(portalAppParam->paramPack, g_ParamPack.encodedParamPack); + + osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(&portalAppParam->serviceToken)); + } + 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? + strcpy(portalAppParam->serviceToken, g_DiscoveryResults.serviceToken); osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(&portalAppParam->serviceToken)); } + void exportPortalAppParam_GetStartUrl(PPCInterpreter_t* hCPU) + { + // r3 = PortalAppParam + ppcDefineParamTypePtr(portalAppParam, PortalAppParam_t, 0); + + cemu_assert_debug(g_DiscoveryResults.portalEndpoint[0]); + snprintf(portalAppParam->startUrl, sizeof(portalAppParam->startUrl), + startUrlTemplate, g_DiscoveryResults.portalEndpoint); + + osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(&portalAppParam->startUrl)); + } + static SysAllocator s_OlvReleaseBgThread; SysAllocator s_OlvReleaseBgThreadStack; SysAllocator s_OlvReleaseBgThreadName; @@ -110,16 +140,6 @@ namespace nn return GetErrorCodeImpl(pResult->value()); } - void exportPortalAppParam_GetStartUrl(PPCInterpreter_t* hCPU) - { - // r3 = PortalAppParam - ppcDefineParamTypePtr(portalAppParam, PortalAppParam_t, 0); - - strcpy(portalAppParam->startUrl, "discovery.olv.pretendo.cc/v1/endpoint"); - - osLib_returnFromFunction(hCPU, memory_getVirtualOffsetFromPointer(&portalAppParam->startUrl)); - } - static_assert(GetErrorCodeImpl(0xa119c600) == 1155004); void load() @@ -135,10 +155,12 @@ namespace nn loadOliveUploadFavoriteTypes(); loadOlivePostAndTopicTypes(); - cafeExportRegisterFunc(GetErrorCode, "nn_olv", "GetErrorCode__Q2_2nn3olvFRCQ2_2nn6Result", LogType::NN_OLV); - - osLib_addFunction("nn_olv", "GetStartUrl__Q4_2nn3olv6hidden14PortalAppParamCFv", exportPortalAppParam_GetStartUrl); + // TODO: loadOlivePortalAppTypes + osLib_addFunction("nn_olv", "GetParamPack__Q4_2nn3olv6hidden14PortalAppParamCFv", exportPortalAppParam_GetParamPack); osLib_addFunction("nn_olv", "GetServiceToken__Q4_2nn3olv6hidden14PortalAppParamCFv", exportPortalAppParam_GetServiceToken); + osLib_addFunction("nn_olv", "GetStartUrl__Q4_2nn3olv6hidden14PortalAppParamCFv", exportPortalAppParam_GetStartUrl); + + cafeExportRegisterFunc(GetErrorCode, "nn_olv", "GetErrorCode__Q2_2nn3olvFRCQ2_2nn6Result", LogType::NN_OLV); cafeExportRegisterFunc(StubPostApp, "nn_olv", "UploadPostDataByPostApp__Q2_2nn3olvFPCQ3_2nn3olv28UploadPostDataByPostAppParam", LogType::NN_OLV); cafeExportRegisterFunc(StubPostApp, "nn_olv", "UploadCommentDataByPostApp__Q2_2nn3olvFPCQ3_2nn3olv31UploadCommentDataByPostAppParam", LogType::NN_OLV); @@ -149,6 +171,14 @@ namespace nn cafeExportRegisterFunc(StubPostAppResult, "nn_olv", "GetResultWithUploadedDirectMessageDataByPostApp__Q2_2nn3olvFPQ3_2nn3olv25UploadedDirectMessageData", LogType::NN_OLV); cafeExportRegisterFunc(StubPostAppResult, "nn_olv", "GetResultWithUploadedCommentDataByPostApp__Q2_2nn3olvFPQ3_2nn3olv19UploadedCommentData", LogType::NN_OLV); + cafeExportRegisterFunc(StubPortalApp, "nn_olv", "GetAppDataSize__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); + cafeExportRegisterFunc(StubPortalApp, "nn_olv", "GetAppData__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); + cafeExportRegisterFunc(StubPortalApp, "nn_olv", "GetDefaultBodyMemo__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); + cafeExportRegisterFunc(StubPortalApp, "nn_olv", "GetExternalBinaryDataSize__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); + cafeExportRegisterFunc(StubPortalApp, "nn_olv", "GetExternalBinaryData__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); + cafeExportRegisterFunc(StubPortalApp, "nn_olv", "GetExternalImageDataSize__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); + cafeExportRegisterFunc(StubPortalApp, "nn_olv", "GetExternalImageData__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); + cafeExportRegisterFunc(UploadedPostData_GetPostId, "nn_olv", "GetPostId__Q3_2nn3olv16UploadedPostDataCFv", LogType::NN_OLV); } @@ -158,4 +188,4 @@ namespace nn } } -} \ No newline at end of file +} diff --git a/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.h b/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.h index 865a1188..810cee35 100644 --- a/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.h +++ b/src/Cafe/OS/libs/nn_olv/nn_olv_InitializeTypes.h @@ -106,8 +106,6 @@ namespace nn public: PortalAppParam() { - this->m_serviceToken = ""; // todo - this->m_startUrl = "https://discovery.olv.pretendo.cc/v1/endpoint"; } static PortalAppParam* __ctor(PortalAppParam* _this) { @@ -119,28 +117,37 @@ namespace nn else return new (_this) PortalAppParam(); } - - std::string GetStartUrl() - { - return this->m_startUrl; - } - static std::string __GetStartUrl(PortalAppParam* _this) - { - return _this->GetStartUrl(); - } - - std::string GetDefaultBodyMemo() - { - // todo - i dont think this is right - return "Default Body Baby"; - } - static std::string __GetDefaultBodyMemo(PortalAppParam* _this) - { - return _this->GetDefaultBodyMemo(); - } - - std::string m_serviceToken; - std::string m_startUrl; + /* + struct PortalAppParam { + uint appDataSize; // for all sizes, if it is 0 then it returns null pointer + char appData[1024]; + uint defaultBodyMemoSize; + char defaultBodyMemo[153644]; + uint externalImageDataSize; + char externalImageData[524288]; + uint externalBinaryDataSize; + char externalBinaryData[1048576]; + char paramPack[512]; + char startUrl[2047]; + char serviceToken[513]; + uint startType; + char bodyText[512]; // may actually be u16, as in, utf-16 + char topicTag[304]; + char searchKey[1520]; + char externalUrl[256]; + uint bodyTextMaxLength; // why is it back here + char feeling; // it is just a char + char padding_0[3]; + uint communityId; + uint userPid; + uint flags; + char postId[32]; + int useWebHost; // unknown, only referenced when initializing?, when 0 portalHost is used otherwise webHost + char webHost[2047]; // actually the api url + char portalHost[2047]; // portal-us.olv.nintendo.net + undefined padding_1[3434]; // unreferenced, alignment? + }; + */ }; @@ -157,6 +164,7 @@ namespace nn static void loadOliveInitializeTypes() { cafeExportRegisterFunc(Initialize, "nn_olv", "Initialize__Q2_2nn3olvFPCQ3_2nn3olv15InitializeParam", LogType::NN_OLV); + cafeExportRegisterFunc(InitializePortalApp, "nn_olv", "InitializePortalApp__Q3_2nn3olv6hiddenFPQ4_2nn3olv6hidden14PortalAppParamPCQ3_2nn3olv15InitializeParam", LogType::NN_OLV); cafeExportRegisterFunc(IsInitialized, "nn_olv", "IsInitialized__Q2_2nn3olvFv", LogType::NN_OLV); cafeExportRegisterFunc(Report::GetReportTypes, "nn_olv", "GetReportTypes__Q3_2nn3olv6ReportFv", LogType::NN_OLV); cafeExportRegisterFunc(Report::SetReportTypes, "nn_olv", "SetReportTypes__Q3_2nn3olv6ReportFUi", LogType::NN_OLV); @@ -168,8 +176,6 @@ namespace nn cafeExportRegisterFunc(InitializeParam::__SetSysArgs, "nn_olv", "SetSysArgs__Q3_2nn3olv15InitializeParamFPCvUi", LogType::NN_OLV); cafeExportRegisterFunc(PortalAppParam::__ctor, "nn_olv", "__ct__Q4_2nn3olv6hidden14PortalAppParamFv", LogType::NN_OLV); - cafeExportRegisterFunc(PortalAppParam::__GetStartUrl, "nn_olv", "GetStartUrl__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); - cafeExportRegisterFunc(PortalAppParam::__GetDefaultBodyMemo, "nn_olv", "GetDefaultBodyMemo__Q4_2nn3olv6hidden14PortalAppParamCFv", LogType::NN_OLV); } } -} \ No newline at end of file +}