summaryrefslogtreecommitdiffstats
path: root/api/logic
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2019-06-27 03:20:11 +0200
committerPetr Mrázek <peterix@gmail.com>2019-06-27 03:20:11 +0200
commitfde43c993e0a143b9dddcaff2190c91f4e5e3cb9 (patch)
treef1a97f55cc655e68c11660290eb9e0460a0ae96f /api/logic
parent917f148fc41db7d68ef94c8ea29cd417a8f1ff33 (diff)
downloadMultiMC-fde43c993e0a143b9dddcaff2190c91f4e5e3cb9.tar
MultiMC-fde43c993e0a143b9dddcaff2190c91f4e5e3cb9.tar.gz
MultiMC-fde43c993e0a143b9dddcaff2190c91f4e5e3cb9.tar.lz
MultiMC-fde43c993e0a143b9dddcaff2190c91f4e5e3cb9.tar.xz
MultiMC-fde43c993e0a143b9dddcaff2190c91f4e5e3cb9.zip
NOISSUE add silly twitch URL and CCIP resolving page to 'add instance'
It needs a few more steps and it will handle all kinds of twitch packs.
Diffstat (limited to 'api/logic')
-rw-r--r--api/logic/CMakeLists.txt2
-rw-r--r--api/logic/modplatform/flame/UrlResolvingTask.cpp140
-rw-r--r--api/logic/modplatform/flame/UrlResolvingTask.h40
3 files changed, 182 insertions, 0 deletions
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt
index 94da2682..1f795556 100644
--- a/api/logic/CMakeLists.txt
+++ b/api/logic/CMakeLists.txt
@@ -443,6 +443,8 @@ set(FLAME_SOURCES
modplatform/flame/PackManifest.cpp
modplatform/flame/FileResolvingTask.h
modplatform/flame/FileResolvingTask.cpp
+ modplatform/flame/UrlResolvingTask.h
+ modplatform/flame/UrlResolvingTask.cpp
)
add_unit_test(Index
diff --git a/api/logic/modplatform/flame/UrlResolvingTask.cpp b/api/logic/modplatform/flame/UrlResolvingTask.cpp
new file mode 100644
index 00000000..068b6a34
--- /dev/null
+++ b/api/logic/modplatform/flame/UrlResolvingTask.cpp
@@ -0,0 +1,140 @@
+#include "UrlResolvingTask.h"
+#include <QtXml>
+
+/*
+namespace {
+const char * metabase = "https://cursemeta.dries007.net";
+}
+*/
+
+Flame::UrlResolvingTask::UrlResolvingTask(const QString& toProcess)
+ : m_url(toProcess)
+{
+}
+
+void Flame::UrlResolvingTask::executeTask()
+{
+ setStatus(tr("Resolving URL..."));
+ setProgress(0, 1);
+ m_dljob.reset(new NetJob("URL resolver"));
+
+ weAreDigging = false;
+ needle = QString();
+
+ if(m_url.startsWith("https://")) {
+ if(m_url.endsWith("?client=y")) {
+ // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download?client=y
+ // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088?client=y
+ m_url.chop(9);
+ // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download
+ // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088
+ }
+ if(m_url.endsWith("/download")) {
+ // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download -> need to dig inside html...
+ weAreDigging = true;
+ needle = m_url;
+ needle.replace("https://", "twitch://");
+ needle.replace("/download", "/download-client/");
+ m_url.append("?client=y");
+ } else if (m_url.contains("/download/")) {
+ // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download/2697088
+ m_url.replace("/download/", "/download-client/");
+ }
+ }
+ else if(m_url.startsWith("twitch://")) {
+ // twitch://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088
+ m_url.replace(0, 9, "https://");
+ // https://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088
+ }
+ 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();
+ } else {
+ processCCIP();
+ }
+}
+
+void Flame::UrlResolvingTask::processHTML()
+{
+ QString htmlDoc = QString::fromUtf8(results);
+ auto index = htmlDoc.indexOf(needle);
+ if(index < 0) {
+ emitFailed(tr("Couldn't find the needle in the haystack..."));
+ return;
+ }
+ auto indexStart = index;
+ int indexEnd = -1;
+ while((index + 1) < htmlDoc.size() && htmlDoc[index] != '"') {
+ index ++;
+ if(htmlDoc[index] == '"') {
+ indexEnd = index;
+ break;
+ }
+ }
+ if(indexEnd > 0) {
+ QString found = htmlDoc.mid(indexStart, indexEnd - indexStart);
+ qDebug() << "Found needle: " << found;
+ // twitch://www.curseforge.com/minecraft/modpacks/ftb-sky-odyssey/download-client/2697088
+ m_url = found;
+ executeTask();
+ return;
+ }
+ emitFailed(tr("Couldn't find the end of the needle in the haystack..."));
+ return;
+}
+
+void Flame::UrlResolvingTask::processCCIP()
+{
+ QDomDocument doc;
+ if (!doc.setContent(results)) {
+ qDebug() << results;
+ emitFailed(tr("Resolving failed."));
+ return;
+ }
+ auto packageNode = doc.namedItem("package");
+ if(!packageNode.isElement()) {
+ emitFailed(tr("Resolving failed: missing package root element."));
+ return;
+ }
+ auto projectNode = packageNode.namedItem("project");
+ if(!projectNode.isElement()) {
+ emitFailed(tr("Resolving failed: missing project element."));
+ return;
+ }
+ auto attribs = projectNode.attributes();
+
+ auto projectIdNode = attribs.namedItem("id");
+ if(!projectIdNode.isAttr()) {
+ emitFailed(tr("Resolving failed: missing id attribute."));
+ return;
+ }
+ auto fileIdNode = attribs.namedItem("file");
+ if(!fileIdNode.isAttr()) {
+ emitFailed(tr("Resolving failed: missing file attribute."));
+ return;
+ }
+
+ auto projectId = projectIdNode.nodeValue();
+ auto fileId = fileIdNode.nodeValue();
+ bool success = true;
+ m_result.projectId = projectId.toInt(&success);
+ if(!success) {
+ emitFailed(tr("Failed to resove projectId as a number."));
+ return;
+ }
+ m_result.fileId = fileId.toInt(&success);
+ if(!success) {
+ emitFailed(tr("Failed to resove fileId as a number."));
+ return;
+ }
+ qDebug() << "Resolved" << m_url << "as" << m_result.projectId << "/" << m_result.fileId;
+ emitSucceeded();
+}
+
diff --git a/api/logic/modplatform/flame/UrlResolvingTask.h b/api/logic/modplatform/flame/UrlResolvingTask.h
new file mode 100644
index 00000000..72f3dce1
--- /dev/null
+++ b/api/logic/modplatform/flame/UrlResolvingTask.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "tasks/Task.h"
+#include "net/NetJob.h"
+#include "PackManifest.h"
+
+#include "multimc_logic_export.h"
+
+namespace Flame
+{
+class MULTIMC_LOGIC_EXPORT UrlResolvingTask : public Task
+{
+ Q_OBJECT
+public:
+ explicit UrlResolvingTask(const QString &toProcess);
+ virtual ~UrlResolvingTask() {};
+
+ const Flame::File &getResults() const
+ {
+ return m_result;
+ }
+
+protected:
+ virtual void executeTask() override;
+
+protected slots:
+ void processCCIP();
+ void processHTML();
+ void netJobFinished();
+
+private: /* data */
+ QString m_url;
+ QString needle;
+ Flame::File m_result;
+ QByteArray results;
+ NetJobPtr m_dljob;
+ bool weAreDigging = false;
+};
+}
+