Merge branch 'develop' into chore/add-compiler-warnings
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
@ -145,7 +145,8 @@ void EnsureMetadataTask::executeTask()
|
||||
connect(project_task.get(), &Task::finished, this, [=] {
|
||||
invalidade_leftover();
|
||||
project_task->deleteLater();
|
||||
m_current_task = nullptr;
|
||||
if (m_current_task)
|
||||
m_current_task.reset();
|
||||
});
|
||||
|
||||
m_current_task = project_task;
|
||||
@ -154,7 +155,8 @@ void EnsureMetadataTask::executeTask()
|
||||
|
||||
connect(version_task.get(), &Task::finished, [=] {
|
||||
version_task->deleteLater();
|
||||
m_current_task = nullptr;
|
||||
if (m_current_task)
|
||||
m_current_task.reset();
|
||||
});
|
||||
|
||||
if (m_mods.size() > 1)
|
||||
|
@ -21,6 +21,10 @@ bool Flame::FileResolvingTask::abort()
|
||||
|
||||
void Flame::FileResolvingTask::executeTask()
|
||||
{
|
||||
if (m_toProcess.files.isEmpty()) { // no file to resolve so leave it empty and emit success immediately
|
||||
emitSucceeded();
|
||||
return;
|
||||
}
|
||||
setStatus(tr("Resolving mod IDs..."));
|
||||
setProgress(0, 3);
|
||||
m_dljob.reset(new NetJob("Mod id resolver", m_network));
|
||||
@ -128,12 +132,13 @@ void Flame::FileResolvingTask::netJobFinished()
|
||||
m_checkJob->start();
|
||||
}
|
||||
|
||||
void Flame::FileResolvingTask::modrinthCheckFinished() {
|
||||
void Flame::FileResolvingTask::modrinthCheckFinished()
|
||||
{
|
||||
setProgress(2, 3);
|
||||
qDebug() << "Finished with blocked mods : " << blockedProjects.size();
|
||||
|
||||
for (auto it = blockedProjects.keyBegin(); it != blockedProjects.keyEnd(); it++) {
|
||||
auto &out = *it;
|
||||
auto& out = *it;
|
||||
auto bytes = blockedProjects[out];
|
||||
if (!out->resolved) {
|
||||
continue;
|
||||
@ -153,15 +158,13 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
|
||||
out->resolved = false;
|
||||
}
|
||||
}
|
||||
//copy to an output list and filter out projects found on modrinth
|
||||
// copy to an output list and filter out projects found on modrinth
|
||||
auto block = std::make_shared<QList<File*>>();
|
||||
auto it = blockedProjects.keys();
|
||||
std::copy_if(it.begin(), it.end(), std::back_inserter(*block), [](File *f) {
|
||||
return !f->resolved;
|
||||
});
|
||||
//Display not found mods early
|
||||
std::copy_if(it.begin(), it.end(), std::back_inserter(*block), [](File* f) { return !f->resolved; });
|
||||
// Display not found mods early
|
||||
if (!block->empty()) {
|
||||
//blocked mods found, we need the slug for displaying.... we need another job :D !
|
||||
// blocked mods found, we need the slug for displaying.... we need another job :D !
|
||||
m_slugJob.reset(new NetJob("Slug Job", m_network));
|
||||
int index = 0;
|
||||
for (auto mod : *block) {
|
||||
@ -173,8 +176,8 @@ void Flame::FileResolvingTask::modrinthCheckFinished() {
|
||||
QObject::connect(dl.get(), &Net::Download::succeeded, [block, index, output]() {
|
||||
auto mod = block->at(index); // use the shared_ptr so it is captured and only freed when we are done
|
||||
auto json = QJsonDocument::fromJson(*output);
|
||||
auto base = Json::requireString(Json::requireObject(Json::requireObject(Json::requireObject(json),"data"),"links"),
|
||||
"websiteUrl");
|
||||
auto base =
|
||||
Json::requireString(Json::requireObject(Json::requireObject(Json::requireObject(json), "data"), "links"), "websiteUrl");
|
||||
auto link = QString("%1/download/%2").arg(base, QString::number(mod->fileId));
|
||||
mod->websiteUrl = link;
|
||||
});
|
||||
|
@ -57,15 +57,11 @@
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
|
||||
#include "meta/Index.h"
|
||||
#include "meta/VersionList.h"
|
||||
#include "minecraft/World.h"
|
||||
#include "minecraft/mod/tasks/LocalResourceParse.h"
|
||||
|
||||
|
||||
const static QMap<QString, QString> forgemap = { { "1.2.5", "3.4.9.171" },
|
||||
{ "1.4.2", "6.0.1.355" },
|
||||
{ "1.4.7", "6.6.2.534" },
|
||||
{ "1.5.2", "7.8.1.737" } };
|
||||
|
||||
static const FlameAPI api;
|
||||
|
||||
bool FlameCreationTask::abort()
|
||||
@ -259,6 +255,56 @@ bool FlameCreationTask::updateInstance()
|
||||
return false;
|
||||
}
|
||||
|
||||
QString FlameCreationTask::getVersionForLoader(QString uid, QString loaderType, QString loaderVersion, QString mcVersion)
|
||||
{
|
||||
if (loaderVersion == "recommended") {
|
||||
auto vlist = APPLICATION->metadataIndex()->get(uid);
|
||||
if (!vlist) {
|
||||
setError(tr("Failed to get local metadata index for %1").arg(uid));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!vlist->isLoaded()) {
|
||||
QEventLoop loadVersionLoop;
|
||||
auto task = vlist->getLoadTask();
|
||||
connect(task.get(), &Task::finished, &loadVersionLoop, &QEventLoop::quit);
|
||||
if (!task->isRunning())
|
||||
task->start();
|
||||
|
||||
loadVersionLoop.exec();
|
||||
}
|
||||
|
||||
for (auto version : vlist->versions()) {
|
||||
// first recommended build we find, we use.
|
||||
if (!version->isRecommended())
|
||||
continue;
|
||||
auto reqs = version->requiredSet();
|
||||
|
||||
// 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 (loaderType == "forge") {
|
||||
auto iter = std::find_if(reqs.begin(), reqs.end(), [mcVersion](const Meta::Require& req) {
|
||||
return req.uid == "net.minecraft" && req.equalsVersion == mcVersion;
|
||||
});
|
||||
if (iter == reqs.end())
|
||||
continue;
|
||||
}
|
||||
return version->descriptor();
|
||||
}
|
||||
|
||||
setError(tr("Failed to find version for %1 loader").arg(loaderType));
|
||||
return {};
|
||||
}
|
||||
|
||||
if (loaderVersion.isEmpty()) {
|
||||
emitFailed(tr("No loader version set for modpack!"));
|
||||
return {};
|
||||
}
|
||||
|
||||
return loaderVersion;
|
||||
}
|
||||
|
||||
bool FlameCreationTask::createInstance()
|
||||
{
|
||||
QEventLoop loop;
|
||||
@ -297,22 +343,29 @@ bool FlameCreationTask::createInstance()
|
||||
}
|
||||
}
|
||||
|
||||
QString forgeVersion;
|
||||
QString fabricVersion;
|
||||
// TODO: is Quilt relevant here?
|
||||
QString loaderType;
|
||||
QString loaderUid;
|
||||
QString loaderVersion;
|
||||
|
||||
for (auto& loader : m_pack.minecraft.modLoaders) {
|
||||
auto id = loader.id;
|
||||
if (id.startsWith("forge-")) {
|
||||
id.remove("forge-");
|
||||
forgeVersion = id;
|
||||
continue;
|
||||
}
|
||||
if (id.startsWith("fabric-")) {
|
||||
loaderType = "forge";
|
||||
loaderUid = "net.minecraftforge";
|
||||
} else if (loaderType == "fabric") {
|
||||
id.remove("fabric-");
|
||||
fabricVersion = id;
|
||||
loaderType = "fabric";
|
||||
loaderUid = "net.fabricmc.fabric-loader";
|
||||
} else if (loaderType == "quilt") {
|
||||
id.remove("quilt-");
|
||||
loaderType = "quilt";
|
||||
loaderUid = "org.quiltmc.quilt-loader";
|
||||
} else {
|
||||
logWarning(tr("Unknown mod loader in manifest: %1").arg(id));
|
||||
continue;
|
||||
}
|
||||
logWarning(tr("Unknown mod loader in manifest: %1").arg(id));
|
||||
loaderVersion = id;
|
||||
}
|
||||
|
||||
QString configPath = FS::PathCombine(m_stagingPath, "instance.cfg");
|
||||
@ -329,19 +382,12 @@ bool FlameCreationTask::createInstance()
|
||||
auto components = instance.getPackProfile();
|
||||
components->buildingFromScratch();
|
||||
components->setComponentVersion("net.minecraft", mcVersion, true);
|
||||
if (!forgeVersion.isEmpty()) {
|
||||
// FIXME: dirty, nasty, hack. Proper solution requires dependency resolution and knowledge of the metadata.
|
||||
if (forgeVersion == "recommended") {
|
||||
if (forgemap.contains(mcVersion)) {
|
||||
forgeVersion = forgemap[mcVersion];
|
||||
} else {
|
||||
logWarning(tr("Could not map recommended Forge version for Minecraft %1").arg(mcVersion));
|
||||
}
|
||||
}
|
||||
components->setComponentVersion("net.minecraftforge", forgeVersion);
|
||||
if (!loaderType.isEmpty()) {
|
||||
auto version = getVersionForLoader(loaderUid, loaderType, loaderVersion, mcVersion);
|
||||
if (version.isEmpty())
|
||||
return false;
|
||||
components->setComponentVersion(loaderUid, version);
|
||||
}
|
||||
if (!fabricVersion.isEmpty())
|
||||
components->setComponentVersion("net.fabricmc.fabric-loader", fabricVersion);
|
||||
|
||||
if (m_instIcon != "default") {
|
||||
instance.setIconKey(m_instIcon);
|
||||
@ -502,7 +548,7 @@ void FlameCreationTask::setupDownloadJob(QEventLoop& loop)
|
||||
m_files_job.reset();
|
||||
setError(reason);
|
||||
});
|
||||
connect(m_files_job.get(), &NetJob::progress, this, [this](qint64 current, qint64 total){
|
||||
connect(m_files_job.get(), &NetJob::progress, this, [this](qint64 current, qint64 total) {
|
||||
setDetails(tr("%1 out of %2 complete").arg(current).arg(total));
|
||||
setProgress(current, total);
|
||||
});
|
||||
@ -545,7 +591,6 @@ void FlameCreationTask::copyBlockedMods(QList<BlockedMod> const& blocked_mods)
|
||||
setAbortable(true);
|
||||
}
|
||||
|
||||
|
||||
void FlameCreationTask::validateZIPResouces()
|
||||
{
|
||||
qDebug() << "Validating whether resources stored as .zip are in the right place";
|
||||
@ -563,11 +608,13 @@ void FlameCreationTask::validateZIPResouces()
|
||||
if (FS::move(localPath, destPath)) {
|
||||
return destPath;
|
||||
}
|
||||
} else {
|
||||
qDebug() << "Target folder of" << fileName << "is correct at" << targetFolder;
|
||||
}
|
||||
return localPath;
|
||||
};
|
||||
|
||||
auto installWorld = [this](QString worldPath){
|
||||
auto installWorld = [this](QString worldPath) {
|
||||
qDebug() << "Installing World from" << worldPath;
|
||||
QFileInfo worldFileInfo(worldPath);
|
||||
World w(worldFileInfo);
|
||||
@ -584,29 +631,29 @@ void FlameCreationTask::validateZIPResouces()
|
||||
QString worldPath;
|
||||
|
||||
switch (type) {
|
||||
case PackedResourceType::ResourcePack :
|
||||
validatePath(fileName, targetFolder, "resourcepacks");
|
||||
break;
|
||||
case PackedResourceType::TexturePack :
|
||||
validatePath(fileName, targetFolder, "texturepacks");
|
||||
break;
|
||||
case PackedResourceType::DataPack :
|
||||
validatePath(fileName, targetFolder, "datapacks");
|
||||
break;
|
||||
case PackedResourceType::Mod :
|
||||
case PackedResourceType::Mod:
|
||||
validatePath(fileName, targetFolder, "mods");
|
||||
break;
|
||||
case PackedResourceType::ShaderPack :
|
||||
case PackedResourceType::ResourcePack:
|
||||
validatePath(fileName, targetFolder, "resourcepacks");
|
||||
break;
|
||||
case PackedResourceType::TexturePack:
|
||||
validatePath(fileName, targetFolder, "texturepacks");
|
||||
break;
|
||||
case PackedResourceType::DataPack:
|
||||
validatePath(fileName, targetFolder, "datapacks");
|
||||
break;
|
||||
case PackedResourceType::ShaderPack:
|
||||
// in theroy flame API can't do this but who knows, that *may* change ?
|
||||
// better to handle it if it *does* occure in the future
|
||||
validatePath(fileName, targetFolder, "shaderpacks");
|
||||
break;
|
||||
case PackedResourceType::WorldSave :
|
||||
case PackedResourceType::WorldSave:
|
||||
worldPath = validatePath(fileName, targetFolder, "saves");
|
||||
installWorld(worldPath);
|
||||
break;
|
||||
case PackedResourceType::UNKNOWN :
|
||||
default :
|
||||
case PackedResourceType::UNKNOWN:
|
||||
default:
|
||||
qDebug() << "Can't Identify" << fileName << "at" << localPath << ", leaving it where it is.";
|
||||
break;
|
||||
}
|
||||
|
@ -57,10 +57,7 @@ class FlameCreationTask final : public InstanceCreationTask {
|
||||
QString id,
|
||||
QString version_id,
|
||||
QString original_instance_id = {})
|
||||
: InstanceCreationTask()
|
||||
, m_parent(parent)
|
||||
, m_managed_id(std::move(id))
|
||||
, m_managed_version_id(std::move(version_id))
|
||||
: InstanceCreationTask(), m_parent(parent), m_managed_id(std::move(id)), m_managed_version_id(std::move(version_id))
|
||||
{
|
||||
setStagingPath(staging_path);
|
||||
setParentSettings(global_settings);
|
||||
@ -78,6 +75,7 @@ class FlameCreationTask final : public InstanceCreationTask {
|
||||
void setupDownloadJob(QEventLoop&);
|
||||
void copyBlockedMods(QList<BlockedMod> const& blocked_mods);
|
||||
void validateZIPResouces();
|
||||
QString getVersionForLoader(QString uid, QString loaderType, QString version, QString mcVersion);
|
||||
|
||||
private:
|
||||
QWidget* m_parent = nullptr;
|
||||
|
@ -166,7 +166,7 @@ void FlamePackExportTask::collectHashes()
|
||||
stepProgress(*progressStep);
|
||||
emitFailed(reason);
|
||||
});
|
||||
connect(hashingTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress);
|
||||
connect(hashingTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propagateStepProgress);
|
||||
|
||||
connect(hashingTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) {
|
||||
progressStep->update(current, total);
|
||||
|
@ -76,13 +76,8 @@ bool Flame::File::parseFromObject(const QJsonObject& obj, bool throw_on_blocked
|
||||
// It is also optional
|
||||
type = File::Type::SingleFile;
|
||||
|
||||
if (fileName.endsWith(".zip")) {
|
||||
// this is probably a resource pack
|
||||
targetFolder = "resourcepacks";
|
||||
} else {
|
||||
// this is probably a mod, dunno what else could modpacks download
|
||||
targetFolder = "mods";
|
||||
}
|
||||
targetFolder = "mods";
|
||||
|
||||
// get the hash
|
||||
hash = QString();
|
||||
auto hashes = Json::ensureArray(obj, "hashes");
|
||||
|
200
launcher/modplatform/helpers/ExportToModList.cpp
Normal file
200
launcher/modplatform/helpers/ExportToModList.cpp
Normal file
@ -0,0 +1,200 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "ExportToModList.h"
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace ExportToModList {
|
||||
QString toHTML(QList<Mod*> mods, OptionalData extraData)
|
||||
{
|
||||
QStringList lines;
|
||||
for (auto mod : mods) {
|
||||
auto meta = mod->metadata();
|
||||
auto modName = mod->name().toHtmlEscaped();
|
||||
if (extraData & Url) {
|
||||
auto url = mod->metaurl().toHtmlEscaped();
|
||||
if (!url.isEmpty())
|
||||
modName = QString("<a href=\"%1\">%2</a>").arg(url, modName);
|
||||
}
|
||||
auto line = modName;
|
||||
if (extraData & Version) {
|
||||
auto ver = mod->version();
|
||||
if (ver.isEmpty() && meta != nullptr)
|
||||
ver = meta->version().toString();
|
||||
if (!ver.isEmpty())
|
||||
line += QString(" [%1]").arg(ver.toHtmlEscaped());
|
||||
}
|
||||
if (extraData & Authors && !mod->authors().isEmpty())
|
||||
line += " by " + mod->authors().join(", ").toHtmlEscaped();
|
||||
lines.append(QString("<li>%1</li>").arg(line));
|
||||
}
|
||||
return QString("<html><body><ul>\n\t%1\n</ul></body></html>").arg(lines.join("\n\t"));
|
||||
}
|
||||
|
||||
QString toMarkdown(QList<Mod*> mods, OptionalData extraData)
|
||||
{
|
||||
QStringList lines;
|
||||
for (auto mod : mods) {
|
||||
auto meta = mod->metadata();
|
||||
auto modName = mod->name();
|
||||
if (extraData & Url) {
|
||||
auto url = mod->metaurl();
|
||||
if (!url.isEmpty())
|
||||
modName = QString("[%1](%2)").arg(modName, url);
|
||||
}
|
||||
auto line = modName;
|
||||
if (extraData & Version) {
|
||||
auto ver = mod->version();
|
||||
if (ver.isEmpty() && meta != nullptr)
|
||||
ver = meta->version().toString();
|
||||
if (!ver.isEmpty())
|
||||
line += QString(" [%1]").arg(ver);
|
||||
}
|
||||
if (extraData & Authors && !mod->authors().isEmpty())
|
||||
line += " by " + mod->authors().join(", ");
|
||||
lines << "- " + line;
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
QString toPlainTXT(QList<Mod*> mods, OptionalData extraData)
|
||||
{
|
||||
QStringList lines;
|
||||
for (auto mod : mods) {
|
||||
auto meta = mod->metadata();
|
||||
auto modName = mod->name();
|
||||
|
||||
auto line = modName;
|
||||
if (extraData & Url) {
|
||||
auto url = mod->metaurl();
|
||||
if (!url.isEmpty())
|
||||
line += QString(" (%1)").arg(url);
|
||||
}
|
||||
if (extraData & Version) {
|
||||
auto ver = mod->version();
|
||||
if (ver.isEmpty() && meta != nullptr)
|
||||
ver = meta->version().toString();
|
||||
if (!ver.isEmpty())
|
||||
line += QString(" [%1]").arg(ver);
|
||||
}
|
||||
if (extraData & Authors && !mod->authors().isEmpty())
|
||||
line += " by " + mod->authors().join(", ");
|
||||
lines << line;
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
QString toJSON(QList<Mod*> mods, OptionalData extraData)
|
||||
{
|
||||
QJsonArray lines;
|
||||
for (auto mod : mods) {
|
||||
auto meta = mod->metadata();
|
||||
auto modName = mod->name();
|
||||
QJsonObject line;
|
||||
line["name"] = modName;
|
||||
if (extraData & Url) {
|
||||
auto url = mod->metaurl();
|
||||
if (!url.isEmpty())
|
||||
line["url"] = url;
|
||||
}
|
||||
if (extraData & Version) {
|
||||
auto ver = mod->version();
|
||||
if (ver.isEmpty() && meta != nullptr)
|
||||
ver = meta->version().toString();
|
||||
if (!ver.isEmpty())
|
||||
line["version"] = ver;
|
||||
}
|
||||
if (extraData & Authors && !mod->authors().isEmpty())
|
||||
line["authors"] = QJsonArray::fromStringList(mod->authors());
|
||||
lines << line;
|
||||
}
|
||||
QJsonDocument doc;
|
||||
doc.setArray(lines);
|
||||
return doc.toJson();
|
||||
}
|
||||
|
||||
QString toCSV(QList<Mod*> mods, OptionalData extraData)
|
||||
{
|
||||
QStringList lines;
|
||||
for (auto mod : mods) {
|
||||
QStringList data;
|
||||
auto meta = mod->metadata();
|
||||
auto modName = mod->name();
|
||||
|
||||
data << modName;
|
||||
if (extraData & Url)
|
||||
data << mod->metaurl();
|
||||
if (extraData & Version) {
|
||||
auto ver = mod->version();
|
||||
if (ver.isEmpty() && meta != nullptr)
|
||||
ver = meta->version().toString();
|
||||
data << ver;
|
||||
}
|
||||
if (extraData & Authors) {
|
||||
QString authors;
|
||||
if (mod->authors().length() == 1)
|
||||
authors = mod->authors().back();
|
||||
else if (mod->authors().length() > 1)
|
||||
authors = QString("\"%1\"").arg(mod->authors().join(","));
|
||||
data << authors;
|
||||
}
|
||||
lines << data.join(",");
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
|
||||
QString exportToModList(QList<Mod*> mods, Formats format, OptionalData extraData)
|
||||
{
|
||||
switch (format) {
|
||||
case HTML:
|
||||
return toHTML(mods, extraData);
|
||||
case MARKDOWN:
|
||||
return toMarkdown(mods, extraData);
|
||||
case PLAINTXT:
|
||||
return toPlainTXT(mods, extraData);
|
||||
case JSON:
|
||||
return toJSON(mods, extraData);
|
||||
case CSV:
|
||||
return toCSV(mods, extraData);
|
||||
default: {
|
||||
return QString("unknown format:%1").arg(format);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString exportToModList(QList<Mod*> mods, QString lineTemplate)
|
||||
{
|
||||
QStringList lines;
|
||||
for (auto mod : mods) {
|
||||
auto meta = mod->metadata();
|
||||
auto modName = mod->name();
|
||||
auto url = mod->metaurl();
|
||||
auto ver = mod->version();
|
||||
if (ver.isEmpty() && meta != nullptr)
|
||||
ver = meta->version().toString();
|
||||
auto authors = mod->authors().join(", ");
|
||||
lines << QString(lineTemplate)
|
||||
.replace("{name}", modName)
|
||||
.replace("{url}", url)
|
||||
.replace("{version}", ver)
|
||||
.replace("{authors}", authors);
|
||||
}
|
||||
return lines.join("\n");
|
||||
}
|
||||
} // namespace ExportToModList
|
33
launcher/modplatform/helpers/ExportToModList.h
Normal file
33
launcher/modplatform/helpers/ExportToModList.h
Normal file
@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Prism Launcher - Minecraft Launcher
|
||||
* Copyright (c) 2023 Trial97 <alexandru.tripon97@gmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <QList>
|
||||
#include <QString>
|
||||
#include "minecraft/mod/Mod.h"
|
||||
|
||||
namespace ExportToModList {
|
||||
|
||||
enum Formats { HTML, MARKDOWN, PLAINTXT, JSON, CSV, CUSTOM };
|
||||
enum OptionalData {
|
||||
Authors = 1 << 0,
|
||||
Url = 1 << 1,
|
||||
Version = 1 << 2,
|
||||
};
|
||||
QString exportToModList(QList<Mod*> mods, Formats format, OptionalData extraData);
|
||||
QString exportToModList(QList<Mod*> mods, QString lineTemplate);
|
||||
} // namespace ExportToModList
|
@ -37,16 +37,16 @@
|
||||
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include "MMCZip.h"
|
||||
#include "BaseInstance.h"
|
||||
#include "FileSystem.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
#include "MMCZip.h"
|
||||
#include "minecraft/GradleSpecifier.h"
|
||||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/PackProfile.h"
|
||||
#include "minecraft/GradleSpecifier.h"
|
||||
#include "settings/INISettingsObject.h"
|
||||
|
||||
#include "BuildConfig.h"
|
||||
#include "Application.h"
|
||||
#include "BuildConfig.h"
|
||||
|
||||
namespace LegacyFTB {
|
||||
|
||||
@ -65,6 +65,7 @@ void PackInstallTask::executeTask()
|
||||
void PackInstallTask::downloadPack()
|
||||
{
|
||||
setStatus(tr("Downloading zip for %1").arg(m_pack.name));
|
||||
setProgress(1, 4);
|
||||
setAbortable(false);
|
||||
|
||||
archivePath = QString("%1/%2/%3").arg(m_pack.dir, m_version.replace(".", "_"), m_pack.file);
|
||||
@ -78,11 +79,10 @@ void PackInstallTask::downloadPack()
|
||||
}
|
||||
netJobContainer->addNetAction(Net::Download::makeFile(url, archivePath));
|
||||
|
||||
connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::onDownloadSucceeded);
|
||||
connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::onDownloadFailed);
|
||||
connect(netJobContainer.get(), &NetJob::progress, this, &PackInstallTask::onDownloadProgress);
|
||||
connect(netJobContainer.get(), &NetJob::succeeded, this, &PackInstallTask::unzip);
|
||||
connect(netJobContainer.get(), &NetJob::failed, this, &PackInstallTask::emitFailed);
|
||||
connect(netJobContainer.get(), &NetJob::stepProgress, this, &PackInstallTask::propagateStepProgress);
|
||||
connect(netJobContainer.get(), &NetJob::aborted, this, &PackInstallTask::onDownloadAborted);
|
||||
connect(netJobContainer.get(), &NetJob::aborted, this, &PackInstallTask::emitAborted);
|
||||
|
||||
netJobContainer->start();
|
||||
|
||||
@ -90,27 +90,6 @@ void PackInstallTask::downloadPack()
|
||||
progress(1, 4);
|
||||
}
|
||||
|
||||
void PackInstallTask::onDownloadSucceeded()
|
||||
{
|
||||
unzip();
|
||||
}
|
||||
|
||||
void PackInstallTask::onDownloadFailed(QString reason)
|
||||
{
|
||||
emitFailed(reason);
|
||||
}
|
||||
|
||||
void PackInstallTask::onDownloadProgress(qint64 current, qint64 total)
|
||||
{
|
||||
progress(current, total * 4);
|
||||
setStatus(tr("Downloading zip for %1 (%2%)").arg(m_pack.name).arg(current / 10));
|
||||
}
|
||||
|
||||
void PackInstallTask::onDownloadAborted()
|
||||
{
|
||||
emitAborted();
|
||||
}
|
||||
|
||||
void PackInstallTask::unzip()
|
||||
{
|
||||
setStatus(tr("Extracting modpack"));
|
||||
@ -120,16 +99,17 @@ void PackInstallTask::unzip()
|
||||
QDir extractDir(m_stagingPath);
|
||||
|
||||
m_packZip.reset(new QuaZip(archivePath));
|
||||
if(!m_packZip->open(QuaZip::mdUnzip))
|
||||
{
|
||||
if (!m_packZip->open(QuaZip::mdUnzip)) {
|
||||
emitFailed(tr("Failed to open modpack file %1!").arg(archivePath));
|
||||
return;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload<QString, QString>::of(MMCZip::extractDir), archivePath, extractDir.absolutePath() + "/unzip");
|
||||
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), QOverload<QString, QString>::of(MMCZip::extractDir), archivePath,
|
||||
extractDir.absolutePath() + "/unzip");
|
||||
#else
|
||||
m_extractFuture = QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip");
|
||||
m_extractFuture =
|
||||
QtConcurrent::run(QThreadPool::globalInstance(), MMCZip::extractDir, archivePath, extractDir.absolutePath() + "/unzip");
|
||||
#endif
|
||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::finished, this, &PackInstallTask::onUnzipFinished);
|
||||
connect(&m_extractFutureWatcher, &QFutureWatcher<QStringList>::canceled, this, &PackInstallTask::onUnzipCanceled);
|
||||
@ -151,11 +131,9 @@ void PackInstallTask::install()
|
||||
setStatus(tr("Installing modpack"));
|
||||
progress(3, 4);
|
||||
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"))
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -172,23 +150,20 @@ void PackInstallTask::install()
|
||||
|
||||
bool fallback = true;
|
||||
|
||||
//handle different versions
|
||||
// handle different versions
|
||||
QFile packJson(m_stagingPath + "/.minecraft/pack.json");
|
||||
QDir jarmodDir = QDir(m_stagingPath + "/unzip/instMods");
|
||||
if(packJson.exists())
|
||||
{
|
||||
if (packJson.exists()) {
|
||||
packJson.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QJsonDocument doc = QJsonDocument::fromJson(packJson.readAll());
|
||||
packJson.close();
|
||||
|
||||
//we only care about the libs
|
||||
// we only care about the libs
|
||||
QJsonArray libs = doc.object().value("libraries").toArray();
|
||||
|
||||
foreach (const QJsonValue &value, libs)
|
||||
{
|
||||
foreach (const QJsonValue& value, libs) {
|
||||
QString nameValue = value.toObject().value("name").toString();
|
||||
if(!nameValue.startsWith("net.minecraftforge"))
|
||||
{
|
||||
if (!nameValue.startsWith("net.minecraftforge")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -199,16 +174,13 @@ void PackInstallTask::install()
|
||||
fallback = false;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(jarmodDir.exists())
|
||||
{
|
||||
if (jarmodDir.exists()) {
|
||||
qDebug() << "Found jarmods, installing...";
|
||||
|
||||
QStringList jarmods;
|
||||
for (auto info: jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files))
|
||||
{
|
||||
for (auto info : jarmodDir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files)) {
|
||||
qDebug() << "Jarmod:" << info.fileName();
|
||||
jarmods.push_back(info.absoluteFilePath());
|
||||
}
|
||||
@ -217,12 +189,11 @@ void PackInstallTask::install()
|
||||
fallback = false;
|
||||
}
|
||||
|
||||
//just nuke unzip directory, it s not needed anymore
|
||||
// just nuke unzip directory, it s not needed anymore
|
||||
FS::deletePath(m_stagingPath + "/unzip");
|
||||
|
||||
if(fallback)
|
||||
{
|
||||
//TODO: Some fallback mechanism... or just keep failing!
|
||||
if (fallback) {
|
||||
// TODO: Some fallback mechanism... or just keep failing!
|
||||
emitFailed(tr("No installation method found!"));
|
||||
return;
|
||||
}
|
||||
@ -232,8 +203,7 @@ void PackInstallTask::install()
|
||||
progress(4, 4);
|
||||
|
||||
instance.setName(name());
|
||||
if(m_instIcon == "default")
|
||||
{
|
||||
if (m_instIcon == "default") {
|
||||
m_instIcon = "ftb_logo";
|
||||
}
|
||||
instance.setIconKey(m_instIcon);
|
||||
@ -252,4 +222,4 @@ bool PackInstallTask::abort()
|
||||
return InstanceTask::abort();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace LegacyFTB
|
||||
|
@ -1,12 +1,12 @@
|
||||
#pragma once
|
||||
#include "InstanceTask.h"
|
||||
#include "net/NetJob.h"
|
||||
#include <quazip/quazip.h>
|
||||
#include <quazip/quazipdir.h>
|
||||
#include "InstanceTask.h"
|
||||
#include "PackHelpers.h"
|
||||
#include "meta/Index.h"
|
||||
#include "meta/Version.h"
|
||||
#include "meta/VersionList.h"
|
||||
#include "PackHelpers.h"
|
||||
#include "net/NetJob.h"
|
||||
|
||||
#include "net/NetJob.h"
|
||||
|
||||
@ -14,36 +14,31 @@
|
||||
|
||||
namespace LegacyFTB {
|
||||
|
||||
class PackInstallTask : public InstanceTask
|
||||
{
|
||||
class PackInstallTask : public InstanceTask {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
public:
|
||||
explicit PackInstallTask(shared_qobject_ptr<QNetworkAccessManager> network, Modpack pack, QString version);
|
||||
virtual ~PackInstallTask(){}
|
||||
virtual ~PackInstallTask() {}
|
||||
|
||||
bool canAbort() const override { return true; }
|
||||
bool abort() override;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
//! Entry point for tasks.
|
||||
virtual void executeTask() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
void downloadPack();
|
||||
void unzip();
|
||||
void install();
|
||||
|
||||
private slots:
|
||||
void onDownloadSucceeded();
|
||||
void onDownloadFailed(QString reason);
|
||||
void onDownloadProgress(qint64 current, qint64 total);
|
||||
void onDownloadAborted();
|
||||
private slots:
|
||||
|
||||
void onUnzipFinished();
|
||||
void onUnzipCanceled();
|
||||
|
||||
private: /* data */
|
||||
private: /* data */
|
||||
shared_qobject_ptr<QNetworkAccessManager> m_network;
|
||||
bool abortable = false;
|
||||
std::unique_ptr<QuaZip> m_packZip;
|
||||
@ -56,4 +51,4 @@ private: /* data */
|
||||
QString m_version;
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace LegacyFTB
|
||||
|
Reference in New Issue
Block a user