feat(libSceNpManager): answer the PS4 account and presence queries for a signed-out user
11 KiB
libSceNpManager technical debt
Silent stubs
- sceNpUnregisterPlusEventCallback (libSceNpManager) - returns 0 whether or not a callback was registered, as
sceNpUnregisterPremiumEventCallbackdoes:sceNpRegisterPlusEventCallbackkeeps no callback, and a signed-out user gets no plus events
Unknown function info
-
libSceNpManager pending exports - 150 named callable exports are present in the local
libSceNpManager.sprxexport table and the public PS5 3.20 symbol list. Their signatures and behavior are unverified; each declaration uses the no-parameter unknown-signature convention and throws throughNotImplemented_nid_no_patch. -
sceNpGetSandboxInfo (libSceNpManager, NID
ZVZ++68nNI8) - the name hashes to the imported NID (found with nidhunt, confirmed withtools/nid_names.py). STAR WARS: Galactic Racer (PPSA28416) imports it; its OnlineSubsystemPS5 calls it with one pointer to a 0x50-byte stack buffer and reads the buffer as a string (discussions/3086). The returned string, the exact parameter struct and console errors are unknown, so every call throws without reading or writing caller memory. A working implementation belongs with that title's bring-up. -
sceNpUnknown_8weiQyIdI3A (libSceNpManager, NID
8weiQyIdI3A) - the name is not in aerolib. EA SPORTS FC 27 (PPSA34015) fails to loadlibSceNpManager.prxwithout it (unresolved ELF import/GetLastError: 127). Its only call ismov edi, r14d(a user id) andlea rsi, [rbp-0x40]after a 17-byte copy into that buffer (mov edx, 0x11);test eax, eaxfollows. The C name, the type of the 17-byte object and the console return are unknown, so every call throws without reading or writing caller memory. -
sceNpUnknown_WxLcN76q19o (libSceNpManager, NID
WxLcN76q19o) - the name is not in aerolib. PPSA34015 imports it fromlibSceNpManager.prxas a strongJUMP_SLOTwith no call found in the eboot; the loader still requires the export. Arguments, result and console errors are unknown, so every call throws. -
sceNpSetTimeout (libSceNpManager) - the signature follows orbital, shadPS4 and SharpProspero; the rejected values (all five 0, negative retries, a resolve timeout under 1 s or another timeout under 10 s, 0 meaning the default) are shadPS4's, not checked on a console. An id that was never created or was deleted returns
REQUEST_NOT_FOUND, as in shadPS4; there is no network, so the timeouts are not stored -
sceNpGetUserIdByAccountId - the
(account id, user id output)signature and its errors follow shadPS4: account id 0 or a null output returnsSCE_NP_ERROR_INVALID_ARGUMENT, and a signed-out NP returnsSCE_NP_ERROR_SIGNED_OUTwithout writing the output. NP is always signed out here, so no account id resolves to a user -
sceNpNotifyPlusFeature (libSceNpManager) - PS4 titles import it; its parameter block and what the console does with it for a signed-out user are unknown (shadPS4 returns 0 without reading it), so every call throws.
Functional
-
sceNpGetAccountCountry, sceNpGetAccountDateOfBirth, sceNpGetAccountLanguage, sceNpGetParentalControlInfo (libSceNpManager) - PS4 forms taking an online id, not measured on a console. Signatures and checks follow shadPS4: a null pointer is
INVALID_ARGUMENT; no user is signed in, so no online id matches one and the rest returnUSER_NOT_FOUNDwithout writing, likesceNpCheckNpAvailability. Request ids are not checked -
sceNpGetUserIdByOnlineId (libSceNpManager) - the
(online id, user id output)signature follows shadPS4: a null online id or output returnsSCE_NP_ERROR_INVALID_ARGUMENT, and a signed-out NP returnsSCE_NP_ERROR_SIGNED_OUTwithout writing the output, assceNpGetUserIdByAccountIddoes -
sceNpCheckPlus (libSceNpManager) - the
(request id, parameter, result)signature follows shadPS4: request id 0 or a null parameter or result returnsSCE_NP_ERROR_INVALID_ARGUMENT, and every other call returnsSCE_NP_ERROR_SIGNED_OUTwithout writing the result, assceNpCheckPremiumdoes. The parameter's size and feature fields, which shadPS4 checks, are not read: the errors the console returns for them are not known -
sceNpGetAccountId, sceNpSetGamePresenceOnline (libSceNpManager) - PS4 forms; the
(online id, account id output)and(request id, online id, presence)signatures follow shadPS4. A null online id or output, or request id 0 forsceNpSetGamePresenceOnline, returnsSCE_NP_ERROR_INVALID_ARGUMENT.sceNpSetGamePresenceOnlinethen returnsSCE_NP_ERROR_REQUEST_NOT_FOUNDfor a request that was never created or was deleted, as shadPS4 does. Otherwise both returnSCE_NP_ERROR_SIGNED_OUTwithout writing, assceNpGetAccountIdAdoes. The console's result for a signed-out user is not measured -
NP reachability callbacks retain one callback and its user data; duplicate registration and unregistering an absent callback return the errors used by shadPS4. No callback is delivered because the existing NP model remains signed out with reachability unavailable.
-
sceNpCheckNpAvailability (libSceNpManager) - the
(req_id, online_id)signature and the errors follow shadPS4 with no user signed in to PSN: a null online id isSCE_NP_ERROR_INVALID_ARGUMENT, and any other online id matches no user,SCE_NP_ERROR_USER_NOT_FOUND; the request id is not checked, as in the other NpManager requests -
NP state callbacks (libSceNpManager) - the registration rules are shadPS4's:
sceNpRegisterStateCallbackAkeeps up to 8 callbacks and returns the slot plus 1, a null callback returnsINVALID_ARGUMENT, a callback already registeredCALLBACK_ALREADY_REGISTEREDand a ninth oneCALLBACK_MAX(0x8055001D, np_error.h);sceNpUnregisterStateCallbackAreturnsINVALID_ARGUMENTfor an id outside 1..8 andCALLBACK_NOT_REGISTEREDfor an empty slot; the legacy sceNpRegisterStateCallback keeps one callback with the same errors. Each registration getsSIGNED_OUTfor the initial user (0x10000000) once, from the nextsceNpCheckCallbackon the calling thread. For the A form this follows KytyPS5, whose sceNpRegisterStateCallbackA marks the registration pending. KytyPS5 never calls the legacy callback (sceNpRegisterStateCallback stores nothing); it is called as(user, SIGNED_OUT, nullptr, userdata), as in shadPS4, which passes an NpId only forSIGNED_IN(L823, L938-L940). shadPS4 instead queuesSIGNED_OUTfrom the user service login event and delivers it fromsceNpCheckCallback(DispatchPendingNpStateCallbacks); the reachability callback is not given an initialUNAVAILABLE, unlike that function (L922-L961). A callback being delivered when another thread unregisters it is still called once. When and how often the console calls the state callbacks, and the errors, are not measured -
sceNpRegisterGamePresenceCallback (libSceNpManager) - accepts any callback, null included, and returns nothing; no game presence event is delivered because the NP model remains signed out. Kyty ignores the callback the same way, and shadPS4 keeps the last one without calling it. Not measured on a PS5
-
The following pending declarations have unverified signatures and behavior; they are parameterless import-resolution declarations and throw through
NotImplemented_nid_no_patch:sceNpCheckCallbackForLib.