From 63c21c53af457673a836915ae7351111c980a4bf Mon Sep 17 00:00:00 2001 From: timoreo Date: Tue, 13 Sep 2022 12:00:22 +0200 Subject: [PATCH 01/17] Added url handler for curseforge Signed-off-by: timoreo --- cmake/MacOSXBundleInfo.plist.in | 11 ++++++ launcher/Application.cpp | 1 - launcher/InstanceImportTask.cpp | 69 +++++++++++++++++++++++++-------- launcher/InstanceImportTask.h | 1 + program_info/win_install.nsi.in | 4 ++ 5 files changed, 69 insertions(+), 17 deletions(-) diff --git a/cmake/MacOSXBundleInfo.plist.in b/cmake/MacOSXBundleInfo.plist.in index 400e482fe..d36ac3e8f 100644 --- a/cmake/MacOSXBundleInfo.plist.in +++ b/cmake/MacOSXBundleInfo.plist.in @@ -67,5 +67,16 @@ Alternate + CFBundleURLTypes + + + CFBundleURLName + Curseforge + CFBundleURLSchemes + + curseforge + + + diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 28c2a9ced..0b1ab16cb 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -240,7 +240,6 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_zipsToImport.append(QUrl::fromLocalFile(QFileInfo(zip_path).absoluteFilePath())); } - // error if --launch is missing with --server or --profile if((!m_serverToJoin.isEmpty() || !m_profileToUse.isEmpty()) && m_instanceIdToLaunch.isEmpty()) { diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 8a48873ef..ef221bf97 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -47,6 +47,8 @@ #include "modplatform/technic/TechnicPackProcessor.h" #include "modplatform/modrinth/ModrinthInstanceCreationTask.h" #include "modplatform/flame/FlameInstanceCreationTask.h" +// FIXME : move this over to FlameInstanceCreationTask +#include "Json.h" #include "settings/INISettingsObject.h" @@ -87,25 +89,59 @@ void InstanceImportTask::executeTask() setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString())); m_downloadRequired = true; - const QString path(m_sourceUrl.host() + '/' + m_sourceUrl.path()); - - auto entry = APPLICATION->metacache()->resolveEntry("general", path); - entry->setStale(true); - m_archivePath = entry->getFullPath(); - - m_filesNetJob.reset(new NetJob(tr("Modpack download"), APPLICATION->network())); - m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry)); - - connect(m_filesNetJob.get(), &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded); - connect(m_filesNetJob.get(), &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged); - connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propogateStepProgress); - connect(m_filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::downloadFailed); - connect(m_filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::downloadAborted); - - m_filesNetJob->start(); + if (m_sourceUrl.scheme() == "curseforge") { + // need to find the download link for the modpack + // format of url curseforge://install?addonId=IDHERE&fileId=IDHERE + QUrlQuery query(m_sourceUrl); + auto addonId = query.allQueryItemValues("addonId")[0]; + auto fileId = query.allQueryItemValues("fileId")[0]; + auto array = new QByteArray(); + auto req = new NetJob("Curseforge Meta", APPLICATION->network()); + req->addNetAction( + Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), array)); + connect(req, &NetJob::finished, [array, req] { + req->deleteLater(); + delete array; + }); + connect(req, &NetJob::failed, this, &InstanceImportTask::downloadFailed); + connect(req, &NetJob::succeeded, [array, this] { + auto doc = Json::requireDocument(*array); + // Have to use ensureString then use QUrl to get proper url encoding + m_sourceUrl = QUrl( + Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); + if (!m_sourceUrl.isValid()) { + emitFailed(tr("The modpack is blocked ! Please download it manually")); + return; + } + downloadFromUrl(); + }); + connect(req, &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged); + connect(req, &NetJob::stepProgress, this, &InstanceImportTask::propogateStepProgress); + connect(req, &NetJob::aborted, this, &InstanceImportTask::downloadAborted); + req->start(); + } else { + downloadFromUrl(); + } } } +void InstanceImportTask::downloadFromUrl() +{ + const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path(); + auto entry = APPLICATION->metacache()->resolveEntry("general", path); + entry->setStale(true); + m_filesNetJob.reset(new NetJob(tr("Modpack download"), APPLICATION->network())); + m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry)); + m_archivePath = entry->getFullPath(); + + connect(m_filesNetJob.get(), &NetJob::succeeded, this, &InstanceImportTask::downloadSucceeded); + connect(m_filesNetJob.get(), &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged); + connect(m_filesNetJob.get(), &NetJob::stepProgress, this, &InstanceImportTask::propogateStepProgress); + connect(m_filesNetJob.get(), &NetJob::failed, this, &InstanceImportTask::downloadFailed); + connect(m_filesNetJob.get(), &NetJob::aborted, this, &InstanceImportTask::downloadAborted); + m_filesNetJob->start(); +} + void InstanceImportTask::downloadSucceeded() { processZipPack(); @@ -396,3 +432,4 @@ void InstanceImportTask::processModrinth() inst_creation_task->start(); } + diff --git a/launcher/InstanceImportTask.h b/launcher/InstanceImportTask.h index 7fda439fc..9c1edc6d1 100644 --- a/launcher/InstanceImportTask.h +++ b/launcher/InstanceImportTask.h @@ -106,4 +106,5 @@ private: /* data */ //FIXME: nuke QWidget* m_parent; + void downloadFromUrl(); }; diff --git a/program_info/win_install.nsi.in b/program_info/win_install.nsi.in index a809c55dd..72ff4709a 100644 --- a/program_info/win_install.nsi.in +++ b/program_info/win_install.nsi.in @@ -294,6 +294,10 @@ Section "@Launcher_DisplayName@" ; Write the installation path into the registry WriteRegStr HKCU Software\@Launcher_CommonName@ "InstallDir" "$INSTDIR" + ; Write the URL Handler into registry for curseforge + WriteRegStr HKCU Software\Classes\curseforge "URL Protocol" "" + WriteRegStr HKCU Software\Classes\curseforge\shell\open\command "" '"$INSTDIR\@Launcher_APP_BINARY_NAME@.exe" "%1"' + ; Write the uninstall keys for Windows ${GetParameters} $R0 ${GetOptions} $R0 "/NoUninstaller" $R1 From 565202c99004a13f4d6b9bad6ec1e0634fb280fb Mon Sep 17 00:00:00 2001 From: timoreo Date: Tue, 13 Sep 2022 14:00:10 +0200 Subject: [PATCH 02/17] Added a protection against giving a mod url Signed-off-by: timoreo --- launcher/InstanceImportTask.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index ef221bf97..4d5193baa 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -106,14 +106,21 @@ void InstanceImportTask::executeTask() connect(req, &NetJob::failed, this, &InstanceImportTask::downloadFailed); connect(req, &NetJob::succeeded, [array, this] { auto doc = Json::requireDocument(*array); - // Have to use ensureString then use QUrl to get proper url encoding - m_sourceUrl = QUrl( - Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); - if (!m_sourceUrl.isValid()) { - emitFailed(tr("The modpack is blocked ! Please download it manually")); - return; + // 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(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "fileName"); + if (fileName.endsWith(".zip")) { + // Have to use ensureString then use QUrl to get proper url encoding + m_sourceUrl = QUrl( + Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); + if (!m_sourceUrl.isValid()) { + emitFailed(tr("The modpack is blocked ! Please download it manually")); + return; + } + downloadFromUrl(); + } else { + emitFailed(tr("This url isn't a valid modpack !")); } - downloadFromUrl(); }); connect(req, &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged); connect(req, &NetJob::stepProgress, this, &InstanceImportTask::propogateStepProgress); From 54fb799d95faa3d646cfc835937e5fbdb10afa4d Mon Sep 17 00:00:00 2001 From: timoreo Date: Wed, 16 Nov 2022 14:26:52 +0100 Subject: [PATCH 03/17] Fix command line args Signed-off-by: timoreo --- launcher/Application.cpp | 3 +++ program_info/org.prismlauncher.PrismLauncher.desktop.in | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 0b1ab16cb..6994d1ba6 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -219,6 +219,9 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"}, {"show", "Opens the window for the specified instance (by instance ID)", "show"} }); + // Has to be positional for some OS to handle that properly + parser.addPositionalArgument("urls","import the resource at the given url(s) (URL to modpack Zip / local Zip / curseforge:// modpack link)","[urls...]"); + parser.addHelpOption(); parser.addVersionOption(); diff --git a/program_info/org.prismlauncher.PrismLauncher.desktop.in b/program_info/org.prismlauncher.PrismLauncher.desktop.in index f08f2ba43..675e1f1f1 100644 --- a/program_info/org.prismlauncher.PrismLauncher.desktop.in +++ b/program_info/org.prismlauncher.PrismLauncher.desktop.in @@ -10,4 +10,4 @@ Icon=org.prismlauncher.PrismLauncher Categories=Game;ActionGame;AdventureGame;Simulation; Keywords=game;minecraft;launcher;mc;multimc;polymc; StartupWMClass=PrismLauncher -MimeType=application/zip;application/x-modrinth-modpack+zip +MimeType=application/zip;application/x-modrinth-modpack+zip;x-scheme-handler/curseforge; From a3173b53717fcea686f267f4eb8fd9788e6677db Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 7 Apr 2023 16:54:25 -0700 Subject: [PATCH 04/17] fix: ensure Application accepts URLs and local files form cmd args refactor: Move curseforge:// url scheme detection to Import Page feat: pass along extra CF pack info so pack metadata is established. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/Application.cpp | 42 +++++++++----- launcher/Application.h | 4 +- launcher/InstanceImportTask.cpp | 40 +------------- launcher/ui/pages/modplatform/ImportPage.cpp | 58 ++++++++++++++++++++ launcher/ui/pages/modplatform/ImportPage.ui | 2 +- 5 files changed, 92 insertions(+), 54 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 6994d1ba6..c97fdb0a6 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -216,11 +216,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) {{"s", "server"}, "Join the specified server on launch (only valid in combination with --launch)", "address"}, {{"a", "profile"}, "Use the account specified by its profile name (only valid in combination with --launch)", "profile"}, {"alive", "Write a small '" + liveCheckFile + "' file after the launcher starts"}, - {{"I", "import"}, "Import instance from specified zip (local path or URL)", "file"}, + {{"I", "import"}, "Import instance or resource from specified local path or URL", "url"}, {"show", "Opens the window for the specified instance (by instance ID)", "show"} }); // Has to be positional for some OS to handle that properly - parser.addPositionalArgument("urls","import the resource at the given url(s) (URL to modpack Zip / local Zip / curseforge:// modpack link)","[urls...]"); + parser.addPositionalArgument("urls","import the resource at the given url(s) (same as -I / --import)","[urls...]"); parser.addHelpOption(); parser.addVersionOption(); @@ -234,13 +234,13 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_instanceIdToShowWindowOf = parser.value("show"); - for (auto zip_path : parser.values("import")){ - m_zipsToImport.append(QUrl::fromLocalFile(QFileInfo(zip_path).absoluteFilePath())); + for (auto url : parser.values("import")){ + addImportUrl(url); } // treat unspecified positional arguments as import urls - for (auto zip_path : parser.positionalArguments()) { - m_zipsToImport.append(QUrl::fromLocalFile(QFileInfo(zip_path).absoluteFilePath())); + for (auto url : parser.positionalArguments()) { + addImportUrl(url); } // error if --launch is missing with --server or --profile @@ -345,12 +345,12 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) activate.command = "activate"; m_peerInstance->sendMessage(activate.serialize(), timeout); - if(!m_zipsToImport.isEmpty()) + if(!m_urlsToImport.isEmpty()) { - for (auto zip_url : m_zipsToImport) { + for (auto url : m_urlsToImport) { ApplicationMessage import; import.command = "import"; - import.args.insert("path", zip_url.toString()); + import.args.insert("path", url.toString()); m_peerInstance->sendMessage(import.serialize(), timeout); } } @@ -1027,10 +1027,10 @@ void Application::performMainStartupAction() showMainWindow(false); qDebug() << "<> Main window shown."; } - if(!m_zipsToImport.isEmpty()) + if(!m_urlsToImport.isEmpty()) { - qDebug() << "<> Importing from zip:" << m_zipsToImport; - m_mainWindow->processURLs( m_zipsToImport ); + qDebug() << "<> Importing from url:" << m_urlsToImport; + m_mainWindow->processURLs( m_urlsToImport ); } } @@ -1083,7 +1083,12 @@ void Application::messageReceived(const QByteArray& message) qWarning() << "Received" << command << "message without a zip path/URL."; return; } - m_mainWindow->processURLs({ QUrl::fromLocalFile(QFileInfo(path).absoluteFilePath()) }); + auto local_file = QFileInfo(path); + if (local_file.exists()) { + m_mainWindow->processURLs({ QUrl::fromLocalFile(local_file.absoluteFilePath()) }); + } else { + m_mainWindow->processURLs({ QUrl::fromUserInput(path) }); + } } else if(command == "launch") { @@ -1735,3 +1740,14 @@ void Application::triggerUpdateCheck() qDebug() << "Updater not available."; } } + +void Application::addImportUrl(QString const& url) +{ + auto local_file = QFileInfo(url); + if (local_file.exists()){ + m_urlsToImport.append(QUrl::fromLocalFile(local_file.absoluteFilePath())); + } else { + m_urlsToImport.append(QUrl::fromUserInput(url)); + } +} + diff --git a/launcher/Application.h b/launcher/Application.h index ced0af17d..83bfa9efd 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -211,6 +211,8 @@ public: int suitableMaxMem(); + void addImportUrl(QString const& url); + signals: void updateAllowedChanged(bool status); void globalSettingsAboutToOpen(); @@ -314,7 +316,7 @@ public: QString m_serverToJoin; QString m_profileToUse; bool m_liveCheck = false; - QList m_zipsToImport; + QList m_urlsToImport; QString m_instanceIdToShowWindowOf; std::unique_ptr logFile; }; diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 4d5193baa..41b7898cb 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -51,6 +51,7 @@ #include "Json.h" #include "settings/INISettingsObject.h" +#include "tasks/Task.h" #include #include @@ -89,46 +90,7 @@ void InstanceImportTask::executeTask() setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString())); m_downloadRequired = true; - if (m_sourceUrl.scheme() == "curseforge") { - // need to find the download link for the modpack - // format of url curseforge://install?addonId=IDHERE&fileId=IDHERE - QUrlQuery query(m_sourceUrl); - auto addonId = query.allQueryItemValues("addonId")[0]; - auto fileId = query.allQueryItemValues("fileId")[0]; - auto array = new QByteArray(); - auto req = new NetJob("Curseforge Meta", APPLICATION->network()); - req->addNetAction( - Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), array)); - connect(req, &NetJob::finished, [array, req] { - req->deleteLater(); - delete array; - }); - connect(req, &NetJob::failed, this, &InstanceImportTask::downloadFailed); - connect(req, &NetJob::succeeded, [array, this] { - auto doc = Json::requireDocument(*array); - // 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(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "fileName"); - if (fileName.endsWith(".zip")) { - // Have to use ensureString then use QUrl to get proper url encoding - m_sourceUrl = QUrl( - Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); - if (!m_sourceUrl.isValid()) { - emitFailed(tr("The modpack is blocked ! Please download it manually")); - return; - } - downloadFromUrl(); - } else { - emitFailed(tr("This url isn't a valid modpack !")); - } - }); - connect(req, &NetJob::progress, this, &InstanceImportTask::downloadProgressChanged); - connect(req, &NetJob::stepProgress, this, &InstanceImportTask::propogateStepProgress); - connect(req, &NetJob::aborted, this, &InstanceImportTask::downloadAborted); - req->start(); - } else { downloadFromUrl(); - } } } diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 30196aad6..78b7d1d56 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -35,12 +35,16 @@ */ #include "ImportPage.h" +#include "ui/dialogs/ProgressDialog.h" #include "ui_ImportPage.h" #include #include #include "ui/dialogs/NewInstanceDialog.h" +#include "ui/dialogs/CustomMessageBox.h" + +#include "Json.h" #include "InstanceImportTask.h" @@ -123,8 +127,62 @@ void ImportPage::updateState() dialog->setSuggestedIcon("default"); } } + else if (url.scheme() == "curseforge") + { + // need to find the download link for the modpack + // format of url curseforge://install?addonId=IDHERE&fileId=IDHERE + QUrlQuery query(url); + auto addonId = query.allQueryItemValues("addonId")[0]; + auto fileId = query.allQueryItemValues("fileId")[0]; + auto array = new QByteArray(); + auto req = unique_qobject_ptr(new NetJob("Curseforge Meta", APPLICATION->network())); + req->addNetAction( + Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), array)); + + connect(req.get(), &NetJob::finished, [array] { + delete array; + }); + connect(req.get(), &NetJob::failed, this, [this](QString reason){ + CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); + }); + connect(req.get(), &NetJob::succeeded, this, [this, array, addonId, fileId] { + qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str(); + auto doc = Json::requireDocument(*array); + // 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(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "fileName"); + if (fileName.endsWith(".zip")) { + // Have to use ensureString then use QUrl to get proper url encoding + auto dl_url = QUrl( + Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); + if (!dl_url.isValid()) { + CustomMessageBox::selectable(this, tr("Error"), tr("The modpack is blocked ! Please download it manually"), QMessageBox::Critical)->show(); + return; + } + + QFileInfo dl_file(dl_url.fileName()); + QString pack_name = Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "displayName", dl_file.completeBaseName(), "displayName"); + + QMap extra_info; + extra_info.insert("pack_id", addonId); + extra_info.insert("pack_version_id", fileId); + + dialog->setSuggestedPack(pack_name, new InstanceImportTask(dl_url, this, std::move(extra_info))); + dialog->setSuggestedIcon("default"); + + } else { + CustomMessageBox::selectable(this, tr("Error"), tr("This url isn't a valid modpack !"), QMessageBox::Critical)->show(); + } + }); + ProgressDialog dlUrlDialod(this); + dlUrlDialod.setSkipButton(true, tr("Abort")); + dlUrlDialod.execWithTask(req.get()); + return; + } else { + + if(input.endsWith("?client=y")) { input.chop(9); input.append("/file"); diff --git a/launcher/ui/pages/modplatform/ImportPage.ui b/launcher/ui/pages/modplatform/ImportPage.ui index 3583cf90a..9a9736b8a 100644 --- a/launcher/ui/pages/modplatform/ImportPage.ui +++ b/launcher/ui/pages/modplatform/ImportPage.ui @@ -40,7 +40,7 @@ - - CurseForge modpacks (ZIP) + - CurseForge modpacks (ZIP / curseforge:// URL) Qt::AlignCenter From 3e11d94829989986a460242fa55c0110772d00f3 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 12 May 2023 01:47:18 -0700 Subject: [PATCH 05/17] spelling suggestions from code review Co-authored-by: Sefa Eyeoglu Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 5694b82e7..5effc01be 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -220,7 +220,7 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) {"show", "Opens the window for the specified instance (by instance ID)", "show"} }); // Has to be positional for some OS to handle that properly - parser.addPositionalArgument("urls","import the resource at the given url(s) (same as -I / --import)","[urls...]"); + parser.addPositionalArgument("URL", "Import the resource(s) at the given URL(s) (same as -I / --import)", "[URL...]"); parser.addHelpOption(); parser.addVersionOption(); From b1ffc8ddab7d9aff10b6195a75e6e58c43b233ca Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Fri, 12 May 2023 16:37:45 -0700 Subject: [PATCH 06/17] refactor: normalize url fn & cleanup Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/Application.cpp | 45 ++++++------------ launcher/Application.h | 2 +- launcher/InstanceImportTask.cpp | 2 +- launcher/ui/pages/modplatform/ImportPage.cpp | 50 ++++++++------------ 4 files changed, 36 insertions(+), 63 deletions(-) diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 5effc01be..edaccadf6 100644 --- a/launcher/Application.cpp +++ b/launcher/Application.cpp @@ -235,12 +235,12 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) m_instanceIdToShowWindowOf = parser.value("show"); for (auto url : parser.values("import")){ - addImportUrl(url); + m_urlsToImport.append(normalizeImportUrl(url)); } // treat unspecified positional arguments as import urls for (auto url : parser.positionalArguments()) { - addImportUrl(url); + m_urlsToImport.append(normalizeImportUrl(url)); } // error if --launch is missing with --server or --profile @@ -345,12 +345,11 @@ Application::Application(int &argc, char **argv) : QApplication(argc, argv) activate.command = "activate"; m_peerInstance->sendMessage(activate.serialize(), timeout); - if(!m_urlsToImport.isEmpty()) - { + if (!m_urlsToImport.isEmpty()) { for (auto url : m_urlsToImport) { ApplicationMessage import; import.command = "import"; - import.args.insert("path", url.toString()); + import.args.insert("url", url.toString()); m_peerInstance->sendMessage(import.serialize(), timeout); } } @@ -1071,27 +1070,16 @@ void Application::messageReceived(const QByteArray& message) auto & command = received.command; - if(command == "activate") - { + if (command == "activate") { showMainWindow(); - } - else if(command == "import") - { - QString path = received.args["path"]; - if(path.isEmpty()) - { + } else if (command == "import") { + QString url = received.args["url"]; + if (url.isEmpty()) { qWarning() << "Received" << command << "message without a zip path/URL."; return; } - auto local_file = QFileInfo(path); - if (local_file.exists()) { - m_mainWindow->processURLs({ QUrl::fromLocalFile(local_file.absoluteFilePath()) }); - } else { - m_mainWindow->processURLs({ QUrl::fromUserInput(path) }); - } - } - else if(command == "launch") - { + m_mainWindow->processURLs({ normalizeImportUrl(url) }); + } else if (command == "launch") { QString id = received.args["id"]; QString server = received.args["server"]; QString profile = received.args["profile"]; @@ -1131,9 +1119,7 @@ void Application::messageReceived(const QByteArray& message) serverObject, accountObject ); - } - else - { + } else { qWarning() << "Received invalid message" << message; } } @@ -1741,13 +1727,12 @@ void Application::triggerUpdateCheck() } } -void Application::addImportUrl(QString const& url) +QUrl Application::normalizeImportUrl(QString const& url) { auto local_file = QFileInfo(url); - if (local_file.exists()){ - m_urlsToImport.append(QUrl::fromLocalFile(local_file.absoluteFilePath())); + if (local_file.exists()) { + return QUrl::fromLocalFile(local_file.absoluteFilePath()); } else { - m_urlsToImport.append(QUrl::fromUserInput(url)); + return QUrl::fromUserInput(url); } } - diff --git a/launcher/Application.h b/launcher/Application.h index 83bfa9efd..97d33830c 100644 --- a/launcher/Application.h +++ b/launcher/Application.h @@ -211,7 +211,7 @@ public: int suitableMaxMem(); - void addImportUrl(QString const& url); + QUrl normalizeImportUrl(QString const& url); signals: void updateAllowedChanged(bool status); diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp index 41b7898cb..badcf0a22 100644 --- a/launcher/InstanceImportTask.cpp +++ b/launcher/InstanceImportTask.cpp @@ -90,7 +90,7 @@ void InstanceImportTask::executeTask() setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString())); m_downloadRequired = true; - downloadFromUrl(); + downloadFromUrl(); } } diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 78b7d1d56..315f6555b 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -102,16 +102,13 @@ void ImportPage::openedImpl() void ImportPage::updateState() { - if(!isOpened) - { + if (!isOpened) { return; } - if(ui->modpackEdit->hasAcceptableInput()) - { + if (ui->modpackEdit->hasAcceptableInput()) { QString input = ui->modpackEdit->text(); auto url = QUrl::fromUserInput(input); - if(url.isLocalFile()) - { + if (url.isLocalFile()) { // FIXME: actually do some validation of what's inside here... this is fake AF QFileInfo fi(input); @@ -120,15 +117,12 @@ void ImportPage::updateState() // mrpack is a modrinth pack bool isMRPack = fi.suffix() == "mrpack"; - if(fi.exists() && (isZip || isMRPack)) - { + if (fi.exists() && (isZip || isMRPack)) { QFileInfo fi(url.fileName()); - dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url,this)); + dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this)); dialog->setSuggestedIcon("default"); } - } - else if (url.scheme() == "curseforge") - { + } else if (url.scheme() == "curseforge") { // need to find the download link for the modpack // format of url curseforge://install?addonId=IDHERE&fileId=IDHERE QUrlQuery query(url); @@ -139,12 +133,9 @@ void ImportPage::updateState() req->addNetAction( Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), array)); - connect(req.get(), &NetJob::finished, [array] { - delete array; - }); - connect(req.get(), &NetJob::failed, this, [this](QString reason){ - CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); - }); + connect(req.get(), &NetJob::finished, [array] { delete array; }); + connect(req.get(), &NetJob::failed, this, + [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); connect(req.get(), &NetJob::succeeded, this, [this, array, addonId, fileId] { qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str(); auto doc = Json::requireDocument(*array); @@ -156,12 +147,15 @@ void ImportPage::updateState() auto dl_url = QUrl( Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); if (!dl_url.isValid()) { - CustomMessageBox::selectable(this, tr("Error"), tr("The modpack is blocked ! Please download it manually"), QMessageBox::Critical)->show(); + CustomMessageBox::selectable(this, tr("Error"), tr("The modpack is blocked ! Please download it manually"), + QMessageBox::Critical) + ->show(); return; } QFileInfo dl_file(dl_url.fileName()); - QString pack_name = Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "displayName", dl_file.completeBaseName(), "displayName"); + QString pack_name = Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "displayName", + dl_file.completeBaseName(), "displayName"); QMap extra_info; extra_info.insert("pack_id", addonId); @@ -169,7 +163,7 @@ void ImportPage::updateState() dialog->setSuggestedPack(pack_name, new InstanceImportTask(dl_url, this, std::move(extra_info))); dialog->setSuggestedIcon("default"); - + } else { CustomMessageBox::selectable(this, tr("Error"), tr("This url isn't a valid modpack !"), QMessageBox::Critical)->show(); } @@ -178,24 +172,18 @@ void ImportPage::updateState() dlUrlDialod.setSkipButton(true, tr("Abort")); dlUrlDialod.execWithTask(req.get()); return; - } - else - { - - - if(input.endsWith("?client=y")) { + } else { + if (input.endsWith("?client=y")) { input.chop(9); input.append("/file"); url = QUrl::fromUserInput(input); } // hook, line and sinker. QFileInfo fi(url.fileName()); - dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url,this)); + dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this)); dialog->setSuggestedIcon("default"); } - } - else - { + } else { dialog->setSuggestedPack(); } } From fc656b6927914d64077e23690859996447908c57 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 15 May 2023 16:34:33 -0700 Subject: [PATCH 07/17] fix: when given a remost resource, download and identify it before import. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .../mod/tasks/LocalResourceParse.cpp | 8 +- launcher/modplatform/flame/FlameAPI.cpp | 12 ++ launcher/modplatform/flame/FlameAPI.h | 1 + launcher/ui/MainWindow.cpp | 104 ++++++++++++++++-- launcher/ui/MainWindow.h | 2 +- launcher/ui/dialogs/NewInstanceDialog.cpp | 8 +- launcher/ui/dialogs/NewInstanceDialog.h | 29 ++--- launcher/ui/pages/modplatform/ImportPage.cpp | 30 +++-- launcher/ui/pages/modplatform/ImportPage.h | 3 +- 9 files changed, 159 insertions(+), 38 deletions(-) diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp index 4d760df2b..ef052afc3 100644 --- a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp @@ -44,7 +44,10 @@ static const QMap s_packed_type_names = { namespace ResourceUtils { PackedResourceType identify(QFileInfo file){ if (file.exists() && file.isFile()) { - if (ResourcePackUtils::validate(file)) { + if (ModUtils::validate(file)) { + qDebug() << file.fileName() << "is a mod"; + return PackedResourceType::Mod; + } else if (ResourcePackUtils::validate(file)) { qDebug() << file.fileName() << "is a resource pack"; return PackedResourceType::ResourcePack; } else if (TexturePackUtils::validate(file)) { @@ -53,9 +56,6 @@ PackedResourceType identify(QFileInfo file){ } else if (DataPackUtils::validate(file)) { qDebug() << file.fileName() << "is a data pack"; return PackedResourceType::DataPack; - } else if (ModUtils::validate(file)) { - qDebug() << file.fileName() << "is a mod"; - return PackedResourceType::Mod; } else if (WorldSaveUtils::validate(file)) { qDebug() << file.fileName() << "is a world save"; return PackedResourceType::WorldSave; diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index 5ef9a4090..674ea427e 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -217,6 +217,18 @@ Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, QByteArray* response) c return netJob; } +Task::Ptr FlameAPI::getFile(const QString& addonId, const QString& fileId, QByteArray* response) const +{ + auto netJob = makeShared(QString("Flame::GetFile"), APPLICATION->network()); + netJob->addNetAction( + Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), response)); + + QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); + QObject::connect(netJob.get(), &NetJob::failed, [addonId, fileId] { qDebug() << "Flame API file failure" << addonId << fileId; }); + + return netJob; +} + // https://docs.curseforge.com/?python#tocS_ModsSearchSortField static QList s_sorts = { { 1, "Featured", QObject::tr("Sort by Featured") }, { 2, "Popularity", QObject::tr("Sort by Popularity") }, diff --git a/launcher/modplatform/flame/FlameAPI.h b/launcher/modplatform/flame/FlameAPI.h index 5811d7175..f3b328a6f 100644 --- a/launcher/modplatform/flame/FlameAPI.h +++ b/launcher/modplatform/flame/FlameAPI.h @@ -17,6 +17,7 @@ class FlameAPI : public NetworkResourceAPI { Task::Ptr getProjects(QStringList addonIds, QByteArray* response) const override; Task::Ptr matchFingerprints(const QList& fingerprints, QByteArray* response); Task::Ptr getFiles(const QStringList& fileIds, QByteArray* response) const; + Task::Ptr getFile(const QString& addonId, const QString& fileId, QByteArray* response) const; [[nodiscard]] auto getSortingMethods() const -> QList override; diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 72b7db641..7e46cc412 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -116,11 +117,15 @@ #include "minecraft/mod/ShaderPackFolderModel.h" #include "minecraft/WorldList.h" +#include "modplatform/flame/FlameAPI.h" + #include "KonamiCode.h" #include "InstanceImportTask.h" #include "InstanceCopyTask.h" +#include "Json.h" + #include "MMCTime.h" namespace { @@ -981,7 +986,7 @@ void MainWindow::finalizeInstance(InstancePtr inst) } } -void MainWindow::addInstance(QString url) +void MainWindow::addInstance(const QString& url, const QMap& extra_info) { QString groupName; do @@ -1003,7 +1008,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; @@ -1031,18 +1036,103 @@ void MainWindow::processURLs(QList urls) if (url.scheme().isEmpty()) url.setScheme("file"); - if (!url.isLocalFile()) { // probably instance/modpack - addInstance(url.toString()); - break; + QMap 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 = new 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); + // 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(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "fileName"); + + // Have to use ensureString then use QUrl to get proper url encoding + dl_url = QUrl(Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", + "", "downloadUrl")); + if (!dl_url.isValid()) { + CustomMessageBox::selectable(this, tr("Error"), tr("The modpack, mod, or resource is blocked ! Please download it manually \n%1").arg(dl_url.toDisplayString()), + QMessageBox::Critical) + ->show(); + return; + } + + QFileInfo dl_file(dl_url.fileName()); + resource_name = Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "displayName", + dl_file.completeBaseName(), "displayName"); + }); + + { // drop stack + ProgressDialog dlUrlDialod(this); + dlUrlDialod.setSkipButton(true, tr("Abort")); + dlUrlDialod.execWithTask(job.get()); + } + + // dialog->setSuggestedPack(pack_name, new InstanceImportTask(dl_url, this, std::move(extra_info))); + // dialog->setSuggestedIcon("default"); + + } 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(new NetJob(tr("Modpack download"), APPLICATION->network())); + dl_job->addNetAction(Net::Download::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; } diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index 3a42c34e1..1b8903194 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -210,7 +210,7 @@ private slots: private: void retranslateUi(); - void addInstance(QString url = QString()); + void addInstance(const QString& url = QString(), const QMap& extra_info = {}); void activateInstance(InstancePtr instance); void setCatBackground(bool enabled); void updateInstanceToolIcon(QString new_icon); diff --git a/launcher/ui/dialogs/NewInstanceDialog.cpp b/launcher/ui/dialogs/NewInstanceDialog.cpp index 64ed76739..3f9e11c39 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.cpp +++ b/launcher/ui/dialogs/NewInstanceDialog.cpp @@ -62,9 +62,10 @@ #include "ui/pages/modplatform/modrinth/ModrinthPage.h" #include "ui/pages/modplatform/technic/TechnicPage.h" - - -NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString & url, QWidget *parent) +NewInstanceDialog::NewInstanceDialog(const QString& initialGroup, + const QString& url, + const QMap& extra_info, + QWidget* parent) : QDialog(parent), ui(new Ui::NewInstanceDialog) { ui->setupUi(this); @@ -128,6 +129,7 @@ NewInstanceDialog::NewInstanceDialog(const QString & initialGroup, const QString QUrl actualUrl(url); m_container->selectPage("import"); importPage->setUrl(url); + importPage->setExtraInfo(extra_info); } updateDialogState(); diff --git a/launcher/ui/dialogs/NewInstanceDialog.h b/launcher/ui/dialogs/NewInstanceDialog.h index 961f512e2..368ad0dfc 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.h +++ b/launcher/ui/dialogs/NewInstanceDialog.h @@ -55,24 +55,27 @@ class NewInstanceDialog : public QDialog, public BasePageProvider Q_OBJECT public: - explicit NewInstanceDialog(const QString & initialGroup, const QString & url = QString(), QWidget *parent = 0); - ~NewInstanceDialog(); + explicit NewInstanceDialog(const QString& initialGroup, + const QString& url = QString(), + const QMap& extra_info = {}, + QWidget* parent = 0); + ~NewInstanceDialog(); - void updateDialogState(); + void updateDialogState(); - void setSuggestedPack(const QString& name = QString(), InstanceTask * task = nullptr); - void setSuggestedPack(const QString& name, QString version, InstanceTask * task = nullptr); - void setSuggestedIconFromFile(const QString &path, const QString &name); - void setSuggestedIcon(const QString &key); + void setSuggestedPack(const QString& name = QString(), InstanceTask* task = nullptr); + void setSuggestedPack(const QString& name, QString version, InstanceTask* task = nullptr); + void setSuggestedIconFromFile(const QString& path, const QString& name); + void setSuggestedIcon(const QString& key); - InstanceTask * extractTask(); + InstanceTask* extractTask(); - QString dialogTitle() override; - QList getPages() override; + QString dialogTitle() override; + QList getPages() override; - QString instName() const; - QString instGroup() const; - QString iconKey() const; + QString instName() const; + QString instGroup() const; + QString iconKey() const; public slots: void accept() override; diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 315f6555b..038b2a842 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -35,15 +35,20 @@ */ #include "ImportPage.h" +#include +#include #include "ui/dialogs/ProgressDialog.h" #include "ui_ImportPage.h" #include #include +#include #include "ui/dialogs/NewInstanceDialog.h" #include "ui/dialogs/CustomMessageBox.h" +#include "modplatform/flame/FlameAPI.h" + #include "Json.h" #include "InstanceImportTask.h" @@ -119,7 +124,9 @@ void ImportPage::updateState() if (fi.exists() && (isZip || isMRPack)) { QFileInfo fi(url.fileName()); - dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this)); + 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))); dialog->setSuggestedIcon("default"); } } else if (url.scheme() == "curseforge") { @@ -129,14 +136,13 @@ void ImportPage::updateState() auto addonId = query.allQueryItemValues("addonId")[0]; auto fileId = query.allQueryItemValues("fileId")[0]; auto array = new QByteArray(); - auto req = unique_qobject_ptr(new NetJob("Curseforge Meta", APPLICATION->network())); - req->addNetAction( - Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), array)); - connect(req.get(), &NetJob::finished, [array] { delete array; }); - connect(req.get(), &NetJob::failed, this, + auto api = FlameAPI(); + auto job = api.getFile(addonId, fileId, array); + + connect(job.get(), &NetJob::failed, this, [this](QString reason) { CustomMessageBox::selectable(this, tr("Error"), reason, QMessageBox::Critical)->show(); }); - connect(req.get(), &NetJob::succeeded, this, [this, array, addonId, fileId] { + connect(job.get(), &NetJob::succeeded, this, [this, array, addonId, fileId] { qDebug() << "Returned CFURL Json:\n" << array->toStdString().c_str(); auto doc = Json::requireDocument(*array); // No way to find out if it's a mod or a modpack before here @@ -170,7 +176,7 @@ void ImportPage::updateState() }); ProgressDialog dlUrlDialod(this); dlUrlDialod.setSkipButton(true, tr("Abort")); - dlUrlDialod.execWithTask(req.get()); + dlUrlDialod.execWithTask(job.get()); return; } else { if (input.endsWith("?client=y")) { @@ -180,7 +186,8 @@ void ImportPage::updateState() } // hook, line and sinker. QFileInfo fi(url.fileName()); - dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this)); + auto extra_info = QMap(m_extra_info); + dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(url, this, std::move(extra_info))); dialog->setSuggestedIcon("default"); } } else { @@ -194,6 +201,11 @@ void ImportPage::setUrl(const QString& url) updateState(); } +void ImportPage::setExtraInfo(const QMap& extra_info) { + m_extra_info = QMap(extra_info); // copy + updateState(); +} + void ImportPage::on_modpackBtn_clicked() { auto filter = QMimeDatabase().mimeTypeForName("application/zip").filterString(); diff --git a/launcher/ui/pages/modplatform/ImportPage.h b/launcher/ui/pages/modplatform/ImportPage.h index 8d13ac100..d35cb361e 100644 --- a/launcher/ui/pages/modplatform/ImportPage.h +++ b/launcher/ui/pages/modplatform/ImportPage.h @@ -76,7 +76,7 @@ public: void setUrl(const QString & url); void openedImpl() override; - + void setExtraInfo(const QMap& extra_info); private slots: void on_modpackBtn_clicked(); void updateState(); @@ -87,5 +87,6 @@ private: private: Ui::ImportPage *ui = nullptr; NewInstanceDialog* dialog = nullptr; + QMap m_extra_info = {}; }; From 649753e97e4609deee09a1c8beeba3027d66e4d0 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Mon, 15 May 2023 16:40:56 -0700 Subject: [PATCH 08/17] cleanup: remove unneeded headers Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .../mod/tasks/LocalResourceParse.cpp | 2 +- launcher/ui/MainWindow.cpp | 1 - launcher/ui/dialogs/NewInstanceDialog.h | 58 +++++++++---------- launcher/ui/pages/modplatform/ImportPage.cpp | 3 +- 4 files changed, 30 insertions(+), 34 deletions(-) diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp index ef052afc3..fa7d7f4ae 100644 --- a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp +++ b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp @@ -44,7 +44,7 @@ static const QMap s_packed_type_names = { namespace ResourceUtils { PackedResourceType identify(QFileInfo file){ if (file.exists() && file.isFile()) { - if (ModUtils::validate(file)) { + if (ModUtils::validate(file)) { // Mods can also contain resource and data packs qDebug() << file.fileName() << "is a mod"; return PackedResourceType::Mod; } else if (ResourcePackUtils::validate(file)) { diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 7e46cc412..31a75e5bf 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -86,7 +86,6 @@ #include #include #include -#include #include #include #include diff --git a/launcher/ui/dialogs/NewInstanceDialog.h b/launcher/ui/dialogs/NewInstanceDialog.h index 368ad0dfc..6a6ad89eb 100644 --- a/launcher/ui/dialogs/NewInstanceDialog.h +++ b/launcher/ui/dialogs/NewInstanceDialog.h @@ -37,11 +37,10 @@ #include -#include "ui/pages/BasePageProvider.h" #include "InstanceTask.h" +#include "ui/pages/BasePageProvider.h" -namespace Ui -{ +namespace Ui { class NewInstanceDialog; } @@ -50,48 +49,47 @@ class QDialogButtonBox; class ImportPage; class FlamePage; -class NewInstanceDialog : public QDialog, public BasePageProvider -{ +class NewInstanceDialog : public QDialog, public BasePageProvider { Q_OBJECT -public: - explicit NewInstanceDialog(const QString& initialGroup, - const QString& url = QString(), - const QMap& extra_info = {}, - QWidget* parent = 0); - ~NewInstanceDialog(); + public: + explicit NewInstanceDialog(const QString& initialGroup, + const QString& url = QString(), + const QMap& extra_info = {}, + QWidget* parent = 0); + ~NewInstanceDialog(); - void updateDialogState(); + void updateDialogState(); - void setSuggestedPack(const QString& name = QString(), InstanceTask* task = nullptr); - void setSuggestedPack(const QString& name, QString version, InstanceTask* task = nullptr); - void setSuggestedIconFromFile(const QString& path, const QString& name); - void setSuggestedIcon(const QString& key); + void setSuggestedPack(const QString& name = QString(), InstanceTask* task = nullptr); + void setSuggestedPack(const QString& name, QString version, InstanceTask* task = nullptr); + void setSuggestedIconFromFile(const QString& path, const QString& name); + void setSuggestedIcon(const QString& key); - InstanceTask* extractTask(); + InstanceTask* extractTask(); - QString dialogTitle() override; - QList getPages() override; + QString dialogTitle() override; + QList getPages() override; - QString instName() const; - QString instGroup() const; - QString iconKey() const; + QString instName() const; + QString instGroup() const; + QString iconKey() const; -public slots: + public slots: void accept() override; void reject() override; -private slots: + private slots: void on_iconButton_clicked(); - void on_instNameTextBox_textChanged(const QString &arg1); + void on_instNameTextBox_textChanged(const QString& arg1); -private: - Ui::NewInstanceDialog *ui = nullptr; - PageContainer * m_container = nullptr; - QDialogButtonBox * m_buttons = nullptr; + private: + Ui::NewInstanceDialog* ui = nullptr; + PageContainer* m_container = nullptr; + QDialogButtonBox* m_buttons = nullptr; QString InstIconKey; - ImportPage *importPage = nullptr; + ImportPage* importPage = nullptr; std::unique_ptr creationTask; bool importIcon = false; diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 038b2a842..1e540cf21 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -35,8 +35,7 @@ */ #include "ImportPage.h" -#include -#include + #include "ui/dialogs/ProgressDialog.h" #include "ui_ImportPage.h" From bd1ea64d02828df7b24081e02ec162abb4b13e9f Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 16 May 2023 00:01:52 -0700 Subject: [PATCH 09/17] cleanup Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/MainWindow.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 31a75e5bf..4546eb1e7 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1088,8 +1088,6 @@ void MainWindow::processURLs(QList urls) dlUrlDialod.execWithTask(job.get()); } - // dialog->setSuggestedPack(pack_name, new InstanceImportTask(dl_url, this, std::move(extra_info))); - // dialog->setSuggestedIcon("default"); } else { dl_url = url; From eb079c80605f88cbd0aaff8285dafc459c6f42eb Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 28 May 2023 11:13:53 -0700 Subject: [PATCH 10/17] cleanup: msgbox msg editor Co-authored-by: flow Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 4546eb1e7..63209b9f5 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1071,7 +1071,7 @@ void MainWindow::processURLs(QList urls) dl_url = QUrl(Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); if (!dl_url.isValid()) { - CustomMessageBox::selectable(this, tr("Error"), tr("The modpack, mod, or resource is blocked ! Please download it manually \n%1").arg(dl_url.toDisplayString()), + CustomMessageBox::selectable(this, tr("Error"), tr("The modpack, mod, or resource is blocked for third-parties! Please download it manually at: \n%1").arg(dl_url.toDisplayString()), QMessageBox::Critical) ->show(); return; From 149bc8e9ce1be5edf93de4a4d63b93129ad321b8 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Sun, 28 May 2023 11:54:32 -0700 Subject: [PATCH 11/17] cleanup: pull out data object so I'm not repeating myself Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/ui/MainWindow.cpp | 22 ++++++++++---------- launcher/ui/pages/modplatform/ImportPage.cpp | 17 ++++++++------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index bc62f9521..25d39c85f 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1085,31 +1085,31 @@ void MainWindow::processURLs(QList urls) 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, &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(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "fileName"); - + auto fileName = Json::ensureString(data, "fileName"); + // Have to use ensureString then use QUrl to get proper url encoding - dl_url = QUrl(Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", - "", "downloadUrl")); + dl_url = QUrl(Json::ensureString(data, "downloadUrl", "", "downloadUrl")); if (!dl_url.isValid()) { - CustomMessageBox::selectable(this, tr("Error"), tr("The modpack, mod, or resource is blocked for third-parties! Please download it manually at: \n%1").arg(dl_url.toDisplayString()), - QMessageBox::Critical) + 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(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "displayName", - dl_file.completeBaseName(), "displayName"); + resource_name = Json::ensureString(data, "displayName", dl_file.completeBaseName(), "displayName"); }); - + { // drop stack ProgressDialog dlUrlDialod(this); dlUrlDialod.setSkipButton(true, tr("Abort")); diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 1e540cf21..67dfbf457 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -144,23 +144,24 @@ void ImportPage::updateState() connect(job.get(), &NetJob::succeeded, this, [this, array, addonId, fileId] { 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(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "fileName"); + auto fileName = Json::ensureString(data, "fileName"); if (fileName.endsWith(".zip")) { // Have to use ensureString then use QUrl to get proper url encoding - auto dl_url = QUrl( - Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "downloadUrl", "", "downloadUrl")); + auto dl_url = QUrl(Json::ensureString(data, "downloadUrl", "", "downloadUrl")); if (!dl_url.isValid()) { - CustomMessageBox::selectable(this, tr("Error"), tr("The modpack is blocked ! Please download it manually"), - QMessageBox::Critical) + CustomMessageBox::selectable( + this, tr("Error"), + tr("The modpack %1 is blocked for third-parties! Please download it manually.").arg(fileName), + QMessageBox::Critical) ->show(); return; } QFileInfo dl_file(dl_url.fileName()); - QString pack_name = Json::ensureString(Json::ensureObject(Json::ensureObject(doc.object()), "data"), "displayName", - dl_file.completeBaseName(), "displayName"); + QString pack_name = Json::ensureString(data, "displayName", dl_file.completeBaseName(), "displayName"); QMap extra_info; extra_info.insert("pack_id", addonId); @@ -201,7 +202,7 @@ void ImportPage::setUrl(const QString& url) } void ImportPage::setExtraInfo(const QMap& extra_info) { - m_extra_info = QMap(extra_info); // copy + m_extra_info = extra_info; updateState(); } From 6d5a2ceefe7f842dd6872b6a38a355bc1b185fb3 Mon Sep 17 00:00:00 2001 From: Rachel Powers <508861+Ryex@users.noreply.github.com> Date: Tue, 11 Jul 2023 21:45:23 -0700 Subject: [PATCH 12/17] fix(flameapi): getFile use shared_ptr Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- launcher/modplatform/flame/FlameAPI.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index 66eba4ff3..485d67363 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -202,13 +202,12 @@ Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, std::shared_ptrresponse) const { auto netJob = makeShared(QString("Flame::GetFile"), APPLICATION->network()); netJob->addNetAction( Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), response)); - QObject::connect(netJob.get(), &NetJob::finished, [response] { delete response; }); QObject::connect(netJob.get(), &NetJob::failed, [addonId, fileId] { qDebug() << "Flame API file failure" << addonId << fileId; }); return netJob; From a83e5be8f2acd66f83ad181e54fe688ed08c1b6f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Aug 2023 21:51:03 +0200 Subject: [PATCH 13/17] fix: makeShared for QByteArray Signed-off-by: Sefa Eyeoglu --- launcher/ui/MainWindow.cpp | 2 +- launcher/ui/pages/modplatform/ImportPage.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 25d39c85f..9feb7cf27 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -1078,7 +1078,7 @@ void MainWindow::processURLs(QList urls) extra_info.insert("pack_id", addonId); extra_info.insert("pack_version_id", fileId); - auto array = new QByteArray(); + auto array = std::make_shared(); auto api = FlameAPI(); auto job = api.getFile(addonId, fileId, array); diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 67dfbf457..8250193ab 100644 --- a/launcher/ui/pages/modplatform/ImportPage.cpp +++ b/launcher/ui/pages/modplatform/ImportPage.cpp @@ -134,7 +134,7 @@ void ImportPage::updateState() QUrlQuery query(url); auto addonId = query.allQueryItemValues("addonId")[0]; auto fileId = query.allQueryItemValues("fileId")[0]; - auto array = new QByteArray(); + auto array = std::make_shared(); auto api = FlameAPI(); auto job = api.getFile(addonId, fileId, array); From 019e5ca3e819f5daf9933bc0fb091784b0ca561f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sat, 12 Aug 2023 11:11:58 +0200 Subject: [PATCH 14/17] fix: use ApiDownload for CF URL handling Signed-off-by: Sefa Eyeoglu --- launcher/modplatform/flame/FlameAPI.cpp | 2 +- launcher/ui/MainWindow.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index 2871f06a0..93d3b76a0 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -208,7 +208,7 @@ Task::Ptr FlameAPI::getFile(const QString& addonId, const QString& fileId, std:: { auto netJob = makeShared(QString("Flame::GetFile"), APPLICATION->network()); netJob->addNetAction( - Net::Download::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), response)); + Net::ApiDownload::makeByteArray(QUrl(QString("https://api.curseforge.com/v1/mods/%1/files/%2").arg(addonId, fileId)), response)); QObject::connect(netJob.get(), &NetJob::failed, [addonId, fileId] { qDebug() << "Flame API file failure" << addonId << fileId; }); diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index dd383b239..8300fe295 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -85,7 +85,7 @@ #include #include #include -#include +#include #include #include #include @@ -1046,7 +1046,7 @@ void MainWindow::processURLs(QList urls) auto entry = APPLICATION->metacache()->resolveEntry("general", path); entry->setStale(true); auto dl_job = unique_qobject_ptr(new NetJob(tr("Modpack download"), APPLICATION->network())); - dl_job->addNetAction(Net::Download::makeCached(dl_url, entry)); + dl_job->addNetAction(Net::ApiDownload::makeCached(dl_url, entry)); auto archivePath = entry->getFullPath(); bool dl_success = false; From c22eec8f27e11a6517abb89075b36705d73b1983 Mon Sep 17 00:00:00 2001 From: Trial97 Date: Tue, 15 Aug 2023 17:00:58 +0300 Subject: [PATCH 15/17] fixed crash on atlauncher pack install Signed-off-by: Trial97 --- .../atlauncher/ATLPackInstallTask.cpp | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp index 5d1a361df..e5771b7cd 100644 --- a/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp +++ b/launcher/modplatform/atlauncher/ATLPackInstallTask.cpp @@ -1005,15 +1005,30 @@ static Meta::Version::Ptr getComponentVersion(const QString& uid, const QString& if (!vlist) return {}; - if (!vlist->isLoaded()) - vlist->load(Net::Mode::Online); + if (!vlist->isLoaded()) { + QEventLoop loadVersionLoop; + auto task = vlist->getLoadTask(); + QObject::connect(task.get(), &Task::finished, &loadVersionLoop, &QEventLoop::quit); + if (!task->isRunning()) + task->start(); + + loadVersionLoop.exec(); + } auto ver = vlist->getVersion(version); if (!ver) return {}; - if (!ver->isLoaded()) + if (!ver->isLoaded()) { + QEventLoop loadVersionLoop; ver->load(Net::Mode::Online); + auto task = ver->getCurrentTask(); + QObject::connect(task.get(), &Task::finished, &loadVersionLoop, &QEventLoop::quit); + if (!task->isRunning()) + task->start(); + + loadVersionLoop.exec(); + } return ver; } From 07f25d6ccadc1958729471f4d68155d33c072564 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Aug 2023 14:19:42 +0000 Subject: [PATCH 16/17] chore(deps): update korthout/backport-action action to v1.4.0 --- .github/workflows/backport.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 77c1a8802..08cfb56dd 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -24,7 +24,7 @@ jobs: with: ref: ${{ github.event.pull_request.head.sha }} - name: Create backport PRs - uses: korthout/backport-action@v1.3.1 + uses: korthout/backport-action@v1.4.0 with: # Config README: https://github.com/korthout/backport-action#backport-action pull_description: |- From 5e2d1ffdfbb3f673c063029c9a6c55071cba160a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 17 Aug 2023 00:23:53 +0300 Subject: [PATCH 17/17] removed line Signed-off-by: Trial97 --- launcher/modplatform/flame/FlameAPI.cpp | 2 +- launcher/ui/MainWindow.cpp | 16 ++++++++-------- launcher/ui/pages/modplatform/ImportPage.cpp | 1 - 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index 4a04e583d..74d7db975 100644 --- a/launcher/modplatform/flame/FlameAPI.cpp +++ b/launcher/modplatform/flame/FlameAPI.cpp @@ -204,7 +204,7 @@ Task::Ptr FlameAPI::getFiles(const QStringList& fileIds, std::shared_ptrresponse) const +Task::Ptr FlameAPI::getFile(const QString& addonId, const QString& fileId, std::shared_ptr response) const { auto netJob = makeShared(QString("Flame::GetFile"), APPLICATION->network()); netJob->addNetAction( diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 7d4148775..067108f2d 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -984,7 +984,7 @@ void MainWindow::processURLs(QList urls) 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); @@ -1027,19 +1027,18 @@ void MainWindow::processURLs(QList urls) 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 +1049,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); diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index ee8757f85..3e3c36b7b 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)));