summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/logic/modplatform/flame/FileResolvingTask.cpp66
-rw-r--r--api/logic/modplatform/flame/PackManifest.cpp60
-rw-r--r--api/logic/modplatform/flame/PackManifest.h3
-rw-r--r--api/logic/modplatform/flame/UrlResolvingTask.cpp58
-rw-r--r--api/logic/modplatform/flame/UrlResolvingTask.h7
-rw-r--r--application/pages/modplatform/TwitchPage.cpp10
6 files changed, 127 insertions, 77 deletions
diff --git a/api/logic/modplatform/flame/FileResolvingTask.cpp b/api/logic/modplatform/flame/FileResolvingTask.cpp
index 24cafcdd..295574f0 100644
--- a/api/logic/modplatform/flame/FileResolvingTask.cpp
+++ b/api/logic/modplatform/flame/FileResolvingTask.cpp
@@ -1,7 +1,9 @@
#include "FileResolvingTask.h"
#include "Json.h"
-const char * metabase = "https://cursemeta.dries007.net";
+namespace {
+ const char * metabase = "https://cursemeta.dries007.net";
+}
Flame::FileResolvingTask::FileResolvingTask(Flame::Manifest& toProcess)
: m_toProcess(toProcess)
@@ -34,70 +36,14 @@ void Flame::FileResolvingTask::netJobFinished()
int index = 0;
for(auto & bytes: results)
{
+ auto & out = m_toProcess.files[index];
try
{
- auto doc = Json::requireDocument(bytes);
- auto obj = Json::requireObject(doc);
- auto & out = m_toProcess.files[index];
- // result code signifies true failure.
- if(obj.contains("code"))
- {
- qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a negative result:";
- qCritical() << bytes;
- failed = true;
- continue;
- }
- out.fileName = Json::requireString(obj, "FileNameOnDisk");
- QString rawUrl = Json::requireString(obj, "DownloadURL");
- out.url = QUrl(rawUrl, QUrl::TolerantMode);
- if(!out.url.isValid())
- {
- throw JSONValidationError(QString("Invalid URL: %1").arg(rawUrl));
- }
- // This is a piece of a Flame project JSON pulled out into the file metadata (here) for convenience
- // It is also optional
- QJsonObject projObj = Json::ensureObject(obj, "_Project", {});
- if(!projObj.isEmpty())
- {
- QString strType = Json::ensureString(projObj, "PackageType", "mod").toLower();
- if(strType == "singlefile")
- {
- out.type = File::Type::SingleFile;
- }
- else if(strType == "ctoc")
- {
- out.type = File::Type::Ctoc;
- }
- else if(strType == "cmod2")
- {
- out.type = File::Type::Cmod2;
- }
- else if(strType == "mod")
- {
- out.type = File::Type::Mod;
- }
- else if(strType == "folder")
- {
- out.type = File::Type::Folder;
- }
- else if(strType == "modpack")
- {
- out.type = File::Type::Modpack;
- }
- else
- {
- qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of unknown file type:" << strType;
- out.type = File::Type::Unknown;
- failed = true;
- continue;
- }
- out.targetFolder = Json::ensureString(projObj, "Path", "mods");
- }
- out.resolved = true;
+ failed &= (!out.parseFromBytes(bytes));
}
catch (const JSONValidationError &e)
{
- auto & out = m_toProcess.files[index];
+
qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a parsing error:";
qCritical() << e.cause();
qCritical() << "JSON:";
diff --git a/api/logic/modplatform/flame/PackManifest.cpp b/api/logic/modplatform/flame/PackManifest.cpp
index 0f57c9bc..1db0a161 100644
--- a/api/logic/modplatform/flame/PackManifest.cpp
+++ b/api/logic/modplatform/flame/PackManifest.cpp
@@ -64,3 +64,63 @@ void Flame::loadManifest(Flame::Manifest & m, const QString &filepath)
}
loadManifestV1(m, obj);
}
+
+bool Flame::File::parseFromBytes(const QByteArray& bytes)
+{
+ auto doc = Json::requireDocument(bytes);
+ auto obj = Json::requireObject(doc);
+ // result code signifies true failure.
+ if(obj.contains("code"))
+ {
+ qCritical() << "Resolving of" << projectId << fileId << "failed because of a negative result:";
+ qCritical() << bytes;
+ return false;
+ }
+ fileName = Json::requireString(obj, "FileNameOnDisk");
+ QString rawUrl = Json::requireString(obj, "DownloadURL");
+ url = QUrl(rawUrl, QUrl::TolerantMode);
+ if(!url.isValid())
+ {
+ throw JSONValidationError(QString("Invalid URL: %1").arg(rawUrl));
+ }
+ // This is a piece of a Flame project JSON pulled out into the file metadata (here) for convenience
+ // It is also optional
+ QJsonObject projObj = Json::ensureObject(obj, "_Project", {});
+ if(!projObj.isEmpty())
+ {
+ QString strType = Json::ensureString(projObj, "PackageType", "mod").toLower();
+ if(strType == "singlefile")
+ {
+ type = File::Type::SingleFile;
+ }
+ else if(strType == "ctoc")
+ {
+ type = File::Type::Ctoc;
+ }
+ else if(strType == "cmod2")
+ {
+ type = File::Type::Cmod2;
+ }
+ else if(strType == "mod")
+ {
+ type = File::Type::Mod;
+ }
+ else if(strType == "folder")
+ {
+ type = File::Type::Folder;
+ }
+ else if(strType == "modpack")
+ {
+ type = File::Type::Modpack;
+ }
+ else
+ {
+ qCritical() << "Resolving of" << projectId << fileId << "failed because of unknown file type:" << strType;
+ type = File::Type::Unknown;
+ return false;
+ }
+ targetFolder = Json::ensureString(projObj, "Path", "mods");
+ }
+ resolved = true;
+ return true;
+}
diff --git a/api/logic/modplatform/flame/PackManifest.h b/api/logic/modplatform/flame/PackManifest.h
index 34232eee..02f39f0e 100644
--- a/api/logic/modplatform/flame/PackManifest.h
+++ b/api/logic/modplatform/flame/PackManifest.h
@@ -8,6 +8,9 @@ namespace Flame
{
struct File
{
+ // NOTE: throws JSONValidationError
+ bool parseFromBytes(const QByteArray &bytes);
+
int projectId = 0;
int fileId = 0;
// NOTE: the opposite to 'optional'. This is at the time of writing unused.
diff --git a/api/logic/modplatform/flame/UrlResolvingTask.cpp b/api/logic/modplatform/flame/UrlResolvingTask.cpp
index 068b6a34..9d53e7e5 100644
--- a/api/logic/modplatform/flame/UrlResolvingTask.cpp
+++ b/api/logic/modplatform/flame/UrlResolvingTask.cpp
@@ -1,11 +1,11 @@
#include "UrlResolvingTask.h"
#include <QtXml>
+#include <Json.h>
+
-/*
namespace {
-const char * metabase = "https://cursemeta.dries007.net";
+ const char * metabase = "https://cursemeta.dries007.net";
}
-*/
Flame::UrlResolvingTask::UrlResolvingTask(const QString& toProcess)
: m_url(toProcess)
@@ -14,11 +14,16 @@ Flame::UrlResolvingTask::UrlResolvingTask(const QString& toProcess)
void Flame::UrlResolvingTask::executeTask()
{
+ resolveUrl();
+}
+
+void Flame::UrlResolvingTask::resolveUrl()
+{
setStatus(tr("Resolving URL..."));
setProgress(0, 1);
m_dljob.reset(new NetJob("URL resolver"));
- weAreDigging = false;
+ bool weAreDigging = false;
needle = QString();
if(m_url.startsWith("https://")) {
@@ -48,17 +53,12 @@ void Flame::UrlResolvingTask::executeTask()
}
auto dl = Net::Download::makeByteArray(QUrl(m_url), &results);
m_dljob->addNetAction(dl);
- connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::netJobFinished);
- m_dljob->start();
-}
-
-void Flame::UrlResolvingTask::netJobFinished()
-{
if(weAreDigging) {
- processHTML();
+ connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processHTML);
} else {
- processCCIP();
+ connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processCCIP);
}
+ m_dljob->start();
}
void Flame::UrlResolvingTask::processHTML()
@@ -83,7 +83,7 @@ void Flame::UrlResolvingTask::processHTML()
qDebug() << "Found needle: " << found;
// twitch://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088
m_url = found;
- executeTask();
+ resolveUrl();
return;
}
emitFailed(tr("Couldn't find the end of the needle in the haystack..."));
@@ -135,6 +135,36 @@ void Flame::UrlResolvingTask::processCCIP()
return;
}
qDebug() << "Resolved" << m_url << "as" << m_result.projectId << "/" << m_result.fileId;
- emitSucceeded();
+ resolveIDs();
}
+void Flame::UrlResolvingTask::resolveIDs()
+{
+ setStatus(tr("Resolving mod IDs..."));
+ m_dljob.reset(new NetJob("Mod id resolver"));
+ auto projectIdStr = QString::number(m_result.projectId);
+ auto fileIdStr = QString::number(m_result.fileId);
+ QString metaurl = QString("%1/%2/%3.json").arg(metabase, projectIdStr, fileIdStr);
+ auto dl = Net::Download::makeByteArray(QUrl(metaurl), &results);
+ m_dljob->addNetAction(dl);
+ connect(m_dljob.get(), &NetJob::finished, this, &Flame::UrlResolvingTask::processCursemeta);
+ m_dljob->start();
+}
+
+void Flame::UrlResolvingTask::processCursemeta()
+{
+ try {
+ if(m_result.parseFromBytes(results)) {
+ emitSucceeded();
+ qDebug() << results;
+ return;
+ }
+ } catch (const JSONValidationError &e) {
+
+ qCritical() << "Resolving of" << m_result.projectId << m_result.fileId << "failed because of a parsing error:";
+ qCritical() << e.cause();
+ qCritical() << "JSON:";
+ qCritical() << results;
+ }
+ emitFailed(tr("Failed to resolve the modpack file."));
+}
diff --git a/api/logic/modplatform/flame/UrlResolvingTask.h b/api/logic/modplatform/flame/UrlResolvingTask.h
index 72f3dce1..98b78f67 100644
--- a/api/logic/modplatform/flame/UrlResolvingTask.h
+++ b/api/logic/modplatform/flame/UrlResolvingTask.h
@@ -26,7 +26,11 @@ protected:
protected slots:
void processCCIP();
void processHTML();
- void netJobFinished();
+ void processCursemeta();
+
+private:
+ void resolveUrl();
+ void resolveIDs();
private: /* data */
QString m_url;
@@ -34,7 +38,6 @@ private: /* data */
Flame::File m_result;
QByteArray results;
NetJobPtr m_dljob;
- bool weAreDigging = false;
};
}
diff --git a/application/pages/modplatform/TwitchPage.cpp b/application/pages/modplatform/TwitchPage.cpp
index 2f138b94..52d87fa4 100644
--- a/application/pages/modplatform/TwitchPage.cpp
+++ b/application/pages/modplatform/TwitchPage.cpp
@@ -3,6 +3,7 @@
#include "MultiMC.h"
#include "dialogs/NewInstanceDialog.h"
+#include <InstanceImportTask.h>
TwitchPage::TwitchPage(NewInstanceDialog* dialog, QWidget *parent)
: QWidget(parent), ui(new Ui::TwitchPage), dialog(dialog)
@@ -42,6 +43,13 @@ void TwitchPage::checkDone()
{
auto result = m_modIdResolver->getResults();
auto formatted = QString("Project %1, File %2").arg(result.projectId).arg(result.fileId);
- ui->twitchLabel->setText(formatted);
+ if(result.resolved && result.type == Flame::File::Type::Modpack) {
+ ui->twitchLabel->setText(formatted);
+ QFileInfo fi(result.fileName);
+ dialog->setSuggestedPack(fi.completeBaseName(), new InstanceImportTask(result.url));
+ } else {
+ ui->twitchLabel->setPixmap(QPixmap(QString::fromUtf8(":/assets/deadglitch")));
+ dialog->setSuggestedPack();
+ }
m_modIdResolver.reset();
}