diff options
| author | Trial97 <alexandru.tripon97@gmail.com> | 2023-08-17 14:23:37 +0300 |
|---|---|---|
| committer | Trial97 <alexandru.tripon97@gmail.com> | 2023-08-17 14:23:37 +0300 |
| commit | 4a1d85f99913d0bacf8cdd118c81401378c758b6 (patch) | |
| tree | e8389ba64e1b1a303545f1dad242c9a9124ddca9 /launcher/ui | |
| parent | 939a2d67ed75be714e9f3b1b918250d006b3860a (diff) | |
| parent | 85f36ebed7e1295547cd2324d1baf7834be89c31 (diff) | |
| download | PrismLauncher-4a1d85f99913d0bacf8cdd118c81401378c758b6.tar.gz PrismLauncher-4a1d85f99913d0bacf8cdd118c81401378c758b6.tar.bz2 PrismLauncher-4a1d85f99913d0bacf8cdd118c81401378c758b6.zip | |
Merge branch 'develop' of https://github.com/PrismLauncher/PrismLauncher into develop
Diffstat (limited to 'launcher/ui')
87 files changed, 1300 insertions, 696 deletions
diff --git a/launcher/ui/InstanceWindow.cpp b/launcher/ui/InstanceWindow.cpp index 9c7886fa..7025cb79 100644 --- a/launcher/ui/InstanceWindow.cpp +++ b/launcher/ui/InstanceWindow.cpp @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me> * * 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 @@ -251,6 +252,11 @@ bool InstanceWindow::selectPage(QString pageId) return m_container->selectPage(pageId); } +BasePage* InstanceWindow::selectedPage() const +{ + return m_container->selectedPage(); +} + void InstanceWindow::refreshContainer() { m_container->refreshContainer(); diff --git a/launcher/ui/InstanceWindow.h b/launcher/ui/InstanceWindow.h index 508bcaa1..70f206f2 100644 --- a/launcher/ui/InstanceWindow.h +++ b/launcher/ui/InstanceWindow.h @@ -2,6 +2,7 @@ /* * Prism Launcher - Minecraft Launcher * Copyright (C) 2022 Sefa Eyeoglu <contact@scrumplex.net> + * Copyright (C) 2023 TheKodeToad <TheKodeToad@proton.me> * * 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 @@ -55,6 +56,7 @@ class InstanceWindow : public QMainWindow, public BasePageContainer { virtual ~InstanceWindow(); bool selectPage(QString pageId) override; + BasePage* selectedPage() const override; void refreshContainer() override; QString instanceId(); diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index e342e833..067108f2 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -85,7 +85,7 @@ #include <launch/LaunchTask.h> #include <minecraft/MinecraftInstance.h> #include <minecraft/auth/AccountList.h> -#include <net/Download.h> +#include <net/ApiDownload.h> #include <net/NetJob.h> #include <news/NewsChecker.h> #include <tools/BaseProfiler.h> @@ -118,11 +118,15 @@ #include "minecraft/mod/ShaderPackFolderModel.h" #include "minecraft/mod/tasks/LocalResourceParse.h" +#include "modplatform/flame/FlameAPI.h" + #include "KonamiCode.h" #include "InstanceCopyTask.h" #include "InstanceImportTask.h" +#include "Json.h" + #include "MMCTime.h" namespace { @@ -515,9 +519,9 @@ void MainWindow::showInstanceContextMenu(const QPoint& pos) QAction* actionCreateInstance = new QAction(tr("Create instance"), this); actionCreateInstance->setToolTip(ui->actionAddInstance->toolTip()); if (!group.isNull()) { - QVariantMap data; - data["group"] = group; - actionCreateInstance->setData(data); + QVariantMap instance_action_data; + instance_action_data["group"] = group; + actionCreateInstance->setData(instance_action_data); } connect(actionCreateInstance, SIGNAL(triggered(bool)), SLOT(on_actionAddInstance_triggered())); @@ -527,9 +531,9 @@ void MainWindow::showInstanceContextMenu(const QPoint& pos) actions.append(actionCreateInstance); if (!group.isNull()) { QAction* actionDeleteGroup = new QAction(tr("Delete group '%1'").arg(group), this); - QVariantMap data; - data["group"] = group; - actionDeleteGroup->setData(data); + QVariantMap delete_group_action_data; + delete_group_action_data["group"] = group; + actionDeleteGroup->setData(delete_group_action_data); connect(actionDeleteGroup, SIGNAL(triggered(bool)), SLOT(deleteGroup())); actions.append(actionDeleteGroup); } @@ -627,7 +631,7 @@ void MainWindow::updateThemeMenu() themeMenu = new QMenu(this); } - auto themes = APPLICATION->getValidApplicationThemes(); + auto themes = APPLICATION->themeManager()->getValidApplicationThemes(); QActionGroup* themesGroup = new QActionGroup(this); @@ -641,7 +645,7 @@ void MainWindow::updateThemeMenu() themeAction->setActionGroup(themesGroup); connect(themeAction, &QAction::triggered, [theme]() { - APPLICATION->setApplicationTheme(theme->id()); + APPLICATION->themeManager()->setApplicationTheme(theme->id()); APPLICATION->settings()->set("ApplicationTheme", theme->id()); }); } @@ -744,9 +748,9 @@ void MainWindow::changeActiveAccount() if (sAction->data().type() != QVariant::Type::Int) return; - QVariant data = sAction->data(); + QVariant action_data = sAction->data(); bool valid = false; - int index = data.toInt(&valid); + int index = action_data.toInt(&valid); if (!valid) { index = -1; } @@ -929,7 +933,7 @@ void MainWindow::finalizeInstance(InstancePtr inst) } } -void MainWindow::addInstance(QString url) +void MainWindow::addInstance(const QString& url, const QMap<QString, QString>& extra_info) { QString groupName; do { @@ -949,7 +953,7 @@ void MainWindow::addInstance(QString url) groupName = APPLICATION->settings()->get("LastUsedGroupForNewInstance").toString(); } - NewInstanceDialog newInstDlg(groupName, url, this); + NewInstanceDialog newInstDlg(groupName, url, extra_info, this); if (!newInstDlg.exec()) return; @@ -976,18 +980,101 @@ void MainWindow::processURLs(QList<QUrl> urls) if (url.scheme().isEmpty()) url.setScheme("file"); - if (!url.isLocalFile()) { // probably instance/modpack - addInstance(url.toString()); - break; + QMap<QString, QString> extra_info; + QUrl local_url; + if (!url.isLocalFile()) { // download the remote resource and identify + QUrl dl_url; + 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); + + auto addonId = query.allQueryItemValues("addonId")[0]; + auto fileId = query.allQueryItemValues("fileId")[0]; + + extra_info.insert("pack_id", addonId); + extra_info.insert("pack_version_id", fileId); + + auto array = std::make_shared<QByteArray>(); + + 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] { + 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"); + + // Have to use ensureString then use QUrl to get proper url encoding + dl_url = QUrl(Json::ensureString(data, "downloadUrl", "", "downloadUrl")); + if (!dl_url.isValid()) { + CustomMessageBox::selectable( + this, tr("Error"), + tr("The modpack, mod, or resource %1 is blocked for third-parties! Please download it manually.").arg(fileName), + QMessageBox::Critical) + ->show(); + return; + } + + QFileInfo dl_file(dl_url.fileName()); + resource_name = Json::ensureString(data, "displayName", dl_file.completeBaseName(), "displayName"); + }); + + { // 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 + } + + const QString path = dl_url.host() + '/' + dl_url.path(); + auto entry = APPLICATION->metacache()->resolveEntry("general", path); + entry->setStale(true); + auto dl_job = unique_qobject_ptr<NetJob>(new NetJob(tr("Modpack download"), APPLICATION->network())); + dl_job->addNetAction(Net::ApiDownload::makeCached(dl_url, entry)); + 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; }); + + { // drop stack + ProgressDialog dlUrlDialod(this); + dlUrlDialod.setSkipButton(true, tr("Abort")); + dlUrlDialod.execWithTask(dl_job.get()); + } + + if (!dl_success) { + continue; // no local file to identify + } + local_url = QUrl::fromLocalFile(archivePath); + + } else { + local_url = url; } - auto localFileName = QDir::toNativeSeparators(url.toLocalFile()); + auto localFileName = QDir::toNativeSeparators(local_url.toLocalFile()); QFileInfo localFileInfo(localFileName); auto type = ResourceUtils::identify(localFileInfo); if (ResourceUtils::ValidResourceTypes.count(type) == 0) { // probably instance/modpack - addInstance(localFileName); + addInstance(localFileName, extra_info); continue; } @@ -1061,9 +1148,9 @@ void MainWindow::on_actionChangeInstIcon_triggered() void MainWindow::iconUpdated(QString icon) { if (icon == m_currentInstIcon) { - auto icon = APPLICATION->icons()->getIcon(m_currentInstIcon); - ui->actionChangeInstIcon->setIcon(icon); - changeIconButton->setIcon(icon); + auto new_icon = APPLICATION->icons()->getIcon(m_currentInstIcon); + ui->actionChangeInstIcon->setIcon(new_icon); + changeIconButton->setIcon(new_icon); } } @@ -1134,26 +1221,40 @@ void MainWindow::undoTrashInstance() ui->actionUndoTrashInstance->setEnabled(APPLICATION->instances()->trashedSomething()); } +void MainWindow::on_actionViewLauncherRootFolder_triggered() +{ + DesktopServices::openDirectory("."); +} + void MainWindow::on_actionViewInstanc |
