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

Support Ps4 Files #110

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 34 additions & 5 deletions src/data/FF7Save.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,29 @@ FF7SaveInfo::FORMAT FF7Save::fileDataFormat(QFile &file)
return FF7SaveInfo::FORMAT::UNKNOWN;
}
}
if ( (file_size == FF7SaveInfo::fileSize(FF7SaveInfo::FORMAT::PS4)) && file.peek(0x00B0 + FF7SaveInfo::fileIdentifier(FF7SaveInfo::FORMAT::PS4).length()).mid(0x00B0,FF7SaveInfo::get()->fileIdentifier(FF7SaveInfo::FORMAT::PS4).length()) == FF7SaveInfo::get()->fileIdentifier(FF7SaveInfo::FORMAT::PS4)) {
QTextStream(stdout)
<< "[FF7Save::loadFile] PS4 Save "
<< file.peek(0x00B0+FF7SaveInfo::get()->fileIdentifier(FF7SaveInfo::FORMAT::PS4).length()).mid(0x00B0,FF7SaveInfo::get()->fileIdentifier(FF7SaveInfo::FORMAT::PS4).length()).toHex( )
<< "\n";
QFile ps4binfile(QFileInfo(file).path() + "/" + QFileInfo(file).fileName() + ".bin");//QFileInfo(file).baseName()
if (!ps4binfile.open(QIODevice::ReadOnly)) {
QTextStream(stdout) << "[FF7Save::loadFile] PS4 BIN File error: missing file: " << QFileInfo(ps4binfile).absoluteFilePath();
return FF7SaveInfo::FORMAT::UNKNOWN;
} else {
QTextStream(stdout) << "[FF7Save::loadFile] PS4 BIN File loaded: " << QFileInfo(ps4binfile).absoluteFilePath() << "\n";
if(ps4binfile.size() == FF7SaveInfo::get()->fileSize(FF7SaveInfo::FORMAT::PS4BIN) && (ps4binfile.peek(FF7SaveInfo::fileHeaderSize(FF7SaveInfo::FORMAT::PS4BIN)) == FF7SaveInfo::fileIdentifier(FF7SaveInfo::FORMAT::PS4BIN))) {
auto ps4bin = ps4binfile.readAll();
m_ps4_iv = ps4bin.mid(0x10, 0x10);
m_ps4_key = ps4bin.mid(0x20, 0x10);
QTextStream(stdout)
<< "[FF7Save::loadFile] PS4 BIN File Size: " << FF7SaveInfo::get()->fileSize(FF7SaveInfo::FORMAT::PS4BIN) << "\n"
<< "[FF7Save::loadFile] PS4 BIN pfsSKKey IV: " << m_ps4_iv.toHex() << "\n"
<< "[FF7Save::loadFile] PS4 BIN pfsSKKey KEY: " << m_ps4_key.toHex() << "\n";
setFormat(FF7SaveInfo::FORMAT::PS4);
}
}
}
if ((file_size == FF7SaveInfo::fileSize(FF7SaveInfo::FORMAT::PSP)) && (file.peek(25)).startsWith(FF7SaveInfo::fileIdentifier(FF7SaveInfo::FORMAT::PSP)))
return FF7SaveInfo::FORMAT::PSP;
if ((file_size == FF7SaveInfo::fileSize(FF7SaveInfo::FORMAT::VGS)) && (file.peek(25)).startsWith(FF7SaveInfo::fileIdentifier(FF7SaveInfo::FORMAT::VGS)))
Expand Down Expand Up @@ -934,7 +957,8 @@ char FF7Save::psx_block_type(int s)
case FF7SaveInfo::FORMAT::PC:
case FF7SaveInfo::FORMAT::SWITCH:
case FF7SaveInfo::FORMAT::PSX:
case FF7SaveInfo::FORMAT::PS3: return 0x00;
case FF7SaveInfo::FORMAT::PS3:
case FF7SaveInfo::FORMAT::PS4: return 0x00;
case FF7SaveInfo::FORMAT::PGE: return _fileHeader.at(0);
default:
int index = 128 + (128 * s);
Expand All @@ -951,7 +975,8 @@ void FF7Save::setPsx_block_type(int s, char block_type)
case FF7SaveInfo::FORMAT::PC:
case FF7SaveInfo::FORMAT::SWITCH:
case FF7SaveInfo::FORMAT::PSX:
case FF7SaveInfo::FORMAT::PS3: return;
case FF7SaveInfo::FORMAT::PS3:
case FF7SaveInfo::FORMAT::PS4: return;
case FF7SaveInfo::FORMAT::PGE: _fileHeader.replace(0, 1, QByteArray(1, block_type)); break;
default:
int index = 128 + (128 * s);
Expand All @@ -972,7 +997,8 @@ void FF7Save::setPsx_block_next(int s, int next)
case FF7SaveInfo::FORMAT::PC:
case FF7SaveInfo::FORMAT::SWITCH:
case FF7SaveInfo::FORMAT::PSX:
case FF7SaveInfo::FORMAT::PS3: return;
case FF7SaveInfo::FORMAT::PS3:
case FF7SaveInfo::FORMAT::PS4: return;
case FF7SaveInfo::FORMAT::PGE: _fileHeader.replace(8, 1, QByteArray(1, next)); break;
default:
int index = 128 + (128 * s);
Expand All @@ -989,7 +1015,8 @@ quint8 FF7Save::psx_block_next(int s)
case FF7SaveInfo::FORMAT::PC:
case FF7SaveInfo::FORMAT::SWITCH:
case FF7SaveInfo::FORMAT::PSX:
case FF7SaveInfo::FORMAT::PS3: return 0x00;
case FF7SaveInfo::FORMAT::PS3:
case FF7SaveInfo::FORMAT::PS4: return 0x00;
case FF7SaveInfo::FORMAT::PGE: return quint8(_fileHeader.at(0x08));
default:
int index = 128 + (128 * s);
Expand All @@ -1006,7 +1033,8 @@ void FF7Save::setPsx_block_size(int s, int blockSize)
case FF7SaveInfo::FORMAT::PC:
case FF7SaveInfo::FORMAT::SWITCH:
case FF7SaveInfo::FORMAT::PSX:
case FF7SaveInfo::FORMAT::PS3: return;
case FF7SaveInfo::FORMAT::PS3:
case FF7SaveInfo::FORMAT::PS4: return;
default: break;
}

