simplify flame export

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>

s
This commit is contained in:
Trial97 2023-07-17 16:25:51 +03:00
parent 0bf70d677e
commit 455c495338
No known key found for this signature in database
GPG Key ID: 55EF5DA53DB36318
2 changed files with 49 additions and 92 deletions

View File

@ -26,6 +26,7 @@
#include <QMessageBox> #include <QMessageBox>
#include <QtConcurrentRun> #include <QtConcurrentRun>
#include <algorithm> #include <algorithm>
#include <iterator>
#include <memory> #include <memory>
#include "Json.h" #include "Json.h"
#include "MMCZip.h" #include "MMCZip.h"
@ -64,20 +65,11 @@ void FlamePackExportTask::executeTask()
bool FlamePackExportTask::abort() bool FlamePackExportTask::abort()
{ {
if (task != nullptr) { if (task) {
task->abort(); task->abort();
task = nullptr;
emitAborted(); emitAborted();
return true; return true;
} }
if (buildZipFuture.isRunning()) {
buildZipFuture.cancel();
// NOTE: Here we don't do `emitAborted()` because it will be done when `buildZipFuture` actually cancels, which may not occur
// immediately.
return true;
}
return false; return false;
} }
@ -336,89 +328,44 @@ void FlamePackExportTask::buildZip()
setStatus(tr("Adding files...")); setStatus(tr("Adding files..."));
setProgress(4, 5); setProgress(4, 5);
buildZipFuture = QtConcurrent::run(QThreadPool::globalInstance(), [this]() { auto zipTask = makeShared<MMCZip::ExportToZipTask>(output, gameRoot, files, "overrides/", true);
QuaZip zip(output); zipTask->addExtraFile("manifest.json", generateIndex());
if (!zip.open(QuaZip::mdCreate)) { zipTask->addExtraFile("modlist.html", generateHTML());
QFile::remove(output);
return BuildZipResult(tr("Could not create file"));
}
if (buildZipFuture.isCanceled()) QStringList exclude;
return BuildZipResult(); std::transform(resolvedFiles.keyBegin(), resolvedFiles.keyEnd(), std::back_insert_iterator(exclude),
[this](QString file) { return gameRoot.relativeFilePath(file); });
QuaZipFile indexFile(&zip); zipTask->setExcludeFiles(exclude);
if (!indexFile.open(QIODevice::WriteOnly, QuaZipNewInfo("manifest.json"))) {
QFile::remove(output);
return BuildZipResult(tr("Could not create index"));
}
indexFile.write(generateIndex());
QuaZipFile modlist(&zip);
if (!modlist.open(QIODevice::WriteOnly, QuaZipNewInfo("modlist.html"))) {
QFile::remove(output);
return BuildZipResult(tr("Could not create index"));
}
QString content = "";
for (auto mod : resolvedFiles) {
if (mod.isMod) {
content += QString(TEMPLATE)
.replace("{name}", mod.name.toHtmlEscaped())
.replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId).toHtmlEscaped())
.replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors).toHtmlEscaped() : "");
}
}
content = "<ul>" + content + "</ul>";
modlist.write(content.toUtf8());
auto progressStep = std::make_shared<TaskStepProgress>(); auto progressStep = std::make_shared<TaskStepProgress>();
connect(zipTask.get(), &Task::finished, this, [this, progressStep] {
size_t progress = 0;
for (const QFileInfo& file : files) {
if (buildZipFuture.isCanceled()) {
QFile::remove(output);
progressStep->state = TaskStepState::Failed;
stepProgress(*progressStep);
return BuildZipResult();
}
progressStep->update(progress, files.length());
stepProgress(*progressStep);
const QString relative = gameRoot.relativeFilePath(file.absoluteFilePath());
if (!resolvedFiles.contains(file.absoluteFilePath()) &&
!JlCompress::compressFile(&zip, file.absoluteFilePath(), "overrides/" + relative)) {
QFile::remove(output);
return BuildZipResult(tr("Could not read and compress %1").arg(relative));
}
progress++;
}
zip.close();
if (zip.getZipError() != 0) {
QFile::remove(output);
progressStep->state = TaskStepState::Failed;
stepProgress(*progressStep);
return BuildZipResult(tr("A zip error occurred"));
}
progressStep->state = TaskStepState::Succeeded; progressStep->state = TaskStepState::Succeeded;
stepProgress(*progressStep); stepProgress(*progressStep);
return BuildZipResult();
}); });
connect(&buildZipWatcher, &QFutureWatcher<BuildZipResult>::finished, this, &FlamePackExportTask::finish);
buildZipWatcher.setFuture(buildZipFuture);
}
void FlamePackExportTask::finish() connect(zipTask.get(), &Task::succeeded, this, &FlamePackExportTask::emitSucceeded);
{ connect(zipTask.get(), &Task::aborted, this, [this]() {
if (buildZipFuture.isCanceled()) QFile::remove(output);
emitAborted(); emitAborted();
else { });
const BuildZipResult result = buildZipFuture.result(); connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) {
if (result.has_value()) progressStep->state = TaskStepState::Failed;
emitFailed(result.value()); stepProgress(*progressStep);
else QFile::remove(output);
emitSucceeded(); emitFailed(reason);
} });
connect(zipTask.get(), &Task::stepProgress, this, &FlamePackExportTask::propogateStepProgress);
connect(zipTask.get(), &Task::progress, this, [this, progressStep](qint64 current, qint64 total) {
progressStep->update(current, total);
stepProgress(*progressStep);
});
connect(zipTask.get(), &Task::status, this, [this, progressStep](QString status) {
progressStep->status = status;
stepProgress(*progressStep);
});
task.reset(zipTask);
zipTask->start();
} }
QByteArray FlamePackExportTask::generateIndex() QByteArray FlamePackExportTask::generateIndex()
@ -471,3 +418,18 @@ QByteArray FlamePackExportTask::generateIndex()
return QJsonDocument(obj).toJson(QJsonDocument::Compact); return QJsonDocument(obj).toJson(QJsonDocument::Compact);
} }
QByteArray FlamePackExportTask::generateHTML()
{
QString content = "";
for (auto mod : resolvedFiles) {
if (mod.isMod) {
content += QString(TEMPLATE)
.replace("{name}", mod.name.toHtmlEscaped())
.replace("{url}", ModPlatform::getMetaURL(ModPlatform::ResourceProvider::FLAME, mod.addonId).toHtmlEscaped())
.replace("{authors}", !mod.authors.isEmpty() ? QString(" (by %1)").arg(mod.authors).toHtmlEscaped() : "");
}
}
content = "<ul>" + content + "</ul>";
return content.toUtf8();
}

