diff options
-rw-r--r-- | .github/ISSUE_TEMPLATE/bug_report.yml | 1 | ||||
-rw-r--r-- | .github/ISSUE_TEMPLATE/suggestion.yml | 1 | ||||
-rw-r--r-- | api/logic/BaseInstance.cpp | 6 | ||||
-rw-r--r-- | api/logic/minecraft/MinecraftInstance.cpp | 7 | ||||
-rw-r--r-- | api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp | 60 | ||||
-rw-r--r-- | api/logic/modplatform/atlauncher/ATLPackInstallTask.h | 18 | ||||
-rw-r--r-- | api/logic/modplatform/atlauncher/ATLPackManifest.cpp | 33 | ||||
-rw-r--r-- | api/logic/modplatform/atlauncher/ATLPackManifest.h | 1 | ||||
-rw-r--r-- | application/MultiMC.cpp | 4 | ||||
-rw-r--r-- | application/pages/global/MinecraftPage.cpp | 7 | ||||
-rw-r--r-- | application/pages/global/MinecraftPage.ui | 23 | ||||
-rw-r--r-- | application/pages/instance/InstanceSettingsPage.cpp | 19 | ||||
-rw-r--r-- | application/pages/instance/InstanceSettingsPage.ui | 54 | ||||
-rw-r--r-- | application/pages/modplatform/atlauncher/AtlPage.cpp | 39 | ||||
-rw-r--r-- | application/pages/modplatform/atlauncher/AtlPage.h | 5 |
15 files changed, 248 insertions, 30 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 7e894785..5b8d858e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,7 +1,6 @@ name: Bug Report description: File a bug report labels: [bug, needs-triage] -issue_body: false body: - type: markdown attributes: diff --git a/.github/ISSUE_TEMPLATE/suggestion.yml b/.github/ISSUE_TEMPLATE/suggestion.yml index ab2449a0..4c6a9eb9 100644 --- a/.github/ISSUE_TEMPLATE/suggestion.yml +++ b/.github/ISSUE_TEMPLATE/suggestion.yml @@ -1,7 +1,6 @@ name: Suggestion description: Make a suggestion labels: [idea, needs-triage] -issue_body: true body: - type: markdown attributes: diff --git a/api/logic/BaseInstance.cpp b/api/logic/BaseInstance.cpp index d08ceb2b..cff16631 100644 --- a/api/logic/BaseInstance.cpp +++ b/api/logic/BaseInstance.cpp @@ -134,6 +134,12 @@ void BaseInstance::setRunning(bool running) m_isRunning = running; + if(!m_settings->get("RecordGameTime").toBool()) + { + emit runningStatusChanged(running); + return; + } + if(running) { m_timeStarted = QDateTime::currentDateTime(); diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp index 37cdece7..2d112757 100644 --- a/api/logic/minecraft/MinecraftInstance.cpp +++ b/api/logic/minecraft/MinecraftInstance.cpp @@ -106,6 +106,11 @@ MinecraftInstance::MinecraftInstance(SettingsObjectPtr globalSettings, SettingsO m_settings->registerOverride(globalSettings->getSetting("UseNativeOpenAL"), nativeLibraryWorkaroundsOverride); m_settings->registerOverride(globalSettings->getSetting("UseNativeGLFW"), nativeLibraryWorkaroundsOverride); + // Game time + auto gameTimeOverride = m_settings->registerSetting("OverrideGameTime", false); + m_settings->registerOverride(globalSettings->getSetting("ShowGameTime"), gameTimeOverride); + m_settings->registerOverride(globalSettings->getSetting("RecordGameTime"), gameTimeOverride); + // DEPRECATED: Read what versions the user configuration thinks should be used m_settings->registerSetting({"IntendedVersion", "MinecraftVersion"}, ""); m_settings->registerSetting("LWJGLVersion", ""); @@ -769,7 +774,7 @@ QString MinecraftInstance::getStatusbarDescription() QString description; description.append(tr("Minecraft %1 (%2)").arg(m_components->getComponentVersion("net.minecraft")).arg(typeName())); - if(totalTimePlayed() > 0) + if(m_settings->get("ShowGameTime").toBool() && totalTimePlayed() > 0) { description.append(tr(", played for %1").arg(prettifyTimeDuration(totalTimePlayed()))); } diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp index 12ceaccd..89c4dfd3 100644 --- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -18,8 +18,9 @@ namespace ATLauncher { -PackInstallTask::PackInstallTask(QString pack, QString version) +PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString pack, QString version) { + m_support = support; m_pack = pack; m_version_name = version; } @@ -154,23 +155,56 @@ QString PackInstallTask::getVersionForLoader(QString uid) auto vlist = ENV.metadataIndex()->get(uid); if(!vlist) { - emitFailed(tr("Failed to get local metadata index for ") + uid); + emitFailed(tr("Failed to get local metadata index for %1").arg(uid)); return Q_NULLPTR; } - // todo: filter by Minecraft version - - if(m_version.loader.recommended) { - return vlist.get()->getRecommended().get()->descriptor(); + if(!vlist->isLoaded()) { + vlist->load(Net::Mode::Online); } - else if(m_version.loader.latest) { - return vlist.get()->at(0)->descriptor(); + + if(m_version.loader.recommended || m_version.loader.latest) { + for (int i = 0; i < vlist->versions().size(); i++) { + auto version = vlist->versions().at(i); + auto reqs = version->requires(); + + // filter by minecraft version, if the loader depends on a certain version. + // not all mod loaders depend on a given Minecraft version, so we won't do this + // filtering for those loaders. + if (m_version.loader.type != "fabric") { + auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require &req) { + return req.uid == "net.minecraft"; + }); + if (iter == reqs.end()) continue; + if (iter->equalsVersion != m_version.minecraft) continue; + } + + if (m_version.loader.recommended) { + // first recommended build we find, we use. + if (!version->isRecommended()) continue; + } + + return version->descriptor(); + } + + emitFailed(tr("Failed to find version for %1 loader").arg(m_version.loader.type)); + return Q_NULLPTR; } else if(m_version.loader.choose) { - // todo: implement + // Fabric Loader doesn't depend on a given Minecraft version. + if (m_version.loader.type == "fabric") { + return m_support->chooseVersion(vlist, Q_NULLPTR); + } + + return m_support->chooseVersion(vlist, m_version.minecraft); } } + if (m_version.loader.version == Q_NULLPTR || m_version.loader.version.isEmpty()) { + emitFailed(tr("No loader version set for modpack!")); + return Q_NULLPTR; + } + return m_version.loader.version; } @@ -428,6 +462,9 @@ void PackInstallTask::downloadMods() jarmods.clear(); jobPtr.reset(new NetJob(tr("Mod download"))); for(const auto& mod : m_version.mods) { + // skip non-client mods + if (!mod.client) continue; + // skip optional mods for now if(mod.optional) continue; @@ -451,7 +488,6 @@ void PackInstallTask::downloadMods() auto cacheName = fileName.completeBaseName() + "-" + mod.md5 + "." + fileName.suffix(); if (mod.type == ModType::Extract || mod.type == ModType::TexturePackExtract || mod.type == ModType::ResourcePackExtract) { - auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName); entry->setStale(true); modsToExtract.insert(entry->getFullPath(), mod); @@ -522,7 +558,7 @@ void PackInstallTask::onModsDownloaded() { qDebug() << "PackInstallTask::onModsDownloaded: " << QThread::currentThreadId(); jobPtr.reset(); - if(modsToExtract.size() || modsToDecomp.size() || modsToCopy.size()) { + if(!modsToExtract.empty() || !modsToDecomp.empty() || !modsToCopy.empty()) { m_modExtractFuture = QtConcurrent::run(QThreadPool::globalInstance(), this, &PackInstallTask::extractMods, modsToExtract, modsToDecomp, modsToCopy); connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onModsExtracted); connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]() @@ -629,6 +665,7 @@ void PackInstallTask::install() // Use a component to add libraries BEFORE Minecraft if(!createLibrariesComponent(instance.instanceRoot(), components)) { + emitFailed(tr("Failed to create libraries component")); return; } @@ -666,6 +703,7 @@ void PackInstallTask::install() // Use a component to fill in the rest of the data // todo: use more detection if(!createPackComponent(instance.instanceRoot(), components)) { + emitFailed(tr("Failed to create pack component")); return; } diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h index 78544bab..3647e471 100644 --- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h +++ b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h @@ -15,12 +15,23 @@ namespace ATLauncher { +class MULTIMC_LOGIC_EXPORT UserInteractionSupport { + +public: + /** + * Requests a user interaction to select a component version from a given version list + * and constrained to a given Minecraft version. + */ + virtual QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) = 0; + +}; + class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask { Q_OBJECT public: - explicit PackInstallTask(QString pack, QString version); + explicit PackInstallTask(UserInteractionSupport *support, QString pack, QString version); virtual ~PackInstallTask(){} bool abort() override; @@ -54,6 +65,8 @@ private: void install(); private: + UserInteractionSupport *m_support; + NetJobPtr jobPtr; QByteArray response; @@ -76,9 +89,6 @@ private: QFuture<bool> m_modExtractFuture; QFutureWatcher<bool> m_modExtractFutureWatcher; - QFuture<bool> m_decompFuture; - QFutureWatcher<bool> m_decompFutureWatcher; - }; } diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp index 84389330..57cc52b6 100644 --- a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp +++ b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp @@ -81,12 +81,21 @@ static ATLauncher::ModType parseModType(QString rawType) { static void loadVersionLoader(ATLauncher::VersionLoader & p, QJsonObject & obj) { p.type = Json::requireString(obj, "type"); - p.latest = Json::ensureBoolean(obj, QString("latest"), false); p.choose = Json::ensureBoolean(obj, QString("choose"), false); - p.recommended = Json::ensureBoolean(obj, QString("recommended"), false); auto metadata = Json::requireObject(obj, "metadata"); - p.version = Json::requireString(metadata, "version"); + p.latest = Json::ensureBoolean(metadata, QString("latest"), false); + p.recommended = Json::ensureBoolean(metadata, QString("recommended"), false); + + // Minecraft Forge + if (p.type == "forge") { + p.version = Json::ensureString(metadata, "version", ""); + } + + // Fabric Loader + if (p.type == "fabric") { + p.version = Json::ensureString(metadata, "loader", ""); + } } static void loadVersionLibrary(ATLauncher::VersionLibrary & p, QJsonObject & obj) { @@ -135,6 +144,7 @@ static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) { } p.optional = Json::ensureBoolean(obj, QString("optional"), false); + p.client = Json::ensureBoolean(obj, QString("client"), false); } void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) @@ -169,12 +179,15 @@ void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj) } } - auto mods = Json::requireArray(obj, "mods"); - for (const auto modRaw : mods) - { - auto modObj = Json::requireObject(modRaw); - ATLauncher::VersionMod mod; - loadVersionMod(mod, modObj); - v.mods.append(mod); + + if(obj.contains("mods")) { + auto mods = Json::requireArray(obj, "mods"); + for (const auto modRaw : mods) + { + auto modObj = Json::requireObject(modRaw); + ATLauncher::VersionMod mod; + loadVersionMod(mod, modObj); + v.mods.append(mod); + } } } diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.h b/api/logic/modplatform/atlauncher/ATLPackManifest.h index 1adf889b..937106a5 100644 --- a/api/logic/modplatform/atlauncher/ATLPackManifest.h +++ b/api/logic/modplatform/atlauncher/ATLPackManifest.h @@ -87,6 +87,7 @@ struct VersionMod QString decompFile; bool optional; + bool client; }; struct PackVersion diff --git a/application/MultiMC.cpp b/application/MultiMC.cpp index 22946e08..3429a377 100644 --- a/application/MultiMC.cpp +++ b/application/MultiMC.cpp @@ -514,6 +514,10 @@ MultiMC::MultiMC(int &argc, char **argv) : QApplication(argc, argv) m_settings->registerSetting("UseNativeOpenAL", false); m_settings->registerSetting("UseNativeGLFW", false); + // Game time + m_settings->registerSetting("ShowGameTime", true); + m_settings->registerSetting("RecordGameTime", true); + // Minecraft launch method m_settings->registerSetting("MCLaunchMethod", "LauncherPart"); diff --git a/application/pages/global/MinecraftPage.cpp b/application/pages/global/MinecraftPage.cpp index 6a780fb4..6c9bd307 100644 --- a/application/pages/global/MinecraftPage.cpp +++ b/application/pages/global/MinecraftPage.cpp @@ -67,6 +67,10 @@ void MinecraftPage::applySettings() // Native library workarounds s->set("UseNativeOpenAL", ui->useNativeOpenALCheck->isChecked()); s->set("UseNativeGLFW", ui->useNativeGLFWCheck->isChecked()); + + // Game time + s->set("ShowGameTime", ui->showGameTime->isChecked()); + s->set("RecordGameTime", ui->recordGameTime->isChecked()); } void MinecraftPage::loadSettings() @@ -80,4 +84,7 @@ void MinecraftPage::loadSettings() ui->useNativeOpenALCheck->setChecked(s->get("UseNativeOpenAL").toBool()); ui->useNativeGLFWCheck->setChecked(s->get("UseNativeGLFW").toBool()); + + ui->showGameTime->setChecked(s->get("ShowGameTime").toBool()); + ui->recordGameTime->setChecked(s->get("RecordGameTime").toBool()); } diff --git a/application/pages/global/MinecraftPage.ui b/application/pages/global/MinecraftPage.ui index c096c969..2abd4bd4 100644 --- a/application/pages/global/MinecraftPage.ui +++ b/application/pages/global/MinecraftPage.ui @@ -135,6 +135,29 @@ </widget> </item> <item> + <widget class="QGroupBox" name="gameTimeGroupBox"> + <property name="title"> + <string>Game time</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <widget class="QCheckBox" name="showGameTime"> + <property name="text"> + <string>Show time spent playing instances</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="recordGameTime"> + <property name="text"> + <string>Record time spent playing instances</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> <spacer name="verticalSpacerMinecraft"> <property name="orientation"> <enum>Qt::Vertical</enum> diff --git a/application/pages/instance/InstanceSettingsPage.cpp b/application/pages/instance/InstanceSettingsPage.cpp index 9a39b034..05041c82 100644 --- a/application/pages/instance/InstanceSettingsPage.cpp +++ b/application/pages/instance/InstanceSettingsPage.cpp @@ -177,6 +177,20 @@ void InstanceSettingsPage::applySettings() m_settings->reset("UseNativeOpenAL"); m_settings->reset("UseNativeGLFW"); } + + // Game time + bool gameTime = ui->gameTimeGroupBox->isChecked(); + m_settings->set("OverrideGameTime", gameTime); + if (gameTime) + { + m_settings->set("ShowGameTime", ui->showGameTime->isChecked()); + m_settings->set("RecordGameTime", ui->recordGameTime->isChecked()); + } + else + { + m_settings->reset("ShowGameTime"); + m_settings->reset("RecordGameTime"); + } } void InstanceSettingsPage::loadSettings() @@ -238,6 +252,11 @@ void InstanceSettingsPage::loadSettings() ui->nativeWorkaroundsGroupBox->setChecked(m_settings->get("OverrideNativeWorkarounds").toBool()); ui->useNativeGLFWCheck->setChecked(m_settings->get("UseNativeGLFW").toBool()); ui->useNativeOpenALCheck->setChecked(m_settings->get("UseNativeOpenAL").toBool()); + + // Miscellanous + ui->gameTimeGroupBox->setChecked(m_settings->get("OverrideGameTime").toBool()); + ui->showGameTime->setChecked(m_settings->get("ShowGameTime").toBool()); + ui->recordGameTime->setChecked(m_settings->get("RecordGameTime").toBool()); } void InstanceSettingsPage::on_javaDetectBtn_clicked() diff --git a/application/pages/instance/InstanceSettingsPage.ui b/application/pages/instance/InstanceSettingsPage.ui index c91570c6..64f90fad 100644 --- a/application/pages/instance/InstanceSettingsPage.ui +++ b/application/pages/instance/InstanceSettingsPage.ui @@ -416,6 +416,58 @@ </item> </layout> </widget> + <widget class="QWidget" name="miscellanousPage"> + <attribute name="title"> + <string>Miscellanous</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_9"> + <item> + <widget class="QGroupBox" name="gameTimeGroupBox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="title"> + <string>Override global game time settings</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>false</bool> + </property> + <layout class="QVBoxLayout" name="verticalLayout_10"> + <item> + <widget class="QCheckBox" name="showGameTime"> + <property name="text"> + <string>Show time spent playing this instance</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="recordGameTime"> + <property name="text"> + <string>Record time spent playing this instance</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="verticalSpacerMiscellanous"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> </widget> </item> </layout> @@ -453,6 +505,8 @@ <tabstop>nativeWorkaroundsGroupBox</tabstop> <tabstop>useNativeGLFWCheck</tabstop> <tabstop>useNativeOpenALCheck</tabstop> + <tabstop>showGameTime</tabstop> + <tabstop>recordGameTime</tabstop> </tabstops> <resources/> <connections/> diff --git a/application/pages/modplatform/atlauncher/AtlPage.cpp b/application/pages/modplatform/atlauncher/AtlPage.cpp index f90d734c..748f467c 100644 --- a/application/pages/modplatform/atlauncher/AtlPage.cpp +++ b/application/pages/modplatform/atlauncher/AtlPage.cpp @@ -4,6 +4,7 @@ #include "dialogs/NewInstanceDialog.h" #include <modplatform/atlauncher/ATLPackInstallTask.h> #include <BuildConfig.h> +#include <dialogs/VersionSelectDialog.h> AtlPage::AtlPage(NewInstanceDialog* dialog, QWidget *parent) : QWidget(parent), ui(new Ui::AtlPage), dialog(dialog) @@ -50,7 +51,7 @@ void AtlPage::openedImpl() void AtlPage::suggestCurrent() { if(isOpened) { - dialog->setSuggestedPack(selected.name, new ATLauncher::PackInstallTask(selected.safeName, selectedVersion)); + dialog->setSuggestedPack(selected.name, new ATLauncher::PackInstallTask(this, selected.safeName, selectedVersion)); } auto editedLogoName = selected.safeName; @@ -112,3 +113,39 @@ void AtlPage::onVersionSelectionChanged(QString data) selectedVersion = data; suggestCurrent(); } + +QString AtlPage::chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) { + VersionSelectDialog vselect(vlist.get(), "Choose Version", MMC->activeWindow(), false); + if (minecraftVersion != Q_NULLPTR) { + vselect.setExactFilter(BaseVersionList::ParentVersionRole, minecraftVersion); + vselect.setEmptyString(tr("No versions are currently available for Minecraft %1").arg(minecraftVersion)); + } + else { + vselect.setEmptyString(tr("No versions are currently available")); + } + vselect.setEmptyErrorString(tr("Couldn't load or download the version lists!")); + + // select recommended build + for (int i = 0; i < vlist->versions().size(); i++) { + auto version = vlist->versions().at(i); + auto reqs = version->requires(); + + // filter by minecraft version, if the loader depends on a certain version. + if (minecraftVersion != Q_NULLPTR) { + auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require &req) { + return req.uid == "net.minecraft"; + }); + if (iter == reqs.end()) continue; + if (iter->equalsVersion != minecraftVersion) continue; + } + + // first recommended build we find, we use. + if (version->isRecommended()) { + vselect.setCurrentVersion(version->descriptor()); + break; + } + } + + vselect.exec(); + return vselect.selectedVersion()->descriptor(); +} diff --git a/application/pages/modplatform/atlauncher/AtlPage.h b/application/pages/modplatform/atlauncher/AtlPage.h index 715cf5f4..6a89b609 100644 --- a/application/pages/modplatform/atlauncher/AtlPage.h +++ b/application/pages/modplatform/atlauncher/AtlPage.h @@ -19,6 +19,7 @@ #include "AtlListModel.h" #include <QWidget> +#include <modplatform/atlauncher/ATLPackInstallTask.h> #include "MultiMC.h" #include "pages/BasePage.h" @@ -31,7 +32,7 @@ namespace Ui class NewInstanceDialog; -class AtlPage : public QWidget, public BasePage +class AtlPage : public QWidget, public BasePage, public ATLauncher::UserInteractionSupport { Q_OBJECT @@ -61,6 +62,8 @@ public: private: void suggestCurrent(); + QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) override; + private slots: void triggerSearch(); void resetSearch(); |