From 0e2584fc9f367c2d3cd3e0ce578fb81b0e74b6ce Mon Sep 17 00:00:00 2001 From: RipleyTom Date: Sun, 25 Jan 2026 07:10:50 +0100 Subject: [PATCH] sceNpBasicLimitedSendMessage --- rpcs3/Emu/Cell/Modules/sceNp.cpp | 65 ++++++++++++++++++++++++++++++-- rpcs3/Emu/Cell/PPUModule.cpp | 1 + rpcs3/Emu/Cell/PPUModule.h | 1 + 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 2b49309a9b..ee9c308265 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -1118,10 +1118,35 @@ error_code sceNpBasicSetPresenceDetails2(vm::cptr pr return CELL_OK; } -error_code sceNpBasicSendMessage(vm::cptr to, vm::cptr data, u32 size) -{ - sceNp.warning("sceNpBasicSendMessage(to=*0x%x, data=*0x%x, size=%d)", to, data, size); +u64 sys_time_get_system_time(); +error_code acquire_time_slot(u64* time_array, usz array_size, u64 slot_duration) +{ + static shared_mutex mutex; + std::lock_guard lock(mutex); + + const u64 current_time = sys_time_get_system_time(); + + for (usz index = 0; index < array_size; index++) + { + if (time_array[index] == 0) + { + time_array[index] = current_time; + return CELL_OK; + } + + if (current_time > (time_array[index] + slot_duration)) + { + time_array[index] = current_time; + return CELL_OK; + } + } + + return SCE_NP_BASIC_ERROR_BUSY; +} + +error_code _sceNpBasicSendMessage(vm::cptr to, vm::cptr data, u32 size, bool rate_limited) +{ auto& nph = g_fxo->get>(); if (!nph.is_NP_init) @@ -1144,6 +1169,22 @@ error_code sceNpBasicSendMessage(vm::cptr to, vm::cptr data, u32 return SCE_NP_BASIC_ERROR_EXCEEDS_MAX; } + if (rate_limited) + { + struct sceNpBasicSendMessage_time_slots + { + sceNpBasicSendMessage_time_slots(sceNpBasicSendMessage_time_slots&&) = delete; + std::array data{}; + }; + + auto& time_slots = g_fxo->get(); + + if (auto error = acquire_time_slot(time_slots.data.data(), time_slots.data.size(), 60000000); error != CELL_OK) + { + return error; + } + } + if (nph.get_psn_status() != SCE_NP_MANAGER_STATUS_ONLINE) { return not_an_error(SCE_NP_BASIC_ERROR_NOT_CONNECTED); @@ -1164,6 +1205,19 @@ error_code sceNpBasicSendMessage(vm::cptr to, vm::cptr data, u32 return CELL_OK; } +error_code sceNpBasicSendMessage(vm::cptr to, vm::cptr data, u32 size) +{ + sceNp.warning("sceNpBasicSendMessage(to=*0x%x, data=*0x%x, size=%d)", to, data, size); + return _sceNpBasicSendMessage(to, data, size, false); +} + +// This function is sceNpBasicSendMessage + a rate limiter that will return SCE_NP_BASIC_ERROR_BUSY if it too many messages have been sent +error_code sceNpBasicLimited_0xEB42E2E6(vm::cptr to, vm::cptr data, u32 size) +{ + sceNp.warning("sceNpBasicLimited_0xEB42E2E6(to=*0x%x, data=*0x%x, size=%d)", to, data, size); + return _sceNpBasicSendMessage(to, data, size, true); +} + error_code sceNpBasicSendMessageGui(ppu_thread& ppu, vm::cptr msg, sys_memory_container_t containerId) { sceNp.warning("sceNpBasicSendMessageGui(msg=*0x%x, containerId=%d)", msg, containerId); @@ -7289,6 +7343,11 @@ s32 _Z32_sce_np_sysutil_cxml_prepare_docPN16sysutil_cxmlutil11FixedMemoryERN4cxm return CELL_OK; } +DECLARE(ppu_module_manager::sceNpBasicLimited) +("sceNpBasicLimited", []() { + ppu_module_manager::register_static_function<&sceNpBasicLimited_0xEB42E2E6>("sceNpBasicLimited", ppu_select_name("sceNpBasicLimited", "sceNpBasicLimited_0xEB42E2E6"), BIND_FUNC_WITH_BLR(sceNpBasicLimited_0xEB42E2E6, "sceNpBasicLimited"), 0xEB42E2E6); +}); + DECLARE(ppu_module_manager::sceNp) ("sceNp", []() { REG_FUNC(sceNp, sceNpInit); diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index 65ab0fe18d..b298539519 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -314,6 +314,7 @@ static void ppu_initialize_modules(ppu_linkage_info* link, utils::serial* ar = n &ppu_module_manager::libsnd3, &ppu_module_manager::libsynth2, &ppu_module_manager::sceNp, + &ppu_module_manager::sceNpBasicLimited, &ppu_module_manager::sceNp2, &ppu_module_manager::sceNpClans, &ppu_module_manager::sceNpCommerce2, diff --git a/rpcs3/Emu/Cell/PPUModule.h b/rpcs3/Emu/Cell/PPUModule.h index fdcd736f38..6171a4faa1 100644 --- a/rpcs3/Emu/Cell/PPUModule.h +++ b/rpcs3/Emu/Cell/PPUModule.h @@ -283,6 +283,7 @@ public: static const ppu_static_module libsnd3; static const ppu_static_module libsynth2; static const ppu_static_module sceNp; + static const ppu_static_module sceNpBasicLimited; static const ppu_static_module sceNp2; static const ppu_static_module sceNpClans; static const ppu_static_module sceNpCommerce2;