From 6cff570a124ef7e80cc13d7168bd732a66004a8f Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Mon, 10 Mar 2025 20:27:39 +0000 Subject: [PATCH] qt: Added update checker behind CMake option ENABLE_QT_UPDATE_CHECKER --- .ci/linux.sh | 4 +++ CMakeLists.txt | 1 + src/citra_qt/CMakeLists.txt | 6 ++++ src/citra_qt/citra_qt.cpp | 18 ++++++++++++ src/citra_qt/update_checker.cpp | 50 +++++++++++++++++++++++++++++++++ src/citra_qt/update_checker.h | 12 ++++++++ 6 files changed, 91 insertions(+) create mode 100644 src/citra_qt/update_checker.cpp create mode 100644 src/citra_qt/update_checker.h diff --git a/.ci/linux.sh b/.ci/linux.sh index 552dafe39..bb6314999 100755 --- a/.ci/linux.sh +++ b/.ci/linux.sh @@ -11,6 +11,10 @@ else export EXTRA_CMAKE_FLAGS=(-DCITRA_USE_PRECOMPILED_HEADERS=OFF) fi +if [ "$GITHUB_REF_TYPE" == "tag" ]; then + export EXTRA_CMAKE_FLAGS=($EXTRA_CMAKE_FLAGS -DENABLE_QT_UPDATE_CHECKER=ON) +fi + mkdir build && cd build cmake .. -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ diff --git a/CMakeLists.txt b/CMakeLists.txt index fd3fe89e2..376f8dc1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,7 @@ option(USE_SYSTEM_SDL2 "Use the system SDL2 lib (instead of the bundled one)" OF # Set bundled qt as dependent options. option(ENABLE_QT "Enable the Qt frontend" ON) option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF) +option(ENABLE_QT_UPDATE_CHECKER "Enable built-in update checker for the Qt frontend" OFF) CMAKE_DEPENDENT_OPTION(ENABLE_TESTS "Enable generating tests executable" ON "NOT IOS" OFF) CMAKE_DEPENDENT_OPTION(ENABLE_ROOM "Enable generating dedicated room executable" ON "NOT ANDROID AND NOT IOS" OFF) diff --git a/src/citra_qt/CMakeLists.txt b/src/citra_qt/CMakeLists.txt index 1f8c31360..1b78605a0 100644 --- a/src/citra_qt/CMakeLists.txt +++ b/src/citra_qt/CMakeLists.txt @@ -198,6 +198,12 @@ file(GLOB COMPAT_LIST file(GLOB_RECURSE ICONS ${PROJECT_SOURCE_DIR}/dist/icons/*) file(GLOB_RECURSE THEMES ${PROJECT_SOURCE_DIR}/dist/qt_themes/*) +if (ENABLE_QT_UPDATE_CHECKER) + target_link_libraries(citra_qt PRIVATE httplib json-headers) + target_sources(citra_qt PRIVATE update_checker.cpp) + target_compile_definitions(citra_qt PUBLIC ENABLE_QT_UPDATE_CHECKER) +endif() + if (ENABLE_QT_TRANSLATION) set(CITRA_QT_LANGUAGES "${PROJECT_SOURCE_DIR}/dist/languages" CACHE PATH "Path to the translation bundle for the Qt frontend") option(GENERATE_QT_TRANSLATION "Generate en.ts as the translation source file" OFF) diff --git a/src/citra_qt/citra_qt.cpp b/src/citra_qt/citra_qt.cpp index ab8b454f0..a5f849b8b 100644 --- a/src/citra_qt/citra_qt.cpp +++ b/src/citra_qt/citra_qt.cpp @@ -69,6 +69,9 @@ #include "citra_qt/play_time_manager.h" #include "citra_qt/qt_image_interface.h" #include "citra_qt/uisettings.h" +#ifdef ENABLE_QT_UPDATE_CHECKER +#include "citra_qt/update_checker.h" +#endif #include "citra_qt/util/clickable_label.h" #include "citra_qt/util/graphics_device_info.h" #include "citra_qt/util/util.h" @@ -305,6 +308,21 @@ GMainWindow::GMainWindow(Core::System& system_) } } +#ifdef ENABLE_QT_UPDATE_CHECKER + const std::optional latest_release = UpdateChecker::CheckForUpdate(); + if (latest_release && latest_release.value() != Common::g_build_fullname) { + if (QMessageBox::information( + this, tr("Update Available"), + tr("Update %1 for Azahar is available.\nWould you like to download it?") + .arg(QString::fromStdString(latest_release.value())), + QMessageBox::Yes | QMessageBox::Ignore) == QMessageBox::Yes) { + QDesktopServices::openUrl(QUrl(QString::fromStdString( + "https://github.com/azahar-emu/azahar/releases/tag/" + latest_release.value()))); + exit(0); + } + } +#endif + #ifdef __unix__ SetGamemodeEnabled(Settings::values.enable_gamemode.GetValue()); #endif diff --git a/src/citra_qt/update_checker.cpp b/src/citra_qt/update_checker.cpp new file mode 100644 index 000000000..050c19c8e --- /dev/null +++ b/src/citra_qt/update_checker.cpp @@ -0,0 +1,50 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#include +#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"; + + std::unique_ptr client = std::make_unique(UPDATE_CHECK_URL); + if (client == nullptr) { + LOG_ERROR(Frontend, "Invalid URL {}{}", UPDATE_CHECK_URL, UPDATE_CHECK_PATH); + return {}; + } + + httplib::Request request{ + .method = "GET", + .path = UPDATE_CHECK_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); + 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); + return {}; + } + if (!response.headers.contains("content-type")) { + LOG_ERROR(Frontend, "GET to {}{} returned no content", UPDATE_CHECK_URL, UPDATE_CHECK_PATH); + return {}; + } + + try { + return nlohmann::json::parse(response.body).at("tag_name"); + } catch (nlohmann::detail::out_of_range&) { + return {}; + } +} diff --git a/src/citra_qt/update_checker.h b/src/citra_qt/update_checker.h new file mode 100644 index 000000000..b416503e7 --- /dev/null +++ b/src/citra_qt/update_checker.h @@ -0,0 +1,12 @@ +// Copyright Citra Emulator Project / Azahar Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include + +namespace UpdateChecker { +std::optional CheckForUpdate(); +}