mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-29 10:43:48 +00:00
Rewrite
Signed-off-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
parent
0fdcca036b
commit
02e63b1948
|
|
@ -23,20 +23,6 @@
|
|||
namespace Common::Net {
|
||||
|
||||
std::vector<Asset> Release::GetPlatformAssets() const {
|
||||
// FIXME(crueter): use search strings based on platform's assets, or a fallback name if not
|
||||
#ifdef _WIN32
|
||||
static constexpr const std::string prefix = "Eden-Windows";
|
||||
#elif defined(__APPLE__)
|
||||
static constexpr const std::string prefix = "Eden-macOS";
|
||||
#elif defined(__ANDROID__)
|
||||
static constexpr const std::string prefix = "Eden-Android";
|
||||
#else
|
||||
LOG_DEBUG(Common, "Unsupported platform for auto-update");
|
||||
static constexpr const std::string prefix = "Eden";
|
||||
#endif
|
||||
|
||||
std::vector<std::string> suffixes;
|
||||
|
||||
// TODO(crueter): Need better handling for this as a whole.
|
||||
#ifdef NIGHTLY_BUILD
|
||||
std::vector<std::string> result;
|
||||
|
|
@ -48,44 +34,57 @@ std::vector<Asset> Release::GetPlatformAssets() const {
|
|||
const auto ref = tag;
|
||||
#endif
|
||||
|
||||
const auto make_asset = [this, ref](const std::string& name,
|
||||
const std::string& suffix) -> Asset {
|
||||
const auto filename = fmt::format("{}-{}{}", prefix, ref, suffix);
|
||||
return Asset{.name = name,
|
||||
.url = host,
|
||||
.path = fmt::format("{}/{}", base_download_url, filename),
|
||||
.filename = filename};
|
||||
std::vector<Asset> found_assets;
|
||||
|
||||
// FIXME: This is mildly inefficient.
|
||||
// Finds assets based on a hierarchy of regex search strings.
|
||||
const auto find_asset = [&found_assets, ref, this](const std::string& name,
|
||||
const std::vector<std::string>& suffixes) {
|
||||
for (const std::string& asset : assets) {
|
||||
for (const auto& suffix : suffixes) {
|
||||
if (asset.ends_with(suffix)) {
|
||||
const std::string_view asset_sv = asset;
|
||||
const size_t pos = asset_sv.find_last_of('/');
|
||||
const std::string_view filename =
|
||||
(pos != std::string_view::npos) ? asset_sv.substr(pos + 1) : asset_sv;
|
||||
|
||||
found_assets.emplace_back(Asset{
|
||||
.name = name,
|
||||
.url = host,
|
||||
.path = asset,
|
||||
.filename = std::string{filename},
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// TODO(crueter): Handle setup when that becomes a thing
|
||||
// TODO(crueter): Descriptions? Android?
|
||||
return {
|
||||
#ifdef _WIN32
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
make_asset(QT_TR_NOOP("Standard"), "-amd64-msvc-standard.zip"),
|
||||
// make_asset(QT_TR_NOOP("MinGW"), "-mingw-amd64-gcc-standard.zip"),
|
||||
make_asset(QT_TR_NOOP("PGO"), "-mingw-amd64-clang-pgo.zip")
|
||||
find_asset("Standard", {"amd64-msvc-standard.exe", "amd64-msvc-standard.zip", "mingw-amd64-gcc-standard.exe", "mingw-amd64-gcc-standard.zip"});
|
||||
find_asset("PGO", {"mingw-amd64-clang-pgo.exe", "mingw-amd64-clang-pgo.zip"});
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
make_asset(QT_TR_NOOP("Standard"), "-mingw-arm64-clang-standard.zip"),
|
||||
make_asset(QT_TR_NOOP("PGO"), "-mingw-arm64-clang-pgo.zip")
|
||||
find_asset("Standard", {"mingw-arm64-clang-standard.exe", "mingw-arm64-clang-standard.zip"});
|
||||
find_asset("PGO", {"mingw-arm64-clang-pgo.exe", "mingw-arm64-clang-pgo.zip"});
|
||||
#endif
|
||||
#elif defined(__APPLE__)
|
||||
#ifdef ARCHITECTURE_arm64
|
||||
make_asset(QT_TR_NOOP("Standard"), ".dmg"),
|
||||
find_asset("Standard", {".dmg", ".tar.gz"});
|
||||
#endif
|
||||
#elif defined(__ANDROID__)
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
make_asset("Standard", "-chromeos.apk"),
|
||||
find_asset("Standard", {"chromeos.apk"});
|
||||
#elif defined(ARCHITECTURE_arm64)
|
||||
#ifdef YUZU_LEGACY
|
||||
make_asset("Standard", "-legacy.apk"),
|
||||
find_asset("Standard", {"legacy.apk"});
|
||||
#else
|
||||
make_asset("Standard", "-standard.apk"),
|
||||
make_asset("Genshin Spoof", "-optimized.apk"),
|
||||
find_asset("Standard", {"standard.apk"});
|
||||
find_asset("Genshin Spoof", {"optimized.apk"});
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
return found_assets;
|
||||
}
|
||||
|
||||
static inline u64 ParseIsoTimestamp(const std::string& iso) {
|
||||
|
|
|
|||
|
|
@ -43,19 +43,22 @@ UpdateDialog::UpdateDialog(const Common::Net::Release& release, QWidget* parent)
|
|||
connect(this, &QDialog::accepted, this, [release]() {
|
||||
QDesktopServices::openUrl(QUrl{QString::fromStdString(release.html_url)});
|
||||
});
|
||||
} else if (assets.size() == 1) {
|
||||
m_asset = assets[0];
|
||||
|
||||
connect(this, &QDialog::accepted, this, &UpdateDialog::Download);
|
||||
} else {
|
||||
u32 i = 0;
|
||||
for (const Common::Net::Asset& a : release.GetPlatformAssets()) {
|
||||
for (const Common::Net::Asset& a : assets) {
|
||||
QRadioButton* r = new QRadioButton(tr(a.name.c_str()), this);
|
||||
if (i == 0) r->setChecked(true);
|
||||
++i;
|
||||
|
||||
r->setProperty("url", QString::fromStdString(a.url));
|
||||
r->setProperty("path", QString::fromStdString(a.path));
|
||||
r->setProperty("filename", QString::fromStdString(a.filename));
|
||||
|
||||
ui->radioButtons->addWidget(r);
|
||||
m_buttons.append(r);
|
||||
|
||||
connect(r, &QRadioButton::clicked, this, [a, this](bool checked) {
|
||||
m_asset = a;
|
||||
});
|
||||
}
|
||||
|
||||
connect(this, &QDialog::accepted, this, &UpdateDialog::Download);
|
||||
|
|
@ -67,22 +70,9 @@ UpdateDialog::~UpdateDialog() {
|
|||
}
|
||||
|
||||
void UpdateDialog::Download() {
|
||||
std::string url, path, asset_filename;
|
||||
for (QRadioButton* r : std::as_const(m_buttons)) {
|
||||
if (r->isChecked()) {
|
||||
url = r->property("url").toString().toStdString();
|
||||
path = r->property("path").toString().toStdString();
|
||||
asset_filename = r->property("filename").toString().toStdString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (url.empty())
|
||||
return;
|
||||
|
||||
const auto filename = QtCommon::Frontend::GetSaveFileName(
|
||||
tr("New Version Location"),
|
||||
qApp->applicationDirPath() % QStringLiteral("/") % QString::fromStdString(asset_filename),
|
||||
qApp->applicationDirPath() % QStringLiteral("/") % QString::fromStdString(m_asset.filename),
|
||||
tr("All Files (*.*)"));
|
||||
|
||||
if (filename.isEmpty())
|
||||
|
|
@ -99,7 +89,7 @@ void UpdateDialog::Download() {
|
|||
// TODO(crueter): Move to net.cpp
|
||||
constexpr std::size_t timeout_seconds = 15;
|
||||
|
||||
std::unique_ptr<httplib::Client> client = std::make_unique<httplib::Client>(url);
|
||||
std::unique_ptr<httplib::Client> client = std::make_unique<httplib::Client>(m_asset.url);
|
||||
client->set_connection_timeout(timeout_seconds);
|
||||
client->set_read_timeout(timeout_seconds);
|
||||
client->set_write_timeout(timeout_seconds);
|
||||
|
|
@ -109,7 +99,7 @@ void UpdateDialog::Download() {
|
|||
#endif
|
||||
|
||||
if (client == nullptr) {
|
||||
LOG_ERROR(Frontend, "Invalid URL {}{}", url, path);
|
||||
LOG_ERROR(Frontend, "Invalid URL {}{}", m_asset.url, m_asset.path);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +130,7 @@ void UpdateDialog::Download() {
|
|||
};
|
||||
|
||||
// Now send off request
|
||||
auto result = client->Get(path, content_receiver, progress_callback);
|
||||
auto result = client->Get(m_asset.path, content_receiver, progress_callback);
|
||||
progress->close();
|
||||
|
||||
// commit to file
|
||||
|
|
@ -151,33 +141,30 @@ void UpdateDialog::Download() {
|
|||
}
|
||||
|
||||
if (!result) {
|
||||
LOG_ERROR(Frontend, "GET to {}{} returned null", url, path);
|
||||
LOG_ERROR(Frontend, "GET to {}{} returned null", m_asset.url, m_asset.path);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& response = result.value();
|
||||
if (response.status >= 400) {
|
||||
LOG_ERROR(Frontend, "GET to {}{} returned error status code: {}", url, path,
|
||||
LOG_ERROR(Frontend, "GET to {}{} returned error status code: {}", m_asset.url, m_asset.path,
|
||||
response.status);
|
||||
QtCommon::Frontend::Critical(
|
||||
tr("Failed to download file"),
|
||||
tr("Could not download from %1%2\nError code: %3")
|
||||
.arg(QString::fromStdString(url), QString::fromStdString(path), QString::number(response.status)));
|
||||
.arg(QString::fromStdString(m_asset.url), QString::fromStdString(m_asset.path), QString::number(response.status)));
|
||||
return;
|
||||
}
|
||||
if (!response.headers.contains("content-type")) {
|
||||
LOG_ERROR(Frontend, "GET to {}{} returned no content", url, path);
|
||||
LOG_ERROR(Frontend, "GET to {}{} returned no content", m_asset.url, m_asset.path);
|
||||
return;
|
||||
}
|
||||
|
||||
// Download is complete. User may choose to open in the file manager.
|
||||
// TODO(crueter): Auto-extract for zip, auto-open for DMG
|
||||
// e.g. download to tmp directory?
|
||||
|
||||
auto button =
|
||||
QtCommon::Frontend::Question(tr("Download Complete"),
|
||||
tr("Successfully downloaded %1. Would you like to open it?")
|
||||
.arg(QString::fromStdString(asset_filename)),
|
||||
.arg(QString::fromStdString(m_asset.filename)),
|
||||
QtCommon::Frontend::Yes | QtCommon::Frontend::No);
|
||||
|
||||
if (button == QtCommon::Frontend::Yes) {
|
||||
|
|
|
|||
|
|
@ -24,4 +24,5 @@ private slots:
|
|||
private:
|
||||
Ui::UpdateDialog* ui;
|
||||
QList<QRadioButton *> m_buttons;
|
||||
Common::Net::Asset m_asset;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue