From 6ee17fdfd21bf3749b8706905bfdcfb64fc5d8a4 Mon Sep 17 00:00:00 2001 From: Pk11 Date: Fri, 27 May 2022 18:14:30 -0500 Subject: [PATCH] Add nightly auto-update - Closes #121 --- Makefile | 11 ++++--- include/utils/config.hpp | 6 +++- include/utils/download.hpp | 1 - romfs/lang/en/app.json | 2 ++ source/menu/settings.cpp | 23 +++++++++++--- source/utils/config.cpp | 2 ++ source/utils/download.cpp | 64 +++++++++++++++++++++++++++----------- 7 files changed, 80 insertions(+), 29 deletions(-) diff --git a/Makefile b/Makefile index 2c4cfe5..af718cf 100644 --- a/Makefile +++ b/Makefile @@ -46,11 +46,14 @@ endif CURRENT_VERSION := $(shell git describe --abbrev=0 --tags) +GIT_TAG := $(shell git describe --abbrev=0 --tags) +GIT_SHA := $(shell git rev-parse --short=7 HEAD) + # If on a tagged commit, use just the tag ifneq ($(shell echo $(shell git tag -l --points-at HEAD) | head -c 1),) -GIT_VER := $(shell git tag -l --points-at HEAD) +GIT_VER := $(GIT_TAG) else -GIT_VER := $(shell git describe --abbrev=0 --tags)-$(shell git rev-parse --short=7 HEAD) +GIT_VER := $(GIT_TAG)-$(GIT_SHA) endif # Ensure version.hpp exists @@ -61,7 +64,7 @@ endif # Print new version if changed ifeq (,$(findstring $(GIT_VER), $(shell cat include/version.hpp))) -$(shell printf "#ifndef VERSION_HPP\n#define VERSION_HPP\n\n#define VER_NUMBER \"$(GIT_VER)\"\n\n#endif\n" > include/version.hpp) +$(shell printf "#ifndef VERSION_HPP\n#define VERSION_HPP\n\n#define VER_NUMBER \"$(GIT_VER)\"\n#define GIT_SHA \"$(GIT_SHA)\"\n\n#endif\n" > include/version.hpp) endif #--------------------------------------------------------------------------------- @@ -121,7 +124,7 @@ CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17 $(CITRA) ASFLAGS := -g $(ARCH) LDFLAGS = -specs=3dsx.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map) -LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -larchive -lbz2 -llzma -lm -lz -lcitro2d -lcitro3d -lctru -lstdc++ +LIBS := -lcurl -lmbedtls -lmbedx509 -lmbedcrypto -larchive -lbz2 -llzma -lz -lcitro2d -lcitro3d -lctru -lstdc++ #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/include/utils/config.hpp b/include/utils/config.hpp index 636fd27..3a2444e 100644 --- a/include/utils/config.hpp +++ b/include/utils/config.hpp @@ -78,6 +78,10 @@ public: bool updatecheck() const { return this->v_updateCheck; }; void updatecheck(bool v) { this->v_updateCheck = v; if (!this->changesMade) this->changesMade = true; }; + /* Check for nightly/release on startup. */ + bool updatenightly() const { return this->v_updateNightly; }; + void updatenightly(bool v) { this->v_updateNightly = v; if (!this->changesMade) this->changesMade = true; }; + /* U-U Update check on startup. */ bool usebg() const { return this->v_showBg; }; void usebg(bool v) { this->v_showBg = v; if (!this->changesMade) this->changesMade = true; }; @@ -117,7 +121,7 @@ private: v_3dsxPath = "sdmc:/3ds", v_ndsPath = "sdmc:", v_archivePath = "sdmc:", v_shortcutPath = "sdmc:/3ds/Universal-Updater/shortcuts", v_firmPath = "sdmc:/luma/payloads", v_theme = "Default"; - bool v_list = false, v_autoUpdate = true, v_metadata = true, v_updateCheck = true, + bool v_list = false, v_autoUpdate = true, v_metadata = true, v_updateCheck = true, v_updateNightly = false, v_showBg = false, v_customFont = false, v_changelog = true, v_prompt = true, v_3dsxInFolder = false; }; diff --git a/include/utils/download.hpp b/include/utils/download.hpp index 6fe5d44..53ebb66 100644 --- a/include/utils/download.hpp +++ b/include/utils/download.hpp @@ -30,7 +30,6 @@ #include "common.hpp" #define APP_TITLE "Universal-Updater" -#define VERSION_STRING "3.0.0" enum DownloadError { DL_ERROR_NONE = 0, diff --git a/romfs/lang/en/app.json b/romfs/lang/en/app.json index 73016b8..92eff29 100644 --- a/romfs/lang/en/app.json +++ b/romfs/lang/en/app.json @@ -9,6 +9,8 @@ "ASCENDING": "Ascending", "ARGUMENT_INVALID": "Argument invalid.\nPlease check the xml file for proper arguments.", "AUTHOR": "Author", + "AUTO_UPDATE_NIGHTLY": "Use nightly versions", + "AUTO_UPDATE_NIGHTLY_DESC": "Use nightly versions of Universal-Updater instead of the stable releases.", "AUTO_UPDATE_SETTINGS": "Auto-Update Settings", "AUTO_UPDATE_SETTINGS_BTN": "Auto-update settings...", "AUTO_UPDATE_UNISTORE": "Auto-update UniStores", diff --git a/source/menu/settings.cpp b/source/menu/settings.cpp index 65b529d..6e32c13 100644 --- a/source/menu/settings.cpp +++ b/source/menu/settings.cpp @@ -56,7 +56,8 @@ static const std::vector langButtons = { static const std::vector toggleAbles = { { 288, 44, 24, 24 }, - { 288, 120, 24, 24 } + { 288, 110, 24, 24 }, + { 288, 180, 24, 24 } }; static const std::vector dirButtons = { @@ -167,10 +168,15 @@ static void DrawAutoUpdate(int selection) { GFX::DrawToggle(toggleAbles[0].x, toggleAbles[0].y, config->autoupdate()); Gui::DrawString(47, 75, 0.4f, UIThemes->TextColor(), Lang::get("AUTO_UPDATE_UNISTORE_DESC"), 265, 0, font, C2D_WordWrap); - Gui::Draw_Rect(40, 120, 280, 24, (selection == 1 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected())); - Gui::DrawString(47, 124, 0.5f, UIThemes->TextColor(), Lang::get("AUTO_UPDATE_UU"), 210, 0, font); + Gui::Draw_Rect(40, 110, 280, 24, (selection == 1 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected())); + Gui::DrawString(47, 114, 0.5f, UIThemes->TextColor(), Lang::get("AUTO_UPDATE_UU"), 210, 0, font); GFX::DrawToggle(toggleAbles[1].x, toggleAbles[1].y, config->updatecheck()); - Gui::DrawString(47, 151, 0.4f, UIThemes->TextColor(), Lang::get("AUTO_UPDATE_UU_DESC"), 265, 0, font, C2D_WordWrap); + Gui::DrawString(47, 141, 0.4f, UIThemes->TextColor(), Lang::get("AUTO_UPDATE_UU_DESC"), 265, 0, font, C2D_WordWrap); + + Gui::Draw_Rect(40, 180, 280, 24, (selection == 2 ? UIThemes->MarkSelected() : UIThemes->MarkUnselected())); + Gui::DrawString(47, 184, 0.5f, UIThemes->TextColor(), Lang::get("AUTO_UPDATE_NIGHTLY"), 210, 0, font); + GFX::DrawToggle(toggleAbles[2].x, toggleAbles[2].y, config->updatenightly()); + Gui::DrawString(47, 211, 0.4f, UIThemes->TextColor(), Lang::get("AUTO_UPDATE_NIGHTLY_DESC"), 265, 0, font, C2D_WordWrap); } /* @@ -442,7 +448,7 @@ static void AutoUpdateLogic(int &page, int &selection) { } if (hRepeat & KEY_DOWN) { - if (selection < 1) selection++; + if (selection < 2) selection++; } if (hRepeat & KEY_UP) { @@ -459,6 +465,9 @@ static void AutoUpdateLogic(int &page, int &selection) { } else if (touching(touch, toggleAbles[1])) { config->updatecheck(!config->updatecheck()); + + } else if (touching(touch, toggleAbles[2])) { + config->updatenightly(!config->updatenightly()); } } @@ -471,6 +480,10 @@ static void AutoUpdateLogic(int &page, int &selection) { case 1: config->updatecheck(!config->updatecheck()); break; + + case 2: + config->updatenightly(!config->updatenightly()); + break; } } } diff --git a/source/utils/config.cpp b/source/utils/config.cpp index 6a7eead..8e60a6f 100644 --- a/source/utils/config.cpp +++ b/source/utils/config.cpp @@ -134,6 +134,7 @@ Config::Config() { if (this->json.contains("Firm_Path")) this->firmPath(this->getString("Firm_Path")); if (this->json.contains("MetaData")) this->metadata(this->getBool("MetaData")); if (this->json.contains("UpdateCheck")) this->updatecheck(this->getBool("UpdateCheck")); + if (this->json.contains("UpdateNightly")) this->updatenightly(this->getBool("UpdateNightly")); if (this->json.contains("UseBG")) this->usebg(this->getBool("UseBG")); if (this->json.contains("CustomFont")) this->customfont(this->getBool("CustomFont")); if (this->json.contains("Shortcut_Path")) this->shortcut(this->getString("Shortcut_Path")); @@ -173,6 +174,7 @@ void Config::save() { this->setString("Firm_Path", this->firmPath()); this->setBool("MetaData", this->metadata()); this->setBool("UpdateCheck", this->updatecheck()); + this->setBool("UpdateNightly", this->updatenightly()); this->setBool("UseBG", this->usebg()); this->setBool("CustomFont", this->customfont()); this->setString("Shortcut_Path", this->shortcut()); diff --git a/source/utils/download.cpp b/source/utils/download.cpp index 3df027b..ca27bcd 100644 --- a/source/utils/download.cpp +++ b/source/utils/download.cpp @@ -33,6 +33,7 @@ #include "screenshot.hpp" #include "scriptUtils.hpp" #include "stringutils.hpp" +#include "version.hpp" #include <3ds.h> #include @@ -43,7 +44,7 @@ #include #include -#define USER_AGENT APP_TITLE "-" VERSION_STRING +#define USER_AGENT APP_TITLE "-" VER_NUMBER static char *result_buf = nullptr; static size_t result_sz = 0; @@ -795,7 +796,11 @@ UUUpdate IsUUUpdateAvailable() { CURL *hnd = curl_easy_init(); - ret = setupContext(hnd, "https://api.github.com/repos/Universal-Team/Universal-Updater/releases/latest"); + const char *url; + if (config->updatenightly()) url = "https://api.github.com/repos/Universal-Team/Universal-Updater/commits"; + else url = "https://api.github.com/repos/Universal-Team/Universal-Updater/releases/latest"; + + ret = setupContext(hnd, url); if (ret != 0) { socExit(); free(result_buf); @@ -826,21 +831,39 @@ UUUpdate IsUUUpdateAvailable() { if (nlohmann::json::accept(result_buf)) { nlohmann::json parsedAPI = nlohmann::json::parse(result_buf); - if (parsedAPI.contains("tag_name") && parsedAPI["tag_name"].is_string()) { - UUUpdate update = { false, "", "" }; - update.Version = parsedAPI["tag_name"]; + if (config->updatenightly()) { + if (parsedAPI.is_array() && parsedAPI.size() > 0 && parsedAPI[0].contains("sha") && parsedAPI[0]["sha"].is_string()) { + socExit(); + free(result_buf); + free(socubuf); + result_buf = nullptr; + result_sz = 0; + result_written = 0; - socExit(); - free(result_buf); - free(socubuf); - result_buf = nullptr; - result_sz = 0; - result_written = 0; + UUUpdate update = { false, "", "" }; + update.Version = parsedAPI[0]["sha"].get_ref().substr(0, 7); + if (parsedAPI[0].contains("commit") && parsedAPI[0]["commit"].is_object() && parsedAPI[0]["commit"].contains("message") && parsedAPI[0]["commit"]["message"].is_string()) + update.Notes = parsedAPI[0]["commit"]["message"]; + update.Notes.erase(remove(update.Notes.begin(), update.Notes.end(), '\r'), update.Notes.end()); // Remove the CRLF \r's. + update.Available = strcasecmp(update.Version.c_str(), GIT_SHA) != 0; + return update; + } + } else { + if (parsedAPI.contains("tag_name") && parsedAPI["tag_name"].is_string()) { + socExit(); + free(result_buf); + free(socubuf); + result_buf = nullptr; + result_sz = 0; + result_written = 0; - if (parsedAPI["body"].is_string()) update.Notes = parsedAPI["body"]; - update.Notes.erase(remove(update.Notes.begin(), update.Notes.end(), '\r'), update.Notes.end()); // Remove the CRLF \r's. - update.Available = strcasecmp(StringUtils::lower_case(update.Version).c_str(), StringUtils::lower_case(C_V).c_str()) > 0; - return update; + UUUpdate update = { false, "", "" }; + update.Version = parsedAPI["tag_name"]; + if (parsedAPI["body"].is_string()) update.Notes = parsedAPI["body"]; + update.Notes.erase(remove(update.Notes.begin(), update.Notes.end(), '\r'), update.Notes.end()); // Remove the CRLF \r's. + update.Available = strcasecmp(update.Version.c_str(), C_V) > 0; + return update; + } } } @@ -904,10 +927,15 @@ void UpdateAction() { if ((down & KEY_A) || (down & KEY_B) || (down & KEY_START) || (down & KEY_TOUCH)) confirmed = true; } - if (ScriptUtils::downloadRelease("Universal-Team/Universal-Updater", (is3DSX ? "Universal-Updater.3dsx" : "Universal-Updater.cia"), - (is3DSX ? _3dsxPath : "sdmc:/Universal-Updater.cia"), - false, Lang::get("DONLOADING_UNIVERSAL_UPDATER"), true) == 0) { + Result dlRes; + if (config->updatenightly()) + dlRes = ScriptUtils::downloadFile("https://raw.githubusercontent.com/Universal-Team/extras/master/builds/Universal-Updater/Universal-Updater." + std::string(is3DSX ? "3dsx" : "cia"), + (is3DSX ? _3dsxPath : "sdmc:/Universal-Updater.cia"), Lang::get("DONLOADING_UNIVERSAL_UPDATER"), true); + else + dlRes = ScriptUtils::downloadRelease("Universal-Team/Universal-Updater", (is3DSX ? "Universal-Updater.3dsx" : "Universal-Updater.cia"), + (is3DSX ? _3dsxPath : "sdmc:/Universal-Updater.cia"), false, Lang::get("DONLOADING_UNIVERSAL_UPDATER"), true); + if (dlRes == ScriptState::NONE) { if (is3DSX) { Msg::waitMsg(Lang::get("UPDATE_DONE")); exiting = true;