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,26 +43,51 @@ void AssetUpdater::update(const ProfileSettings& profile) {
qInfo() << "Starting update sequence..."; qInfo() << "Starting update sequence...";
const bool hasDalamud = QFile::exists(dataDir + "/NativeLauncher.exe") &&
QFile::exists(dataDir + "/Dalamud");
bool isDalamudUpdated = false; bool isDalamudUpdated = false;
if (hasDalamud) { if (remoteDalamudVersion.isEmpty()) {
if (remoteDalamudVersion.isEmpty()) { QNetworkRequest request(dalamudVersionPath);
QNetworkRequest request(dalamudVersionPath);
auto reply = launcher.mgr->get(request); auto reply = launcher.mgr->get(request);
reply->setObjectName("DalamudVersionCheck"); reply->setObjectName("DalamudVersionCheck");
currentSettings = &profile; // TODO: this is dirty, should change currentSettings = &profile; // TODO: this is dirty, should change
return; return;
} else {
if (profile.dalamudVersion != remoteDalamudVersion) {
isDalamudUpdated = false;
} else { } else {
if (profile.dalamudVersion != remoteDalamudVersion) { qInfo() << "No need to update Dalamud.";
isDalamudUpdated = false; isDalamudUpdated = true;
} else { }
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 if(remoteDalamudVersion != profile.dalamudVersion) {
const bool needsDalamud = qInfo() << "Downloading Dalamud...";
profile.enableDalamud && (!hasDalamud || !isDalamudUpdated); doneDownloadingDalamud = false;
if (needsDalamud) { 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 // download nativelauncher release (needed to launch the game with fixed
// ACLs) // ACLs)
{ {
qInfo() << "Downloading NativeLauncher..."; qInfo() << "Downloading NativeLauncher...";
doneDownloadingNativelauncher = false; doneDownloadingNativelauncher = false;
needsInstall = true; needsNativeInstall = true;
QNetworkRequest request(nativeLauncherRemotePath + QNetworkRequest request(nativeLauncherRemotePath +
nativeLauncherVersion + nativeLauncherVersion +
@ -177,19 +212,6 @@ void AssetUpdater::update(const ProfileSettings& profile) {
auto reply = launcher.mgr->get(request); auto reply = launcher.mgr->get(request);
reply->setObjectName("NativeLauncher"); 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(); file.close();
doneDownloadingDalamud = true; doneDownloadingDalamud = true;
checkIfFinished(); checkIfFinished();
} else if (reply->objectName() == "NativeLauncher") { } else if (reply->objectName() == "NativeLauncher") {
qInfo() << "NativeLauncher finished downloading!"; qInfo() << "NativeLauncher finished downloading!";
@ -213,6 +236,7 @@ void AssetUpdater::finishDownload(QNetworkReply* reply) {
file.close(); file.close();
doneDownloadingNativelauncher = true; doneDownloadingNativelauncher = true;
checkIfFinished(); checkIfFinished();
} else if (reply->objectName() == "DalamudVersionCheck") { } else if (reply->objectName() == "DalamudVersionCheck") {
QByteArray str = reply->readAll(); QByteArray str = reply->readAll();
@ -228,29 +252,83 @@ void AssetUpdater::finishDownload(QNetworkReply* reply) {
QJsonDocument doc = QJsonDocument::fromJson(reassmbled.toUtf8()); QJsonDocument doc = QJsonDocument::fromJson(reassmbled.toUtf8());
remoteDalamudVersion = doc["AssemblyVersion"].toString(); remoteDalamudVersion = doc["AssemblyVersion"].toString();
remoteRuntimeVersion = doc["RuntimeVersion"].toString();
qInfo() << "Latest Dalamud version reported: " << remoteDalamudVersion; qInfo() << "Latest Dalamud version reported: " << remoteDalamudVersion;
qInfo() << "Latest NET runtime reported: " << remoteRuntimeVersion;
update(*currentSettings); update(*currentSettings);
currentSettings = nullptr; 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() { void AssetUpdater::beginInstall() {
QString dataDir = const QString dataDir =
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
bool success = !JlCompress::extractDir(tempDir.path() + "/latest.zip", if(needsDalamudInstall) {
dataDir + "/Dalamud") bool success = !JlCompress::extractDir(tempDir.path() + "/latest.zip",
.empty(); dataDir + "/Dalamud")
if (success) { .empty();
if(!success) {
// TODO: handle failure here
} else {
needsDalamudInstall = false;
}
}
if(needsNativeInstall) {
QFile::copy(tempDir.path() + "/NativeLauncher.exe", QFile::copy(tempDir.path() + "/NativeLauncher.exe",
dataDir + "/NativeLauncher.exe"); dataDir + "/NativeLauncher.exe");
finishedUpdating(); needsNativeInstall = false;
} else {
// STUB: install failure
} }
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() { void AssetUpdater::checkIfDalamudAssetsDone() {
@ -268,11 +346,14 @@ void AssetUpdater::checkIfDalamudAssetsDone() {
checkIfFinished(); checkIfFinished();
} }
} }
void AssetUpdater::checkIfFinished() { void AssetUpdater::checkIfFinished() {
if (doneDownloadingDalamud && if (doneDownloadingDalamud &&
doneDownloadingNativelauncher && doneDownloadingNativelauncher &&
doneDownloadingRuntimeCore &&
doneDownloadingRuntimeDesktop &&
dalamudAssetNeededFilenames.empty()) { dalamudAssetNeededFilenames.empty()) {
if(needsInstall) if(needsRuntimeInstall || needsNativeInstall || needsDalamudInstall)
beginInstall(); beginInstall();
else else
finishedUpdating(); finishedUpdating();

View file

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

View file

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