diff --git a/Makefile b/Makefile index 55df082..7ae6963 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ DATA := data INCLUDES := include lib/zipper/include APP_TITLE := All-in-One Switch Updater APP_AUTHOR := HamletDuFromage -APP_VERSION := 1.5.3 +APP_VERSION := 2.0.0 TARGET := $(notdir $(CURDIR)) ROMFS := resources diff --git a/README.md b/README.md index 378c6f4..372f0f9 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,13 @@ ![tag](https://img.shields.io/github/v/release/HamletDuFromage/AIO-switch-updater) ![GitHub](https://img.shields.io/github/license/HamletDuFromage/aio-switch-updater) +[![btc](https://img.shields.io/badge/BTC-1CoFc1bY5AHLP6Noe1zmqnJnp7ZWBxyo79-yellow)](https://github.com/HamletDuFromage/aio-switch-updater#like-the-app) + +[![eth](https://img.shields.io/badge/ETH-0xf68f568e21a15934e0e9a6949288c3ca009140ba-purple)](https://github.com/HamletDuFromage/aio-switch-updater#like-the-app) + +[![eth](https://img.shields.io/badge/LINK-0xf68f568e21a15934e0e9a6949288c3ca009140ba-lightblue +)](https://github.com/HamletDuFromage/aio-switch-updater#like-the-app) + [//]: ([![ko-fi](https://img.shields.io/badge/ko--fi-buy%20me%20a%20coffee-ff69b4)](https://ko-fi.com/hamletdufromage)) @@ -19,16 +26,17 @@ Copy the `aio-switch-updater/` directory to `/switch/` in your sdcard ## Description of the features ### ⬦ Update CFW -Download the most popular Switch CFWs. After downloading the CFW archive, the program will ask you whether you want to override your existing .ini files. If you would like to preserve additional files or directories, write their path (one line each) in `/config/aio-switch-updater/preserve.txt` and they won't be overwritten when updating. +- Download the most popular Switch CFWs. After downloading the CFW archive, the program will ask you whether you want to override your existing .ini files. If you would like to preserve additional files or directories, write their path (one line each) in `/config/aio-switch-updater/preserve.txt` and they won't be overwritten when updating. ### ⬦ Update Sigpatches -For Atmosphère. Downloads sigpatches, which are patches required for launching unofficial .NSPs. Both AMS and Hekate+AMS sigpatches are available. After downloading the sigpatches archive, the program will ask you whether you want to override your existing .ini files. +- For Atmosphère. Downloads sigpatches, which are patches required for launching unofficial .NSPs. Both AMS and Hekate+AMS sigpatches are available. After downloading the sigpatches archive, the program will ask you whether you want to override your existing .ini files. ### ⬦ Download firmwares -Download firmare files to `/firmware` that can then be installed using DayBreak or ChoiDuJour. +- Download firmare files to `/firmware` that can then be installed using DayBreak or ChoiDuJour. ### ⬦ Download cheats -Downloads and extracts daily-updated cheat code. The program will only extract cheat codes for the games you own. By default, this homebrew will overwrite the existing cheats. If you have your own cheat files that you'd like to keep as is, you can turn off cheat updates for specific titles in `Tools->Cheat Menu`. +- Downloads and extracts daily-updated cheat code. The program will only extract cheat codes for the games you own. By default, this homebrew will overwrite the existing cheats. If you have your own cheat files that you'd like to keep as is, you can turn off cheat updates for specific titles in `Tools->Cheat Menu`. +- Since v2.0.0, aio-switch-updater can also download cheat sheets from [`CheatSlips.com`](https://www.cheatslips.com/). ## Extras (in the `Tools` tab) - Reboot to specific payload. @@ -40,11 +48,12 @@ Downloads and extracts daily-updated cheat code. The program will only extract c - Edit internet settings (DNS, IP address, MTU, etc). Add you own configs to `config/aio-switch-updater/internet.json`. You can find a template in the root of the repo. ## Screenshots -![ss](https://user-images.githubusercontent.com/61667930/105403528-263eda80-5c29-11eb-842d-c3f8c4e19466.jpg) +![ss](https://user-images.githubusercontent.com/61667930/107124480-7a41f400-68a4-11eb-9a01-d7b3c9f3e828.jpg) ![ss](https://user-images.githubusercontent.com/61667930/93721670-42e6db00-fb81-11ea-9f94-1308898398f0.jpg) ![ss](https://user-images.githubusercontent.com/61667930/93721673-437f7180-fb81-11ea-9256-377575148a40.jpg) ![ss](https://user-images.githubusercontent.com/61667930/93691404-3193c500-fad4-11ea-9647-927c979960bc.jpg) ![ss](https://user-images.githubusercontent.com/61667930/105404737-98fc8580-5c2a-11eb-9efb-eb6e69d82b7b.jpg) +![ss](https://user-images.githubusercontent.com/61667930/107124438-364eef00-68a4-11eb-97d4-57df6d8aaa9d.jpg) ![ss](https://user-images.githubusercontent.com/61667930/105404840-b9c4db00-5c2a-11eb-8385-48454465063c.jpg) ![ss](https://user-images.githubusercontent.com/61667930/105407043-80da3580-5c2d-11eb-8f35-27f77079ea53.jpg) ![ss](https://user-images.githubusercontent.com/61667930/105403520-250dad80-5c29-11eb-95e6-d9ab3822d1d6.jpg) @@ -54,45 +63,47 @@ You need to have installed devkitPro and devkitARM in order to compile this proj Install the required dependencies: ```bash -sudo (dkp-)pacman -Sy +$ sudo (dkp-)pacman -Sy ``` ```bash -sudo (dkp-)pacman -S switch-glfw \ -switch-curl \ -switch-glm \ -switch-mbedtls \ -switch-zlib +$ sudo (dkp-)pacman -S switch-glfw \ + switch-curl \ + switch-glm \ + switch-mbedtls \ + switch-zlib ``` Use [`switch-ex-curl`](https://github.com/eXhumer/switch-ex-curl) instead of `switch-curl` to use this app with an invalid SSL certificate. Clone the repository ```bash -git clone --recursive https://github.com/HamletDuFromage/aio-switch-updater -cd aio-switch-updater +$ git clone --recursive https://github.com/HamletDuFromage/aio-switch-updater +$ cd aio-switch-updater ``` Compile ```bash -make -``` -OR -```bash -make -j$(nproc) +$ cd aiosu-forwarder +$ make +$ cd .. +$ make ``` ## Disclaimer I do not own, host nor distribute any of the files that can be downloaded with this homebrew tool. At the owner's request, I will immediately remove the ability to download any problematic file. ## Special thanks +- [natinusala](https://github.com/natinusala) for the Borealis library. - [tiansongyu](https://github.com/tiansongyu) for bringing support for multi-language and for his Chinese translation. - [yyoossk](https://github.com/yyoossk) for the Japanese locale. - [sergiou87](https://github.com/sergiou87) for the Spanish locale. - [pedruhb](https://github.com/pedruhb) for the Brazilian locale. - [AD2076](https://github.com/AD2076) for the Italian locale. - [qazrfv1234](https://github.com/qazrfv1234) for the Traditional Chinese locale. -- [Team Neptune](https://github.com/Team-Neptune) whose rcm code I used -- [fennectech](https://github.com/fennectech) for helping test the app and providing suggestions -- +- [Team Neptune](https://github.com/Team-Neptune) whose rcm code I used. +- [fennectech](https://github.com/fennectech) for helping test the app and providing suggestions. +- Iliak for cheatslips.com. ### Like the app? -[//]: [![5cbed8a433a3f45a772abaf5_SupportMe_blue-p-500](https://user-images.githubusercontent.com/61667930/93899702-1a2b2680-fce4-11ea-9eaa-4e2b44eebe86.png)](https://ko-fi.com/hamletdufromage) +- BTC: 1CoFc1bY5AHLP6Noe1zmqnJnp7ZWBxyo79 +- ETH: 0xf68f568e21a15934e0e9a6949288c3ca009140ba +- LINKCHAIN: 0xf68f568e21a15934e0e9a6949288c3ca009140ba \ No newline at end of file diff --git a/include/ams_tab.hpp b/include/ams_tab.hpp index 554da84..12f61ec 100644 --- a/include/ams_tab.hpp +++ b/include/ams_tab.hpp @@ -11,7 +11,7 @@ class AmsTab : public brls::List { private: - std::vector linkItems; + brls::ListItem* listItem; brls::Label *notFound; brls::Label *description; public: diff --git a/include/app_page.hpp b/include/app_page.hpp index 41e1ad7..6fbc9c5 100644 --- a/include/app_page.hpp +++ b/include/app_page.hpp @@ -9,6 +9,7 @@ #include "worker_page.hpp" #include "confirm_page.hpp" +#include "download_cheats_page.hpp" typedef struct app App; @@ -19,10 +20,10 @@ class AppPage : public brls::AppletFrame brls::List* list; brls::Label* label; brls::ListItem* download; + brls::ListItem* listItem; std::vector apps; std::set titles; - std::vector items; public: - AppPage(); + AppPage(bool cheatSlips = false); }; \ No newline at end of file diff --git a/include/constants.hpp b/include/constants.hpp index 2950683..50d41ec 100644 --- a/include/constants.hpp +++ b/include/constants.hpp @@ -34,6 +34,9 @@ #define CHEATS_RELEASE_URL "https://github.com/HamletDuFromage/switch-cheats-db/releases/tag/v1.0" #define CHEATS_URL_TITLES "https://github.com/HamletDuFromage/switch-cheats-db/releases/download/v1.0/titles.zip" #define CHEATS_URL_CONTENTS "https://github.com/HamletDuFromage/switch-cheats-db/releases/download/v1.0/contents.zip" +#define LOOKUP_TABLE_URL "https://raw.githubusercontent.com/HamletDuFromage/switch-cheats-db/master/versions.json" +#define CHEATSLIPS_TOKEN_URL "https://www.cheatslips.com/api/v1/token" +#define TOKEN_PATH "/config/aio-switch-updater/token.json" #define CHEATS_FILENAME "/config/aio-switch-updater/cheats.zip" #define CHEATS_EXCLUDE "/config/aio-switch-updater/exclude.txt" #define FILES_IGNORE "/config/aio-switch-updater/preserve.txt" @@ -70,6 +73,8 @@ #define SEPT_DIRECTORY_PATH "/config/aio-switch-updater/sept/" #define FW_DIRECTORY_PATH "/firmware/" +#define HIDE_TABS_JSON "/config/aio-switch-updater/hide_tabs.json" + #define ROMFS_FORWARDER "romfs:/aiosu-forwarder.nro" #define FORWARDER_PATH "/config/aio-switch-updater/aiosu-forwarder.nro" diff --git a/include/download.hpp b/include/download.hpp index 3057f2b..f31370c 100644 --- a/include/download.hpp +++ b/include/download.hpp @@ -9,12 +9,13 @@ #include #include - #include #include "progress_event.hpp" +#include "json.hpp" void downloadFile(const char *url, const char *output, int api); std::tuple, std::vector> fetchLinks(const char *url); std::string fetchTitle(const char *url); -std::string downloadPage(const char* url); \ No newline at end of file +std::string downloadPage(const char* url, std::vector headers = {}, std::string body = ""); +nlohmann::json getRequest(std::string url, std::vector headers = {}, std::string body = ""); \ No newline at end of file diff --git a/include/download_cheats_page.hpp b/include/download_cheats_page.hpp new file mode 100644 index 0000000..14dd22e --- /dev/null +++ b/include/download_cheats_page.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include "download.hpp" +#include "utils.hpp" +#include "json.hpp" + +class DownloadCheatsPage : public brls::AppletFrame +{ + private: + brls::List* list; + brls::Label* label; + brls::ListItem* del; + brls::ToggleListItem* listItem; + std::vector> toggles; + + public: + DownloadCheatsPage(uint64_t tid); + std::string GetBuilID(uint64_t tid); + std::string GetCheatsTitle(nlohmann::json cheat); + void WriteCheats(uint64_t tid, std::string bid, std::string cheatContent); + void DeleteCheats(uint64_t tid, std::string bid); +}; \ No newline at end of file diff --git a/include/hide_tabs_page.hpp b/include/hide_tabs_page.hpp new file mode 100644 index 0000000..8264e9c --- /dev/null +++ b/include/hide_tabs_page.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include "json.hpp" +#include "constants.hpp" +#include + +class HideTabsPage : public brls::AppletFrame +{ + private: + brls::List* list; + brls::Label* label; + brls::ToggleListItem* about; + brls::ToggleListItem* ams; + brls::ToggleListItem* cfws; + brls::ToggleListItem* sigpatches; + brls::ToggleListItem* fws; + brls::ToggleListItem* cheats; + + public: + HideTabsPage(); +}; \ No newline at end of file diff --git a/include/list_download_tab.hpp b/include/list_download_tab.hpp index a570d61..9514612 100644 --- a/include/list_download_tab.hpp +++ b/include/list_download_tab.hpp @@ -10,7 +10,8 @@ class ListDownloadTab : public brls::List { private: - std::vector linkItems; + brls::ListItem* listItem; + brls::ListItem *cheatslipsItem; brls::Label *notFound; brls::Label *description; public: diff --git a/include/main_frame.hpp b/include/main_frame.hpp index b0dac58..e4367c1 100644 --- a/include/main_frame.hpp +++ b/include/main_frame.hpp @@ -6,6 +6,7 @@ #include "list_download_tab.hpp" #include "ams_tab.hpp" #include "tools_tab.hpp" +#include "json.hpp" class MainFrame : public brls::TabFrame { diff --git a/include/ntcp.hpp b/include/ntcp.hpp.meh similarity index 100% rename from include/ntcp.hpp rename to include/ntcp.hpp.meh diff --git a/include/tools_tab.hpp b/include/tools_tab.hpp index c9e8d7c..8817549 100644 --- a/include/tools_tab.hpp +++ b/include/tools_tab.hpp @@ -13,6 +13,7 @@ #include "net_page.hpp" #include "extract.hpp" #include "utils.hpp" +#include "hide_tabs_page.hpp" //#include "ntcp.hpp" class ToolsTab : public brls::List @@ -27,6 +28,7 @@ class ToolsTab : public brls::List brls::ListItem* changelog; brls::ListItem* language; brls::ListItem* cleanUp; + brls::ListItem* hideTabs; brls::ListItem* ntcp; brls::ListItem* netSettings; brls::ListItem* browser; diff --git a/include/utils.hpp b/include/utils.hpp index bb0da95..aa97482 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include "download.hpp" @@ -19,7 +18,6 @@ struct app uint64_t tid; NsApplicationName name; NsApplicationIcon icon; - brls::ListItem* listItem; }; diff --git a/lib/borealis b/lib/borealis index b81a39f..1e59d4a 160000 --- a/lib/borealis +++ b/lib/borealis @@ -1 +1 @@ -Subproject commit b81a39f73b98aa61919b251521ba1297157a3cf7 +Subproject commit 1e59d4aa7c87792fe92885f4fd17bd00531793e3 diff --git a/lib/zipper b/lib/zipper index 29f0275..f806815 160000 --- a/lib/zipper +++ b/lib/zipper @@ -1 +1 @@ -Subproject commit 29f02751f063c2440d363f2049b0b59f5b330b20 +Subproject commit f80681569d73ffb27e85473e3bccb95b9856f1c1 diff --git a/resources/i18n/en-US/brls.json b/resources/i18n/en-US/brls.json index bd84e13..6fe8fb3 100644 --- a/resources/i18n/en-US/brls.json +++ b/resources/i18n/en-US/brls.json @@ -7,5 +7,9 @@ "crash_frame": { "button": "OK" + }, + + "thumbnail_sidebar": { + "save": "Save" } } diff --git a/resources/i18n/en-US/custom_layout.json b/resources/i18n/en-US/custom_layout.json new file mode 100644 index 0000000..86a6ba3 --- /dev/null +++ b/resources/i18n/en-US/custom_layout.json @@ -0,0 +1,5 @@ +{ + "first_button": "First button", + "second_button": "Second button", + "third_button": "Third button" +} diff --git a/resources/i18n/en-US/menus.json b/resources/i18n/en-US/menus.json index 3422e8e..ac0adbd 100644 --- a/resources/i18n/en-US/menus.json +++ b/resources/i18n/en-US/menus.json @@ -3,7 +3,8 @@ "About_Title": "All-in-One Nintendo Switch Updater", "copyright": "AIO-switch-updater is licensed under GPL-3.0\n\u00A9 2020 HamletDuFromage", "Disclaimers": "\uE016 Aside from cheat codes that are mirrored from the main Gbatemp thread, HamletDuFromage isn't hosting anything. All credits go to respective owners.\n\uE016 Links are refreshed every three hours. If a link remains broken after 3 hours have passed, please open a Github issue.\n", - + "donate": "\uE016 Like the app? Consider donating to support my efforts: 'https://git.io/donate_homlet'", + "app_page.cpp":"", "app_title": "Installed cheats", "app_label": "The following titles have received cheat code updates the last time you used the app. Please note that despite having been downloaded for a game, cheats may not match its current update.", @@ -62,6 +63,8 @@ "v1_5_1_text": "\uE016 A few graphical tweaks.", "v1_5_2": "v1.5.2", "v1_5_2_text": "\uE016 Added support for Traditional Chinese (thanks to 'https://github.com/qazrfv1234')", + "v2_0_0": "v2.0.0", + "v2_0_0_text": "\uE016 Added ability to download cheatslips cheats\n\uE016 Added way to toggle out tabs\n\uE016 Various code improvements", "Ok_button": "Ok", "cheats_page.cpp":"", @@ -73,6 +76,16 @@ "cheat_Deleting": "Deleting...", "cheat_All_done": "All done!", + "get_cheatslips": "Download CheatSlips.com cheat sheets", + "download_cheatslips": "Download a selection of cheat sheets from CheatSlips.com.\nThose cheat codes will be added to the end of your existing cheat file.", + "delete_cheat": "Delete existing cheat file", + "couldnt_dl_cheats": "Could not fetch selected cheat codes/invalid token.\nYou may have reached your daily download quota. Head on to 'https://www.cheatslips.com/subscriptions' to see increase it.\n", + "cheat_cheat_content": "Cheatsheet content: ", + "app_cheatslips_label": "Select a game to download cheats for.", + "/wrong_cheatslips_id": "Couldn't retrieve token, make you enter you login properly", + "see_more": "See more", + "download_cheats": "Download cheats and go back", + "choice_page.cpp":"", "choice_yes":"Yes", "choice_no":"No", @@ -132,7 +145,7 @@ "list_cfw": "CFW", "list_ams": "\uE016 From this menu, you can download and update the Atmosphère custom firmware necessary to run homebrew software.\n\uE016 DeepSea by Team Neptune is a CFW pack that includes Atmosphère, hekate, and various homebrew apps.", "list_main": "\uE016 Alternative CFWs, bootloaders.", - "list_latest_ver": "Latest (ver ", + "list_latest_ver": "Download GBAtemp.net cheat archive (ver ", "list_cheats": "cheats", "list_down": "Downloading:\n", "list_from": "\n\nFrom:\n", @@ -163,6 +176,9 @@ "payload_shut": "Shut Down", "payload_reboot_2": "Reboot", + "hide_tabs_page": "Hide tabs", + "hide_tabs_label": "Hide tabs from the main menu", + "tools_tab.cpp":"", "tool_cheats": "Cheats menu", "tool_change": "Change the Joy-Cons color", @@ -177,6 +193,7 @@ "tool_all_done": " All done!", "tool_changelog": "Changelog", "tool_cleanUp": "Clean up downloaded files", + "hide_tabs": "Hide tabs", "tool_net_settings": "Edit internet settings", "tool_browser": "Web Browser", diff --git a/resources/i18n/es/menus.json b/resources/i18n/es/menus.json index 9bb14a6..6ea98af 100644 --- a/resources/i18n/es/menus.json +++ b/resources/i18n/es/menus.json @@ -104,7 +104,6 @@ "list_app": "app", "list_cfw": "CFW", "list_main": "\uE016 Switch CFWs principales. Si quieres usar Atmosphère con Hekate, descarga Atmosphère, y después Hekate.", - "list_latest_ver": "Último (ver ", "list_cheats": "trucos", "list_down": "Descargando:\n", "list_from": "\n\nDesde:\n", diff --git a/resources/i18n/fr/brls.json b/resources/i18n/fr/brls.json index d498a45..9ed2173 100644 --- a/resources/i18n/fr/brls.json +++ b/resources/i18n/fr/brls.json @@ -7,5 +7,9 @@ "crash_frame": { "button": "OK" + }, + + "thumbnail_sidebar": { + "save": "Sauvegarder" } } diff --git a/resources/i18n/fr/custom_layout.json b/resources/i18n/fr/custom_layout.json new file mode 100644 index 0000000..9f29306 --- /dev/null +++ b/resources/i18n/fr/custom_layout.json @@ -0,0 +1,5 @@ +{ + "first_button": "Premier bouton", + "second_button": "Deuxième bouton", + "third_button": "Troisième bouton" +} diff --git a/resources/i18n/fr/menus.json b/resources/i18n/fr/menus.json index c40ddee..7abc5d2 100644 --- a/resources/i18n/fr/menus.json +++ b/resources/i18n/fr/menus.json @@ -80,7 +80,6 @@ "list_app": "app", "list_cfw": "CFW", "list_main": "\uE016 Principaux CFWs. Si vous souhaitez utiliser Atmosphère avec Hekate, téléchargez Atmosphère, puis Hekate.", - "list_latest_ver": "Derniers (ver ", "list_cheats": "codes de triche", "list_down": "Archive à télécharger :\n", "list_from": "\n\nLien complet de l'archive :\n", diff --git a/resources/i18n/it/menus.json b/resources/i18n/it/menus.json index 5f346e7..b628523 100644 --- a/resources/i18n/it/menus.json +++ b/resources/i18n/it/menus.json @@ -106,7 +106,6 @@ "list_app": "app", "list_cfw": "CFW", "list_main": "\uE016 Main Switch CFWs. Se vuoi usare Atmosphère con Hekate, scarica Atmosphère, poi Hekate.", - "list_latest_ver": "Ultimi (ver ", "list_cheats": "cheats", "list_down": "Scarico:\n", "list_from": "\n\nDa:\n", diff --git a/resources/i18n/ja/menus.json b/resources/i18n/ja/menus.json index 00d8ca1..2686c80 100644 --- a/resources/i18n/ja/menus.json +++ b/resources/i18n/ja/menus.json @@ -79,7 +79,6 @@ "list_app": "アプリ", "list_cfw": "CFW", "list_main": "\uE016 AtmosphereをHekateで使用する場合は、Atmosphereをダウンロードしてから、Hekateをダウンロードしてください。", - "list_latest_ver": "最新 (バージョン ", "list_cheats": "チート", "list_down": "ダウンロード中:\n", "list_from": "\n\n以下から:\n", diff --git a/resources/i18n/pt-BR/menus.json b/resources/i18n/pt-BR/menus.json index d4b5047..8745dcc 100644 --- a/resources/i18n/pt-BR/menus.json +++ b/resources/i18n/pt-BR/menus.json @@ -104,7 +104,6 @@ "list_app": "app", "list_cfw": "CFW", "list_main": "\uE016 Principais CFWs do Switch. Se você quiser usar o Atmosphère com Hekate, baixe o Atmosphère e, em seguida o Hekate.", - "list_latest_ver": "Último (ver ", "list_cheats": "trapaças", "list_down": "Baixando:\n", "list_from": "\n\nDesde:\n", diff --git a/resources/i18n/zh-CN/menus.json b/resources/i18n/zh-CN/menus.json index 8ded680..a3ad117 100644 --- a/resources/i18n/zh-CN/menus.json +++ b/resources/i18n/zh-CN/menus.json @@ -97,7 +97,6 @@ "list_app": "应用", "list_cfw": "自制系统", "list_main": "\uE016 主要 Switch 破解系统. 如果你使用 Atmosphère with Hekate, 下载 Atmosphère, 然后 Hekate.", - "list_latest_ver": "最新版本 (版本 ", "list_cheats": "金手指", "list_down": "下载中:\n", "list_from": "\n\n从:\n", diff --git a/resources/i18n/zh-TW/menus.json b/resources/i18n/zh-TW/menus.json index 63b6ef3..734b296 100644 --- a/resources/i18n/zh-TW/menus.json +++ b/resources/i18n/zh-TW/menus.json @@ -130,7 +130,6 @@ "list_cfw": "CFW", "list_ams": "\uE016 請從清單進行選擇更新的項目,你可以選擇包含可執行第三方自製程式韌體的Atmosphère。\n\uE016 DeepSea是由Team Neptune提供的CFW整合套件,包括Atmosphère、hekate與數種第三方自製程式。", "list_main": "\uE016 備用CFWs、引導程序", - "list_latest_ver": "最新(版本 ", "list_cheats": "金手指", "list_down": "正在下載:\n", "list_from": "\n\n來源:\n", diff --git a/source/about_tab.cpp b/source/about_tab.cpp index d12bb7e..a8e9509 100644 --- a/source/about_tab.cpp +++ b/source/about_tab.cpp @@ -28,7 +28,7 @@ AboutTab::AboutTab() this->addView(new brls::Header("Disclaimers")); brls::Label *links = new brls::Label( brls::LabelStyle::SMALL, - "menus/Disclaimers"_i18n, + "menus/Disclaimers"_i18n + "\n" + "menus/donate"_i18n, true ); this->addView(links); diff --git a/source/ams_tab.cpp b/source/ams_tab.cpp index 6972cd6..9b85e30 100644 --- a/source/ams_tab.cpp +++ b/source/ams_tab.cpp @@ -25,13 +25,12 @@ AmsTab::AmsTab() : std::string hekate_url = std::get<1>(hekate_link)[0]; std::string text_hekate = "menus/list_down"_i18n + std::get<0>(hekate_link)[0]; - linkItems.reserve(nbLinks); for (int i = 0; i(links)[i]; std::string text("menus/list_down"_i18n + std::get<0>(links)[i] + "menus/list_from"_i18n + url); - linkItems[i] = new brls::ListItem(std::get<0>(links)[i]); - linkItems[i]->setHeight(LISTITEM_HEIGHT); - linkItems[i]->getClickEvent()->subscribe([&, text, text_hekate, url, hekate_url, operation](brls::View* view) { + listItem = new brls::ListItem(std::get<0>(links)[i]); + listItem->setHeight(LISTITEM_HEIGHT); + listItem->getClickEvent()->subscribe([&, text, text_hekate, url, hekate_url, operation](brls::View* view) { brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame(); stagedFrame->setTitle(operation); stagedFrame->addStage( @@ -57,7 +56,7 @@ AmsTab::AmsTab() : ); brls::Application::pushView(stagedFrame); }); - this->addView(linkItems[i]); + this->addView(listItem); } } else{ diff --git a/source/app_page.cpp b/source/app_page.cpp index e0f6c89..af569cb 100644 --- a/source/app_page.cpp +++ b/source/app_page.cpp @@ -1,15 +1,14 @@ #include "app_page.hpp" -//TODO: Serialize it in extract.cpp namespace i18n = brls::i18n; using namespace i18n::literals; -AppPage::AppPage() : AppletFrame(true, true) +AppPage::AppPage(bool cheatSlips) : AppletFrame(true, true) { this->setTitle("menus/app_title"_i18n ); list = new brls::List(); label = new brls::Label( brls::LabelStyle::DESCRIPTION, - "menus/app_label"_i18n , + cheatSlips ? "menus/app_cheatslips_label"_i18n : "menus/app_label"_i18n, true ); list->addView(label); @@ -26,42 +25,41 @@ AppPage::AppPage() : AppletFrame(true, true) titles = readLineByLine(UPDATED_TITLES_PATH); - if(!titles.empty()){ + if(!titles.empty() || cheatSlips){ while (true) { rc = nsListApplicationRecord(&record, sizeof(record), i, &recordCount); if (R_FAILED(rc)) break; - - if(recordCount <= 0) - break; + if(recordCount <= 0) break; tid = record.application_id; rc = nsGetApplicationControlData(NsApplicationControlSource_Storage, tid, &controlData, sizeof(controlData), &controlSize); if (R_FAILED(rc)) break; rc = nacpGetLanguageEntry(&controlData.nacp, &langEntry); if (R_FAILED(rc)) break; - if (!langEntry->name || titles.find(formatApplicationId(tid)) == titles.end()) - { + + if (!langEntry->name) { + i++; + continue; + } + if(!cheatSlips && titles.find(formatApplicationId(tid)) == titles.end()) { i++; continue; } - App* app = (App*) malloc(sizeof(App)); - app->tid = tid; - memset(app->name, 0, sizeof(app->name)); - strncpy(app->name, langEntry->name, sizeof(app->name)-1); + listItem = new brls::ListItem(formatListItemTitle(std::string(langEntry->name)), "", formatApplicationId(tid)); + listItem->setThumbnail(controlData.icon, sizeof(controlData.icon)); + if(cheatSlips){ + listItem->getClickEvent()->subscribe([&, tid](brls::View* view) { + brls::Application::pushView(new DownloadCheatsPage(tid)); + }); + } - memcpy(app->icon, controlData.icon, sizeof(app->icon)); - - // Add the ListItem - brls::ListItem *listItem = new brls::ListItem(formatListItemTitle(std::string(app->name)), "", formatApplicationId(app->tid)); - - listItem->setThumbnail(app->icon, sizeof(app->icon)); list->addView(listItem); i++; } } - std::string text("text_download"); + std::string text("menus/text_download"_i18n); std::string url = ""; switch(getCFW()){ case ams: diff --git a/source/changelog_page.cpp b/source/changelog_page.cpp index 3c2d78f..6781e93 100644 --- a/source/changelog_page.cpp +++ b/source/changelog_page.cpp @@ -79,6 +79,9 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true) verTitles.push_back("menus/v1_5_2"_i18n ); changes.push_back("menus/v1_5_2_text"_i18n ); + verTitles.push_back("menus/v2_0_0"_i18n ); + changes.push_back("menus/v2_0_0_text"_i18n ); + int nbVersions = verTitles.size(); items.reserve(nbVersions); for(int i = nbVersions -1 ; i >= 0; i--){ diff --git a/source/confirm_page.cpp b/source/confirm_page.cpp index d286cd4..2f38aed 100644 --- a/source/confirm_page.cpp +++ b/source/confirm_page.cpp @@ -14,7 +14,6 @@ ConfirmPage::ConfirmPage(brls::StagedAppletFrame* frame, std::string text, bool brls::Application::pushView(new MainFrame()); } else if (this->reboot){ - std::cout << "rebootin" << std::endl; reboot_to_payload(RCM_PAYLOAD_PATH); } }); diff --git a/source/download.cpp b/source/download.cpp index 860289d..1a1b67f 100644 --- a/source/download.cpp +++ b/source/download.cpp @@ -7,6 +7,8 @@ #define API_AGENT "HamletDuFromage" #define _1MiB 0x100000 +using json = nlohmann::json; + typedef struct { char *memory; @@ -189,10 +191,11 @@ std::string fetchTitle(const char *url){ return ver; } -std::string downloadPage(const char* url){ +std::string downloadPage(const char* url, std::vector headers, std::string body){ std::string res; CURL *curl_handle; struct MemoryStruct chunk; + struct curl_slist *list = NULL; chunk.memory = static_cast(malloc(1)); /* will be grown as needed by the realloc above */ chunk.size = 0; /* no data at this point */ @@ -200,6 +203,16 @@ std::string downloadPage(const char* url){ curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, url); + if(!headers.empty()){ + for (auto& h : headers){ + list = curl_slist_append(list, h.c_str()); + } + curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, list); + } + if(body != "") { + curl_easy_setopt(curl_handle, CURLOPT_POSTFIELDS, body.c_str()); + } + curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback2); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, API_AGENT); @@ -213,3 +226,13 @@ std::string downloadPage(const char* url){ curl_global_cleanup(); return res; } + +json getRequest(std::string url, std::vector headers, std::string body) { + std::string request; + request = downloadPage(url.c_str(), headers, body); + + json res = {}; + bool valid = json::accept(request); + if(valid) return json::parse(request); + else return json::object(); +} \ No newline at end of file diff --git a/source/download_cheats_page.cpp b/source/download_cheats_page.cpp new file mode 100644 index 0000000..70e6986 --- /dev/null +++ b/source/download_cheats_page.cpp @@ -0,0 +1,183 @@ +#include "download_cheats_page.hpp" +#include "constants.hpp" + +namespace i18n = brls::i18n; +using namespace i18n::literals; +using json = nlohmann::json; + +DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true) +{ + this->setTitle("menus/cheat_menu"_i18n ); + + std::string bid = GetBuilID(tid); + list = new brls::List(); + label = new brls::Label( + brls::LabelStyle::DESCRIPTION, + "menus/download_cheatslips"_i18n + "\n\uE016 Build ID: " + bid, + true + ); + list->addView(label); + + if(bid != "") { + std::vector headers = {"accept: application/json"}; + json cheatsInfo = getRequest(("https://www.cheatslips.com/api/v1/cheats/" + formatApplicationId(tid) + "/" + bid).c_str(), headers); + if(cheatsInfo.find("cheats") != cheatsInfo.end()) { + for (const auto& p : cheatsInfo["cheats"].items()) { + json cheat = p.value(); + listItem = new::brls::ToggleListItem(GetCheatsTitle(cheat), 0); + listItem->registerAction("menus/see_more"_i18n , brls::Key::Y, [this, cheat] { + std::string str = "menus/cheat_cheat_content"_i18n + "\n"; + if(cheat.find("titles") != cheat.end()) { + for(auto& p : cheat["titles"]){ + str += "[" + p.get() + "]" + "\n"; + } + str.pop_back(); + } + brls::Dialog* dialog = new brls::Dialog(str); + brls::GenericEvent::Callback callback = [dialog](brls::View* view) { + dialog->close(); + }; + dialog->addButton("menus/Ok_button"_i18n , callback); + dialog->setCancelable(true); + dialog->open(); + return true; + }); + toggles.push_back(std::make_pair(listItem, cheat["id"])); + list->addView(listItem); + } + } + list->addView(new brls::ListItemGroupSpacing(true)); + } + + list->registerAction("menus/download_cheats"_i18n , brls::Key::B, [this, bid, tid] { + std::vector ids; + for(auto& e : toggles){ + if(e.first->getToggleState()){ + ids.push_back(e.second); + } + } + if(!ids.empty()) { + json token; + std::ifstream tokenFile(TOKEN_PATH); + tokenFile >> token; + tokenFile.close(); + std::vector headers = {"accept: application/json"}; + if(token.find("token") != token.end()) { + headers.push_back("X-API-TOKEN: " + token["token"].get()); + } + json cheatsInfo = getRequest(("https://www.cheatslips.com/api/v1/cheats/" + formatApplicationId(tid) + "/" + bid).c_str(), headers); + if(cheatsInfo.find("cheats") != cheatsInfo.end()) { + for (const auto& p : cheatsInfo["cheats"].items()) { + if(std::find(ids.begin(), ids.end(), p.value()["id"]) != ids.end()) { + WriteCheats(tid, bid, p.value()["content"]); + } + } + } + else { + brls::Dialog* dialog = new brls::Dialog("menus/couldnt_dl_cheats"_i18n); + brls::GenericEvent::Callback callback = [dialog](brls::View* view) { + dialog->close(); + }; + dialog->addButton("menus/Ok_button"_i18n , callback); + dialog->setCancelable(true); + dialog->open(); + } + } + brls::Application::popView(); + return true; + }); + + del = new brls::ListItem("menus/delete_cheat"_i18n); + del->getClickEvent()->subscribe([this, tid, bid](brls::View* view) { + DeleteCheats(tid, bid); + brls::Dialog* dialog = new brls::Dialog("menus/All_done"_i18n); + brls::GenericEvent::Callback callback = [dialog](brls::View* view) { + dialog->close(); + }; + dialog->addButton("menus/Ok_button"_i18n , callback); + dialog->setCancelable(true); + dialog->open(); + }); + list->addView(del); + + this->setContentView(list); +} + +std::string DownloadCheatsPage::GetBuilID(uint64_t tid) { + NsApplicationContentMetaStatus *MetaSatus = new NsApplicationContentMetaStatus[100U]; + s32 out; + nsListApplicationContentMetaStatus(tid, 0, MetaSatus, 100, &out); + u32 version = 0; + for(int i = 0; i < out ; i++){ + if(version < MetaSatus[i].version) version = MetaSatus[i].version; + } + + this->setFooterText("Game version: v" + std::to_string(version / 0x10000)); + + json lookupTable = getRequest(LOOKUP_TABLE_URL); + + std::string tidstr = formatApplicationId(tid); + std::string versionstr = std::to_string(version); + if(lookupTable.find(tidstr) != lookupTable.end()) { + json buildIDs = lookupTable[tidstr]; + if(buildIDs.find(versionstr) != buildIDs.end()) { + return buildIDs[versionstr]; + } + } + return ""; +} + +std::string DownloadCheatsPage::GetCheatsTitle(json cheat) { + std::string res = ""; + if(cheat.find("titles") != cheat.end()) { + for(auto& p : cheat["titles"]){ + res += "[" + p.get() + "]" + " - "; + } + } + res.erase(res.length() - 3); + if(res.size() > 80){ + res = res.substr(0, 79) + "..."; + } + return res; +} + +void DownloadCheatsPage::WriteCheats(uint64_t tid, std::string bid, std::string cheatContent) { + std::string path; + std::string tidstr = formatApplicationId(tid); + switch(getCFW()){ + case ams: + path = std::string(AMS_PATH) + std::string(CONTENTS_PATH); + break; + case rnx: + path = std::string(REINX_PATH) + std::string(CONTENTS_PATH); + break; + case sxos: + path = std::string(SXOS_PATH) + std::string(TITLES_PATH); + break; + } + path += tidstr + "/cheats/"; + createTree(path); + path += bid + ".txt"; + std::ofstream cheatFile; + cheatFile.open(path, std::ios::app); + cheatFile << "\n" << cheatContent; + std::ofstream updated; + updated.open(UPDATED_TITLES_PATH, std::ios::app); + updated << "\n" << tidstr; +} + +void DownloadCheatsPage::DeleteCheats(uint64_t tid, std::string bid) { + std::string path; + switch(getCFW()){ + case ams: + path = std::string(AMS_PATH) + std::string(CONTENTS_PATH); + break; + case rnx: + path = std::string(REINX_PATH) + std::string(CONTENTS_PATH); + break; + case sxos: + path = std::string(SXOS_PATH) + std::string(TITLES_PATH); + break; + } + std::filesystem::remove(path + formatApplicationId(tid) + "/cheats/" + bid + ".txt"); +} \ No newline at end of file diff --git a/source/extract.cpp b/source/extract.cpp index 7fb8805..845f541 100644 --- a/source/extract.cpp +++ b/source/extract.cpp @@ -26,7 +26,6 @@ void extract(const char * filename, const char* workingPath, int overwriteInis){ } while (it != ignoreList.end() ){ k = ("/" + entries[i].name).find((*it)); - //std::cout << k << " " << (*it) << " " << entries[i].name << std::endl; if(k == 0 || k == 1){ isIgnored = true; if(!std::filesystem::exists("/" + entries[i].name)){ @@ -38,15 +37,13 @@ void extract(const char * filename, const char* workingPath, int overwriteInis){ } if(!isIgnored){ if(entries[i].name == "sept/payload.bin" || entries[i].name == "atmosphere/fusee-secondary.bin"){ - //std::cout << entries[i].name << std::endl; unzipper.extractEntry(entries[i].name, CONFIG_PATH_UNZIP); } else if(entries[i].name.substr(0, 13) == "hekate_ctcaer"){ - std::cout << "Found hekate payload : " << entries[i].name << std::endl; unzipper.extractEntry(entries[i].name); int c = 0; while(R_FAILED(CopyFile(("/" + entries[i].name).c_str(), UPDATE_BIN_PATH)) && c < 10){ - std::cout << c++ << std::endl; + c++; } } else{ diff --git a/source/hide_tabs_page.cpp b/source/hide_tabs_page.cpp new file mode 100644 index 0000000..7bb1e39 --- /dev/null +++ b/source/hide_tabs_page.cpp @@ -0,0 +1,83 @@ +#include "hide_tabs_page.hpp" + +namespace i18n = brls::i18n; +using namespace i18n::literals; +using json = nlohmann::json; + +HideTabsPage::HideTabsPage() : AppletFrame(true, true) { + this->setTitle("menus/hide_tabs_page"_i18n ); + list = new brls::List(); + label = new brls::Label( + brls::LabelStyle::DESCRIPTION, + "menus/hide_tabs_label"_i18n , + true + ); + list->addView(label); + + json hideStatus; + std::ifstream hideFile(HIDE_TABS_JSON); + + std::string fileContent((std::istreambuf_iterator(hideFile) ), + (std::istreambuf_iterator() )); + + if(json::accept(fileContent)) hideStatus = json::parse(fileContent); + else hideStatus = json::object(); + + bool status = false; + if(hideStatus.find("about") != hideStatus.end()) { + status = hideStatus["about"]; + } + about = new brls::ToggleListItem("menus/main_about"_i18n, status); + list->addView(about); + + status = false; + if(hideStatus.find("atmosphere") != hideStatus.end()) { + status = hideStatus["atmosphere"]; + } + ams = new brls::ToggleListItem("menus/main_update_ams"_i18n, status); + list->addView(ams); + + status = false; + if(hideStatus.find("cfw") != hideStatus.end()) { + status = hideStatus["cfw"]; + } + cfws = new brls::ToggleListItem("menus/main_update_cfw"_i18n, status); + list->addView(cfws); + + status = false; + if(hideStatus.find("sigpatches") != hideStatus.end()) { + status = hideStatus["sigpatches"]; + } + sigpatches = new brls::ToggleListItem("menus/main_update_si"_i18n, status); + list->addView(sigpatches); + + status = false; + if(hideStatus.find("firmwares") != hideStatus.end()) { + status = hideStatus["firmwares"]; + } + fws = new brls::ToggleListItem("menus/main_firmwares"_i18n, status); + list->addView(fws); + + status = false; + if(hideStatus.find("cheats") != hideStatus.end()) { + status = hideStatus["cheats"]; + } + cheats = new brls::ToggleListItem("menus/Download cheats"_i18n, status); + list->addView(cheats); + + list->registerAction("menus/save"_i18n , brls::Key::B, [this] { + json updatedStatus = json::object(); + updatedStatus["about"] = about->getToggleState(); + updatedStatus["atmosphere"] = ams->getToggleState(); + updatedStatus["cfw"] = cfws->getToggleState(); + updatedStatus["sigpatches"] = sigpatches->getToggleState(); + updatedStatus["firmwares"] = fws->getToggleState(); + updatedStatus["cheats"] = cheats->getToggleState(); + std::ofstream out(HIDE_TABS_JSON); + out << updatedStatus.dump(4); + out.close(); + brls::Application::popView(); + return true; + }); + this->setContentView(list); +} \ No newline at end of file diff --git a/source/list_download_tab.cpp b/source/list_download_tab.cpp index 96af5dd..81f9306 100644 --- a/source/list_download_tab.cpp +++ b/source/list_download_tab.cpp @@ -8,12 +8,11 @@ ListDownloadTab::ListDownloadTab(archiveType type) : { std::tuple, std::vector> links; std::string operation = "menus/Getting"_i18n ; - std::string firmwareText("menus/firmware_text"_i18n - ); + std::string firmwareText("menus/firmware_text"_i18n); std::string currentCheatsVer = "menus/currentCeatsver"_i18n ; - + this->description = new brls::Label(brls::LabelStyle::DESCRIPTION, "", true); switch(type){ case sigpatches: @@ -64,19 +63,73 @@ ListDownloadTab::ListDownloadTab(archiveType type) : this->description->setText(currentCheatsVer); break; } -/* std::get<0>(links).push_back("Test"); - std::get<1>(links).push_back("https://github.com"); */ + this->addView(description); + if(type == cheats){ + cheatslipsItem = new brls::ListItem("menus/get_cheatslips"_i18n); + cheatslipsItem->setHeight(LISTITEM_HEIGHT); + cheatslipsItem->getClickEvent()->subscribe([&](brls::View* view) { + if(std::filesystem::exists(TOKEN_PATH)) { + brls::Application::pushView(new AppPage(true)); + return true; + } + else { + SwkbdConfig kbd; + char usr[0x100] = {0}; + char pwd[0x100] = {0}; + Result rc = swkbdCreate(&kbd, 0); + if (R_SUCCEEDED(rc)) { + swkbdConfigMakePresetDefault(&kbd); + swkbdConfigSetOkButtonText(&kbd, "Submit"); + swkbdConfigSetGuideText(&kbd, "www.cheatslips.com e-mail"); + swkbdShow(&kbd, usr, sizeof(usr)); + swkbdClose(&kbd); + rc = swkbdCreate(&kbd, 0); + if(R_SUCCEEDED(rc)){ + swkbdConfigMakePresetPassword(&kbd); + swkbdConfigSetOkButtonText(&kbd, "Submit"); + swkbdConfigSetGuideText(&kbd, "www.cheatslips.com password"); + swkbdShow(&kbd, pwd, sizeof(pwd)); + swkbdClose(&kbd); + } + } + std::string body = "{\"email\":\"" + std::string(usr) + + "\",\"password\":\"" + std::string(pwd) + "\"}"; + nlohmann::json token = getRequest(CHEATSLIPS_TOKEN_URL, + {"Accept: application/json", + "Content-Type: application/json", + "charset: utf-8"}, + body); + if(token.find("token") != token.end()) { + std::ofstream tokenFile(TOKEN_PATH); + tokenFile << token.dump(); + tokenFile.close(); + brls::Application::pushView(new AppPage(true)); + return true; + } + else { + brls::Dialog* dialog = new brls::Dialog("menus/wrong_cheatslips_id"_i18n); + brls::GenericEvent::Callback callback = [dialog](brls::View* view) { + dialog->close(); + }; + dialog->addButton("menus/Ok_button"_i18n , callback); + dialog->setCancelable(true); + dialog->open(); + return true; + } + } + }); + this->addView(cheatslipsItem); + } int nbLinks = std::get<0>(links).size(); if(nbLinks){ - linkItems.reserve(nbLinks); for (int i = 0; i(links)[i]; std::string text("menus/list_down"_i18n + std::get<0>(links)[i] + "menus/list_from"_i18n + url); - linkItems[i] = new brls::ListItem(std::get<0>(links)[i]); - linkItems[i]->setHeight(LISTITEM_HEIGHT); - linkItems[i]->getClickEvent()->subscribe([&, text, url, type, operation](brls::View* view) { + listItem = new brls::ListItem(std::get<0>(links)[i]); + listItem->setHeight(LISTITEM_HEIGHT); + listItem->getClickEvent()->subscribe([&, text, url, type, operation](brls::View* view) { brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame(); stagedFrame->setTitle(operation); stagedFrame->addStage( @@ -93,8 +146,9 @@ ListDownloadTab::ListDownloadTab(archiveType type) : ); brls::Application::pushView(stagedFrame); }); - this->addView(linkItems[i]); + this->addView(listItem); } + } else{ notFound = new brls::Label( diff --git a/source/main_frame.cpp b/source/main_frame.cpp index e3d5fc6..5318ffa 100644 --- a/source/main_frame.cpp +++ b/source/main_frame.cpp @@ -2,6 +2,7 @@ namespace i18n = brls::i18n; using namespace i18n::literals; +using json = nlohmann::json; MainFrame::MainFrame() : TabFrame() { @@ -13,18 +14,33 @@ MainFrame::MainFrame() : TabFrame() this->setFooterText("v" + std::string(APP_VERSION) + "menus/main_app"_i18n ); else this->setFooterText("v" + std::string(APP_VERSION)); + + json hideStatus; + std::ifstream hideFile(HIDE_TABS_JSON); + + std::string fileContent((std::istreambuf_iterator(hideFile) ), + (std::istreambuf_iterator() )); + + if(json::accept(fileContent)) hideStatus = json::parse(fileContent); + else hideStatus = json::object(); + + if(hideStatus.find("about") == hideStatus.end() || !hideStatus["about"]) + this->addTab("menus/main_about"_i18n, new AboutTab()); - this->addTab("menus/main_about"_i18n , new AboutTab()); + if(hideStatus.find("atmosphere") == hideStatus.end() || !hideStatus["atmosphere"]) + this->addTab("menus/main_update_ams"_i18n, new AmsTab()); - //this->addSeparator(); + if(hideStatus.find("cfw") == hideStatus.end() || !hideStatus["cfw"]) + this->addTab("menus/main_update_cfw"_i18n, new ListDownloadTab(cfw)); - this->addTab("menus/main_update_ams"_i18n , new AmsTab()); - this->addTab("menus/main_update_cfw"_i18n , new ListDownloadTab(cfw)); - this->addTab("menus/main_update_si"_i18n , new ListDownloadTab(sigpatches)); - this->addTab("menus/main_firmwares"_i18n , new ListDownloadTab(fw)); - this->addTab("menus/main_cheats"_i18n , new ListDownloadTab(cheats)); + if(hideStatus.find("sigpatches") == hideStatus.end() || !hideStatus["sigpatches"]) + this->addTab("menus/main_update_si"_i18n, new ListDownloadTab(sigpatches)); - //this->addSeparator(); + if(hideStatus.find("firmwares") == hideStatus.end() || !hideStatus["firmwares"]) + this->addTab("menus/main_firmwares"_i18n, new ListDownloadTab(fw)); + + if(hideStatus.find("cheats") == hideStatus.end() || !hideStatus["cheats"]) + this->addTab("menus/main_cheats"_i18n, new ListDownloadTab(cheats)); this->addTab("menus/main_tools"_i18n , new ToolsTab(tag)); diff --git a/source/net_page.cpp b/source/net_page.cpp index 70f5d59..731928b 100644 --- a/source/net_page.cpp +++ b/source/net_page.cpp @@ -1,9 +1,6 @@ #include "net_page.hpp" -#include #include - - namespace i18n = brls::i18n; using namespace i18n::literals; using json = nlohmann::json; diff --git a/source/ntcp.cpp b/source/ntcp.cpp.meh similarity index 100% rename from source/ntcp.cpp rename to source/ntcp.cpp.meh diff --git a/source/tools_tab.cpp b/source/tools_tab.cpp index d55ab2f..bb82d64 100644 --- a/source/tools_tab.cpp +++ b/source/tools_tab.cpp @@ -63,9 +63,19 @@ ToolsTab::ToolsTab(std::string tag) : brls::List() browser = new brls::ListItem("menus/tool_browser"_i18n ); browser->getClickEvent()->subscribe([&](brls::View* view){ - Result rc=0; char url[0xc00] = {0}; - strcpy(url, "https://duckduckgo.com"); + SwkbdConfig kbd; + Result rc = swkbdCreate(&kbd, 0); + if (R_SUCCEEDED(rc)) { + swkbdConfigMakePresetDefault(&kbd); + swkbdConfigSetGuideText(&kbd, "www.cheatslips.com e-mail"); + swkbdConfigSetInitialText(&kbd, "https://duckduckgo.com"); + swkbdShow(&kbd, url, sizeof(url)); + swkbdClose(&kbd); + } + else { + strcpy(url, "https://duckduckgo.com"); + } int at = appletGetAppletType(); std::string error = ""; if(at == AppletType_Application) { // Running as a title @@ -73,16 +83,16 @@ ToolsTab::ToolsTab(std::string tag) : brls::List() WebCommonReply out; rc = webPageCreate(&conf, url); if (R_FAILED(rc)) - error += "\uE016 Error starting Browser\nLookup error code for more info " + rc; + error += "\uE016 Error starting Browser\n\uE016 Lookup error code for more info " + rc; webConfigSetJsExtension(&conf, true); webConfigSetPageCache(&conf, true); webConfigSetBootLoadingIcon(&conf, true); webConfigSetWhitelist(&conf, ".*"); rc = webConfigShow(&conf, &out); if (R_FAILED(rc)) - error += "Error starting Browser\nLookup error code for more info " + rc; + error += "\uE016 Error starting Browser\n\uE016 Lookup error code for more info " + rc; } else { // Running under applet - error += "\uE016 Running in applet mode.\nPlease launch hbmenu by holding R on an APP (e.g. a game) NOT an applet (e.g. Gallery)"; + error += "\uE016 Running in applet mode.\n\uE016 Please launch hbmenu by holding [R] on a game"; } if(!error.empty()){ brls::Dialog* dialog = new brls::Dialog(error); @@ -122,9 +132,15 @@ ToolsTab::ToolsTab(std::string tag) : brls::List() }); cleanUp->setHeight(LISTITEM_HEIGHT); this->addView(cleanUp); + + hideTabs = new brls::ListItem("menus/hide_tabs"_i18n ); + hideTabs->getClickEvent()->subscribe([&](brls::View* view) { + brls::Application::pushView(new HideTabsPage()); + }); + hideTabs->setHeight(LISTITEM_HEIGHT); + this->addView(hideTabs); //tag = "1.TEST" - //std::cout << "tag: " << tag << std::endl; if(!tag.empty() && tag != APP_VERSION){ updateApp = new brls::ListItem("menus/tool_update"_i18n + tag +")"); std::string text("menus/tool_DownLoad"_i18n + std::string(APP_URL)); diff --git a/source/utils.cpp b/source/utils.cpp index 8e4569f..4ec7457 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -252,7 +252,6 @@ std::vector fetchPayloads(){ for (auto& path : payloadPaths){ for (const auto & entry : std::filesystem::directory_iterator(path)){ if(entry.path().extension().string() == ".bin"){ - std::cout << entry.path().string() << std::endl; if(entry.path().string() != FUSEE_SECONDARY && entry.path().string() != FUSEE_MTC) res.push_back(entry.path().string().c_str()); } @@ -287,7 +286,7 @@ void cp(const char *from, const char *to){ if (src.good() && dst.good()) { dst << src.rdbuf(); -} + } } Result CopyFile(const char src_path[FS_MAX_PATH], const char dest_path[FS_MAX_PATH]) { diff --git a/source/worker_page.cpp b/source/worker_page.cpp index 86b80bd..6f9f1ee 100644 --- a/source/worker_page.cpp +++ b/source/worker_page.cpp @@ -11,6 +11,8 @@ WorkerPage::WorkerPage(brls::StagedAppletFrame* frame, const std::string& text, this->button = new brls::Button(brls::ButtonStyle::BORDERLESS); // avoid back button bug this->button->setParent(this); + + this->registerAction("", brls::Key::B, [this] { return true; }); } void WorkerPage::draw(NVGcontext* vg, int x, int y, unsigned width, unsigned height, brls::Style* style, brls::FrameContext* ctx)