From 22327bbe71b271a126521db737101ae07ba26f8d Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 6 Jul 2023 18:04:44 +0100 Subject: Combine launch buttons in Instance window, persist profiler Signed-off-by: TheKodeToad --- launcher/Application.cpp | 21 +++-- launcher/Application.h | 13 ++-- launcher/BaseInstance.cpp | 5 +- launcher/BaseInstance.h | 14 +++- launcher/LaunchController.cpp | 10 +-- launcher/NullInstance.h | 6 +- launcher/minecraft/MinecraftInstance.cpp | 50 +++++++++++- launcher/minecraft/MinecraftInstance.h | 4 +- launcher/ui/InstanceWindow.cpp | 115 ++++++++-------------------- launcher/ui/InstanceWindow.h | 16 ++-- launcher/ui/MainWindow.cpp | 119 ++--------------------------- launcher/ui/MainWindow.h | 8 +- launcher/ui/MainWindow.ui | 22 +----- launcher/ui/pages/instance/ServersPage.cpp | 4 +- 14 files changed, 143 insertions(+), 264 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 1d97a5f2..625cebd3 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1005,7 +1005,7 @@ void Application::performMainStartupAction() qDebug() << " Launching with account" << m_profileToUse; } - launch(inst, true, false, nullptr, serverToJoin, accountToUse); + launch(inst, true, false, serverToJoin, accountToUse); return; } } @@ -1120,7 +1120,6 @@ void Application::messageReceived(const QByteArray& message) instance, true, false, - nullptr, serverObject, accountObject ); @@ -1187,14 +1186,12 @@ bool Application::openJsonEditor(const QString &filename) } } -bool Application::launch( - InstancePtr instance, - bool online, - bool demo, - BaseProfilerFactory *profiler, - MinecraftServerTargetPtr serverToJoin, - MinecraftAccountPtr accountToUse -) { +bool Application::launch(InstancePtr instance, + bool online, + bool demo, + MinecraftServerTargetPtr serverToJoin, + MinecraftAccountPtr accountToUse) +{ if(m_updateRunning) { qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; @@ -1202,7 +1199,7 @@ bool Application::launch( else if(instance->canLaunch()) { auto & extras = m_instanceExtras[instance->id()]; - auto & window = extras.window; + auto window = extras.window; if(window) { if(!window->saveAll()) @@ -1215,7 +1212,7 @@ bool Application::launch( controller->setInstance(instance); controller->setOnline(online); controller->setDemo(demo); - controller->setProfiler(profiler); + controller->setProfiler(profilers().value(instance->settings()->get("Profiler").toString(), nullptr).get()); controller->setServerToJoin(serverToJoin); controller->setAccountToUse(accountToUse); if(window) diff --git a/launcher/Application.h b/launcher/Application.h index ced0af17..b911edc1 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -222,14 +222,11 @@ signals: #endif public slots: - bool launch( - InstancePtr instance, - bool online = true, - bool demo = false, - BaseProfilerFactory *profiler = nullptr, - MinecraftServerTargetPtr serverToJoin = nullptr, - MinecraftAccountPtr accountToUse = nullptr - ); + bool launch(InstancePtr instance, + bool online = true, + bool demo = false, + MinecraftServerTargetPtr serverToJoin = nullptr, + MinecraftAccountPtr accountToUse = nullptr); bool kill(InstancePtr instance); void closeCurrentWindow(); diff --git a/launcher/BaseInstance.cpp b/launcher/BaseInstance.cpp index a8fce879..28b4cb5c 100644 --- a/launcher/BaseInstance.cpp +++ b/launcher/BaseInstance.cpp @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -101,6 +102,8 @@ BaseInstance::BaseInstance(SettingsObjectPtr globalSettings, SettingsObjectPtr s m_settings->registerSetting("ManagedPackName", ""); m_settings->registerSetting("ManagedPackVersionID", ""); m_settings->registerSetting("ManagedPackVersionName", ""); + + m_settings->registerSetting("Profiler", ""); } QString BaseInstance::getPreLaunchCommand() diff --git a/launcher/BaseInstance.h b/launcher/BaseInstance.h index 83a8064f..7da4e20b 100644 --- a/launcher/BaseInstance.h +++ b/launcher/BaseInstance.h @@ -1,8 +1,9 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (c) 2022 Jamie Mansfield + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,11 +38,12 @@ #pragma once #include -#include -#include "QObjectPtr.h" #include -#include +#include +#include #include +#include +#include "QObjectPtr.h" #include "settings/SettingsObject.h" @@ -270,6 +272,8 @@ public: virtual bool canEdit() const = 0; virtual bool canExport() const = 0; + virtual void populateLaunchMenu(QMenu* menu) = 0; + bool reloadSettings(); /** @@ -306,6 +310,8 @@ signals: void runningStatusChanged(bool running); + void profilerChanged(); + void statusChanged(Status from, Status to); protected slots: diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 070ee283..5a79b253 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -406,22 +407,21 @@ void LaunchController::readyForLaunch() if (!m_profiler->check(&error)) { m_launcher->abort(); - QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Couldn't start profiler: %1").arg(error)); emitFailed("Profiler startup failed!"); + QMessageBox::critical(m_parentWidget, tr("Error!"), tr("Profiler check for %1 failed: %2").arg(m_profiler->name(), error)); return; } BaseProfiler *profilerInstance = m_profiler->createProfiler(m_launcher->instance(), this); connect(profilerInstance, &BaseProfiler::readyToLaunch, [this](const QString & message) { - QMessageBox msg; + QMessageBox msg(m_parentWidget); msg.setText(tr("The game launch is delayed until you press the " "button. This is the right time to setup the profiler, as the " "profiler server is running now.\n\n%1").arg(message)); msg.setWindowTitle(tr("Waiting.")); msg.setIcon(QMessageBox::Information); - msg.addButton(tr("Launch"), QMessageBox::AcceptRole); - msg.setModal(true); + msg.addButton(tr("&Launch"), QMessageBox::AcceptRole); msg.exec(); m_launcher->proceed(); }); diff --git a/launcher/NullInstance.h b/launcher/NullInstance.h index 53edfa0b..b0ec89f4 100644 --- a/launcher/NullInstance.h +++ b/launcher/NullInstance.h @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -110,6 +111,9 @@ public: { return false; } + void populateLaunchMenu(QMenu* menu) override + { + } QStringList verboseDescription(AuthSessionPtr session, MinecraftServerTargetPtr serverToJoin) override { QStringList out; diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index aab930de..d511451e 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -3,7 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu * Copyright (C) 2022 Jamie Mansfield - * Copyright (C) 2022 TheKodeToad + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -88,6 +88,8 @@ #include "minecraft/gameoptions/GameOptions.h" #include "minecraft/update/FoldersTask.h" +#include "tools/BaseProfiler.h" + #ifdef Q_OS_LINUX #include "MangoHud.h" #endif @@ -234,6 +236,52 @@ QSet MinecraftInstance::traits() const return profile->getTraits(); } +void MinecraftInstance::populateLaunchMenu(QMenu* menu) +{ + QAction* normalLaunch = menu->addAction(tr("&Launch")); + normalLaunch->setShortcut(QKeySequence::Open); + QAction* normalLaunchOffline = menu->addAction(tr("Launch &Offline")); + normalLaunchOffline->setShortcut(QKeySequence(tr("Ctrl+Shift+O"))); + QAction* normalLaunchDemo = menu->addAction(tr("Launch &Demo")); + normalLaunchDemo->setShortcut(QKeySequence(tr("Ctrl+Alt+O"))); + + normalLaunchDemo->setEnabled(supportsDemo()); + + connect(normalLaunch, &QAction::triggered, [this] { APPLICATION->launch(shared_from_this()); }); + connect(normalLaunchOffline, &QAction::triggered, [this] { APPLICATION->launch(shared_from_this(), false, false); }); + connect(normalLaunchDemo, &QAction::triggered, [this] { APPLICATION->launch(shared_from_this(), false, true); }); + + QString profilersTitle = tr("Profilers"); + menu->addSeparator()->setText(profilersTitle); + + auto profilers = new QActionGroup(menu); + profilers->setExclusive(true); + connect(profilers, &QActionGroup::triggered, [this](QAction* action) { + settings()->set("Profiler", action->data()); + emit profilerChanged(); + }); + + QAction* noProfilerAction = menu->addAction(tr("&No Profiler")); + noProfilerAction->setData(""); + noProfilerAction->setCheckable(true); + noProfilerAction->setChecked(true); + profilers->addAction(noProfilerAction); + + for (auto profiler = APPLICATION->profilers().begin(); profiler != APPLICATION->profilers().end(); profiler++) { + QAction* profilerAction = menu->addAction(profiler.value()->name()); + profilers->addAction(profilerAction); + profilerAction->setData(profiler.key()); + profilerAction->setCheckable(true); + profilerAction->setChecked(settings()->get("Profiler").toString() == profiler.key()); + + QString error; + if (profiler.value()->check(&error)) + profilerAction->setIcon(APPLICATION->getThemedIcon("status-good")); + else + profilerAction->setIcon(APPLICATION->getThemedIcon("status-bad")); + } +} + QString MinecraftInstance::gameRoot() const { QFileInfo mcDir(FS::PathCombine(instanceRoot(), "minecraft")); diff --git a/launcher/minecraft/MinecraftInstance.h b/launcher/minecraft/MinecraftInstance.h index 068b3008..c5ebbb7c 100644 --- a/launcher/minecraft/MinecraftInstance.h +++ b/launcher/minecraft/MinecraftInstance.h @@ -2,7 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu - * Copyright (C) 2022 TheKodeToad + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -77,6 +77,8 @@ public: return true; } + void populateLaunchMenu(QMenu* menu) override; + ////// Directories and files ////// QString jarModsDir() const; QString resourcePacksDir() const; diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index c62b370f..350b1907 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -43,8 +44,6 @@ #include #include -#include "ui/dialogs/CustomMessageBox.h" -#include "ui/dialogs/ProgressDialog.h" #include "ui/widgets/PageContainer.h" #include "InstancePageProvider.h" @@ -83,33 +82,36 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) auto btnHelp = new QPushButton(); btnHelp->setText(tr("Help")); horizontalLayout->addWidget(btnHelp); - connect(btnHelp, SIGNAL(clicked(bool)), m_container, SLOT(help())); + connect(btnHelp, &QPushButton::clicked, m_container, &PageContainer::help); auto spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); horizontalLayout->addSpacerItem(spacer); - m_killButton = new QPushButton(); - horizontalLayout->addWidget(m_killButton); - connect(m_killButton, SIGNAL(clicked(bool)), SLOT(on_btnKillMinecraft_clicked())); - - m_launchOfflineButton = new QPushButton(); - horizontalLayout->addWidget(m_launchOfflineButton); - m_launchOfflineButton->setText(tr("Launch Offline")); + m_launchButton = new QToolButton(this); + m_launchButton->setText(tr("&Launch")); + m_launchButton->setToolTip(tr("Launch the instance")); + m_launchButton->setPopupMode(QToolButton::MenuButtonPopup); + m_launchButton->setMinimumWidth(80); // HACK!! + horizontalLayout->addWidget(m_launchButton); + connect(m_launchButton, &QPushButton::clicked, this, [this] { APPLICATION->launch(m_instance); }); - m_launchDemoButton = new QPushButton(); - horizontalLayout->addWidget(m_launchDemoButton); - m_launchDemoButton->setText(tr("Launch Demo")); + m_killButton = new QPushButton(this); + m_killButton->setText(tr("&Kill")); + m_killButton->setToolTip(tr("Kill the running instance")); + horizontalLayout->addWidget(m_killButton); + connect(m_killButton, &QPushButton::clicked, this, [this] { APPLICATION->kill(m_instance); }); - updateLaunchButtons(); - connect(m_launchOfflineButton, SIGNAL(clicked(bool)), SLOT(on_btnLaunchMinecraftOffline_clicked())); - connect(m_launchDemoButton, SIGNAL(clicked(bool)), SLOT(on_btnLaunchMinecraftDemo_clicked())); + updateButtons(); m_closeButton = new QPushButton(); m_closeButton->setText(tr("Close")); horizontalLayout->addWidget(m_closeButton); - connect(m_closeButton, SIGNAL(clicked(bool)), SLOT(on_closeButton_clicked())); + connect(m_closeButton, &QPushButton::clicked, this, &QMainWindow::close); m_container->addButtons(horizontalLayout); + + connect(m_instance.get(), &BaseInstance::profilerChanged, this, &InstanceWindow::updateButtons); + connect(APPLICATION, &Application::globalSettingsClosed, this, &InstanceWindow::updateButtons); } // restore window state @@ -150,52 +152,18 @@ void InstanceWindow::on_instanceStatusChanged(BaseInstance::Status, BaseInstance } } -void InstanceWindow::updateLaunchButtons() +void InstanceWindow::updateButtons() { - if(m_instance->isRunning()) - { - m_launchOfflineButton->setEnabled(false); - m_launchDemoButton->setEnabled(false); - m_killButton->setText(tr("Kill")); - m_killButton->setObjectName("killButton"); - m_killButton->setToolTip(tr("Kill the running instance")); - } - else if(!m_instance->canLaunch()) - { - m_launchOfflineButton->setEnabled(false); - m_launchDemoButton->setEnabled(false); - m_killButton->setText(tr("Launch")); - m_killButton->setObjectName("launchButton"); - m_killButton->setToolTip(tr("Launch the instance")); - m_killButton->setEnabled(false); - } - else - { - m_launchOfflineButton->setEnabled(true); + m_launchButton->setEnabled(m_instance->canLaunch()); + m_killButton->setEnabled(m_instance->isRunning()); - // Disable demo-mode if not available. - auto instance = dynamic_cast(m_instance.get()); - if (instance) { - m_launchDemoButton->setEnabled(instance->supportsDemo()); - } - - m_killButton->setText(tr("Launch")); - m_killButton->setObjectName("launchButton"); - m_killButton->setToolTip(tr("Launch the instance")); - } - // NOTE: this is a hack to force the button to recalculate its style - m_killButton->setStyleSheet("/* */"); - m_killButton->setStyleSheet(QString()); -} - -void InstanceWindow::on_btnLaunchMinecraftOffline_clicked() -{ - APPLICATION->launch(m_instance, false, false, nullptr); -} - -void InstanceWindow::on_btnLaunchMinecraftDemo_clicked() -{ - APPLICATION->launch(m_instance, false, true, nullptr); + QMenu *launchMenu = m_launchButton->menu(); + if (launchMenu) + launchMenu->clear(); + else + launchMenu = new QMenu(this); + m_instance->populateLaunchMenu(launchMenu); + m_launchButton->setMenu(launchMenu); } void InstanceWindow::instanceLaunchTaskChanged(shared_qobject_ptr proc) @@ -205,18 +173,13 @@ void InstanceWindow::instanceLaunchTaskChanged(shared_qobject_ptr pr void InstanceWindow::runningStateChanged(bool running) { - updateLaunchButtons(); + updateButtons(); m_container->refreshContainer(); if(running) { selectPage("log"); } } -void InstanceWindow::on_closeButton_clicked() -{ - close(); -} - void InstanceWindow::closeEvent(QCloseEvent *event) { bool proceed = true; @@ -241,18 +204,6 @@ bool InstanceWindow::saveAll() return m_container->saveAll(); } -void InstanceWindow::on_btnKillMinecraft_clicked() -{ - if(m_instance->isRunning()) - { - APPLICATION->kill(m_instance); - } - else - { - APPLICATION->launch(m_instance, true, false, nullptr); - } -} - QString InstanceWindow::instanceId() { return m_instance->id(); @@ -268,10 +219,6 @@ void InstanceWindow::refreshContainer() m_container->refreshContainer(); } -InstanceWindow::~InstanceWindow() -{ -} - bool InstanceWindow::requestClose() { if(m_container->prepareToClose()) diff --git a/launcher/ui/InstanceWindow.h b/launcher/ui/InstanceWindow.h index 554c4c74..64d9a45e 100644 --- a/launcher/ui/InstanceWindow.h +++ b/launcher/ui/InstanceWindow.h @@ -1,7 +1,8 @@ // SPDX-License-Identifier: GPL-3.0-only /* - * PolyMC - Minecraft Launcher + * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,6 +38,7 @@ #include #include +#include #include "LaunchController.h" #include "launch/LaunchTask.h" @@ -53,7 +55,7 @@ class InstanceWindow : public QMainWindow, public BasePageContainer public: explicit InstanceWindow(InstancePtr proc, QWidget *parent = 0); - virtual ~InstanceWindow(); + virtual ~InstanceWindow() = default; bool selectPage(QString pageId) override; void refreshContainer() override; @@ -71,11 +73,6 @@ signals: private slots: - void on_closeButton_clicked(); - void on_btnKillMinecraft_clicked(); - void on_btnLaunchMinecraftOffline_clicked(); - void on_btnLaunchMinecraftDemo_clicked(); - void instanceLaunchTaskChanged(shared_qobject_ptr proc); void runningStateChanged(bool running); void on_instanceStatusChanged(BaseInstance::Status, BaseInstance::Status newStatus); @@ -84,7 +81,7 @@ protected: void closeEvent(QCloseEvent *) override; private: - void updateLaunchButtons(); + void updateButtons(); private: shared_qobject_ptr m_proc; @@ -92,7 +89,6 @@ private: bool m_doNotSave = false; PageContainer *m_container = nullptr; QPushButton *m_closeButton = nullptr; + QToolButton *m_launchButton = nullptr; QPushButton *m_killButton = nullptr; - QPushButton *m_launchOfflineButton = nullptr; - QPushButton *m_launchDemoButton = nullptr; }; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 515abf07..a2137dd3 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -572,93 +572,14 @@ void MainWindow::updateMainToolBar() ui->mainToolBar->setVisible(ui->menuBar->isNativeMenuBar() || !APPLICATION->settings()->get("MenuBarInsteadOfToolBar").toBool()); } -void MainWindow::updateToolsMenu() +void MainWindow::updateLaunchButton() { - bool currentInstanceRunning = m_selectedInstance && m_selectedInstance->isRunning(); - - ui->actionLaunchInstance->setDisabled(!m_selectedInstance || currentInstanceRunning); - ui->actionLaunchInstanceOffline->setDisabled(!m_selectedInstance || currentInstanceRunning); - ui->actionLaunchInstanceDemo->setDisabled(!m_selectedInstance || currentInstanceRunning); - QMenu *launchMenu = ui->actionLaunchInstance->menu(); if (launchMenu) - { launchMenu->clear(); - } else - { launchMenu = new QMenu(this); - } - QAction *normalLaunch = launchMenu->addAction(tr("Launch")); - normalLaunch->setShortcut(QKeySequence::Open); - QAction *normalLaunchOffline = launchMenu->addAction(tr("Launch Offline")); - normalLaunchOffline->setShortcut(QKeySequence(tr("Ctrl+Shift+O"))); - QAction *normalLaunchDemo = launchMenu->addAction(tr("Launch Demo")); - normalLaunchDemo->setShortcut(QKeySequence(tr("Ctrl+Alt+O"))); - if (m_selectedInstance) - { - normalLaunch->setEnabled(m_selectedInstance->canLaunch()); - normalLaunchOffline->setEnabled(m_selectedInstance->canLaunch()); - normalLaunchDemo->setEnabled(m_selectedInstance->canLaunch()); - - connect(normalLaunch, &QAction::triggered, [this]() { - APPLICATION->launch(m_selectedInstance, true, false); - }); - connect(normalLaunchOffline, &QAction::triggered, [this]() { - APPLICATION->launch(m_selectedInstance, false, false); - }); - connect(normalLaunchDemo, &QAction::triggered, [this]() { - APPLICATION->launch(m_selectedInstance, false, true); - }); - } - else - { - normalLaunch->setDisabled(true); - normalLaunchOffline->setDisabled(true); - normalLaunchDemo->setDisabled(true); - } - - // Disable demo-mode if not available. - auto instance = dynamic_cast(m_selectedInstance.get()); - if (instance) { - normalLaunchDemo->setEnabled(instance->supportsDemo()); - } - - QString profilersTitle = tr("Profilers"); - launchMenu->addSeparator()->setText(profilersTitle); - for (auto profiler : APPLICATION->profilers().values()) - { - QAction *profilerAction = launchMenu->addAction(profiler->name()); - QAction *profilerOfflineAction = launchMenu->addAction(tr("%1 Offline").arg(profiler->name())); - QString error; - if (!profiler->check(&error)) - { - profilerAction->setDisabled(true); - profilerOfflineAction->setDisabled(true); - QString profilerToolTip = tr("Profiler not setup correctly. Go into settings, \"External Tools\"."); - profilerAction->setToolTip(profilerToolTip); - profilerOfflineAction->setToolTip(profilerToolTip); - } - else if (m_selectedInstance) - { - profilerAction->setEnabled(m_selectedInstance->canLaunch()); - profilerOfflineAction->setEnabled(m_selectedInstance->canLaunch()); - - connect(profilerAction, &QAction::triggered, [this, profiler]() - { - APPLICATION->launch(m_selectedInstance, true, false, profiler.get()); - }); - connect(profilerOfflineAction, &QAction::triggered, [this, profiler]() - { - APPLICATION->launch(m_selectedInstance, false, false, profiler.get()); - }); - } - else - { - profilerAction->setDisabled(true); - profilerOfflineAction->setDisabled(true); - } - } + m_selectedInstance->populateLaunchMenu(launchMenu); ui->actionLaunchInstance->setMenu(launchMenu); } @@ -1268,7 +1189,7 @@ void MainWindow::globalSettingsClosed() proxymodel->invalidate(); proxymodel->sort(0); updateMainToolBar(); - updateToolsMenu(); + updateLaunchButton(); updateThemeMenu(); updateStatusCenter(); // This needs to be done to prevent UI elements disappearing in the event the config is changed @@ -1471,22 +1392,6 @@ void MainWindow::activateInstance(InstancePtr instance) APPLICATION->launch(instance); } -void MainWindow::on_actionLaunchInstanceOffline_triggered() -{ - if (m_selectedInstance) - { - APPLICATION->launch(m_selectedInstance, false); - } -} - -void MainWindow::on_actionLaunchInstanceDemo_triggered() -{ - if (m_selectedInstance) - { - APPLICATION->launch(m_selectedInstance, false, true); - } -} - void MainWindow::on_actionKillInstance_triggered() { if(m_selectedInstance && m_selectedInstance->isRunning()) @@ -1633,6 +1538,7 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & } if (m_selectedInstance) { disconnect(m_selectedInstance.get(), &BaseInstance::runningStatusChanged, this, &MainWindow::refreshCurrentInstance); + disconnect(m_selectedInstance.get(), &BaseInstance::profilerChanged, this, &MainWindow::refreshCurrentInstance); } QString id = current.data(InstanceList::InstanceIDRole).toString(); m_selectedInstance = APPLICATION->instances()->getInstanceById(id); @@ -1641,14 +1547,6 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & ui->instanceToolBar->setEnabled(true); setInstanceActionsEnabled(true); ui->actionLaunchInstance->setEnabled(m_selectedInstance->canLaunch()); - ui->actionLaunchInstanceOffline->setEnabled(m_selectedInstance->canLaunch()); - ui->actionLaunchInstanceDemo->setEnabled(m_selectedInstance->canLaunch()); - - // Disable demo-mode if not available. - auto instance = dynamic_cast(m_selectedInstance.get()); - if (instance) { - ui->actionLaunchInstanceDemo->setEnabled(instance->supportsDemo()); - } ui->actionKillInstance->setEnabled(m_selectedInstance->isRunning()); ui->actionExportInstance->setEnabled(m_selectedInstance->canExport()); @@ -1657,19 +1555,18 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & updateStatusCenter(); updateInstanceToolIcon(m_selectedInstance->iconKey()); - updateToolsMenu(); + updateLaunchButton(); APPLICATION->settings()->set("SelectedInstance", m_selectedInstance->id()); connect(m_selectedInstance.get(), &BaseInstance::runningStatusChanged, this, &MainWindow::refreshCurrentInstance); + connect(m_selectedInstance.get(), &BaseInstance::profilerChanged, this, &MainWindow::refreshCurrentInstance); } else { ui->instanceToolBar->setEnabled(false); setInstanceActionsEnabled(false); ui->actionLaunchInstance->setEnabled(false); - ui->actionLaunchInstanceOffline->setEnabled(false); - ui->actionLaunchInstanceDemo->setEnabled(false); ui->actionKillInstance->setEnabled(false); APPLICATION->settings()->set("SelectedInstance", QString()); selectionBad(); @@ -1700,7 +1597,7 @@ void MainWindow::selectionBad() statusBar()->clearMessage(); ui->instanceToolBar->setEnabled(false); setInstanceActionsEnabled(false); - updateToolsMenu(); + updateLaunchButton(); renameButton->setText(tr("Rename Instance")); updateInstanceToolIcon("grass"); @@ -1769,7 +1666,7 @@ void MainWindow::setInstanceActionsEnabled(bool enabled) ui->actionCreateInstanceShortcut->setEnabled(enabled); } -void MainWindow::refreshCurrentInstance(bool running) +void MainWindow::refreshCurrentInstance() { auto current = view->selectionModel()->currentIndex(); instanceChanged(current, current); diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 3bb20c4a..7814e5b1 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -143,10 +143,6 @@ private slots: void on_actionLaunchInstance_triggered(); - void on_actionLaunchInstanceOffline_triggered(); - - void on_actionLaunchInstanceDemo_triggered(); - void on_actionKillInstance_triggered(); void on_actionDeleteInstance_triggered(); @@ -175,7 +171,7 @@ private slots: void updateMainToolBar(); - void updateToolsMenu(); + void updateLaunchButton(); void updateThemeMenu(); @@ -210,7 +206,7 @@ private slots: void keyReleaseEvent(QKeyEvent *event) override; #endif - void refreshCurrentInstance(bool running); + void refreshCurrentInstance(); private: void retranslateUi(); diff --git a/launcher/ui/MainWindow.ui b/launcher/ui/MainWindow.ui index 113dfc1e..bc1edf39 100644 --- a/launcher/ui/MainWindow.ui +++ b/launcher/ui/MainWindow.ui @@ -435,22 +435,6 @@ Ctrl+D - - - Launch &Offline - - - Launch the selected instance in offline mode. - - - - - Launch &Demo - - - Launch the selected instance in demo mode. - - @@ -465,7 +449,8 @@ - + + .. Prism Launcher (zip) @@ -473,7 +458,8 @@ - + + .. Modrinth (mrpack) diff --git a/launcher/ui/pages/instance/ServersPage.cpp b/launcher/ui/pages/instance/ServersPage.cpp index 4b1fa08a..5e899a11 100644 --- a/launcher/ui/pages/instance/ServersPage.cpp +++ b/launcher/ui/pages/instance/ServersPage.cpp @@ -3,7 +3,7 @@ * Prism Launcher - Minecraft Launcher * Copyright (c) 2022 Jamie Mansfield * Copyright (C) 2022 Sefa Eyeoglu - * Copyright (C) 2022 TheKodeToad + * Copyright (C) 2023 TheKodeToad * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -835,7 +835,7 @@ void ServersPage::on_actionMove_Down_triggered() void ServersPage::on_actionJoin_triggered() { const auto &address = m_model->at(currentServer)->m_address; - APPLICATION->launch(m_inst, true, false, nullptr, std::make_shared(MinecraftServerTarget::parse(address))); + APPLICATION->launch(m_inst, true, false, std::make_shared(MinecraftServerTarget::parse(address))); } #include "ServersPage.moc" -- cgit From 440dcdf02206e582814f7fdcc58c9b4755d8d3cc Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 6 Jul 2023 18:31:59 +0100 Subject: Import QActionGroup properly :P Signed-off-by: TheKodeToad --- launcher/minecraft/MinecraftInstance.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index d511451e..30f41de3 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -90,6 +90,8 @@ #include "tools/BaseProfiler.h" +#include + #ifdef Q_OS_LINUX #include "MangoHud.h" #endif -- cgit From 4c25e3ce75158b6a17fafd60849621f5e0338fc9 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 6 Jul 2023 21:04:21 +0100 Subject: Add keyboard shortcut to Kill action Signed-off-by: TheKodeToad --- launcher/ui/InstanceWindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index 350b1907..78580bcb 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -98,6 +98,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) m_killButton = new QPushButton(this); m_killButton->setText(tr("&Kill")); m_killButton->setToolTip(tr("Kill the running instance")); + m_killButton->setShortcut(QKeySequence(tr("Ctrl+K"))); horizontalLayout->addWidget(m_killButton); connect(m_killButton, &QPushButton::clicked, this, [this] { APPLICATION->kill(m_instance); }); -- cgit From ec85266860b7503b24ff3840fb6bf74588acc7c8 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Fri, 7 Jul 2023 12:18:04 +0100 Subject: Memory leak fixes Signed-off-by: TheKodeToad --- launcher/ui/InstanceWindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index 78580bcb..ac8454c7 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -75,11 +75,11 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) // Add custom buttons to the page container layout. { - auto horizontalLayout = new QHBoxLayout(); + auto horizontalLayout = new QHBoxLayout(this); horizontalLayout->setObjectName(QStringLiteral("horizontalLayout")); horizontalLayout->setContentsMargins(6, -1, 6, -1); - auto btnHelp = new QPushButton(); + auto btnHelp = new QPushButton(this); btnHelp->setText(tr("Help")); horizontalLayout->addWidget(btnHelp); connect(btnHelp, &QPushButton::clicked, m_container, &PageContainer::help); @@ -104,7 +104,7 @@ InstanceWindow::InstanceWindow(InstancePtr instance, QWidget *parent) updateButtons(); - m_closeButton = new QPushButton(); + m_closeButton = new QPushButton(this); m_closeButton->setText(tr("Close")); horizontalLayout->addWidget(m_closeButton); connect(m_closeButton, &QPushButton::clicked, this, &QMainWindow::close); -- cgit From eeb5fdbc9f7848717a167b251ddae521f19a056e Mon Sep 17 00:00:00 2001 From: seth Date: Fri, 4 Aug 2023 11:55:31 -0400 Subject: feat(nix): add darwin support Signed-off-by: seth --- nix/default.nix | 5 ++- nix/distribution.nix | 1 + nix/package.nix | 87 ++++++++++++++++++++++++++++------------------------ 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/nix/default.nix b/nix/default.nix index 47172927..71c95c2c 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -25,8 +25,7 @@ systems = [ "x86_64-linux" "aarch64-linux" - # Disabled due to our packages not supporting darwin yet. - # "x86_64-darwin" - # "aarch64-darwin" + "x86_64-darwin" + "aarch64-darwin" ]; } diff --git a/nix/distribution.nix b/nix/distribution.nix index 0f2e26f3..d0904d41 100644 --- a/nix/distribution.nix +++ b/nix/distribution.nix @@ -17,6 +17,7 @@ mkPrism = qt: qt.callPackage ./package.nix { inherit (inputs) libnbtplusplus; + inherit (prev.darwin.apple_sdk.frameworks) Cocoa; inherit self version; }; in { diff --git a/nix/package.nix b/nix/package.nix index edc266dc..1dbadd40 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -2,6 +2,8 @@ lib, stdenv, cmake, + cmark, + Cocoa, ninja, jdk17, zlib, @@ -9,57 +11,62 @@ quazip, extra-cmake-modules, tomlplusplus, - cmark, ghc_filesystem, gamemode, msaClientID ? null, - gamemodeSupport ? true, + gamemodeSupport ? stdenv.isLinux, self, version, libnbtplusplus, }: -stdenv.mkDerivation rec { - pname = "prismlauncher-unwrapped"; - inherit version; +assert lib.assertMsg (stdenv.isLinux || !gamemodeSupport) "gamemodeSupport is only available on Linux"; + stdenv.mkDerivation rec { + pname = "prismlauncher-unwrapped"; + inherit version; - src = lib.cleanSource self; + src = lib.cleanSource self; - nativeBuildInputs = [extra-cmake-modules cmake jdk17 ninja]; - buildInputs = - [ - qtbase - zlib - quazip - ghc_filesystem - tomlplusplus - cmark - ] - ++ lib.optional gamemodeSupport gamemode; + nativeBuildInputs = [extra-cmake-modules cmake jdk17 ninja]; + buildInputs = + [ + qtbase + zlib + quazip + ghc_filesystem + tomlplusplus + cmark + ] + ++ lib.optional gamemodeSupport gamemode + ++ lib.optionals stdenv.isDarwin [Cocoa]; - hardeningEnable = ["pie"]; + hardeningEnable = lib.optionals stdenv.isLinux ["pie"]; - cmakeFlags = - lib.optionals (msaClientID != null) ["-DLauncher_MSA_CLIENT_ID=${msaClientID}"] - ++ lib.optionals (lib.versionOlder qtbase.version "6") ["-DLauncher_QT_VERSION_MAJOR=5"]; + cmakeFlags = + [ + "-DLauncher_BUILD_PLATFORM=nixpkgs" + ] + ++ lib.optionals (msaClientID != null) ["-DLauncher_MSA_CLIENT_ID=${msaClientID}"] + ++ lib.optionals (lib.versionOlder qtbase.version "6") ["-DLauncher_QT_VERSION_MAJOR=5"] + ++ lib.optionals stdenv.isDarwin ["-DINSTALL_BUNDLE=nodeps" "-DMACOSX_SPARKLE_UPDATE_FEED_URL=''"]; - postUnpack = '' - rm -rf source/libraries/libnbtplusplus - ln -s ${libnbtplusplus} source/libraries/libnbtplusplus - ''; + postUnpack = '' + rm -rf source/libraries/libnbtplusplus + ln -s ${libnbtplusplus} source/libraries/libnbtplusplus + ''; - dontWrapQtApps = true; + dontWrapQtApps = true; - meta = with lib; { - homepage = "https://prismlauncher.org/"; - description = "A free, open source launcher for Minecraft"; - longDescription = '' - Allows you to have multiple, separate instances of Minecraft (each with - their own mods, texture packs, saves, etc) and helps you manage them and - their associated options with a simple interface. - ''; - platforms = platforms.linux; - changelog = "https://github.com/PrismLauncher/PrismLauncher/releases/tag/${version}"; - license = licenses.gpl3Only; - maintainers = with maintainers; [minion3665 Scrumplex]; - }; -} + meta = with lib; { + homepage = "https://prismlauncher.org/"; + description = "A free, open source launcher for Minecraft"; + longDescription = '' + Allows you to have multiple, separate instances of Minecraft (each with + their own mods, texture packs, saves, etc) and helps you manage them and + their associated options with a simple interface. + ''; + platforms = with platforms; linux ++ darwin; + changelog = "https://github.com/PrismLauncher/PrismLauncher/releases/tag/${version}"; + license = licenses.gpl3Only; + maintainers = with maintainers; [minion3665 Scrumplex getchoo]; + }; + } -- cgit From f0da16a758e4d3c2d41813f723b21390281e4a4e Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 17 Aug 2023 00:13:12 +0300 Subject: removed line Signed-off-by: Trial97 --- launcher/ui/pages/modplatform/ImportPage.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index ee8757f8..3e3c36b7 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -114,7 +114,6 @@ void ImportPage::updateState() bool isMRPack = fi.suffix() == "mrpack"; if (fi.exists() && (isZip || isMRPack)) { - QFileInfo fi(url.fileName()); auto extra_info = QMap(m_extra_info); qDebug() << "Pack Extra Info" << extra_info << m_extra_info; dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this, std::move(extra_info))); -- cgit From bad44ea264eab5ce896f51a981cf1659f2755716 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 17 Aug 2023 00:14:49 +0300 Subject: feat:added flame install mod metadata Signed-off-by: Trial97 --- launcher/minecraft/mod/ModFolderModel.cpp | 49 +++++++++++++++++++++++++++++++ launcher/minecraft/mod/ModFolderModel.h | 2 ++ launcher/ui/MainWindow.cpp | 31 +++++++++---------- 3 files changed, 67 insertions(+), 15 deletions(-) diff --git a/launcher/minecraft/mod/ModFolderModel.cpp b/launcher/minecraft/mod/ModFolderModel.cpp index 280e70d7..eed35615 100644 --- a/launcher/minecraft/mod/ModFolderModel.cpp +++ b/launcher/minecraft/mod/ModFolderModel.cpp @@ -51,8 +51,13 @@ #include "Application.h" +#include "Json.h" #include "minecraft/mod/tasks/LocalModParseTask.h" +#include "minecraft/mod/tasks/LocalModUpdateTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h" +#include "modplatform/ModIndex.h" +#include "modplatform/flame/FlameAPI.h" +#include "modplatform/flame/FlameModIndex.h" ModFolderModel::ModFolderModel(const QString& dir, BaseInstance* instance, bool is_indexed, bool create_dir) : ResourceFolderModel(QDir(dir), instance, nullptr, create_dir), m_is_indexed(is_indexed) @@ -309,3 +314,47 @@ void ModFolderModel::onParseSucceeded(int ticket, QString mod_id) emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1)); } + +static const FlameAPI flameAPI; +bool ModFolderModel::installMod(QString file_path, ModPlatform::IndexedVersion& vers) +{ + if (vers.addonId.isValid()) { + ModPlatform::IndexedPack pack{ + vers.addonId, + ModPlatform::ResourceProvider::FLAME, + }; + + QEventLoop loop; + + auto response = std::make_shared(); + auto job = flameAPI.getProject(vers.addonId.toString(), response); + + QObject::connect(job.get(), &Task::failed, [&loop] { loop.quit(); }); + QObject::connect(job.get(), &Task::aborted, &loop, &QEventLoop::quit); + QObject::connect(job.get(), &Task::succeeded, [response, this, &vers, &loop, &pack] { + QJsonParseError parse_error{}; + QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); + if (parse_error.error != QJsonParseError::NoError) { + qWarning() << "Error while parsing JSON response for mod info at " << parse_error.offset + << " reason: " << parse_error.errorString(); + qDebug() << *response; + return; + } + try { + auto obj = Json::requireObject(Json::requireObject(doc), "data"); + FlameMod::loadIndexedPack(pack, obj); + } catch (const JSONValidationError& e) { + qDebug() << doc; + qWarning() << "Error while reading mod info: " << e.cause(); + } + LocalModUpdateTask update_metadata(indexDir(), pack, vers); + QObject::connect(&update_metadata, &Task::finished, &loop, &QEventLoop::quit); + update_metadata.start(); + }); + + job->start(); + + loop.exec(); + } + return ResourceFolderModel::installResource(file_path); +} diff --git a/launcher/minecraft/mod/ModFolderModel.h b/launcher/minecraft/mod/ModFolderModel.h index 06fd7814..f1890e87 100644 --- a/launcher/minecraft/mod/ModFolderModel.h +++ b/launcher/minecraft/mod/ModFolderModel.h @@ -48,6 +48,7 @@ #include "minecraft/mod/tasks/LocalModParseTask.h" #include "minecraft/mod/tasks/ModFolderLoadTask.h" +#include "modplatform/ModIndex.h" class LegacyInstance; class BaseInstance; @@ -75,6 +76,7 @@ class ModFolderModel : public ResourceFolderModel { [[nodiscard]] Task* createParseTask(Resource&) override; bool installMod(QString file_path) { return ResourceFolderModel::installResource(file_path); } + bool installMod(QString file_path, ModPlatform::IndexedVersion& vers); bool uninstallMod(const QString& filename, bool preserve_metadata = false); /// Deletes all the selected mods diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 7d414877..6736e912 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -43,6 +43,8 @@ #include "FileSystem.h" #include "MainWindow.h" +#include "modplatform/ModIndex.h" +#include "modplatform/flame/FlameModIndex.h" #include "ui/dialogs/ExportToModListDialog.h" #include "ui_MainWindow.h" @@ -980,11 +982,12 @@ void MainWindow::processURLs(QList urls) if (url.scheme().isEmpty()) url.setScheme("file"); + ModPlatform::IndexedVersion version; QMap extra_info; QUrl local_url; if (!url.isLocalFile()) { // download the remote resource and identify QUrl dl_url; - if(url.scheme() == "curseforge") { + if (url.scheme() == "curseforge") { // need to find the download link for the modpack / resource // format of url curseforge://install?addonId=IDHERE&fileId=IDHERE QUrlQuery query(url); @@ -1000,20 +1003,19 @@ void MainWindow::processURLs(QList urls) auto api = FlameAPI(); auto job = api.getFile(addonId, fileId, array); - QString resource_name; - connect(job.get(), &Task::failed, this, [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); - connect(job.get(), &Task::succeeded, this, [this, array, addonId, fileId, &dl_url, &resource_name] { + connect(job.get(), &Task::succeeded, this, [this, array, addonId, fileId, &dl_url, &version] { qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str(); auto doc = Json::requireDocument(*array); auto data = Json::ensureObject(Json::ensureObject(doc.object()), "data"); // No way to find out if it's a mod or a modpack before here // And also we need to check if it ends with .zip, instead of any better way - auto fileName = Json::ensureString(data, "fileName"); + version = FlameMod::loadIndexedPackVersion(data); + auto fileName = version.fileName; // Have to use ensureString then use QUrl to get proper url encoding - dl_url = QUrl(Json::ensureString(data, "downloadUrl", "", "downloadUrl")); + dl_url = QUrl(version.downloadUrl); if (!dl_url.isValid()) { CustomMessageBox::selectable( this, tr("Error"), @@ -1024,22 +1026,20 @@ void MainWindow::processURLs(QList urls) } QFileInfo dl_file(dl_url.fileName()); - resource_name = Json::ensureString(data, "displayName", dl_file.completeBaseName(), "displayName"); }); - { // drop stack + { // drop stack ProgressDialog dlUrlDialod(this); dlUrlDialod.setSkipButton(true, tr("Abort")); dlUrlDialod.execWithTask(job.get()); } - } else { dl_url = url; } if (!dl_url.isValid()) { - continue; // no valid url to download this resource + continue; // no valid url to download this resource } const QString path = dl_url.host() + '/' + dl_url.path(); @@ -1050,17 +1050,18 @@ void MainWindow::processURLs(QList urls) auto archivePath = entry->getFullPath(); bool dl_success = false; - connect(dl_job.get(), &Task::failed, this, [this](QString reason){CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); - connect(dl_job.get(), &Task::succeeded, this, [&dl_success]{dl_success = true;}); + connect(dl_job.get(), &Task::failed, this, + [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); + connect(dl_job.get(), &Task::succeeded, this, [&dl_success] { dl_success = true; }); - { // drop stack + { // drop stack ProgressDialog dlUrlDialod(this); dlUrlDialod.setSkipButton(true, tr("Abort")); dlUrlDialod.execWithTask(dl_job.get()); } if (!dl_success) { - continue; // no local file to identify + continue; // no local file to identify } local_url = QUrl::fromLocalFile(archivePath); @@ -1099,7 +1100,7 @@ void MainWindow::processURLs(QList urls) qWarning() << "Importing of Data Packs not supported at this time. Ignoring" << localFileName; break; case PackedResourceType::Mod: - minecraftInst->loaderModList()->installMod(localFileName); + minecraftInst->loaderModList()->installMod(localFileName, version); break; case PackedResourceType::ShaderPack: minecraftInst->shaderPackList()->installResource(localFileName); -- cgit From 6da2e7d3f6f06916e9d92578546b5d80474aaa5f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 17 Aug 2023 10:12:38 +0100 Subject: I was forced /j Co-authored-by: Sefa Eyeoglu Signed-off-by: TheKodeToad --- launcher/minecraft/MinecraftInstance.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index babf9298..d930d681 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -272,10 +272,7 @@ void MinecraftInstance::populateLaunchMenu(QMenu* menu) profilerAction->setChecked(settings()->get("Profiler").toString() == profiler.key()); QString error; - if (profiler.value()->check(&error)) - profilerAction->setIcon(APPLICATION->getThemedIcon("status-good")); - else - profilerAction->setIcon(APPLICATION->getThemedIcon("status-bad")); + profilerAction->setEnabled(profiler.value()->check(&error)); } } -- cgit From ffd8ed550f05e1336afc6ddc424b6733256ecf02 Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Thu, 17 Aug 2023 10:16:52 +0100 Subject: Reformat Signed-off-by: TheKodeToad --- launcher/Application.cpp | 15 +++++---------- launcher/Application.h | 2 +- launcher/ui/InstanceWindow.h | 2 +- launcher/ui/MainWindow.cpp | 2 +- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index c1bf7e5e..4da7629c 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -1104,18 +1104,13 @@ bool Application::launch(InstancePtr instance, MinecraftServerTargetPtr serverToJoin, MinecraftAccountPtr accountToUse) { - if(m_updateRunning) - { + if (m_updateRunning) { qDebug() << "Cannot launch instances while an update is running. Please try again when updates are completed."; - } - else if(instance->canLaunch()) - { - auto & extras = m_instanceExtras[instance->id()]; + } else if (instance->canLaunch()) { + auto& extras = m_instanceExtras[instance->id()]; auto window = extras.window; - if(window) - { - if(!window->saveAll()) - { + if (window) { + if (!window->saveAll()) { return false; } } diff --git a/launcher/Application.h b/launcher/Application.h index a09f46b5..8a85fd95 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -187,7 +187,7 @@ class Application : public QApplication { void clickedOnDock(); #endif -public slots: + public slots: bool launch(InstancePtr instance, bool online = true, bool demo = false, diff --git a/launcher/ui/InstanceWindow.h b/launcher/ui/InstanceWindow.h index a8a7559f..e5bc24d4 100644 --- a/launcher/ui/InstanceWindow.h +++ b/launcher/ui/InstanceWindow.h @@ -52,7 +52,7 @@ class PageContainer; class InstanceWindow : public QMainWindow, public BasePageContainer { Q_OBJECT -public: + public: explicit InstanceWindow(InstancePtr proc, QWidget* parent = 0); virtual ~InstanceWindow() = default; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 48feea09..36a6e379 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -551,7 +551,7 @@ void MainWindow::updateMainToolBar() void MainWindow::updateLaunchButton() { - QMenu *launchMenu = ui->actionLaunchInstance->menu(); + QMenu* launchMenu = ui->actionLaunchInstance->menu(); if (launchMenu) launchMenu->clear(); else -- cgit From 6d1c67663dd5388b2209d162d517d6d9baa37d83 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Fri, 18 Aug 2023 12:24:28 +0300 Subject: feat:added option to show playtime in hours Signed-off-by: Trial97 --- launcher/Application.cpp | 1 + launcher/MMCTime.cpp | 7 ++++--- launcher/MMCTime.h | 2 +- launcher/minecraft/MinecraftInstance.cpp | 11 +++++++---- launcher/ui/MainWindow.cpp | 4 +++- launcher/ui/pages/global/MinecraftPage.cpp | 2 ++ launcher/ui/pages/global/MinecraftPage.ui | 7 +++++++ 7 files changed, 25 insertions(+), 9 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 78de8747..44297015 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -598,6 +598,7 @@ Application::Application(int& argc, char** argv) : QApplication(argc, argv) m_settings->registerSetting("ShowGameTime", true); m_settings->registerSetting("ShowGlobalGameTime", true); m_settings->registerSetting("RecordGameTime", true); + m_settings->registerSetting("ShowGameTimeWithoutDays", false); // Minecraft mods m_settings->registerSetting("ModMetadataDisabled", false); diff --git a/launcher/MMCTime.cpp b/launcher/MMCTime.cpp index 3972dbd5..1765fd84 100644 --- a/launcher/MMCTime.cpp +++ b/launcher/MMCTime.cpp @@ -16,19 +16,20 @@ */ #include +#include #include #include #include -QString Time::prettifyDuration(int64_t duration) +QString Time::prettifyDuration(int64_t duration, bool noDays) { int seconds = (int)(duration % 60); duration /= 60; int minutes = (int)(duration % 60); duration /= 60; - int hours = (int)(duration % 24); - int days = (int)(duration / 24); + int hours = (int)(noDays ? duration : (duration % 24)); + int days = (int)(noDays ? 0 : (duration / 24)); if ((hours == 0) && (days == 0)) { return QObject::tr("%1min %2s").arg(minutes).arg(seconds); } diff --git a/launcher/MMCTime.h b/launcher/MMCTime.h index b7d34b5d..ea6d37e7 100644 --- a/launcher/MMCTime.h +++ b/launcher/MMCTime.h @@ -20,7 +20,7 @@ namespace Time { -QString prettifyDuration(int64_t duration); +QString prettifyDuration(int64_t duration, bool noDays = false); /** * @brief Returns a string with short form time duration ie. `2days 1h3m4s56.0ms`. diff --git a/launcher/minecraft/MinecraftInstance.cpp b/launcher/minecraft/MinecraftInstance.cpp index 62d22019..c90d4362 100644 --- a/launcher/minecraft/MinecraftInstance.cpp +++ b/launcher/minecraft/MinecraftInstance.cpp @@ -897,13 +897,16 @@ QString MinecraftInstance::getStatusbarDescription() if (m_settings->get("ShowGameTime").toBool()) { if (lastTimePlayed() > 0) { QDateTime lastLaunchTime = QDateTime::fromMSecsSinceEpoch(lastLaunch()); - description.append(tr(", last played on %1 for %2") - .arg(QLocale().toString(lastLaunchTime, QLocale::ShortFormat)) - .arg(Time::prettifyDuration(lastTimePlayed()))); + description.append( + tr(", last played on %1 for %2") + .arg(QLocale().toString(lastLaunchTime, QLocale::ShortFormat)) + .arg(Time::prettifyDuration(lastTimePlayed(), APPLICATION->settings()->get("ShowGameTimeWithoutDays").toBool()))); } if (totalTimePlayed() > 0) { - description.append(tr(", total played for %1").arg(Time::prettifyDuration(totalTimePlayed()))); + description.append( + tr(", total played for %1") + .arg(Time::prettifyDuration(totalTimePlayed(), APPLICATION->settings()->get("ShowGameTimeWithoutDays").toBool()))); } } if (hasCrashed()) { diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 067108f2..de2b9634 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1810,7 +1810,9 @@ void MainWindow::updateStatusCenter() int timePlayed = APPLICATION->instances()->getTotalPlayTime(); if (timePlayed > 0) { - m_statusCenter->setText(tr("Total playtime: %1").arg(Time::prettifyDuration(timePlayed))); + m_statusCenter->setText( + tr("Total playtime: %1") + .arg(Time::prettifyDuration(timePlayed, APPLICATION->settings()->get("ShowGameTimeWithoutDays").toBool()))); } } // "Instance actions" are actions that require an instance to be selected (i.e. "new instance" is not here) diff --git a/launcher/ui/pages/global/MinecraftPage.cpp b/launcher/ui/pages/global/MinecraftPage.cpp index 1c774721..9beaa433 100644 --- a/launcher/ui/pages/global/MinecraftPage.cpp +++ b/launcher/ui/pages/global/MinecraftPage.cpp @@ -115,6 +115,7 @@ void MinecraftPage::applySettings() s->set("ShowGameTime", ui->showGameTime->isChecked()); s->set("ShowGlobalGameTime", ui->showGlobalGameTime->isChecked()); s->set("RecordGameTime", ui->recordGameTime->isChecked()); + s->set("ShowGameTimeWithoutDays", ui->showGameTimeWithoutDays->isChecked()); // Miscellaneous s->set("CloseAfterLaunch", ui->closeAfterLaunchCheck->isChecked()); @@ -169,6 +170,7 @@ void MinecraftPage::loadSettings() ui->showGameTime->setChecked(s->get("ShowGameTime").toBool()); ui->showGlobalGameTime->setChecked(s->get("ShowGlobalGameTime").toBool()); ui->recordGameTime->setChecked(s->get("RecordGameTime").toBool()); + ui->showGameTimeWithoutDays->setChecked(s->get("ShowGameTimeWithoutDays").toBool()); ui->closeAfterLaunchCheck->setChecked(s->get("CloseAfterLaunch").toBool()); ui->quitAfterGameStopCheck->setChecked(s->get("QuitAfterGameStop").toBool()); diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 98e90e4e..89bef949 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -138,6 +138,13 @@ + + + + Show time spent playing without days + + + -- cgit From 28ffa8bf44f220e541d00204b52a45573fba645a Mon Sep 17 00:00:00 2001 From: Alexandru Ionut Tripon Date: Fri, 18 Aug 2023 12:57:08 +0300 Subject: Update launcher/ui/pages/global/MinecraftPage.ui Co-authored-by: Sefa Eyeoglu Signed-off-by: Alexandru Ionut Tripon --- launcher/ui/pages/global/MinecraftPage.ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/pages/global/MinecraftPage.ui b/launcher/ui/pages/global/MinecraftPage.ui index 89bef949..6fb21da4 100644 --- a/launcher/ui/pages/global/MinecraftPage.ui +++ b/launcher/ui/pages/global/MinecraftPage.ui @@ -141,7 +141,7 @@ - Show time spent playing without days + Show time spent playing in hours -- cgit From 0138cd65cb259966fa9902732bb03e3e7888cc64 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Sat, 19 Aug 2023 09:00:59 +0300 Subject: feat:neoforge can download forge mods Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameAPI.h | 7 ++++--- launcher/modplatform/modrinth/ModrinthAPI.h | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index a1256e17..e423189a 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -47,9 +47,10 @@ class FlameAPI : public NetworkResourceAPI { return 4; // TODO: remove this once Quilt drops official Fabric support if (loaders & Quilt) // NOTE: Most if not all Fabric mods should work *currently* - return 4; // FIXME: implement multiple loaders filter - if (loaders & NeoForge) - return 6; + return 4; // FIXME: implement multiple loaders filter (this should be 5) + // TODO: remove this once NeoForge drops official Forge support + if (loaders & NeoForge) // NOTE: Most if not all Forge mods should work *currently* + return 1; // FIXME: implement multi