fixed trophy extraction (#4254)

* fixed trophy extraction

* opps

* fixing indexing in np_trophy

* fix
This commit is contained in:
georgemoralis 2026-04-13 01:23:00 +03:00 committed by GitHub
parent 311c2dd1cd
commit 1c8ace6619
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 71 additions and 5 deletions

View File

@ -8,6 +8,7 @@
#include <string_view>
#include <vector>
#include <map>
#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<std::string> npCommIds{};
std::map<int, std::string> trophyIndexMap{};
public:
static constexpr u32 FW_10 = 0x1000000;
@ -145,6 +147,10 @@ public:
[[nodiscard]] const std::vector<std::string> GetNpCommIds() const {
return npCommIds;
}
[[nodiscard]] const std::map<int, std::string>& GetTrophyIndexMap() const {
return trophyIndexMap;
}
};
} // namespace Common

View File

@ -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<std::filesystem::path> 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;

View File

@ -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 =

View File

@ -201,6 +201,7 @@ void Emulator::Run(std::filesystem::path file, std::vector<std::string> 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<std::string> args,
if (npCommIds.empty()) {
LOG_WARNING(Common_Filesystem, "No NPComm IDs found in npbind.dat");
} else {
std::vector<std::pair<int, std::string>> 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<int, std::string> 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);
}
}