Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unmojang: Automatically install authlib-injector when missing #101

Merged
merged 1 commit into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions launcher/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
#include "tools/MCEditTool.h"

#include "settings/INISettingsObject.h"
#include "settings/MissingAuthlibInjectorBehavior.h"
#include "settings/Setting.h"

#include "meta/Index.h"
Expand Down Expand Up @@ -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", "");

Expand Down Expand Up @@ -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();
}
Expand Down
2 changes: 0 additions & 2 deletions launcher/BaseInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
1 change: 1 addition & 0 deletions launcher/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,7 @@ set(SETTINGS_SOURCES
settings/Setting.h
settings/SettingsObject.cpp
settings/SettingsObject.h
settings/MissingAuthlibInjectorBehavior.h
)

set(JAVA_SOURCES
Expand Down
112 changes: 78 additions & 34 deletions launcher/LaunchController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"

Expand Down Expand Up @@ -143,44 +146,85 @@ void LaunchController::login()

if (m_accountToUse->usesCustomApiServers()) {
MinecraftInstancePtr inst = std::dynamic_pointer_cast<MinecraftInstance>(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<VersionPage*>(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;
Fixed Show fixed Hide fixed
APPLICATION->settings()->set("MissingAuthlibInjectorBehavior", globalMissingBehavior);
}
} else {
missingBehavior = globalMissingBehavior;
}

if (missingBehavior == MissingAuthlibInjectorBehavior::Install) {
Fixed Show fixed Hide fixed
// 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;
}
}
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions launcher/minecraft/PackProfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
* limitations under the License.
*/

#include "Application.h"

#include <Version.h>
#include <QCryptographicHash>
#include <QDebug>
Expand Down
7 changes: 7 additions & 0 deletions launcher/settings/MissingAuthlibInjectorBehavior.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#pragma once

enum MissingAuthlibInjectorBehavior {
Ask,
Ignore,
Install,
};
17 changes: 17 additions & 0 deletions launcher/ui/pages/global/LauncherPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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()
{
Expand Down Expand Up @@ -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()
Expand Down
16 changes: 16 additions & 0 deletions launcher/ui/pages/global/LauncherPage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,22 @@
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="authlibInjectorBox">
<property name="title">
<string>Missing authlib-injector behavior</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="missingAIComboBox">
<property name="toolTip">
<string>What to do when using an authlib-injector account with an instance that does not have authlib-injector installed</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
Expand Down
4 changes: 0 additions & 4 deletions launcher/ui/pages/instance/InstanceSettingsPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down Expand Up @@ -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()
Expand Down
10 changes: 0 additions & 10 deletions launcher/ui/pages/instance/InstanceSettingsPage.ui
Original file line number Diff line number Diff line change
Expand Up @@ -710,16 +710,6 @@
</layout>
</widget>
</item>
<item>
<widget class="QCheckBox" name="suggestAuthlibInjector">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Suggest installing authlib-injector when using custom API servers.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>Suggest Authlib Injector</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacerMiscellaneous">
<property name="orientation">
Expand Down
Loading