1
0
Fork 0
mirror of https://github.com/HamletDuFromage/aio-switch-updater.git synced 2025-01-01 12:16:02 +00:00

Added ability to download invidual cheet codes from the GBAtemp.net archive.

This commit is contained in:
flb 2021-06-05 19:10:51 +02:00
parent bab943bb0a
commit c2eef003aa
12 changed files with 333 additions and 198 deletions

View file

@ -22,7 +22,7 @@ DATA := data
INCLUDES := include lib/zipper/include /lib/borealis/library/include/borealis/extern/nlohmann INCLUDES := include lib/zipper/include /lib/borealis/library/include/borealis/extern/nlohmann
APP_TITLE := All-in-One Switch Updater APP_TITLE := All-in-One Switch Updater
APP_AUTHOR := HamletDuFromage APP_AUTHOR := HamletDuFromage
APP_VERSION := 2.5.3 APP_VERSION := 2.6.0
TARGET := $(notdir $(CURDIR)) TARGET := $(notdir $(CURDIR))
ROMFS := resources ROMFS := resources

View file

@ -6,6 +6,11 @@
typedef struct app App; typedef struct app App;
enum class appPageType{
base,
cheatSlips,
gbatempCheats
};
class AppPage : public brls::AppletFrame class AppPage : public brls::AppletFrame
{ {
@ -18,5 +23,5 @@ class AppPage : public brls::AppletFrame
std::set<std::string> titles; std::set<std::string> titles;
public: public:
AppPage(const bool cheatSlips = false); AppPage(const appPageType type = appPageType::base);
}; };

View file

@ -41,6 +41,7 @@ constexpr const char CHEATS_URL_VERSION[] = "https://github.com/HamletDuFromage/
constexpr const char LOOKUP_TABLE_URL[] = "https://raw.githubusercontent.com/HamletDuFromage/switch-cheats-db/master/versions.json"; constexpr const char LOOKUP_TABLE_URL[] = "https://raw.githubusercontent.com/HamletDuFromage/switch-cheats-db/master/versions.json";
constexpr const char LOOKUP_TABLE_CBOR[] = "https://github.com/HamletDuFromage/switch-cheats-db/raw/master/versions.cbor"; constexpr const char LOOKUP_TABLE_CBOR[] = "https://github.com/HamletDuFromage/switch-cheats-db/raw/master/versions.cbor";
constexpr const char VERSIONS_DIRECTORY[] = "https://raw.githubusercontent.com/HamletDuFromage/switch-cheats-db/master/versions/"; constexpr const char VERSIONS_DIRECTORY[] = "https://raw.githubusercontent.com/HamletDuFromage/switch-cheats-db/master/versions/";
constexpr const char CHEATS_DIRECTORY[] = "https://raw.githubusercontent.com/HamletDuFromage/switch-cheats-db/master/cheats/";
constexpr const char CHEATSLIPS_CHEATS_URL[] ="https://www.cheatslips.com/api/v1/cheats/"; constexpr const char CHEATSLIPS_CHEATS_URL[] ="https://www.cheatslips.com/api/v1/cheats/";
constexpr const char CHEATSLIPS_TOKEN_URL[] ="https://www.cheatslips.com/api/v1/token"; constexpr const char CHEATSLIPS_TOKEN_URL[] ="https://www.cheatslips.com/api/v1/token";
constexpr const char TOKEN_PATH[] = "/config/aio-switch-updater/token.json"; constexpr const char TOKEN_PATH[] = "/config/aio-switch-updater/token.json";

View file

@ -6,21 +6,21 @@
class DownloadCheatsPage : public brls::AppletFrame class DownloadCheatsPage : public brls::AppletFrame
{ {
private: protected:
brls::List* list; brls::List* list;
brls::Label* label; brls::Label* label;
brls::ListItem* del; brls::ListItem* del;
brls::ToggleListItem* listItem; uint64_t tid = 0;
std::vector<std::pair<brls::ToggleListItem*, int>> toggles; std::string bid = "";
u32 version = 0;
public:
DownloadCheatsPage(uint64_t tid); DownloadCheatsPage(uint64_t tid);
std::string GetBuilID(uint64_t tid); void GetBuildID();
std::string GetBuilIDFromFile(uint64_t tid); void GetBuildIDFromDmnt();
std::string GetCheatsTitle(nlohmann::json cheat); void GetVersion();
void WriteCheats(uint64_t tid, std::string bid, std::string cheatContent); void GetBuildIDFromFile();
void DeleteCheats(uint64_t tid, std::string bid); void WriteCheats(std::string cheatContent);
void ShowCheatsContent(nlohmann::ordered_json titles); void DeleteCheats();
typedef struct { typedef struct {
u64 base; u64 base;
@ -37,3 +37,23 @@ class DownloadCheatsPage : public brls::AppletFrame
u8 main_nso_build_id[0x20]; u8 main_nso_build_id[0x20];
} DmntCheatProcessMetadata; } DmntCheatProcessMetadata;
}; };
class DownloadCheatsPage_CheatSlips : public DownloadCheatsPage {
private:
brls::ToggleListItem* listItem;
std::vector<std::pair<brls::ToggleListItem*, int>> toggles;
std::string GetCheatsTitle(nlohmann::json cheat);
void ShowCheatsContent(nlohmann::ordered_json titles);
public:
DownloadCheatsPage_CheatSlips(uint64_t tid);
};
class DownloadCheatsPage_GbaTemp : public DownloadCheatsPage {
private:
brls::ListItem* listItem;
public:
DownloadCheatsPage_GbaTemp(uint64_t tid);
};

