1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-20 11:47:46 +00:00

Update NET runtime automatically

Now we can setup Dalamud out of the box, without XIVQuickLauncher
installation!
This commit is contained in:
Joshua Goins 2022-02-25 20:06:29 -05:00
parent 31c3499bcb
commit b01f96005f
4 changed files with 168 additions and 63 deletions

View file

@ -43,11 +43,7 @@ void AssetUpdater::update(const ProfileSettings& profile) {
qInfo() << "Starting update sequence...";
const bool hasDalamud = QFile::exists(dataDir + "/NativeLauncher.exe") &&
QFile::exists(dataDir + "/Dalamud");
bool isDalamudUpdated = false;
if (hasDalamud) {
if (remoteDalamudVersion.isEmpty()) {
QNetworkRequest request(dalamudVersionPath);
@ -63,6 +59,35 @@ void AssetUpdater::update(const ProfileSettings& profile) {
qInfo() << "No need to update Dalamud.";
isDalamudUpdated = true;
}
if(profile.runtimeVersion != remoteRuntimeVersion) {
doneDownloadingRuntimeCore = false;
doneDownloadingRuntimeDesktop = false;
needsRuntimeInstall = true;
// core
{
QNetworkRequest request(
QString("https://dotnetcli.azureedge.net/dotnet/Runtime/%1/dotnet-runtime-%1-win-x64.zip")
.arg(remoteRuntimeVersion));
auto reply = launcher.mgr->get(request);
reply->setObjectName("Dotnet-core");
}
// desktop
{
QNetworkRequest request(
QString("https://dotnetcli.azureedge.net/dotnet/WindowsDesktop/%1/windowsdesktop-runtime-%1-win-x64.zip")
.arg(remoteRuntimeVersion));
auto reply = launcher.mgr->get(request);
reply->setObjectName("Dotnet-desktop");
}
} else {
qInfo() << "No need to update Runtime.";
doneDownloadingRuntimeCore = true;
doneDownloadingRuntimeDesktop = true;
}
}
@ -159,16 +184,26 @@ void AssetUpdater::update(const ProfileSettings& profile) {
});
}
// first we determine if we need dalamud
const bool needsDalamud =
profile.enableDalamud && (!hasDalamud || !isDalamudUpdated);
if (needsDalamud) {
if(remoteDalamudVersion != profile.dalamudVersion) {
qInfo() << "Downloading Dalamud...";
doneDownloadingDalamud = false;
needsDalamudInstall = true;
QNetworkRequest request(dalamudRemotePath + dalamudVersion +
".zip");
auto reply = launcher.mgr->get(request);
reply->setObjectName("Dalamud");
}
const bool hasNative = QFile::exists(dataDir + "/NativeLauncher.exe");
if (!hasNative) {
// download nativelauncher release (needed to launch the game with fixed
// ACLs)
{
qInfo() << "Downloading NativeLauncher...";
doneDownloadingNativelauncher = false;
needsInstall = true;
needsNativeInstall = true;
QNetworkRequest request(nativeLauncherRemotePath +
nativeLauncherVersion +
@ -177,19 +212,6 @@ void AssetUpdater::update(const ProfileSettings& profile) {
auto reply = launcher.mgr->get(request);
reply->setObjectName("NativeLauncher");
}
// download dalamud (... duh)
{
qInfo() << "Downloading Dalamud...";
doneDownloadingDalamud = false;
needsInstall = true;
QNetworkRequest request(dalamudRemotePath + dalamudVersion +
".zip");
auto reply = launcher.mgr->get(request);
reply->setObjectName("Dalamud");
}
}
}
@ -203,6 +225,7 @@ void AssetUpdater::finishDownload(QNetworkReply* reply) {
file.close();
doneDownloadingDalamud = true;
checkIfFinished();
} else if (reply->objectName() == "NativeLauncher") {
qInfo() << "NativeLauncher finished downloading!";
@ -213,6 +236,7 @@ void AssetUpdater::finishDownload(QNetworkReply* reply) {
file.close();
doneDownloadingNativelauncher = true;
checkIfFinished();
} else if (reply->objectName() == "DalamudVersionCheck") {
QByteArray str = reply->readAll();
@ -228,29 +252,83 @@ void AssetUpdater::finishDownload(QNetworkReply* reply) {
QJsonDocument doc = QJsonDocument::fromJson(reassmbled.toUtf8());
remoteDalamudVersion = doc["AssemblyVersion"].toString();
remoteRuntimeVersion = doc["RuntimeVersion"].toString();
qInfo() << "Latest Dalamud version reported: " << remoteDalamudVersion;
qInfo() << "Latest NET runtime reported: " << remoteRuntimeVersion;
update(*currentSettings);
currentSettings = nullptr;
} else if(reply->objectName() == "Dotnet-core") {
qInfo() << "Dotnet-core finished downloading!";
QFile file(tempDir.path() + "/dotnet-core.zip");
file.open(QIODevice::WriteOnly);
file.write(reply->readAll());
file.close();
doneDownloadingRuntimeCore = true;
checkIfFinished();
} else if(reply->objectName() == "Dotnet-desktop") {
qInfo() << "Dotnet-desktop finished downloading!";
QFile file(tempDir.path() + "/dotnet-desktop.zip");
file.open(QIODevice::WriteOnly);
file.write(reply->readAll());
file.close();
doneDownloadingRuntimeDesktop = true;
checkIfFinished();
}
}
void AssetUpdater::beginInstall() {
QString dataDir =
const QString dataDir =
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if(needsDalamudInstall) {
bool success = !JlCompress::extractDir(tempDir.path() + "/latest.zip",
dataDir + "/Dalamud")
.empty();
if (success) {
if(!success) {
// TODO: handle failure here
} else {
needsDalamudInstall = false;
}
}
if(needsNativeInstall) {
QFile::copy(tempDir.path() + "/NativeLauncher.exe",
dataDir + "/NativeLauncher.exe");
finishedUpdating();
} else {
// STUB: install failure
needsNativeInstall = false;
}
if(needsRuntimeInstall) {
bool success = !JlCompress::extractDir(tempDir.path() + "/dotnet-core.zip",
dataDir + "/DalamudRuntime")
.empty();
success |= !JlCompress::extractDir(tempDir.path() + "/dotnet-desktop.zip",
dataDir + "/DalamudRuntime")
.empty();
if(!success) {
// TODO: handle failure here
} else {
QFile file(dataDir + "/DalamudRuntime/runtime.ver");
file.open(QIODevice::WriteOnly | QIODevice::Text);
file.write(remoteRuntimeVersion.toUtf8());
file.close();
needsRuntimeInstall = false;
}
}
checkIfFinished();
}
void AssetUpdater::checkIfDalamudAssetsDone() {
@ -268,11 +346,14 @@ void AssetUpdater::checkIfDalamudAssetsDone() {
checkIfFinished();
}
}
void AssetUpdater::checkIfFinished() {
if (doneDownloadingDalamud &&
doneDownloadingNativelauncher &&
doneDownloadingRuntimeCore &&
doneDownloadingRuntimeDesktop &&
dalamudAssetNeededFilenames.empty()) {
if(needsInstall)
if(needsRuntimeInstall || needsNativeInstall || needsDalamudInstall)
beginInstall();
else
finishedUpdating();

View file

@ -28,12 +28,17 @@ private:
const ProfileSettings* currentSettings = nullptr;
QString remoteDalamudVersion;
QString remoteRuntimeVersion;
QTemporaryDir tempDir;
bool doneDownloadingDalamud = true;
bool doneDownloadingNativelauncher = true;
bool needsInstall = false;
bool doneDownloadingRuntimeCore = true;
bool doneDownloadingRuntimeDesktop = true;
bool needsRuntimeInstall = false;
bool needsDalamudInstall = false;
bool needsNativeInstall = false;
int remoteDalamudAssetVersion;
QList<QString> dalamudAssetNeededFilenames;

View file

@ -149,14 +149,21 @@ void LauncherCore::launchGame(const ProfileSettings& profile, const LoginAuth au
}
auto gameProcess = new QProcess(this);
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
if(profile.useSteam) {
gameArgs.push_back({"IsSteam", "1"});
gameProcess->environment() << "IS_FFXIV_LAUNCH_FROM_STEAM=1";
env.insert("IS_FFXIV_LAUNCH_FROM_STEAM", QString::number(1));
}
env.insert("DALAMUD_RUNTIME", "Z:" + dataDir.replace('/', '\\') + "\\DalamudRuntime");
gameProcess->setProcessEnvironment(env);
gameProcess->setProcessChannelMode(QProcess::MergedChannels);
if(profile.enableDalamud) {
connect(gameProcess, &QProcess::readyReadStandardOutput, [this, gameProcess, profile, dataDir] {
connect(gameProcess, &QProcess::readyReadStandardOutput, [this, gameProcess, profile] {
QString output = gameProcess->readAllStandardOutput();
bool success;
int dec = output.toInt(&success, 10);
@ -167,13 +174,16 @@ void LauncherCore::launchGame(const ProfileSettings& profile, const LoginAuth au
qDebug() << "Now launching dalamud...";
QString dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
dataDir = "Z:" + dataDir.replace('/', '\\');
QJsonObject startInfo;
startInfo["WorkingDirectory"] = QJsonValue();
startInfo["ConfigurationPath"] = dataDir + "/dalamudConfig.json";
startInfo["PluginDirectory"] = dataDir + "/installedPlugins";
startInfo["AssetDirectory"] = dataDir + "/DalamudAssets";
startInfo["DefaultPluginDirectory"] = dataDir + "/devPlugins";
startInfo["DelayInitializeMs"] = 5;
startInfo["WorkingDirectory"] = dataDir;
startInfo["ConfigurationPath"] = dataDir + "\\dalamudConfig.json";
startInfo["PluginDirectory"] = dataDir + "\\installedPlugins";
startInfo["AssetDirectory"] = dataDir + "\\DalamudAssets";
startInfo["DefaultPluginDirectory"] = dataDir + "\\devPlugins";
startInfo["DelayInitializeMs"] = 0;
startInfo["GameVersion"] = profile.gameVersion;
startInfo["Language"] = profile.language;
startInfo["OptOutMbCollection"] = false;
@ -183,16 +193,17 @@ void LauncherCore::launchGame(const ProfileSettings& profile, const LoginAuth au
auto dalamudProcess = new QProcess();
dalamudProcess->setProcessChannelMode(QProcess::ForwardedChannels);
QStringList dalamudEnv = gameProcess->environment();
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
env.insert("DALAMUD_RUNTIME", dataDir + "\\DalamudRuntime");
#if defined(Q_OS_LINUX) || defined(Q_OS_MAC)
dalamudEnv << "XL_WINEONLINUX=true";
env.insert("XL_WINEONLINUX", "true");
#endif
dalamudProcess->setProcessEnvironment(env);
dalamudProcess->setEnvironment(dalamudEnv);
QString dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
auto list = dalamudProcess->processEnvironment().toStringList();
// TODO: what if we aren't on wine?
dalamudProcess->start(profile.winePath, {dataDir + "/Dalamud/" + "Dalamud.Injector.exe", output, argsEncoded});
});
}
@ -227,7 +238,7 @@ void LauncherCore::launchExecutable(const ProfileSettings& profile, const QStrin
void LauncherCore::launchExecutable(const ProfileSettings& profile, QProcess* process, const QStringList args) {
QList<QString> arguments;
QStringList env = QProcess::systemEnvironment();
auto env = process->processEnvironment();
#if defined(Q_OS_LINUX)
if(profile.useGamescope) {
@ -253,17 +264,17 @@ void LauncherCore::launchExecutable(const ProfileSettings& profile, QProcess* pr
arguments.push_back("gamemoderun");
if(profile.useEsync) {
env << "WINEESYNC=1";
env << "WINEFSYNC=1";
env << "WINEFSYNC_FUTEX2=1";
env.insert("WINEESYNC", QString::number(1));
env.insert("WINEFSYNC", QString::number(1));
env.insert("WINEFSYNC_FUTEX2", QString::number(1));
}
#endif
#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
env << "WINEPREFIX=" + profile.winePrefixPath;
env.insert("WINEPREFIX", profile.winePrefixPath);
if(profile.enableDXVKhud)
env << "DXVK_HUD=full";
env.insert("DXVK_HUD", "full");
arguments.push_back(profile.winePath);
#endif
@ -274,7 +285,7 @@ void LauncherCore::launchExecutable(const ProfileSettings& profile, QProcess* pr
arguments.removeFirst();
process->setWorkingDirectory(profile.gamePath + "/game/");
process->setEnvironment(env);
process->setProcessEnvironment(env);
process->start(executable, arguments);
}
@ -343,6 +354,13 @@ void LauncherCore::readInitialInformation() {
profile.dalamudAssetVersion = QString(assetJson.readAll()).toInt();
}
if(QFile::exists(dataDir + "/DalamudRuntime/runtime.ver")) {
QFile runtimeVer(dataDir + "/DalamudRuntime/runtime.ver");
runtimeVer.open(QFile::ReadOnly | QFile::Text);
profile.runtimeVersion = QString(runtimeVer.readAll());
}
}
if(settings.contains("gamePath") && settings.value("gamePath").canConvert<QString>() && !settings.value("gamePath").toString().isEmpty()) {

View file

@ -49,6 +49,7 @@ struct ProfileSettings {
QString dalamudVersion; // TODO: move out of profile settings
int dalamudAssetVersion = -1;
QString runtimeVersion;
// login
bool encryptArguments = true;