From 0be69baad5216a12b175ff11112551bfd305f245 Mon Sep 17 00:00:00 2001 From: Slluxx Date: Wed, 19 Apr 2023 18:28:09 +0200 Subject: [PATCH] Fixed DMCA bug --- example/main.cpp | 369 +++++++++++++++++++++++------------------- library/lib/swkbd.cpp | 2 +- 2 files changed, 206 insertions(+), 165 deletions(-) diff --git a/example/main.cpp b/example/main.cpp index 32f3687..1c555a5 100644 --- a/example/main.cpp +++ b/example/main.cpp @@ -1,19 +1,18 @@ +#include +#include +#include #include #include #include #include -#include -#include +#include #include +#include #include #include -#include -#include #include -#include - -#include +#include // #define STB_IMAGE_IMPLEMENTATION // #include "stb_image/stb_image.h" @@ -46,27 +45,31 @@ std::vector allowedImageResolutions = { "1024x1024" }; -nlohmann::json loadConfig(){ - if (std::filesystem::exists(configPath.c_str())){ +nlohmann::json loadConfig() +{ + if (std::filesystem::exists(configPath.c_str())) + { brls::Logger::info("Loading config from file"); std::ifstream i(configPath.c_str()); nlohmann::json j; i >> j; return j; } - else{ + else + { brls::Logger::info("using default config"); nlohmann::json config; - config["api_token"] = ""; - config["style_id"] = 0; + config["api_token"] = ""; + config["style_id"] = 0; config["resolution_id"] = 5; return config; } } -void saveConfig(nlohmann::json config){ +void saveConfig(nlohmann::json config) +{ if (!std::filesystem::exists("sdmc:/config/icongrabber/")) - if(!std::filesystem::create_directories("sdmc:/config/icongrabber/")) + if (!std::filesystem::create_directories("sdmc:/config/icongrabber/")) brls::Logger::info("Could not create directory"); std::ofstream o(configPath.c_str()); @@ -82,48 +85,58 @@ std::string formatApplicationId(u64 ApplicationId) return strm.str(); } -void overwriteIcon(std::string tid, std::string imagePath){ +void overwriteIcon(std::string tid, std::string imagePath) +{ int width, height, channels; - unsigned char *img = stbi_load(imagePath.c_str(), &width, &height, &channels, 0); - if(img == NULL) { + unsigned char* img = stbi_load(imagePath.c_str(), &width, &height, &channels, 0); + if (img == NULL) + { brls::Logger::info("Image could not be loaded"); - } else { + } + else + { brls::Logger::info("Image is loaded"); - unsigned char *data = NULL; - data = (unsigned char * )malloc( 256 * 256 * 3 * sizeof(unsigned char)); + unsigned char* data = NULL; + data = (unsigned char*)malloc(256 * 256 * 3 * sizeof(unsigned char)); - if(stbir_resize_uint8(img, width, height, 0, data, 256, 256, 256* 3, 3)){ + if (stbir_resize_uint8(img, width, height, 0, data, 256, 256, 256 * 3, 3)) + { brls::Logger::info("resize good"); - } else { + } + else + { brls::Logger::info("resize bad"); } std::string outPath = "sdmc:/atmosphere/contents/"; - outPath = outPath.append(tid); - if(!std::filesystem::create_directories(outPath)) + outPath = outPath.append(tid); + if (!std::filesystem::create_directories(outPath)) brls::Logger::info("Could not create directory"); outPath = outPath.append("/icon.jpg"); brls::Logger::info(outPath); - if(stbi_write_jpg(outPath.c_str(), 256, 256, channels, data, 100)){ + if (stbi_write_jpg(outPath.c_str(), 256, 256, channels, data, 100)) + { brls::Application::notify("Icon saved"); - } else { + } + else + { brls::Application::notify("Icon could not be saved"); }; } } - -nlohmann::json getInstalledGames(){ - NsApplicationRecord *records = new NsApplicationRecord[64000](); +nlohmann::json getInstalledGames() +{ + NsApplicationRecord* records = new NsApplicationRecord[64000](); uint64_t tid; NsApplicationControlData controlData; NacpLanguageEntry* langEntry = NULL; Result rc; - int recordCount = 0; - size_t controlSize = 0; + int recordCount = 0; + size_t controlSize = 0; nlohmann::json games = nlohmann::json::array(); @@ -131,54 +144,59 @@ nlohmann::json getInstalledGames(){ for (s32 i = 0; i < recordCount; i++) { tid = records[i].application_id; - rc = nsGetApplicationControlData(NsApplicationControlSource_Storage, tid, &controlData, sizeof(controlData), &controlSize); - if(R_FAILED(rc)) break; + 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) + if (R_FAILED(rc)) + break; + + if (!langEntry->name) continue; std::string appName = langEntry->name; std::string titleId = formatApplicationId(tid); - games.push_back({ {"tid", titleId}, {"name", appName} }); + games.push_back({ { "tid", titleId }, { "name", appName } }); } delete[] records; return games; } -size_t write_to_string(void *ptr, size_t size, size_t nmemb, std::string stream) +size_t write_to_string(void* ptr, size_t size, size_t nmemb, std::string stream) { - size_t realsize = size * nmemb; - std::string temp(static_cast(ptr), realsize); - stream.append(temp); - return realsize; + size_t realsize = size * nmemb; + std::string temp(static_cast(ptr), realsize); + stream.append(temp); + return realsize; } -size_t write_to_file(void *ptr, size_t size, size_t nmemb, FILE *stream) +size_t write_to_file(void* ptr, size_t size, size_t nmemb, FILE* stream) { size_t written; written = fwrite(ptr, size, nmemb, stream); return written; } -std::string base_name(std::string const & path) +std::string base_name(std::string const& path) { - return path.substr(path.find_last_of("/\\") + 1); + return path.substr(path.find_last_of("/\\") + 1); } -std::string downloadFile(nlohmann::json game, bool thumbnail){ +std::string downloadFile(nlohmann::json game, bool thumbnail) +{ std::string url = game["thumb"].get(); std::string outpath = "sdmc:/gameIcons/"; - if (thumbnail){ + if (thumbnail) + { outpath = outpath.append("thumbnails/"); - } else { + } + else + { outpath = outpath.append("full/"); } if (!std::filesystem::exists(outpath)) - if(!std::filesystem::create_directories(outpath)) + if (!std::filesystem::create_directories(outpath)) brls::Logger::info("Could not create directory"); - std::string filename = ""; filename.append(game["width"].dump()); filename.append("x"); @@ -187,47 +205,55 @@ std::string downloadFile(nlohmann::json game, bool thumbnail){ filename.append(base_name(url)); outpath = outpath.append(filename); - - - if (!std::filesystem::exists(outpath)){ - CURL *curl; - FILE *fp; + if (!std::filesystem::exists(outpath)) + { + CURL* curl; + FILE* fp; CURLcode res; curl = curl_easy_init(); - if (curl) { - fp = fopen(outpath.c_str(),"wb"); + if (curl) + { + fp = fopen(outpath.c_str(), "wb"); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_file); curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp); res = curl_easy_perform(curl); curl_easy_cleanup(curl); fclose(fp); - } else { + } + else + { outpath = ""; } } - if (!thumbnail){ - if (thumbnail == false && outpath != ""){ + if (!thumbnail) + { + if (thumbnail == false && outpath != "") + { brls::Application::notify("Image Downloaded.\nApply to a title in main menu."); - } else { + } + else + { brls::Application::notify("Image Download Failed."); } } return outpath; } -nlohmann::json requestGames(std::string gameName){ +nlohmann::json requestGames(std::string gameName) +{ nlohmann::json config = loadConfig(); std::string api_token = config["api_token"]; std::string authString = "Authorization: Bearer "; authString.append(api_token); - CURL *curl; + CURL* curl; CURLcode res; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); - if (curl) { + if (curl) + { struct curl_slist* headers = NULL; @@ -235,8 +261,8 @@ nlohmann::json requestGames(std::string gameName){ headers = curl_slist_append(headers, authString.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - char *output = curl_easy_escape(curl, gameName.c_str(), gameName.length()); - std::string url = "https://www.steamgriddb.com/api/v2/search/autocomplete/"; + char* output = curl_easy_escape(curl, gameName.c_str(), gameName.length()); + std::string url = "https://www.steamgriddb.com/api/v2/search/autocomplete/"; std::string fullurl = url.append(output); curl_easy_setopt(curl, CURLOPT_URL, fullurl.c_str()); curl_easy_setopt(curl, CURLOPT_USERAGENT, "libnx curl example/1.0"); @@ -246,13 +272,16 @@ nlohmann::json requestGames(std::string gameName){ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); res = curl_easy_perform(curl); - if (res != CURLE_OK) { + if (res != CURLE_OK) + { nlohmann::json j; j["success"] = false; curl_easy_cleanup(curl); curl_global_cleanup(); return j; - } else { + } + else + { nlohmann::json j = nlohmann::json::parse(response); curl_easy_cleanup(curl); curl_global_cleanup(); @@ -266,7 +295,8 @@ nlohmann::json requestGames(std::string gameName){ return j; } -nlohmann::json requestIcons(std::string gameId){ +nlohmann::json requestIcons(std::string gameId) +{ nlohmann::json config = loadConfig(); std::string api_token = config["api_token"]; @@ -275,23 +305,27 @@ nlohmann::json requestIcons(std::string gameId){ std::string postFields = ""; postFields.append("?styles="); - if (config["style_id"] == 0){ + if (config["style_id"] == 0) + { postFields.append("alternate,blurred,white_logo,material,no_logo"); - } else { + } + else + { postFields.append(allowedStyles[config["style_id"]]); } - + postFields.append("&dimensions="); postFields.append(allowedImageResolutions[config["resolution_id"]]); postFields.append("&mimes=image/png,image/jpeg"); brls::Logger::info(postFields); - CURL *curl; + CURL* curl; CURLcode res; curl_global_init(CURL_GLOBAL_ALL); curl = curl_easy_init(); - if (curl) { + if (curl) + { struct curl_slist* headers = NULL; @@ -299,7 +333,7 @@ nlohmann::json requestIcons(std::string gameId){ headers = curl_slist_append(headers, authString.c_str()); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - std::string url = "https://www.steamgriddb.com/api/v2/grids/game/"; + std::string url = "https://www.steamgriddb.com/api/v2/grids/game/"; std::string fullurl = url.append(gameId); fullurl.append(postFields); @@ -312,13 +346,16 @@ nlohmann::json requestIcons(std::string gameId){ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); res = curl_easy_perform(curl); - if (res != CURLE_OK) { + if (res != CURLE_OK) + { nlohmann::json j; j["success"] = false; curl_easy_cleanup(curl); curl_global_cleanup(); return j; - } else { + } + else + { nlohmann::json j = nlohmann::json::parse(response); curl_easy_cleanup(curl); curl_global_cleanup(); @@ -332,7 +369,8 @@ nlohmann::json requestIcons(std::string gameId){ return j; } -void frame_showOnlineTitleIcons(std::string gameId){ +void frame_showOnlineTitleIcons(std::string gameId) +{ brls::Logger::info("frame_showOnlineTitleIcons"); brls::ThumbnailFrame* rootFrame = new brls::ThumbnailFrame(); rootFrame->setTitle("List of fetched icons from SteamGridDB"); @@ -340,19 +378,26 @@ void frame_showOnlineTitleIcons(std::string gameId){ rootFrame->getSidebar()->setThumbnail(BOREALIS_ASSET("icon/borealis.jpg")); rootFrame->getSidebar()->getButton()->setLabel("Download"); nlohmann::json iconList = requestIcons(gameId); - brls::List* list = new brls::List(); + brls::List* list = new brls::List(); brls::Logger::info(iconList.dump()); brls::Logger::info(iconList["success"].dump()); brls::Logger::info(std::to_string(iconList["data"].size())); - if (iconList["success"].get() && iconList["data"].size() != 0){ + if (iconList["success"].get() && iconList["data"].size() != 0) + { brls::Logger::info("iconlist success"); for (auto it : iconList["data"]) { + if (it["lock"].get()) + { + brls::Logger::info("skipped DMCA hidden image"); + continue; + } brls::Logger::info(it["id"].dump()); brls::ListItem* litem = new brls::ListItem(it["id"].dump()); - litem->getFocusEvent()->subscribe([=](brls::View* view) { + litem->getFocusEvent()->subscribe([=](brls::View* view) + { rootFrame->getSidebar()->getButton()->getClickEvent()->unsubscribeAll(); std::string path = downloadFile(it, true); if (path != ""){ @@ -365,11 +410,12 @@ void frame_showOnlineTitleIcons(std::string gameId){ rootFrame->getSidebar()->setThumbnail(BOREALIS_ASSET("icon/borealis.jpg")); rootFrame->getSidebar()->setTitle("Could not fetch thumbnail"); rootFrame->getSidebar()->setSubtitle(""); - } - }); + } }); list->addView(litem); } - } else { + } + else + { brls::Logger::info("error"); brls::ListItem* litem = new brls::ListItem("No icon found", "Maybe select a different icon style or resolution."); list->addView(litem); @@ -378,25 +424,28 @@ void frame_showOnlineTitleIcons(std::string gameId){ brls::Application::pushView(rootFrame); } -void frame_showOnlineTitles(std::string searchTerm){ +void frame_showOnlineTitles(std::string searchTerm) +{ brls::AppletFrame* onlinegamelistFrame = new brls::AppletFrame(true, true); onlinegamelistFrame->setTitle("Found games on steamgriddb.com"); onlinegamelistFrame->setIcon(BOREALIS_ASSET("icon/borealis.jpg")); brls::List* onlinetitleList = new brls::List(); - nlohmann::json foundGames = requestGames(searchTerm); + nlohmann::json foundGames = requestGames(searchTerm); brls::Logger::info(foundGames.dump()); brls::Logger::info(foundGames["success"].dump()); brls::Logger::info(foundGames["data"].dump()); - if (foundGames["success"].get() && foundGames["data"].size() != 0){ + if (foundGames["success"].get() && foundGames["data"].size() != 0) + { for (auto it : foundGames["data"]) { brls::ListItem* litem = new brls::ListItem(it["name"]); - litem->getClickEvent()->subscribe([=](brls::View* view) { - frame_showOnlineTitleIcons(it["id"].dump()); - }); + litem->getClickEvent()->subscribe([=](brls::View* view) + { frame_showOnlineTitleIcons(it["id"].dump()); }); onlinetitleList->addView(litem); } - } else { + } + else + { brls::Logger::info("error"); brls::ListItem* litem = new brls::ListItem("No game found"); onlinetitleList->addView(litem); @@ -406,41 +455,47 @@ void frame_showOnlineTitles(std::string searchTerm){ brls::Application::pushView(onlinegamelistFrame); } - -void frame_showLocalTitles(std::string imagePath){ - nlohmann::json installedGames = getInstalledGames(); +void frame_showLocalTitles(std::string imagePath) +{ + nlohmann::json installedGames = getInstalledGames(); brls::AppletFrame* gamelistFrame = new brls::AppletFrame(true, true); - if (imagePath != ""){ + if (imagePath != "") + { gamelistFrame->setTitle("Choose a title to search for icons."); - } else { + } + else + { gamelistFrame->setTitle("Choose a title to overwrite its icon."); } - - + gamelistFrame->setIcon(BOREALIS_ASSET("icon/borealis.jpg")); brls::List* titleList = new brls::List(); for (auto it : installedGames) { - std::string name = it["name"].get(); - std::string tid = it["tid"].get(); + std::string name = it["name"].get(); + std::string tid = it["tid"].get(); brls::ListItem* litem = new brls::ListItem(it["name"]); - litem->getClickEvent()->subscribe([name, tid, imagePath](brls::View* view) { - if (imagePath == ""){ - frame_showOnlineTitles(name); - } else { - overwriteIcon(tid, imagePath); - } - - }); - if(imagePath == ""){ - litem->registerAction("Delete current icon", brls::Key::X, [=] { + litem->getClickEvent()->subscribe([name, tid, imagePath](brls::View* view) + { + if (imagePath == "") + { + frame_showOnlineTitles(name); + } + else + { + overwriteIcon(tid, imagePath); + } + }); + if (imagePath == "") + { + litem->registerAction("Delete current icon", brls::Key::X, [=] + { std::string outPath = "sdmc:/atmosphere/contents/"; outPath = outPath.append(tid); outPath = outPath.append("/icon.jpg"); std::remove(outPath.c_str()); brls::Application::notify("Icon deleted"); - return true; - }); + return true; }); } titleList->addView(litem); @@ -449,7 +504,8 @@ void frame_showLocalTitles(std::string imagePath){ brls::Application::pushView(gamelistFrame); } -void frame_showLocalIcons(){ +void frame_showLocalIcons() +{ brls::ThumbnailFrame* rootFrame = new brls::ThumbnailFrame(); rootFrame->setTitle("A list of downloaded icons"); rootFrame->setIcon(BOREALIS_ASSET("icon/borealis.jpg")); @@ -459,23 +515,25 @@ void frame_showLocalIcons(){ brls::List* list = new brls::List(); int count = 0; - for(auto const& dir_entry: std::filesystem::directory_iterator("sdmc:/gameIcons/full/")){ + for (auto const& dir_entry : std::filesystem::directory_iterator("sdmc:/gameIcons/full/")) + { count++; - std::string filepath = dir_entry.path().string(); - std::string filename = dir_entry.path().filename().string(); + std::string filepath = dir_entry.path().string(); + std::string filename = dir_entry.path().filename().string(); brls::ListItem* litem = new brls::ListItem(filename); - litem->getFocusEvent()->subscribe([filename, filepath, rootFrame](brls::View* view) { + litem->getFocusEvent()->subscribe([filename, filepath, rootFrame](brls::View* view) + { rootFrame->getSidebar()->getButton()->getClickEvent()->unsubscribeAll(); rootFrame->getSidebar()->setThumbnail(filepath); rootFrame->getSidebar()->getButton()->getClickEvent()->subscribe([filepath](brls::View* view) { frame_showLocalTitles(filepath); - }); - }); + }); }); list->addView(litem); } - if (count == 0) { + if (count == 0) + { brls::ListItem* litem = new brls::ListItem("No files found."); list->addView(litem); } @@ -497,73 +555,58 @@ int main(int argc, char* argv[]) return EXIT_FAILURE; } - nlohmann::json config = loadConfig(); + nlohmann::json config = loadConfig(); brls::TabFrame* rootFrame = new brls::TabFrame(); rootFrame->setTitle("main/name"_i18n); rootFrame->setIcon(BOREALIS_ASSET("icon/borealis.jpg")); - - - - brls::List* settingsTab = new brls::List(); - brls::InputListItem* settingApiToken = new brls::InputListItem("Set the API token", config["api_token"], "Enter your steamgriddb.com api key", "Get it on steamgriddb.com", 32); - brls::SelectListItem* settingStyles = new brls::SelectListItem("Choose icon style", allowedStyles, config["style_id"]); + brls::List* settingsTab = new brls::List(); + brls::InputListItem* settingApiToken = new brls::InputListItem("Set the API token", config["api_token"], "Enter your steamgriddb.com api key", "Get it on steamgriddb.com", 32); + brls::SelectListItem* settingStyles = new brls::SelectListItem("Choose icon style", allowedStyles, config["style_id"]); brls::SelectListItem* settingResolution = new brls::SelectListItem("Choose icon resolution", allowedImageResolutions, config["resolution_id"], "All icons will be resized. Default Switch icons are 1:1 (512x512 or 1024x1024) while vertical icon themes should use 2:3 (600x900)."); - settingApiToken->getClickEvent()->subscribe([&settingApiToken](brls::View* view) { + settingApiToken->getClickEvent()->subscribe([&settingApiToken](brls::View* view) + { nlohmann::json c = loadConfig(); c["api_token"] = settingApiToken->getValue(); - saveConfig(c); - }); - settingStyles->getValueSelectedEvent()->subscribe([](size_t selection) { + saveConfig(c); }); + settingStyles->getValueSelectedEvent()->subscribe([](size_t selection) + { nlohmann::json c = loadConfig(); c["style_id"] = selection; - saveConfig(c); - }); - settingResolution->getValueSelectedEvent()->subscribe([](size_t selection) { + saveConfig(c); }); + settingResolution->getValueSelectedEvent()->subscribe([](size_t selection) + { nlohmann::json c = loadConfig(); c["resolution_id"] = selection; - saveConfig(c); - }); + saveConfig(c); }); - - brls::List* searchTab = new brls::List(); + brls::List* searchTab = new brls::List(); brls::InputListItem* browseByName = new brls::InputListItem("Search for a game by name", "", "Enter the name of a game to search icons", "", 32); - brls::ListItem* browseByTitle = new brls::ListItem("Search by installed titles"); - browseByName->getClickEvent()->subscribe([&browseByName](brls::View* view) { + brls::ListItem* browseByTitle = new brls::ListItem("Search by installed titles"); + browseByName->getClickEvent()->subscribe([&browseByName](brls::View* view) + { std::string text = browseByName->getValue(); if (text == "") text = " "; - frame_showOnlineTitles(text); - }); - browseByTitle->getClickEvent()->subscribe([](brls::View* view) { - frame_showLocalTitles(""); - }); - + frame_showOnlineTitles(text); }); + browseByTitle->getClickEvent()->subscribe([](brls::View* view) + { frame_showLocalTitles(""); }); - - brls::List* localIcons = new brls::List(); - brls::ListItem* browseIcons = new brls::ListItem("Browse downloaded Icons"); + brls::List* localIcons = new brls::List(); + brls::ListItem* browseIcons = new brls::ListItem("Browse downloaded Icons"); brls::ListItem* deleteIconCache = new brls::ListItem("Delete Imagecache", "This will not delete already applied icons."); - browseIcons->getClickEvent()->subscribe([=](brls::View* view) { - frame_showLocalIcons(); - }); - deleteIconCache->getClickEvent()->subscribe([=](brls::View* view) { + browseIcons->getClickEvent()->subscribe([=](brls::View* view) + { frame_showLocalIcons(); }); + deleteIconCache->getClickEvent()->subscribe([=](brls::View* view) + { if (std::filesystem::remove_all("sdmc:/gameIcons/full/")) std::filesystem::create_directory("sdmc:/gameIcons/full/"); if (std::filesystem::remove_all("sdmc:/gameIcons/thumbnails/")) std::filesystem::create_directory("sdmc:/gameIcons/thumbnails/"); - brls::Application::notify("Done"); - }); - + brls::Application::notify("Done"); }); - - - - - - settingsTab->addView(settingApiToken); settingsTab->addView(settingStyles); settingsTab->addView(settingResolution); @@ -579,8 +622,6 @@ int main(int argc, char* argv[]) rootFrame->addTab("Search Icons", searchTab); rootFrame->addTab("Downloaded Icons", localIcons); - - brls::Application::pushView(rootFrame); while (brls::Application::mainLoop()) diff --git a/library/lib/swkbd.cpp b/library/lib/swkbd.cpp index fac1c69..ba0b973 100644 --- a/library/lib/swkbd.cpp +++ b/library/lib/swkbd.cpp @@ -42,7 +42,7 @@ static SwkbdConfig createSwkbdBaseConfig(std::string headerText, std::string sub swkbdConfigSetSubText(&config, subText.c_str()); swkbdConfigSetStringLenMax(&config, maxStringLength); swkbdConfigSetInitialText(&config, initialText.c_str()); - swkbdConfigSetStringLenMaxExt(&config, 1); + // swkbdConfigSetStringLenMaxExt(&config, 1); swkbdConfigSetBlurBackground(&config, true); return config;