Merge pull request #12620 from zaryabzip/feat/nputility-title-ctx-a

feat(libSceNpUtility): create lookup and word filter title contexts for a user id
This commit is contained in:
Dean authored and GitHub committed 2026-10-29 23:54:33 +13:00
commit 3b6ccf73ae
3 files changed
+32 -7

No files matched your search

+10 -6
View File
@@ -52,8 +52,7 @@ struct Service {
Service lookup(1, 1);
Service wordFilter(WORD_FILTER_TITLE_CTX_ID_OFFSET + 1, WORD_FILTER_REQUEST_ID_OFFSET + 1);
int CreateTitleContext(Service& service, const void* selfNpId) {
if (!selfNpId) return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT;
int AddTitleContext(Service& service) {
std::lock_guard lock(service.mutex);
if (service.titleContexts.size() >= MAX_TITLE_CONTEXTS) return SCE_NP_COMMUNITY_ERROR_TOO_MANY_OBJECTS;
const int titleCtxId = service.nextTitleContext++;
@@ -61,6 +60,11 @@ int CreateTitleContext(Service& service, const void* selfNpId) {
return titleCtxId;
}
int CreateTitleContext(Service& service, const void* selfNpId) {
if (!selfNpId) return SCE_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT;
return AddTitleContext(service);
}
int DeleteTitleContext(Service& service, int titleCtxId) {
std::lock_guard lock(service.mutex);
if (!service.titleContexts.erase(titleCtxId)) return SCE_NP_COMMUNITY_ERROR_INVALID_ID;
@@ -298,8 +302,8 @@ int APS5_VABI sceNpBandwidthTestShutdownWithDetailedInfo() {
return SCE_NP_ERROR_INVALID_ARGUMENT;
}
int APS5_VABI sceNpLookupCreateTitleCtxA(int userId) {
NotImplemented_nid_no_patch(__func__);
return 0;
(void)userId;
return AddTitleContext(lookup);
}
int APS5_VABI sceNpLookupNetAbortRequest() {
NotImplemented_nid_no_patch(__func__);
@@ -458,8 +462,8 @@ int APS5_VABI sceNpUtilityTerm() {
return 0;
}
int APS5_VABI sceNpWordFilterCreateTitleCtxA(int userId) {
NotImplemented_nid_no_patch(__func__);
return 0;
(void)userId;
return AddTitleContext(wordFilter);
}
}
+21
View File
@@ -234,6 +234,26 @@ void CheckWordFilterAsync() {
sceNpWordFilterDeleteTitleCtx(context);
}
void CheckTitleContextsA() {
int lookups[32];
int created = 0;
while (created < 32) {
const int context = sceNpLookupCreateTitleCtxA(created == 0 ? -1 : 1);
if (context == TooManyObjects) break;
Require(context > 0 && context < WordFilterTitleCtxBase, "sceNpLookupCreateTitleCtxA", "a lookup context id was not returned");
lookups[created++] = context;
}
Require(created > 0, "sceNpLookupCreateTitleCtxA", "no context was created");
Require(sceNpLookupCreateTitleCtxA(1) == TooManyObjects, "sceNpLookupCreateTitleCtxA", "the 32-context limit was not applied");
Require(sceNpLookupCreateTitleCtx(selfNpId) == TooManyObjects, "sceNpLookupCreateTitleCtxA", "the A contexts do not share the lookup limit");
for (int index = 0; index < created; ++index) Require(sceNpLookupDeleteTitleCtx(lookups[index]) == 0, "sceNpLookupCreateTitleCtxA", "an A context could not be deleted");
const int filter = sceNpWordFilterCreateTitleCtxA(-1);
Require(filter > WordFilterTitleCtxBase, "sceNpWordFilterCreateTitleCtxA", "a word filter context id was not returned");
Require(sceNpLookupDeleteTitleCtx(filter) == InvalidId, "sceNpWordFilterCreateTitleCtxA", "the context was created among the lookup contexts");
Require(sceNpWordFilterDeleteTitleCtx(filter) == 0, "sceNpWordFilterCreateTitleCtxA", "the context could not be deleted");
}
int main() {
std::memset(selfNpId, 0, sizeof(selfNpId));
std::strcpy(reinterpret_cast<char*>(selfNpId), "player_1");
@@ -243,6 +263,7 @@ int main() {
CheckWordFilter();
CheckLookupAsync();
CheckWordFilterAsync();
CheckTitleContextsA();
if (failures != 0) return 1;
std::puts("NpUtility offline tests passed");
return 0;
+1 -1
View File
@@ -1,6 +1,6 @@
# libSceNpUtility technical debt
- [sceNpLookupCreateTitleCtxA, sceNpWordFilterCreateTitleCtxA](../../../core/libs/prx/libSceNpUtility/Export.cpp) - throw through `NotImplemented_nid_no_patch`; behaviour and the PS5 prototypes are unmeasured. The only source of the parameter lists is shadPS4's PS4-derived prototypes (GPLv2, used as a reference only), with no second reference; structure pointers are `void*` because no layout is known.
- [sceNpLookupCreateTitleCtxA, sceNpWordFilterCreateTitleCtxA](../../../core/libs/prx/libSceNpUtility/Export.cpp) (libSceNpUtility) - not measured on a console: both take only a user id and create a context in the same table and under the same 32-context limit as their NpId forms, as [shadPS4](https://github.com/shadps4-emu/shadPS4/blob/0614ce324be092791b758d79f93d9f1ca5b10a81/src/core/libraries/np/np_utility/np_utility.cpp#L60-L71) and [ghostldr](https://github.com/asylumexp/ghostldr/blob/398ca8e293de4dec05170b38cb9a8a8e56ed8f70/ghostldr/native/ext/src/hle_np.c#L951-L956) do; [fpPS4](https://github.com/red-prig/fpPS4/blob/04cefd43e6fddd1ab033e7980cd356d14c964905/src/np/ps4_libscenputility.pas#L31-L34) has the same lookup prototype. The user id is not checked (as in shadPS4 and `sceNpTusCreateNpTitleCtxA`); ghostldr refuses user id -1 with `INVALID_ARGUMENT`
### Unknown function info
- [sceNpAppInfoIntAbortRequest, sceNpAppInfoIntCheckAvailability, sceNpAppInfoIntCheckAvailabilityA, sceNpAppInfoIntCheckAvailabilityAll, sceNpAppInfoIntCheckAvailabilityAllA and sceNpAppInfoIntCheckServiceAvailability](../../../core/libs/prx/libSceNpUtility/Export.cpp) (libSceNpUtility) - The list is the intersection of the export table of the console's libSceNpUtility (function symbols only), the pinned aerolib names and the functions not yet defined anywhere in the repo; names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceNpUtility.c) and the [verified NID name database](https://github.com/zecoxao/sce_symbols/blob/2883963a0a514ba6e77407a08ef4730a65e88254/aerolib.csv), but no credible prototypes were found. They are declared without parameters solely to resolve known imports; this is not an ABI claim and callers must not call them until signatures are verified.