From 74e084c8933c18d519f8e1286a50ea5ce4a046df Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Fri, 5 Jan 2024 03:56:31 +0100 Subject: [PATCH] Improve sceNpEula --- rpcs3/Emu/Cell/Modules/cellSysutilNpEula.cpp | 102 +++++++++++-------- rpcs3/Emu/Cell/Modules/sceNp.cpp | 15 +++ rpcs3/Emu/Cell/Modules/sceNp.h | 17 ++++ 3 files changed, 94 insertions(+), 40 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/cellSysutilNpEula.cpp b/rpcs3/Emu/Cell/Modules/cellSysutilNpEula.cpp index d2210dc11d..1676ef7cfc 100644 --- a/rpcs3/Emu/Cell/Modules/cellSysutilNpEula.cpp +++ b/rpcs3/Emu/Cell/Modules/cellSysutilNpEula.cpp @@ -1,74 +1,96 @@ #include "stdafx.h" #include "Emu/Cell/PPUModule.h" #include "cellSysutil.h" +#include "sceNp.h" +#include "Emu/IdManager.h" LOG_CHANNEL(cellSysutilNpEula); -struct sceNpEulaStructUnk0 +enum SceNpEulaStatus { - char buf[0xc]; + SCE_NP_EULA_UNKNOWN = 0, + SCE_NP_EULA_ACCEPTED = 1, + SCE_NP_EULA_ALREADY_ACCEPTED = 2, + SCE_NP_EULA_REJECTED = 3, + SCE_NP_EULA_ABORTED = 4, + SCE_NP_EULA_ERROR = 5, }; -// All error codes are unknown at this point in implementation and just guesses -enum cellSysutilNpEulaError : u32 +using SceNpEulaVersion = u32; +using SceNpEulaCheckEulaStatusCallback = void(SceNpEulaStatus status, u32 errorCode, SceNpEulaVersion version, vm::ptr arg); + +struct sceNpEulaCallbacksRegistered { - CELL_SYSUTIL_NP_EULA_NOT_INIT = 0x8002E500, - CELL_SYSUTIL_NP_EULA_INVALID_PARAM = 0x8002E501, - CELL_SYSUTIL_NP_EULA_UNKNOWN_502 = 0x8002E502, - CELL_SYSUTIL_NP_EULA_UNKNOWN_503 = 0x8002E503, + atomic_t status = SCE_NP_EULA_UNKNOWN; + atomic_t sceNpEulaCheckEulaStatus_callback_registered = false; + atomic_t sceNpEulaShowCurrentEula_callback_registered = false; }; -template<> -void fmt_class_string::format(std::string& out, u64 arg) +error_code sceNpEulaCheckEulaStatus(vm::cptr communicationId, u32 arg2, u64 arg3, vm::ptr cbFunc, vm::ptr cbFuncArg) { - format_enum(out, arg, [](auto error) + cellSysutilNpEula.warning("sceNpEulaCheckEulaStatus(communicationId=*0x%x, arg2=0x%x, arg3=0x%x, cbFunc=*0x%x, cbFuncArg=*0x%x)", communicationId, arg2, arg3, cbFunc, cbFuncArg); + + if (!communicationId || !cbFunc) { - switch (error) - { - STR_CASE(CELL_SYSUTIL_NP_EULA_NOT_INIT); - STR_CASE(CELL_SYSUTIL_NP_EULA_INVALID_PARAM); - STR_CASE(CELL_SYSUTIL_NP_EULA_UNKNOWN_502); - STR_CASE(CELL_SYSUTIL_NP_EULA_UNKNOWN_503); - } + return SCE_NP_EULA_ERROR_INVALID_ARGUMENT; + } - return unknown; + auto& cb_infos = g_fxo->get(); + + if (cb_infos.sceNpEulaCheckEulaStatus_callback_registered || cb_infos.sceNpEulaShowCurrentEula_callback_registered) + { + return SCE_NP_EULA_ERROR_ALREADY_INITIALIZED; + } + + cb_infos.sceNpEulaCheckEulaStatus_callback_registered = true; + cb_infos.status = SCE_NP_EULA_ALREADY_ACCEPTED; + + sysutil_register_cb([=](ppu_thread& cb_ppu) -> s32 + { + auto& cb_infos = g_fxo->get(); + cbFunc(cb_ppu, cb_infos.status, CELL_OK, 1, cbFuncArg); + cb_infos.sceNpEulaCheckEulaStatus_callback_registered = false; + return 0; }); -} - -// Seen on: Resistance 3, Uncharted 2 -error_code sceNpEulaCheckEulaStatus(vm::ptr arg1, u32 arg2, u64 arg3, u32 arg4, vm::ptr callback1) -{ - cellSysutilNpEula.todo("sceNpEulaCheckEulaStatus(arg1=*0x%x, arg2=0x%x, arg3=0x%x, arg4=0x%x, callback1=*0x%x)", arg1, arg2, arg3, arg4, callback1); - - if (!arg1) - return CELL_SYSUTIL_NP_EULA_INVALID_PARAM; - - if (arg4 == 0) - return CELL_SYSUTIL_NP_EULA_INVALID_PARAM; return CELL_OK; } -// Seen on: Resistance 3 error_code sceNpEulaAbort() { - cellSysutilNpEula.todo("sceNpEulaAbort()"); + cellSysutilNpEula.warning("sceNpEulaAbort()"); - // Can return CELL_SYSUTIL_NP_EULA_NOT_INIT + auto& cb_infos = g_fxo->get(); + + if (!cb_infos.sceNpEulaCheckEulaStatus_callback_registered && !cb_infos.sceNpEulaShowCurrentEula_callback_registered) + { + return SCE_NP_EULA_ERROR_NOT_INITIALIZED; + } + + // It would forcefully abort the dialog/process of getting the eula but since we don't show the dialog, just alter the status returned + cb_infos.status = SCE_NP_EULA_ABORTED; return CELL_OK; } // Seen on: Resistance 3, Uncharted 2 -error_code sceNpEulaShowCurrentEula(vm::ptr arg1, u64 arg2, vm::ptr callback1, vm::ptr callback2) +error_code sceNpEulaShowCurrentEula(vm::cptr communicationId, u64 arg2, vm::ptr cbFunc, vm::ptr cbFuncArg) { - cellSysutilNpEula.todo("sceNpEulaShowCurrentEula(arg1=*0x%x, arg2=0x%x, callback1=*0x%x, callback2=*0x%x)", arg1, arg2, callback1, callback2); + cellSysutilNpEula.todo("sceNpEulaShowCurrentEula(communicationId=*0x%x, arg2=0x%x, cbFunc=*0x%x, cbFuncArg=*0x%x)", communicationId, arg2, cbFunc, cbFuncArg); - if (!arg1) - return CELL_SYSUTIL_NP_EULA_INVALID_PARAM; + if (!communicationId || !cbFunc) + { + return SCE_NP_EULA_ERROR_INVALID_ARGUMENT; + } - if (!callback1) - return CELL_SYSUTIL_NP_EULA_INVALID_PARAM; + auto& cb_infos = g_fxo->get(); + + if (cb_infos.sceNpEulaCheckEulaStatus_callback_registered || cb_infos.sceNpEulaShowCurrentEula_callback_registered) + { + return SCE_NP_EULA_ERROR_ALREADY_INITIALIZED; + } + + // Call callback (Unknown parameters) return CELL_OK; } diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 922c763a63..660282ea8d 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -398,6 +398,21 @@ void fmt_class_string::format(std::string& out, u64 arg) STR_CASE(SCE_NP_CUSTOM_MENU_ERROR_NOT_REGISTERED); STR_CASE(SCE_NP_CUSTOM_MENU_ERROR_EXCEEDS_MAX); STR_CASE(SCE_NP_CUSTOM_MENU_ERROR_INVALID_CHARACTER); + STR_CASE(SCE_NP_EULA_ERROR_UNKNOWN); + STR_CASE(SCE_NP_EULA_ERROR_INVALID_ARGUMENT); + STR_CASE(SCE_NP_EULA_ERROR_NOT_INITIALIZED); + STR_CASE(SCE_NP_EULA_ERROR_ALREADY_INITIALIZED); + STR_CASE(SCE_NP_EULA_ERROR_OUT_OF_MEMORY); + STR_CASE(SCE_NP_EULA_ERROR_BUSY); + STR_CASE(SCE_NP_EULA_ERROR_EULA_NOT_FOUND); + STR_CASE(SCE_NP_EULA_ERROR_NET_OUT_OF_MEMORY); + STR_CASE(SCE_NP_EULA_ERROR_CONF_FORMAT); + STR_CASE(SCE_NP_EULA_ERROR_CONF_INVALID_FILENAME); + STR_CASE(SCE_NP_EULA_ERROR_CONF_TOO_MANY_EULA_FILES); + STR_CASE(SCE_NP_EULA_ERROR_CONF_INVALID_LANGUAGE); + STR_CASE(SCE_NP_EULA_ERROR_CONF_INVALID_COUNTRY); + STR_CASE(SCE_NP_EULA_ERROR_CONF_INVALID_NPCOMMID); + STR_CASE(SCE_NP_EULA_ERROR_CONF_INVALID_EULA_VERSION); } return unknown; diff --git a/rpcs3/Emu/Cell/Modules/sceNp.h b/rpcs3/Emu/Cell/Modules/sceNp.h index f65e77c4e4..58641a194e 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.h +++ b/rpcs3/Emu/Cell/Modules/sceNp.h @@ -454,6 +454,23 @@ enum SceNpError : u32 SCE_NP_CUSTOM_MENU_ERROR_NOT_REGISTERED = 0x80023b0b, SCE_NP_CUSTOM_MENU_ERROR_EXCEEDS_MAX = 0x80023b0c, SCE_NP_CUSTOM_MENU_ERROR_INVALID_CHARACTER = 0x80023b0d, + + // EULA + SCE_NP_EULA_ERROR_UNKNOWN = 0x8002e500, + SCE_NP_EULA_ERROR_INVALID_ARGUMENT = 0x8002e501, + SCE_NP_EULA_ERROR_NOT_INITIALIZED = 0x8002e502, + SCE_NP_EULA_ERROR_ALREADY_INITIALIZED = 0x8002e503, + SCE_NP_EULA_ERROR_OUT_OF_MEMORY = 0x8002E504, + SCE_NP_EULA_ERROR_BUSY = 0x8002e505, + SCE_NP_EULA_ERROR_EULA_NOT_FOUND = 0x8002e5a0, + SCE_NP_EULA_ERROR_NET_OUT_OF_MEMORY = 0x8002e5a1, + SCE_NP_EULA_ERROR_CONF_FORMAT = 0x8002e5b0, + SCE_NP_EULA_ERROR_CONF_INVALID_FILENAME = 0x8002e5b1, + SCE_NP_EULA_ERROR_CONF_TOO_MANY_EULA_FILES = 0x8002e5b2, + SCE_NP_EULA_ERROR_CONF_INVALID_LANGUAGE = 0x8002e5b3, + SCE_NP_EULA_ERROR_CONF_INVALID_COUNTRY = 0x8002e5b4, + SCE_NP_EULA_ERROR_CONF_INVALID_NPCOMMID = 0x8002e5b5, + SCE_NP_EULA_ERROR_CONF_INVALID_EULA_VERSION = 0x8002e5b6, }; // Basic presence options