diff --git a/src/common/elf_info.h b/src/common/elf_info.h index 8f79c9e69..661f911d8 100644 --- a/src/common/elf_info.h +++ b/src/common/elf_info.h @@ -8,6 +8,7 @@ #include #include +#include #include "assert.h" #include "bit_field.h" #include "singleton.h" @@ -75,6 +76,7 @@ class ElfInfo { std::filesystem::path splash_path{}; std::filesystem::path game_folder{}; std::vector npCommIds{}; + std::map trophyIndexMap{}; public: static constexpr u32 FW_10 = 0x1000000; @@ -145,6 +147,10 @@ public: [[nodiscard]] const std::vector GetNpCommIds() const { return npCommIds; } + + [[nodiscard]] const std::map& GetTrophyIndexMap() const { + return trophyIndexMap; + } }; } // namespace Common diff --git a/src/core/file_format/trp.cpp b/src/core/file_format/trp.cpp index 6269fc6c7..76fa5a1f0 100644 --- a/src/core/file_format/trp.cpp +++ b/src/core/file_format/trp.cpp @@ -44,13 +44,35 @@ static void hexToBytes(const char* hex, unsigned char* dst) { bool TRP::Extract(const std::filesystem::path& trophyPath, int index, std::string npCommId, const std::filesystem::path& outputPath) { - std::filesystem::path gameSysDir = - trophyPath / "sce_sys/trophy/" / std::format("trophy{:02d}.trp", index); - if (!std::filesystem::exists(gameSysDir)) { - LOG_WARNING(Common_Filesystem, "Game trophy directory doesn't exist"); + + std::filesystem::path trophyDir = trophyPath / "sce_sys/trophy"; + + if (!std::filesystem::exists(trophyDir)) { + LOG_WARNING(Common_Filesystem, "Trophy directory doesn't exist: {}", trophyDir.string()); return false; } + // Collect all .trp files in the directory + std::vector trpFiles; + for (const auto& entry : std::filesystem::directory_iterator(trophyDir)) { + if (entry.is_regular_file() && entry.path().extension() == ".trp") { + trpFiles.push_back(entry.path()); + } + } + + // Sort files to ensure consistent ordering + std::sort(trpFiles.begin(), trpFiles.end()); + + if (index >= trpFiles.size()) { + LOG_WARNING(Common_Filesystem, "Trophy index {} out of range (only {} .trp files found)", + index, trpFiles.size()); + return false; + } + + // Select the file at the given index + std::filesystem::path gameSysDir = trpFiles[index]; + LOG_INFO(Common_Filesystem, "Using trophy file: {}", gameSysDir.filename().string()); + const auto& user_key_vec = KeyManager::GetInstance()->GetAllKeys().TrophyKeySet.ReleaseTrophyKey; diff --git a/src/core/libraries/np/np_trophy.cpp b/src/core/libraries/np/np_trophy.cpp index 449ee775a..0e8990c81 100644 --- a/src/core/libraries/np/np_trophy.cpp +++ b/src/core/libraries/np/np_trophy.cpp @@ -219,7 +219,16 @@ s32 PS4_SYSV_ABI sceNpTrophyCreateContext(OrbisNpTrophyContext* context, ctx.context_id = *context; // Resolve and cache all paths once so callers never recompute them. - const std::string np_comm_id = Common::ElfInfo::Instance().GetNpCommIds()[service_label]; + std::string np_comm_id; + const auto& trophyMap = Common::ElfInfo::Instance().GetTrophyIndexMap(); + auto it = trophyMap.find(service_label); + if (it != trophyMap.end()) { + np_comm_id = it->second; + } else { + LOG_ERROR(Lib_NpTrophy, "No npCommId found for trophy index/service_label: {}", + service_label); + return ORBIS_NP_TROPHY_ERROR_UNKNOWN; + } const auto trophy_base = Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "trophy" / np_comm_id; ctx.xml_save_file = diff --git a/src/emulator.cpp b/src/emulator.cpp index 040a4272e..d9d0103e0 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -201,6 +201,7 @@ void Emulator::Run(std::filesystem::path file, std::vector args, game_info.game_folder = game_folder; std::filesystem::path npbindPath = game_folder / "sce_sys/npbind.dat"; + std::filesystem::path trophyDir = game_folder / "sce_sys/trophy"; NPBindFile npbind; if (!npbind.Load(npbindPath.string())) { LOG_WARNING(Common_Filesystem, "Failed to load npbind.dat file"); @@ -209,6 +210,34 @@ void Emulator::Run(std::filesystem::path file, std::vector args, if (npCommIds.empty()) { LOG_WARNING(Common_Filesystem, "No NPComm IDs found in npbind.dat"); } else { + std::vector> trophyFiles; // (trophy_index, filename) + std::string pattern = "trophy"; + for (const auto& entry : std::filesystem::directory_iterator(trophyDir)) { + if (entry.is_regular_file() && entry.path().extension() == ".trp") { + std::string filename = + entry.path().stem().string(); // "trophy00", "trophy01", etc. + + // Check if filename starts with "trophy" + if (filename.find(pattern) == 0) { + // Extract the number part + std::string numStr = filename.substr(pattern.length()); + int trophy_index = std::stoi(numStr); + trophyFiles.emplace_back(trophy_index, filename); + } + } + } + // Sort by trophy index + std::sort(trophyFiles.begin(), trophyFiles.end()); + std::map trophyIndexMap{}; + // Map trophy indices to npCommIds (assuming npCommIds are in the same order as sorted + // trophy files) + for (size_t i = 0; i < trophyFiles.size() && i < npCommIds.size(); i++) { + int trophy_index = trophyFiles[i].first; + const std::string& npCommId = npCommIds[i]; + trophyIndexMap[trophy_index] = npCommId; + LOG_DEBUG(Loader, "Mapped trophy index {} to npCommId: {}", trophy_index, npCommId); + } + game_info.trophyIndexMap = std::move(trophyIndexMap); game_info.npCommIds = std::move(npCommIds); } }