diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 1477d831d8..d8ece152a4 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -5829,8 +5829,10 @@ error_code scenp_score_get_ranking_by_npid(s32 transId, SceNpScoreBoardId boardI return SCE_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT; } - // Function can actually accept SceNpScoreRankData though it is undocumented - if (rankArraySize != (arrayNum * sizeof(SceNpScorePlayerRankData)) && rankArraySize != (arrayNum * sizeof(SceNpScoreRankData))) + // SceNpScorePlayerRankData changed with 180.002 + const bool deprecated = (rankArraySize == (arrayNum * sizeof(SceNpScorePlayerRankData_deprecated))); + + if (rankArraySize != (arrayNum * sizeof(SceNpScorePlayerRankData)) && !deprecated) { return SCE_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT; } @@ -5866,7 +5868,7 @@ error_code scenp_score_get_ranking_by_npid(s32 transId, SceNpScoreBoardId boardI } } - nph.get_score_npid(trans_ctx, boardId, npid_vec, rankArray, rankArraySize, commentArray, commentArraySize, infoArray, infoArraySize, arrayNum, lastSortDate, totalRecord, async); + nph.get_score_npid(trans_ctx, boardId, npid_vec, rankArray, rankArraySize, commentArray, commentArraySize, infoArray, infoArraySize, arrayNum, lastSortDate, totalRecord, async, deprecated); if (async) { @@ -5957,7 +5959,10 @@ error_code scenp_score_get_ranking_by_range(s32 transId, SceNpScoreBoardId board return SCE_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT; } - if (rankArraySize != (arrayNum * sizeof(SceNpScoreRankData))) + // SceNpScoreRankData changed with 180.002 + const bool deprecated = (rankArraySize == (arrayNum * sizeof(SceNpScoreRankData_deprecated))); + + if (rankArraySize != (arrayNum * sizeof(SceNpScoreRankData)) && !deprecated) { return SCE_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT; } @@ -5967,7 +5972,7 @@ error_code scenp_score_get_ranking_by_range(s32 transId, SceNpScoreBoardId board return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - nph.get_score_range(trans_ctx, boardId, startSerialRank, rankArray, rankArraySize, commentArray, commentArraySize, infoArray, infoArraySize, arrayNum, lastSortDate, totalRecord, async); + nph.get_score_range(trans_ctx, boardId, startSerialRank, rankArray, rankArraySize, commentArray, commentArraySize, infoArray, infoArraySize, arrayNum, lastSortDate, totalRecord, async, deprecated); if (async) { @@ -6036,7 +6041,10 @@ error_code scenp_score_get_friends_ranking(s32 transId, SceNpScoreBoardId boardI return SCE_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT; } - if (rankArraySize != (arrayNum * sizeof(SceNpScoreRankData))) + // The SceNpScoreRankData changed with 180.002 + const bool deprecated = (rankArraySize == (arrayNum * sizeof(SceNpScoreRankData_deprecated))); + + if (rankArraySize != (arrayNum * sizeof(SceNpScoreRankData)) && !deprecated) { return SCE_NP_COMMUNITY_ERROR_INVALID_ALIGNMENT; } @@ -6046,7 +6054,7 @@ error_code scenp_score_get_friends_ranking(s32 transId, SceNpScoreBoardId boardI return SCE_NP_COMMUNITY_ERROR_INVALID_ONLINE_ID; } - nph.get_score_friend(trans_ctx, boardId, includeSelf, rankArray, rankArraySize, commentArray, commentArraySize, infoArray, infoArraySize, arrayNum, lastSortDate, totalRecord, async); + nph.get_score_friend(trans_ctx, boardId, includeSelf, rankArray, rankArraySize, commentArray, commentArraySize, infoArray, infoArraySize, arrayNum, lastSortDate, totalRecord, async, deprecated); if (async) { diff --git a/rpcs3/Emu/Cell/Modules/sceNp.h b/rpcs3/Emu/Cell/Modules/sceNp.h index c92fd97605..e32dba27b5 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.h +++ b/rpcs3/Emu/Cell/Modules/sceNp.h @@ -1434,6 +1434,19 @@ struct SceNpScoreRankData CellRtcTick recordDate; }; +// Version of SceNpScoreRankData that was deprecated in 180.002 +struct SceNpScoreRankData_deprecated +{ + SceNpId npId; + SceNpOnlineName onlineName; + be_t serialRank; + be_t rank; + be_t highestRank; + be_t hasGameData; + be_t scoreValue; + CellRtcTick recordDate; +}; + // Ranking information of a player or a clan member struct SceNpScorePlayerRankData { @@ -1442,6 +1455,14 @@ struct SceNpScorePlayerRankData SceNpScoreRankData rankData; }; +// Version of SceNpScorePlayerRankData that was deprecated in 180.002 +struct SceNpScorePlayerRankData_deprecated +{ + be_t hasData; + u8 pad0[4]; + SceNpScoreRankData_deprecated rankData; +}; + // Scoreboard information struct SceNpScoreBoardInfo { diff --git a/rpcs3/Emu/NP/np_contexts.h b/rpcs3/Emu/NP/np_contexts.h index d7824daf76..3a9b7e46f6 100644 --- a/rpcs3/Emu/NP/np_contexts.h +++ b/rpcs3/Emu/NP/np_contexts.h @@ -77,6 +77,8 @@ struct tdata_get_score_generic u32 arrayNum = 0; vm::ptr lastSortDate; vm::ptr totalRecord; + bool player_rank_data = false; + bool deprecated = false; }; // TUS transaction data diff --git a/rpcs3/Emu/NP/np_handler.h b/rpcs3/Emu/NP/np_handler.h index 5aee2547f9..1345cc0803 100644 --- a/rpcs3/Emu/NP/np_handler.h +++ b/rpcs3/Emu/NP/np_handler.h @@ -181,9 +181,9 @@ namespace np void record_score(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, vm::cptr scoreComment, const u8* data, u32 data_size, vm::ptr tmpRank, bool async); void record_score_data(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreValue score, u32 totalSize, u32 sendSize, const u8* score_data, bool async); void get_score_data(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const SceNpId& npId, vm::ptr totalSize, u32 recvSize, vm::ptr score_data, bool async); - void get_score_range(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async); - void get_score_npid(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async); - void get_score_friend(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async); + void get_score_range(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); + void get_score_npid(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); + void get_score_friend(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated); // TUS requests void tus_set_multislot_variable(std::shared_ptr& trans_ctx, const SceNpOnlineId& targetNpId, vm::cptr slotIdArray, vm::cptr variableArray, s32 arrayNum, bool vuser, bool async); diff --git a/rpcs3/Emu/NP/np_requests.cpp b/rpcs3/Emu/NP/np_requests.cpp index 418fe79145..05cf8c675f 100644 --- a/rpcs3/Emu/NP/np_requests.cpp +++ b/rpcs3/Emu/NP/np_requests.cpp @@ -1062,7 +1062,7 @@ namespace np return score_trans->set_result_and_wake(not_an_error(to_copy)); } - void np_handler::get_score_range(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async) + void np_handler::get_score_range(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, SceNpScoreRankNumber startSerialRank, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) { std::unique_lock lock(trans_ctx->mutex); u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); @@ -1076,6 +1076,8 @@ namespace np .arrayNum = arrayNum, .lastSortDate = lastSortDate, .totalRecord = totalRecord, + .player_rank_data = false, + .deprecated = deprecated, }; bool with_comments = !!commentArray; @@ -1086,6 +1088,25 @@ namespace np transaction_async_handler(std::move(lock), trans_ctx, req_id, async); } + template + void set_rankdata_values(T& cur_rank, const ScoreRankData* fb_rankdata) + { + string_to_npid(fb_rankdata->npId()->string_view(), cur_rank.npId); + string_to_online_name(fb_rankdata->onlineName()->string_view(), cur_rank.onlineName); + + static_assert(std::is_same_v || std::is_same_v); + + if constexpr (std::is_same_v) + cur_rank.pcId = fb_rankdata->pcId(); + + cur_rank.serialRank = fb_rankdata->rank(); + cur_rank.rank = fb_rankdata->rank(); + cur_rank.highestRank = fb_rankdata->rank(); + cur_rank.scoreValue = fb_rankdata->score(); + cur_rank.hasGameData = fb_rankdata->hasGameData(); + cur_rank.recordDate.tick = fb_rankdata->recordDate(); + } + bool np_handler::handle_GetScoreResponse(u32 req_id, std::vector& reply_data, bool simple_result) { std::lock_guard lock_trans(mutex_async_transactions); @@ -1120,8 +1141,10 @@ namespace np memset(tdata->rankArray.get_ptr(), 0, tdata->rankArraySize); auto* fb_rankarray = resp->rankArray(); - vm::ptr rankArray = vm::static_ptr_cast(tdata->rankArray); vm::ptr rankPlayerArray = vm::static_ptr_cast(tdata->rankArray); + vm::ptr rankPlayerArray_deprecated = vm::static_ptr_cast(tdata->rankArray); + vm::ptr rankArray = vm::static_ptr_cast(tdata->rankArray); + vm::ptr rankArray_deprecated = vm::static_ptr_cast(tdata->rankArray); for (flatbuffers::uoffset_t i = 0; i < fb_rankarray->size(); i++) { @@ -1131,27 +1154,30 @@ namespace np if (fb_rankdata->recordDate() == 0) continue; - SceNpScoreRankData* cur_rank; - if (tdata->rankArraySize == (tdata->arrayNum * sizeof(SceNpScoreRankData))) + if (tdata->player_rank_data) { - cur_rank = &rankArray[i]; + if (tdata->deprecated) + { + rankPlayerArray_deprecated[i].hasData = 1; + set_rankdata_values(rankPlayerArray_deprecated[i].rankData, fb_rankdata); + } + else + { + rankPlayerArray[i].hasData = 1; + set_rankdata_values(rankPlayerArray[i].rankData, fb_rankdata); + } } else { - rankPlayerArray[i].hasData = 1; - cur_rank = &rankPlayerArray[i].rankData; + if (tdata->deprecated) + { + set_rankdata_values(rankArray_deprecated[i], fb_rankdata); + } + else + { + set_rankdata_values(rankArray[i], fb_rankdata); + } } - - string_to_npid(fb_rankdata->npId()->string_view(), cur_rank->npId); - string_to_online_name(fb_rankdata->onlineName()->string_view(), cur_rank->onlineName); - - cur_rank->pcId = fb_rankdata->pcId(); - cur_rank->serialRank = fb_rankdata->rank(); - cur_rank->rank = fb_rankdata->rank(); - cur_rank->highestRank = fb_rankdata->rank(); - cur_rank->scoreValue = fb_rankdata->score(); - cur_rank->hasGameData = fb_rankdata->hasGameData(); - cur_rank->recordDate.tick = fb_rankdata->recordDate(); } if (tdata->commentArray) @@ -1214,7 +1240,7 @@ namespace np return handle_GetScoreResponse(req_id, reply_data); } - void np_handler::get_score_friend(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async) + void np_handler::get_score_friend(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, bool include_self, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) { std::unique_lock lock(trans_ctx->mutex); u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); @@ -1227,6 +1253,8 @@ namespace np .arrayNum = arrayNum, .lastSortDate = lastSortDate, .totalRecord = totalRecord, + .player_rank_data = false, + .deprecated = deprecated, }; bool with_comments = !!commentArray; @@ -1241,7 +1269,7 @@ namespace np return handle_GetScoreResponse(req_id, reply_data); } - void np_handler::get_score_npid(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async) + void np_handler::get_score_npid(std::shared_ptr& trans_ctx, SceNpScoreBoardId boardId, const std::vector>& npid_vec, vm::ptr rankArray, u32 rankArraySize, vm::ptr commentArray, [[maybe_unused]] u32 commentArraySize, vm::ptr infoArray, u32 infoArraySize, u32 arrayNum, vm::ptr lastSortDate, vm::ptr totalRecord, bool async, bool deprecated) { std::unique_lock lock(trans_ctx->mutex); u32 req_id = get_req_id(REQUEST_ID_HIGH::SCORE); @@ -1254,6 +1282,8 @@ namespace np .arrayNum = arrayNum, .lastSortDate = lastSortDate, .totalRecord = totalRecord, + .player_rank_data = true, + .deprecated = deprecated, }; bool with_comments = !!commentArray; diff --git a/rpcs3/Emu/NP/np_structs_extra.cpp b/rpcs3/Emu/NP/np_structs_extra.cpp index dd73974031..1a3b8c5a8b 100644 --- a/rpcs3/Emu/NP/np_structs_extra.cpp +++ b/rpcs3/Emu/NP/np_structs_extra.cpp @@ -411,4 +411,31 @@ namespace extra_nps sceNp.warning("markedAsUsed: %d", data->markedAsUsed); } + void print_SceNpScoreRankData(const SceNpScoreRankData* data) + { + sceNp.warning("sceNpScoreRankData:"); + sceNp.warning("npId: %s", static_cast(data->npId.handle.data)); + sceNp.warning("onlineName: %s", static_cast(data->onlineName.data)); + sceNp.warning("pcId: %d", data->pcId); + sceNp.warning("serialRank: %d", data->serialRank); + sceNp.warning("rank: %d", data->rank); + sceNp.warning("highestRank: %d", data->highestRank); + sceNp.warning("scoreValue: %d", data->scoreValue); + sceNp.warning("hasGameData: %d", data->hasGameData); + sceNp.warning("recordDate: %d", data->recordDate.tick); + } + + void print_SceNpScoreRankData_deprecated(const SceNpScoreRankData_deprecated* data) + { + sceNp.warning("sceNpScoreRankData_deprecated:"); + sceNp.warning("npId: %s", static_cast(data->npId.handle.data)); + sceNp.warning("onlineName: %s", static_cast(data->onlineName.data)); + sceNp.warning("serialRank: %d", data->serialRank); + sceNp.warning("rank: %d", data->rank); + sceNp.warning("highestRank: %d", data->highestRank); + sceNp.warning("scoreValue: %d", data->scoreValue); + sceNp.warning("hasGameData: %d", data->hasGameData); + sceNp.warning("recordDate: %d", data->recordDate.tick); + } + } // namespace extra_nps diff --git a/rpcs3/Emu/NP/np_structs_extra.h b/rpcs3/Emu/NP/np_structs_extra.h index b2be20d42b..418a828719 100644 --- a/rpcs3/Emu/NP/np_structs_extra.h +++ b/rpcs3/Emu/NP/np_structs_extra.h @@ -27,4 +27,7 @@ namespace extra_nps void print_SceNpBasicAttachmentData(const SceNpBasicAttachmentData* data); void print_SceNpBasicExtendedAttachmentData(const SceNpBasicExtendedAttachmentData* data); + + void print_SceNpScoreRankData(const SceNpScoreRankData* data); + void print_SceNpScoreRankData_deprecated(const SceNpScoreRankData_deprecated* data); } // namespace extra_nps