diff --git a/Makefile b/Makefile index b26bbd1..a21ac11 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DATA := data INCLUDES := include /lib/borealis/library/include/borealis/extern/nlohmann APP_TITLE := All-in-One Switch Updater APP_AUTHOR := HamletDuFromage -APP_VERSION := 2.20.1 +APP_VERSION := 2.21.0 TARGET := $(notdir $(CURDIR)) ROMFS := resources diff --git a/aiosu-forwarder/source/main.cpp b/aiosu-forwarder/source/main.cpp index 9fedc17..8f065d0 100644 --- a/aiosu-forwarder/source/main.cpp +++ b/aiosu-forwarder/source/main.cpp @@ -41,6 +41,6 @@ int main(int argc, char* argv[]) std::filesystem::remove(FORWARDER_PATH); - envSetNextLoad(FULL_PATH, ("\"" + std::string(FULL_PATH) + "\"").c_str()); + envSetNextLoad(FULL_PATH, FULL_PATH); return 0; } diff --git a/include/ams_tab.hpp b/include/ams_tab.hpp index f288bf9..363a0a4 100644 --- a/include/ams_tab.hpp +++ b/include/ams_tab.hpp @@ -8,20 +8,45 @@ class AmsTab : public brls::List { -private: +protected: brls::ListItem* listItem; bool erista; - contentType type; + nlohmann::ordered_json nxlinks; nlohmann::ordered_json hekate; - std::string GetRepoName(const std::string& repo); - std::set GetLastDownloadedModules(const std::string& json_path); + contentType type; void CreateStagedFrames(const std::string& text, const std::string& url, bool erista, bool ams = true, bool hekate = false, const std::string& text_hekate = "", const std::string& hekate_url = ""); - void CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate = true, bool ams = true); - nlohmann::ordered_json SortDeepseaModules(const nlohmann::ordered_json& modules); - void ShowCustomDeepseaBuilder(nlohmann::ordered_json& modules); + bool CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate = true, bool ams = true); + void CreateNotFoundLabel(); + virtual void RegisterListItemAction(brls::ListItem* listItem); public: - AmsTab(const nlohmann::json& nxlinks, const bool erista = true, const bool custom = false); + AmsTab(const nlohmann::ordered_json& nxlinks, const bool erista = true); +}; + +class AmsTab_Regular : public AmsTab +{ +private: + void CreateLists(); + bool CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate = true, bool ams = true); + void ShowCustomDeepseaBuilder(nlohmann::ordered_json& modules); + std::set GetLastDownloadedModules(const std::string& json_path); + nlohmann::ordered_json SortDeepseaModules(const nlohmann::ordered_json& modules); + std::string GetRepoName(const std::string& repo); + +public: + AmsTab_Regular(const nlohmann::ordered_json& nxlinks, const bool erista = true); +}; + +class AmsTab_Custom : public AmsTab +{ +private: + nlohmann::ordered_json custom_packs; + void CreateLists(); + void RegisterListItemAction(brls::ListItem* listItem) override; + void AddLinkCreator(); + +public: + AmsTab_Custom(const nlohmann::ordered_json& nxlinks, const bool erista = true); }; class UnTogglableListItem : public brls::ToggleListItem diff --git a/include/color_swapper.hpp b/include/color_swapper.hpp index 72601ce..b445722 100644 --- a/include/color_swapper.hpp +++ b/include/color_swapper.hpp @@ -6,10 +6,10 @@ namespace JC { int setColor(const std::vector& colors); - int backupToJSON(nlohmann::json& profiles, const std::string& path); + int backupToJSON(nlohmann::ordered_json& profiles, const std::string& path); std::deque>> getProfiles(const std::string& path); void changeJCColor(const std::vector& values); - nlohmann::json backupProfile(); + nlohmann::ordered_json backupProfile(); void backupJCColor(const std::string& path); } // namespace JC @@ -17,10 +17,10 @@ namespace JC { namespace PC { int setColor(const std::vector& colors); - int backupToJSON(nlohmann::json& profiles, const std::string& path); + int backupToJSON(nlohmann::ordered_json& profiles, const std::string& path); std::deque>> getProfiles(const std::string& path); void changePCColor(const std::vector& values); - nlohmann::json backupProfile(); + nlohmann::ordered_json backupProfile(); void backupPCColor(const std::string& path); } // namespace PC diff --git a/include/constants.hpp b/include/constants.hpp index 63ad498..4883e9e 100644 --- a/include/constants.hpp +++ b/include/constants.hpp @@ -3,6 +3,7 @@ constexpr const char ROOT_PATH[] = "/"; constexpr const char APP_PATH[] = "/switch/aio-switch-updater/"; constexpr const char NRO_PATH[] = "/switch/aio-switch-updater/aio-switch-updater.nro"; +constexpr const char NRO_PATH_REGEX[] = ".*(/switch/.*aio-switch-updater.nro).*"; constexpr const char DOWNLOAD_PATH[] = "/config/aio-switch-updater/"; constexpr const char CONFIG_PATH[] = "/config/aio-switch-updater/"; constexpr const char CONFIG_FILE[] = "/config/aio-switch-updater/config.json"; diff --git a/include/download_cheats_page.hpp b/include/download_cheats_page.hpp index 8383583..452d761 100644 --- a/include/download_cheats_page.hpp +++ b/include/download_cheats_page.hpp @@ -57,7 +57,7 @@ class DownloadCheatsPage_CheatSlips : public DownloadCheatsPage private: brls::ToggleListItem* listItem; std::vector> toggles; - std::string GetCheatsTitle(nlohmann::json cheat); + std::string GetCheatsTitle(nlohmann::ordered_json cheat); void ShowCheatsContent(nlohmann::ordered_json titles); public: diff --git a/include/fs.hpp b/include/fs.hpp index 1e2b8bf..017c7ab 100644 --- a/include/fs.hpp +++ b/include/fs.hpp @@ -9,7 +9,7 @@ namespace fs { std::vector splitString(const std::string& s, char delimiter); bool removeDir(const std::string& path); nlohmann::ordered_json parseJsonFile(const std::string& path); - void writeJsonToFile(nlohmann::json& data, const std::string& path); + void writeJsonToFile(nlohmann::ordered_json& data, const std::string& path); bool copyFile(const std::string& from, const std::string& to); std::string copyFiles(const std::string& path); void createTree(std::string path); diff --git a/include/tools_tab.hpp b/include/tools_tab.hpp index c743eb6..54ba262 100644 --- a/include/tools_tab.hpp +++ b/include/tools_tab.hpp @@ -10,5 +10,5 @@ private: brls::StagedAppletFrame* stagedFrame; public: - ToolsTab(const std::string& tag, const nlohmann::ordered_json& payloads, bool erista = true, const nlohmann::json& hideStatus = {}); + ToolsTab(const std::string& tag, const nlohmann::ordered_json& payloads, bool erista = true, const nlohmann::ordered_json& hideStatus = {}); }; \ No newline at end of file diff --git a/include/utils.hpp b/include/utils.hpp index 12232ca..7ebe0ee 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -41,6 +41,7 @@ namespace util { void saveToFile(const std::string& text, const std::string& path); std::string readFile(const std::string& path); std::string getAppPath(); + void restartApp(); bool isErista(); void removeSysmodulesFlags(const std::string& directory); std::string lowerCase(const std::string& str); @@ -48,6 +49,6 @@ namespace util { std::string getErrorMessage(long status_code); bool isApplet(); std::string getContentsPath(); - bool getBoolValue(const nlohmann::json& jsonFile, const std::string& key); + bool getBoolValue(const nlohmann::ordered_json& jsonFile, const std::string& key); const nlohmann::ordered_json getValueFromKey(const nlohmann::ordered_json& jsonFile, const std::string& key); } // namespace util \ No newline at end of file diff --git a/resources/i18n/en-US/menus.json b/resources/i18n/en-US/menus.json index 17d9942..ac64a13 100644 --- a/resources/i18n/en-US/menus.json +++ b/resources/i18n/en-US/menus.json @@ -189,7 +189,9 @@ "custom_packs_label": "\u25c6 Here are packs listed in the {} file. Be aware that those are not endorsed by AIO-Switch-Updater so make sure you trust their source.", "custom_packs_ams": "\u25c6 Downloads containing the Atmosphère custom firmware.", "custom_packs_misc": "\u25c6 Downloads containing homebrew and tools.", - "custom_download" : "Custom download" + "custom_download" : "Custom download", + "add_custom_link": "Add a custom link", + "delete_custom_link": "Delete" }, "firmware": { "launch_daybreak": "Do you want to launch Daybreak to install the downloaded sysupdate?" diff --git a/source/ams_tab.cpp b/source/ams_tab.cpp index 53829b2..756c121 100644 --- a/source/ams_tab.cpp +++ b/source/ams_tab.cpp @@ -1,6 +1,7 @@ #include "ams_tab.hpp" #include +#include #include #include "confirm_page.hpp" @@ -11,75 +12,30 @@ #include "fs.hpp" #include "utils.hpp" #include "worker_page.hpp" - namespace i18n = brls::i18n; using namespace i18n::literals; -AmsTab::AmsTab(const nlohmann::json& nxlinks, const bool erista, const bool custom) : brls::List() +AmsTab::AmsTab(const nlohmann::ordered_json& nxlinks, const bool erista) : brls::List() { this->erista = erista; + this->nxlinks = nxlinks; this->hekate = util::getValueFromKey(nxlinks, "hekate"); - - if (!custom) { - this->type = contentType::ams_cfw; - auto cfws = util::getValueFromKey(nxlinks, "cfws"); - - this->addView(new brls::Label(brls::LabelStyle::DESCRIPTION, "menus/main/ams_text"_i18n + (CurrentCfw::running_cfw == CFW::ams ? "\n" + "menus/ams_update/current_ams"_i18n + CurrentCfw::getAmsInfo() : "") + (erista ? "\n" + "menus/ams_update/erista_rev"_i18n : "\n" + "menus/ams_update/mariko_rev"_i18n), true)); - CreateDownloadItems(util::getValueFromKey(cfws, "Atmosphere")); - - this->addView(new brls::Label( - brls::LabelStyle::DESCRIPTION, - "menus/ams_update/deepsea_label"_i18n, - true)); - - listItem = new brls::ListItem("menus/ams_update/get_custom_deepsea"_i18n); - listItem->setHeight(LISTITEM_HEIGHT); - listItem->getClickEvent()->subscribe([this](brls::View* view) { - nlohmann::ordered_json modules; - download::getRequest(DEEPSEA_META_JSON, modules); - this->ShowCustomDeepseaBuilder(modules); - }); - this->addView(listItem); - CreateDownloadItems(util::getValueFromKey(cfws, "DeepSea"), false); - } - - else { - auto custom_pack = fs::parseJsonFile(CUSTOM_PACKS_PATH); - this->addView(new brls::Label( - brls::LabelStyle::DESCRIPTION, - fmt::format("menus/ams_update/custom_packs_label"_i18n, CUSTOM_PACKS_PATH), - true)); - if (custom_pack.contains("ams") && custom_pack["ams"].size() != 0) { - this->type = contentType::ams_cfw; - this->addView(new brls::Label( - brls::LabelStyle::DESCRIPTION, - "menus/ams_update/custom_packs_ams"_i18n, - true)); - CreateDownloadItems(custom_pack["ams"], true); - } - if (custom_pack.contains("misc") && custom_pack["misc"].size() != 0) { - this->type = contentType::custom; - this->addView(new brls::Label( - brls::LabelStyle::DESCRIPTION, - "menus/ams_update/custom_packs_misc"_i18n, - true)); - CreateDownloadItems(custom_pack["misc"], false, false); - } - } } -void AmsTab::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate, bool ams) +void AmsTab::RegisterListItemAction(brls::ListItem* listItem) {} + +bool AmsTab::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate, bool ams) { std::vector> links; links = download::getLinksFromJson(cfw_links); - if (links.size() && !this->hekate.empty()) { // non-empty this->hekate indicates internet connection + if (links.size() && !this->hekate.empty()) { // non-empty this->hekate indicates internet connection auto hekate_link = download::getLinksFromJson(this->hekate); std::string hekate_url = hekate_link[0].second; std::string text_hekate = "menus/common/download"_i18n + hekate_link[0].first; for (const auto& link : links) { std::string url = link.second; - std::string text("menus/common/download"_i18n + link.first + "menus/common/from"_i18n + url); + std::string text("menus/common/download"_i18n + link.second + "menus/common/from"_i18n + url); listItem = new brls::ListItem(link.first); listItem->setHeight(LISTITEM_HEIGHT); listItem->getClickEvent()->subscribe([this, text, text_hekate, url, hekate_url, hekate, ams](brls::View* view) { @@ -90,17 +46,12 @@ void AmsTab::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool h CreateStagedFrames(text, url, erista, ams, hekate, text_hekate, hekate_url); } }); + this->RegisterListItemAction(listItem); this->addView(listItem); } + return true; } - else { - brls::Label* description = new brls::Label( - brls::LabelStyle::SMALL, - "menus/main/links_not_found"_i18n, - true); - description->setHorizontalAlign(NVG_ALIGN_CENTER); - this->addView(description); - } + return false; } void AmsTab::CreateStagedFrames(const std::string& text, const std::string& url, bool erista, bool ams, bool hekate, const std::string& text_hekate, const std::string& hekate_url) @@ -128,14 +79,56 @@ void AmsTab::CreateStagedFrames(const std::string& text, const std::string& url, brls::Application::pushView(stagedFrame); } -std::string AmsTab::GetRepoName(const std::string& repo) +AmsTab_Regular::AmsTab_Regular(const nlohmann::ordered_json& nxlinks, const bool erista) : AmsTab(nxlinks, erista) +{ + this->CreateLists(); +} + +bool AmsTab_Regular::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate, bool ams) +{ + if (!AmsTab::CreateDownloadItems(cfw_links, hekate, ams)) { + brls::Label* description = new brls::Label( + brls::LabelStyle::SMALL, + "menus/main/links_not_found"_i18n, + true); + description->setHorizontalAlign(NVG_ALIGN_CENTER); + this->addView(description); + return true; + } + return false; +} + +void AmsTab_Regular::CreateLists() +{ + this->type = contentType::ams_cfw; + auto cfws = util::getValueFromKey(this->nxlinks, "cfws"); + + this->addView(new brls::Label(brls::LabelStyle::DESCRIPTION, "menus/main/ams_text"_i18n + (CurrentCfw::running_cfw == CFW::ams ? "\n" + "menus/ams_update/current_ams"_i18n + CurrentCfw::getAmsInfo() : "") + (erista ? "\n" + "menus/ams_update/erista_rev"_i18n : "\n" + "menus/ams_update/mariko_rev"_i18n), true)); + CreateDownloadItems(util::getValueFromKey(cfws, "Atmosphere")); + + this->addView(new brls::Label( + brls::LabelStyle::DESCRIPTION, + "menus/ams_update/deepsea_label"_i18n, + true)); + listItem = new brls::ListItem("menus/ams_update/get_custom_deepsea"_i18n); + listItem->setHeight(LISTITEM_HEIGHT); + listItem->getClickEvent()->subscribe([this](brls::View* view) { + nlohmann::ordered_json modules; + download::getRequest(DEEPSEA_META_JSON, modules); + this->ShowCustomDeepseaBuilder(modules); + }); + this->addView(listItem); + CreateDownloadItems(util::getValueFromKey(cfws, "DeepSea"), false); +} + +std::string AmsTab_Regular::GetRepoName(const std::string& repo) { return repo.substr(repo.find("/") + 1, repo.length()); } -std::set AmsTab::GetLastDownloadedModules(const std::string& json_path) +std::set AmsTab_Regular::GetLastDownloadedModules(const std::string& json_path) { - nlohmann::json package = fs::parseJsonFile(json_path); + nlohmann::ordered_json package = fs::parseJsonFile(json_path); std::set res; if (package.find("modules") != package.end()) { for (const auto& module : package.at("modules")) { @@ -145,7 +138,7 @@ std::set AmsTab::GetLastDownloadedModules(const std::string& json_p return res; } -nlohmann::ordered_json AmsTab::SortDeepseaModules(const nlohmann::ordered_json& modules) +nlohmann::ordered_json AmsTab_Regular::SortDeepseaModules(const nlohmann::ordered_json& modules) { nlohmann::ordered_json sorted_modules = nlohmann::ordered_json::object(); if (modules.find("modules") != modules.end()) { @@ -156,7 +149,7 @@ nlohmann::ordered_json AmsTab::SortDeepseaModules(const nlohmann::ordered_json& return sorted_modules; } -void AmsTab::ShowCustomDeepseaBuilder(nlohmann::ordered_json& modules) +void AmsTab_Regular::ShowCustomDeepseaBuilder(nlohmann::ordered_json& modules) { modules = SortDeepseaModules(modules); std::map name_map; @@ -228,6 +221,69 @@ void AmsTab::ShowCustomDeepseaBuilder(nlohmann::ordered_json& modules) brls::PopupFrame::open("menus/ams_update/deepsea_builder"_i18n, appView, modules.empty() ? "menus/ams_update/cant_fetch_deepsea"_i18n : "menus/ams_update/build_your_deepsea"_i18n, ""); } +AmsTab_Custom::AmsTab_Custom(const nlohmann::ordered_json& nxlinks, const bool erista) : AmsTab(nxlinks, erista) +{ + this->custom_packs = fs::parseJsonFile(CUSTOM_PACKS_PATH); + this->CreateLists(); +} + +void AmsTab_Custom::CreateLists() +{ + this->addView(new brls::Label( + brls::LabelStyle::DESCRIPTION, + fmt::format("menus/ams_update/custom_packs_label"_i18n, CUSTOM_PACKS_PATH), + true)); + + this->type = contentType::ams_cfw; + this->addView(new brls::Label( + brls::LabelStyle::DESCRIPTION, + "menus/ams_update/custom_packs_ams"_i18n, + true)); + CreateDownloadItems(util::getValueFromKey(this->custom_packs, "ams"), true); + this->AddLinkCreator(); + + this->type = contentType::custom; + this->addView(new brls::Label( + brls::LabelStyle::DESCRIPTION, + "menus/ams_update/custom_packs_misc"_i18n, + true)); + CreateDownloadItems(util::getValueFromKey(this->custom_packs, "misc"), false, false); + this->AddLinkCreator(); +} + +void AmsTab_Custom::AddLinkCreator() +{ + std::string category = this->type == contentType::ams_cfw ? "ams" : "misc"; + listItem = new brls::ListItem("menus/ams_update/add_custom_link"_i18n); + listItem->setHeight(LISTITEM_HEIGHT); + listItem->getClickEvent()->subscribe([this, category](brls::View* view) { + std::string title, link; + brls::Swkbd::openForText([&title](std::string text) { title = text; }, "Enter title", "", 64, "", 0, "Submit", "Title"); + brls::Swkbd::openForText([&link](std::string text) { link = text; }, "Enter direct link", "", 64, "", 0, "Submit", "https://site/download.zip"); + auto links = util::getValueFromKey(this->custom_packs, category); + links[title] = link; + this->custom_packs[category] = links; + fs::writeJsonToFile(this->custom_packs, CUSTOM_PACKS_PATH); + util::restartApp(); + }); + this->addView(listItem); +} + +void AmsTab_Custom::RegisterListItemAction(brls::ListItem* listItem) +{ + std::string label = listItem->getLabel(); + std::string category = this->type == contentType::ams_cfw ? "ams" : "misc"; + listItem->registerAction("menus/ams_update/delete_custom_link"_i18n, brls::Key::X, [this, label, category] { + brls::Logger::info(label); + brls::Logger::info(category); + auto& links = this->custom_packs.at(category); + links.erase(label); + fs::writeJsonToFile(this->custom_packs, CUSTOM_PACKS_PATH); + util::restartApp(); + return true; + }); +} + bool UnTogglableListItem::onClick() { return true; diff --git a/source/color_swapper.cpp b/source/color_swapper.cpp index d3f7faf..4d994fc 100644 --- a/source/color_swapper.cpp +++ b/source/color_swapper.cpp @@ -12,7 +12,7 @@ #include "progress_event.hpp" #include "utils.hpp" -using json = nlohmann::json; +using json = nlohmann::ordered_json; namespace { diff --git a/source/confirm_page.cpp b/source/confirm_page.cpp index 01f5be3..4cb37c4 100644 --- a/source/confirm_page.cpp +++ b/source/confirm_page.cpp @@ -35,7 +35,7 @@ ConfirmPage_Done::ConfirmPage_Done(brls::StagedAppletFrame* frame, const std::st ConfirmPage_AppUpdate::ConfirmPage_AppUpdate(brls::StagedAppletFrame* frame, const std::string& text) : ConfirmPage_Done(frame, text) { this->button->getClickEvent()->subscribe([](View* view) { - envSetNextLoad(FORWARDER_PATH, fmt::format("\"{}\"", FORWARDER_PATH).c_str()); + envSetNextLoad(FORWARDER_PATH, FORWARDER_PATH); romfsExit(); brls::Application::quit(); }); diff --git a/source/download.cpp b/source/download.cpp index a30fffc..a753d07 100644 --- a/source/download.cpp +++ b/source/download.cpp @@ -22,7 +22,7 @@ using namespace i18n::literals; constexpr const char API_AGENT[] = "HamletDuFromage"; constexpr int _1MiB = 0x100000; -using json = nlohmann::json; +using json = nlohmann::ordered_json; namespace download { diff --git a/source/download_cheats_page.cpp b/source/download_cheats_page.cpp index 71faacb..83e058b 100644 --- a/source/download_cheats_page.cpp +++ b/source/download_cheats_page.cpp @@ -12,7 +12,7 @@ namespace i18n = brls::i18n; using namespace i18n::literals; -using json = nlohmann::json; +using json = nlohmann::ordered_json; namespace cheats_util { u32 GetVersion(uint64_t title_id) diff --git a/source/fs.cpp b/source/fs.cpp index 0f7d61b..ebb2a60 100644 --- a/source/fs.cpp +++ b/source/fs.cpp @@ -43,7 +43,7 @@ namespace fs { return nlohmann::ordered_json::object(); } - void writeJsonToFile(nlohmann::json& data, const std::string& path) + void writeJsonToFile(nlohmann::ordered_json& data, const std::string& path) { std::ofstream out(path); out << data.dump(4); diff --git a/source/hide_tabs_page.cpp b/source/hide_tabs_page.cpp index aab8897..c4f728e 100644 --- a/source/hide_tabs_page.cpp +++ b/source/hide_tabs_page.cpp @@ -9,7 +9,7 @@ namespace i18n = brls::i18n; using namespace i18n::literals; -using json = nlohmann::json; +using json = nlohmann::ordered_json; HideTabsPage::HideTabsPage() : AppletFrame(true, true) { diff --git a/source/main.cpp b/source/main.cpp index 246220d..842c971 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -25,7 +25,7 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } - nlohmann::json languageFile = fs::parseJsonFile(LANGUAGE_JSON); + nlohmann::ordered_json languageFile = fs::parseJsonFile(LANGUAGE_JSON); if (languageFile.find("language") != languageFile.end()) i18n::loadTranslations(languageFile["language"]); else diff --git a/source/main_frame.cpp b/source/main_frame.cpp index 1c2bd7b..2bfe9e3 100644 --- a/source/main_frame.cpp +++ b/source/main_frame.cpp @@ -13,7 +13,7 @@ namespace i18n = brls::i18n; using namespace i18n::literals; -using json = nlohmann::json; +using json = nlohmann::ordered_json; namespace { constexpr const char AppTitle[] = APP_TITLE; @@ -41,7 +41,7 @@ MainFrame::MainFrame() : TabFrame() this->addTab("menus/main/about"_i18n, new AboutTab()); if (!util::getBoolValue(hideStatus, "atmosphere")) - this->addTab("menus/main/update_ams"_i18n, new AmsTab(nxlinks, erista, false)); + this->addTab("menus/main/update_ams"_i18n, new AmsTab_Regular(nxlinks, erista)); if (!util::getBoolValue(hideStatus, "cfw")) this->addTab("menus/main/update_bootloaders"_i18n, new ListDownloadTab(contentType::bootloaders, nxlinks)); @@ -53,7 +53,7 @@ MainFrame::MainFrame() : TabFrame() this->addTab("menus/main/download_cheats"_i18n, new ListDownloadTab(contentType::cheats)); if (!util::getBoolValue(hideStatus, "custom")) - this->addTab("menus/main/custom_downloads"_i18n, new AmsTab(nxlinks, erista, true)); + this->addTab("menus/main/custom_downloads"_i18n, new AmsTab_Custom(nxlinks, erista)); if (!util::getBoolValue(hideStatus, "tools")) this->addTab("menus/main/tools"_i18n, new ToolsTab(tag, util::getValueFromKey(nxlinks, "payloads"), erista, hideStatus)); diff --git a/source/tools_tab.cpp b/source/tools_tab.cpp index 9551b2b..481c058 100644 --- a/source/tools_tab.cpp +++ b/source/tools_tab.cpp @@ -19,13 +19,13 @@ namespace i18n = brls::i18n; using namespace i18n::literals; -using json = nlohmann::json; +using json = nlohmann::ordered_json; namespace { constexpr const char AppVersion[] = APP_VERSION; } -ToolsTab::ToolsTab(const std::string& tag, const nlohmann::ordered_json& payloads, bool erista, const nlohmann::json& hideStatus) : brls::List() +ToolsTab::ToolsTab(const std::string& tag, const nlohmann::ordered_json& payloads, bool erista, const nlohmann::ordered_json& hideStatus) : brls::List() { if (!tag.empty() && tag != AppVersion) { brls::ListItem* updateApp = new brls::ListItem(fmt::format("menus/tools/update_app"_i18n, tag)); diff --git a/source/utils.cpp b/source/utils.cpp index 9bacf99..3c47e57 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -294,12 +294,26 @@ namespace util { std::string getAppPath() { if (envHasArgv()) { + std::smatch match; std::string argv = (char*)envGetArgv(); - return fs::splitString(argv, '\"')[1].substr(5); + if (std::regex_match(argv, match, std::regex(NRO_PATH_REGEX))) { + if (match.size() >= 2) { + return match[1].str(); + } + } } return NRO_PATH; } + void restartApp() + { + std::string path = "sdmc:" + getAppPath(); + std::string argv = "\"" + path + "\""; + envSetNextLoad(path.c_str(), argv.c_str()); + romfsExit(); + brls::Application::quit(); + } + bool isErista() { SetSysProductModel model; @@ -387,10 +401,8 @@ namespace util { return path; } - bool getBoolValue(const nlohmann::json& jsonFile, const std::string& key) + bool getBoolValue(const nlohmann::ordered_json& jsonFile, const std::string& key) { - /* try { return jsonFile.at(key); } - catch (nlohmann::json::out_of_range& e) { return false; } */ return (jsonFile.find(key) != jsonFile.end()) ? jsonFile.at(key).get() : false; }