mirror of https://github.com/mgba-emu/mgba.git
Qt: Initial support for forwarder-kit
This commit is contained in:
parent
6bdb3470e7
commit
7f30bdc850
|
@ -11,9 +11,11 @@
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
|
||||||
#include "ConfigController.h"
|
#include "ConfigController.h"
|
||||||
|
#include "VFileDevice.h"
|
||||||
|
|
||||||
#include <mgba/core/version.h>
|
#include <mgba/core/version.h>
|
||||||
#include <mgba/feature/updater.h>
|
#include <mgba/feature/updater.h>
|
||||||
|
#include <mgba-util/vfs.h>
|
||||||
|
|
||||||
using namespace QGBA;
|
using namespace QGBA;
|
||||||
|
|
||||||
|
@ -28,22 +30,17 @@ const char* SUFFIX = "";
|
||||||
ForwarderController::ForwarderController(QObject* parent)
|
ForwarderController::ForwarderController(QObject* parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_netman(new QNetworkAccessManager(this))
|
, m_netman(new QNetworkAccessManager(this))
|
||||||
|
, m_originalPath(qgetenv("PATH"))
|
||||||
{
|
{
|
||||||
m_netman->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
m_netman->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||||
connect(this, &ForwarderController::buildFailed, this, [this]() {
|
connect(this, &ForwarderController::buildFailed, this, &ForwarderController::cleanup);
|
||||||
m_inProgress = false;
|
connect(this, &ForwarderController::buildComplete, this, &ForwarderController::cleanup);
|
||||||
});
|
|
||||||
connect(this, &ForwarderController::buildComplete, this, [this]() {
|
|
||||||
m_inProgress = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwarderController::setGenerator(std::unique_ptr<ForwarderGenerator>&& generator) {
|
void ForwarderController::setGenerator(std::unique_ptr<ForwarderGenerator>&& generator) {
|
||||||
m_generator = std::move(generator);
|
m_generator = std::move(generator);
|
||||||
connect(m_generator.get(), &ForwarderGenerator::buildFailed, this, &ForwarderController::buildFailed);
|
connect(m_generator.get(), &ForwarderGenerator::buildFailed, this, &ForwarderController::buildFailed);
|
||||||
connect(m_generator.get(), &ForwarderGenerator::buildFailed, this, &ForwarderController::cleanup);
|
|
||||||
connect(m_generator.get(), &ForwarderGenerator::buildComplete, this, &ForwarderController::buildComplete);
|
connect(m_generator.get(), &ForwarderGenerator::buildComplete, this, &ForwarderController::buildComplete);
|
||||||
connect(m_generator.get(), &ForwarderGenerator::buildComplete, this, &ForwarderController::cleanup);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwarderController::startBuild(const QString& outFilename) {
|
void ForwarderController::startBuild(const QString& outFilename) {
|
||||||
|
@ -53,6 +50,15 @@ void ForwarderController::startBuild(const QString& outFilename) {
|
||||||
m_inProgress = true;
|
m_inProgress = true;
|
||||||
m_outFilename = outFilename;
|
m_outFilename = outFilename;
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
||||||
|
// Amend the path for downloaded programs forwarder-kit
|
||||||
|
QByteArray arr = m_originalPath;
|
||||||
|
QStringList path = QString::fromUtf8(arr).split(LIST_SPLIT);
|
||||||
|
path << ConfigController::cacheDir();
|
||||||
|
arr = path.join(LIST_SPLIT).toUtf8();
|
||||||
|
qputenv("PATH", arr);
|
||||||
|
#endif
|
||||||
|
|
||||||
QStringList neededTools = m_generator->externalTools();
|
QStringList neededTools = m_generator->externalTools();
|
||||||
for (const auto& tool : neededTools) {
|
for (const auto& tool : neededTools) {
|
||||||
if (!toolInstalled(tool)) {
|
if (!toolInstalled(tool)) {
|
||||||
|
@ -64,8 +70,67 @@ void ForwarderController::startBuild(const QString& outFilename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwarderController::downloadForwarderKit() {
|
void ForwarderController::downloadForwarderKit() {
|
||||||
|
QString fkUrl("https://github.com/mgba-emu/forwarder-kit/releases/latest/download/forwarder-kit-%1.zip");
|
||||||
|
#ifdef Q_OS_WIN64
|
||||||
|
fkUrl = fkUrl.arg("win64");
|
||||||
|
#elif defined(Q_OS_WIN32)
|
||||||
|
fkUrl = fkUrl.arg("win32");
|
||||||
|
#elif defined(Q_OS_MAC) && (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
|
// Modern macOS build
|
||||||
|
fkUrl = fkUrl.arg("macos");
|
||||||
|
#else
|
||||||
// TODO
|
// TODO
|
||||||
emit buildFailed();
|
emit buildFailed();
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
QNetworkReply* reply = m_netman->get(QNetworkRequest(QUrl(fkUrl)));
|
||||||
|
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||||
|
gotForwarderKit(reply);
|
||||||
|
});
|
||||||
|
connectErrorFailure(reply);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ForwarderController::gotForwarderKit(QNetworkReply* reply) {
|
||||||
|
if (reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() != 200) {
|
||||||
|
emit buildFailed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile fkZip(ConfigController::cacheDir() + "/forwarder-kit.zip");
|
||||||
|
fkZip.open(QIODevice::WriteOnly | QIODevice::Truncate);
|
||||||
|
QByteArray arr;
|
||||||
|
do {
|
||||||
|
arr = reply->read(0x800);
|
||||||
|
fkZip.write(arr);
|
||||||
|
} while (!arr.isEmpty());
|
||||||
|
fkZip.close();
|
||||||
|
|
||||||
|
VDir* fkDir = VFileDevice::openArchive(fkZip.fileName());
|
||||||
|
|
||||||
|
// This has to be done in multiple passes to avoid seeking breaking the listing
|
||||||
|
QStringList files;
|
||||||
|
for (VDirEntry* entry = fkDir->listNext(fkDir); entry; entry = fkDir->listNext(fkDir)) {
|
||||||
|
if (entry->type(entry) != VFS_FILE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
files << entry->name(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const QString& source : files) {
|
||||||
|
VFile* sourceVf = fkDir->openFile(fkDir, source.toUtf8().constData(), O_RDONLY);
|
||||||
|
VFile* targetVf = VFileDevice::open(ConfigController::cacheDir() + "/" + source, O_CREAT | O_TRUNC | O_WRONLY);
|
||||||
|
VFileDevice::copyFile(sourceVf, targetVf);
|
||||||
|
sourceVf->close(sourceVf);
|
||||||
|
targetVf->close(targetVf);
|
||||||
|
|
||||||
|
QFile target(ConfigController::cacheDir() + "/" + source);
|
||||||
|
target.setPermissions(target.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
fkDir->close(fkDir);
|
||||||
|
fkZip.remove();
|
||||||
|
|
||||||
|
downloadManifest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwarderController::downloadManifest() {
|
void ForwarderController::downloadManifest() {
|
||||||
|
@ -73,13 +138,7 @@ void ForwarderController::downloadManifest() {
|
||||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||||
gotManifest(reply);
|
gotManifest(reply);
|
||||||
});
|
});
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
connectErrorFailure(reply);
|
||||||
connect(reply, &QNetworkReply::errorOccurred, this, [this, reply]() {
|
|
||||||
#else
|
|
||||||
connect(reply, qOverload<>(&QNetworkReply::error), this, [this, reply]() {
|
|
||||||
#endif
|
|
||||||
emit buildFailed();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwarderController::gotManifest(QNetworkReply* reply) {
|
void ForwarderController::gotManifest(QNetworkReply* reply) {
|
||||||
|
@ -128,6 +187,7 @@ void ForwarderController::downloadBuild(const QUrl& url) {
|
||||||
QByteArray data = reply->readAll();
|
QByteArray data = reply->readAll();
|
||||||
m_sourceFile.write(data);
|
m_sourceFile.write(data);
|
||||||
});
|
});
|
||||||
|
connectErrorFailure(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForwarderController::gotBuild(QNetworkReply* reply) {
|
void ForwarderController::gotBuild(QNetworkReply* reply) {
|
||||||
|
@ -144,6 +204,11 @@ void ForwarderController::gotBuild(QNetworkReply* reply) {
|
||||||
|
|
||||||
void ForwarderController::cleanup() {
|
void ForwarderController::cleanup() {
|
||||||
m_sourceFile.remove();
|
m_sourceFile.remove();
|
||||||
|
m_inProgress = false;
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
||||||
|
qputenv("PATH", m_originalPath);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ForwarderController::toolInstalled(const QString& tool) {
|
bool ForwarderController::toolInstalled(const QString& tool) {
|
||||||
|
@ -157,3 +222,13 @@ bool ForwarderController::toolInstalled(const QString& tool) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ForwarderController::connectErrorFailure(QNetworkReply* reply) {
|
||||||
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||||
|
connect(reply, &QNetworkReply::errorOccurred, this, [this, reply]() {
|
||||||
|
#else
|
||||||
|
connect(reply, qOverload<>(&QNetworkReply::error), this, [this, reply]() {
|
||||||
|
#endif
|
||||||
|
emit buildFailed();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@ signals:
|
||||||
private slots:
|
private slots:
|
||||||
void gotManifest(QNetworkReply*);
|
void gotManifest(QNetworkReply*);
|
||||||
void gotBuild(QNetworkReply*);
|
void gotBuild(QNetworkReply*);
|
||||||
|
void gotForwarderKit(QNetworkReply*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void downloadForwarderKit();
|
void downloadForwarderKit();
|
||||||
|
@ -46,12 +47,15 @@ private:
|
||||||
bool toolInstalled(const QString& tool);
|
bool toolInstalled(const QString& tool);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
|
void connectErrorFailure(QNetworkReply*);
|
||||||
|
|
||||||
QString m_channel{"dev"};
|
QString m_channel{"dev"};
|
||||||
QString m_outFilename;
|
QString m_outFilename;
|
||||||
QNetworkAccessManager* m_netman;
|
QNetworkAccessManager* m_netman;
|
||||||
std::unique_ptr<ForwarderGenerator> m_generator;
|
std::unique_ptr<ForwarderGenerator> m_generator;
|
||||||
QFile m_sourceFile;
|
QFile m_sourceFile;
|
||||||
bool m_inProgress = false;
|
bool m_inProgress = false;
|
||||||
|
QByteArray m_originalPath;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue