From aa589701edfdbee7581df81dd66099a56ae2d30e Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Fri, 22 Sep 2023 14:12:12 -0400 Subject: [PATCH] Automatically install authlib-injector when missing Add MissingAuthlibInjectorBehavior setting to control this behavior Signed-off-by: Evan Goode --- launcher/Application.cpp | 10 +- launcher/BaseInstance.cpp | 2 - launcher/CMakeLists.txt | 1 + launcher/LaunchController.cpp | 112 ++++++++++++------ launcher/minecraft/PackProfile.cpp | 2 + .../settings/MissingAuthlibInjectorBehavior.h | 7 ++ launcher/ui/pages/global/LauncherPage.cpp | 17 +++ launcher/ui/pages/global/LauncherPage.ui | 16 +++ .../pages/instance/InstanceSettingsPage.cpp | 4 - .../ui/pages/instance/InstanceSettingsPage.ui | 10 -- 10 files changed, 127 insertions(+), 54 deletions(-) create mode 100644 launcher/settings/MissingAuthlibInjectorBehavior.h diff --git a/launcher/Application.cpp b/launcher/Application.cpp index e7a490853..49e99d10b 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -115,6 +115,7 @@ #include "tools/MCEditTool.h" #include "settings/INISettingsObject.h" +#include "settings/MissingAuthlibInjectorBehavior.h" #include "settings/Setting.h" #include "meta/Index.h" @@ -601,6 +602,9 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) // Minecraft mods m_settings->registerSetting("ModMetadataDisabled", false); + // Missing authlib-injector behavior + m_settings->registerSetting("MissingAuthlibInjectorBehavior", MissingAuthlibInjectorBehavior::Ask); + // Minecraft offline player name m_settings->registerSetting("LastOfflinePlayerName", ""); @@ -982,12 +986,10 @@ void Application::performMainStartupAction() } { bool shouldFetch = m_settings->get("FlameKeyShouldBeFetchedOnStartup").toBool(); - if (!BuildConfig.FLAME_API_KEY_API_URL.isEmpty() && shouldFetch && !(capabilities() & Capability::SupportsFlame)) - { + if (!BuildConfig.FLAME_API_KEY_API_URL.isEmpty() && shouldFetch && !(capabilities() & Capability::SupportsFlame)) { // don't ask, just fetch QString apiKey = GuiUtil::fetchFlameKey(); - if (!apiKey.isEmpty()) - { + if (!apiKey.isEmpty()) { m_settings->set("FlameKeyOverride", apiKey); updateCapabilities(); } diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index e23a987e4..725036395 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -103,8 +103,6 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("ManagedPackVersionName", ""); m_settings->registerSetting("Profiler", ""); - - m_settings->registerSetting("SuggestAuthlibInjector", true); } QString BaseInstance::getPreLaunchCommand() diff --git a/launcher/CMakeLists.txt b/launcher/CMakeLists.txt index 68a681abe..f66b81859 100644 --- a/launcher/CMakeLists.txt +++ b/launcher/CMakeLists.txt @@ -430,6 +430,7 @@ set(SETTINGS_SOURCES settings/Setting.h settings/SettingsObject.cpp settings/SettingsObject.h + settings/MissingAuthlibInjectorBehavior.h ) set(JAVA_SOURCES diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index c067ec2bc..1b2e73a62 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -37,6 +37,7 @@ #include "LaunchController.h" #include "Application.h" #include "minecraft/auth/AccountList.h" +#include "settings/MissingAuthlibInjectorBehavior.h" #include "ui/pages/instance/VersionPage.h" #include "ui/InstanceWindow.h" @@ -59,6 +60,8 @@ #include "BuildConfig.h" #include "JavaCommon.h" #include "launch/steps/TextPrint.h" +#include "meta/Index.h" +#include "meta/VersionList.h" #include "minecraft/auth/AccountTask.h" #include "tasks/Task.h" @@ -143,44 +146,85 @@ void LaunchController::login() if (m_accountToUse->usesCustomApiServers()) { MinecraftInstancePtr inst = std::dynamic_pointer_cast(m_instance); - const auto suggestAuthlibInjector = m_instance->settings()->get("SuggestAuthlibInjector").toBool(); + const auto& authlibInjectorVersion = inst->getPackProfile()->getComponentVersion("moe.yushi.authlibinjector"); - if (suggestAuthlibInjector && authlibInjectorVersion == "") { + + if (authlibInjectorVersion == "") { // Account uses custom API servers, but authlib-injector is missing - // Prompt user to install authlib-injector on the instance before launching - QMessageBox msgBox{ m_parentWidget }; - msgBox.setWindowTitle(tr("Missing authlib-injector")); - msgBox.setText(tr("authlib-injector is not installed.")); - msgBox.setInformativeText( - tr("You are logging in using an account that uses custom API servers, but authlib-injector " - "is not installed on this instance.\n\n" - "Would you like to install authlib-injector now?")); - msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Ignore | QMessageBox::Yes); - msgBox.setDefaultButton(QMessageBox::Yes); - msgBox.setModal(true); - - QCheckBox* checkBox = new QCheckBox("Don't ask again", m_parentWidget); - checkBox->setChecked(!suggestAuthlibInjector); - - msgBox.setCheckBox(checkBox); - const auto& result = msgBox.exec(); - - m_instance->settings()->set("SuggestAuthlibInjector", !checkBox->isChecked()); - - switch (result) { - case QMessageBox::Ignore: - break; - case QMessageBox::Cancel: - return; - case QMessageBox::Yes: - if (result == QMessageBox::Yes) { - const auto& window = APPLICATION->showInstanceWindow(m_instance, "version"); - const auto& page = dynamic_cast(window->getPage("version")); - if (page != nullptr) { - page->openInstallAuthlibInjector(); - } + + int globalMissingBehavior = APPLICATION->settings()->get("MissingAuthlibInjectorBehavior").toInt(); + int missingBehavior = globalMissingBehavior; + + if (globalMissingBehavior == MissingAuthlibInjectorBehavior::Ask) { + QMessageBox msgBox{ m_parentWidget }; + msgBox.setWindowTitle(tr("Missing authlib-injector")); + msgBox.setText(tr("authlib-injector is not installed.")); + msgBox.setInformativeText( + tr("You are logging in using an account that uses custom API servers, but authlib-injector " + "is not installed on this instance.\n\n" + "Would you like to install authlib-injector now?")); + msgBox.setStandardButtons(QMessageBox::Cancel | QMessageBox::Ignore | QMessageBox::Yes); + msgBox.setDefaultButton(QMessageBox::Yes); + msgBox.setModal(true); + + QCheckBox* checkBox = new QCheckBox("Always do the same for all instances without asking", m_parentWidget); + checkBox->setChecked(false); + + msgBox.setCheckBox(checkBox); + const auto& result = msgBox.exec(); + + switch (result) { + case QMessageBox::Cancel: { return; + } break; + case QMessageBox::Ignore: { + missingBehavior = MissingAuthlibInjectorBehavior::Ignore; + } break; + case QMessageBox::Yes: { + missingBehavior = MissingAuthlibInjectorBehavior::Install; + } break; + } + + if (checkBox->isChecked()) { + globalMissingBehavior = missingBehavior; + APPLICATION->settings()->set("MissingAuthlibInjectorBehavior", globalMissingBehavior); + } + } else { + missingBehavior = globalMissingBehavior; + } + + if (missingBehavior == MissingAuthlibInjectorBehavior::Install) { + // Install recommended authlib-injector version + try { + auto vlist = APPLICATION->metadataIndex()->get("moe.yushi.authlibinjector"); + if (!vlist) { + throw Exception(tr("No authlib-injector versions available.")); } + + ProgressDialog loadDialog(m_parentWidget); + loadDialog.setSkipButton(true, tr("Abort")); + auto loadTask = vlist->getLoadTask(); + loadDialog.execWithTask(loadTask.get()); + + if (!loadTask->wasSuccessful()) { + throw Exception(tr("Failed to load authlib-injector versions.")); + } + + auto recommended = vlist->getRecommended(); + if (recommended == nullptr) { + throw Exception(tr("No authlib-injector versions available.")); + } + + inst->getPackProfile()->setComponentVersion("moe.yushi.authlibinjector", recommended->descriptor()); + } catch (const Exception& e) { + const auto& message = e.cause() + "\n\n" + tr("Launch anyway?"); + auto result = QMessageBox::question(m_parentWidget, tr("Failed to install authlib-injector"), message); + + if (result == QMessageBox::No) { + emitAborted(); + return; + } + } } } } diff --git a/launcher/minecraft/PackProfile.cpp b/launcher/minecraft/PackProfile.cpp index 9e42c5dd6..d24ee3bee 100644 --- a/launcher/minecraft/PackProfile.cpp +++ b/launcher/minecraft/PackProfile.cpp @@ -37,6 +37,8 @@ * limitations under the License. */ +#include "Application.h" + #include #include #include diff --git a/launcher/settings/MissingAuthlibInjectorBehavior.h b/launcher/settings/MissingAuthlibInjectorBehavior.h new file mode 100644 index 000000000..b356a7947 --- /dev/null +++ b/launcher/settings/MissingAuthlibInjectorBehavior.h @@ -0,0 +1,7 @@ +#pragma once + +enum MissingAuthlibInjectorBehavior { + Ask, + Ignore, + Install, +}; diff --git a/launcher/ui/pages/global/LauncherPage.cpp b/launcher/ui/pages/global/LauncherPage.cpp index 7f22fdb50..2ab9b492a 100644 --- a/launcher/ui/pages/global/LauncherPage.cpp +++ b/launcher/ui/pages/global/LauncherPage.cpp @@ -48,6 +48,7 @@ #include "Application.h" #include "BuildConfig.h" #include "DesktopServices.h" +#include "settings/MissingAuthlibInjectorBehavior.h" #include "settings/SettingsObject.h" #include "ui/themes/ITheme.h" #include "updater/ExternalUpdater.h" @@ -76,6 +77,11 @@ LauncherPage::LauncherPage(QWidget* parent) : QWidget(parent), ui(new Ui::Launch defaultFormat = new QTextCharFormat(ui->fontPreview->currentCharFormat()); m_languageModel = APPLICATION->translations(); + + ui->missingAIComboBox->addItem("Always ask", MissingAuthlibInjectorBehavior::Ask); + ui->missingAIComboBox->addItem("Ignore missing authlib-injector", MissingAuthlibInjectorBehavior::Ignore); + ui->missingAIComboBox->addItem("Automatically install authlib-injector", MissingAuthlibInjectorBehavior::Install); + loadSettings(); ui->updateSettingsBox->setHidden(!APPLICATION->updater()); @@ -220,6 +226,9 @@ void LauncherPage::applySettings() // Mods s->set("ModMetadataDisabled", ui->metadataDisableBtn->isChecked()); + + // authlib-injector + s->set("MissingAuthlibInjectorBehavior", ui->missingAIComboBox->currentData().toInt()); } void LauncherPage::loadSettings() { @@ -272,6 +281,14 @@ void LauncherPage::loadSettings() // Mods ui->metadataDisableBtn->setChecked(s->get("ModMetadataDisabled").toBool()); ui->metadataWarningLabel->setHidden(!ui->metadataDisableBtn->isChecked()); + + // Missing authlib-injector behavior + int missingAI = s->get("MissingAuthlibInjectorBehavior").toInt(); + int missingAIIndex = ui->missingAIComboBox->findData(missingAI); + if (missingAIIndex == -1) { + missingAIIndex = ui->missingAIComboBox->findData(MissingAuthlibInjectorBehavior::Ask); + } + ui->missingAIComboBox->setCurrentIndex(missingAIIndex); } void LauncherPage::refreshFontPreview() diff --git a/launcher/ui/pages/global/LauncherPage.ui b/launcher/ui/pages/global/LauncherPage.ui index bc259a9b8..a71aea754 100644 --- a/launcher/ui/pages/global/LauncherPage.ui +++ b/launcher/ui/pages/global/LauncherPage.ui @@ -189,6 +189,22 @@ + + + + Missing authlib-injector behavior + + + + + + What to do when using an authlib-injector account with an instance that does not have authlib-injector installed + + + + + + diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.cpp b/launcher/ui/pages/instance/InstanceSettingsPage.cpp index 2ee3e5d60..87dd0ffa5 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.cpp +++ b/launcher/ui/pages/instance/InstanceSettingsPage.cpp @@ -262,8 +262,6 @@ void InstanceSettingsPage::applySettings() m_settings->reset("DisableQuiltBeacon"); } - m_settings->set("SuggestAuthlibInjector", ui->suggestAuthlibInjector->isChecked()); - // FIXME: This should probably be called by a signal instead m_instance->updateRuntimeContext(); } @@ -371,8 +369,6 @@ void InstanceSettingsPage::loadSettings() // Mod loader specific settings ui->modLoaderSettingsGroupBox->setChecked(m_settings->get("OverrideModLoaderSettings").toBool()); ui->disableQuiltBeaconCheckBox->setChecked(m_settings->get("DisableQuiltBeacon").toBool()); - - ui->suggestAuthlibInjector->setChecked(m_settings->get("SuggestAuthlibInjector").toBool()); } void InstanceSettingsPage::on_javaDetectBtn_clicked() diff --git a/launcher/ui/pages/instance/InstanceSettingsPage.ui b/launcher/ui/pages/instance/InstanceSettingsPage.ui index 05058626f..fcc2a5d0a 100644 --- a/launcher/ui/pages/instance/InstanceSettingsPage.ui +++ b/launcher/ui/pages/instance/InstanceSettingsPage.ui @@ -710,16 +710,6 @@ - - - - <html><head/><body><p>Suggest installing authlib-injector when using custom API servers.</p></body></html> - - - Suggest Authlib Injector - - -