Correct NpScoreRankData structures

This commit is contained in:
Marcin Mikołajczyk 2026-03-27 22:54:21 +01:00
parent 43bb7c4aa7
commit 8d908807e9
2 changed files with 140 additions and 55 deletions

View File

@ -85,8 +85,9 @@ struct NpScoreRequest {
u32 pcId;
std::future<int> requestFuture;
template <typename T>
void GetRankingByRange(OrbisNpScoreBoardId scoreBoardId, OrbisNpScoreRankNumber startRank,
OrbisNpScoreRankDataA* ranks, u64 ranksLen,
T* ranks, u64 ranksLen,
OrbisNpScoreGameInfo* gameInfos, OrbisNpScoreComment* comments,
Rtc::OrbisRtcTick* lastUpdate, OrbisNpScoreRankNumber* totalRecords) {
requestFuture = std::async(std::launch::async, [=]() {
@ -108,17 +109,23 @@ struct NpScoreRequest {
auto json_ranks = json["ranks"];
auto ranks_obtained = 0;
for (auto r : json_ranks) {
strcpy(ranks[ranks_obtained].onlineId.data, "shadps4");
if constexpr (std::is_same_v<T, OrbisNpScoreRankData>) {
strcpy(ranks[ranks_obtained].npId.handle.data, "shadps4");
} else if constexpr (std::is_same_v<T, OrbisNpScoreRankDataA>) {
strcpy(ranks[ranks_obtained].onlineId.data, "shadps4");
ranks[ranks_obtained].accountId = r["id"]["accountId"].get<u64>();
} else {
static_assert(false, "unsupported type");
}
ranks[ranks_obtained].pcId = r["id"]["pcId"].get<u32>();
// most probably not correct but need more RE to figure out what are the
// different ranks here
ranks[ranks_obtained].rank1 = r["rank"].get<u32>();
ranks[ranks_obtained].rank2 = r["rank"].get<u32>();
ranks[ranks_obtained].rank3 = r["rank"].get<u32>();
ranks[ranks_obtained].serialRank = r["rank"].get<u32>();
ranks[ranks_obtained].rank = r["rank"].get<u32>();
ranks[ranks_obtained].highestRank = r["rank"].get<u32>();
ranks[ranks_obtained].hasGameData = false;
ranks[ranks_obtained].score = r["score"].get<s64>();
Libraries::Rtc::sceRtcGetCurrentTick(&ranks[ranks_obtained].recordTime);
ranks[ranks_obtained].accountId = r["id"]["accountId"].get<u64>();
if (gameInfos && r.contains("gameInfo")) {
std::vector<u8> decoded = base64::decode(r["gameInfo"].get<std::string>());
gameInfos[ranks_obtained].dataSize = decoded.size();
@ -571,19 +578,9 @@ int PS4_SYSV_ABI sceNpScoreGetRankingByNpIdPcId(
return -1; //?
}
int PS4_SYSV_ABI sceNpScoreGetRankingByRange() {
LOG_ERROR(Lib_NpScore, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpScoreGetRankingByRangeA() {
LOG_ERROR(Lib_NpScore, "(STUBBED) called");
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpScoreGetRankingByRangeAsync(
int reqId, OrbisNpScoreBoardId scoreBoardId, OrbisNpScoreRankNumber startRank,
OrbisNpScoreRankDataA* ranks, u64 ranksBytes, OrbisNpScoreComment* comments, u64 commentsBytes,
OrbisNpScoreRankData* ranks, u64 ranksBytes, OrbisNpScoreComment* comments, u64 commentsBytes,
OrbisNpScoreGameInfo* gameInfos, u64 gameInfosBytes, u64 ranksLen,
Rtc::OrbisRtcTick* lastUpdate, OrbisNpScoreRankNumber* totalRecords, void* option) {
LOG_ERROR(Lib_NpScore,
@ -624,15 +621,102 @@ int PS4_SYSV_ABI sceNpScoreGetRankingByRangeAsync(
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpScoreGetRankingByRange(
int reqId, OrbisNpScoreBoardId scoreBoardId, OrbisNpScoreRankNumber startRank,
OrbisNpScoreRankData* ranks, u64 ranksBytes, OrbisNpScoreComment* comments, u64 commentsBytes,
OrbisNpScoreGameInfo* gameInfos, u64 gameInfosBytes, u64 ranksLen,
Rtc::OrbisRtcTick* lastUpdate, OrbisNpScoreRankNumber* totalRecords, void* option) {
LOG_ERROR(Lib_NpScore,
"(STUBBED) called, reqId = {:#x}, scoreBoardId = {}, startRank = {}, ranks = {}, "
"comments = {}, gameInfos = {}, ranksLen = {}",
reqId, scoreBoardId, startRank, fmt::ptr(ranks), fmt::ptr(comments),
fmt::ptr(gameInfos), ranksLen);
int ret = sceNpScoreGetRankingByRangeAsync(
reqId, scoreBoardId, startRank, ranks, ranksBytes, comments,
commentsBytes, gameInfos, gameInfosBytes, ranksLen, lastUpdate, totalRecords, option);
if (ret < 0) {
return ret;
}
int result = 0;
if (sceNpScoreWaitAsync(reqId, &result) == 0) {
return result;
}
return -1; //?
}
int PS4_SYSV_ABI sceNpScoreGetRankingByRangeAAsync(
int reqId, OrbisNpScoreBoardId scoreBoardId, OrbisNpScoreRankNumber startRank,
OrbisNpScoreRankDataA* ranks, u64 ranksBytes, OrbisNpScoreComment* comments, u64 commentsBytes,
OrbisNpScoreGameInfo* gameInfos, u64 gameInfosBytes, u64 ranksLen,
Rtc::OrbisRtcTick* lastUpdate, OrbisNpScoreRankNumber* totalRecords, void* option) {
// at least in 9.00 it's identical A vs non-A
return sceNpScoreGetRankingByRangeAsync(reqId, scoreBoardId, startRank, ranks, ranksBytes,
comments, commentsBytes, gameInfos, gameInfosBytes,
ranksLen, lastUpdate, totalRecords, option);
LOG_ERROR(Lib_NpScore,
"(STUBBED) called, reqId = {:#x}, scoreBoardId = {}, startRank = {}, ranks = {}, "
"comments = {}, gameInfos = {}, ranksLen = {}",
reqId, scoreBoardId, startRank, fmt::ptr(ranks), fmt::ptr(comments),
fmt::ptr(gameInfos), ranksLen);
if (ranksLen * sizeof(*ranks) != ranksBytes) {
return ORBIS_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT;
}
if (startRank == 0 || option != nullptr || ranksLen > 100) {
return ORBIS_NP_COMMUNITY_ERROR_INVALID_ARGUMENT;
}
// if sdk version > 1.70 zero all of the provided buffers
if (ranks == nullptr || ranksLen == 0) {
return ORBIS_NP_COMMUNITY_ERROR_INSUFFICIENT_ARGUMENT;
}
if (comments) {
if (ranksLen * sizeof(*comments) != commentsBytes) {
return ORBIS_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT;
}
}
if (gameInfos) {
if (ranksLen * sizeof(*gameInfos) != gameInfosBytes) {
return ORBIS_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT;
}
}
NpScoreRequest* req = nullptr;
if (auto ret = GetRequest(reqId, &req); ret < 0) {
return ret;
}
req->GetRankingByRange(scoreBoardId, startRank, ranks, ranksLen, gameInfos, comments,
lastUpdate, totalRecords);
return ORBIS_OK;
}
int PS4_SYSV_ABI sceNpScoreGetRankingByRangeA(
int reqId, OrbisNpScoreBoardId scoreBoardId, OrbisNpScoreRankNumber startRank,
OrbisNpScoreRankDataA* ranks, u64 ranksBytes, OrbisNpScoreComment* comments, u64 commentsBytes,
OrbisNpScoreGameInfo* gameInfos, u64 gameInfosBytes, u64 ranksLen,
Rtc::OrbisRtcTick* lastUpdate, OrbisNpScoreRankNumber* totalRecords, void* option) {
LOG_ERROR(Lib_NpScore,
"(STUBBED) called, reqId = {:#x}, scoreBoardId = {}, startRank = {}, ranks = {}, "
"comments = {}, gameInfos = {}, ranksLen = {}",
reqId, scoreBoardId, startRank, fmt::ptr(ranks), fmt::ptr(comments),
fmt::ptr(gameInfos), ranksLen);
int ret = sceNpScoreGetRankingByRangeAAsync(
reqId, scoreBoardId, startRank, ranks, ranksBytes, comments,
commentsBytes, gameInfos, gameInfosBytes, ranksLen, lastUpdate, totalRecords, option);
if (ret < 0) {
return ret;
}
int result = 0;
if (sceNpScoreWaitAsync(reqId, &result) == 0) {
return result;
}
return -1; //?
}
int PS4_SYSV_ABI sceNpScoreGetRankingByRangeForCrossSave() {

View File

@ -32,48 +32,41 @@ struct OrbisNpScoreAccountIdPcId {
u8 pad[4];
};
struct OrbisNpScoreRankDataA {
OrbisNpOnlineId onlineId;
u8 reserved[68];
OrbisNpScorePcId pcId;
OrbisNpScoreRankNumber rank1;
OrbisNpScoreRankNumber rank2;
OrbisNpScoreRankNumber rank3;
int hasGameData;
u8 pad[4];
OrbisNpScoreValue score;
Rtc::OrbisRtcTick recordTime;
OrbisNpAccountId accountId;
u8 pad1[8];
};
static_assert(sizeof(OrbisNpScoreRankDataA) == 0x90);
struct OrbisNpScorePlayerRankDataA {
int hasData;
u8 pad[4];
OrbisNpScoreRankDataA rankData;
};
static_assert(sizeof(OrbisNpScorePlayerRankDataA) == 0x98);
struct OrbisNpScoreRankData {
OrbisNpOnlineId onlineId;
u8 reserved[52];
OrbisNpId npId;
u8 reserved[49];
u8 pad0[3];
OrbisNpScorePcId pcId;
OrbisNpScoreRankNumber rank1;
OrbisNpScoreRankNumber rank2;
OrbisNpScoreRankNumber rank3;
int hasGameData;
u8 pad[4];
OrbisNpScoreRankNumber serialRank;
OrbisNpScoreRankNumber rank;
OrbisNpScoreRankNumber highestRank;
OrbisNpScoreValue score;
int hasGameData;
u8 pad1[4];
Rtc::OrbisRtcTick recordTime;
OrbisNpAccountId accountId;
u8 pad1[8];
};
static_assert(sizeof(OrbisNpScoreRankData) == 0x80);
struct OrbisNpScoreRankDataA {
OrbisNpOnlineId onlineId;
u8 reserved0[16];
u8 reserved[49];
u8 pad0[3];
OrbisNpScorePcId pcId;
OrbisNpScoreRankNumber serialRank;
OrbisNpScoreRankNumber rank;
OrbisNpScoreRankNumber highestRank;
int hasGameData;
u8 pad1[4];
OrbisNpScoreValue score;
Rtc::OrbisRtcTick recordTime;
OrbisNpAccountId accountId;
u8 pad2[8];
};
static_assert(sizeof(OrbisNpScoreRankDataA) == 0x90);
struct OrbisNpScorePlayerRankData {
int hasData;
u8 pad[4];
@ -82,6 +75,14 @@ struct OrbisNpScorePlayerRankData {
static_assert(sizeof(OrbisNpScorePlayerRankData) == 0x88);
struct OrbisNpScorePlayerRankDataA {
int hasData;
u8 pad[4];
OrbisNpScoreRankDataA rankData;
};
static_assert(sizeof(OrbisNpScorePlayerRankDataA) == 0x98);
struct OrbisNpScoreComment {
char comment[64];
};