|
@@ -330,119 +330,152 @@ void FirstLaunchView::extractGogData()
|
|
|
return file;
|
|
|
};
|
|
|
|
|
|
- auto checkMagic = [this](QString filename, QString filter, QByteArray magic)
|
|
|
+ QString filterBin = tr("GOG data") + " (*.bin)";
|
|
|
+ QString filterExe = tr("GOG installer") + " (*.exe)";
|
|
|
+
|
|
|
+ QString fileBin = fileSelection(filterBin);
|
|
|
+ if(fileBin.isEmpty())
|
|
|
+ return;
|
|
|
+ QString fileExe = fileSelection(filterExe, QFileInfo(fileBin).absolutePath());
|
|
|
+ if(fileExe.isEmpty())
|
|
|
+ return;
|
|
|
+
|
|
|
+ ui->progressBarGog->setVisible(true);
|
|
|
+ ui->pushButtonGogInstall->setVisible(false);
|
|
|
+ setEnabled(false);
|
|
|
+
|
|
|
+ QTimer::singleShot(100, this, [this, fileBin, fileExe](){ // background to make sure FileDialog is closed...
|
|
|
+ extractGogDataAsync(fileBin, fileExe);
|
|
|
+ ui->progressBarGog->setVisible(false);
|
|
|
+ ui->pushButtonGogInstall->setVisible(true);
|
|
|
+ setEnabled(true);
|
|
|
+ });
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+void FirstLaunchView::extractGogDataAsync(QString filePathBin, QString filePathExe)
|
|
|
+{
|
|
|
+ logGlobal->info("Extracting gog data from '%s' and '%s'", filePathBin.toStdString(), filePathExe.toStdString());
|
|
|
+
|
|
|
+#ifdef ENABLE_INNOEXTRACT
|
|
|
+ auto checkMagic = [](QString filename, QString filter, QByteArray magic)
|
|
|
{
|
|
|
- QString titleErr = tr("You have to select %1 file!", "param is file extension").arg(filter);
|
|
|
+ logGlobal->info("Checking file %s", filename.toStdString());
|
|
|
|
|
|
QFile tmpFile(filename);
|
|
|
if(!tmpFile.open(QIODevice::ReadOnly))
|
|
|
{
|
|
|
- QMessageBox::critical(this, tr("File cannot be opened"), tmpFile.errorString());
|
|
|
- return false;
|
|
|
+ logGlobal->info("File cannot be opened: %s", tmpFile.errorString().toStdString());
|
|
|
+ return tr("Failed to open file: %1").arg(tmpFile.errorString());
|
|
|
}
|
|
|
+
|
|
|
QByteArray magicFile = tmpFile.read(magic.length());
|
|
|
if(!magicFile.startsWith(magic))
|
|
|
{
|
|
|
- QMessageBox::critical(this, tr("Invalid file selected"), titleErr);
|
|
|
- return false;
|
|
|
+ logGlobal->info("Invalid file selected: %s", filter.toStdString());
|
|
|
+ return tr("You have to select %1 file!", "param is file extension").arg(filter);
|
|
|
}
|
|
|
- return true;
|
|
|
+
|
|
|
+ logGlobal->info("Checking file %s", filename.toStdString());
|
|
|
+ return QString();
|
|
|
};
|
|
|
|
|
|
QString filterBin = tr("GOG data") + " (*.bin)";
|
|
|
QString filterExe = tr("GOG installer") + " (*.exe)";
|
|
|
|
|
|
- QString fileBin = fileSelection(filterBin);
|
|
|
- if(fileBin.isEmpty())
|
|
|
- return;
|
|
|
- QString fileExe = fileSelection(filterExe, QFileInfo(fileBin).absolutePath());
|
|
|
- if(fileExe.isEmpty())
|
|
|
- return;
|
|
|
+ QDir tempDir(pathToQString(VCMIDirs::get().userDataPath()));
|
|
|
+ if(tempDir.cd("tmp"))
|
|
|
+ {
|
|
|
+ logGlobal->info("Cleaning up old data");
|
|
|
+ tempDir.removeRecursively(); // remove if already exists (e.g. previous crash)
|
|
|
+ tempDir.cdUp();
|
|
|
+ }
|
|
|
+ tempDir.mkdir("tmp");
|
|
|
+ if(!tempDir.cd("tmp"))
|
|
|
+ return; // should not happen - but avoid deleting wrong folder in any case
|
|
|
|
|
|
- ui->progressBarGog->setVisible(true);
|
|
|
- ui->pushButtonGogInstall->setVisible(false);
|
|
|
- setEnabled(false);
|
|
|
+ logGlobal->info("Using '%s' as temporary directory", tempDir.path().toStdString());
|
|
|
|
|
|
- QTimer::singleShot(100, this, [this, fileExe, fileBin, checkMagic, filterBin, filterExe](){ // background to make sure FileDialog is closed...
|
|
|
- QDir tempDir(pathToQString(VCMIDirs::get().userDataPath()));
|
|
|
- if(tempDir.cd("tmp"))
|
|
|
- {
|
|
|
- tempDir.removeRecursively(); // remove if already exists (e.g. previous crash)
|
|
|
- tempDir.cdUp();
|
|
|
- }
|
|
|
- tempDir.mkdir("tmp");
|
|
|
- if(!tempDir.cd("tmp"))
|
|
|
- return; // should not happen - but avoid deleting wrong folder in any case
|
|
|
+ QString tmpFileExe = tempDir.filePath("h3_gog.exe");
|
|
|
+ QString tmpFileBin = tempDir.filePath("h3_gog-1.bin");
|
|
|
|
|
|
- QString tmpFileExe = tempDir.filePath("h3_gog.exe");
|
|
|
- QString tmpFileBin = tempDir.filePath("h3_gog-1.bin");
|
|
|
+ logGlobal->info("Performing native copy...");
|
|
|
+ Helper::performNativeCopy(filePathExe, tmpFileExe);
|
|
|
+ Helper::performNativeCopy(filePathBin, tmpFileBin);
|
|
|
+ logGlobal->info("Native copy completed");
|
|
|
|
|
|
- Helper::performNativeCopy(fileExe, tmpFileExe);
|
|
|
- Helper::performNativeCopy(fileBin, tmpFileBin);
|
|
|
+ QString errorText{};
|
|
|
|
|
|
- if (!checkMagic(tmpFileBin, filterBin, QByteArray{"idska32"}) ||
|
|
|
- !checkMagic(tmpFileExe, filterExe, QByteArray{"MZ"}))
|
|
|
- return;
|
|
|
+ if (errorText.isEmpty())
|
|
|
+ errorText = checkMagic(tmpFileBin, filterBin, QByteArray{"idska32"});
|
|
|
|
|
|
- logGlobal->info("Installing exe '%s' ('%s')", tmpFileExe.toStdString(), fileExe.toStdString());
|
|
|
- logGlobal->info("Installing bin '%s' ('%s')", tmpFileBin.toStdString(), fileBin.toStdString());
|
|
|
+ if (errorText.isEmpty())
|
|
|
+ errorText = checkMagic(tmpFileExe, filterExe, QByteArray{"MZ"});
|
|
|
|
|
|
- QString errorText{};
|
|
|
+ logGlobal->info("Installing exe '%s' ('%s')", tmpFileExe.toStdString(), filePathExe.toStdString());
|
|
|
+ logGlobal->info("Installing bin '%s' ('%s')", tmpFileBin.toStdString(), filePathBin.toStdString());
|
|
|
|
|
|
- auto isGogGalaxyExe = [](QString fileToTest) {
|
|
|
- QFile file(fileToTest);
|
|
|
- quint64 fileSize = file.size();
|
|
|
+ auto isGogGalaxyExe = [](QString fileToTest) {
|
|
|
+ QFile file(fileToTest);
|
|
|
+ quint64 fileSize = file.size();
|
|
|
|
|
|
- if(fileSize > 10 * 1024 * 1024)
|
|
|
- return false; // avoid to load big files; galaxy exe is smaller...
|
|
|
+ if(fileSize > 10 * 1024 * 1024)
|
|
|
+ return false; // avoid to load big files; galaxy exe is smaller...
|
|
|
|
|
|
- if(!file.open(QIODevice::ReadOnly))
|
|
|
- return false;
|
|
|
- QByteArray data = file.readAll();
|
|
|
+ if(!file.open(QIODevice::ReadOnly))
|
|
|
+ return false;
|
|
|
+ QByteArray data = file.readAll();
|
|
|
|
|
|
- const QByteArray magicId{reinterpret_cast<const char*>(u"GOG Galaxy"), 20};
|
|
|
- return data.contains(magicId);
|
|
|
- };
|
|
|
+ const QByteArray magicId{reinterpret_cast<const char*>(u"GOG Galaxy"), 20};
|
|
|
+ return data.contains(magicId);
|
|
|
+ };
|
|
|
|
|
|
+ if(errorText.isEmpty())
|
|
|
+ {
|
|
|
if(isGogGalaxyExe(tmpFileExe))
|
|
|
+ {
|
|
|
+ logGlobal->info("Gog Galaxy detected! Aborting...");
|
|
|
errorText = tr("You've provided a GOG Galaxy installer! This file doesn't contain the game. Please download the offline backup game installer!");
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- if(errorText.isEmpty())
|
|
|
- errorText = Innoextract::extract(tmpFileExe, tempDir.path(), [this](float progress) {
|
|
|
- ui->progressBarGog->setValue(progress * 100);
|
|
|
- qApp->processEvents();
|
|
|
- });
|
|
|
-
|
|
|
- QString hashError;
|
|
|
- if(!errorText.isEmpty())
|
|
|
- hashError = Innoextract::getHashError(tmpFileExe, tmpFileBin, fileExe, fileBin);
|
|
|
+ if(errorText.isEmpty())
|
|
|
+ {
|
|
|
+ logGlobal->info("Performing extraction using innoextract...");
|
|
|
+ errorText = Innoextract::extract(tmpFileExe, tempDir.path(), [this](float progress) {
|
|
|
+ ui->progressBarGog->setValue(progress * 100);
|
|
|
+ qApp->processEvents();
|
|
|
+ });
|
|
|
+ logGlobal->info("Extraction done!");
|
|
|
+ }
|
|
|
|
|
|
- ui->progressBarGog->setVisible(false);
|
|
|
- ui->pushButtonGogInstall->setVisible(true);
|
|
|
- setEnabled(true);
|
|
|
+ QString hashError;
|
|
|
+ if(!errorText.isEmpty())
|
|
|
+ hashError = Innoextract::getHashError(tmpFileExe, tmpFileBin, filePathExe, filePathBin);
|
|
|
|
|
|
- QStringList dirData = tempDir.entryList({"data"}, QDir::Filter::Dirs);
|
|
|
- if(!errorText.isEmpty() || dirData.empty() || QDir(tempDir.filePath(dirData.front())).entryList({"*.lod"}, QDir::Filter::Files).empty())
|
|
|
+ QStringList dirData = tempDir.entryList({"data"}, QDir::Filter::Dirs);
|
|
|
+ if(!errorText.isEmpty() || dirData.empty() || QDir(tempDir.filePath(dirData.front())).entryList({"*.lod"}, QDir::Filter::Files).empty())
|
|
|
+ {
|
|
|
+ if(!errorText.isEmpty())
|
|
|
{
|
|
|
- if(!errorText.isEmpty())
|
|
|
+ logGlobal->error("Gog installer extraction failure! Reason: %s", errorText.toStdString());
|
|
|
+ QMessageBox::critical(this, tr("Extracting error!"), errorText, QMessageBox::Ok, QMessageBox::Ok);
|
|
|
+ if(!hashError.isEmpty())
|
|
|
{
|
|
|
- logGlobal->error("Gog installer extraction failure! Reason: %s", errorText.toStdString());
|
|
|
- QMessageBox::critical(this, tr("Extracting error!"), errorText, QMessageBox::Ok, QMessageBox::Ok);
|
|
|
- if(!hashError.isEmpty())
|
|
|
- {
|
|
|
- logGlobal->error("Hash error: %s", hashError.toStdString());
|
|
|
- QMessageBox::critical(this, tr("Hash error!"), hashError, QMessageBox::Ok, QMessageBox::Ok);
|
|
|
- }
|
|
|
+ logGlobal->error("Hash error: %s", hashError.toStdString());
|
|
|
+ QMessageBox::critical(this, tr("Hash error!"), hashError, QMessageBox::Ok, QMessageBox::Ok);
|
|
|
}
|
|
|
- else
|
|
|
- QMessageBox::critical(this, tr("No Heroes III data!"), tr("Selected files do not contain Heroes III data!"), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
- tempDir.removeRecursively();
|
|
|
- return;
|
|
|
}
|
|
|
- copyHeroesData(tempDir.path(), true);
|
|
|
-
|
|
|
+ else
|
|
|
+ QMessageBox::critical(this, tr("No Heroes III data!"), tr("Selected files do not contain Heroes III data!"), QMessageBox::Ok, QMessageBox::Ok);
|
|
|
tempDir.removeRecursively();
|
|
|
- });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ logGlobal->info("Copying provided game files...");
|
|
|
+ copyHeroesData(tempDir.path(), true);
|
|
|
+
|
|
|
+ tempDir.removeRecursively();
|
|
|
#endif
|
|
|
}
|
|
|
|