diff options
author | Petr Mrázek <peterix@gmail.com> | 2019-06-27 03:20:11 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2019-06-27 03:20:11 +0200 |
commit | fde43c993e0a143b9dddcaff2190c91f4e5e3cb9 (patch) | |
tree | f1a97f55cc655e68c11660290eb9e0460a0ae96f /api | |
parent | 917f148fc41db7d68ef94c8ea29cd417a8f1ff33 (diff) | |
download | MultiMC-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')
-rw-r--r-- | api/logic/CMakeLists.txt | 2 | ||||
-rw-r--r-- | api/logic/modplatform/flame/UrlResolvingTask.cpp | 140 | ||||
-rw-r--r-- | api/logic/modplatform/flame/UrlResolvingTask.h | 40 |
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; +}; +} + |