Expand All @@ -1029,6 +1057,7 @@ quint8 FF7Save::psx_block_size(int s)
switch (fileFormat) {
case FF7SaveInfo::FORMAT::UNKNOWN:
case FF7SaveInfo::FORMAT::PC:
case FF7SaveInfo::FORMAT::PS4:
case FF7SaveInfo::FORMAT::SWITCH: return 1;
case FF7SaveInfo::FORMAT::PSX: return quint8(QFile(fileName()).size() / FF7SaveInfo::fileSize(FF7SaveInfo::FORMAT::PSX));
case FF7SaveInfo::FORMAT::PS3: return quint8((QFile(fileName()).size() - 0x84) / FF7SaveInfo::fileSize(FF7SaveInfo::FORMAT::PSX));
Expand Down
2 changes: 2 additions & 0 deletions src/data/FF7Save.h
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,8 @@ class FF7TKDATA_EXPORT FF7Save: public QObject
bool fileHasChanged;
QString buffer_region; // hold the buffers region data.
QString SG_Region_String[15];
QByteArray m_ps4_iv;
QByteArray m_ps4_key;
QString filename;//opened file
QVector< SubContainer > parseXML(const QString &fileName, const QString &metadataPath, const QString &UserID);
QVector< SubContainer > createMetadata(const QString &fileName, const QString &UserID);
Expand Down
30 changes: 26 additions & 4 deletions src/data/FF7SaveInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ int FF7SaveInfo::fileSize(FF7SaveInfo::FORMAT format)
case FORMAT::VMC: return get()->d->VMC_FILE_SIZE;
case FORMAT::PSP: return get()->d->PSP_FILE_SIZE;
case FORMAT::PS3: return get()->d->PS3_FILE_SIZE;
case FORMAT::PS4: return get()->d->PS4_FILE_SIZE;
case FORMAT::PS4BIN: return get()->d->PS4_BINFILE_SIZE;
case FORMAT::DEX: return get()->d->DEX_FILE_SIZE;
case FORMAT::VGS: return get()->d->VGS_FILE_SIZE;
case FORMAT::SWITCH: return get()->d->SWITCH_FILE_SIZE;
Expand All @@ -46,6 +48,8 @@ int FF7SaveInfo::fileHeaderSize(FF7SaveInfo::FORMAT format)
case FORMAT::VMC: return get()->d->VMC_FILE_HEADER_SIZE;
case FORMAT::PSP: return get()->d->PSP_FILE_HEADER_SIZE;
case FORMAT::PS3: return get()->d->PS3_FILE_HEADER_SIZE;
case FORMAT::PS4: return get()->d->PS4_FILE_HEADER_SIZE;
case FORMAT::PS4BIN: return get()->d->PS4_BINFILE_FILE_ID_SIZE;
case FORMAT::DEX: return get()->d->DEX_FILE_HEADER_SIZE;
case FORMAT::VGS: return get()->d->VGS_FILE_HEADER_SIZE;
case FORMAT::SWITCH: return get()->d->SWITCH_FILE_HEADER_SIZE;
Expand All @@ -62,6 +66,7 @@ int FF7SaveInfo::slotHeaderSize(FF7SaveInfo::FORMAT format)
case FORMAT::VMC:
case FORMAT::PSP:
case FORMAT::PS3:
case FORMAT::PS4:
case FORMAT::DEX:
case FORMAT::PGE:
case FORMAT::PDA:
Expand All @@ -77,6 +82,7 @@ int FF7SaveInfo::slotFooterSize(FF7SaveInfo::FORMAT format)
case FORMAT::VMC:
case FORMAT::PSP:
case FORMAT::PS3:
case FORMAT::PS4:
case FORMAT::DEX:
case FORMAT::PGE:
case FORMAT::PDA:
Expand All @@ -91,7 +97,8 @@ int FF7SaveInfo::slotCount(FF7SaveInfo::FORMAT format)
case FORMAT::PDA:
case FORMAT::PGE:
case FORMAT::PSX:
case FORMAT::PS3: return 1;
case FORMAT::PS3:
case FORMAT::PS4: return 1;
case FORMAT::VMC:
case FORMAT::PSP:
case FORMAT::DEX:
Expand All @@ -110,6 +117,8 @@ QByteArray FF7SaveInfo::fileIdentifier(FF7SaveInfo::FORMAT format)
case FORMAT::VMC: return get()->d->VMC_FILE_ID;
case FORMAT::PSP: return get()->d->PSP_FILE_ID;
case FORMAT::PS3: return get()->d->PS3_FILE_ID;
case FORMAT::PS4: return get()->d->PS4_FILE_ID;
case FORMAT::PS4BIN: return get()->d->PS4_BINFILE_FILE_ID;
case FORMAT::DEX: return get()->d->DEX_FILE_ID;
case FORMAT::VGS: return get()->d->VGS_FILE_ID;
case FORMAT::SWITCH: return get()->d->SWITCH_FILE_ID;
Expand All @@ -127,6 +136,7 @@ QByteArray FF7SaveInfo::fileHeader(FF7SaveInfo::FORMAT format)
case FORMAT::VMC: return QByteArray(fileIdentifier(format)).append(fileHeaderSize(format) - fileIdentifier(format).length(), 0x00);
case FORMAT::PSP: return get()->d->PSP_FILE_HEADER;
case FORMAT::PS3: return get()->d->PS3_FILE_HEADER;
case FORMAT::PS4: return get()->d->PS4_FILE_HEADER;
default: return QByteArray();
}
}
Expand All @@ -140,6 +150,7 @@ QByteArray FF7SaveInfo::slotHeader(FF7SaveInfo::FORMAT format, int slot)
case FORMAT::PSX:
case FORMAT::PSP:
case FORMAT::PS3:
case FORMAT::PS4:
case FORMAT::DEX:
case FORMAT::VGS:
case FORMAT::VMC: return QByteArray(get()->d->PSX_SLOT_HEADER.at(slot)).append(256, 0x00);
Expand All @@ -155,6 +166,7 @@ QByteArray FF7SaveInfo::slotFooter(FF7SaveInfo::FORMAT format)
case FORMAT::PSX:
case FORMAT::PSP:
case FORMAT::PS3:
case FORMAT::PS4:
case FORMAT::DEX:
case FORMAT::VGS:
case FORMAT::VMC: return QByteArray(get()->d->PSX_SLOT_FOOTER_SIZE, 0x00);
Expand All @@ -167,6 +179,7 @@ QByteArray FF7SaveInfo::signingKey(FF7SaveInfo::FORMAT format)
switch (format) {
case FORMAT::PSP:
case FORMAT::PS3: return get()->d->PS_SIGNING_KEY;
case FORMAT::PS4: return get()->d->PS4_SIGNING_KEY;
default: return QByteArray();
}
}
Expand All @@ -187,6 +200,7 @@ QByteArray FF7SaveInfo::signingIV(FF7SaveInfo::FORMAT format)
switch (format) {
case FORMAT::PSP:
case FORMAT::PS3: return get()->d->PS_SIGNING_IV;
case FORMAT::PS4: return get()->d->PS4_SIGNING_IV;
default: return QByteArray();
}
}
Expand All @@ -196,6 +210,7 @@ int FF7SaveInfo::fileSeedOffset(FF7SaveInfo::FORMAT format)
switch (format) {
case FORMAT::PSP: return get()->d->PSP_SEED_OFFSET;
case FORMAT::PS3: return get()->d->PS3_SEED_OFFSET;
case FORMAT::PS4: return get()->d->PS4_SEED_OFFSET;
default: return -1;
}
}
Expand All @@ -205,6 +220,7 @@ int FF7SaveInfo::fileSignatureOffset(FF7SaveInfo::FORMAT format)
switch (format) {
case FORMAT::PSP: return get()->d->PSP_SIGNATURE_OFFSET;
case FORMAT::PS3: return get()->d->PS3_SIGNATURE_OFFSET;
case FORMAT::PS4: return get()->d->PS4_SIGNATURE_OFFSET;
default: return -1;
}
}
Expand All @@ -214,6 +230,7 @@ int FF7SaveInfo::fileSignatureSize(FF7SaveInfo::FORMAT format)
switch (format) {
case FORMAT::PSP:
case FORMAT::PS3: return get()->d->PS_SIGNATURE_SIZE;
case FORMAT::PS4: return get()->d->PS4_SIGNATURE_SIZE;
default: return 0;
}
}
Expand All @@ -230,6 +247,7 @@ QRegularExpression FF7SaveInfo::validNames(FF7SaveInfo::FORMAT format)
case FORMAT::PSX: return get()->d->PSX_VALID_NAME_REGEX;
case FORMAT::PSP: return get()->d->PSP_VALID_NAME_REGEX;
case FORMAT::PS3: return get()->d->PS3_VALID_NAME_REGEX;
case FORMAT::PS4: return get()->d->PS4_VALID_NAME_REGEX;
case FORMAT::DEX: return get()->d->DEX_VALID_NAME_REGEX;
case FORMAT::VGS: return get()->d->VGS_VALID_NAME_REGEX;
case FORMAT::VMC: return get()->d->VMC_VALID_NAME_REGEX;
Expand All @@ -247,6 +265,7 @@ QString FF7SaveInfo::typeDescription(FF7SaveInfo::FORMAT format)
case FORMAT::PSX: return tr(get()->d->PSX_FILE_DESCRIPTION.toUtf8());
case FORMAT::PSP: return tr(get()->d->PSP_FILE_DESCRIPTION.toUtf8());
case FORMAT::PS3: return tr(get()->d->PS3_FILE_DESCRIPTION.toUtf8());
case FORMAT::PS4: return tr(get()->d->PS4_FILE_DESCRIPTION.toUtf8());
case FORMAT::DEX: return tr(get()->d->DEX_FILE_DESCRIPTION.toUtf8());
case FORMAT::VGS: return tr(get()->d->VGS_FILE_DESCRIPTION.toUtf8());
case FORMAT::VMC: return tr(get()->d->VMC_FILE_DESCRIPTION.toUtf8());
Expand All @@ -264,6 +283,7 @@ QStringList FF7SaveInfo::typeExtension(FF7SaveInfo::FORMAT format)
case FORMAT::PSX: return get()->d->PSX_VALID_EXTENSIONS;
case FORMAT::PSP: return get()->d->PSP_VALID_EXTENSIONS;
case FORMAT::PS3: return get()->d->PS3_VALID_EXTENSIONS;
case FORMAT::PS4: return get()->d->PS4_VALID_EXTENSIONS;
case FORMAT::DEX: return get()->d->DEX_VALID_EXTENSIONS;
case FORMAT::VGS: return get()->d->VGS_VALID_EXTENSIONS;
case FORMAT::VMC: return get()->d->VMC_VALID_EXTENSIONS;
Expand All @@ -284,25 +304,27 @@ QString FF7SaveInfo::typeFilter(FF7SaveInfo::FORMAT format)
QString FF7SaveInfo::knownTypesFilter()
{
QString space = QStringLiteral(" ");
QString allTypes = QStringLiteral("%1 %2 %3 %4 %5 %6 %7 %8 %9 %10")
QString allTypes = QStringLiteral("%1 %2 %3 %4 %5 %6 %7 %8 %9 %10 %11")
.arg(get()->d->PC_VALID_EXTENSIONS.join(space)
, get()->d->PSX_VALID_EXTENSIONS.join(space)
, get()->d->PSP_VALID_EXTENSIONS.join(space)
, get()->d->PS3_VALID_EXTENSIONS.join(space)
, get()->d->PS4_VALID_EXTENSIONS.join(space)
, get()->d->DEX_VALID_EXTENSIONS.join(space)
, get()->d->VGS_VALID_EXTENSIONS.join(space)
, get()->d->VMC_VALID_EXTENSIONS.join(space)
, get()->d->SWITCH_VALID_EXTENSIONS.join(space)
, get()->d->PGE_VALID_EXTENSIONS.join(space)
, get()->d->PDA_VALID_EXTENSIONS.join(space));

return QStringLiteral("%1;;%2;;%3;;%4;;%5;;%6;;%7;;%8;;%9;;%10;;%11;;%12")
return QStringLiteral("%1;;%2;;%3;;%4;;%5;;%6;;%7;;%8;;%9;;%10;;%11;;%12;;%13")
.arg(tr("Known FF7 Save Types (%1)").arg(allTypes)
, typeFilter(FORMAT::PC)
, typeFilter(FORMAT::SWITCH)
, typeFilter(FORMAT::VMC)
, typeFilter(FORMAT::PSX)
, typeFilter(FORMAT::PS3)
, typeFilter(FORMAT::PS4)
, typeFilter(FORMAT::PSP)
, typeFilter(FORMAT::DEX)
, typeFilter(FORMAT::VGS)
Expand All @@ -315,6 +337,7 @@ bool FF7SaveInfo::isTypePC(FF7SaveInfo::FORMAT format)
{
switch(format) {
case FORMAT::SWITCH:
case FORMAT::PS4:
case FORMAT::PC: return true;
default: return false;
};
Expand Down Expand Up @@ -368,4 +391,3 @@ QByteArray FF7SaveInfo::defaultSaveData()
{
return get()->d->DEFAULT_SAVE;
}

50 changes: 50 additions & 0 deletions src/data/FF7SaveInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@

#pragma once

#ifdef _MSC_VER
# define PACK(structure) \
__pragma(pack(push, 1)) \
structure \
__pragma(pack(pop))
#elif defined(__MINGW32__)
#define PACK(structure) structure __attribute__ ((gcc_struct, __packed__))
#else
#define PACK(structure) structure Q_PACKED
#endif

#include <QObject>
#include <QRegularExpression>
#if QT_VERSION < QT_VERSION_CHECK(6, 5, 0)
Expand Down Expand Up @@ -36,6 +47,8 @@ class FF7TKDATA_EXPORT FF7SaveInfo : public QObject
SWITCH = 7, //!< Switch Format
PGE = 8, //!< Psx Game Edit Style Single Save
PDA = 9, //!< GS , Dantel Style Save
PS4 = 10, //!< PS4 Save Format
PS4BIN = 11 //!< PS4 BIN File (pfsSKKey)
};
Q_ENUM(FORMAT)

Expand Down Expand Up @@ -63,6 +76,21 @@ class FF7TKDATA_EXPORT FF7SaveInfo : public QObject
};
Q_ENUM(PSVINFO)

/**
* \struct pfsSKKey
* \brief Extra bin file (Sealedkey) used for PS4 format
*/
PACK(
struct pfsSKKey {
quint8 MAGIC[8]; /**< [0x0000] MAGIC (0x08) */
quint16 KEYSET; /**< [0x0008] KEYSET (0x02) */
quint8 pad[6]; /**< [0x000A] Padding zeros (0x06) */
quint8 IV[16]; /**< [0x0010] AES IV (0x10) */
quint8 KEY[32]; /**< [0x0020] AES KEY (0x20) */
quint8 SHA256[32]; /**< [0x0040] AES SHA256 (0x20) */
}
);

/**
* @brief Get the FF7SaveInfo Instance.
*/
Expand Down Expand Up @@ -331,6 +359,28 @@ class FF7TKDATA_EXPORT FF7SaveInfo : public QObject
inline static const int PS_SIGNATURE_SIZE = 0x0014;
inline static const QByteArray PS_SIGNING_KEY= QByteArray::fromRawData("\xAB\x5A\xBC\x9F\xC1\xF4\x9D\xE6\xA0\x51\xDB\xAE\xFA\x51\x88\x59", 0x10);
inline static const QByteArray PS_SIGNING_IV= QByteArray::fromRawData("\xB3\x0F\xFE\xED\xB7\xDC\x5E\xB7\x13\x3D\xA6\x0D\x1B\x6B\x2C\xDC", 0x10);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~PS4 SAVE INFO~~~~~~~~~~~~~~~~~~~~~~~~~*/
static const int PS4_FILE_SIZE = 0xA00000;
static const int PS4_FILE_HEADER_SIZE = 0x00AF;
inline static const QString PS4_FILE_DESCRIPTION = QT_TR_NOOP("PS4 Save File");
inline static const QStringList PS4_VALID_EXTENSIONS { QStringLiteral("*.ff7") };
inline static const QRegularExpression PS4_VALID_NAME_REGEX = QRegularExpression(QStringLiteral("save0[0-9].ff7"));
inline static const QByteArray PS4_FILE_ID = QByteArray::fromRawData("\x17\x00\x00\x00\x00\x00\x00\x00", 8);
inline static const QByteArray PS4_BINFILE_FILE_ID = QByteArray::fromRawData("\x70\x66\x73\x53\x4B\x4B\x65\x79", 8);
static const int PS4_BINFILE_FILE_ID_SIZE = 8;
static const int PS4_BINFILE_SIZE = 0x60;
static const int PS4_BINFILE_IV_OFFSET= 0x10;
static const int PS4_BINFILE_IV_SIZE= 0x10;
static const int PS4_SEED_OFFSET = 0x0008;
static const int PS4_SIGNATURE_OFFSET = 0x001C;
static const int PS4_FILE_TYPE_OFFSET = 0x0038;
static const int PS4_FILE_DISP_SIZE_OFFSET = 0x0040;
static const int PS4_FILE_SIZE_OFFSET = 0x005C;
inline static const QByteArray PS4_FILE_HEADER = QByteArray::fromRawData("\x00\x56\x53\x50\x00\x00\x00\x00\x04\xbc\x97\x58\x11\x0f\x7e\x85\xc7\x4f\x2f\xd0\x5a\x28\xb6\x25\xe6\x9a\x6e\xa1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x01\x00\x00\x00\x00\x20\x00\x00\x84\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x03\x90\x00\x00\x42\x41\x53\x43\x55\x53\x2d\x39\x34\x31\x36\x33\x46\x46\x37\x2d\x53\x30\x31\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", PS3_FILE_HEADER_SIZE);
/*~~~~~~~ PS4 Signing ~~~~~~~~~~~~~~*/
static const int PS4_SIGNATURE_SIZE = 0x0014;
inline static const QByteArray PS4_SIGNING_KEY= QByteArray::fromRawData("\xAB\x5A\xBC\x9F\xC1\xF4\x9D\xE6\xA0\x51\xDB\xAE\xFA\x51\x88\x59", 0x10);
inline static const QByteArray PS4_SIGNING_IV= QByteArray::fromRawData("\xB3\x0F\xFE\xED\xB7\xDC\x5E\xB7\x13\x3D\xA6\x0D\x1B\x6B\x2C\xDC", 0x10);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Mem Card Format~~~~~~~~~~~~~~~~~~~*/
inline static const int VMC_FILE_SIZE = 0x20000;
inline static const int VMC_FILE_HEADER_SIZE = 0x2000;
Expand Down
4 changes: 4 additions & 0 deletions translations/ff7tk_de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6915,6 +6915,10 @@ Die km / h beschleunigt berechnet werden während des Spielens </translation>
<source>XP AR GS Caetla SmartLink Dantel</source>
<translation type="unfinished">XP AR GS Caetla SmartLink Dantel</translation>
</message>
<message>
<source>PS4 Save File</source>
<translation type="unfinished">PS4 Spielstand</translation>
</message>
</context>
<context>
<name>ItemList</name>
Expand Down
4 changes: 4 additions & 0 deletions translations/ff7tk_en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6915,6 +6915,10 @@ The km/h speeds are calculated while playing </translation>
<source>XP AR GS Caetla SmartLink Dantel</source>
<translation>XP AR GS Caetla SmartLink Dantel</translation>
</message>
<message>
<source>PS4 Save File</source>
<translation>PS4 Save File</translation>
</message>
</context>
<context>
<name>ItemList</name>
Expand Down
4 changes: 4 additions & 0 deletions translations/ff7tk_es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6915,6 +6915,10 @@ Los km/h son calculados mientras se juega </translation>
<source>XP AR GS Caetla SmartLink Dantel</source>
<translation type="unfinished">XP AR GS Caetla SmartLink Dantel</translation>
</message>
<message>
<source>PS4 Save File</source>
<translation type="unfinished">Partida Guardada PS4</translation>
</message>
</context>
<context>
<name>ItemList</name>
Expand Down
Loading