mirror of
https://github.com/redstrate/Astra.git
synced 2025-04-24 05:17:46 +00:00
Add Dalamud asset updating support
Note: Our Dalamud injection DOES not use this yet.
This commit is contained in:
parent
c081f92d39
commit
511763e33f
6 changed files with 168 additions and 13 deletions
|
@ -5,14 +5,20 @@
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
#include <quazip/JlCompress.h>
|
#include <quazip/JlCompress.h>
|
||||||
|
|
||||||
#include "launchercore.h"
|
#include "launchercore.h"
|
||||||
|
|
||||||
const QString dalamudRemotePath = "https://goatcorp.github.io/dalamud-distrib/";
|
const QString baseGoatcorpDomain = "https://goatcorp.github.io";
|
||||||
const QString dalamudVersion = "latest";
|
|
||||||
const QString dalamudVersionPath = dalamudRemotePath + "version";
|
const QString dalamudRemotePath = baseGoatcorpDomain + "/dalamud-distrib";
|
||||||
|
const QString dalamudVersion = "/latest";
|
||||||
|
const QString dalamudVersionPath = dalamudRemotePath + "/version";
|
||||||
|
|
||||||
|
const QString dalamudAssetRemotePath = baseGoatcorpDomain + "/DalamudAssets";
|
||||||
|
const QString dalamudAssetManifestPath = dalamudAssetRemotePath + "/asset.json";
|
||||||
|
|
||||||
const QString nativeLauncherRemotePath =
|
const QString nativeLauncherRemotePath =
|
||||||
"https://github.com/redstrate/nativelauncher/releases/download/";
|
"https://github.com/redstrate/nativelauncher/releases/download/";
|
||||||
|
@ -26,6 +32,12 @@ AssetUpdater::AssetUpdater(LauncherCore& launcher) : launcher(launcher) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetUpdater::update(const ProfileSettings& profile) {
|
void AssetUpdater::update(const ProfileSettings& profile) {
|
||||||
|
// non-dalamud users can bypass this process since it's not needed
|
||||||
|
if(!profile.enableDalamud) {
|
||||||
|
finishedUpdating();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const QString dataDir =
|
const QString dataDir =
|
||||||
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||||
|
|
||||||
|
@ -54,6 +66,99 @@ void AssetUpdater::update(const ProfileSettings& profile) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
qInfo() << "Checking Dalamud assets...";
|
||||||
|
|
||||||
|
// we want to prevent logging in before we actually check the version
|
||||||
|
dalamudAssetNeededFilenames.append("dummy");
|
||||||
|
|
||||||
|
// first we want to fetch the list of assets required
|
||||||
|
QNetworkRequest request(dalamudAssetManifestPath);
|
||||||
|
|
||||||
|
auto reply = launcher.mgr->get(request);
|
||||||
|
|
||||||
|
connect(reply, &QNetworkReply::finished, [reply, this, profile] {
|
||||||
|
// lol, they actually provide invalid json. let's fix it if it's borked
|
||||||
|
QString badJson = reply->readAll();
|
||||||
|
|
||||||
|
qInfo() << reply->errorString();
|
||||||
|
qInfo() << "Got asset manifest: " << badJson;
|
||||||
|
|
||||||
|
auto lastCommaLoc = badJson.lastIndexOf(',');
|
||||||
|
auto lastBracketLoc = badJson.lastIndexOf('{');
|
||||||
|
|
||||||
|
qInfo() << "Location of last comma: " << lastCommaLoc;
|
||||||
|
qInfo() << "Location of last bracket: " << lastBracketLoc;
|
||||||
|
|
||||||
|
// basically, if { supersedes the last ,
|
||||||
|
if (lastCommaLoc > lastBracketLoc) {
|
||||||
|
qInfo() << "Dalamud server gave bad json, attempting to fix...";
|
||||||
|
badJson.remove(lastCommaLoc, 1);
|
||||||
|
} else {
|
||||||
|
qInfo() << "Got valid json.";
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonDocument doc = QJsonDocument::fromJson(badJson.toUtf8());
|
||||||
|
|
||||||
|
qInfo() << "Dalamud asset remote version" << doc.object()["Version"].toInt();
|
||||||
|
qInfo() << "Dalamud asset local version" << profile.dalamudAssetVersion;
|
||||||
|
|
||||||
|
remoteDalamudAssetVersion = doc.object()["Version"].toInt();
|
||||||
|
|
||||||
|
if(remoteDalamudAssetVersion != profile.dalamudAssetVersion) {
|
||||||
|
qInfo() << "Dalamud assets out of date.";
|
||||||
|
|
||||||
|
dalamudAssetNeededFilenames.clear();
|
||||||
|
|
||||||
|
for(auto assetObject : doc.object()["Assets"].toArray()) {
|
||||||
|
{
|
||||||
|
qInfo() << "Starting download for " << assetObject.toObject()["FileName"];
|
||||||
|
|
||||||
|
dalamudAssetNeededFilenames.append(assetObject.toObject()["FileName"].toString());
|
||||||
|
|
||||||
|
QNetworkRequest assetRequest(assetObject.toObject()["Url"].toString());
|
||||||
|
auto assetReply = launcher.mgr->get(assetRequest);
|
||||||
|
|
||||||
|
connect(assetReply, &QNetworkReply::finished, [this, assetReply, assetObject = assetObject.toObject()] {
|
||||||
|
const QString dataDir =
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/DalamudAssets/";
|
||||||
|
|
||||||
|
if (!QDir().exists(dataDir))
|
||||||
|
QDir().mkdir(dataDir);
|
||||||
|
|
||||||
|
const QString fileName = assetObject["FileName"].toString();
|
||||||
|
const QList<QString> dirPath = fileName.left(fileName.lastIndexOf("/")).split('/');
|
||||||
|
|
||||||
|
qInfo() << "Needed directories: " << dirPath;
|
||||||
|
|
||||||
|
QString build = dataDir;
|
||||||
|
for(auto dir : dirPath) {
|
||||||
|
if (!QDir().exists(build + dir))
|
||||||
|
QDir().mkdir(build + dir);
|
||||||
|
|
||||||
|
build += dir + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile file(dataDir + assetObject["FileName"].toString());
|
||||||
|
file.open(QIODevice::WriteOnly);
|
||||||
|
file.write(assetReply->readAll());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
dalamudAssetNeededFilenames.removeOne(assetObject["FileName"].toString());
|
||||||
|
checkIfDalamudAssetsDone();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dalamudAssetNeededFilenames.clear();
|
||||||
|
|
||||||
|
qInfo() << "Dalamud assets up to date.";
|
||||||
|
|
||||||
|
checkIfFinished();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// first we determine if we need dalamud
|
// first we determine if we need dalamud
|
||||||
const bool needsDalamud =
|
const bool needsDalamud =
|
||||||
profile.enableDalamud && (!hasDalamud || !isDalamudUpdated);
|
profile.enableDalamud && (!hasDalamud || !isDalamudUpdated);
|
||||||
|
@ -62,6 +167,8 @@ void AssetUpdater::update(const ProfileSettings& profile) {
|
||||||
// ACLs)
|
// ACLs)
|
||||||
{
|
{
|
||||||
qInfo() << "Downloading NativeLauncher...";
|
qInfo() << "Downloading NativeLauncher...";
|
||||||
|
doneDownloadingNativelauncher = false;
|
||||||
|
needsInstall = true;
|
||||||
|
|
||||||
QNetworkRequest request(nativeLauncherRemotePath +
|
QNetworkRequest request(nativeLauncherRemotePath +
|
||||||
nativeLauncherVersion +
|
nativeLauncherVersion +
|
||||||
|
@ -74,6 +181,8 @@ void AssetUpdater::update(const ProfileSettings& profile) {
|
||||||
// download dalamud (... duh)
|
// download dalamud (... duh)
|
||||||
{
|
{
|
||||||
qInfo() << "Downloading Dalamud...";
|
qInfo() << "Downloading Dalamud...";
|
||||||
|
doneDownloadingDalamud = false;
|
||||||
|
needsInstall = true;
|
||||||
|
|
||||||
QNetworkRequest request(dalamudRemotePath + dalamudVersion +
|
QNetworkRequest request(dalamudRemotePath + dalamudVersion +
|
||||||
".zip");
|
".zip");
|
||||||
|
@ -81,20 +190,10 @@ void AssetUpdater::update(const ProfileSettings& profile) {
|
||||||
auto reply = launcher.mgr->get(request);
|
auto reply = launcher.mgr->get(request);
|
||||||
reply->setObjectName("Dalamud");
|
reply->setObjectName("Dalamud");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// non-dalamud users can bypass this process since it's not needed
|
|
||||||
finishedUpdating();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetUpdater::finishDownload(QNetworkReply* reply) {
|
void AssetUpdater::finishDownload(QNetworkReply* reply) {
|
||||||
const auto checkIfFinished = [=] {
|
|
||||||
if (QFile::exists(tempDir.path() + "/NativeLauncher.exe") &&
|
|
||||||
QFile::exists(tempDir.path() + "/latest.zip")) {
|
|
||||||
beginInstall();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (reply->objectName() == "Dalamud") {
|
if (reply->objectName() == "Dalamud") {
|
||||||
qInfo() << "Dalamud finished downloading!";
|
qInfo() << "Dalamud finished downloading!";
|
||||||
|
|
||||||
|
@ -103,6 +202,7 @@ void AssetUpdater::finishDownload(QNetworkReply* reply) {
|
||||||
file.write(reply->readAll());
|
file.write(reply->readAll());
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
doneDownloadingDalamud = true;
|
||||||
checkIfFinished();
|
checkIfFinished();
|
||||||
} else if (reply->objectName() == "NativeLauncher") {
|
} else if (reply->objectName() == "NativeLauncher") {
|
||||||
qInfo() << "NativeLauncher finished downloading!";
|
qInfo() << "NativeLauncher finished downloading!";
|
||||||
|
@ -112,6 +212,7 @@ void AssetUpdater::finishDownload(QNetworkReply* reply) {
|
||||||
file.write(reply->readAll());
|
file.write(reply->readAll());
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
doneDownloadingNativelauncher = true;
|
||||||
checkIfFinished();
|
checkIfFinished();
|
||||||
} else if (reply->objectName() == "DalamudVersionCheck") {
|
} else if (reply->objectName() == "DalamudVersionCheck") {
|
||||||
QByteArray str = reply->readAll();
|
QByteArray str = reply->readAll();
|
||||||
|
@ -151,3 +252,29 @@ void AssetUpdater::beginInstall() {
|
||||||
// STUB: install failure
|
// STUB: install failure
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetUpdater::checkIfDalamudAssetsDone() {
|
||||||
|
if(dalamudAssetNeededFilenames.empty()) {
|
||||||
|
qInfo() << "Finished downloading Dalamud assets.";
|
||||||
|
|
||||||
|
const QString dataDir =
|
||||||
|
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/DalamudAssets/";
|
||||||
|
|
||||||
|
QFile file(dataDir + "asset.ver");
|
||||||
|
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
|
file.write(QString::number(remoteDalamudAssetVersion).toUtf8());
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
checkIfFinished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void AssetUpdater::checkIfFinished() {
|
||||||
|
if (doneDownloadingDalamud &&
|
||||||
|
doneDownloadingNativelauncher &&
|
||||||
|
dalamudAssetNeededFilenames.empty()) {
|
||||||
|
if(needsInstall)
|
||||||
|
beginInstall();
|
||||||
|
else
|
||||||
|
finishedUpdating();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,9 @@ public:
|
||||||
void finishDownload(QNetworkReply* reply);
|
void finishDownload(QNetworkReply* reply);
|
||||||
void beginInstall();
|
void beginInstall();
|
||||||
|
|
||||||
|
void checkIfDalamudAssetsDone();
|
||||||
|
void checkIfFinished();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void finishedUpdating();
|
void finishedUpdating();
|
||||||
|
|
||||||
|
@ -27,4 +30,11 @@ private:
|
||||||
QString remoteDalamudVersion;
|
QString remoteDalamudVersion;
|
||||||
|
|
||||||
QTemporaryDir tempDir;
|
QTemporaryDir tempDir;
|
||||||
|
|
||||||
|
bool doneDownloadingDalamud = true;
|
||||||
|
bool doneDownloadingNativelauncher = true;
|
||||||
|
bool needsInstall = false;
|
||||||
|
|
||||||
|
int remoteDalamudAssetVersion;
|
||||||
|
QList<QString> dalamudAssetNeededFilenames;
|
||||||
};
|
};
|
||||||
|
|
|
@ -323,6 +323,13 @@ void LauncherCore::readInitialInformation() {
|
||||||
.filter("Dalamud")[0];
|
.filter("Dalamud")[0];
|
||||||
profile.dalamudVersion = versionString.remove("Dalamud/");
|
profile.dalamudVersion = versionString.remove("Dalamud/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(QFile::exists(dataDir + "/DalamudAssets/asset.ver")) {
|
||||||
|
QFile assetJson(dataDir + "/DalamudAssets/asset.ver");
|
||||||
|
assetJson.open(QFile::ReadOnly | QFile::Text);
|
||||||
|
|
||||||
|
profile.dalamudAssetVersion = QString(assetJson.readAll()).toInt();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(settings.contains("gamePath") && settings.value("gamePath").canConvert<QString>() && !settings.value("gamePath").toString().isEmpty()) {
|
if(settings.contains("gamePath") && settings.value("gamePath").canConvert<QString>() && !settings.value("gamePath").toString().isEmpty()) {
|
||||||
|
|
|
@ -48,6 +48,7 @@ struct ProfileSettings {
|
||||||
} gamescope;
|
} gamescope;
|
||||||
|
|
||||||
QString dalamudVersion; // TODO: move out of profile settings
|
QString dalamudVersion; // TODO: move out of profile settings
|
||||||
|
int dalamudAssetVersion = -1;
|
||||||
|
|
||||||
// login
|
// login
|
||||||
bool encryptArguments = true;
|
bool encryptArguments = true;
|
||||||
|
|
|
@ -372,6 +372,9 @@ SettingsWindow::SettingsWindow(LauncherWindow& window, LauncherCore& core, QWidg
|
||||||
|
|
||||||
dalamudVersionLabel = new QLabel();
|
dalamudVersionLabel = new QLabel();
|
||||||
dalamudBoxLayout->addRow("Dalamud Version", dalamudVersionLabel);
|
dalamudBoxLayout->addRow("Dalamud Version", dalamudVersionLabel);
|
||||||
|
|
||||||
|
dalamudAssetVersionLabel = new QLabel();
|
||||||
|
dalamudBoxLayout->addRow("Dalamud Asset Version", dalamudAssetVersionLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadControls();
|
reloadControls();
|
||||||
|
@ -478,6 +481,12 @@ void SettingsWindow::reloadControls() {
|
||||||
dalamudVersionLabel->setText(profile.dalamudVersion);
|
dalamudVersionLabel->setText(profile.dalamudVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(profile.dalamudAssetVersion == -1) {
|
||||||
|
dalamudAssetVersionLabel->setText("Dalamud assets are not installed.");
|
||||||
|
} else {
|
||||||
|
dalamudAssetVersionLabel->setText(QString::number(profile.dalamudAssetVersion));
|
||||||
|
}
|
||||||
|
|
||||||
window.reloadControls();
|
window.reloadControls();
|
||||||
|
|
||||||
currentlyReloadingControls = false;
|
currentlyReloadingControls = false;
|
||||||
|
|
|
@ -54,6 +54,7 @@ private:
|
||||||
// dalamud
|
// dalamud
|
||||||
QCheckBox* enableDalamudBox = nullptr;
|
QCheckBox* enableDalamudBox = nullptr;
|
||||||
QLabel* dalamudVersionLabel = nullptr;
|
QLabel* dalamudVersionLabel = nullptr;
|
||||||
|
QLabel* dalamudAssetVersionLabel = nullptr;
|
||||||
|
|
||||||
bool currentlyReloadingControls = false;
|
bool currentlyReloadingControls = false;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue