1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-23 21:07:45 +00:00
astra/launcher/core/src/patcher.cpp

142 lines
4.5 KiB
C++

#include "patcher.h"
#include <QDir>
#include <QFile>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QStandardPaths>
#include <physis.hpp>
Patcher::Patcher(QString baseDirectory, BootData* boot_data) : boot_data(boot_data), baseDirectory(baseDirectory) {
dialog = new QProgressDialog();
dialog->setLabelText("Checking the FINAL FANTASY XIV Updater/Launcher version.");
dialog->show();
}
Patcher::Patcher(QString baseDirectory, GameData* game_data) : game_data(game_data), baseDirectory(baseDirectory) {
dialog = new QProgressDialog();
dialog->setLabelText("Checking the FINAL FANTASY XIV Game version.");
dialog->show();
}
void Patcher::processPatchList(QNetworkAccessManager& mgr, QString patchList) {
if (patchList.isEmpty()) {
dialog->hide();
emit done();
} else {
if (isBoot()) {
dialog->setLabelText("Updating the FINAL FANTASY XIV Updater/Launcher version.");
} else {
dialog->setLabelText("Updating the FINAL FANTASY XIV Game version.");
}
const QStringList parts = patchList.split(QRegExp("\n|\r\n|\r"));
remainingPatches = parts.size() - 7;
for (int i = 5; i < parts.size() - 2; i++) {
const QStringList patchParts = parts[i].split("\t");
const int length = patchParts[0].toInt();
QString name, url, version, repository;
if (isBoot()) {
name = patchParts[4];
url = patchParts[5];
version = name;
} else {
url = patchParts[8];
version = patchParts[4];
name = url.split('/').last().remove(".patch");
}
auto url_parts = url.split('/');
repository = url_parts[url_parts.size() - 3];
if (isBoot()) {
dialog->setLabelText(
"Updating the FINAL FANTASY XIV Updater/Launcher version.\nDownloading ffxivboot - " + version);
} else {
dialog->setLabelText(
"Updating the FINAL FANTASY XIV Game version.\nDownloading " + repository + " - " + version);
}
dialog->setMinimum(0);
dialog->setMaximum(length);
const QString patchesDir =
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/patches/" + repository;
if (!QDir().exists(patchesDir))
QDir().mkdir(patchesDir);
if (!QFile::exists(patchesDir + "/" + name + ".patch")) {
QNetworkRequest patchRequest(url);
auto patchReply = mgr.get(patchRequest);
connect(patchReply, &QNetworkReply::downloadProgress, [=](int recieved, int total) {
dialog->setValue(recieved);
});
connect(patchReply, &QNetworkReply::finished, [=] {
QFile file(patchesDir + "/" + name + ".patch");
file.open(QIODevice::WriteOnly);
file.write(patchReply->readAll());
file.close();
auto patch_path = patchesDir + "/" + name + ".patch";
patchQueue.push_back({name, repository, version, patch_path});
remainingPatches--;
checkIfDone();
});
} else {
patchQueue.push_back({name, repository, version, patchesDir + "/" + name + ".patch"});
remainingPatches--;
checkIfDone();
}
}
}
}
void Patcher::checkIfDone() {
if (remainingPatches <= 0) {
for (const auto& patch : patchQueue) {
processPatch(patch);
}
patchQueue.clear();
dialog->hide();
emit done();
}
}
void Patcher::processPatch(const QueuedPatch& patch) {
if (isBoot()) {
physis_bootdata_apply_patch(boot_data, patch.path.toStdString().c_str());
} else {
physis_gamedata_apply_patch(game_data, patch.path.toStdString().c_str());
}
QString verFilePath;
if (isBoot()) {
verFilePath = baseDirectory + "/ffxivboot.ver";
} else {
if (patch.repository == "game") {
verFilePath = baseDirectory + "/ffxivgame.ver";
} else {
verFilePath = baseDirectory + "/sqpack/" + patch.repository + "/" + patch.repository + ".ver";
}
}
QFile verFile(verFilePath);
verFile.open(QIODevice::WriteOnly | QIODevice::Text);
verFile.write(patch.version.toUtf8());
verFile.close();
}