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: 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/ui/pages/modplatform/ImportPage.cpp | 58 ++++++++++++++++++++++++++++ launcher/ui/pages/modplatform/ImportPage.ui | 2 +- 2 files changed, 59 insertions(+), 1 deletion(-) (limited to 'launcher/ui/pages') diff --git a/launcher/ui/pages/modplatform/ImportPage.cpp b/launcher/ui/pages/modplatform/ImportPage.cpp index 30196aad..78b7d1d5 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 3583cf90..9a9736b8 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 -- cgit 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: 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(-) (limited to 'launcher/ui/pages') diff --git a/launcher/Application.cpp b/launcher/Application.cpp index 5effc01b..edaccadf 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 83bfa9ef..97d33830 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 41b7898c..badcf0a2 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 78b7d1d5..315f6555 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(); } } -- cgit 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: fix: when given a remost resource, download and identify it before import. Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .../minecraft/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(-) (limited to 'launcher/ui/pages') diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp index 4d760df2..ef052afc 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 5ef9a409..674ea427 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 5811d717..f3b328a6 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 72b7db64..7e46cc41 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 3a42c34e..1b890319 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 64ed7673..3f9e11c3 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 961f512e..368ad0df 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 315f6555..038b2a84 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 8d13ac10..d35cb361 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 = {}; }; -- cgit 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: cleanup: remove unneeded headers Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com> --- .../minecraft/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(-) (limited to 'launcher/ui/pages') diff --git a/launcher/minecraft/mod/tasks/LocalResourceParse.cpp b/launcher/minecraft/mod/tasks/LocalResourceParse.cpp index ef052afc..fa7d7f4a 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 7e46cc41..31a75e5b 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 368ad0df..6a6ad89e 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 038b2a84..1e540cf2 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" -- cgit 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: 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(-) (limited to 'launcher/ui/pages') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index bc62f952..25d39c85 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 1e540cf2..67dfbf45 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(); } -- cgit From a83e5be8f2acd66f83ad181e54fe688ed08c1b6f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Sun, 6 Aug 2023 21:51:03 +0200 Subject: 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(-) (limited to 'launcher/ui/pages') diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 25d39c85..9feb7cf2 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 67dfbf45..8250193a 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); -- cgit From 5e2d1ffdfbb3f673c063029c9a6c55071cba160a Mon Sep 17 00:00:00 2001 From: Trial97 Date: Thu, 17 Aug 2023 00:23:53 +0300 Subject: 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(-) (limited to 'launcher/ui/pages') diff --git a/launcher/modplatform/flame/FlameAPI.cpp b/launcher/modplatform/flame/FlameAPI.cpp index 4a04e583..74d7db97 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 7d414877..067108f2 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 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