View File

@ -19,8 +19,6 @@
#pragma once #pragma once
#include <QFuture>
#include <QFutureWatcher>
#include "BaseInstance.h" #include "BaseInstance.h"
#include "MMCZip.h" #include "MMCZip.h"
#include "minecraft/MinecraftInstance.h" #include "minecraft/MinecraftInstance.h"
@ -52,7 +50,6 @@ class FlamePackExportTask : public Task {
const QString output; const QString output;
const MMCZip::FilterFunction filter; const MMCZip::FilterFunction filter;
typedef std::optional<QString> BuildZipResult;
struct ResolvedFile { struct ResolvedFile {
int addonId; int addonId;
int version; int version;
@ -76,15 +73,13 @@ class FlamePackExportTask : public Task {
QMap<QString, HashInfo> pendingHashes{}; QMap<QString, HashInfo> pendingHashes{};
QMap<QString, ResolvedFile> resolvedFiles{}; QMap<QString, ResolvedFile> resolvedFiles{};
Task::Ptr task; Task::Ptr task;
QFuture<BuildZipResult> buildZipFuture;
QFutureWatcher<BuildZipResult> buildZipWatcher;
void collectFiles(); void collectFiles();
void collectHashes(); void collectHashes();
void makeApiRequest(); void makeApiRequest();
void getProjectsInfo(); void getProjectsInfo();
void buildZip(); void buildZip();
void finish();
QByteArray generateIndex(); QByteArray generateIndex();
QByteArray generateHTML();
}; };