aboutsummaryrefslogtreecommitdiff
path: root/api/logic/modplatform
diff options
context:
space:
mode:
Diffstat (limited to 'api/logic/modplatform')
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackIndex.cpp33
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackIndex.h36
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp764
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackInstallTask.h102
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackManifest.cpp218
-rw-r--r--api/logic/modplatform/atlauncher/ATLPackManifest.h126
-rw-r--r--api/logic/modplatform/flame/FileResolvingTask.cpp63
-rw-r--r--api/logic/modplatform/flame/FileResolvingTask.h34
-rw-r--r--api/logic/modplatform/flame/FlamePackIndex.cpp92
-rw-r--r--api/logic/modplatform/flame/FlamePackIndex.h43
-rw-r--r--api/logic/modplatform/flame/PackManifest.cpp126
-rw-r--r--api/logic/modplatform/flame/PackManifest.h62
-rw-r--r--api/logic/modplatform/legacy_ftb/PackFetchTask.cpp172
-rw-r--r--api/logic/modplatform/legacy_ftb/PackFetchTask.h44
-rw-r--r--api/logic/modplatform/legacy_ftb/PackHelpers.h45
-rw-r--r--api/logic/modplatform/legacy_ftb/PackInstallTask.cpp214
-rw-r--r--api/logic/modplatform/legacy_ftb/PackInstallTask.h55
-rw-r--r--api/logic/modplatform/legacy_ftb/PrivatePackManager.cpp41
-rw-r--r--api/logic/modplatform/legacy_ftb/PrivatePackManager.h44
-rw-r--r--api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp209
-rw-r--r--api/logic/modplatform/modpacksch/FTBPackInstallTask.h47
-rw-r--r--api/logic/modplatform/modpacksch/FTBPackManifest.cpp156
-rw-r--r--api/logic/modplatform/modpacksch/FTBPackManifest.h127
-rw-r--r--api/logic/modplatform/technic/SingleZipPackInstallTask.cpp141
-rw-r--r--api/logic/modplatform/technic/SingleZipPackInstallTask.h65
-rw-r--r--api/logic/modplatform/technic/SolderPackInstallTask.cpp207
-rw-r--r--api/logic/modplatform/technic/SolderPackInstallTask.h60
-rw-r--r--api/logic/modplatform/technic/TechnicPackProcessor.cpp208
-rw-r--r--api/logic/modplatform/technic/TechnicPackProcessor.h35
29 files changed, 0 insertions, 3569 deletions
diff --git a/api/logic/modplatform/atlauncher/ATLPackIndex.cpp b/api/logic/modplatform/atlauncher/ATLPackIndex.cpp
deleted file mode 100644
index 35f50b18..00000000
--- a/api/logic/modplatform/atlauncher/ATLPackIndex.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "ATLPackIndex.h"
-
-#include <QRegularExpression>
-
-#include "Json.h"
-
-static void loadIndexedVersion(ATLauncher::IndexedVersion & v, QJsonObject & obj)
-{
- v.version = Json::requireString(obj, "version");
- v.minecraft = Json::requireString(obj, "minecraft");
-}
-
-void ATLauncher::loadIndexedPack(ATLauncher::IndexedPack & m, QJsonObject & obj)
-{
- m.id = Json::requireInteger(obj, "id");
- m.position = Json::requireInteger(obj, "position");
- m.name = Json::requireString(obj, "name");
- m.type = Json::requireString(obj, "type") == "private" ?
- ATLauncher::PackType::Private :
- ATLauncher::PackType::Public;
- auto versionsArr = Json::requireArray(obj, "versions");
- for (const auto versionRaw : versionsArr)
- {
- auto versionObj = Json::requireObject(versionRaw);
- ATLauncher::IndexedVersion version;
- loadIndexedVersion(version, versionObj);
- m.versions.append(version);
- }
- m.system = Json::ensureBoolean(obj, QString("system"), false);
- m.description = Json::ensureString(obj, "description", "");
-
- m.safeName = Json::requireString(obj, "name").replace(QRegularExpression("[^A-Za-z0-9]"), "");
-}
diff --git a/api/logic/modplatform/atlauncher/ATLPackIndex.h b/api/logic/modplatform/atlauncher/ATLPackIndex.h
deleted file mode 100644
index 5e2e6487..00000000
--- a/api/logic/modplatform/atlauncher/ATLPackIndex.h
+++ /dev/null
@@ -1,36 +0,0 @@
-#pragma once
-
-#include "ATLPackManifest.h"
-
-#include <QString>
-#include <QVector>
-#include <QMetaType>
-
-#include "multimc_logic_export.h"
-
-namespace ATLauncher
-{
-
-struct IndexedVersion
-{
- QString version;
- QString minecraft;
-};
-
-struct IndexedPack
-{
- int id;
- int position;
- QString name;
- PackType type;
- QVector<IndexedVersion> versions;
- bool system;
- QString description;
-
- QString safeName;
-};
-
-MULTIMC_LOGIC_EXPORT void loadIndexedPack(IndexedPack & m, QJsonObject & obj);
-}
-
-Q_DECLARE_METATYPE(ATLauncher::IndexedPack)
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp b/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
deleted file mode 100644
index 55087a27..00000000
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.cpp
+++ /dev/null
@@ -1,764 +0,0 @@
-#include <Env.h>
-#include <quazip.h>
-#include <QtConcurrent/QtConcurrent>
-#include <MMCZip.h>
-#include <minecraft/OneSixVersionFormat.h>
-#include <Version.h>
-#include <net/ChecksumValidator.h>
-#include "ATLPackInstallTask.h"
-
-#include "BuildConfig.h"
-#include "FileSystem.h"
-#include "Json.h"
-#include "minecraft/MinecraftInstance.h"
-#include "minecraft/PackProfile.h"
-#include "settings/INISettingsObject.h"
-#include "meta/Index.h"
-#include "meta/Version.h"
-#include "meta/VersionList.h"
-
-namespace ATLauncher {
-
-PackInstallTask::PackInstallTask(UserInteractionSupport *support, QString pack, QString version)
-{
- m_support = support;
- m_pack = pack;
- m_version_name = version;
-}
-
-bool PackInstallTask::abort()
-{
- if(abortable)
- {
- return jobPtr->abort();
- }
- return false;
-}
-
-void PackInstallTask::executeTask()
-{
- qDebug() << "PackInstallTask::executeTask: " << QThread::currentThreadId();
- auto *netJob = new NetJob("ATLauncher::VersionFetch");
- auto searchUrl = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.json")
- .arg(m_pack).arg(m_version_name);
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
- jobPtr = netJob;
- jobPtr->start();
-
- QObject::connect(netJob, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
- QObject::connect(netJob, &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
-}
-
-void PackInstallTask::onDownloadSucceeded()
-{
- qDebug() << "PackInstallTask::onDownloadSucceeded: " << QThread::currentThreadId();
- jobPtr.reset();
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- auto obj = doc.object();
-
- ATLauncher::PackVersion version;
- try
- {
- ATLauncher::loadVersion(version, obj);
- }
- catch (const JSONValidationError &e)
- {
- emitFailed(tr("Could not understand pack manifest:\n") + e.cause());
- return;
- }
- m_version = version;
-
- auto vlist = ENV.metadataIndex()->get("net.minecraft");
- if(!vlist)
- {
- emitFailed(tr("Failed to get local metadata index for %1").arg("net.minecraft"));
- return;
- }
-
- auto ver = vlist->getVersion(m_version.minecraft);
- if (!ver) {
- emitFailed(tr("Failed to get local metadata index for '%1' v%2").arg("net.minecraft").arg(m_version.minecraft));
- return;
- }
- ver->load(Net::Mode::Online);
- minecraftVersion = ver;
-
- if(m_version.noConfigs) {
- downloadMods();
- }
- else {
- installConfigs();
- }
-}
-
-void PackInstallTask::onDownloadFailed(QString reason)
-{
- qDebug() << "PackInstallTask::onDownloadFailed: " << QThread::currentThreadId();
- jobPtr.reset();
- emitFailed(reason);
-}
-
-QString PackInstallTask::getDirForModType(ModType type, QString raw)
-{
- switch (type) {
- // Mod types that can either be ignored at this stage, or ignored
- // completely.
- case ModType::Root:
- case ModType::Extract:
- case ModType::Decomp:
- case ModType::TexturePackExtract:
- case ModType::ResourcePackExtract:
- case ModType::MCPC:
- return Q_NULLPTR;
- case ModType::Forge:
- // Forge detection happens later on, if it cannot be detected it will
- // install a jarmod component.
- case ModType::Jar:
- return "jarmods";
- case ModType::Mods:
- return "mods";
- case ModType::Flan:
- return "Flan";
- case ModType::Dependency:
- return FS::PathCombine("mods", m_version.minecraft);
- case ModType::Ic2Lib:
- return FS::PathCombine("mods", "ic2");
- case ModType::DenLib:
- return FS::PathCombine("mods", "denlib");
- case ModType::Coremods:
- return "coremods";
- case ModType::Plugins:
- return "plugins";
- case ModType::TexturePack:
- return "texturepacks";
- case ModType::ResourcePack:
- return "resourcepacks";
- case ModType::ShaderPack:
- return "shaderpacks";
- case ModType::Millenaire:
- qWarning() << "Unsupported mod type: " + raw;
- return Q_NULLPTR;
- case ModType::Unknown:
- emitFailed(tr("Unknown mod type: %1").arg(raw));
- return Q_NULLPTR;
- }
-
- return Q_NULLPTR;
-}
-
-QString PackInstallTask::getVersionForLoader(QString uid)
-{
- if(m_version.loader.recommended || m_version.loader.latest || m_version.loader.choose) {
- auto vlist = ENV.metadataIndex()->get(uid);
- if(!vlist)
- {
- emitFailed(tr("Failed to get local metadata index for %1").arg(uid));
- return Q_NULLPTR;
- }
-
- if(!vlist->isLoaded()) {
- vlist->load(Net::Mode::Online);
- }
-
- if(m_version.loader.recommended || m_version.loader.latest) {
- for (int i = 0; i < vlist->versions().size(); i++) {
- auto version = vlist->versions().at(i);
- auto reqs = version->requires();
-
- // filter by minecraft version, if the loader depends on a certain version.
- // not all mod loaders depend on a given Minecraft version, so we won't do this
- // filtering for those loaders.
- if (m_version.loader.type != "fabric") {
- auto iter = std::find_if(reqs.begin(), reqs.end(), [](const Meta::Require &req) {
- return req.uid == "net.minecraft";
- });
- if (iter == reqs.end()) continue;
- if (iter->equalsVersion != m_version.minecraft) continue;
- }
-
- if (m_version.loader.recommended) {
- // first recommended build we find, we use.
- if (!version->isRecommended()) continue;
- }
-
- return version->descriptor();
- }
-
- emitFailed(tr("Failed to find version for %1 loader").arg(m_version.loader.type));
- return Q_NULLPTR;
- }
- else if(m_version.loader.choose) {
- // Fabric Loader doesn't depend on a given Minecraft version.
- if (m_version.loader.type == "fabric") {
- return m_support->chooseVersion(vlist, Q_NULLPTR);
- }
-
- return m_support->chooseVersion(vlist, m_version.minecraft);
- }
- }
-
- if (m_version.loader.version == Q_NULLPTR || m_version.loader.version.isEmpty()) {
- emitFailed(tr("No loader version set for modpack!"));
- return Q_NULLPTR;
- }
-
- return m_version.loader.version;
-}
-
-QString PackInstallTask::detectLibrary(VersionLibrary library)
-{
- // Try to detect what the library is
- if (!library.server.isEmpty() && library.server.split("/").length() >= 3) {
- auto lastSlash = library.server.lastIndexOf("/");
- auto locationAndVersion = library.server.mid(0, lastSlash);
- auto fileName = library.server.mid(lastSlash + 1);
-
- lastSlash = locationAndVersion.lastIndexOf("/");
- auto location = locationAndVersion.mid(0, lastSlash);
- auto version = locationAndVersion.mid(lastSlash + 1);
-
- lastSlash = location.lastIndexOf("/");
- auto group = location.mid(0, lastSlash).replace("/", ".");
- auto artefact = location.mid(lastSlash + 1);
-
- return group + ":" + artefact + ":" + version;
- }
-
- if(library.file.contains("-")) {
- auto lastSlash = library.file.lastIndexOf("-");
- auto name = library.file.mid(0, lastSlash);
- auto version = library.file.mid(lastSlash + 1).remove(".jar");
-
- if(name == QString("guava")) {
- return "com.google.guava:guava:" + version;
- }
- else if(name == QString("commons-lang3")) {
- return "org.apache.commons:commons-lang3:" + version;
- }
- }
-
- return "org.multimc.atlauncher:" + library.md5 + ":1";
-}
-
-bool PackInstallTask::createLibrariesComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile)
-{
- if(m_version.libraries.isEmpty()) {
- return true;
- }
-
- QList<GradleSpecifier> exempt;
- for(const auto & componentUid : componentsToInstall.keys()) {
- auto componentVersion = componentsToInstall.value(componentUid);
-
- for(const auto & library : componentVersion->data()->libraries) {
- GradleSpecifier lib(library->rawName());
- exempt.append(lib);
- }
- }
-
- {
- for(const auto & library : minecraftVersion->data()->libraries) {
- GradleSpecifier lib(library->rawName());
- exempt.append(lib);
- }
- }
-
- auto uuid = QUuid::createUuid();
- auto id = uuid.toString().remove('{').remove('}');
- auto target_id = "org.multimc.atlauncher." + id;
-
- auto patchDir = FS::PathCombine(instanceRoot, "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
- auto patchFileName = FS::PathCombine(patchDir, target_id + ".json");
-
- auto f = std::make_shared<VersionFile>();
- f->name = m_pack + " " + m_version_name + " (libraries)";
-
- for(const auto & lib : m_version.libraries) {
- auto libName = detectLibrary(lib);
- GradleSpecifier libSpecifier(libName);
-
- bool libExempt = false;
- for(const auto & existingLib : exempt) {
- if(libSpecifier.matchName(existingLib)) {
- // If the pack specifies a newer version of the lib, use that!
- libExempt = Version(libSpecifier.version()) >= Version(existingLib.version());
- }
- }
- if(libExempt) continue;
-
- auto library = std::make_shared<Library>();
- library->setRawName(libName);
-
- switch(lib.download) {
- case DownloadType::Server:
- library->setAbsoluteUrl(BuildConfig.ATL_DOWNLOAD_SERVER_URL + lib.url);
- break;
- case DownloadType::Direct:
- library->setAbsoluteUrl(lib.url);
- break;
- case DownloadType::Browser:
- case DownloadType::Unknown:
- emitFailed(tr("Unknown or unsupported download type: %1").arg(lib.download_raw));
- return false;
- }
-
- f->libraries.append(library);
- }
-
- if(f->libraries.isEmpty()) {
- return true;
- }
-
- QFile file(patchFileName);
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
- file.close();
-
- profile->appendComponent(new Component(profile.get(), target_id, f));
- return true;
-}
-
-bool PackInstallTask::createPackComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile)
-{
- if(m_version.mainClass == QString() && m_version.extraArguments == QString()) {
- return true;
- }
-
- auto uuid = QUuid::createUuid();
- auto id = uuid.toString().remove('{').remove('}');
- auto target_id = "org.multimc.atlauncher." + id;
-
- auto patchDir = FS::PathCombine(instanceRoot, "patches");
- if(!FS::ensureFolderPathExists(patchDir))
- {
- return false;
- }
- auto patchFileName = FS::PathCombine(patchDir, target_id + ".json");
-
- QStringList mainClasses;
- QStringList tweakers;
- for(const auto & componentUid : componentsToInstall.keys()) {
- auto componentVersion = componentsToInstall.value(componentUid);
-
- if(componentVersion->data()->mainClass != QString("")) {
- mainClasses.append(componentVersion->data()->mainClass);
- }
- tweakers.append(componentVersion->data()->addTweakers);
- }
-
- auto f = std::make_shared<VersionFile>();
- f->name = m_pack + " " + m_version_name;
- if(m_version.mainClass != QString() && !mainClasses.contains(m_version.mainClass)) {
- f->mainClass = m_version.mainClass;
- }
-
- // Parse out tweakers
- auto args = m_version.extraArguments.split(" ");
- QString previous;
- for(auto arg : args) {
- if(arg.startsWith("--tweakClass=") || previous == "--tweakClass") {
- auto tweakClass = arg.remove("--tweakClass=");
- if(tweakers.contains(tweakClass)) continue;
-
- f->addTweakers.append(tweakClass);
- }
- previous = arg;
- }
-
- if(f->mainClass == QString() && f->addTweakers.isEmpty()) {
- return true;
- }
-
- QFile file(patchFileName);
- if (!file.open(QFile::WriteOnly))
- {
- qCritical() << "Error opening" << file.fileName()
- << "for reading:" << file.errorString();
- return false;
- }
- file.write(OneSixVersionFormat::versionFileToJson(f).toJson());
- file.close();
-
- profile->appendComponent(new Component(profile.get(), target_id, f));
- return true;
-}
-
-void PackInstallTask::installConfigs()
-{
- qDebug() << "PackInstallTask::installConfigs: " << QThread::currentThreadId();
- setStatus(tr("Downloading configs..."));
- jobPtr.reset(new NetJob(tr("Config download")));
-
- auto path = QString("Configs/%1/%2.zip").arg(m_pack).arg(m_version_name);
- auto url = QString(BuildConfig.ATL_DOWNLOAD_SERVER_URL + "packs/%1/versions/%2/Configs.zip")
- .arg(m_pack).arg(m_version_name);
- auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", path);
- entry->setStale(true);
-
- auto dl = Net::Download::makeCached(url, entry);
- if (!m_version.configs.sha1.isEmpty()) {
- auto rawSha1 = QByteArray::fromHex(m_version.configs.sha1.toLatin1());
- dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
- }
- jobPtr->addNetAction(dl);
- archivePath = entry->getFullPath();
-
- connect(jobPtr.get(), &NetJob::succeeded, this, [&]()
- {
- abortable = false;
- jobPtr.reset();
- extractConfigs();
- });
- connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
- {
- abortable = false;
- jobPtr.reset();
- emitFailed(reason);
- });
- connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total)
- {
- abortable = true;
- setProgress(current, total);
- });
-
- jobPtr->start();
-}
-
-void PackInstallTask::extractConfigs()
-{
- qDebug() << "PackInstallTask::extractConfigs: " << QThread::currentThreadId();
- setStatus(tr("Extracting configs..."));
-
- QDir extractDir(m_stagingPath);
-
- QuaZip packZip(archivePath);
- if(!packZip.open(QuaZip::mdUnzip))
- {
- emitFailed(tr("Failed to open pack configs %1!").arg(archivePath));
- return;
- }
-
- m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/minecraft");
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, [&]()
- {
- downloadMods();
- });
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
- {
- emitAborted();
- });
- m_extractFutureWatcher.setFuture(m_extractFuture);
-}
-
-void PackInstallTask::downloadMods()
-{
- qDebug() << "PackInstallTask::installMods: " << QThread::currentThreadId();
-
- QVector<ATLauncher::VersionMod> optionalMods;
- for (const auto& mod : m_version.mods) {
- if (mod.optional) {
- optionalMods.push_back(mod);
- }
- }
-
- // Select optional mods, if pack contains any
- QVector<QString> selectedMods;
- if (!optionalMods.isEmpty()) {
- setStatus(tr("Selecting optional mods..."));
- selectedMods = m_support->chooseOptionalMods(optionalMods);
- }
-
- setStatus(tr("Downloading mods..."));
-
- jarmods.clear();
- jobPtr.reset(new NetJob(tr("Mod download")));
- for(const auto& mod : m_version.mods) {
- // skip non-client mods
- if(!mod.client) continue;
-
- // skip optional mods that were not selected
- if(mod.optional && !selectedMods.contains(mod.name)) continue;
-
- QString url;
- switch(mod.download) {
- case DownloadType::Server:
- url = BuildConfig.ATL_DOWNLOAD_SERVER_URL + mod.url;
- break;
- case DownloadType::Browser:
- emitFailed(tr("Unsupported download type: %1").arg(mod.download_raw));
- return;
- case DownloadType::Direct:
- url = mod.url;
- break;
- case DownloadType::Unknown:
- emitFailed(tr("Unknown download type: %1").arg(mod.download_raw));
- return;
- }
-
- QFileInfo fileName(mod.file);
- auto cacheName = fileName.completeBaseName() + "-" + mod.md5 + "." + fileName.suffix();
-
- if (mod.type == ModType::Extract || mod.type == ModType::TexturePackExtract || mod.type == ModType::ResourcePackExtract) {
- auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName);
- entry->setStale(true);
- modsToExtract.insert(entry->getFullPath(), mod);
-
- auto dl = Net::Download::makeCached(url, entry);
- if (!mod.md5.isEmpty()) {
- auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
- dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
- }
- jobPtr->addNetAction(dl);
- }
- else if(mod.type == ModType::Decomp) {
- auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName);
- entry->setStale(true);
- modsToDecomp.insert(entry->getFullPath(), mod);
-
- auto dl = Net::Download::makeCached(url, entry);
- if (!mod.md5.isEmpty()) {
- auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
- dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
- }
- jobPtr->addNetAction(dl);
- }
- else {
- auto relpath = getDirForModType(mod.type, mod.type_raw);
- if(relpath == Q_NULLPTR) continue;
-
- auto entry = ENV.metacache()->resolveEntry("ATLauncherPacks", cacheName);
- entry->setStale(true);
-
- auto dl = Net::Download::makeCached(url, entry);
- if (!mod.md5.isEmpty()) {
- auto rawMd5 = QByteArray::fromHex(mod.md5.toLatin1());
- dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Md5, rawMd5));
- }
- jobPtr->addNetAction(dl);
-
- auto path = FS::PathCombine(m_stagingPath, "minecraft", relpath, mod.file);
- qDebug() << "Will download" << url << "to" << path;
- modsToCopy[entry->getFullPath()] = path;
-
- if(mod.type == ModType::Forge) {
- auto vlist = ENV.metadataIndex()->get("net.minecraftforge");
- if(vlist)
- {
- auto ver = vlist->getVersion(mod.version);
- if(ver) {
- ver->load(Net::Mode::Online);
- componentsToInstall.insert("net.minecraftforge", ver);
- continue;
- }
- }
-
- qDebug() << "Jarmod: " + path;
- jarmods.push_back(path);
- }
-
- if(mod.type == ModType::Jar) {
- qDebug() << "Jarmod: " + path;
- jarmods.push_back(path);
- }
- }
- }
-
- connect(jobPtr.get(), &NetJob::succeeded, this, &PackInstallTask::onModsDownloaded);
- connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
- {
- abortable = false;
- jobPtr.reset();
- emitFailed(reason);
- });
- connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total)
- {
- abortable = true;
- setProgress(current, total);
- });
-
- jobPtr->start();
-}
-
-void PackInstallTask::onModsDownloaded() {
- abortable = false;
-
- qDebug() << "PackInstallTask::onModsDownloaded: " << QThread::currentThreadId();
- jobPtr.reset();
-
- if(!modsToExtract.empty() || !modsToDecomp.empty() || !modsToCopy.empty()) {
- m_modExtractFuture = QtConcurrent::run(QThreadPool::globalInstance(), this, &PackInstallTask::extractMods, modsToExtract, modsToDecomp, modsToCopy);
- connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onModsExtracted);
- connect(&m_modExtractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, [&]()
- {
- emitAborted();
- });
- m_modExtractFutureWatcher.setFuture(m_modExtractFuture);
- }
- else {
- install();
- }
-}
-
-void PackInstallTask::onModsExtracted() {
- qDebug() << "PackInstallTask::onModsExtracted: " << QThread::currentThreadId();
- if(m_modExtractFuture.result()) {
- install();
- }
- else {
- emitFailed(tr("Failed to extract mods..."));
- }
-}
-
-bool PackInstallTask::extractMods(
- const QMap<QString, VersionMod> &toExtract,
- const QMap<QString, VersionMod> &toDecomp,
- const QMap<QString, QString> &toCopy
-) {
- qDebug() << "PackInstallTask::extractMods: " << QThread::currentThreadId();
-
- setStatus(tr("Extracting mods..."));
- for (auto iter = toExtract.begin(); iter != toExtract.end(); iter++) {
- auto &modPath = iter.key();
- auto &mod = iter.value();
-
- QString extractToDir;
- if(mod.type == ModType::Extract) {
- extractToDir = getDirForModType(mod.extractTo, mod.extractTo_raw);
- }
- else if(mod.type == ModType::TexturePackExtract) {
- extractToDir = FS::PathCombine("texturepacks", "extracted");
- }
- else if(mod.type == ModType::ResourcePackExtract) {
- extractToDir = FS::PathCombine("resourcepacks", "extracted");
- }
-
- QDir extractDir(m_stagingPath);
- auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir);
-
- QString folderToExtract = "";
- if(mod.type == ModType::Extract) {
- folderToExtract = mod.extractFolder;
- folderToExtract.remove(QRegExp("^/"));
- }
-
- qDebug() << "Extracting " + mod.file + " to " + extractToDir;
- if(!MMCZip::extractDir(modPath, folderToExtract, extractToPath)) {
- // assume error
- return false;
- }
- }
-
- for (auto iter = toDecomp.begin(); iter != toDecomp.end(); iter++) {
- auto &modPath = iter.key();
- auto &mod = iter.value();
- auto extractToDir = getDirForModType(mod.decompType, mod.decompType_raw);
-
- QDir extractDir(m_stagingPath);
- auto extractToPath = FS::PathCombine(extractDir.absolutePath(), "minecraft", extractToDir, mod.decompFile);
-
- qDebug() << "Extracting " + mod.decompFile + " to " + extractToDir;
- if(!MMCZip::extractFile(modPath, mod.decompFile, extractToPath)) {
- qWarning() << "Failed to extract" << mod.decompFile;
- return false;
- }
- }
-
- for (auto iter = toCopy.begin(); iter != toCopy.end(); iter++) {
- auto &from = iter.key();
- auto &to = iter.value();
- FS::copy fileCopyOperation(from, to);
- if(!fileCopyOperation()) {
- qWarning() << "Failed to copy" << from << "to" << to;
- return false;
- }
- }
- return true;
-}
-
-void PackInstallTask::install()
-{
- qDebug() << "PackInstallTask::install: " << QThread::currentThreadId();
- setStatus(tr("Installing modpack"));
-
- auto instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
- auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath);
- instanceSettings->suspendSave();
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
-
- MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
- auto components = instance.getPackProfile();
- components->buildingFromScratch();
-
- // Use a component to add libraries BEFORE Minecraft
- if(!createLibrariesComponent(instance.instanceRoot(), components)) {
- emitFailed(tr("Failed to create libraries component"));
- return;
- }
-
- // Minecraft
- components->setComponentVersion("net.minecraft", m_version.minecraft, true);
-
- // Loader
- if(m_version.loader.type == QString("forge"))
- {
- auto version = getVersionForLoader("net.minecraftforge");
- if(version == Q_NULLPTR) return;
-
- components->setComponentVersion("net.minecraftforge", version, true);
- }
- else if(m_version.loader.type == QString("fabric"))
- {
- auto version = getVersionForLoader("net.fabricmc.fabric-loader");
- if(version == Q_NULLPTR) return;
-
- components->setComponentVersion("net.fabricmc.fabric-loader", version, true);
- }
- else if(m_version.loader.type != QString())
- {
- emitFailed(tr("Unknown loader type: ") + m_version.loader.type);
- return;
- }
-
- for(const auto & componentUid : componentsToInstall.keys()) {
- auto version = componentsToInstall.value(componentUid);
- components->setComponentVersion(componentUid, version->version());
- }
-
- components->installJarMods(jarmods);
-
- // Use a component to fill in the rest of the data
- // todo: use more detection
- if(!createPackComponent(instance.instanceRoot(), components)) {
- emitFailed(tr("Failed to create pack component"));
- return;
- }
-
- components->saveNow();
-
- instance.setName(m_instName);
- instance.setIconKey(m_instIcon);
- instanceSettings->resumeSave();
-
- jarmods.clear();
- emitSucceeded();
-}
-
-}
diff --git a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h b/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
deleted file mode 100644
index 15fd9b32..00000000
--- a/api/logic/modplatform/atlauncher/ATLPackInstallTask.h
+++ /dev/null
@@ -1,102 +0,0 @@
-#pragma once
-
-#include <meta/VersionList.h>
-#include "ATLPackManifest.h"
-
-#include "InstanceTask.h"
-#include "multimc_logic_export.h"
-#include "net/NetJob.h"
-#include "settings/INISettingsObject.h"
-#include "minecraft/MinecraftInstance.h"
-#include "minecraft/PackProfile.h"
-#include "meta/Version.h"
-
-#include <nonstd/optional>
-
-namespace ATLauncher {
-
-class MULTIMC_LOGIC_EXPORT UserInteractionSupport {
-
-public:
- /**
- * Requests a user interaction to select which optional mods should be installed.
- */
- virtual QVector<QString> chooseOptionalMods(QVector<ATLauncher::VersionMod> mods) = 0;
-
- /**
- * Requests a user interaction to select a component version from a given version list
- * and constrained to a given Minecraft version.
- */
- virtual QString chooseVersion(Meta::VersionListPtr vlist, QString minecraftVersion) = 0;
-
-};
-
-class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
-{
-Q_OBJECT
-
-public:
- explicit PackInstallTask(UserInteractionSupport *support, QString pack, QString version);
- virtual ~PackInstallTask(){}
-
- bool canAbort() const override { return true; }
- bool abort() override;
-
-protected:
- virtual void executeTask() override;
-
-private slots:
- void onDownloadSucceeded();
- void onDownloadFailed(QString reason);
-
- void onModsDownloaded();
- void onModsExtracted();
-
-private:
- QString getDirForModType(ModType type, QString raw);
- QString getVersionForLoader(QString uid);
- QString detectLibrary(VersionLibrary library);
-
- bool createLibrariesComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile);
- bool createPackComponent(QString instanceRoot, std::shared_ptr<PackProfile> profile);
-
- void installConfigs();
- void extractConfigs();
- void downloadMods();
- bool extractMods(
- const QMap<QString, VersionMod> &toExtract,
- const QMap<QString, VersionMod> &toDecomp,
- const QMap<QString, QString> &toCopy
- );
- void install();
-
-private:
- UserInteractionSupport *m_support;
-
- bool abortable = false;
-
- NetJobPtr jobPtr;
- QByteArray response;
-
- QString m_pack;
- QString m_version_name;
- PackVersion m_version;
-
- QMap<QString, VersionMod> modsToExtract;
- QMap<QString, VersionMod> modsToDecomp;
- QMap<QString, QString> modsToCopy;
-
- QString archivePath;
- QStringList jarmods;
- Meta::VersionPtr minecraftVersion;
- QMap<QString, Meta::VersionPtr> componentsToInstall;
-
- QFuture<nonstd::optional<QStringList>> m_extractFuture;
- QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
-
- QFuture<bool> m_modExtractFuture;
- QFutureWatcher<bool> m_modExtractFutureWatcher;
-
-};
-
-}
diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp b/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
deleted file mode 100644
index e25d8346..00000000
--- a/api/logic/modplatform/atlauncher/ATLPackManifest.cpp
+++ /dev/null
@@ -1,218 +0,0 @@
-#include "ATLPackManifest.h"
-
-#include "Json.h"
-
-static ATLauncher::DownloadType parseDownloadType(QString rawType) {
- if(rawType == QString("server")) {
- return ATLauncher::DownloadType::Server;
- }
- else if(rawType == QString("browser")) {
- return ATLauncher::DownloadType::Browser;
- }
- else if(rawType == QString("direct")) {
- return ATLauncher::DownloadType::Direct;
- }
-
- return ATLauncher::DownloadType::Unknown;
-}
-
-static ATLauncher::ModType parseModType(QString rawType) {
- // See https://wiki.atlauncher.com/mod_types
- if(rawType == QString("root")) {
- return ATLauncher::ModType::Root;
- }
- else if(rawType == QString("forge")) {
- return ATLauncher::ModType::Forge;
- }
- else if(rawType == QString("jar")) {
- return ATLauncher::ModType::Jar;
- }
- else if(rawType == QString("mods")) {
- return ATLauncher::ModType::Mods;
- }
- else if(rawType == QString("flan")) {
- return ATLauncher::ModType::Flan;
- }
- else if(rawType == QString("dependency") || rawType == QString("depandency")) {
- return ATLauncher::ModType::Dependency;
- }
- else if(rawType == QString("ic2lib")) {
- return ATLauncher::ModType::Ic2Lib;
- }
- else if(rawType == QString("denlib")) {
- return ATLauncher::ModType::DenLib;
- }
- else if(rawType == QString("coremods")) {
- return ATLauncher::ModType::Coremods;
- }
- else if(rawType == QString("mcpc")) {
- return ATLauncher::ModType::MCPC;
- }
- else if(rawType == QString("plugins")) {
- return ATLauncher::ModType::Plugins;
- }
- else if(rawType == QString("extract")) {
- return ATLauncher::ModType::Extract;
- }
- else if(rawType == QString("decomp")) {
- return ATLauncher::ModType::Decomp;
- }
- else if(rawType == QString("texturepack")) {
- return ATLauncher::ModType::TexturePack;
- }
- else if(rawType == QString("resourcepack")) {
- return ATLauncher::ModType::ResourcePack;
- }
- else if(rawType == QString("shaderpack")) {
- return ATLauncher::ModType::ShaderPack;
- }
- else if(rawType == QString("texturepackextract")) {
- return ATLauncher::ModType::TexturePackExtract;
- }
- else if(rawType == QString("resourcepackextract")) {
- return ATLauncher::ModType::ResourcePackExtract;
- }
- else if(rawType == QString("millenaire")) {
- return ATLauncher::ModType::Millenaire;
- }
-
- return ATLauncher::ModType::Unknown;
-}
-
-static void loadVersionLoader(ATLauncher::VersionLoader & p, QJsonObject & obj) {
- p.type = Json::requireString(obj, "type");
- p.choose = Json::ensureBoolean(obj, QString("choose"), false);
-
- auto metadata = Json::requireObject(obj, "metadata");
- p.latest = Json::ensureBoolean(metadata, QString("latest"), false);
- p.recommended = Json::ensureBoolean(metadata, QString("recommended"), false);
-
- // Minecraft Forge
- if (p.type == "forge") {
- p.version = Json::ensureString(metadata, "version", "");
- }
-
- // Fabric Loader
- if (p.type == "fabric") {
- p.version = Json::ensureString(metadata, "loader", "");
- }
-}
-
-static void loadVersionLibrary(ATLauncher::VersionLibrary & p, QJsonObject & obj) {
- p.url = Json::requireString(obj, "url");
- p.file = Json::requireString(obj, "file");
- p.md5 = Json::requireString(obj, "md5");
-
- p.download_raw = Json::requireString(obj, "download");
- p.download = parseDownloadType(p.download_raw);
-
- p.server = Json::ensureString(obj, "server", "");
-}
-
-static void loadVersionConfigs(ATLauncher::VersionConfigs & p, QJsonObject & obj) {
- p.filesize = Json::requireInteger(obj, "filesize");
- p.sha1 = Json::requireString(obj, "sha1");
-}
-
-static void loadVersionMod(ATLauncher::VersionMod & p, QJsonObject & obj) {
- p.name = Json::requireString(obj, "name");
- p.version = Json::requireString(obj, "version");
- p.url = Json::requireString(obj, "url");
- p.file = Json::requireString(obj, "file");
- p.md5 = Json::ensureString(obj, "md5", "");
-
- p.download_raw = Json::requireString(obj, "download");
- p.download = parseDownloadType(p.download_raw);
-
- p.type_raw = Json::requireString(obj, "type");
- p.type = parseModType(p.type_raw);
-
- // This contributes to the Minecraft Forge detection, where we rely on mod.type being "Forge"
- // when the mod represents Forge. As there is little difference between "Jar" and "Forge, some
- // packs regretfully use "Jar". This will correct the type to "Forge" in these cases (as best
- // it can).
- if(p.name == QString("Minecraft Forge") && p.type == ATLauncher::ModType::Jar) {
- p.type_raw = "forge";
- p.type = ATLauncher::ModType::Forge;
- }
-
- if(obj.contains("extractTo")) {
- p.extractTo_raw = Json::requireString(obj, "extractTo");
- p.extractTo = parseModType(p.extractTo_raw);
- p.extractFolder = Json::ensureString(obj, "extractFolder", "").replace("%s%", "/");
- }
-
- if(obj.contains("decompType")) {
- p.decompType_raw = Json::requireString(obj, "decompType");
- p.decompType = parseModType(p.decompType_raw);
- p.decompFile = Json::requireString(obj, "decompFile");
- }
-
- p.description = Json::ensureString(obj, QString("description"), "");
- p.optional = Json::ensureBoolean(obj, QString("optional"), false);
- p.recommended = Json::ensureBoolean(obj, QString("recommended"), false);
- p.selected = Json::ensureBoolean(obj, QString("selected"), false);
- p.hidden = Json::ensureBoolean(obj, QString("hidden"), false);
- p.library = Json::ensureBoolean(obj, QString("library"), false);
- p.group = Json::ensureString(obj, QString("group"), "");
- if(obj.contains("depends")) {
- auto dependsArr = Json::requireArray(obj, "depends");
- for (const auto depends : dependsArr) {
- p.depends.append(Json::requireString(depends));
- }
- }
-
- p.client = Json::ensureBoolean(obj, QString("client"), false);
-
- // computed
- p.effectively_hidden = p.hidden || p.library;
-}
-
-void ATLauncher::loadVersion(PackVersion & v, QJsonObject & obj)
-{
- v.version = Json::requireString(obj, "version");
- v.minecraft = Json::requireString(obj, "minecraft");
- v.noConfigs = Json::ensureBoolean(obj, QString("noConfigs"), false);
-
- if(obj.contains("mainClass")) {
- auto main = Json::requireObject(obj, "mainClass");
- v.mainClass = Json::ensureString(main, "mainClass", "");
- }
-
- if(obj.contains("extraArguments")) {
- auto arguments = Json::requireObject(obj, "extraArguments");
- v.extraArguments = Json::ensureString(arguments, "arguments", "");
- }
-
- if(obj.contains("loader")) {
- auto loader = Json::requireObject(obj, "loader");
- loadVersionLoader(v.loader, loader);
- }
-
- if(obj.contains("libraries")) {
- auto libraries = Json::requireArray(obj, "libraries");
- for (const auto libraryRaw : libraries)
- {
- auto libraryObj = Json::requireObject(libraryRaw);
- ATLauncher::VersionLibrary target;
- loadVersionLibrary(target, libraryObj);
- v.libraries.append(target);
- }
- }
-
- if(obj.contains("mods")) {
- auto mods = Json::requireArray(obj, "mods");
- for (const auto modRaw : mods)
- {
- auto modObj = Json::requireObject(modRaw);
- ATLauncher::VersionMod mod;
- loadVersionMod(mod, modObj);
- v.mods.append(mod);
- }
- }
-
- if(obj.contains("configs")) {
- auto configsObj = Json::requireObject(obj, "configs");
- loadVersionConfigs(v.configs, configsObj);
- }
-}
diff --git a/api/logic/modplatform/atlauncher/ATLPackManifest.h b/api/logic/modplatform/atlauncher/ATLPackManifest.h
deleted file mode 100644
index 17821e4c..00000000
--- a/api/logic/modplatform/atlauncher/ATLPackManifest.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QVector>
-#include <QJsonObject>
-#include <multimc_logic_export.h>
-
-namespace ATLauncher
-{
-
-enum class PackType
-{
- Public,
- Private
-};
-
-enum class ModType
-{
- Root,
- Forge,
- Jar,
- Mods,
- Flan,
- Dependency,
- Ic2Lib,
- DenLib,
- Coremods,
- MCPC,
- Plugins,
- Extract,
- Decomp,
- TexturePack,
- ResourcePack,
- ShaderPack,
- TexturePackExtract,
- ResourcePackExtract,
- Millenaire,
- Unknown
-};
-
-enum class DownloadType
-{
- Server,
- Browser,
- Direct,
- Unknown
-};
-
-struct VersionLoader
-{
- QString type;
- bool latest;
- bool recommended;
- bool choose;
-
- QString version;
-};
-
-struct VersionLibrary
-{
- QString url;
- QString file;
- QString server;
- QString md5;
- DownloadType download;
- QString download_raw;
-};
-
-struct VersionMod
-{
- QString name;
- QString version;
- QString url;
- QString file;
- QString md5;
- DownloadType download;
- QString download_raw;
- ModType type;
- QString type_raw;
-
- ModType extractTo;
- QString extractTo_raw;
- QString extractFolder;
-
- ModType decompType;
- QString decompType_raw;
- QString decompFile;
-
- QString description;
- bool optional;
- bool recommended;
- bool selected;
- bool hidden;
- bool library;
- QString group;
- QVector<QString> depends;
-
- bool client;
-
- // computed
- bool effectively_hidden;
-};
-
-struct VersionConfigs
-{
- int filesize;
- QString sha1;
-};
-
-struct PackVersion
-{
- QString version;
- QString minecraft;
- bool noConfigs;
- QString mainClass;
- QString extraArguments;
-
- VersionLoader loader;
- QVector<VersionLibrary> libraries;
- QVector<VersionMod> mods;
- VersionConfigs configs;
-};
-
-MULTIMC_LOGIC_EXPORT void loadVersion(PackVersion & v, QJsonObject & obj);
-
-}
diff --git a/api/logic/modplatform/flame/FileResolvingTask.cpp b/api/logic/modplatform/flame/FileResolvingTask.cpp
deleted file mode 100644
index 295574f0..00000000
--- a/api/logic/modplatform/flame/FileResolvingTask.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-#include "FileResolvingTask.h"
-#include "Json.h"
-
-namespace {
- const char * metabase = "https://cursemeta.dries007.net";
-}
-
-Flame::FileResolvingTask::FileResolvingTask(Flame::Manifest& toProcess)
- : m_toProcess(toProcess)
-{
-}
-
-void Flame::FileResolvingTask::executeTask()
-{
- setStatus(tr("Resolving mod IDs..."));
- setProgress(0, m_toProcess.files.size());
- m_dljob.reset(new NetJob("Mod id resolver"));
- results.resize(m_toProcess.files.size());
- int index = 0;
- for(auto & file: m_toProcess.files)
- {
- auto projectIdStr = QString::number(file.projectId);
- auto fileIdStr = QString::number(file.fileId);
- QString metaurl = QString("%1/%2/%3.json").arg(metabase, projectIdStr, fileIdStr);
- auto dl = Net::Download::makeByteArray(QUrl(metaurl), &results[index]);
- m_dljob->addNetAction(dl);
- index ++;
- }
- connect(m_dljob.get(), &NetJob::finished, this, &Flame::FileResolvingTask::netJobFinished);
- m_dljob->start();
-}
-
-void Flame::FileResolvingTask::netJobFinished()
-{
- bool failed = false;
- int index = 0;
- for(auto & bytes: results)
- {
- auto & out = m_toProcess.files[index];
- try
- {
- failed &= (!out.parseFromBytes(bytes));
- }
- catch (const JSONValidationError &e)
- {
-
- qCritical() << "Resolving of" << out.projectId << out.fileId << "failed because of a parsing error:";
- qCritical() << e.cause();
- qCritical() << "JSON:";
- qCritical() << bytes;
- failed = true;
- }
- index++;
- }
- if(!failed)
- {
- emitSucceeded();
- }
- else
- {
- emitFailed(tr("Some mod ID resolving tasks failed."));
- }
-}
diff --git a/api/logic/modplatform/flame/FileResolvingTask.h b/api/logic/modplatform/flame/FileResolvingTask.h
deleted file mode 100644
index 5679b907..00000000
--- a/api/logic/modplatform/flame/FileResolvingTask.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#pragma once
-
-#include "tasks/Task.h"
-#include "net/NetJob.h"
-#include "PackManifest.h"
-
-#include "multimc_logic_export.h"
-
-namespace Flame
-{
-class MULTIMC_LOGIC_EXPORT FileResolvingTask : public Task
-{
- Q_OBJECT
-public:
- explicit FileResolvingTask(Flame::Manifest &toProcess);
- virtual ~FileResolvingTask() {};
-
- const Flame::Manifest &getResults() const
- {
- return m_toProcess;
- }
-
-protected:
- virtual void executeTask() override;
-
-protected slots:
- void netJobFinished();
-
-private: /* data */
- Flame::Manifest m_toProcess;
- QVector<QByteArray> results;
- NetJobPtr m_dljob;
-};
-}
diff --git a/api/logic/modplatform/flame/FlamePackIndex.cpp b/api/logic/modplatform/flame/FlamePackIndex.cpp
deleted file mode 100644
index 3d8ea22a..00000000
--- a/api/logic/modplatform/flame/FlamePackIndex.cpp
+++ /dev/null
@@ -1,92 +0,0 @@
-#include "FlamePackIndex.h"
-
-#include "Json.h"
-
-void Flame::loadIndexedPack(Flame::IndexedPack & pack, QJsonObject & obj)
-{
- pack.addonId = Json::requireInteger(obj, "id");
- pack.name = Json::requireString(obj, "name");
- pack.websiteUrl = Json::ensureString(obj, "websiteUrl", "");
- pack.description = Json::ensureString(obj, "summary", "");
-
- bool thumbnailFound = false;
- auto attachments = Json::requireArray(obj, "attachments");
- for(auto attachmentRaw: attachments) {
- auto attachmentObj = Json::requireObject(attachmentRaw);
- bool isDefault = attachmentObj.value("isDefault").toBool(false);
- if(isDefault) {
- thumbnailFound = true;
- pack.logoName = Json::requireString(attachmentObj, "title");
- pack.logoUrl = Json::requireString(attachmentObj, "thumbnailUrl");
- break;
- }
- }
-
- if(!thumbnailFound) {
- throw JSONValidationError(QString("Pack without an icon, skipping: %1").arg(pack.name));
- }
-
- auto authors = Json::requireArray(obj, "authors");
- for(auto authorIter: authors) {
- auto author = Json::requireObject(authorIter);
- Flame::ModpackAuthor packAuthor;
- packAuthor.name = Json::requireString(author, "name");
- packAuthor.url = Json::requireString(author, "url");
- pack.authors.append(packAuthor);
- }
- int defaultFileId = Json::requireInteger(obj, "defaultFileId");
-
- bool found = false;
- // check if there are some files before adding the pack
- auto files = Json::requireArray(obj, "latestFiles");
- for(auto fileIter: files) {
- auto file = Json::requireObject(fileIter);
- int id = Json::requireInteger(file, "id");
-
- // NOTE: for now, ignore everything that's not the default...
- if(id != defaultFileId) {
- continue;
- }
-
- auto versionArray = Json::requireArray(file, "gameVersion");
- if(versionArray.size() < 1) {
- continue;
- }
-
- found = true;
- break;
- }
- if(!found) {
- throw JSONValidationError(QString("Pack with no good file, skipping: %1").arg(pack.name));
- }
-}
-
-void Flame::loadIndexedPackVersions(Flame::IndexedPack & pack, QJsonArray & arr)
-{
- QVector<Flame::IndexedVersion> unsortedVersions;
- for(auto versionIter: arr) {
- auto version = Json::requireObject(versionIter);
- Flame::IndexedVersion file;
-
- file.addonId = pack.addonId;
- file.fileId = Json::requireInteger(version, "id");
- auto versionArray = Json::requireArray(version, "gameVersion");
- if(versionArray.size() < 1) {
- continue;
- }
-
- // pick the latest version supported
- file.mcVersion = versionArray[0].toString();
- file.version = Json::requireString(version, "displayName");
- file.downloadUrl = Json::requireString(version, "downloadUrl");
- unsortedVersions.append(file);
- }
-
- auto orderSortPredicate = [](const IndexedVersion & a, const IndexedVersion & b) -> bool
- {
- return a.fileId > b.fileId;
- };
- std::sort(unsortedVersions.begin(), unsortedVersions.end(), orderSortPredicate);
- pack.versions = unsortedVersions;
- pack.versionsLoaded = true;
-}
diff --git a/api/logic/modplatform/flame/FlamePackIndex.h b/api/logic/modplatform/flame/FlamePackIndex.h
deleted file mode 100644
index cdeb2c13..00000000
--- a/api/logic/modplatform/flame/FlamePackIndex.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#pragma once
-
-#include <QList>
-#include <QMetaType>
-#include <QString>
-#include <QVector>
-
-#include "multimc_logic_export.h"
-
-namespace Flame {
-
-struct ModpackAuthor {
- QString name;
- QString url;
-};
-
-struct IndexedVersion {
- int addonId;
- int fileId;
- QString version;
- QString mcVersion;
- QString downloadUrl;
-};
-
-struct IndexedPack
-{
- int addonId;
- QString name;
- QString description;
- QList<ModpackAuthor> authors;
- QString logoName;
- QString logoUrl;
- QString websiteUrl;
-
- bool versionsLoaded = false;
- QVector<IndexedVersion> versions;
-};
-
-MULTIMC_LOGIC_EXPORT void loadIndexedPack(IndexedPack & m, QJsonObject & obj);
-MULTIMC_LOGIC_EXPORT void loadIndexedPackVersions(IndexedPack & m, QJsonArray & arr);
-}
-
-Q_DECLARE_METATYPE(Flame::IndexedPack)
diff --git a/api/logic/modplatform/flame/PackManifest.cpp b/api/logic/modplatform/flame/PackManifest.cpp
deleted file mode 100644
index b928fd16..00000000
--- a/api/logic/modplatform/flame/PackManifest.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-#include "PackManifest.h"
-#include "Json.h"
-
-static void loadFileV1(Flame::File & f, QJsonObject & file)
-{
- f.projectId = Json::requireInteger(file, "projectID");
- f.fileId = Json::requireInteger(file, "fileID");
- f.required = Json::ensureBoolean(file, QString("required"), true);
-}
-
-static void loadModloaderV1(Flame::Modloader & m, QJsonObject & modLoader)
-{
- m.id = Json::requireString(modLoader, "id");
- m.primary = Json::ensureBoolean(modLoader, QString("primary"), false);
-}
-
-static void loadMinecraftV1(Flame::Minecraft & m, QJsonObject & minecraft)
-{
- m.version = Json::requireString(minecraft, "version");
- // extra libraries... apparently only used for a custom Minecraft launcher in the 1.2.5 FTB retro pack
- // intended use is likely hardcoded in the 'Flame' client, the manifest says nothing
- m.libraries = Json::ensureString(minecraft, QString("libraries"), QString());
- auto arr = Json::ensureArray(minecraft, "modLoaders", QJsonArray());
- for (QJsonValueRef item : arr)
- {
- auto obj = Json::requireObject(item);
- Flame::Modloader loader;
- loadModloaderV1(loader, obj);
- m.modLoaders.append(loader);
- }
-}
-
-static void loadManifestV1(Flame::Manifest & m, QJsonObject & manifest)
-{
- auto mc = Json::requireObject(manifest, "minecraft");
- loadMinecraftV1(m.minecraft, mc);
- m.name = Json::ensureString(manifest, QString("name"), "Unnamed");
- m.version = Json::ensureString(manifest, QString("version"), QString());
- m.author = Json::ensureString(manifest, QString("author"), "Anonymous Coward");
- auto arr = Json::ensureArray(manifest, "files", QJsonArray());
- for (QJsonValueRef item : arr)
- {
- auto obj = Json::requireObject(item);
- Flame::File file;
- loadFileV1(file, obj);
- m.files.append(file);
- }
- m.overrides = Json::ensureString(manifest, "overrides", "overrides");
-}
-
-void Flame::loadManifest(Flame::Manifest & m, const QString &filepath)
-{
- auto doc = Json::requireDocument(filepath);
- auto obj = Json::requireObject(doc);
- m.manifestType = Json::requireString(obj, "manifestType");
- if(m.manifestType != "minecraftModpack")
- {
- throw JSONValidationError("Not a modpack manifest!");
- }
- m.manifestVersion = Json::requireInteger(obj, "manifestVersion");
- if(m.manifestVersion != 1)
- {
- throw JSONValidationError(QString("Unknown manifest version (%1)").arg(m.manifestVersion));
- }
- 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
deleted file mode 100644
index 02f39f0e..00000000
--- a/api/logic/modplatform/flame/PackManifest.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QVector>
-#include <QUrl>
-
-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.
- bool required = true;
-
- // our
- bool resolved = false;
- QString fileName;
- QUrl url;
- QString targetFolder = QLatin1Literal("mods");
- enum class Type
- {
- Unknown,
- Folder,
- Ctoc,
- SingleFile,
- Cmod2,
- Modpack,
- Mod
- } type = Type::Mod;
-};
-
-struct Modloader
-{
- QString id;
- bool primary = false;
-};
-
-struct Minecraft
-{
- QString version;
- QString libraries;
- QVector<Flame::Modloader> modLoaders;
-};
-
-struct Manifest
-{
- QString manifestType;
- int manifestVersion = 0;
- Flame::Minecraft minecraft;
- QString name;
- QString version;
- QString author;
- QVector<Flame::File> files;
- QString overrides;
-};
-
-void loadManifest(Flame::Manifest & m, const QString &filepath);
-}
diff --git a/api/logic/modplatform/legacy_ftb/PackFetchTask.cpp b/api/logic/modplatform/legacy_ftb/PackFetchTask.cpp
deleted file mode 100644
index c2ef6436..00000000
--- a/api/logic/modplatform/legacy_ftb/PackFetchTask.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-#include "PackFetchTask.h"
-#include "PrivatePackManager.h"
-
-#include <QDomDocument>
-#include <BuildConfig.h>
-
-namespace LegacyFTB {
-
-void PackFetchTask::fetch()
-{
- publicPacks.clear();
- thirdPartyPacks.clear();
-
- NetJob *netJob = new NetJob("LegacyFTB::ModpackFetch");
-
- QUrl publicPacksUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/modpacks.xml");
- qDebug() << "Downloading public version info from" << publicPacksUrl.toString();
- netJob->addNetAction(Net::Download::makeByteArray(publicPacksUrl, &publicModpacksXmlFileData));
-
- QUrl thirdPartyUrl = QUrl(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/thirdparty.xml");
- qDebug() << "Downloading thirdparty version info from" << thirdPartyUrl.toString();
- netJob->addNetAction(Net::Download::makeByteArray(thirdPartyUrl, &thirdPartyModpacksXmlFileData));
-
- QObject::connect(netJob, &NetJob::succeeded, this, &PackFetchTask::fileDownloadFinished);
- QObject::connect(netJob, &NetJob::failed, this, &PackFetchTask::fileDownloadFailed);
-
- jobPtr.reset(netJob);
- netJob->start();
-}
-
-void PackFetchTask::fetchPrivate(const QStringList & toFetch)
-{
- QString privatePackBaseUrl = BuildConfig.LEGACY_FTB_CDN_BASE_URL + "static/%1.xml";
-
- for (auto &packCode: toFetch)
- {
- QByteArray *data = new QByteArray();
- NetJob *job = new NetJob("Fetching private pack");
- job->addNetAction(Net::Download::makeByteArray(privatePackBaseUrl.arg(packCode), data));
-
- QObject::connect(job, &NetJob::succeeded, this, [this, job, data, packCode]
- {
- ModpackList packs;
- parseAndAddPacks(*data, PackType::Private, packs);
- foreach(Modpack currentPack, packs)
- {
- currentPack.packCode = packCode;
- emit privateFileDownloadFinished(currentPack);
- }
-
- job->deleteLater();
-
- data->clear();
- delete data;
- });
-
- QObject::connect(job, &NetJob::failed, this, [this, job, packCode, data](QString reason)
- {
- emit privateFileDownloadFailed(reason, packCode);
- job->deleteLater();
-
- data->clear();
- delete data;
- });
-
- job->start();
- }
-}
-
-void PackFetchTask::fileDownloadFinished()
-{
- jobPtr.reset();
-
- QStringList failedLists;
-
- if(!parseAndAddPacks(publicModpacksXmlFileData, PackType::Public, publicPacks))
- {
- failedLists.append(tr("Public Packs"));
- }
-
- if(!parseAndAddPacks(thirdPartyModpacksXmlFileData, PackType::ThirdParty, thirdPartyPacks))
- {
- failedLists.append(tr("Third Party Packs"));
- }
-
- if(failedLists.size() > 0)
- {
- emit failed(tr("Failed to download some pack lists: %1").arg(failedLists.join("\n- ")));
- }
- else
- {
- emit finished(publicPacks, thirdPartyPacks);
- }
-}
-
-bool PackFetchTask::parseAndAddPacks(QByteArray &data, PackType packType, ModpackList &list)
-{
- QDomDocument doc;
-
- QString errorMsg = "Unknown error.";
- int errorLine = -1;
- int errorCol = -1;
-
- if(!doc.setContent(data, false, &errorMsg, &errorLine, &errorCol))
- {
- auto fullErrMsg = QString("Failed to fetch modpack data: %1 %2:3d!").arg(errorMsg, errorLine, errorCol);
- qWarning() << fullErrMsg;
- data.clear();
- return false;
- }
-
- QDomNodeList nodes = doc.elementsByTagName("modpack");
- for(int i = 0; i < nodes.length(); i++)
- {
- QDomElement element = nodes.at(i).toElement();
-
- Modpack modpack;
- modpack.name = element.attribute("name");
- modpack.currentVersion = element.attribute("version");
- modpack.mcVersion = element.attribute("mcVersion");
- modpack.description = element.attribute("description");
- modpack.mods = element.attribute("mods");
- modpack.logo = element.attribute("logo");
- modpack.oldVersions = element.attribute("oldVersions").split(";");
- modpack.broken = false;
- modpack.bugged = false;
-
- //remove empty if the xml is bugged
- for(QString curr : modpack.oldVersions)
- {
- if(curr.isNull() || curr.isEmpty())
- {
- modpack.oldVersions.removeAll(curr);
- modpack.bugged = true;
- qWarning() << "Removed some empty versions from" << modpack.name;
- }
- }
-
- if(modpack.oldVersions.size() < 1)
- {
- if(!modpack.currentVersion.isNull() && !modpack.currentVersion.isEmpty())
- {
- modpack.oldVersions.append(modpack.currentVersion);
- qWarning() << "Added current version to oldVersions because oldVersions was empty! (" + modpack.name + ")";
- }
- else
- {
- modpack.broken = true;
- qWarning() << "Broken pack:" << modpack.name << " => No valid version!";
- }
- }
-
- modpack.author = element.attribute("author");
-
- modpack.dir = element.attribute("dir");
- modpack.file = element.attribute("url");
-
- modpack.type = packType;
-
- list.append(modpack);
- }
-
- return true;
-}
-
-void PackFetchTask::fileDownloadFailed(QString reason)
-{
- qWarning() << "Fetching FTBPacks failed:" << reason;
- emit failed(reason);
-}
-
-}
diff --git a/api/logic/modplatform/legacy_ftb/PackFetchTask.h b/api/logic/modplatform/legacy_ftb/PackFetchTask.h
deleted file mode 100644
index 4a8469b1..00000000
--- a/api/logic/modplatform/legacy_ftb/PackFetchTask.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-#include "net/NetJob.h"
-#include <QTemporaryDir>
-#include <QByteArray>
-#include <QObject>
-#include "PackHelpers.h"
-
-namespace LegacyFTB {
-
-class MULTIMC_LOGIC_EXPORT PackFetchTask : public QObject {
-
- Q_OBJECT
-
-public:
- PackFetchTask() = default;
- virtual ~PackFetchTask() = default;
-
- void fetch();
- void fetchPrivate(const QStringList &toFetch);
-
-private:
- NetJobPtr jobPtr;
-
- QByteArray publicModpacksXmlFileData;
- QByteArray thirdPartyModpacksXmlFileData;
-
- bool parseAndAddPacks(QByteArray &data, PackType packType, ModpackList &list);
- ModpackList publicPacks;
- ModpackList thirdPartyPacks;
-
-protected slots:
- void fileDownloadFinished();
- void fileDownloadFailed(QString reason);
-
-signals:
- void finished(ModpackList publicPacks, ModpackList thirdPartyPacks);
- void failed(QString reason);
-
- void privateFileDownloadFinished(Modpack modpack);
- void privateFileDownloadFailed(QString reason, QString packCode);
-};
-
-}
diff --git a/api/logic/modplatform/legacy_ftb/PackHelpers.h b/api/logic/modplatform/legacy_ftb/PackHelpers.h
deleted file mode 100644
index 566210d0..00000000
--- a/api/logic/modplatform/legacy_ftb/PackHelpers.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-
-#include <QList>
-#include <QString>
-#include <QStringList>
-#include <QMetaType>
-
-namespace LegacyFTB {
-
-//Header for structs etc...
-enum class PackType
-{
- Public,
- ThirdParty,
- Private
-};
-
-struct Modpack
-{
- QString name;
- QString description;
- QString author;
- QStringList oldVersions;
- QString currentVersion;
- QString mcVersion;
- QString mods;
- QString logo;
-
- //Technical data
- QString dir;
- QString file; //<- Url in the xml, but doesn't make much sense
-
- bool bugged = false;
- bool broken = false;
-
- PackType type;
- QString packCode;
-};
-
-typedef QList<Modpack> ModpackList;
-
-}
-
-//We need it for the proxy model
-Q_DECLARE_METATYPE(LegacyFTB::Modpack)
diff --git a/api/logic/modplatform/legacy_ftb/PackInstallTask.cpp b/api/logic/modplatform/legacy_ftb/PackInstallTask.cpp
deleted file mode 100644
index c77f3250..00000000
--- a/api/logic/modplatform/legacy_ftb/PackInstallTask.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-#include "PackInstallTask.h"
-
-#include "Env.h"
-#include "MMCZip.h"
-
-#include "BaseInstance.h"
-#include "FileSystem.h"
-#include "settings/INISettingsObject.h"
-#include "minecraft/MinecraftInstance.h"
-#include "minecraft/PackProfile.h"
-#include "minecraft/GradleSpecifier.h"
-#include "BuildConfig.h"
-
-#include <QtConcurrent>
-
-namespace LegacyFTB {
-
-PackInstallTask::PackInstallTask(Modpack pack, QString version)
-{
- m_pack = pack;
- m_version = version;
-}
-
-void PackInstallTask::executeTask()
-{
- downloadPack();
-}
-
-void PackInstallTask::downloadPack()
-{
- setStatus(tr("Downloading zip for %1").arg(m_pack.name));
-
- auto packoffset = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
- auto entry = ENV.metacache()->resolveEntry("FTBPacks", packoffset);
- NetJob *job = new NetJob("Download FTB Pack");
-
- entry->setStale(true);
- QString url;
- if(m_pack.type == PackType::Private)
- {
- url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "privatepacks/%1").arg(packoffset);
- }
- else
- {
- url = QString(BuildConfig.LEGACY_FTB_CDN_BASE_URL + "modpacks/%1").arg(packoffset);
- }
- job->addNetAction(Net::Download::makeCached(url, entry));
- archivePath = entry->getFullPath();
-
- netJobContainer.reset(job);
- connect(job, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
- connect(job, &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
- connect(job, &NetJob::progress, this, &PackInstallTask::onDownloadProgress);
- job->start();
-
- progress(1, 4);
-}
-
-void PackInstallTask::onDownloadSucceeded()
-{
- abortable = false;
- unzip();
-}
-
-void PackInstallTask::onDownloadFailed(QString reason)
-{
- abortable = false;
- emitFailed(reason);
-}
-
-void PackInstallTask::onDownloadProgress(qint64 current, qint64 total)
-{
- abortable = true;
- progress(current, total * 4);
- setStatus(tr("Downloading zip for %1 (%2%)").arg(m_pack.name).arg(current / 10));
-}
-
-void PackInstallTask::unzip()
-{
- progress(2, 4);
- setStatus(tr("Extracting modpack"));
- QDir extractDir(m_stagingPath);
-
- m_packZip.reset(new QuaZip(archivePath));
- if(!m_packZip->open(QuaZip::mdUnzip))
- {
- emitFailed(tr("Failed to open modpack file %1!").arg(archivePath));
- return;
- }
-
- m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip");
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onUnzipFinished);
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &PackInstallTask::onUnzipCanceled);
- m_extractFutureWatcher.setFuture(m_extractFuture);
-}
-
-void PackInstallTask::onUnzipFinished()
-{
- install();
-}
-
-void PackInstallTask::onUnzipCanceled()
-{
- emitAborted();
-}
-
-void PackInstallTask::install()
-{
- progress(3, 4);
- setStatus(tr("Installing modpack"));
- QDir unzipMcDir(m_stagingPath + "/unzip/minecraft");
- if(unzipMcDir.exists())
- {
- //ok, found minecraft dir, move contents to instance dir
- if(!QDir().rename(m_stagingPath + "/unzip/minecraft", m_stagingPath + "/.minecraft"))
- {
- emitFailed(tr("Failed to move unzipped minecraft!"));
- return;
- }
- }
-
- QString instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
- auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath);
- instanceSettings->suspendSave();
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
-
- MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
- auto components = instance.getPackProfile();
- components->buildingFromScratch();
- components->setComponentVersion("net.minecraft", m_pack.mcVersion, true);
-
- bool fallback = true;
-
- //handle different versions
- QFile packJson(m_stagingPath + "/.minecraft/pack.json");
- QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods");
- if(packJson.exists())
- {
- packJson.open(QIODevice::ReadOnly | QIODevice::Text);
- QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll());
- packJson.close();
-
- //we only care about the libs
- QJsonArray libs = doc.object().value("libraries").toArray();
-
- foreach (const QJsonValue &value, libs)
- {
- QString nameValue = value.toObject().value("name").toString();
- if(!nameValue.startsWith("net.minecraftforge"))
- {
- continue;
- }
-
- GradleSpecifier forgeVersion(nameValue);
-
- components->setComponentVersion("net.minecraftforge", forgeVersion.version().replace(m_pack.mcVersion, "").replace("-", ""));
- packJson.remove();
- fallback = false;
- break;
- }
-
- }
-
- if(jarmodDir.exists())
- {
- qDebug() << "Found jarmods, installing...";
-
- QStringList jarmods;
- for (auto info: jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
- {
- qDebug() << "Jarmod:" << info.fileName();
- jarmods.push_back(info.absoluteFilePath());
- }
-
- components->installJarMods(jarmods);
- fallback = false;
- }
-
- //just nuke unzip directory, it s not needed anymore
- FS::deletePath(m_stagingPath + "/unzip");
-
- if(fallback)
- {
- //TODO: Some fallback mechanism... or just keep failing!
- emitFailed(tr("No installation method found!"));
- return;
- }
-
- components->saveNow();
-
- progress(4, 4);
-
- instance.setName(m_instName);
- if(m_instIcon == "default")
- {
- m_instIcon = "ftb_logo";
- }
- instance.setIconKey(m_instIcon);
- instanceSettings->resumeSave();
-
- emitSucceeded();
-}
-
-bool PackInstallTask::abort()
-{
- if(abortable)
- {
- return netJobContainer->abort();
- }
- return false;
-}
-
-}
diff --git a/api/logic/modplatform/legacy_ftb/PackInstallTask.h b/api/logic/modplatform/legacy_ftb/PackInstallTask.h
deleted file mode 100644
index f3515781..00000000
--- a/api/logic/modplatform/legacy_ftb/PackInstallTask.h
+++ /dev/null
@@ -1,55 +0,0 @@
-#pragma once
-#include "InstanceTask.h"
-#include "net/NetJob.h"
-#include "quazip.h"
-#include "quazipdir.h"
-#include "meta/Index.h"
-#include "meta/Version.h"
-#include "meta/VersionList.h"
-#include "PackHelpers.h"
-
-#include <nonstd/optional>
-
-namespace LegacyFTB {
-
-class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
-{
- Q_OBJECT
-
-public:
- explicit PackInstallTask(Modpack pack, QString version);
- virtual ~PackInstallTask(){}
-
- bool canAbort() const override { return true; }
- bool abort() override;
-
-protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
-
-private:
- void downloadPack();
- void unzip();
- void install();
-
-private slots:
- void onDownloadSucceeded();
- void onDownloadFailed(QString reason);
- void onDownloadProgress(qint64 current, qint64 total);
-
- void onUnzipFinished();
- void onUnzipCanceled();
-
-private: /* data */
- bool abortable = false;
- std::unique_ptr<QuaZip> m_packZip;
- QFuture<nonstd::optional<QStringList>> m_extractFuture;
- QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
- NetJobPtr netJobContainer;
- QString archivePath;
-
- Modpack m_pack;
- QString m_version;
-};
-
-}
diff --git a/api/logic/modplatform/legacy_ftb/PrivatePackManager.cpp b/api/logic/modplatform/legacy_ftb/PrivatePackManager.cpp
deleted file mode 100644
index 501e6003..00000000
--- a/api/logic/modplatform/legacy_ftb/PrivatePackManager.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "PrivatePackManager.h"
-
-#include <QDebug>
-
-#include "FileSystem.h"
-
-namespace LegacyFTB {
-
-void PrivatePackManager::load()
-{
- try
- {
- currentPacks = QString::fromUtf8(FS::read(m_filename)).split('\n', QString::SkipEmptyParts).toSet();
- dirty = false;
- }
- catch(...)
- {
- currentPacks = {};
- qWarning() << "Failed to read third party FTB pack codes from" << m_filename;
- }
-}
-
-void PrivatePackManager::save() const
-{
- if(!dirty)
- {
- return;
- }
- try
- {
- QStringList list = currentPacks.toList();
- FS::write(m_filename, list.join('\n').toUtf8());
- dirty = false;
- }
- catch(...)
- {
- qWarning() << "Failed to write third party FTB pack codes to" << m_filename;
- }
-}
-
-}
diff --git a/api/logic/modplatform/legacy_ftb/PrivatePackManager.h b/api/logic/modplatform/legacy_ftb/PrivatePackManager.h
deleted file mode 100644
index 0232bac7..00000000
--- a/api/logic/modplatform/legacy_ftb/PrivatePackManager.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#pragma once
-
-#include <QSet>
-#include <QString>
-#include <QFile>
-#include "multimc_logic_export.h"
-
-namespace LegacyFTB {
-
-class MULTIMC_LOGIC_EXPORT PrivatePackManager
-{
-public:
- ~PrivatePackManager()
- {
- save();
- }
- void load();
- void save() const;
- bool empty() const
- {
- return currentPacks.empty();
- }
- const QSet<QString> &getCurrentPackCodes() const
- {
- return currentPacks;
- }
- void add(const QString &code)
- {
- currentPacks.insert(code);
- dirty = true;
- }
- void remove(const QString &code)
- {
- currentPacks.remove(code);
- dirty = true;
- }
-
-private:
- QSet<QString> currentPacks;
- QString m_filename = "private_packs.txt";
- mutable bool dirty = false;
-};
-
-}
diff --git a/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp b/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp
deleted file mode 100644
index f22373bc..00000000
--- a/api/logic/modplatform/modpacksch/FTBPackInstallTask.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-#include "FTBPackInstallTask.h"
-
-#include "BuildConfig.h"
-#include "Env.h"
-#include "FileSystem.h"
-#include "Json.h"
-#include "minecraft/MinecraftInstance.h"
-#include "minecraft/PackProfile.h"
-#include "net/ChecksumValidator.h"
-#include "settings/INISettingsObject.h"
-
-namespace ModpacksCH {
-
-PackInstallTask::PackInstallTask(Modpack pack, QString version)
-{
- m_pack = pack;
- m_version_name = version;
-}
-
-bool PackInstallTask::abort()
-{
- if(abortable)
- {
- return jobPtr->abort();
- }
- return false;
-}
-
-void PackInstallTask::executeTask()
-{
- // Find pack version
- bool found = false;
- VersionInfo version;
-
- for(auto vInfo : m_pack.versions) {
- if (vInfo.name == m_version_name) {
- found = true;
- version = vInfo;
- break;
- }
- }
-
- if(!found) {
- emitFailed(tr("Failed to find pack version %1").arg(m_version_name));
- return;
- }
-
- auto *netJob = new NetJob("ModpacksCH::VersionFetch");
- auto searchUrl = QString(BuildConfig.MODPACKSCH_API_BASE_URL + "public/modpack/%1/%2")
- .arg(m_pack.id).arg(version.id);
- netJob->addNetAction(Net::Download::makeByteArray(QUrl(searchUrl), &response));
- jobPtr = netJob;
- jobPtr->start();
-
- QObject::connect(netJob, &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
- QObject::connect(netJob, &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
-}
-
-void PackInstallTask::onDownloadSucceeded()
-{
- jobPtr.reset();
-
- QJsonParseError parse_error;
- QJsonDocument doc = QJsonDocument::fromJson(response, &parse_error);
- if(parse_error.error != QJsonParseError::NoError) {
- qWarning() << "Error while parsing JSON response from FTB at " << parse_error.offset << " reason: " << parse_error.errorString();
- qWarning() << response;
- return;
- }
-
- auto obj = doc.object();
-
- ModpacksCH::Version version;
- try
- {
- ModpacksCH::loadVersion(version, obj);
- }
- catch (const JSONValidationError &e)
- {
- emitFailed(tr("Could not understand pack manifest:\n") + e.cause());
- return;
- }
- m_version = version;
-
- downloadPack();
-}
-
-void PackInstallTask::onDownloadFailed(QString reason)
-{
- jobPtr.reset();
- emitFailed(reason);
-}
-
-void PackInstallTask::downloadPack()
-{
- setStatus(tr("Downloading mods..."));
-
- jobPtr.reset(new NetJob(tr("Mod download")));
- for(auto file : m_version.files) {
- if(file.serverOnly) continue;
-
- QFileInfo fileName(file.name);
- auto cacheName = fileName.completeBaseName() + "-" + file.sha1 + "." + fileName.suffix();
-
- auto entry = ENV.metacache()->resolveEntry("ModpacksCHPacks", cacheName);
- entry->setStale(true);
-
- auto relpath = FS::PathCombine("minecraft", file.path, file.name);
- auto path = FS::PathCombine(m_stagingPath, relpath);
-
- qDebug() << "Will download" << file.url << "to" << path;
- filesToCopy[entry->getFullPath()] = path;
-
- auto dl = Net::Download::makeCached(file.url, entry);
- if (!file.sha1.isEmpty()) {
- auto rawSha1 = QByteArray::fromHex(file.sha1.toLatin1());
- dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, rawSha1));
- }
- jobPtr->addNetAction(dl);
- }
-
- connect(jobPtr.get(), &NetJob::succeeded, this, [&]()
- {
- abortable = false;
- jobPtr.reset();
- install();
- });
- connect(jobPtr.get(), &NetJob::failed, [&](QString reason)
- {
- abortable = false;
- jobPtr.reset();
- emitFailed(reason);
- });
- connect(jobPtr.get(), &NetJob::progress, [&](qint64 current, qint64 total)
- {
- abortable = true;
- setProgress(current, total);
- });
-
- jobPtr->start();
-}
-
-void PackInstallTask::install()
-{
- setStatus(tr("Copying modpack files"));
-
- for (auto iter = filesToCopy.begin(); iter != filesToCopy.end(); iter++) {
- auto &from = iter.key();
- auto &to = iter.value();
- FS::copy fileCopyOperation(from, to);
- if(!fileCopyOperation()) {
- qWarning() << "Failed to copy" << from << "to" << to;
- emitFailed(tr("Failed to copy files"));
- return;
- }
- }
-
- setStatus(tr("Installing modpack"));
-
- auto instanceConfigPath = FS::PathCombine(m_stagingPath, "instance.cfg");
- auto instanceSettings = std::make_shared<INISettingsObject>(instanceConfigPath);
- instanceSettings->suspendSave();
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
-
- MinecraftInstance instance(m_globalSettings, instanceSettings, m_stagingPath);
- auto components = instance.getPackProfile();
- components->buildingFromScratch();
-
- for(auto target : m_version.targets) {
- if(target.type == "game" && target.name == "minecraft") {
- components->setComponentVersion("net.minecraft", target.version, true);
- break;
- }
- }
-
- for(auto target : m_version.targets) {
- if(target.type != "modloader") continue;
-
- if(target.name == "forge") {
- components->setComponentVersion("net.minecraftforge", target.version, true);
- }
- else if(target.name == "fabric") {
- components->setComponentVersion("net.fabricmc.fabric-loader", target.version, true);
- }
- }
-
- // install any jar mods
- QDir jarModsDir(FS::PathCombine(m_stagingPath, "minecraft", "jarmods"));
- if (jarModsDir.exists()) {
- QStringList jarMods;
-
- for (const auto& info : jarModsDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) {
- jarMods.push_back(info.absoluteFilePath());
- }
-
- components->installJarMods(jarMods);
- }
-
- components->saveNow();
-
- instance.setName(m_instName);
- instance.setIconKey(m_instIcon);
- instanceSettings->resumeSave();
-
- emitSucceeded();
-}
-
-}
diff --git a/api/logic/modplatform/modpacksch/FTBPackInstallTask.h b/api/logic/modplatform/modpacksch/FTBPackInstallTask.h
deleted file mode 100644
index 55db3d3c..00000000
--- a/api/logic/modplatform/modpacksch/FTBPackInstallTask.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include "FTBPackManifest.h"
-
-#include "InstanceTask.h"
-#include "multimc_logic_export.h"
-#include "net/NetJob.h"
-
-namespace ModpacksCH {
-
-class MULTIMC_LOGIC_EXPORT PackInstallTask : public InstanceTask
-{
- Q_OBJECT
-
-public:
- explicit PackInstallTask(Modpack pack, QString version);
- virtual ~PackInstallTask(){}
-
- bool canAbort() const override { return true; }
- bool abort() override;
-
-protected:
- virtual void executeTask() override;
-
-private slots:
- void onDownloadSucceeded();
- void onDownloadFailed(QString reason);
-
-private:
- void downloadPack();
- void install();
-
-private:
- bool abortable = false;
-
- NetJobPtr jobPtr;
- QByteArray response;
-
- Modpack m_pack;
- QString m_version_name;
- Version m_version;
-
- QMap<QString, QString> filesToCopy;
-
-};
-
-}
diff --git a/api/logic/modplatform/modpacksch/FTBPackManifest.cpp b/api/logic/modplatform/modpacksch/FTBPackManifest.cpp
deleted file mode 100644
index fd99d332..00000000
--- a/api/logic/modplatform/modpacksch/FTBPackManifest.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-#include "FTBPackManifest.h"
-
-#include "Json.h"
-
-static void loadSpecs(ModpacksCH::Specs & s, QJsonObject & obj)
-{
- s.id = Json::requireInteger(obj, "id");
- s.minimum = Json::requireInteger(obj, "minimum");
- s.recommended = Json::requireInteger(obj, "recommended");
-}
-
-static void loadTag(ModpacksCH::Tag & t, QJsonObject & obj)
-{
- t.id = Json::requireInteger(obj, "id");
- t.name = Json::requireString(obj, "name");
-}
-
-static void loadArt(ModpacksCH::Art & a, QJsonObject & obj)
-{
- a.id = Json::requireInteger(obj, "id");
- a.url = Json::requireString(obj, "url");
- a.type = Json::requireString(obj, "type");
- a.width = Json::requireInteger(obj, "width");
- a.height = Json::requireInteger(obj, "height");
- a.compressed = Json::requireBoolean(obj, "compressed");
- a.sha1 = Json::requireString(obj, "sha1");
- a.size = Json::requireInteger(obj, "size");
- a.updated = Json::requireInteger(obj, "updated");
-}
-
-static void loadAuthor(ModpacksCH::Author & a, QJsonObject & obj)
-{
- a.id = Json::requireInteger(obj, "id");
- a.name = Json::requireString(obj, "name");
- a.type = Json::requireString(obj, "type");
- a.website = Json::requireString(obj, "website");
- a.updated = Json::requireInteger(obj, "updated");
-}
-
-static void loadVersionInfo(ModpacksCH::VersionInfo & v, QJsonObject & obj)
-{
- v.id = Json::requireInteger(obj, "id");
- v.name = Json::requireString(obj, "name");
- v.type = Json::requireString(obj, "type");
- v.updated = Json::requireInteger(obj, "updated");
- auto specs = Json::requireObject(obj, "specs");
- loadSpecs(v.specs, specs);
-}
-
-void ModpacksCH::loadModpack(ModpacksCH::Modpack & m, QJsonObject & obj)
-{
- m.id = Json::requireInteger(obj, "id");
- m.name = Json::requireString(obj, "name");
- m.synopsis = Json::requireString(obj, "synopsis");
- m.description = Json::requireString(obj, "description");
- m.type = Json::requireString(obj, "type");
- m.featured = Json::requireBoolean(obj, "featured");
- m.installs = Json::requireInteger(obj, "installs");
- m.plays = Json::requireInteger(obj, "plays");
- m.updated = Json::requireInteger(obj, "updated");
- m.refreshed = Json::requireInteger(obj, "refreshed");
- auto artArr = Json::requireArray(obj, "art");
- for (QJsonValueRef artRaw : artArr)
- {
- auto artObj = Json::requireObject(artRaw);
- ModpacksCH::Art art;
- loadArt(art, artObj);
- m.art.append(art);
- }
- auto authorArr = Json::requireArray(obj, "authors");
- for (QJsonValueRef authorRaw : authorArr)
- {
- auto authorObj = Json::requireObject(authorRaw);
- ModpacksCH::Author author;
- loadAuthor(author, authorObj);
- m.authors.append(author);
- }
- auto versionArr = Json::requireArray(obj, "versions");
- for (QJsonValueRef versionRaw : versionArr)
- {
- auto versionObj = Json::requireObject(versionRaw);
- ModpacksCH::VersionInfo version;
- loadVersionInfo(version, versionObj);
- m.versions.append(version);
- }
- auto tagArr = Json::requireArray(obj, "tags");
- for (QJsonValueRef tagRaw : tagArr)
- {
- auto tagObj = Json::requireObject(tagRaw);
- ModpacksCH::Tag tag;
- loadTag(tag, tagObj);
- m.tags.append(tag);
- }
- m.updated = Json::requireInteger(obj, "updated");
-}
-
-static void loadVersionTarget(ModpacksCH::VersionTarget & a, QJsonObject & obj)
-{
- a.id = Json::requireInteger(obj, "id");
- a.name = Json::requireString(obj, "name");
- a.type = Json::requireString(obj, "type");
- a.version = Json::requireString(obj, "version");
- a.updated = Json::requireInteger(obj, "updated");
-}
-
-static void loadVersionFile(ModpacksCH::VersionFile & a, QJsonObject & obj)
-{
- a.id = Json::requireInteger(obj, "id");
- a.type = Json::requireString(obj, "type");
- a.path = Json::requireString(obj, "path");
- a.name = Json::requireString(obj, "name");
- a.version = Json::requireString(obj, "version");
- a.url = Json::requireString(obj, "url");
- a.sha1 = Json::requireString(obj, "sha1");
- a.size = Json::requireInteger(obj, "size");
- a.clientOnly = Json::requireBoolean(obj, "clientonly");
- a.serverOnly = Json::requireBoolean(obj, "serveronly");
- a.optional = Json::requireBoolean(obj, "optional");
- a.updated = Json::requireInteger(obj, "updated");
-}
-
-void ModpacksCH::loadVersion(ModpacksCH::Version & m, QJsonObject & obj)
-{
- m.id = Json::requireInteger(obj, "id");
- m.parent = Json::requireInteger(obj, "parent");
- m.name = Json::requireString(obj, "name");
- m.type = Json::requireString(obj, "type");
- m.installs = Json::requireInteger(obj, "installs");
- m.plays = Json::requireInteger(obj, "plays");
- m.updated = Json::requireInteger(obj, "updated");
- m.refreshed = Json::requireInteger(obj, "refreshed");
- auto specs = Json::requireObject(obj, "specs");
- loadSpecs(m.specs, specs);
- auto targetArr = Json::requireArray(obj, "targets");
- for (QJsonValueRef targetRaw : targetArr)
- {
- auto versionObj = Json::requireObject(targetRaw);
- ModpacksCH::VersionTarget target;
- loadVersionTarget(target, versionObj);
- m.targets.append(target);
- }
- auto fileArr = Json::requireArray(obj, "files");
- for (QJsonValueRef fileRaw : fileArr)
- {
- auto fileObj = Json::requireObject(fileRaw);
- ModpacksCH::VersionFile file;
- loadVersionFile(file, fileObj);
- m.files.append(file);
- }
-}
-
-//static void loadVersionChangelog(ModpacksCH::VersionChangelog & m, QJsonObject & obj)
-//{
-// m.content = Json::requireString(obj, "content");
-// m.updated = Json::requireInteger(obj, "updated");
-//}
diff --git a/api/logic/modplatform/modpacksch/FTBPackManifest.h b/api/logic/modplatform/modpacksch/FTBPackManifest.h
deleted file mode 100644
index 518fffbf..00000000
--- a/api/logic/modplatform/modpacksch/FTBPackManifest.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#pragma once
-
-#include <QString>
-#include <QVector>
-#include <QUrl>
-#include <QJsonObject>
-#include <QMetaType>
-
-#include "multimc_logic_export.h"
-
-namespace ModpacksCH
-{
-
-struct Specs
-{
- int id;
- int minimum;
- int recommended;
-};
-
-struct Tag
-{
- int id;
- QString name;
-};
-
-struct Art
-{
- int id;
- QString url;
- QString type;
- int width;
- int height;
- bool compressed;
- QString sha1;
- int size;
- int64_t updated;
-};
-
-struct Author
-{
- int id;
- QString name;
- QString type;
- QString website;
- int64_t updated;
-};
-
-struct VersionInfo
-{
- int id;
- QString name;
- QString type;
- int64_t updated;
- Specs specs;
-};
-
-struct Modpack
-{
- int id;
- QString name;
- QString synopsis;
- QString description;
- QString type;
- bool featured;
- int installs;
- int plays;
- int64_t updated;
- int64_t refreshed;
- QVector<Art> art;
- QVector<Author> authors;
- QVector<VersionInfo> versions;
- QVector<Tag> tags;
-};
-
-struct VersionTarget
-{
- int id;
- QString type;
- QString name;
- QString version;
- int64_t updated;
-};
-
-struct VersionFile
-{
- int id;
- QString type;
- QString path;
- QString name;
- QString version;
- QString url;
- QString sha1;
- int size;
- bool clientOnly;
- bool serverOnly;
- bool optional;
- int64_t updated;
-};
-
-struct Version
-{
- int id;
- int parent;
- QString name;
- QString type;
- int installs;
- int plays;
- int64_t updated;
- int64_t refreshed;
- Specs specs;
- QVector<VersionTarget> targets;
- QVector<VersionFile> files;
-};
-
-struct VersionChangelog
-{
- QString content;
- int64_t updated;
-};
-
-MULTIMC_LOGIC_EXPORT void loadModpack(Modpack & m, QJsonObject & obj);
-
-MULTIMC_LOGIC_EXPORT void loadVersion(Version & m, QJsonObject & obj);
-}
-
-Q_DECLARE_METATYPE(ModpacksCH::Modpack)
diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp b/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
deleted file mode 100644
index dbce8e53..00000000
--- a/api/logic/modplatform/technic/SingleZipPackInstallTask.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Copyright 2013-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "SingleZipPackInstallTask.h"
-
-#include "Env.h"
-#include "MMCZip.h"
-#include "TechnicPackProcessor.h"
-
-#include <QtConcurrent>
-#include <FileSystem.h>
-
-Technic::SingleZipPackInstallTask::SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion)
-{
- m_sourceUrl = sourceUrl;
- m_minecraftVersion = minecraftVersion;
-}
-
-bool Technic::SingleZipPackInstallTask::abort() {
- if(m_abortable)
- {
- return m_filesNetJob->abort();
- }
- return false;
-}
-
-void Technic::SingleZipPackInstallTask::executeTask()
-{
- setStatus(tr("Downloading modpack:\n%1").arg(m_sourceUrl.toString()));
-
- const QString path = m_sourceUrl.host() + '/' + m_sourceUrl.path();
- auto entry = ENV.metacache()->resolveEntry("general", path);
- entry->setStale(true);
- m_filesNetJob.reset(new NetJob(tr("Modpack download")));
- m_filesNetJob->addNetAction(Net::Download::makeCached(m_sourceUrl, entry));
- m_archivePath = entry->getFullPath();
- auto job = m_filesNetJob.get();
- connect(job, &NetJob::succeeded, this, &Technic::SingleZipPackInstallTask::downloadSucceeded);
- connect(job, &NetJob::progress, this, &Technic::SingleZipPackInstallTask::downloadProgressChanged);
- connect(job, &NetJob::failed, this, &Technic::SingleZipPackInstallTask::downloadFailed);
- m_filesNetJob->start();
-}
-
-void Technic::SingleZipPackInstallTask::downloadSucceeded()
-{
- m_abortable = false;
-
- setStatus(tr("Extracting modpack"));
- QDir extractDir(FS::PathCombine(m_stagingPath, ".minecraft"));
- qDebug() << "Attempting to create instance from" << m_archivePath;
-
- // open the zip and find relevant files in it
- m_packZip.reset(new QuaZip(m_archivePath));
- if (!m_packZip->open(QuaZip::mdUnzip))
- {
- emitFailed(tr("Unable to open supplied modpack zip file."));
- return;
- }
- m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractSubDir, m_packZip.get(), QString(""), extractDir.absolutePath());
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &Technic::SingleZipPackInstallTask::extractFinished);
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &Technic::SingleZipPackInstallTask::extractAborted);
- m_extractFutureWatcher.setFuture(m_extractFuture);
- m_filesNetJob.reset();
-}
-
-void Technic::SingleZipPackInstallTask::downloadFailed(QString reason)
-{
- m_abortable = false;
- emitFailed(reason);
- m_filesNetJob.reset();
-}
-
-void Technic::SingleZipPackInstallTask::downloadProgressChanged(qint64 current, qint64 total)
-{
- m_abortable = true;
- setProgress(current / 2, total);
-}
-
-void Technic::SingleZipPackInstallTask::extractFinished()
-{
- m_packZip.reset();
- if (!m_extractFuture.result())
- {
- emitFailed(tr("Failed to extract modpack"));
- return;
- }
- QDir extractDir(m_stagingPath);
-
- qDebug() << "Fixing permissions for extracted pack files...";
- QDirIterator it(extractDir, QDirIterator::Subdirectories);
- while (it.hasNext())
- {
- auto filepath = it.next();
- QFileInfo file(filepath);
- auto permissions = QFile::permissions(filepath);
- auto origPermissions = permissions;
- if (file.isDir())
- {
- // Folder +rwx for current user
- permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser;
- }
- else
- {
- // File +rw for current user
- permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser;
- }
- if (origPermissions != permissions)
- {
- if (!QFile::setPermissions(filepath, permissions))
- {
- logWarning(tr("Could not fix permissions for %1").arg(filepath));
- }
- else
- {
- qDebug() << "Fixed" << filepath;
- }
- }
- }
-
- shared_qobject_ptr<Technic::TechnicPackProcessor> packProcessor = new Technic::TechnicPackProcessor();
- connect(packProcessor.get(), &Technic::TechnicPackProcessor::succeeded, this, &Technic::SingleZipPackInstallTask::emitSucceeded);
- connect(packProcessor.get(), &Technic::TechnicPackProcessor::failed, this, &Technic::SingleZipPackInstallTask::emitFailed);
- packProcessor->run(m_globalSettings, m_instName, m_instIcon, m_stagingPath, m_minecraftVersion);
-}
-
-void Technic::SingleZipPackInstallTask::extractAborted()
-{
- emitFailed(tr("Instance import has been aborted."));
-}
diff --git a/api/logic/modplatform/technic/SingleZipPackInstallTask.h b/api/logic/modplatform/technic/SingleZipPackInstallTask.h
deleted file mode 100644
index ec2ff605..00000000
--- a/api/logic/modplatform/technic/SingleZipPackInstallTask.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright 2013-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include "InstanceTask.h"
-#include "net/NetJob.h"
-#include "multimc_logic_export.h"
-
-#include "quazip.h"
-
-#include <QFutureWatcher>
-#include <QStringList>
-#include <QUrl>
-
-#include <nonstd/optional>
-
-namespace Technic {
-
-class MULTIMC_LOGIC_EXPORT SingleZipPackInstallTask : public InstanceTask
-{
- Q_OBJECT
-
-public:
- SingleZipPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion);
-
- bool canAbort() const override { return true; }
- bool abort() override;
-
-protected:
- void executeTask() override;
-
-
-private slots:
- void downloadSucceeded();
- void downloadFailed(QString reason);
- void downloadProgressChanged(qint64 current, qint64 total);
- void extractFinished();
- void extractAborted();
-
-private:
- bool m_abortable = false;
-
- QUrl m_sourceUrl;
- QString m_minecraftVersion;
- QString m_archivePath;
- NetJobPtr m_filesNetJob;
- std::unique_ptr<QuaZip> m_packZip;
- QFuture<nonstd::optional<QStringList>> m_extractFuture;
- QFutureWatcher<nonstd::optional<QStringList>> m_extractFutureWatcher;
-};
-
-} // namespace Technic
diff --git a/api/logic/modplatform/technic/SolderPackInstallTask.cpp b/api/logic/modplatform/technic/SolderPackInstallTask.cpp
deleted file mode 100644
index 1b4186d4..00000000
--- a/api/logic/modplatform/technic/SolderPackInstallTask.cpp
+++ /dev/null
@@ -1,207 +0,0 @@
-/* Copyright 2013-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "SolderPackInstallTask.h"
-
-#include <FileSystem.h>
-#include <Json.h>
-#include <QtConcurrentRun>
-#include <MMCZip.h>
-#include "TechnicPackProcessor.h"
-
-Technic::SolderPackInstallTask::SolderPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion)
-{
- m_sourceUrl = sourceUrl;
- m_minecraftVersion = minecraftVersion;
-}
-
-bool Technic::SolderPackInstallTask::abort() {
- if(m_abortable)
- {
- return m_filesNetJob->abort();
- }
- return false;
-}
-
-void Technic::SolderPackInstallTask::executeTask()
-{
- setStatus(tr("Finding recommended version:\n%1").arg(m_sourceUrl.toString()));
- m_filesNetJob.reset(new NetJob(tr("Finding recommended version")));
- m_filesNetJob->addNetAction(Net::Download::makeByteArray(m_sourceUrl, &m_response));
- auto job = m_filesNetJob.get();
- connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::versionSucceeded);
- connect(job, &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed);
- m_filesNetJob->start();
-}
-
-void Technic::SolderPackInstallTask::versionSucceeded()
-{
- try
- {
- QJsonDocument doc = Json::requireDocument(m_response);
- QJsonObject obj = Json::requireObject(doc);
- QString version = Json::requireString(obj, "recommended", "__placeholder__");
- m_sourceUrl = m_sourceUrl.toString() + '/' + version;
- }
- catch (const JSONValidationError &e)
- {
- emitFailed(e.cause());
- m_filesNetJob.reset();
- return;
- }
-
- setStatus(tr("Resolving modpack files:\n%1").arg(m_sourceUrl.toString()));
- m_filesNetJob.reset(new NetJob(tr("Resolving modpack files")));
- m_filesNetJob->addNetAction(Net::Download::makeByteArray(m_sourceUrl, &m_response));
- auto job = m_filesNetJob.get();
- connect(job, &NetJob::succeeded, this, &Technic::SolderPackInstallTask::fileListSucceeded);
- connect(job, &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed);
- m_filesNetJob->start();
-}
-
-void Technic::SolderPackInstallTask::fileListSucceeded()
-{
- setStatus(tr("Downloading modpack:"));
- QStringList modUrls;
- try
- {
- QJsonDocument doc = Json::requireDocument(m_response);
- QJsonObject obj = Json::requireObject(doc);
- QString minecraftVersion = Json::ensureString(obj, "minecraft", QString(), "__placeholder__");
- if (!minecraftVersion.isEmpty())
- m_minecraftVersion = minecraftVersion;
- QJsonArray mods = Json::requireArray(obj, "mods", "'mods'");
- for (auto mod: mods)
- {
- QJsonObject modObject = Json::requireObject(mod);
- modUrls.append(Json::requireString(modObject, "url", "'url'"));
- }
- }
- catch (const JSONValidationError &e)
- {
- emitFailed(e.cause());
- m_filesNetJob.reset();
- return;
- }
- m_filesNetJob.reset(new NetJob(tr("Downloading modpack")));
- int i = 0;
- for (auto &modUrl: modUrls)
- {
- auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(i));
- m_filesNetJob->addNetAction(Net::Download::makeFile(modUrl, path));
- i++;
- }
-
- m_modCount = modUrls.size();
-
- connect(m_filesNetJob.get(), &NetJob::succeeded, this, &Technic::SolderPackInstallTask::downloadSucceeded);
- connect(m_filesNetJob.get(), &NetJob::progress, this, &Technic::SolderPackInstallTask::downloadProgressChanged);
- connect(m_filesNetJob.get(), &NetJob::failed, this, &Technic::SolderPackInstallTask::downloadFailed);
- m_filesNetJob->start();
-}
-
-void Technic::SolderPackInstallTask::downloadSucceeded()
-{
- m_abortable = false;
-
- setStatus(tr("Extracting modpack"));
- m_filesNetJob.reset();
- m_extractFuture = QtConcurrent::run([this]()
- {
- int i = 0;
- QString extractDir = FS::PathCombine(m_stagingPath, ".minecraft");
- FS::ensureFolderPathExists(extractDir);
-
- while (m_modCount > i)
- {
- auto path = FS::PathCombine(m_outputDir.path(), QString("%1").arg(i));
- if (!MMCZip::extractDir(path, extractDir))
- {
- return false;
- }
- i++;
- }
- return true;
- });
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &Technic::SolderPackInstallTask::extractFinished);
- connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &Technic::SolderPackInstallTask::extractAborted);
- m_extractFutureWatcher.setFuture(m_extractFuture);
-}
-
-void Technic::SolderPackInstallTask::downloadFailed(QString reason)
-{
- m_abortable = false;
- emitFailed(reason);
- m_filesNetJob.reset();
-}
-
-void Technic::SolderPackInstallTask::downloadProgressChanged(qint64 current, qint64 total)
-{
- m_abortable = true;
- setProgress(current / 2, total);
-}
-
-void Technic::SolderPackInstallTask::extractFinished()
-{
- if (!m_extractFuture.result())
- {
- emitFailed(tr("Failed to extract modpack"));
- return;
- }
- QDir extractDir(m_stagingPath);
-
- qDebug() << "Fixing permissions for extracted pack files...";
- QDirIterator it(extractDir, QDirIterator::Subdirectories);
- while (it.hasNext())
- {
- auto filepath = it.next();
- QFileInfo file(filepath);
- auto permissions = QFile::permissions(filepath);
- auto origPermissions = permissions;
- if(file.isDir())
- {
- // Folder +rwx for current user
- permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser | QFileDevice::Permission::ExeUser;
- }
- else
- {
- // File +rw for current user
- permissions |= QFileDevice::Permission::ReadUser | QFileDevice::Permission::WriteUser;
- }
- if(origPermissions != permissions)
- {
- if(!QFile::setPermissions(filepath, permissions))
- {
- logWarning(tr("Could not fix permissions for %1").arg(filepath));
- }
- else
- {
- qDebug() << "Fixed" << filepath;
- }
- }
- }
-
- shared_qobject_ptr<Technic::TechnicPackProcessor> packProcessor = new Technic::TechnicPackProcessor();
- connect(packProcessor.get(), &Technic::TechnicPackProcessor::succeeded, this, &Technic::SolderPackInstallTask::emitSucceeded);
- connect(packProcessor.get(), &Technic::TechnicPackProcessor::failed, this, &Technic::SolderPackInstallTask::emitFailed);
- packProcessor->run(m_globalSettings, m_instName, m_instIcon, m_stagingPath, m_minecraftVersion, true);
-}
-
-void Technic::SolderPackInstallTask::extractAborted()
-{
- emitFailed(tr("Instance import has been aborted."));
- return;
-}
-
diff --git a/api/logic/modplatform/technic/SolderPackInstallTask.h b/api/logic/modplatform/technic/SolderPackInstallTask.h
deleted file mode 100644
index 9f0f20a9..00000000
--- a/api/logic/modplatform/technic/SolderPackInstallTask.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Copyright 2013-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <InstanceTask.h>
-#include <net/NetJob.h>
-#include <tasks/Task.h>
-
-#include <QUrl>
-
-namespace Technic
-{
- class MULTIMC_LOGIC_EXPORT SolderPackInstallTask : public InstanceTask
- {
- Q_OBJECT
- public:
- explicit SolderPackInstallTask(const QUrl &sourceUrl, const QString &minecraftVersion);
-
- bool canAbort() const override { return true; }
- bool abort() override;
-
- protected:
- //! Entry point for tasks.
- virtual void executeTask() override;
-
- private slots:
- void versionSucceeded();
- void fileListSucceeded();
- void downloadSucceeded();
- void downloadFailed(QString reason);
- void downloadProgressChanged(qint64 current, qint64 total);
- void extractFinished();
- void extractAborted();
-
- private:
- bool m_abortable = false;
-
- NetJobPtr m_filesNetJob;
- QUrl m_sourceUrl;
- QString m_minecraftVersion;
- QByteArray m_response;
- QTemporaryDir m_outputDir;
- int m_modCount;
- QFuture<bool> m_extractFuture;
- QFutureWatcher<bool> m_extractFutureWatcher;
- };
-}
diff --git a/api/logic/modplatform/technic/TechnicPackProcessor.cpp b/api/logic/modplatform/technic/TechnicPackProcessor.cpp
deleted file mode 100644
index 52979b7c..00000000
--- a/api/logic/modplatform/technic/TechnicPackProcessor.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* Copyright 2020-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "TechnicPackProcessor.h"
-
-#include <FileSystem.h>
-#include <Json.h>
-#include <minecraft/MinecraftInstance.h>
-#include <minecraft/PackProfile.h>
-#include <quazip.h>
-#include <quazipdir.h>
-#include <quazipfile.h>
-#include <settings/INISettingsObject.h>
-
-#include <memory>
-
-void Technic::TechnicPackProcessor::run(SettingsObjectPtr globalSettings, const QString &instName, const QString &instIcon, const QString &stagingPath, const QString &minecraftVersion, const bool isSolder)
-{
- QString minecraftPath = FS::PathCombine(stagingPath, ".minecraft");
- QString configPath = FS::PathCombine(stagingPath, "instance.cfg");
- auto instanceSettings = std::make_shared<INISettingsObject>(configPath);
- instanceSettings->registerSetting("InstanceType", "Legacy");
- instanceSettings->set("InstanceType", "OneSix");
- MinecraftInstance instance(globalSettings, instanceSettings, stagingPath);
-
- instance.setName(instName);
-
- if (instIcon != "default")
- {
- instance.setIconKey(instIcon);
- }
-
- auto components = instance.getPackProfile();
- components->buildingFromScratch();
-
- QByteArray data;
-
- QString modpackJar = FS::PathCombine(minecraftPath, "bin", "modpack.jar");
- QString versionJson = FS::PathCombine(minecraftPath, "bin", "version.json");
- QString fmlMinecraftVersion;
- if (QFile::exists(modpackJar))
- {
- QuaZip zipFile(modpackJar);
- if (!zipFile.open(QuaZip::mdUnzip))
- {
- emit failed(tr("Unable to open \"bin/modpack.jar\" file!"));
- return;
- }
- QuaZipDir zipFileRoot(&zipFile, "/");
- if (zipFileRoot.exists("/version.json"))
- {
- if (zipFileRoot.exists("/fmlversion.properties"))
- {
- zipFile.setCurrentFile("fmlversion.properties");
- QuaZipFile file(&zipFile);
- if (!file.open(QIODevice::ReadOnly))
- {
- emit failed(tr("Unable to open \"fmlversion.properties\"!"));
- return;
- }
- QByteArray fmlVersionData = file.readAll();
- file.close();
- INIFile iniFile;
- iniFile.loadFile(fmlVersionData);
- // If not present, this evaluates to a null string
- fmlMinecraftVersion = iniFile["fmlbuild.mcversion"].toString();
- }
- zipFile.setCurrentFile("version.json", QuaZip::csSensitive);
- QuaZipFile file(&zipFile);
- if (!file.open(QIODevice::ReadOnly))
- {
- emit failed(tr("Unable to open \"version.json\"!"));
- return;
- }
- data = file.readAll();
- file.close();
- }
- else
- {
- if (minecraftVersion.isEmpty())
- emit failed(tr("Could not find \"version.json\" inside \"bin/modpack.jar\", but minecraft version is unknown"));
- components->setComponentVersion("net.minecraft", minecraftVersion, true);
- components->installJarMods({modpackJar});
-
- // Forge for 1.4.7 and for 1.5.2 require extra libraries.
- // Figure out the forge version and add it as a component
- // (the code still comes from the jar mod installed above)
- if (zipFileRoot.exists("/forgeversion.properties"))
- {
- zipFile.setCurrentFile("forgeversion.properties", QuaZip::csSensitive);
- QuaZipFile file(&zipFile);
- if (!file.open(QIODevice::ReadOnly))
- {
- // Really shouldn't happen, but error handling shall not be forgotten
- emit failed(tr("Unable to open \"forgeversion.properties\""));
- return;
- }
- QByteArray forgeVersionData = file.readAll();
- file.close();
- INIFile iniFile;
- iniFile.loadFile(forgeVersionData);
- QString major, minor, revision, build;
- major = iniFile["forge.major.number"].toString();
- minor = iniFile["forge.minor.number"].toString();
- revision = iniFile["forge.revision.number"].toString();
- build = iniFile["forge.build.number"].toString();
-
- if (major.isEmpty() || minor.isEmpty() || revision.isEmpty() || build.isEmpty())
- {
- emit failed(tr("Invalid \"forgeversion.properties\"!"));
- return;
- }
-
- components->setComponentVersion("net.minecraftforge", major + '.' + minor + '.' + revision + '.' + build);
- }
-
- components->saveNow();
- emit succeeded();
- return;
- }
- }
- else if (QFile::exists(versionJson))
- {
- QFile file(versionJson);
- if (!file.open(QIODevice::ReadOnly))
- {
- emit failed(tr("Unable to open \"version.json\"!"));
- return;
- }
- data = file.readAll();
- file.close();
- }
- else
- {
- // This is the "Vanilla" modpack, excluded by the search code
- emit failed(tr("Unable to find a \"version.json\"!"));
- return;
- }
-
- try
- {
- QJsonDocument doc = Json::requireDocument(data);
- QJsonObject root = Json::requireObject(doc, "version.json");
- QString minecraftVersion = Json::ensureString(root, "inheritsFrom", QString(), "");
- if (minecraftVersion.isEmpty())
- {
- if (fmlMinecraftVersion.isEmpty())
- {
- emit failed(tr("Could not understand \"version.json\":\ninheritsFrom is missing"));
- return;
- }
- minecraftVersion = fmlMinecraftVersion;
- }
- components->setComponentVersion("net.minecraft", minecraftVersion, true);
- for (auto library: Json::ensureArray(root, "libraries", {}))
- {
- if (!library.isObject())
- {
- continue;
- }
-
- auto libraryObject = Json::ensureObject(library, {}, "");
- auto libraryName = Json::ensureString(libraryObject, "name", "", "");
-
- if (libraryName.startsWith("net.minecraftforge:forge:") && libraryName.contains('-'))
- {
- QString libraryVersion = libraryName.section(':', 2);
- if (!libraryVersion.startsWith("1.7.10-"))
- {
- components->setComponentVersion("net.minecraftforge", libraryName.section('-', 1));
- }
- else
- {
- // 1.7.10 versions sometimes look like 1.7.10-10.13.4.1614-1.7.10, this filters out the 10.13.4.1614 part
- components->setComponentVersion("net.minecraftforge", libraryName.section('-', 1, 1));
- }
- }
- else if (libraryName.startsWith("net.minecraftforge:minecraftforge:"))
- {
- components->setComponentVersion("net.minecraftforge", libraryName.section(':', 2));
- }
- else if (libraryName.startsWith("net.fabricmc:fabric-loader:"))
- {
- components->setComponentVersion("net.fabricmc.fabric-loader", libraryName.section(':', 2));
- }
- }
- }
- catch (const JSONValidationError &e)
- {
- emit failed(tr("Could not understand \"version.json\":\n") + e.cause());
- return;
- }
-
- components->saveNow();
- emit succeeded();
-}
diff --git a/api/logic/modplatform/technic/TechnicPackProcessor.h b/api/logic/modplatform/technic/TechnicPackProcessor.h
deleted file mode 100644
index 2ad803b3..00000000
--- a/api/logic/modplatform/technic/TechnicPackProcessor.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Copyright 2020-2021 MultiMC Contributors
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <QString>
-#include "settings/SettingsObject.h"
-
-namespace Technic
-{
- // not exporting it, only used in SingleZipPackInstallTask, InstanceImportTask and SolderPackInstallTask
- class TechnicPackProcessor : public QObject
- {
- Q_OBJECT
-
- signals:
- void succeeded();
- void failed(QString reason);
-
- public:
- void run(SettingsObjectPtr globalSettings, const QString &instName, const QString &instIcon, const QString &stagingPath, const QString &minecraftVersion=QString(), const bool isSolder = false);
- };
-}