Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve trophy context loader #10000

Merged
merged 2 commits into from May 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions rpcs3/Emu/Cell/Modules/sceNpTrophy.cpp
Expand Up @@ -578,11 +578,11 @@ error_code sceNpTrophyRegisterContext(ppu_thread& ppu, u32 context, u32 handle,
return SCE_NP_TROPHY_ERROR_ILLEGAL_UPDATE;
}

TROPUSRLoader* tropusr = new TROPUSRLoader();
const auto& tropusr = ctxt->tropusr = std::make_unique<TROPUSRLoader>();
const std::string trophyUsrPath = trophyPath + "/TROPUSR.DAT";
const std::string trophyConfPath = trophyPath + "/TROPCONF.SFM";
tropusr->Load(trophyUsrPath, trophyConfPath);
ctxt->tropusr.reset(tropusr);

ensure(tropusr->Load(trophyUsrPath, trophyConfPath).success);

// This emulates vsh sending the events and ensures that not 2 events are processed at once
const std::pair<u32, s32> statuses[] =
Expand Down
68 changes: 41 additions & 27 deletions rpcs3/Loader/TROPUSR.cpp
Expand Up @@ -5,25 +5,52 @@

LOG_CHANNEL(trp_log, "Trophy");

bool TROPUSRLoader::Load(const std::string& filepath, const std::string& configpath)
enum : u32
{
TROPUSR_MAGIC = 0x818F54AD
};

TROPUSRLoader::load_result TROPUSRLoader::Load(const std::string& filepath, const std::string& configpath)
{
const std::string& path = vfs::get(filepath);

if (!m_file.open(path, fs::read))
load_result res{};

// Generate TROPUSR.DAT
auto generate = [&]
{
if (!Generate(filepath, configpath))
// Reset filesystem error
fs::g_tls_error = fs::error::ok;

// Generate TROPUSR.DAT if not existing
res.success = Generate(filepath, configpath);

if (!res.success)
{
return false;
trp_log.error("TROPUSRLoader::Load(): Failed to generate TROPUSR.DAT (path='%s', cfg='%s', %s)", path, configpath, fs::g_tls_error);
}

m_file.close();
return res;
};

if (!m_file.open(path))
{
return generate();
}

if (!LoadHeader() || !LoadTableHeaders() || !LoadTables())
{
return false;
// Ignore existing TROPUSR.DAT because it is invalid
m_file.close();
res.discarded_existing = true;
trp_log.error("TROPUSRLoader::Load(): Failed to load existing TROPUSR.DAT, trying to generate new file with empty trophies history! (path='%s')", path);
return generate();
}

m_file.release();
return true;
m_file.close();
res.success = true;
return res;
}

bool TROPUSRLoader::LoadHeader()
Expand All @@ -35,7 +62,7 @@ bool TROPUSRLoader::LoadHeader()

m_file.seek(0);

if (!m_file.read(m_header))
if (!m_file.read(m_header) || m_header.magic != TROPUSR_MAGIC)
{
return false;
}
Expand Down Expand Up @@ -105,21 +132,9 @@ bool TROPUSRLoader::Save(const std::string& filepath)
}

temp.file.write(m_header);

for (const TROPUSRTableHeader& tableHeader : m_tableHeaders)
{
temp.file.write(tableHeader);
}

for (const auto& entry : m_table4)
{
temp.file.write(entry);
}

for (const auto& entry : m_table6)
{
temp.file.write(entry);
}
temp.file.write(m_tableHeaders);
temp.file.write(m_table4);
temp.file.write(m_table6);

return temp.commit();
}
Expand Down Expand Up @@ -180,14 +195,13 @@ bool TROPUSRLoader::Generate(const std::string& filepath, const std::string& con
m_tableHeaders.push_back(table4header);
m_tableHeaders.push_back(table6header);

m_header.magic = 0x818F54AD;
std::memset(&m_header, 0, sizeof(m_header));
m_header.magic = TROPUSR_MAGIC;
m_header.unk1 = 0x00010000;
m_header.tables_count = ::size32(m_tableHeaders);
m_header.unk2 = 0;

Save(filepath);

return true;
return Save(filepath);
}

u32 TROPUSRLoader::GetTrophiesCount()
Expand Down
8 changes: 7 additions & 1 deletion rpcs3/Loader/TROPUSR.h
Expand Up @@ -80,7 +80,13 @@ class TROPUSRLoader
public:
virtual ~TROPUSRLoader() = default;

virtual bool Load(const std::string& filepath, const std::string& configpath);
struct load_result
{
bool discarded_existing;
bool success;
};

virtual load_result Load(const std::string& filepath, const std::string& configpath);
virtual bool Save(const std::string& filepath);

virtual u32 GetTrophiesCount();
Expand Down
2 changes: 1 addition & 1 deletion rpcs3/rpcs3qt/trophy_manager_dialog.cpp
Expand Up @@ -358,7 +358,7 @@ bool trophy_manager_dialog::LoadTrophyFolderToDB(const std::string& trop_name)
game_trophy_data->trop_usr.reset(new TROPUSRLoader());
const std::string trophyUsrPath = trophyPath + "/TROPUSR.DAT";
const std::string trophyConfPath = trophyPath + "/TROPCONF.SFM";
const bool success = game_trophy_data->trop_usr->Load(trophyUsrPath, trophyConfPath);
const bool success = game_trophy_data->trop_usr->Load(trophyUsrPath, trophyConfPath).success;

fs::file config(vfs::get(trophyConfPath));

Expand Down