Files
AnyPS5/docs/dev/debt/libSceNpUniversalDataSystem.md
T
Eduardo Ruiz b11ad4cdd3 feat(libSceNpUniversalDataSystem): implement the Int record builders
Recover the Int record API signatures from the 11.00 wrappers and implement the
initialization, record array, record object and record data builders on top of
the event property array and object types. The host appends typed values, sets
object keys, clones nested values, estimates the MessagePack size and reports
zero memory statistics; the record store and the network post remain
unimplemented.
2026-11-03 10:10:07 +01:00

36 lines
8.7 KiB
Markdown

# libSceNpUniversalDataSystem technical debt
### Silent stubs
- [sceNpUniversalDataSystemRegisterContext](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Context.cpp) (libSceNpUniversalDataSystem) - returns `SCE_NP_UNIVERSAL_DATA_SYSTEM_OK` without checking the context or handle and without recording anything. `sceNpUniversalDataSystemPostEvent` uses only its context and ignores the handle, so nothing depends on the registration. All ten titles in my set call it.
- [sceNpUniversalDataSystemDestroyHandle and sceNpUniversalDataSystemAbortHandle](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Handle.cpp) (libSceNpUniversalDataSystem) - return `SCE_NP_UNIVERSAL_DATA_SYSTEM_OK` without checking the handle. `sceNpUniversalDataSystemCreateHandle` always hands out the same handle and keeps no state, so there is nothing to tear down. All ten titles in my set call `sceNpUniversalDataSystemDestroyHandle`; Metal Gear Solid 4 (PPSA18194) also calls `sceNpUniversalDataSystemAbortHandle`.
### Unknown function info
- [libSceNpUniversalDataSystem additional exports](../../../core/libs/prx/libSceNpUniversalDataSystem/Export.cpp) - these name/NID pairs are present in the 13.60 export inventory. Parameter lists, return types and behavior are unverified. Parameterless `int` declarations are import-resolution placeholders, not verified ABI prototypes; every entry throws through `NotImplemented_nid_no_patch`. No runtime functionality is implemented.
| Name | NID |
| --- | --- |
| `sceNpUniversalDataSystemIntCloseStream` | `pSyd06cKZVk` |
| `sceNpUniversalDataSystemIntDeleteUserData` | `IiSeRSN++Mc` |
| `sceNpUniversalDataSystemIntGetNpCommIdByNpTitleId` | `ONOoGEhy+mg` |
| `sceNpUniversalDataSystemIntGetNpTitleIdListByNpCommId` | `FgmhJGcGztU` |
| `sceNpUniversalDataSystemIntGetObjectState` | `KSHif9MWQjQ` |
| `sceNpUniversalDataSystemIntOpenObjectsDefinitionConfStream` | `O5enyfsJoK0` |
| `sceNpUniversalDataSystemIntOpenObjectsDefinitionConfStreamByObjectId` | `vOdDBWSu-Gk` |
| `sceNpUniversalDataSystemIntOpenStreamByUri` | `tkUOy4Ag4wo` |
| `sceNpUniversalDataSystemIntReadStream` | `ABFxQ2B50RA` |
- [Events](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Event.cpp): `sceNpUniversalDataSystemCreateEvent` copies `prop` and returns the event's own property object through `prop_ptr`, as [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/9e41d8320a2774b303fbad344c2347e8d0292e83/src/libs/libTrophy.cpp) does; `sceNpUniversalDataSystemEventPropertyObjectSetObject`, `SetArray` and the array setters for objects and arrays store a copy of `value` and return the stored copy through `value_ptr`. Destroying a property object or array that its Create function did not return (an event's property object or a stored copy) does nothing, as its owner frees it. These ownership rules are not verified on a console, nor is the text of `sceNpUniversalDataSystemEventToString` (a debug rendering of the event, not the console's format) and the size that `sceNpUniversalDataSystemEventEstimateSize` returns (a MessagePack size model, not measured).
- [sceNpUniversalDataSystemCreateContext](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Context.cpp) and [sceNpUniversalDataSystemCreateHandle](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Handle.cpp) (libSceNpUniversalDataSystem) - native return codes for null output pointers (`context == nullptr` and `handle == nullptr`) are unresolved and unverified on a console. The reimplementation in [KytyPS5](https://github.com/KytyPS5/KytyPS5/blob/9e41d8320a2774b303fbad344c2347e8d0292e83/src/libs/libTrophy.cpp#L620-L640) returns `0x80553102` (`SCE_NP_UNIVERSAL_DATA_SYSTEM_ERROR_INVALID_ARGUMENT`), but this error return is unverified against native hardware; host paths continue to throw `std::invalid_argument` until the native contract is established. No call that could be decoded in the titles checked passes a constant null pointer to either function.
- [sceNpUniversalDataSystemIntAbortHandle, sceNpUniversalDataSystemIntCheckNetSyncTitles, sceNpUniversalDataSystemIntCreateContext, sceNpUniversalDataSystemIntCreateHandle, sceNpUniversalDataSystemIntDeleteAllData and sceNpUniversalDataSystemIntDeleteUserDataWithServerData](../../../core/libs/prx/libSceNpUniversalDataSystem/Export.cpp) (libSceNpUniversalDataSystem) - names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceNpUniversalDataSystem.c), but no credible prototypes were found. They are declared without parameters solely to resolve known imports; this is not an ABI claim, and each throws until its signature is verified
- [sceNpUniversalDataSystemIntDestroyContext, sceNpUniversalDataSystemIntDestroyHandle, sceNpUniversalDataSystemIntInitialize, sceNpUniversalDataSystemIntNetSyncTitles and sceNpUniversalDataSystemIntTerminate](../../../core/libs/prx/libSceNpUniversalDataSystem/Export.cpp) (libSceNpUniversalDataSystem) - names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceNpUniversalDataSystem.c), but no credible prototypes were found. They are declared without parameters solely to resolve known imports; this is not an ABI claim, and each throws until its signature is verified
### Functional
- [Record builders](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Record.cpp) (libSceNpUniversalDataSystem) - the signatures come from the 11.00 wrappers: `IntInitialize` takes a 16-byte `{size, memory}` parameter and rejects another size with `0x80553112`; the create, destroy and setter functions use the confirmed `0x80553101`, `0x80553102`, `0x8055310D`, `0x80553114`, `0x80553115`, `0x80553119` and `0x8055311A` codes. The host models record arrays and objects with the event property array and object types: arrays append typed values, objects set keys, nested values are cloned and the stored copy is returned through `value_ptr`. `IntCreateRecordData` stores the validated type in `recordType` and an empty `context` object. `IntRecordDataEstimateSize` uses the event MessagePack size; the memory pool passed to `IntInitialize` is ignored, so `IntGetMemoryStat` reports zeroes. The console's record store, serialization and estimate are not measured.
- [Trophy events](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Event.cpp): `sceNpUniversalDataSystemPostEvent` stores an `_UnlockTrophy` event with an int32 `_trophy_id` of 0 or more as an unlock for the user and service label of its context, as KytyPS5 does, except an id that [libSceNpTrophy2](../../../core/libs/prx/libSceNpTrophy2/src/TrophyStore.cpp) refuses when the title's trophy data is loaded (one not in the data, a platinum or a progressive trophy). `_UpdateTrophyProgress` goes through the title's statistic rules like any other event (below). A context need not be registered, and every post of an event that `sceNpUniversalDataSystemCreateEvent` returned and that is not yet destroyed returns success (a null or any other event pointer stops the game): KytyPS5's errors for an unknown or unregistered context and for a malformed unlock are not verified. The storage statistics stay zero.
- [Statistics](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Event.cpp): every other event goes through the title's rules in `sce_sys/uds/udsNN.ucp`, which [libSceNpTrophy2](../../../core/libs/prx/libSceNpTrophy2/src/TitleTrophies.cpp) reads. Only `"aggregation":"latest"` and `"max"` statistics of `dataType` `uint32`, `uint64` or `int32` are kept; no public source documents the other aggregations (such as `count`, `collection` and `eachLatest`) or types, so their definitions and rules are skipped. Only rules whose input is a `$.name` path (dotted for nested objects) are applied. A value is used when it is an integer of any width that is not negative and fits the statistic's type and `minValue`/`maxValue`; KytyPS5 requires the statistic's exact width, and whether the console converts, clamps or rejects other values is not known. Statistics are stored per user and service label, and every trophy's `unlockCondition` is compared after each event that sets one.
- [Event checks](../../../core/libs/prx/libSceNpUniversalDataSystem/src/Event.cpp): before `sceNpUniversalDataSystemInitialize` the 13.42 module returns 0x80553117 from the event and property functions (creating, setting, destroying, sizing and describing), even for null arguments; these functions keep no initialized state and run normally. The module's `sceNpUniversalDataSystemCreateEvent` also compares packed sizes with 0x5000 bytes when `prop` is given (read from its disassembly, not measured); this one does not. `sceNpUniversalDataSystemEventToString` writes NaN and infinite properties as `std::to_chars` does; the console's text for them is not measured.