Cleanup downloaders

Signed-off-by: Trial97 <alexandru.tripon97@gmail.com>
This commit is contained in:
Trial97
2024-01-25 22:58:12 +02:00
parent e897032383
commit f36be3f0e3
11 changed files with 132 additions and 401 deletions

View File

@ -0,0 +1,88 @@
// 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 "java/download/ArchiveJavaDownloader.h"
#include <quazip.h>
#include <memory>
#include "MMCZip.h"
#include "Application.h"
#include "net/NetJob.h"
#include "tasks/Task.h"
void ArchiveJavaDownloader::executeTask()
{
// JRE found ! download the zip
setStatus(tr("Downloading Java"));
MetaEntryPtr entry = APPLICATION->metacache()->resolveEntry("java", m_url.toLocalFile());
auto download = makeShared<NetJob>(QString("JRE::DownloadJava"), APPLICATION->network());
download->addNetAction(Net::Download::makeCached(m_url, entry));
auto fullPath = entry->getFullPath();
connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); });
// connect(download.get(), &NetJob::aborted, [path] { APPLICATION->instances()->destroyStagingPath(path); });
connect(download.get(), &NetJob::progress, this, &ArchiveJavaDownloader::progress);
connect(download.get(), &NetJob::failed, this, &ArchiveJavaDownloader::emitFailed);
connect(this, &Task::aborted, download.get(), &NetJob::abort);
connect(download.get(), &NetJob::succeeded, [this, fullPath] {
// This should do all of the extracting and creating folders
extractJava(fullPath);
});
download->start();
};
void ArchiveJavaDownloader::extractJava(QString input)
{
setStatus(tr("Extracting java"));
auto zip = std::make_shared<QuaZip>(input);
auto files = zip->getFileNameList();
if (files.isEmpty()) {
emitFailed("Empty archive");
return;
}
auto zipTask = makeShared<MMCZip::ExtractZipTask>(input, m_final_path, files[0]);
auto progressStep = std::make_shared<TaskStepProgress>();
connect(zipTask.get(), &Task::finished, this, [this, progressStep] {
progressStep->state = TaskStepState::Succeeded;
stepProgress(*progressStep);
});
connect(this, &Task::aborted, zipTask.get(), &Task::abort);
connect(zipTask.get(), &Task::finished, [zipTask, this] { disconnect(this, &Task::aborted, zipTask.get(), &Task::abort); });
connect(zipTask.get(), &Task::succeeded, this, &ArchiveJavaDownloader::emitSucceeded);
connect(zipTask.get(), &Task::aborted, this, &ArchiveJavaDownloader::emitAborted);
connect(zipTask.get(), &Task::failed, this, [this, progressStep](QString reason) {
progressStep->state = TaskStepState::Failed;
stepProgress(*progressStep);
emitFailed(reason);
});
connect(zipTask.get(), &Task::stepProgress, this, &ArchiveJavaDownloader::propagateStepProgress);
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);
});
zipTask->start();
};

View File

@ -0,0 +1,41 @@
// 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 <QUrl>
#include "tasks/Task.h"
class ArchiveJavaDownloader : public Task {
Q_OBJECT
public:
ArchiveJavaDownloader(QUrl url, QString final_path);
virtual ~ArchiveJavaDownloader() = default;
[[nodiscard]] bool canAbort() const override { return true; }
void executeTask() override;
private slots:
void extractJava(QString input);
protected:
QUrl m_url;
QString m_final_path;
Task::Ptr m_current_task;
};

View File

