From 6e38894bccdc66d7f146e199fb70c70a10c9b740 Mon Sep 17 00:00:00 2001 From: Syping Date: Wed, 5 Apr 2023 22:26:57 +0200 Subject: [PATCH] improved RDR 2 support, libragephoto upstream --- src/ProfileInterface.cpp | 63 ++++++++++++++-------------------------- src/ProfileLoader.cpp | 26 ++--------------- src/SavegameData.cpp | 22 +++++++------- src/UserInterface.cpp | 15 +++++----- src/libragephoto | 2 +- 5 files changed, 43 insertions(+), 85 deletions(-) diff --git a/src/ProfileInterface.cpp b/src/ProfileInterface.cpp index 408cccc..295013e 100644 --- a/src/ProfileInterface.cpp +++ b/src/ProfileInterface.cpp @@ -277,13 +277,13 @@ void ProfileInterface::directoryChanged(const QString &path) const QStringList files = dir.entryList(QDir::Files); for (const QString &fileName : files) { - if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) { + if ((fileName.startsWith("SGTA5") || fileName.startsWith("SRDR3")) && !fileName.endsWith(".bak")) { t_savegameFiles << fileName; if (!savegameFiles.contains(fileName)) { n_savegameFiles << fileName; } } - if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) { + if ((fileName.startsWith("PGTA5") || fileName.startsWith("PRDR3")) && !fileName.endsWith(".bak")) { t_snapmaticPics << fileName; if (fileName.endsWith(".hidden")) { const QString originalFileName = fileName.left(fileName.length() - 7); @@ -559,18 +559,18 @@ fileDialogPreOpen: //Work? for (const QByteArray &imageFormat : QImageReader::supportedImageFormats()) { imageFormatsStr += QString("*.") % QString::fromUtf8(imageFormat).toLower() % " "; } - QString importableFormatsStr = QString("*.g5e SGTA* PGTA*"); + QString importableFormatsStr = QString("*.g5e SGTA5* PGTA5*"); if (!imageFormatsStr.trimmed().isEmpty()) { - importableFormatsStr = QString("*.g5e%1SGTA* PGTA*").arg(imageFormatsStr); + importableFormatsStr = QString("*.g5e%1SGTA5* PGTA5*").arg(imageFormatsStr); } QStringList filters; - filters << tr("Importable files (%1)").arg(importableFormatsStr); - filters << tr("GTA V Export (*.g5e)"); - filters << tr("Savegames files (SGTA*)"); - filters << tr("Snapmatic pictures (PGTA*)"); + filters << tr("All importable files (%1)").arg(importableFormatsStr); + filters << tr("GTA V Export (%1)").arg("*.g5e"); + filters << tr("GTA V Savegames files (%1)").arg("SGTA5*"); + filters << tr("GTA V Snapmatic files (%1)").arg("PGTA5*"); filters << tr("All image files (%1)").arg(imageFormatsStr.trimmed()); - filters << tr("All files (**)"); + filters << tr("All files (%1)").arg("**"); fileDialog.setNameFilters(filters); QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); @@ -796,15 +796,8 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime cEnough++; } spJson.createdDateTime = importDateTime; -#if QT_VERSION >= 0x060000 - quint64 timestamp = spJson.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - spJson.createdTimestamp = (quint32)timestamp; -#else - spJson.createdTimestamp = spJson.createdDateTime.toTime_t(); -#endif + qint64 timestamp = spJson.createdDateTime.toSecsSinceEpoch(); + spJson.createdTimestamp = timestamp; picture->setSnapmaticProperties(spJson); const QString picFileName = QString("PGTA5%1").arg(QString::number(spJson.uid)); picture->setPicFileName(picFileName); @@ -854,15 +847,8 @@ bool ProfileInterface::importFile(QString selectedFile, QDateTime importDateTime cEnough++; } spJson.createdDateTime = importDateTime; -#if QT_VERSION >= 0x060000 - quint64 timestamp = spJson.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - spJson.createdTimestamp = (quint32)timestamp; -#else - spJson.createdTimestamp = spJson.createdDateTime.toTime_t(); -#endif + qint64 timestamp = spJson.createdDateTime.toSecsSinceEpoch(); + spJson.createdTimestamp = timestamp; picture->setSnapmaticProperties(spJson); const QString picFileName = QString("PGTA5%1").arg(QString::number(spJson.uid)); picture->setPicFileName(picFileName); @@ -1124,15 +1110,15 @@ bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, bool wa { QString picFileName = picture->getPictureFileName(); QString adjustedFileName = picture->getOriginalPictureFileName(); - if (!picFileName.startsWith("PGTA5")) { + if (!picFileName.startsWith("PGTA5") && !picFileName.startsWith("PRDR3")) { if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Snapmatic picture, file not begin with PGTA or end with .g5e")); + QMessageBox::warning(this, tr("Import..."), tr("Photo import failed! It is not a GTA V or RDR 2 compatible photo")); return false; } else if (QFile::exists(profileFolder % "/" % adjustedFileName) || QFile::exists(profileFolder % "/" % adjustedFileName % ".hidden")) { SnapmaticProperties snapmaticProperties = picture->getSnapmaticProperties(); if (warn) { - int uchoice = QMessageBox::question(this, tr("Import..."), tr("A Snapmatic picture already exists with the uid %1, you want assign your import a new uid and timestamp?").arg(QString::number(snapmaticProperties.uid)), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); + int uchoice = QMessageBox::question(this, tr("Import..."), tr("A Photo already exists with the uid %1, you want assign your import a new uid and timestamp?").arg(QString::number(snapmaticProperties.uid)), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); if (uchoice == QMessageBox::Yes) { // Update Snapmatic uid snapmaticProperties.uid = getRandomUid(); @@ -1177,15 +1163,8 @@ bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, bool wa // Update Snapmatic uid snapmaticProperties.uid = getRandomUid(); snapmaticProperties.createdDateTime = QDateTime::currentDateTime(); -#if QT_VERSION >= 0x060000 - quint64 timestamp = snapmaticProperties.createdDateTime.toSecsSinceEpoch(); - if (timestamp > UINT32_MAX) { - timestamp = UINT32_MAX; - } - snapmaticProperties.createdTimestamp = (quint32)timestamp; -#else - snapmaticProperties.createdTimestamp = snapmaticProperties.createdDateTime.toTime_t(); -#endif + qint64 timestamp = snapmaticProperties.createdDateTime.toSecsSinceEpoch(); + snapmaticProperties.createdTimestamp = timestamp; bool fExists = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid)); bool fExistsBackup = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".bak"); bool fExistsHidden = QFile::exists(profileFolder % "/PGTA5" % QString::number(snapmaticProperties.uid) % ".hidden"); @@ -1219,7 +1198,7 @@ bool ProfileInterface::importSnapmaticPicture(SnapmaticPicture *picture, bool wa } else { if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Snapmatic picture, can't copy the file into profile")); + QMessageBox::warning(this, tr("Import..."), tr("Photo import failed! Can not copy the file in the profile")); return false; } } @@ -1255,13 +1234,13 @@ bool ProfileInterface::importSavegameData(SavegameData *savegame, QString sgdPat } else { if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Savegame, can't copy the file into profile")); + QMessageBox::warning(this, tr("Import..."), tr("Savegame import failed! Can not copy the file in the profile")); return false; } } else { if (warn) - QMessageBox::warning(this, tr("Import..."), tr("Failed to import the Savegame, no Savegame slot is left")); + QMessageBox::warning(this, tr("Import..."), tr("Savegame import failed! No Savegame slot is available")); return false; } } diff --git a/src/ProfileLoader.cpp b/src/ProfileLoader.cpp index 63e3c71..b5d293c 100644 --- a/src/ProfileLoader.cpp +++ b/src/ProfileLoader.cpp @@ -45,40 +45,18 @@ void ProfileLoader::run() QVector savegameFiles; QVector snapmaticPics; -#ifdef Q_OS_WIN QDir dir(profileFolder); const QStringList files = dir.entryList(QDir::Files); for (const QString &fileName : files) { - if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) { + if ((fileName.startsWith("SGTA5") || fileName.startsWith("SRDR3")) && !fileName.endsWith(".bak")) { savegameFiles << fileName; maximumV++; } - if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) { + if ((fileName.startsWith("PGTA5") || fileName.startsWith("PRDR3")) && !fileName.endsWith(".bak")) { snapmaticPics << fileName; maximumV++; } } -#else - DIR *dirp = opendir(profileFolder.toUtf8().constData()); - struct dirent *dp; - while ((dp = readdir(dirp)) != 0) { - const QString fileName = QString::fromUtf8(dp->d_name); - const QString filePath = profileFolder % "/" % fileName; - struct stat fileStat; - stat(filePath.toUtf8().constData(), &fileStat); - if (S_ISREG(fileStat.st_mode) != 0) { - if (fileName.startsWith("SGTA5") && !fileName.endsWith(".bak")) { - savegameFiles << fileName; - maximumV++; - } - if (fileName.startsWith("PGTA5") && !fileName.endsWith(".bak")) { - snapmaticPics << fileName; - maximumV++; - } - } - } - closedir(dirp); -#endif // Directory successfully scanned emit directoryScanned(savegameFiles, snapmaticPics); diff --git a/src/SavegameData.cpp b/src/SavegameData.cpp index c83fcf3..c61d911 100644 --- a/src/SavegameData.cpp +++ b/src/SavegameData.cpp @@ -1,6 +1,6 @@ /***************************************************************************** * gta5view Grand Theft Auto V Profile Viewer -* Copyright (C) 2016-2017 Syping +* Copyright (C) 2016-2023 Syping * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,7 +24,8 @@ #include #define savegameHeaderLength 260 -#define verificationValue QByteArray::fromHex("00000001") +#define verificationValue_GTA5 QByteArray::fromHex("00000001") +#define verificationValue_RDR2 QByteArray::fromHex("00000004") SavegameData::SavegameData(const QString &fileName, QObject *parent) : QObject(parent), savegameFileName(fileName) { @@ -57,13 +58,10 @@ bool SavegameData::readingSavegame() return false; } QByteArray savegameHeaderLine = saveFile->read(savegameHeaderLength); - if (savegameHeaderLine.left(4) == verificationValue) - { + if (savegameHeaderLine.startsWith(verificationValue_GTA5) || savegameHeaderLine.startsWith(verificationValue_RDR2)) { savegameStr = getSavegameDataString(savegameHeaderLine); if (savegameStr.length() >= 1) - { savegameOk = true; - } } saveFile->close(); saveFile->deleteLater(); @@ -74,7 +72,12 @@ bool SavegameData::readingSavegame() QString SavegameData::getSavegameDataString(const QByteArray &savegameHeader) { QByteArray savegameBytes = savegameHeader.left(savegameHeaderLength); - QList savegameBytesList = savegameBytes.split(char(0x01)); + char split_byte = 0x00; + if (savegameHeader.startsWith(verificationValue_GTA5)) + split_byte = 0x01; + else if (savegameHeader.startsWith(verificationValue_RDR2)) + split_byte = 0x04; + QList savegameBytesList = savegameBytes.split(split_byte); savegameBytes = savegameBytesList.at(1); savegameBytesList.clear(); return SnapmaticPicture::parseTitleString(savegameBytes); @@ -82,15 +85,12 @@ QString SavegameData::getSavegameDataString(const QByteArray &savegameHeader) bool SavegameData::readingSavegameFromFile(const QString &fileName) { - if (fileName != "") - { + if (fileName != "") { savegameFileName = fileName; return readingSavegame(); } else - { return false; - } } bool SavegameData::isSavegameOk() diff --git a/src/UserInterface.cpp b/src/UserInterface.cpp index 8ec369d..a980758 100644 --- a/src/UserInterface.cpp +++ b/src/UserInterface.cpp @@ -564,11 +564,12 @@ fileDialogPreOpen: fileDialog.setWindowTitle(tr("Open File...")); QStringList filters; - filters << ProfileInterface::tr("All profile files (*.g5e SGTA* PGTA*)"); - filters << ProfileInterface::tr("GTA V Export (*.g5e)"); - filters << ProfileInterface::tr("Savegames files (SGTA*)"); - filters << ProfileInterface::tr("Snapmatic pictures (PGTA*)"); - filters << ProfileInterface::tr("All files (**)"); + filters << ProfileInterface::tr("All profile files (%1)").arg("*.g5e SGTA5* PGTA5* PRDR3*"); + filters << ProfileInterface::tr("GTA V Export (%1)").arg("*.g5e"); + filters << ProfileInterface::tr("GTA V Savegames files (%1)").arg("SGTA5*"); + filters << ProfileInterface::tr("GTA V Snapmatic files (%1)").arg("PGTA5*"); + filters << ProfileInterface::tr("RDR 2 Photo files (%1)").arg("PRDR3*"); + filters << ProfileInterface::tr("All files (%1)").arg("**"); fileDialog.setNameFilters(filters); QList sidebarUrls = SidebarGenerator::generateSidebarUrls(fileDialog.sidebarUrls()); @@ -603,7 +604,7 @@ bool UserInterface::openFile(QString selectedFile, bool warn) } else { if (warn) - QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Snapmatic picture")); + QMessageBox::warning(this, tr("Open File"), ProfileInterface::tr("Failed to read Photo file")); delete picture; return false; } @@ -641,7 +642,7 @@ bool UserInterface::openFile(QString selectedFile, bool warn) delete savegame; delete picture; if (warn) - QMessageBox::warning(this, tr("Open File"), tr("Can't open %1 because of not valid file format").arg("\""+selectedFileName+"\"")); + QMessageBox::warning(this, tr("Open File"), tr("Can not open %1 because file format is not valid").arg("\""+selectedFileName+"\"")); return false; } } diff --git a/src/libragephoto b/src/libragephoto index 302be66..9339184 160000 --- a/src/libragephoto +++ b/src/libragephoto @@ -1 +1 @@ -Subproject commit 302be665e2bdd6fb00628ad6310b161dcf8c834d +Subproject commit 933918454f16af118a3cb9e1359a00bca589d7e7