mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-14 04:51:30 +00:00
Applied Turtle's feedback (Thanks good teacher)
This commit is contained in:
parent
337b5413c6
commit
dd4f4866cc
8 changed files with 78 additions and 110 deletions
|
@ -135,17 +135,17 @@ public:
|
||||||
return (variable) & static_cast<u32>(flag);
|
return (variable) & static_cast<u32>(flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<PKGContentFlag, std::string>> flagNames = {
|
static constexpr std::array<std::pair<PKGContentFlag, std::string_view>, 10> flagNames = {
|
||||||
{PKGContentFlag::FIRST_PATCH, "FIRST_PATCH"},
|
{{PKGContentFlag::FIRST_PATCH, "FIRST_PATCH"},
|
||||||
{PKGContentFlag::PATCHGO, "PATCHGO"},
|
{PKGContentFlag::PATCHGO, "PATCHGO"},
|
||||||
{PKGContentFlag::REMASTER, "REMASTER"},
|
{PKGContentFlag::REMASTER, "REMASTER"},
|
||||||
{PKGContentFlag::PS_CLOUD, "PS_CLOUD"},
|
{PKGContentFlag::PS_CLOUD, "PS_CLOUD"},
|
||||||
{PKGContentFlag::GD_AC, "GD_AC"},
|
{PKGContentFlag::GD_AC, "GD_AC"},
|
||||||
{PKGContentFlag::NON_GAME, "NON_GAME"},
|
{PKGContentFlag::NON_GAME, "NON_GAME"},
|
||||||
{PKGContentFlag::UNKNOWN_0x8000000, "UNKNOWN_0x8000000"},
|
{PKGContentFlag::UNKNOWN_0x8000000, "UNKNOWN_0x8000000"},
|
||||||
{PKGContentFlag::SUBSEQUENT_PATCH, "SUBSEQUENT_PATCH"},
|
{PKGContentFlag::SUBSEQUENT_PATCH, "SUBSEQUENT_PATCH"},
|
||||||
{PKGContentFlag::DELTA_PATCH, "DELTA_PATCH"},
|
{PKGContentFlag::DELTA_PATCH, "DELTA_PATCH"},
|
||||||
{PKGContentFlag::CUMULATIVE_PATCH, "CUMULATIVE_PATCH"}};
|
{PKGContentFlag::CUMULATIVE_PATCH, "CUMULATIVE_PATCH"}}};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Crypto crypto;
|
Crypto crypto;
|
||||||
|
|
|
@ -14,15 +14,9 @@ PSF::~PSF() = default;
|
||||||
|
|
||||||
bool PSF::open(const std::string& filepath, std::vector<u8> psfBuffer) {
|
bool PSF::open(const std::string& filepath, std::vector<u8> psfBuffer) {
|
||||||
if (!psfBuffer.empty()) {
|
if (!psfBuffer.empty()) {
|
||||||
psf.clear();
|
|
||||||
map_integers.clear();
|
|
||||||
map_strings.clear();
|
|
||||||
psf.resize(psfBuffer.size());
|
psf.resize(psfBuffer.size());
|
||||||
psf = psfBuffer;
|
psf = psfBuffer;
|
||||||
} else {
|
} else {
|
||||||
psf.clear();
|
|
||||||
map_integers.clear();
|
|
||||||
map_strings.clear();
|
|
||||||
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
||||||
if (!file.IsOpen()) {
|
if (!file.IsOpen()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -6,20 +6,15 @@
|
||||||
TRP::TRP() = default;
|
TRP::TRP() = default;
|
||||||
TRP::~TRP() = default;
|
TRP::~TRP() = default;
|
||||||
|
|
||||||
void TRP::GetNPcommID(std::filesystem::path trophyPath, int fileNbr) {
|
void TRP::GetNPcommID(std::filesystem::path trophyPath, int index) {
|
||||||
std::filesystem::path trpPath = trophyPath / "sce_sys/npbind.dat";
|
std::filesystem::path trpPath = trophyPath / "sce_sys/npbind.dat";
|
||||||
Common::FS::IOFile npbindFile(trpPath, Common::FS::FileAccessMode::Read);
|
Common::FS::IOFile npbindFile(trpPath, Common::FS::FileAccessMode::Read);
|
||||||
if (!npbindFile.IsOpen()) {
|
if (!npbindFile.IsOpen()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < fileNbr; i++) {
|
npbindFile.Seek(0x84 + (index * 0x180));
|
||||||
std::vector<u8> vec(12);
|
npbindFile.Read(NPcommID);
|
||||||
npbindFile.Seek(0x84 + (i * 0x180));
|
NPcommID.resize(16);
|
||||||
npbindFile.Read(vec);
|
|
||||||
vec.resize(16);
|
|
||||||
NPcommID.push_back(vec);
|
|
||||||
}
|
|
||||||
npbindFile.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TRP::removePadding(std::vector<u8>& vec) {
|
void TRP::removePadding(std::vector<u8>& vec) {
|
||||||
|
@ -39,81 +34,63 @@ bool TRP::Extract(std::filesystem::path trophyPath) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::vector<std::filesystem::path> fileList;
|
std::vector<std::filesystem::path> fileList;
|
||||||
for (const auto& entry : std::filesystem::directory_iterator(gameSysDir)) {
|
for (int index = 0; const auto& it : std::filesystem::directory_iterator(gameSysDir)) {
|
||||||
if (entry.is_regular_file()) {
|
if (it.is_regular_file()) {
|
||||||
fileList.push_back(entry.path());
|
GetNPcommID(trophyPath, index);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fileList.empty())
|
Common::FS::IOFile file(it.path(), Common::FS::FileAccessMode::Read);
|
||||||
return false;
|
if (!file.IsOpen()) {
|
||||||
|
return false;
|
||||||
GetNPcommID(trophyPath, fileList.size());
|
|
||||||
for (int nbr = 0; const std::filesystem::path& fileinfo : fileList) {
|
|
||||||
std::string multiTrp = fileinfo.stem().string();
|
|
||||||
|
|
||||||
Common::FS::IOFile file(fileinfo, Common::FS::FileAccessMode::Read);
|
|
||||||
if (!file.IsOpen()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
trp_header header;
|
|
||||||
file.ReadRaw<u8>(&header, sizeof(trp_header));
|
|
||||||
|
|
||||||
if (header.magic != 0xDCA24D00)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
s64 seekPos = sizeof(trp_header);
|
|
||||||
std::filesystem::path trpFilesPath(std::filesystem::current_path() / "game_data" / title);
|
|
||||||
std::filesystem::path multiPath(trpFilesPath / "TrophyFiles");
|
|
||||||
if (fileList.size() > 1) {
|
|
||||||
multiPath = trpFilesPath / "TrophyFiles" / multiTrp;
|
|
||||||
}
|
|
||||||
std::filesystem::create_directories(multiPath / "Icons");
|
|
||||||
|
|
||||||
for (int i = 0; i < header.entry_num; i++) {
|
|
||||||
file.Seek(seekPos);
|
|
||||||
seekPos += (s64)header.entry_size;
|
|
||||||
trp_entry entry;
|
|
||||||
file.ReadRaw<u8>(&entry, sizeof(trp_entry));
|
|
||||||
std::string name(entry.entry_name);
|
|
||||||
if (entry.flag == 0 && name.find("TROP") != std::string::npos) { // PNG
|
|
||||||
file.Seek(entry.entry_pos);
|
|
||||||
std::vector<u8> icon(entry.entry_len);
|
|
||||||
file.Read(icon);
|
|
||||||
|
|
||||||
Common::FS::IOFile out(multiPath / "Icons" / name,
|
|
||||||
Common::FS::FileAccessMode::Write);
|
|
||||||
out.Write(icon);
|
|
||||||
out.Close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.flag == 3 && NPcommID.at(nbr)[0] == 'N' &&
|
TrpHeader header;
|
||||||
NPcommID.at(nbr)[1] == 'P') { // ESFM, encrypted.
|
file.Read(header);
|
||||||
file.Seek(entry.entry_pos);
|
if (header.magic != 0xDCA24D00)
|
||||||
efsmIv.resize(16);
|
return false;
|
||||||
file.Read(efsmIv); // get iv key.
|
|
||||||
|
|
||||||
std::vector<u8> ESFM(entry.entry_len - 16);
|
s64 seekPos = sizeof(TrpHeader);
|
||||||
std::vector<u8> XML(entry.entry_len - 16);
|
std::filesystem::path trpFilesPath(std::filesystem::current_path() / "game_data" /
|
||||||
XML.reserve(entry.entry_len - 16);
|
title / "TrophyFiles" / it.path().stem());
|
||||||
file.Seek(entry.entry_pos + 16);
|
std::filesystem::create_directories(trpFilesPath / "Icons");
|
||||||
file.ReadRaw<u8>(ESFM.data(), entry.entry_len - 16);
|
std::filesystem::create_directory(trpFilesPath / "Xml");
|
||||||
|
|
||||||
crypto.decryptEFSM(NPcommID.at(nbr), efsmIv, ESFM, XML); // decrypt
|
for (int i = 0; i < header.entry_num; i++) {
|
||||||
ESFM.clear();
|
file.Seek(seekPos);
|
||||||
removePadding(XML);
|
seekPos += (s64)header.entry_size;
|
||||||
std::string xml_name = name;
|
TrpEntry entry;
|
||||||
size_t pos = xml_name.find("ESFM");
|
file.Read(entry);
|
||||||
if (pos != std::string::npos)
|
std::string_view name(entry.entry_name);
|
||||||
xml_name.replace(pos, xml_name.length(), "XML");
|
if (entry.flag == 0 && name.find("TROP") != std::string::npos) { // PNG
|
||||||
Common::FS::IOFile out(multiPath / xml_name, Common::FS::FileAccessMode::Write);
|
file.Seek(entry.entry_pos);
|
||||||
out.Write(XML);
|
std::vector<u8> icon(entry.entry_len);
|
||||||
out.Close();
|
file.Read(icon);
|
||||||
|
|
||||||
|
Common::FS::IOFile out(trpFilesPath / "Icons" / name,
|
||||||
|
Common::FS::FileAccessMode::Write);
|
||||||
|
out.Write(icon);
|
||||||
|
out.Close();
|
||||||
|
}
|
||||||
|
if (entry.flag == 3 && NPcommID[0] == 'N' &&
|
||||||
|
NPcommID[1] == 'P') { // ESFM, encrypted.
|
||||||
|
file.Seek(entry.entry_pos);
|
||||||
|
file.Read(efsmIv); // get iv key.
|
||||||
|
std::vector<u8> ESFM(entry.entry_len - 16);
|
||||||
|
std::vector<u8> XML(entry.entry_len - 16);
|
||||||
|
file.Seek(entry.entry_pos + 16);
|
||||||
|
file.Read(ESFM);
|
||||||
|
crypto.decryptEFSM(NPcommID, efsmIv, ESFM, XML); // decrypt
|
||||||
|
removePadding(XML);
|
||||||
|
std::string xml_name = entry.entry_name;
|
||||||
|
size_t pos = xml_name.find("ESFM");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
xml_name.replace(pos, xml_name.length(), "XML");
|
||||||
|
Common::FS::IOFile out(trpFilesPath / "Xml" / xml_name,
|
||||||
|
Common::FS::FileAccessMode::Write);
|
||||||
|
out.Write(XML);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.Close();
|
index++;
|
||||||
nbr++;
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
|
@ -5,11 +5,11 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/endian.h"
|
#include "common/endian.h"
|
||||||
|
#include "common/io_file.h"
|
||||||
|
#include "common/types.h"
|
||||||
#include "core/crypto/crypto.h"
|
#include "core/crypto/crypto.h"
|
||||||
#include "src/common/io_file.h"
|
|
||||||
#include "src/common/types.h"
|
|
||||||
|
|
||||||
struct trp_header {
|
struct TrpHeader {
|
||||||
u32_be magic; // (0xDCA24D00)
|
u32_be magic; // (0xDCA24D00)
|
||||||
u32_be version;
|
u32_be version;
|
||||||
u64_be file_size; // size of full trp file
|
u64_be file_size; // size of full trp file
|
||||||
|
@ -21,7 +21,7 @@ struct trp_header {
|
||||||
unsigned char padding[44];
|
unsigned char padding[44];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct trp_entry {
|
struct TrpEntry {
|
||||||
char entry_name[32];
|
char entry_name[32];
|
||||||
u64_be entry_pos;
|
u64_be entry_pos;
|
||||||
u64_be entry_len;
|
u64_be entry_len;
|
||||||
|
@ -34,12 +34,12 @@ public:
|
||||||
TRP();
|
TRP();
|
||||||
~TRP();
|
~TRP();
|
||||||
bool Extract(std::filesystem::path trophyPath);
|
bool Extract(std::filesystem::path trophyPath);
|
||||||
void GetNPcommID(std::filesystem::path trophyPath, int fileNbr);
|
void GetNPcommID(std::filesystem::path trophyPath, int index);
|
||||||
void removePadding(std::vector<u8>& vec);
|
void removePadding(std::vector<u8>& vec);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Crypto crypto;
|
Crypto crypto;
|
||||||
std::vector<std::vector<CryptoPP::byte>> NPcommID;
|
std::vector<u8> NPcommID = std::vector<u8>(12);
|
||||||
std::vector<CryptoPP::byte> efsmIv;
|
std::vector<u8> efsmIv = std::vector<u8>(16);
|
||||||
std::filesystem::path trpFilesPath;
|
std::filesystem::path trpFilesPath;
|
||||||
};
|
};
|
|
@ -53,7 +53,7 @@ void ElfViewer::OpenElfFolder() {
|
||||||
m_elf_list.append(fileInfo.absoluteFilePath());
|
m_elf_list.append(fileInfo.absoluteFilePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(m_elf_list.begin(), m_elf_list.end());
|
std::ranges::sort(m_elf_list);
|
||||||
OpenElfFiles();
|
OpenElfFiles();
|
||||||
dir_list_std.clear();
|
dir_list_std.clear();
|
||||||
for (auto dir : dir_list) {
|
for (auto dir : dir_list) {
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <ranges>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
|
|
@ -124,7 +124,7 @@ void PKGViewer::ProcessPKGInfo() {
|
||||||
if (package.isFlagSet(pkg_content_flag, flag.first)) {
|
if (package.isFlagSet(pkg_content_flag, flag.first)) {
|
||||||
if (!flagss.isEmpty())
|
if (!flagss.isEmpty())
|
||||||
flagss += (", ");
|
flagss += (", ");
|
||||||
flagss += QString::fromStdString(flag.second);
|
flagss += QString::fromStdString(flag.second.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,13 +33,9 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
|
||||||
if (dirList.isEmpty())
|
if (dirList.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QString tabName = "trophy00";
|
|
||||||
for (const QFileInfo& dirInfo : dirList) {
|
for (const QFileInfo& dirInfo : dirList) {
|
||||||
QString trpDir = trophyDir;
|
QString tabName = dirInfo.fileName();
|
||||||
if (dirList.size() > 1) {
|
QString trpDir = trophyDir + "/" + tabName;
|
||||||
tabName = dirInfo.completeBaseName();
|
|
||||||
trpDir += "/" + tabName;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString iconsPath = trpDir + "/Icons";
|
QString iconsPath = trpDir + "/Icons";
|
||||||
QDir iconsDir(iconsPath);
|
QDir iconsDir(iconsPath);
|
||||||
|
@ -60,7 +56,7 @@ void TrophyViewer::PopulateTrophyWidget(QString title) {
|
||||||
QStringList trophyNames;
|
QStringList trophyNames;
|
||||||
QStringList trophyDetails;
|
QStringList trophyDetails;
|
||||||
|
|
||||||
QString xmlPath = trpDir + "/TROP.XML";
|
QString xmlPath = trpDir + "/Xml/TROP.XML";
|
||||||
QFile file(xmlPath);
|
QFile file(xmlPath);
|
||||||
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
if (!file.open(QFile::ReadOnly | QFile::Text)) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue