feat: add setting to control the loaders for mod search (#3659)

This commit is contained in:
Alexandru Ionut Tripon
2025-06-02 11:39:39 +03:00
committed by GitHub
7 changed files with 168 additions and 11 deletions

View File

@@ -279,4 +279,29 @@ QJsonValue requireIsType<QJsonValue>(const QJsonValue& value, const QString& wha
return value;
}
QStringList toStringList(const QString& jsonString)
{
QJsonParseError parseError;
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8(), &parseError);
if (parseError.error != QJsonParseError::NoError || !doc.isArray())
return {};
try {
return ensureIsArrayOf<QString>(doc.array(), "");
} catch (Json::JsonException& e) {
return {};
}
}
QString fromStringList(const QStringList& list)
{
QJsonArray array;
for (const QString& str : list) {
array.append(str);
}
QJsonDocument doc(toJsonArray(list));
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
}
} // namespace Json

View File

@@ -99,7 +99,7 @@ template <typename T>
QJsonArray toJsonArray(const QList<T>& container)
{
QJsonArray array;
for (const T item : container) {
for (const T& item : container) {
array.append(toJson<T>(item));
}
return array;
@@ -278,5 +278,9 @@ JSON_HELPERFUNCTIONS(Variant, QVariant)
#undef JSON_HELPERFUNCTIONS
// helper functions for settings
QStringList toStringList(const QString& jsonString);
QString fromStringList(const QStringList& list);
} // namespace Json
using JSONValidationError = Json::JsonException;

View File

@@ -250,6 +250,10 @@ void MinecraftInstance::loadSpecificSettings()
m_settings->registerSetting("ExportOptionalFiles", true);
m_settings->registerSetting("ExportRecommendedRAM");
// Join server on launch, this does not have a global override
m_settings->registerSetting("OverrideModDownloadLoaders", false);
m_settings->registerSetting("ModDownloadLoaders", "[]");
qDebug() << "Instance-type specific settings were loaded!";
setSpecificSettingsLoaded(true);

View File

@@ -39,6 +39,8 @@
#include "Application.h"
#include "BuildConfig.h"
#include "Json.h"
#include "minecraft/PackProfile.h"
#include "minecraft/WorldList.h"
#include "minecraft/auth/AccountList.h"
#include "settings/Setting.h"
@@ -55,6 +57,7 @@ MinecraftSettingsWidget::MinecraftSettingsWidget(MinecraftInstancePtr instance,
m_ui->openGlobalSettingsButton->setVisible(false);
m_ui->instanceAccountGroupBox->hide();
m_ui->serverJoinGroupBox->hide();
m_ui->loaderGroup->hide();
} else {
m_javaSettings = new JavaSettingsWidget(m_instance, this);
m_ui->javaScrollArea->setWidget(m_javaSettings);
@@ -93,6 +96,17 @@ MinecraftSettingsWidget::MinecraftSettingsWidget(MinecraftInstancePtr instance,
connect(m_ui->openGlobalSettingsButton, &QCommandLinkButton::clicked, this, &MinecraftSettingsWidget::openGlobalSettings);
connect(m_ui->serverJoinAddressButton, &QAbstractButton::toggled, m_ui->serverJoinAddress, &QWidget::setEnabled);
connect(m_ui->worldJoinButton, &QAbstractButton::toggled, m_ui->worldsCb, &QWidget::setEnabled);
connect(m_ui->loaderGroup, &QGroupBox::toggled, this, [this](bool value) {
m_instance->settings()->set("OverrideModDownloadLoaders", value);
if (!value)
m_instance->settings()->reset("ModDownloadLoaders");
});
connect(m_ui->neoForge, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged);
connect(m_ui->forge, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged);
connect(m_ui->fabric, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged);
connect(m_ui->quilt, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged);
connect(m_ui->liteLoader, &QCheckBox::stateChanged, this, &MinecraftSettingsWidget::selectedLoadersChanged);
}
m_ui->maximizedWarning->hide();
@@ -220,6 +234,35 @@ void MinecraftSettingsWidget::loadSettings()
m_ui->instanceAccountGroupBox->setChecked(settings->get("UseAccountForInstance").toBool());
updateAccountsMenu(*settings);
m_ui->loaderGroup->blockSignals(true);
m_ui->neoForge->blockSignals(true);
m_ui->forge->blockSignals(true);
m_ui->fabric->blockSignals(true);
m_ui->quilt->blockSignals(true);
m_ui->liteLoader->blockSignals(true);
auto instLoaders = m_instance->getPackProfile()->getSupportedModLoaders().value();
m_ui->loaderGroup->setChecked(settings->get("OverrideModDownloadLoaders").toBool());
auto loaders = Json::toStringList(settings->get("ModDownloadLoaders").toString());
if (loaders.isEmpty()) {
m_ui->neoForge->setChecked(instLoaders & ModPlatform::NeoForge);
m_ui->forge->setChecked(instLoaders & ModPlatform::Forge);
m_ui->fabric->setChecked(instLoaders & ModPlatform::Fabric);
m_ui->quilt->setChecked(instLoaders & ModPlatform::Quilt);
m_ui->liteLoader->setChecked(instLoaders & ModPlatform::LiteLoader);
} else {
m_ui->neoForge->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::NeoForge)));
m_ui->forge->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::Forge)));
m_ui->fabric->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::Fabric)));
m_ui->quilt->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::Quilt)));
m_ui->liteLoader->setChecked(loaders.contains(getModLoaderAsString(ModPlatform::LiteLoader)));
}
m_ui->loaderGroup->blockSignals(false);
m_ui->neoForge->blockSignals(false);
m_ui->forge->blockSignals(false);
m_ui->fabric->blockSignals(false);
m_ui->quilt->blockSignals(false);
m_ui->liteLoader->blockSignals(false);
}
m_ui->legacySettingsGroupBox->setChecked(settings->get("OverrideLegacySettings").toBool());
@@ -238,7 +281,6 @@ void MinecraftSettingsWidget::saveSettings()
{
SettingsObject::Lock lock(settings);
// Console
bool console = m_instance == nullptr || m_ui->consoleSettingsBox->isChecked();
@@ -267,7 +309,7 @@ void MinecraftSettingsWidget::saveSettings()
settings->set("LaunchMaximized", m_ui->maximizedCheckBox->isChecked());
settings->set("MinecraftWinWidth", m_ui->windowWidthSpinBox->value());
settings->set("MinecraftWinHeight", m_ui->windowHeightSpinBox->value());
settings->set("CloseAfterLaunch", m_ui->closeAfterLaunchCheck->isChecked());
settings->set("CloseAfterLaunch", m_ui->closeAfterLaunchCheck->isChecked());
settings->set("QuitAfterGameStop", m_ui->quitAfterGameStopCheck->isChecked());
} else {
settings->reset("LaunchMaximized");
@@ -444,3 +486,19 @@ bool MinecraftSettingsWidget::isQuickPlaySupported()
{
return m_instance->traits().contains("feature:is_quick_play_singleplayer");
}
void MinecraftSettingsWidget::selectedLoadersChanged()
{
QStringList loaders;
if (m_ui->neoForge->isChecked())
loaders << getModLoaderAsString(ModPlatform::NeoForge);
if (m_ui->forge->isChecked())
loaders << getModLoaderAsString(ModPlatform::Forge);
if (m_ui->fabric->isChecked())
loaders << getModLoaderAsString(ModPlatform::Fabric);
if (m_ui->quilt->isChecked())
loaders << getModLoaderAsString(ModPlatform::Quilt);
if (m_ui->liteLoader->isChecked())
loaders << getModLoaderAsString(ModPlatform::LiteLoader);
m_instance->settings()->set("ModDownloadLoaders", Json::fromStringList(loaders));
}

View File

@@ -56,6 +56,8 @@ class MinecraftSettingsWidget : public QWidget {
void openGlobalSettings();
void updateAccountsMenu(const SettingsObject& settings);
bool isQuickPlaySupported();
private slots:
void selectedLoadersChanged();
MinecraftInstancePtr m_instance;
Ui::MinecraftSettingsWidget* m_ui;

View File

@@ -58,9 +58,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-207</y>
<width>603</width>
<height>694</height>
<y>-537</y>
<width>623</width>
<height>1007</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
@@ -394,11 +394,67 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="loaderGroup">
<property name="title">
<string>Override Mod Download &amp;Loaders</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QCheckBox" name="neoForge">
<property name="text">
<string>NeoForge</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="forge">
<property name="text">
<string>Forge</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fabric">
<property name="text">
<string>Fabric</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="quilt">
<property name="text">
<string>Quilt</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="liteLoader">
<property name="text">
<string>LiteLoader</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
@@ -433,8 +489,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>487</height>
<width>98</width>
<height>28</height>
</rect>
</property>
</widget>
@@ -457,8 +513,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>624</width>
<height>487</height>
<width>299</width>
<height>499</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">

View File

@@ -40,6 +40,7 @@
#include <algorithm>
#include <list>
#include "BaseVersionList.h"
#include "Json.h"
#include "Version.h"
#include "meta/Index.h"
#include "modplatform/ModIndex.h"
@@ -218,7 +219,14 @@ void ModFilterWidget::prepareBasicFilter()
if (m_instance) {
m_filter->hideInstalled = false;
m_filter->side = ""; // or "both"
auto loaders = m_instance->getPackProfile()->getSupportedModLoaders().value();
ModPlatform::ModLoaderTypes loaders;
if (m_instance->settings()->get("OverrideModDownloadLoaders").toBool()) {
for (auto loader : Json::toStringList(m_instance->settings()->get("ModDownloadLoaders").toString())) {
loaders |= ModPlatform::getModLoaderFromString(loader);
}
} else {
loaders = m_instance->getPackProfile()->getSupportedModLoaders().value();
}
ui->neoForge->setChecked(loaders & ModPlatform::NeoForge);
ui->forge->setChecked(loaders & ModPlatform::Forge);
ui->fabric->setChecked(loaders & ModPlatform::Fabric);