@ -0,0 +1,114 @@
// 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 "java/download/ManifestJavaDownloader.h"
#include "Application.h"
#include "FileSystem.h"
#include "Json.h"
#include "net/ChecksumValidator.h"
#include "net/NetJob.h"
struct File {
QString path;
QString url;
QByteArray hash;
bool isExec;
};
ManifestJavaDownloader::ManifestJavaDownloader(QUrl url, QString final_path) : m_url(url), m_final_path(final_path){};
void ManifestJavaDownloader::executeTask()
{
setStatus(tr("Downloading Java"));
auto download = makeShared<NetJob>(QString("JRE::DownloadJava"), APPLICATION->network());
auto files = std::make_shared<QByteArray>();
download->addNetAction(Net::Download::makeByteArray(m_url, files));
connect(download.get(), &NetJob::finished, [download, this] { disconnect(this, &Task::aborted, download.get(), &NetJob::abort); });
connect(download.get(), &NetJob::progress, this, &ManifestJavaDownloader::progress);
connect(download.get(), &NetJob::failed, this, &ManifestJavaDownloader::emitFailed);
connect(this, &Task::aborted, download.get(), &NetJob::abort);
connect(download.get(), &NetJob::succeeded, [files, this] {
QJsonParseError parse_error{};
QJsonDocument doc = QJsonDocument::fromJson(*files, &parse_error);
if (parse_error.error != QJsonParseError::NoError) {
qWarning() << "Error while parsing JSON response at " << parse_error.offset << " reason: " << parse_error.errorString();
qWarning() << *files;
emitFailed(parse_error.errorString());
return;
}
downloadJava(doc);
});
download->start();
};
void ManifestJavaDownloader::downloadJava(const QJsonDocument& doc)
{
// valid json doc, begin making jre spot
FS::ensureFolderPathExists(m_final_path);
std::vector<File> toDownload;
auto list = Json::ensureObject(Json::ensureObject(doc.object()), "files");
for (const auto& paths : list.keys()) {
auto file = FS::PathCombine(m_final_path, paths);
const QJsonObject& meta = Json::ensureObject(list, paths);
auto type = Json::ensureString(meta, "type");
if (type == "directory") {
FS::ensureFolderPathExists(file);
} else if (type == "link") {
// this is linux only !
auto path = Json::ensureString(meta, "target");
if (!path.isEmpty()) {
auto target = FS::PathCombine(file, "../" + path);
QFile(target).link(file);
}
} else if (type == "file") {
// TODO download compressed version if it exists ?
auto raw = Json::ensureObject(Json::ensureObject(meta, "downloads"), "raw");
auto isExec = Json::ensureBoolean(meta, "executable", false);
auto url = Json::ensureString(raw, "url");
if (!url.isEmpty() && QUrl(url).isValid()) {
auto f = File{ file, url, QByteArray::fromHex(Json::ensureString(raw, "sha1").toLatin1()), isExec };
toDownload.push_back(f);
}
}
}
auto elementDownload = new NetJob("JRE::FileDownload", APPLICATION->network());
for (const auto& file : toDownload) {
auto dl = Net::Download::makeFile(file.url, file.path);
if (!file.hash.isEmpty()) {
dl->addValidator(new Net::ChecksumValidator(QCryptographicHash::Sha1, file.hash));
}
if (file.isExec) {
connect(dl.get(), &Net::Download::succeeded,
[file] { QFile(file.path).setPermissions(QFile(file.path).permissions() | QFileDevice::Permissions(0x1111)); });
}
elementDownload->addNetAction(dl);
}
connect(elementDownload, &NetJob::finished, [elementDownload, this] {
disconnect(this, &Task::aborted, elementDownload, &NetJob::abort);
elementDownload->deleteLater();
});
connect(elementDownload, &NetJob::progress, this, &ManifestJavaDownloader::progress);
connect(elementDownload, &NetJob::failed, this, &ManifestJavaDownloader::emitFailed);
connect(this, &Task::aborted, elementDownload, &NetJob::abort);
connect(elementDownload, &NetJob::succeeded, [this] { emitSucceeded(); });
elementDownload->start();
};

View File

@ -0,0 +1,41 @@
// 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 <QUrl>
#include "tasks/Task.h"
class ManifestJavaDownloader : public Task {
Q_OBJECT
public:
ManifestJavaDownloader(QUrl url, QString final_path);
virtual ~ManifestJavaDownloader() = default;
[[nodiscard]] bool canAbort() const override { return true; }
void executeTask() override;
private slots:
void downloadJava(const QJsonDocument& doc);
protected:
QUrl m_url;
QString m_final_path;
Task::Ptr m_current_task;
};