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