diff --git a/include/color_swapper.hpp b/include/color_swapper.hpp index 49f74b1..72601ce 100644 --- a/include/color_swapper.hpp +++ b/include/color_swapper.hpp @@ -1,12 +1,13 @@ #pragma once #include +#include namespace JC { int setColor(const std::vector& colors); int backupToJSON(nlohmann::json& profiles, const std::string& path); - std::vector>> getProfiles(const std::string& path); + std::deque>> getProfiles(const std::string& path); void changeJCColor(const std::vector& values); nlohmann::json backupProfile(); void backupJCColor(const std::string& path); @@ -17,7 +18,7 @@ namespace PC { int setColor(const std::vector& colors); int backupToJSON(nlohmann::json& profiles, const std::string& path); - std::vector>> getProfiles(const std::string& path); + std::deque>> getProfiles(const std::string& path); void changePCColor(const std::vector& values); nlohmann::json backupProfile(); void backupPCColor(const std::string& path); diff --git a/include/constants.hpp b/include/constants.hpp index 116b43a..c135308 100644 --- a/include/constants.hpp +++ b/include/constants.hpp @@ -68,7 +68,9 @@ constexpr const char CONTENTS_PATH[] = "contents/"; constexpr const char TITLES_PATH[] = "titles/"; constexpr const char COLOR_PICKER_URL[] = "https://git.io/jcpicker"; -constexpr const char COLOR_PROFILES_PATH[] = "/config/aio-switch-updater/jc_profiles.json"; +constexpr const char JC_COLOR_URL[] = "https://raw.githubusercontent.com/HamletDuFromage/aio-switch-updater/master/jc_profiles.json"; +constexpr const char JC_COLOR_PATH[] = "/config/aio-switch-updater/jc_profiles.json"; +constexpr const char PC_COLOR_URL[] = "https://raw.githubusercontent.com/HamletDuFromage/aio-switch-updater/master/pc_profiles.json"; constexpr const char PC_COLOR_PATH[] = "/config/aio-switch-updater/pc_profiles.json"; constexpr const char PAYLOAD_PATH[] = "/payloads/"; diff --git a/jc_profiles.json b/jc_profiles.json index 0fe7e95..44ac34c 100644 --- a/jc_profiles.json +++ b/jc_profiles.json @@ -1,143 +1,31 @@ [ { - "L_BTN": "1E0F46", - "L_JC": "2D50F0", - "R_BTN": "00051E", - "R_JC": "500FC8", - "name": "The Legend of Zelda: Skyward Sword HD" + "L_BTN": "0F0F0F", + "L_JC": "828282", + "R_BTN": "0F0F0F", + "R_JC": "828282", + "name": "Gray" + }, + { + "L_BTN": "323232", + "L_JC": "E6E6E6", + "R_BTN": "323232", + "R_JC": "E6E6E6", + "name": "White" }, { "L_BTN": "0F0F0F", - "L_JC": "818282", + "L_JC": "313131", "R_BTN": "0F0F0F", - "R_JC": "818282", - "name": "Monster Hunter Rise Edition Gray" - }, - { - "L_BTN": "140014", - "L_JC": "B400E6", - "R_BTN": "28001E", - "R_JC": "FF3278", - "name": "Disney Tsum Tsum Festival" - }, - { - "L_BTN": "00000F", - "L_JC": "1473FA", - "R_BTN": "00000F", - "R_JC": "1473FA", - "name": "Dragon Quest XI S Lotto Edition Royal-Blue" - }, - { - "L_BTN": "0A1E0A", - "L_JC": "82FF96", - "R_BTN": "0A1E28", - "R_JC": "96F5F5", - "name": "Animal Crossing: New Horizons" - }, - { - "L_BTN": "1E1914", - "L_JC": "D7AA73", - "R_BTN": "1E1914", - "R_JC": "D7AA73", - "name": "Nintendo Labo Creators Contest Edition" - }, - { - "L_BTN": "281900", - "L_JC": "C88C32", - "R_BTN": "322800", - "R_JC": "FFDC00", - "name": "Pokemon Let's Go! Eevee and Pikachu" - }, - { - "L_BTN": "1E1914", - "L_JC": "F04614", - "R_BTN": "1E1914", - "R_JC": "F04614", - "name": "Mario Red & Blue" - }, - { - "L_BTN": "000F1E", - "L_JC": "0084FF", - "R_BTN": "1A1100", - "R_JC": "FFCC00", - "name": "Fortnite Fleet Force" - }, - { - "L_BTN": "1A1100", - "L_JC": "FFCC00", - "R_BTN": "000F1E", - "R_JC": "0084FF", - "name": "Fortnite Wildcat" - }, - { - "L_BTN": "002800", - "L_JC": "1EDC00", - "R_BTN": "28001E", - "R_JC": "FF3278", - "name": "Splatoon 2 Neon Green & Neon Pink" - }, - { - "L_BTN": "00000A", - "L_JC": "4655F5", - "R_BTN": "00000A", - "R_JC": "4655F5", - "name": "Blue" - }, - { - "L_BTN": "280A0A", - "L_JC": "E10F00", - "R_BTN": "280A0A", - "R_JC": "E10F00", - "name": "Red" - }, - { - "L_BTN": "0F0A00", - "L_JC": "FAA005", - "R_BTN": "0F0A00", - "R_JC": "FAA005", - "name": "Neon Orange" - }, - { - "L_BTN": "140014", - "L_JC": "B400E6", - "R_BTN": "140014", - "R_JC": "B400E6", - "name": "Neon Purple" - }, - { - "L_BTN": "002800", - "L_JC": "1EDC00", - "R_BTN": "002800", - "R_JC": "1EDC00", - "name": "Neon Green" - }, - { - "L_BTN": "28001E", - "L_JC": "FF3278", - "R_BTN": "28001E", - "R_JC": "FF3278", - "name": "Neon Pink" - }, - { - "L_BTN": "142800", - "L_JC": "E6FF00", - "R_BTN": "142800", - "R_JC": "E6FF00", - "name": "Neon Yellow" - }, - { - "L_BTN": "1E0A0A", - "L_JC": "FF3C28", - "R_BTN": "1E0A0A", - "R_JC": "FF3C28", - "name": "Neon Red" + "R_JC": "313131", + "name": "Black (devkit)" }, { "L_BTN": "001E1E", "L_JC": "0AB9E6", - "R_BTN": "001E1E", - "R_JC": "0AB9E6", - "name": "Neon Blue" + "R_BTN": "1E0A0A", + "R_JC": "FF3C28", + "name": "Neon Blue (L) & Neon Red (R)" }, { "L_BTN": "1E0A0A", @@ -149,29 +37,141 @@ { "L_BTN": "001E1E", "L_JC": "0AB9E6", + "R_BTN": "001E1E", + "R_JC": "0AB9E6", + "name": "Neon Blue" + }, + { + "L_BTN": "1E0A0A", + "L_JC": "FF3C28", "R_BTN": "1E0A0A", "R_JC": "FF3C28", - "name": "Neon Blue (L) & Neon Red (R)" + "name": "Neon Red" + }, + { + "L_BTN": "142800", + "L_JC": "E6FF00", + "R_BTN": "142800", + "R_JC": "E6FF00", + "name": "Neon Yellow" + }, + { + "L_BTN": "28001E", + "L_JC": "FF3278", + "R_BTN": "28001E", + "R_JC": "FF3278", + "name": "Neon Pink" + }, + { + "L_BTN": "002800", + "L_JC": "1EDC00", + "R_BTN": "002800", + "R_JC": "1EDC00", + "name": "Neon Green" + }, + { + "L_BTN": "140014", + "L_JC": "B400E6", + "R_BTN": "140014", + "R_JC": "B400E6", + "name": "Neon Purple" + }, + { + "L_BTN": "0F0A00", + "L_JC": "FAA005", + "R_BTN": "0F0A00", + "R_JC": "FAA005", + "name": "Neon Orange" + }, + { + "L_BTN": "280A0A", + "L_JC": "E10F00", + "R_BTN": "280A0A", + "R_JC": "E10F00", + "name": "Red" + }, + { + "L_BTN": "00000A", + "L_JC": "4655F5", + "R_BTN": "00000A", + "R_JC": "4655F5", + "name": "Blue" + }, + { + "L_BTN": "002800", + "L_JC": "1EDC00", + "R_BTN": "28001E", + "R_JC": "FF3278", + "name": "Splatoon 2 Neon Green & Neon Pink" + }, + { + "L_BTN": "1A1100", + "L_JC": "FFCC00", + "R_BTN": "000F1E", + "R_JC": "0084FF", + "name": "Fortnite Wildcat" + }, + { + "L_BTN": "000F1E", + "L_JC": "0084FF", + "R_BTN": "1A1100", + "R_JC": "FFCC00", + "name": "Fortnite Fleet Force" + }, + { + "L_BTN": "1E1914", + "L_JC": "F04614", + "R_BTN": "1E1914", + "R_JC": "F04614", + "name": "Mario Red & Blue" + }, + { + "L_BTN": "281900", + "L_JC": "C88C32", + "R_BTN": "322800", + "R_JC": "FFDC00", + "name": "Pokemon Let's Go! Eevee and Pikachu" + }, + { + "L_BTN": "1E1914", + "L_JC": "D7AA73", + "R_BTN": "1E1914", + "R_JC": "D7AA73", + "name": "Nintendo Labo Creators Contest Edition" + }, + { + "L_BTN": "0A1E0A", + "L_JC": "82FF96", + "R_BTN": "0A1E28", + "R_JC": "96F5F5", + "name": "Animal Crossing: New Horizons" + }, + { + "L_BTN": "00000F", + "L_JC": "1473FA", + "R_BTN": "00000F", + "R_JC": "1473FA", + "name": "Dragon Quest XI S Lotto Edition Royal-Blue" + }, + { + "L_BTN": "140014", + "L_JC": "B400E6", + "R_BTN": "28001E", + "R_JC": "FF3278", + "name": "Disney Tsum Tsum Festival" }, { "L_BTN": "0F0F0F", - "L_JC": "313131", + "L_JC": "818282", "R_BTN": "0F0F0F", - "R_JC": "313131", - "name": "Black (devkit)" + "R_JC": "818282", + "name": "Monster Hunter Rise Edition Gray" }, { - "L_BTN": "323232", - "L_JC": "E6E6E6", - "R_BTN": "323232", - "R_JC": "E6E6E6", - "name": "White" - }, - { - "L_BTN": "0F0F0F", - "L_JC": "828282", - "R_BTN": "0F0F0F", - "R_JC": "828282", - "name": "Gray" + "L_BTN": "1E0F46", + "L_JC": "2D50F0", + "R_BTN": "00051E", + "R_JC": "500FC8", + "name": "The Legend of Zelda: Skyward Sword HD" } -] +] \ No newline at end of file diff --git a/source/JC_page.cpp b/source/JC_page.cpp index e1c7c43..16e144c 100644 --- a/source/JC_page.cpp +++ b/source/JC_page.cpp @@ -11,7 +11,7 @@ JCPage::JCPage() : AppletFrame(true, true) { this->setTitle("menus/joy_con/title"_i18n); list = new brls::List(); - label = new brls::Label(brls::LabelStyle::DESCRIPTION, fmt::format("menus/joy_con/description"_i18n, COLOR_PROFILES_PATH, COLOR_PICKER_URL), true); + label = new brls::Label(brls::LabelStyle::DESCRIPTION, fmt::format("menus/joy_con/description"_i18n, JC_COLOR_PATH, COLOR_PICKER_URL), true); list->addView(label); backup = new brls::ListItem("menus/joy_con/backup"_i18n); @@ -20,7 +20,7 @@ JCPage::JCPage() : AppletFrame(true, true) stagedFrame->setTitle("menus/joy_con/label"_i18n); stagedFrame->addStage( new WorkerPage(stagedFrame, "menus/joy_con/backing_up"_i18n, - []() { JC::backupJCColor(COLOR_PROFILES_PATH); })); + []() { JC::backupJCColor(JC_COLOR_PATH); })); stagedFrame->addStage( new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true)); brls::Application::pushView(stagedFrame); @@ -29,10 +29,10 @@ JCPage::JCPage() : AppletFrame(true, true) list->addView(new brls::ListItemGroupSpacing(true)); - auto profiles = JC::getProfiles(COLOR_PROFILES_PATH); - for (int i = profiles.size() - 1; i >= 0; i--) { - std::vector value = profiles[i].second; - listItem = new brls::ListItem(profiles[i].first); + auto profiles = JC::getProfiles(JC_COLOR_PATH); + for (const auto& profile : profiles) { + std::vector value = profile.second; + listItem = new brls::ListItem(profile.first); listItem->getClickEvent()->subscribe([value](brls::View* view) { brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame(); stagedFrame->setTitle("menus/joy_con/label"_i18n); diff --git a/source/PC_page.cpp b/source/PC_page.cpp index 96ae20c..17041c5 100644 --- a/source/PC_page.cpp +++ b/source/PC_page.cpp @@ -31,9 +31,9 @@ PCPage::PCPage() : AppletFrame(true, true) list->addView(new brls::ListItemGroupSpacing(true)); auto profiles = PC::getProfiles(PC_COLOR_PATH); - for (int i = profiles.size() - 1; i >= 0; i--) { - std::vector value = profiles[i].second; - listItem = new brls::ListItem(profiles[i].first); + for (const auto& profile : profiles) { + std::vector value = profile.second; + listItem = new brls::ListItem(profile.first); listItem->getClickEvent()->subscribe([value](brls::View* view) { brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame(); stagedFrame->setTitle("menus/pro_con/label"_i18n); diff --git a/source/changelog_page.cpp b/source/changelog_page.cpp index 8a232f3..e5e85e6 100644 --- a/source/changelog_page.cpp +++ b/source/changelog_page.cpp @@ -220,8 +220,8 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true) verTitles.push_back("v2.16.2"); changes.push_back("\uE016 Allow offline extraction of cheats.\n\uE016 Fixed extraction of the the complete cheat archive.\n\uE016 Fixed display bug for cheats extraction."); - verTitles.push_back("v2.16.2"); - changes.push_back("\uE016 Updated french localization (https://github.com/NotaInutilis)."); + verTitles.push_back("v2.16.3"); + changes.push_back("\uE016 Fetch default profiles online for joy-con and pro-con color swaps.\n\uE016 Updated french localization (https://github.com/NotaInutilis)."); for (int i = verTitles.size() - 1; i >= 0; i--) { listItem = new brls::ListItem(verTitles[i]); diff --git a/source/color_swapper.cpp b/source/color_swapper.cpp index 9774e36..639bc5e 100644 --- a/source/color_swapper.cpp +++ b/source/color_swapper.cpp @@ -7,13 +7,16 @@ #include #include "constants.hpp" +#include "download.hpp" #include "fs.hpp" #include "progress_event.hpp" #include "utils.hpp" using json = nlohmann::json; -namespace ColorSwapper { +namespace { + + constexpr const char BACKUP[] = "_backup"; int hexToBGR(const std::string& hex) { @@ -40,7 +43,7 @@ namespace ColorSwapper { return true; } -} // namespace ColorSwapper +} // namespace namespace JC { @@ -73,7 +76,7 @@ namespace JC { if (R_SUCCEEDED(res)) { int i = 0; for (const auto& x : profiles.items()) { - if (x.value()["name"] == "_backup") { + if (x.value()["name"] == BACKUP) { oldBackups.push_back(i); } i++; @@ -82,11 +85,11 @@ namespace JC { profiles.erase(profiles.begin() + k); } json newBackup = json::object( - {{"name", "_backup"}, - {"L_JC", ColorSwapper::BGRToHex(color_left.main)}, - {"L_BTN", ColorSwapper::BGRToHex(color_left.sub)}, - {"R_JC", ColorSwapper::BGRToHex(color_right.main)}, - {"R_BTN", ColorSwapper::BGRToHex(color_right.sub)}}); + {{"name", BACKUP}, + {"L_JC", BGRToHex(color_left.main)}, + {"L_BTN", BGRToHex(color_left.sub)}, + {"R_JC", BGRToHex(color_right.main)}, + {"R_BTN", BGRToHex(color_right.sub)}}); profiles.push_back(newBackup); fs::writeJsonToFile(profiles, path); return 0; @@ -104,21 +107,22 @@ namespace JC { Result res = hidGetNpadControllerColorSplit(HidNpadIdType_Handheld, &color_left, &color_right); if (R_SUCCEEDED(res)) { newBackup = json::object( - {{"name", "_backup"}, - {"L_JC", ColorSwapper::BGRToHex(color_left.main)}, - {"L_BTN", ColorSwapper::BGRToHex(color_left.sub)}, - {"R_JC", ColorSwapper::BGRToHex(color_right.main)}, - {"R_BTN", ColorSwapper::BGRToHex(color_right.sub)}}); + {{"name", BACKUP}, + {"L_JC", BGRToHex(color_left.main)}, + {"L_BTN", BGRToHex(color_left.sub)}, + {"R_JC", BGRToHex(color_right.main)}, + {"R_BTN", BGRToHex(color_right.sub)}}); } return newBackup; } - std::vector>> getProfiles(const std::string& path) + std::deque>> getProfiles(const std::string& path) { - std::vector>> res; + std::deque>> res; bool properData; std::fstream profilesFile; - json profilesJson = fs::parseJsonFile(path); + nlohmann::ordered_json profilesJson; + download::getRequest(JC_COLOR_URL, profilesJson); if (profilesJson.empty()) { profilesJson = {{{"L_BTN", "0A1E0A"}, {"L_JC", "82FF96"}, @@ -126,26 +130,35 @@ namespace JC { {"R_JC", "96F5F5"}, {"name", "Animal Crossing: New Horizons"}}}; } - for (const auto& x : profilesJson.items()) { - std::string name = x.value()["name"]; - std::vector values = { - std::string(x.value()["L_JC"]), - std::string(x.value()["L_BTN"]), - std::string(x.value()["R_JC"]), - std::string(x.value()["R_BTN"])}; - properData = true; - for (auto& str : values) { - if (!ColorSwapper::isHexaAnd3Bytes(str)) { - properData = false; + for (const auto& profiles : {fs::parseJsonFile(path), profilesJson}) { + for (const auto& x : profiles.items()) { + std::string name = x.value()["name"]; + brls::Logger::warning(name); + std::vector values = { + std::string(x.value()["L_JC"]), + std::string(x.value()["L_BTN"]), + std::string(x.value()["R_JC"]), + std::string(x.value()["R_BTN"])}; + properData = true; + for (auto& str : values) { + if (!isHexaAnd3Bytes(str)) { + properData = false; + } + } + if (properData) { + if (name == "") name = "Unamed"; + auto profile = std::make_pair(name, (std::vector){ + hexToBGR(values[0]), + hexToBGR(values[1]), + hexToBGR(values[2]), + hexToBGR(values[3])}); + if (name == BACKUP) { + res.push_front(profile); + } + else { + res.push_back(profile); + } } - } - if (properData) { - if (name == "") name = "Unamed"; - res.push_back(std::make_pair(name, (std::vector){ - ColorSwapper::hexToBGR(values[0]), - ColorSwapper::hexToBGR(values[1]), - ColorSwapper::hexToBGR(values[2]), - ColorSwapper::hexToBGR(values[3])})); } } return res; @@ -182,7 +195,7 @@ namespace JC { std::vector oldBackups; int i = 0; for (const auto& x : profiles.items()) { - if (x.value()["name"] == "_backup") { + if (x.value()["name"] == BACKUP) { oldBackups.push_back(i); } i++; @@ -233,7 +246,7 @@ namespace PC { if (R_SUCCEEDED(res)) { int i = 0; for (const auto& x : profiles.items()) { - if (x.value()["name"] == "_backup") { + if (x.value()["name"] == BACKUP) { oldBackups.push_back(i); } i++; @@ -242,9 +255,9 @@ namespace PC { profiles.erase(profiles.begin() + k); } json newBackup = json::object( - {{"name", "_backup"}, - {"BODY", ColorSwapper::BGRToHex(color.main)}, - {"BTN", ColorSwapper::BGRToHex(color.sub)}}); + {{"name", BACKUP}, + {"BODY", BGRToHex(color.main)}, + {"BTN", BGRToHex(color.sub)}}); profiles.push_back(newBackup); fs::writeJsonToFile(profiles, path); return 0; @@ -261,19 +274,21 @@ namespace PC { Result res = hidGetNpadControllerColorSingle(HidNpadIdType_No1, &color); if (R_SUCCEEDED(res)) { newBackup = json::object( - {{"name", "_backup"}, - {"BODY", ColorSwapper::BGRToHex(color.main)}, - {"BTN", ColorSwapper::BGRToHex(color.sub)}}); + {{"name", BACKUP}, + {"BODY", BGRToHex(color.main)}, + {"BTN", BGRToHex(color.sub)}}); } return newBackup; } - std::vector>> getProfiles(const std::string& path) + std::deque>> getProfiles(const std::string& path) { - std::vector>> res; + std::deque>> res; bool properData; std::fstream profilesFile; - json profilesJson = fs::parseJsonFile(path); + nlohmann::ordered_json profilesJson; + download::getRequest(PC_COLOR_URL, profilesJson); + profilesJson += fs::parseJsonFile(path); if (profilesJson.empty()) { profilesJson = {{{"BTN", "e6e6e6"}, {"BODY", "2d2d2d"}, @@ -286,15 +301,21 @@ namespace PC { std::string(x.value()["BTN"])}; properData = true; for (auto& str : values) { - if (!ColorSwapper::isHexaAnd3Bytes(str)) { + if (!isHexaAnd3Bytes(str)) { properData = false; } } if (properData) { if (name == "") name = "Unamed"; - res.push_back(std::make_pair(name, (std::vector){ - ColorSwapper::hexToBGR(values[0]), - ColorSwapper::hexToBGR(values[1])})); + auto profile = std::make_pair(name, (std::vector){ + hexToBGR(values[0]), + hexToBGR(values[1])}); + if (name == BACKUP) { + res.push_front(profile); + } + else { + res.push_back(profile); + } } } return res; @@ -331,7 +352,7 @@ namespace PC { std::vector oldBackups; int i = 0; for (const auto& x : profiles.items()) { - if (x.value()["name"] == "_backup") { + if (x.value()["name"] == BACKUP) { oldBackups.push_back(i); } i++;