diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index d6c4ccbec..650395d78 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -940,6 +940,11 @@ void MainWindow::processURLs(QList urls) QMap extra_info; QUrl local_url; if (!url.isLocalFile()) { // download the remote resource and identify + + const bool isExternalURLImport = + (url.host().toLower() == "import") || + (url.path().startsWith("/import", Qt::CaseInsensitive)); + QUrl dl_url; if (url.scheme() == "curseforge") { // need to find the download link for the modpack / resource @@ -993,7 +998,7 @@ void MainWindow::processURLs(QList urls) dlUrlDialod.execWithTask(job.get()); } - } else if (url.scheme() == BuildConfig.LAUNCHER_APP_BINARY_NAME) { + } else if (url.scheme() == BuildConfig.LAUNCHER_APP_BINARY_NAME && !isExternalURLImport) { QVariantMap receivedData; const QUrlQuery query(url.query()); const auto items = query.queryItems(); @@ -1001,6 +1006,77 @@ void MainWindow::processURLs(QList urls) receivedData.insert(it->first, it->second); emit APPLICATION->oauthReplyRecieved(receivedData); continue; + } else if (url.scheme() == "prismlauncher" && isExternalURLImport) { + // PrismLauncher URL protocol modpack import + // works for any prism fork + // preferred import format: ://import?url=ENCODED + + const auto host = url.host().toLower(); + const auto path = url.path(); + + QString encodedTarget; + + { + QUrlQuery query(url); + const auto values = query.allQueryItemValues("url"); + if (!values.isEmpty()) { + encodedTarget = values.first(); + } + } + + // alternative import format: ://import/ENCODED + if (encodedTarget.isEmpty()) { + + QString p = path; + + if (p.startsWith("/import/", Qt::CaseInsensitive)) { + p = p.mid(QString("/import/").size()); + } else if (host == "import" && p.startsWith("/")) { + p = p.mid(1); + } + + if (!p.isEmpty() && p != "/import") { + encodedTarget = p; + } + } + + if (encodedTarget.isEmpty()) { + CustomMessageBox::selectable( + this, + tr("Error"), + tr("Invalid import link: missing 'url' parameter."), + QMessageBox::Critical + )->show(); + continue; + } + + const QString decodedStr = QUrl::fromPercentEncoding(encodedTarget.toUtf8()).trimmed(); + + QUrl target = QUrl::fromUserInput(decodedStr); + + // Validate: only allow http(s) + if (!target.isValid() || (target.scheme() != "https" && target.scheme() != "http")) { + CustomMessageBox::selectable( + this, + tr("Error"), + tr("Invalid import link: URL must be http(s)."), + QMessageBox::Critical + )->show(); + continue; + } + + const auto res = QMessageBox::question( + this, + tr("Install modpack"), + tr("Do you want to download and import a modpack from:\n%1\n\nURL:\n%2") + .arg(target.host(), target.toString()), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::Yes + ); + if (res != QMessageBox::Yes) { + continue; + } + } else { dl_url = url; }