aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRachel Powers <508861+Ryex@users.noreply.github.com>2023-04-07 16:54:25 -0700
committerRachel Powers <508861+Ryex@users.noreply.github.com>2023-05-05 15:05:17 -0700
commita3173b53717fcea686f267f4eb8fd9788e6677db (patch)
treea0cf79f0efb05e797426c81438370aeeb0f5ca66
parent54fb799d95faa3d646cfc835937e5fbdb10afa4d (diff)
downloadPrismLauncher-a3173b53717fcea686f267f4eb8fd9788e6677db.tar.gz
PrismLauncher-a3173b53717fcea686f267f4eb8fd9788e6677db.tar.bz2
PrismLauncher-a3173b53717fcea686f267f4eb8fd9788e6677db.zip
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>
-rw-r--r--launcher/Application.cpp42
-rw-r--r--launcher/Application.h4
-rw-r--r--launcher/InstanceImportTask.cpp40
-rw-r--r--launcher/ui/pages/modplatform/ImportPage.cpp58
-rw-r--r--launcher/ui/pages/modplatform/ImportPage.ui2
5 files changed, 92 insertions, 54 deletions
diff --git a/launcher/Application.cpp b/launcher/Application.cpp
index 6994d1ba..c97fdb0a 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 ced0af17..83bfa9ef 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<QUrl> m_zipsToImport;
+ QList<QUrl> m_urlsToImport;
QString m_instanceIdToShowWindowOf;
std::unique_ptr<QFile> logFile;
};
diff --git a/launcher/InstanceImportTask.cpp b/launcher/InstanceImportTask.cpp
index 4d5193ba..41b7898c 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 <QtConcurrentRun>
#include <algorithm>
@@ -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 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 <QFileDialog>
#include <QValidator>
#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<NetJob>(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<QString, QString> 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 @@
<item>
<widget class="QLabel" name="label_5">
<property name="text">
- <string>- CurseForge modpacks (ZIP)</string>
+ <string>- CurseForge modpacks (ZIP / curseforge:// URL)</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>