diff --git a/src/citra_qt/citra_qt.cpp b/src/citra_qt/citra_qt.cpp index 03dfcce6c..84c074dec 100644 --- a/src/citra_qt/citra_qt.cpp +++ b/src/citra_qt/citra_qt.cpp @@ -394,9 +394,12 @@ GMainWindow::GMainWindow(Core::System& system_) #ifdef ENABLE_QT_UPDATE_CHECKER if (UISettings::values.check_for_update_on_start) { update_future = QtConcurrent::run([]() -> QString { - const std::optional latest_release = UpdateChecker::CheckForUpdate(); - if (latest_release && latest_release.value() != Common::g_build_fullname) { - return QString::fromStdString(latest_release.value()); + const bool is_prerelease = // TODO: This can be done better -OS + (strstr(Common::g_build_fullname, "rc") != NULL); + const std::optional latest_release_tag = + UpdateChecker::GetLatestRelease(is_prerelease); + if (latest_release_tag && latest_release_tag.value() != Common::g_build_fullname) { + return QString::fromStdString(latest_release_tag.value()); } return QString{}; }); diff --git a/src/citra_qt/update_checker.cpp b/src/citra_qt/update_checker.cpp index a8a3955d7..b4d34344c 100644 --- a/src/citra_qt/update_checker.cpp +++ b/src/citra_qt/update_checker.cpp @@ -9,47 +9,74 @@ #include "common/logging/log.h" #include "update_checker.h" -std::optional UpdateChecker::CheckForUpdate() { - constexpr auto UPDATE_CHECK_URL = "http://api.github.com"; - constexpr auto UPDATE_CHECK_PATH = "/repos/azahar-emu/azahar/releases/latest"; - constexpr std::size_t UPDATE_CHECK_TIMEOUT_SECONDS = 15; +std::optional GetResponse(std::string url, std::string path) { + constexpr std::size_t timeout_seconds = 15; - std::unique_ptr client = std::make_unique(UPDATE_CHECK_URL); - client->set_connection_timeout(UPDATE_CHECK_TIMEOUT_SECONDS); - client->set_read_timeout(UPDATE_CHECK_TIMEOUT_SECONDS); - client->set_write_timeout(UPDATE_CHECK_TIMEOUT_SECONDS); + std::unique_ptr client = std::make_unique(url); + client->set_connection_timeout(timeout_seconds); + client->set_read_timeout(timeout_seconds); + client->set_write_timeout(timeout_seconds); if (client == nullptr) { - LOG_ERROR(Frontend, "Invalid URL {}{}", UPDATE_CHECK_URL, UPDATE_CHECK_PATH); + LOG_ERROR(Frontend, "Invalid URL {}{}", url, path); return {}; } httplib::Request request{ .method = "GET", - .path = UPDATE_CHECK_PATH, + .path = path, }; client->set_follow_location(true); const auto result = client->send(request); if (!result) { - LOG_ERROR(Frontend, "GET to {}{} returned null", UPDATE_CHECK_URL, UPDATE_CHECK_PATH); + LOG_ERROR(Frontend, "GET to {}{} returned null", url, path); return {}; } const auto& response = result.value(); if (response.status >= 400) { - LOG_ERROR(Frontend, "GET to {}{} returned error status code: {}", UPDATE_CHECK_URL, - UPDATE_CHECK_PATH, response.status); + LOG_ERROR(Frontend, "GET to {}{} returned error status code: {}", url, path, + response.status); return {}; } if (!response.headers.contains("content-type")) { - LOG_ERROR(Frontend, "GET to {}{} returned no content", UPDATE_CHECK_URL, UPDATE_CHECK_PATH); + LOG_ERROR(Frontend, "GET to {}{} returned no content", url, path); return {}; } + return response.body; +} + +std::optional UpdateChecker::GetLatestRelease(bool include_prereleases) { + constexpr auto update_check_url = "http://api.github.com"; + std::string update_check_path = "/repos/azahar-emu/azahar/releases"; try { - return nlohmann::json::parse(response.body).at("tag_name"); + if (include_prereleases) { + // This can return either a prerelease or a normal release, whichever is more recent + const auto response = GetResponse(update_check_url, update_check_path); + if (!response) + return {}; + return nlohmann::json::parse(response.value()).at(0).at("tag_name"); + } else { + update_check_path += "/latest"; + const auto response = GetResponse(update_check_url, update_check_path); + if (!response) + return {}; + return nlohmann::json::parse(response.value()).at("tag_name"); + } + } catch (nlohmann::detail::out_of_range&) { + LOG_ERROR(Frontend, + "Parsing JSON response from {}{} failed during update check: " + "nlohmann::detail::out_of_range", + update_check_url, update_check_path); + return {}; + } catch (nlohmann::detail::type_error&) { + LOG_ERROR(Frontend, + "Parsing JSON response from {}{} failed during update check: " + "nlohmann::detail::type_error", + update_check_url, update_check_path); return {}; } } diff --git a/src/citra_qt/update_checker.h b/src/citra_qt/update_checker.h index b416503e7..843b5a1cb 100644 --- a/src/citra_qt/update_checker.h +++ b/src/citra_qt/update_checker.h @@ -8,5 +8,5 @@ #include namespace UpdateChecker { -std::optional CheckForUpdate(); +std::optional GetLatestRelease(bool); }