View file

@ -8,10 +8,14 @@ class ListDownloadTab : public brls::List
private: private:
brls::ListItem* listItem; brls::ListItem* listItem;
brls::ListItem *cheatslipsItem; brls::ListItem *cheatslipsItem;
brls::ListItem *gbatempItem;
brls::Label *notFound; brls::Label *notFound;
brls::Label *description; brls::Label *description;
brls::Label *cheatSlipLabel; brls::Label *cheatsLabel;
int size; int size;
void createCheatSlipItem();
void creategbatempItem();
public: public:
ListDownloadTab(const archiveType type); ListDownloadTab(const archiveType type);
brls::View* getDefaultFocus() override; brls::View* getDefaultFocus() override;

View file

@ -18,8 +18,10 @@
"delete_all": "Delete all cheats", "delete_all": "Delete all cheats",
"deleting": "Deleting...", "deleting": "Deleting...",
"cheastlips_title": "Cheatslips cheats", "cheastlips_title": "Cheatslips cheats",
"gbatemp_title": "GBAtemp cheats",
"get_gbatemp": "Download GBAtemp.net cheat codes",
"get_cheatslips": "Download CheatSlips.com cheat sheets", "get_cheatslips": "Download CheatSlips.com cheat sheets",
"cheatslips_label": "\ue016 Log into CheatSlips.com and download cheat sheets for your games.", "cheats_label": "\ue016 Download individual cheat codes from the GBAtemp.net database or cheat sheets from CheatSlips.com",
"cheatslips_dl": "Download a selection of cheat sheets from CheatSlips.com.\nThose cheat codes will be added to the end of your existing cheat file.", "cheatslips_dl": "Download a selection of cheat sheets from CheatSlips.com.\nThose cheat codes will be added to the end of your existing cheat file.",
"delete_file": "Delete existing cheat file", "delete_file": "Delete existing cheat file",
"cheatslips_error": "Could not fetch selected cheat codes/invalid token.", "cheatslips_error": "Could not fetch selected cheat codes/invalid token.",
@ -34,7 +36,10 @@
"exclude_titles": "Exclude titles", "exclude_titles": "Exclude titles",
"exclude_titles_desc": "You can turn off cheat updates with this menu", "exclude_titles_desc": "You can turn off cheat updates with this menu",
"exclude_titles_save": "Save choice and return", "exclude_titles_save": "Save choice and return",
"dl_all": "Download and extract the entire gbatemp cheats archive" "dl_all": "Download and extract the entire gbatemp cheats archive",
"gbatemp_dl": "Download cheat codes curated from GBAtemp. Those cheats will be added to the end of your existing cheat file.\n\uE016 Build ID: {}",
"gbatemp_dl_cheatcode": "Download cheat code",
"gbatemp_dl_successful_dl": "Successfully downloaded the following cheat code:\n{}"
}, },
"common": { "common": {
"downloading": "Downloading...", "downloading": "Downloading...",

View file

@ -11,15 +11,23 @@
namespace i18n = brls::i18n; namespace i18n = brls::i18n;
using namespace i18n::literals; using namespace i18n::literals;
AppPage::AppPage(const bool cheatSlips) : AppletFrame(true, true) AppPage::AppPage(const appPageType type) : AppletFrame(true, true)
{ {
this->setTitle(cheatSlips ? "menus/cheats/cheastlips_title"_i18n : "menus/cheats/installed"_i18n);
list = new brls::List(); list = new brls::List();
label = new brls::Label( switch(type){
brls::LabelStyle::DESCRIPTION, case appPageType::base:
cheatSlips ? "menus/cheats/cheatslips_select"_i18n : "menus/cheats/label"_i18n, this->setTitle("menus/cheats/installed"_i18n);
true label = new brls::Label(brls::LabelStyle::DESCRIPTION, "menus/cheats/label"_i18n, true);
); break;
case appPageType::cheatSlips:
this->setTitle("menus/cheats/cheastlips_title"_i18n);
label = new brls::Label(brls::LabelStyle::DESCRIPTION, "menus/cheats/cheatslips_select"_i18n, true);
break;
case appPageType::gbatempCheats:
this->setTitle("menus/cheats/gbatemp_title"_i18n);
label = new brls::Label( brls::LabelStyle::DESCRIPTION,"menus/cheats/cheatslips_select"_i18n,true);
break;
}
list->addView(label); list->addView(label);
NsApplicationRecord record; NsApplicationRecord record;
@ -34,7 +42,7 @@ AppPage::AppPage(const bool cheatSlips) : AppletFrame(true, true)
titles = fs::readLineByLine(UPDATED_TITLES_PATH); titles = fs::readLineByLine(UPDATED_TITLES_PATH);
if(!titles.empty() || cheatSlips) { if(!titles.empty() || type == appPageType::cheatSlips || type == appPageType::gbatempCheats) {
while (true) while (true)
{ {
rc = nsListApplicationRecord(&record, sizeof(record), i, &recordCount); rc = nsListApplicationRecord(&record, sizeof(record), i, &recordCount);
@ -51,17 +59,23 @@ AppPage::AppPage(const bool cheatSlips) : AppletFrame(true, true)
i++; i++;
continue; continue;
} }
if(!cheatSlips && titles.find(util::formatApplicationId(tid)) == titles.end()) { if(type == appPageType::base && titles.find(util::formatApplicationId(tid)) == titles.end()) {
i++; i++;
continue; continue;
} }
listItem = new brls::ListItem(std::string(langEntry->name), "", util::formatApplicationId(tid)); listItem = new brls::ListItem(std::string(langEntry->name), "", util::formatApplicationId(tid));
listItem->setThumbnail(controlData.icon, sizeof(controlData.icon)); listItem->setThumbnail(controlData.icon, sizeof(controlData.icon));
if(cheatSlips){
listItem->getClickEvent()->subscribe([&, tid](brls::View* view) { switch(type){
brls::Application::pushView(new DownloadCheatsPage(tid)); case appPageType::cheatSlips:
}); listItem->getClickEvent()->subscribe([&, tid](brls::View* view) { brls::Application::pushView(new DownloadCheatsPage_CheatSlips(tid)); });
break;
case appPageType::gbatempCheats:
listItem->getClickEvent()->subscribe([&, tid](brls::View* view) { brls::Application::pushView(new DownloadCheatsPage_GbaTemp(tid)); });
break;
case appPageType::base:
break;
} }
list->addView(listItem); list->addView(listItem);

View file

@ -32,13 +32,13 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
changes.push_back("\uE016 Now displays the latest installed cheat version.\n\uE016 Now warns in the app title if a new update is available."); changes.push_back("\uE016 Now displays the latest installed cheat version.\n\uE016 Now warns in the app title if a new update is available.");
verTitles.push_back("v1.2.3"); verTitles.push_back("v1.2.3");
changes.push_back("\uE016 Now multilingual (thanks to 'github.com/tiansongyu').\n\uE016 Chinese and French are currently supported."); changes.push_back("\uE016 Now multilingual (credits to github.com/tiansongyu).\n\uE016 Chinese and French are currently supported.");
verTitles.push_back("v1.2.1"); verTitles.push_back("v1.2.1");
changes.push_back("\uE016 Added option to set a payload to /bootloader/update.bin"); changes.push_back("\uE016 Added option to set a payload to /bootloader/update.bin");
verTitles.push_back("v1.2.2"); verTitles.push_back("v1.2.2");
changes.push_back("\uE016 Added japanese localisation (thanks to github.com/yyoossk)."); changes.push_back("\uE016 Added japanese localisation (credits to github.com/yyoossk).");
verTitles.push_back("v1.2.4"); verTitles.push_back("v1.2.4");
changes.push_back("\uE016 Fixed app self-update"); changes.push_back("\uE016 Fixed app self-update");
@ -47,7 +47,7 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
changes.push_back("\uE016 Improved japanese translation"); changes.push_back("\uE016 Improved japanese translation");
verTitles.push_back("v1.2.6"); verTitles.push_back("v1.2.6");
changes.push_back("\uE016 Added spanish translation (thanks to 'https://github.com/sergiou87'"); changes.push_back("\uE016 Added spanish translation (credits to github.com/sergiou87");
verTitles.push_back("v1.3.0"); verTitles.push_back("v1.3.0");
changes.push_back("\uE016 Added back the ability to update CFWs"); changes.push_back("\uE016 Added back the ability to update CFWs");
@ -77,7 +77,7 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
changes.push_back("\uE016 A few graphical tweaks."); changes.push_back("\uE016 A few graphical tweaks.");
verTitles.push_back("v1.5.2"); verTitles.push_back("v1.5.2");
changes.push_back("\uE016 Added support for Traditional Chinese (thanks to 'https://github.com/qazrfv1234')"); changes.push_back("\uE016 Added support for Traditional Chinese (credits to github.com/qazrfv1234)");
verTitles.push_back("v2.0.0"); verTitles.push_back("v2.0.0");
changes.push_back("\uE016 Added ability to download cheatslips cheats.\n\uE016 Added way to toggle out tabs.\n\uE016 Various code improvements."); changes.push_back("\uE016 Added ability to download cheatslips cheats.\n\uE016 Added way to toggle out tabs.\n\uE016 Various code improvements.");
@ -116,7 +116,7 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
changes.push_back("\uE016 Minor fixes, refactored old switch-cheats updater code and changed way to detect CFW"); changes.push_back("\uE016 Minor fixes, refactored old switch-cheats updater code and changed way to detect CFW");
verTitles.push_back("v2.4.0"); verTitles.push_back("v2.4.0");
changes.push_back("\uE016 Added option to extract the entire gbatemp cheats archive.\n\uE016 Shortened load times.\n\uE016 Added German localisation (thanks to github.com/Slluxx).\n\uE016 Added option to disable sysmodules prior to updating.\n\uE016 Improved Japanese localisation (thanks to github.com/yyoossk).\n\uE016 Added current AMS version display."); changes.push_back("\uE016 Added option to extract the entire gbatemp cheats archive.\n\uE016 Shortened load times.\n\uE016 Added German localisation (credits to github.com/Slluxx).\n\uE016 Added option to disable sysmodules prior to updating.\n\uE016 Improved Japanese localisation (credits to github.com/yyoossk).\n\uE016 Added current AMS version display.");
verTitles.push_back("v2.4.1"); verTitles.push_back("v2.4.1");
changes.push_back("\uE016 Added information about download progress."); changes.push_back("\uE016 Added information about download progress.");
@ -125,10 +125,10 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
changes.push_back("\uE016 Added option to manually change language.\n\uE016 Fixed broken strings.\n\uE016 Few visual tweaks."); changes.push_back("\uE016 Added option to manually change language.\n\uE016 Fixed broken strings.\n\uE016 Few visual tweaks.");
verTitles.push_back("v2.4.3"); verTitles.push_back("v2.4.3");
changes.push_back("\uE016 Added way to select system default in language selection.\n\uE016 Display local IP in internet settings.\n\uE016 Added Polish localisation (thanks to https://github.com/teddy74eva).\n\uE016 Updated Traditional Chinese localisation (thanks to https://github.com/qazrfv1234).\n\uE016 Minor code changes."); changes.push_back("\uE016 Added way to select system default in language selection.\n\uE016 Display local IP in internet settings.\n\uE016 Added Polish localisation (credits to github.com/teddy74eva).\n\uE016 Updated Traditional Chinese localisation (credits to https://github.com/qazrfv1234).\n\uE016 Minor code changes.");
verTitles.push_back("v2.4.4"); verTitles.push_back("v2.4.4");
changes.push_back("\uE016 Significantly reduced time to retrieve build IDs.\n\uE016 Updated Polish localisation (thanks to https://github.com/teddy74eva)."); changes.push_back("\uE016 Significantly reduced time to retrieve build IDs.\n\uE016 Updated Polish localisation (credits to github.com/teddy74eva).");
verTitles.push_back("v2.4.5-fix_ams"); verTitles.push_back("v2.4.5-fix_ams");
changes.push_back("\uE016 Atmosphère 0.19+ support. Note that this version assumes your switch is running Atmosphère. I should fix this soon, but if you're on SXOS, please stay on 2.4.4."); changes.push_back("\uE016 Atmosphère 0.19+ support. Note that this version assumes your switch is running Atmosphère. I should fix this soon, but if you're on SXOS, please stay on 2.4.4.");
@ -152,11 +152,14 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
changes.push_back("\uE016 Fixed bug copying Mariko payloads on Erista."); changes.push_back("\uE016 Fixed bug copying Mariko payloads on Erista.");
verTitles.push_back("v2.5.2"); verTitles.push_back("v2.5.2");
changes.push_back("\uE016 Updated Japanese and Traditional Chinese translations (thanks to yyoossk and qazrfv1234).\n\uE016 Updated payload so that it doesn't throw errors if the bootloader folder is missing.\n\uE016 Minor code changes that may or may not result in performace improvements."); changes.push_back("\uE016 Updated Japanese and Traditional Chinese translations (credits to github.com/yyoossk and github.com/qazrfv1234).\n\uE016 Updated payload so that it doesn't throw errors if the bootloader folder is missing.\n\uE016 Minor code changes that may or may not result in performace improvements.");
verTitles.push_back("v2.5.3"); verTitles.push_back("v2.5.3");
changes.push_back("\uE016 Check available size before downloading and extracting files.\n\uE016 Now displaying a message when the custom payload is running."); changes.push_back("\uE016 Check available size before downloading and extracting files.\n\uE016 Now displaying a message when the custom payload is running.");
verTitles.push_back("v2.6.0");
changes.push_back("\uE016 Added ability to download invidual cheet codes from the GBAtemp.net archive.\n\uE016 Updated Polish translation (credits to github.com/teddy74eva)");
for(int i = verTitles.size() -1 ; i >= 0; i--){ for(int i = verTitles.size() -1 ; i >= 0; i--){
listItem = new brls::ListItem(verTitles[i]); listItem = new brls::ListItem(verTitles[i]);
change = changes[i]; change = changes[i];

View file

@ -294,8 +294,7 @@ std::vector<std::uint8_t> downloadPageBinary(const std::string& url, std::vector
} }
nlohmann::ordered_json getRequest(const std::string& url, std::vector<std::string> headers, std::string body) { nlohmann::ordered_json getRequest(const std::string& url, std::vector<std::string> headers, std::string body) {
std::string request; std::string request = downloadPage(url, headers, body);
request = downloadPage(url, headers, body);
if(json::accept(request)) return nlohmann::ordered_json::parse(request); if(json::accept(request)) return nlohmann::ordered_json::parse(request);
else return nlohmann::ordered_json::object(); else return nlohmann::ordered_json::object();

View file

@ -11,27 +11,117 @@ namespace i18n = brls::i18n;
using namespace i18n::literals; using namespace i18n::literals;
using json = nlohmann::json; using json = nlohmann::json;
DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true) DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true), tid(tid)
{
GetVersion();
GetBuildID();
this->setTitle("menus/cheats/menu"_i18n);
this->setFooterText("Game version: v" + std::to_string(this->version / 0x10000));
}
void DownloadCheatsPage::GetBuildID() {
if(CurrentCfw::running_cfw == CFW::ams)
GetBuildIDFromDmnt();
if(this->bid == "")
GetBuildIDFromFile();
}
void DownloadCheatsPage::GetBuildIDFromDmnt() {
static Service g_dmntchtSrv;
DmntCheatProcessMetadata metadata;
smGetService(&g_dmntchtSrv, "dmnt:cht");
serviceDispatch(&g_dmntchtSrv, 65003);
serviceDispatchOut(&g_dmntchtSrv, 65002, metadata);
serviceClose(&g_dmntchtSrv);
if(metadata.title_id == this->tid){
u8 buildID[0x20];
memcpy(buildID, metadata.main_nso_build_id, 0x20);
std::stringstream ss;
for (u8 i = 0; i < 8; i++)
ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << (u16)buildID[i];
this->bid = ss.str();
}
else{
this->bid = "";
}
}
void DownloadCheatsPage::GetVersion() {
NsApplicationContentMetaStatus *MetaSatus = new NsApplicationContentMetaStatus[100U];
s32 out;
nsListApplicationContentMetaStatus(this->tid, 0, MetaSatus, 100, &out);
for(int i = 0; i < out ; i++) {
if(version < MetaSatus[i].version) this->version = MetaSatus[i].version;
}
}
void DownloadCheatsPage::GetBuildIDFromFile() {
json versions_json = download::getRequest(VERSIONS_DIRECTORY + util::formatApplicationId(this->tid) + ".json");
std::string version_str = std::to_string(this->version);
if(versions_json.find(version_str) != versions_json.end()) {
this->bid = versions_json[version_str];
}
else {
this->bid = "";
}
}
void DownloadCheatsPage::WriteCheats(std::string cheatContent) {
std::string path;
std::string tidstr = util::formatApplicationId(this->tid);
switch(CurrentCfw::running_cfw){
case CFW::ams:
path = std::string(AMS_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::rnx:
path = std::string(REINX_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::sxos:
path = std::string(SXOS_PATH) + std::string(TITLES_PATH);
break;
}
path += tidstr + "/cheats/";
fs::createTree(path);
path += this->bid + ".txt";
std::ofstream cheatFile;
cheatFile.open(path, std::ios::app);
cheatFile << "\n\n" << cheatContent;
std::ofstream updated;
updated.open(UPDATED_TITLES_PATH, std::ios::app);
updated << "\n" << tidstr;
}
void DownloadCheatsPage::DeleteCheats() {
std::string path;
switch(CurrentCfw::running_cfw){
case CFW::ams:
path = std::string(AMS_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::rnx:
path = std::string(REINX_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::sxos:
path = std::string(SXOS_PATH) + std::string(TITLES_PATH);
break;
}
std::filesystem::remove(path + util::formatApplicationId(this->tid) + "/cheats/" + this->bid + ".txt");
}
DownloadCheatsPage_CheatSlips::DownloadCheatsPage_CheatSlips(uint64_t tid) : DownloadCheatsPage(tid)
{ {
this->setTitle("menus/cheats/menu"_i18n); this->setTitle("menus/cheats/menu"_i18n);
std::string bid = "";
if(CurrentCfw::running_cfw == CFW::ams)
bid = GetBuilID(tid);
if(bid == "")
bid = GetBuilIDFromFile(tid);
list = new brls::List(); list = new brls::List();
label = new brls::Label( label = new brls::Label(
brls::LabelStyle::DESCRIPTION, brls::LabelStyle::DESCRIPTION,
"menus/cheats/cheatslips_dl"_i18n + "\n\uE016 Build ID: " + bid, "menus/cheats/cheatslips_dl"_i18n + "\n\uE016 Build ID: " + this->bid,
true true
); );
list->addView(label); list->addView(label);
if(bid != "") { if(this->bid != "") {
std::vector<std::string> headers = {"accept: application/json"}; std::vector<std::string> headers = {"accept: application/json"};
json cheatsInfo = download::getRequest(CHEATSLIPS_CHEATS_URL + util::formatApplicationId(tid) + "/" + bid, headers); json cheatsInfo = download::getRequest(CHEATSLIPS_CHEATS_URL + util::formatApplicationId(this->tid) + "/" + this->bid, headers);
if(cheatsInfo.find("cheats") != cheatsInfo.end()) { if(cheatsInfo.find("cheats") != cheatsInfo.end()) {
for (const auto& p : cheatsInfo["cheats"].items()) { for (const auto& p : cheatsInfo["cheats"].items()) {
json cheat = p.value(); json cheat = p.value();
@ -58,7 +148,7 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
list->addView(label); list->addView(label);
} }
list->registerAction((bid != "") ? "menus/cheats/cheatslips_dl_cheats"_i18n : "brls/hints/back"_i18n, brls::Key::B, [this, bid, tid] { list->registerAction((this->bid != "") ? "menus/cheats/cheatslips_dl_cheats"_i18n : "brls/hints/back"_i18n, brls::Key::B, [this] {
std::vector<int> ids; std::vector<int> ids;
for(auto& e : toggles){ for(auto& e : toggles){
if(e.first->getToggleState()){ if(e.first->getToggleState()){
@ -75,7 +165,7 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
if(token.find("token") != token.end()) { if(token.find("token") != token.end()) {
headers.push_back("X-API-TOKEN: " + token["token"].get<std::string>()); headers.push_back("X-API-TOKEN: " + token["token"].get<std::string>());
} }
json cheatsInfo = download::getRequest("https://www.cheatslips.com/api/v1/cheats/" + util::formatApplicationId(tid) + "/" + bid, headers); nlohmann::ordered_json cheatsInfo = download::getRequest("https://www.cheatslips.com/api/v1/cheats/" + util::formatApplicationId(this->tid) + "/" + this->bid, headers);
if(cheatsInfo.find("cheats") != cheatsInfo.end()) { if(cheatsInfo.find("cheats") != cheatsInfo.end()) {
for (const auto& p : cheatsInfo["cheats"].items()) { for (const auto& p : cheatsInfo["cheats"].items()) {
if(std::find(ids.begin(), ids.end(), p.value()["id"]) != ids.end()) { if(std::find(ids.begin(), ids.end(), p.value()["id"]) != ids.end()) {
@ -83,7 +173,7 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
error = 1; error = 1;
} }
else { else {
WriteCheats(tid, bid, p.value()["content"]); WriteCheats(p.value()["content"]);
} }
} }
} }
@ -132,8 +222,8 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
}); });
del = new brls::ListItem("menus/cheats/delete_file"_i18n); del = new brls::ListItem("menus/cheats/delete_file"_i18n);
del->getClickEvent()->subscribe([this, tid, bid](brls::View* view) { del->getClickEvent()->subscribe([this](brls::View* view) {
DeleteCheats(tid, bid); DeleteCheats();
brls::Dialog* dialog = new brls::Dialog("menus/common/all_done"_i18n); brls::Dialog* dialog = new brls::Dialog("menus/common/all_done"_i18n);
brls::GenericEvent::Callback callback = [dialog](brls::View* view) { brls::GenericEvent::Callback callback = [dialog](brls::View* view) {
dialog->close(); dialog->close();
@ -145,50 +235,8 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
list->addView(del); list->addView(del);
this->setContentView(list); this->setContentView(list);
} }
std::string DownloadCheatsPage::GetBuilID(uint64_t tid) {
static Service g_dmntchtSrv;
DmntCheatProcessMetadata metadata;
smGetService(&g_dmntchtSrv, "dmnt:cht");
serviceDispatch(&g_dmntchtSrv, 65003);
serviceDispatchOut(&g_dmntchtSrv, 65002, metadata);
serviceClose(&g_dmntchtSrv);
if(metadata.title_id == tid){
u8 buildID[0x20];
memcpy(buildID, metadata.main_nso_build_id, 0x20);
std::stringstream ss;
for (u8 i = 0; i < 8; i++)
ss << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << (u16)buildID[i];
return ss.str();
}
else{
return "";
}
}
std::string DownloadCheatsPage::GetBuilIDFromFile(uint64_t tid) { std::string DownloadCheatsPage_CheatSlips::GetCheatsTitle(json cheat) {
NsApplicationContentMetaStatus *MetaSatus = new NsApplicationContentMetaStatus[100U];
s32 out;
nsListApplicationContentMetaStatus(tid, 0, MetaSatus, 100, &out);
u32 v = 0;
for(int i = 0; i < out ; i++) {
if(v < MetaSatus[i].version) v = MetaSatus[i].version;
}
this->setFooterText("Game version: v" + std::to_string(v / 0x10000));
std::string version = std::to_string(v);
std::string versions_str = download::downloadPage(VERSIONS_DIRECTORY + util::formatApplicationId(tid) + ".json");
json versions;
if (json::accept(versions_str)) versions = json::parse(versions_str);
else versions = json::object();
if(versions.find(version) != versions.end()) {
return versions[version];
}
return "";
}
std::string DownloadCheatsPage::GetCheatsTitle(json cheat) {
std::string res = ""; std::string res = "";
if(cheat.find("titles") != cheat.end()) { if(cheat.find("titles") != cheat.end()) {
for(auto& p : cheat["titles"]){ for(auto& p : cheat["titles"]){
@ -202,48 +250,7 @@ std::string DownloadCheatsPage::GetCheatsTitle(json cheat) {
return res; return res;
} }
void DownloadCheatsPage::WriteCheats(uint64_t tid, std::string bid, std::string cheatContent) { void DownloadCheatsPage_CheatSlips::ShowCheatsContent(nlohmann::ordered_json titles) {
std::string path;
std::string tidstr = util::formatApplicationId(tid);
switch(CurrentCfw::running_cfw){
case CFW::ams:
path = std::string(AMS_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::rnx:
path = std::string(REINX_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::sxos:
path = std::string(SXOS_PATH) + std::string(TITLES_PATH);
break;
}
path += tidstr + "/cheats/";
fs::createTree(path);
path += bid + ".txt";
std::ofstream cheatFile;
cheatFile.open(path, std::ios::app);
cheatFile << "\n\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(CurrentCfw::running_cfw){
case CFW::ams:
path = std::string(AMS_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::rnx:
path = std::string(REINX_PATH) + std::string(CONTENTS_PATH);
break;
case CFW::sxos:
path = std::string(SXOS_PATH) + std::string(TITLES_PATH);
break;
}
std::filesystem::remove(path + util::formatApplicationId(tid) + "/cheats/" + bid + ".txt");
}
void DownloadCheatsPage::ShowCheatsContent(nlohmann::ordered_json titles) {
brls::AppletFrame* appView = new brls::AppletFrame(true, true); brls::AppletFrame* appView = new brls::AppletFrame(true, true);
brls::List* list = new brls::List(); brls::List* list = new brls::List();
brls::ListItem* listItem; brls::ListItem* listItem;
@ -257,3 +264,62 @@ void DownloadCheatsPage::ShowCheatsContent(nlohmann::ordered_json titles) {
appView->setContentView(list); appView->setContentView(list);
brls::PopupFrame::open("menus/cheats/sheet_content"_i18n, appView, "", ""); brls::PopupFrame::open("menus/cheats/sheet_content"_i18n, appView, "", "");
} }
DownloadCheatsPage_GbaTemp::DownloadCheatsPage_GbaTemp(uint64_t tid) : DownloadCheatsPage(tid)
{
list = new brls::List();
label = new brls::Label(
brls::LabelStyle::DESCRIPTION,
fmt::format("menus/cheats/gbatemp_dl"_i18n, this->bid),
true
);
list->addView(label);
if(this->bid != "") {
nlohmann::ordered_json cheatsJson = download::getRequest(CHEATS_DIRECTORY + util::formatApplicationId(this->tid) + ".json");
if(cheatsJson.find(this->bid) != cheatsJson.end()) {
for (const auto& p : cheatsJson[this->bid].items()) {
json cheat = p.value();
listItem = new::brls::ListItem(cheat["title"]);
listItem->registerAction("menus/cheats/gbatemp_dl_cheatcode"_i18n, brls::Key::A, [this, cheat] {
WriteCheats(cheat["content"]);
brls::Dialog* dialog = new brls::Dialog(fmt::format("menus/cheats/gbatemp_dl_successful_dl"_i18n, cheat["title"]));
brls::GenericEvent::Callback callback = [dialog](brls::View* view) {
dialog->close();
};
dialog->addButton("menus/common/ok"_i18n, callback);
dialog->setCancelable(true);
dialog->open();
return true;
});
list->addView(listItem);
}
list->addView(new brls::ListItemGroupSpacing(true));
}
}
else {
label = new brls::Label(
brls::LabelStyle::REGULAR,
"menus/cheats/bid_not_found"_i18n,
true
);
list->addView(label);
}
del = new brls::ListItem("menus/cheats/delete_file"_i18n);
del->getClickEvent()->subscribe([this](brls::View* view) {
DeleteCheats();
brls::Dialog* dialog = new brls::Dialog("menus/common/all_done"_i18n);
brls::GenericEvent::Callback callback = [dialog](brls::View* view) {
dialog->close();
};
dialog->addButton("menus/common/ok"_i18n, callback);
dialog->setCancelable(true);
dialog->open();
});
list->addView(del);
this->setContentView(list);
}

View file

@ -121,18 +121,24 @@ ListDownloadTab::ListDownloadTab(const archiveType type) :
} }
if(type == archiveType::cheats){ if(type == archiveType::cheats){
cheatSlipLabel = new brls::Label( cheatsLabel = new brls::Label(
brls::LabelStyle::DESCRIPTION, brls::LabelStyle::DESCRIPTION,
"menus/cheats/cheatslips_label"_i18n, "menus/cheats/cheats_label"_i18n,
true true
); );
this->addView(cheatSlipLabel); this->addView(cheatsLabel);
creategbatempItem();
createCheatSlipItem();
}
}
void ListDownloadTab::createCheatSlipItem() {
this->size += 1; this->size += 1;
cheatslipsItem = new brls::ListItem("menus/cheats/get_cheatslips"_i18n); cheatslipsItem = new brls::ListItem("menus/cheats/get_cheatslips"_i18n);
cheatslipsItem->setHeight(LISTITEM_HEIGHT); cheatslipsItem->setHeight(LISTITEM_HEIGHT);
cheatslipsItem->getClickEvent()->subscribe([&](brls::View* view) { cheatslipsItem->getClickEvent()->subscribe([&](brls::View* view) {
if(std::filesystem::exists(TOKEN_PATH)) { if(std::filesystem::exists(TOKEN_PATH)) {
brls::Application::pushView(new AppPage(true)); brls::Application::pushView(new AppPage(appPageType::cheatSlips));
return true; return true;
} }
else { else {
@ -166,7 +172,7 @@ ListDownloadTab::ListDownloadTab(const archiveType type) :
std::ofstream tokenFile(TOKEN_PATH); std::ofstream tokenFile(TOKEN_PATH);
tokenFile << token.dump(); tokenFile << token.dump();
tokenFile.close(); tokenFile.close();
brls::Application::pushView(new AppPage(true)); brls::Application::pushView(new AppPage(appPageType::cheatSlips));
return true; return true;
} }
else { else {
@ -182,7 +188,18 @@ ListDownloadTab::ListDownloadTab(const archiveType type) :
} }
}); });
this->addView(cheatslipsItem); this->addView(cheatslipsItem);
} }
void ListDownloadTab::creategbatempItem() {
this->size += 1;
gbatempItem = new brls::ListItem("menus/cheats/get_gbatemp"_i18n);
gbatempItem->setHeight(LISTITEM_HEIGHT);
gbatempItem->getClickEvent()->subscribe([&](brls::View* view) {
brls::Application::pushView(new AppPage(appPageType::gbatempCheats));
return true;
});
this->addView(gbatempItem);
} }
brls::View* ListDownloadTab::getDefaultFocus() brls::View* ListDownloadTab::getDefaultFocus()

View file

@ -1,4 +1,3 @@
#include <switch.h>
#include "utils.hpp" #include "utils.hpp"
#include "fs.hpp" #include "fs.hpp"
#include "current_cfw.hpp" #include "current_cfw.hpp"
@ -8,9 +7,11 @@
#include "main_frame.hpp" #include "main_frame.hpp"
#include "reboot_payload.h" #include "reboot_payload.h"
#include "unistd.h" #include "unistd.h"
#include <switch.h>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
namespace i18n = brls::i18n; namespace i18n = brls::i18n;
using namespace i18n::literals; using namespace i18n::literals;