From 9b80fa5dc837916ef63819eb825c481951e9f6c3 Mon Sep 17 00:00:00 2001 From: J-D-K Date: Tue, 30 Sep 2025 15:51:54 -0400 Subject: [PATCH] Complete Update checking/downloading. --- Makefile | 2 +- include/JKSV.hpp | 6 +++++- include/builddate.hpp | 2 +- include/cmdargs.hpp | 10 ++++++++++ source/JKSV.cpp | 8 +++++--- source/appstates/BlacklistEditState.cpp | 2 +- source/appstates/SettingsState.cpp | 9 +++++++-- source/cmdargs.cpp | 21 +++++++++++++++++++++ source/config/ConfigContext.cpp | 4 +++- source/config/config.cpp | 9 +++++++-- source/data/data.cpp | 1 + source/main.cpp | 4 ++++ source/tasks/backup.cpp | 15 ++++----------- source/tasks/update.cpp | 8 ++++++-- 14 files changed, 76 insertions(+), 25 deletions(-) create mode 100644 include/cmdargs.hpp create mode 100644 source/cmdargs.cpp diff --git a/Makefile b/Makefile index bc76fd8..eb054f4 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ INCLUDES := include ./Libraries/FsLib/Switch/FsLib/include ./Libraries/SDLLib/SD EXEFS_SRC := exefs_src APP_TITLE := JKSV APP_AUTHOR := JK -APP_VERSION := 09.29.2025 +APP_VERSION := 09.30.2025 ROMFS := romfs ICON := icon.jpg diff --git a/include/JKSV.hpp b/include/JKSV.hpp index cc2fe2f..f7be225 100644 --- a/include/JKSV.hpp +++ b/include/JKSV.hpp @@ -2,6 +2,7 @@ #include "appstates/BaseState.hpp" #include "sdl.hpp" +#include #include #include @@ -25,9 +26,12 @@ class JKSV /// @brief Runs JKSV's render routine. void render(); + /// @brief Function to allow tasks to tell JKSV to exit. + static void request_quit() noexcept; + private: /// @brief Whether or not initialization was successful and JKSV is still running. - bool m_isRunning{}; + static inline std::atomic_bool sm_isRunning{}; /// @brief Whether or not to print the translation credits. bool m_showTranslationInfo{}; diff --git a/include/builddate.hpp b/include/builddate.hpp index 94b94c2..cb0634b 100644 --- a/include/builddate.hpp +++ b/include/builddate.hpp @@ -3,6 +3,6 @@ namespace builddate { inline constexpr int MONTH = 9; - inline constexpr int DAY = 29; + inline constexpr int DAY = 30; inline constexpr int YEAR = 2025; } diff --git a/include/cmdargs.hpp b/include/cmdargs.hpp new file mode 100644 index 0000000..b7492fa --- /dev/null +++ b/include/cmdargs.hpp @@ -0,0 +1,10 @@ +#pragma once + +namespace cmdargs +{ + /// @brief Stores the pointers passed to main for later usage without making JKSV a mess. + void store(int argc, const char *argv[]); + + /// @brief Gets the argument at index. + const char *get(int index); +} diff --git a/source/JKSV.cpp b/source/JKSV.cpp index 7c09765..f862b43 100644 --- a/source/JKSV.cpp +++ b/source/JKSV.cpp @@ -85,7 +85,7 @@ JKSV::JKSV() data::launch_initialization(false, finish_initialization); - m_isRunning = true; + sm_isRunning = true; } JKSV::~JKSV() @@ -101,7 +101,7 @@ JKSV::~JKSV() appletUnlockExit(); } -bool JKSV::is_running() const noexcept { return m_isRunning && appletMainLoop(); } +bool JKSV::is_running() const noexcept { return sm_isRunning && appletMainLoop(); } void JKSV::update() { @@ -109,7 +109,7 @@ void JKSV::update() const bool plusPressed = input::button_pressed(HidNpadButton_Plus); const bool isClosable = StateManager::back_is_closable(); - if (plusPressed && isClosable) { m_isRunning = false; } + if (plusPressed && isClosable) { sm_isRunning = false; } StateManager::update(); ui::PopMessageManager::update(); @@ -141,6 +141,8 @@ void JKSV::render() sdl::frame_end(); } +void JKSV::request_quit() noexcept { sm_isRunning = false; } + bool JKSV::initialize_filesystem() { // This needs to be in this specific order diff --git a/source/appstates/BlacklistEditState.cpp b/source/appstates/BlacklistEditState.cpp index 38eabad..f0345b3 100644 --- a/source/appstates/BlacklistEditState.cpp +++ b/source/appstates/BlacklistEditState.cpp @@ -25,7 +25,7 @@ void BlacklistEditState::update() sm_slidePanel->update(hasFocus); if (aPressed) { BlacklistEditState::remove_from_blacklist(); } - else if (bPressed || m_blacklist.empty()) { sm_slidePanel->close(); } + else if (bPressed || config::blacklist_is_empty()) { sm_slidePanel->close(); } else if (sm_slidePanel->is_closed()) { BlacklistEditState::deactivate_state(); } } diff --git a/source/appstates/SettingsState.cpp b/source/appstates/SettingsState.cpp index a40be14..3337ac8 100644 --- a/source/appstates/SettingsState.cpp +++ b/source/appstates/SettingsState.cpp @@ -179,7 +179,9 @@ void SettingsState::change_working_directory() moved = fs::move_directory_recursively(oldPath, newPath); error::fslib(fslib::delete_directory_recursively(oldPath)); } - else { moved = fslib::rename_directory(oldPath, newPath); } + else { + moved = fslib::rename_directory(oldPath, newPath); + } if (!moved) { @@ -212,6 +214,7 @@ void SettingsState::create_push_blacklist_edit() void SettingsState::toggle_options() { const int selected = m_settingsMenu->get_selected(); + switch (selected) { case CHANGE_WORK_DIR: SettingsState::change_working_directory(); break; @@ -270,7 +273,9 @@ void SettingsState::toggle_trash_folder() config::toggle_by_key(config::keys::ENABLE_TRASH_BIN); if (trashEnabled) { error::fslib(fslib::delete_directory_recursively(trashPath)); } - else { error::fslib(fslib::create_directory(trashPath)); } + else { + error::fslib(fslib::create_directory(trashPath)); + } } void SettingsState::cycle_anim_scaling() diff --git a/source/cmdargs.cpp b/source/cmdargs.cpp new file mode 100644 index 0000000..2eb86f7 --- /dev/null +++ b/source/cmdargs.cpp @@ -0,0 +1,21 @@ +#include "CmdArgs.hpp" + +#include + +namespace +{ + std::vector s_args{}; +} + +void cmdargs::store(int argc, const char *argv[]) +{ + for (int i = 0; i < argc; i++) { s_args.push_back(argv[i]); } +} + +const char *cmdargs::get(int index) +{ + const int argCount = s_args.size(); + if (index < 0 || index >= argCount) { return nullptr; } + + return s_args[index]; +} diff --git a/source/config/ConfigContext.cpp b/source/config/ConfigContext.cpp index 5b69437..81dd961 100644 --- a/source/config/ConfigContext.cpp +++ b/source/config/ConfigContext.cpp @@ -201,7 +201,9 @@ bool config::ConfigContext::load_config_file() else if (scaling) { m_animationScaling = json_object_get_double(value); } else if (favorites) { ConfigContext::read_array_to_set(m_favorites, value); } else if (blacklist) { ConfigContext::read_array_to_set(m_blacklist, value); } - else { m_configMap[key] = json_object_get_uint64(value); } + else { + m_configMap[key] = json_object_get_uint64(value); + } json_object_iter_next(&configIter); } diff --git a/source/config/config.cpp b/source/config/config.cpp index 7d7612c..57688ea 100644 --- a/source/config/config.cpp +++ b/source/config/config.cpp @@ -1,6 +1,7 @@ #include "config/config.hpp" #include "config/ConfigContext.hpp" +#include "logging/logger.hpp" namespace { @@ -38,7 +39,9 @@ void config::add_remove_favorite(uint64_t applicationID) { const bool favorite = s_context.is_favorite(applicationID); if (favorite) { s_context.remove_favorite(applicationID); } - else { s_context.add_favorite(applicationID); } + else { + s_context.add_favorite(applicationID); + } } bool config::is_favorite(uint64_t applicationID) noexcept { return s_context.is_favorite(applicationID); } @@ -47,7 +50,9 @@ void config::add_remove_blacklist(uint64_t applicationID) { const bool blacklisted = s_context.is_blacklisted(applicationID); if (blacklisted) { s_context.remove_from_blacklist(applicationID); } - else { s_context.add_to_blacklist(applicationID); } + else { + s_context.add_to_blacklist(applicationID); + } } void config::get_blacklisted_titles(std::vector &listOut) { s_context.get_blacklist(listOut); } diff --git a/source/data/data.cpp b/source/data/data.cpp index 4467337..e236707 100644 --- a/source/data/data.cpp +++ b/source/data/data.cpp @@ -1,6 +1,7 @@ #include "data/data.hpp" #include "appstates/DataLoadingState.hpp" +#include "appstates/FadeState.hpp" #include "data/DataContext.hpp" #include "error.hpp" #include "logging/logger.hpp" diff --git a/source/main.cpp b/source/main.cpp index d489d06..153b12a 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,9 +1,13 @@ #include "JKSV.hpp" +#include "cmdargs.hpp" #include int main(int argc, const char *argv[]) { + // Store the pointers here so JKSV can update itself from where ever the use might have placed it. + cmdargs::store(argc, argv); + JKSV jksv{}; while (jksv.is_running()) { diff --git a/source/tasks/backup.cpp b/source/tasks/backup.cpp index 43ac65a..c60c0f5 100644 --- a/source/tasks/backup.cpp +++ b/source/tasks/backup.cpp @@ -40,8 +40,6 @@ void tasks::backup::create_new_backup_local(sys::threadpool::JobData taskData) if (error::is_null(user) || error::is_null(titleInfo)) { TASK_FINISH_RETURN(task); } const std::string targetString = target.string(); - logger::log("targetString: %s", targetString.c_str()); - const bool hasZipExt = std::strstr(targetString.c_str(), STRING_ZIP_EXT); const uint64_t applicationID = titleInfo->get_application_id(); const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID); @@ -56,8 +54,7 @@ void tasks::backup::create_new_backup_local(sys::threadpool::JobData taskData) auto scopedMount = create_scoped_mount(saveInfo); fs::copy_directory_to_zip(fs::DEFAULT_SAVE_ROOT, zip, task); } - else - { + else { const bool needsDir = !fslib::directory_exists(target); const bool createError = needsDir && error::fslib(fslib::create_directory(target)); if (needsDir && createError) { TASK_FINISH_RETURN(task); } @@ -264,8 +261,7 @@ void tasks::backup::restore_backup_local(sys::threadpool::JobData taskData) auto scopedMount = create_scoped_mount(saveInfo); fs::copy_directory_commit(target, fs::DEFAULT_SAVE_ROOT, journalSize, task); } - else - { + else { auto scopedMount = create_scoped_mount(saveInfo); fs::copy_file_commit(target, fs::DEFAULT_SAVE_ROOT, journalSize, task); } @@ -395,8 +391,7 @@ void tasks::backup::delete_backup_local(sys::threadpool::JobData taskData) dirError = isDir && error::fslib(fslib::rename_directory(path, newPath)); fileError = !isDir && error::fslib(fslib::rename_file(path, newPath)); } - else - { + else { dirError = isDir && error::fslib(fslib::delete_directory_recursively(path)); fileError = !isDir && error::fslib(fslib::delete_file(path)); } @@ -535,14 +530,12 @@ static void auto_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskD tasks::backup::create_new_backup_remote(tempData); } - else - { + else { // We're going to get the target dir from the path passed. const size_t lastSlash = target.find_last_of('/'); if (lastSlash == target.NOT_FOUND) { return; } fslib::Path autoTarget{target.sub_path(lastSlash) / backupName}; - logger::log("autoTarget: %s", autoTarget.string().c_str()); tempData->path = std::move(autoTarget); diff --git a/source/tasks/update.cpp b/source/tasks/update.cpp index cc7c5da..f80ffbe 100644 --- a/source/tasks/update.cpp +++ b/source/tasks/update.cpp @@ -4,6 +4,7 @@ #include "appstates/ConfirmState.hpp" #include "appstates/MainMenuState.hpp" #include "builddate.hpp" +#include "cmdargs.hpp" #include "curl/curl.hpp" #include "error.hpp" #include "json.hpp" @@ -75,8 +76,9 @@ void tasks::update::download_update(sys::threadpool::JobData jobData) task->reset(static_cast(nroSize)); // To do: Figure out how to get the argument from main here. - error::libnx(romfsExit()); // This is needed so I can overwrite the NRO. - fslib::File jksv{"sdmc:/switch/JKSV.nro", FsOpenMode_Create | FsOpenMode_Write, static_cast(nroSize)}; + error::libnx(romfsExit()); // This is needed so I can overwrite the NRO. + const char *location = cmdargs::get(0); // This is the location from the command line args. + fslib::File jksv{location, FsOpenMode_Create | FsOpenMode_Write, static_cast(nroSize)}; if (error::fslib(jksv.is_open())) { TASK_FINISH_RETURN(task); } auto download = curl::create_download_struct(jksv, task, nroSize); @@ -90,6 +92,8 @@ void tasks::update::download_update(sys::threadpool::JobData jobData) download->writeComplete.acquire(); task->complete(); + + JKSV::request_quit(); } static std::string get_git_json(curl::Handle &handle)