mirror of
https://github.com/HamletDuFromage/aio-switch-updater.git
synced 2024-12-28 18:36:02 +00:00
Added ability to download invidual cheet codes from the GBAtemp.net archive.
This commit is contained in:
parent
bab943bb0a
commit
c2eef003aa
12 changed files with 333 additions and 198 deletions
2
Makefile
2
Makefile
|
@ -22,7 +22,7 @@ DATA := data
|
|||
INCLUDES := include lib/zipper/include /lib/borealis/library/include/borealis/extern/nlohmann
|
||||
APP_TITLE := All-in-One Switch Updater
|
||||
APP_AUTHOR := HamletDuFromage
|
||||
APP_VERSION := 2.5.3
|
||||
APP_VERSION := 2.6.0
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
|
||||
ROMFS := resources
|
||||
|
|
|
@ -6,6 +6,11 @@
|
|||
|
||||
typedef struct app App;
|
||||
|
||||
enum class appPageType{
|
||||
base,
|
||||
cheatSlips,
|
||||
gbatempCheats
|
||||
};
|
||||
|
||||
class AppPage : public brls::AppletFrame
|
||||
{
|
||||
|
@ -18,5 +23,5 @@ class AppPage : public brls::AppletFrame
|
|||
std::set<std::string> titles;
|
||||
|
||||
public:
|
||||
AppPage(const bool cheatSlips = false);
|
||||
AppPage(const appPageType type = appPageType::base);
|
||||
};
|
|
@ -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_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 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_TOKEN_URL[] ="https://www.cheatslips.com/api/v1/token";
|
||||
constexpr const char TOKEN_PATH[] = "/config/aio-switch-updater/token.json";
|
||||
|
|
|
@ -6,21 +6,21 @@
|
|||
|
||||
class DownloadCheatsPage : public brls::AppletFrame
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
brls::List* list;
|
||||
brls::Label* label;
|
||||
brls::ListItem* del;
|
||||
brls::ToggleListItem* listItem;
|
||||
std::vector<std::pair<brls::ToggleListItem*, int>> toggles;
|
||||
uint64_t tid = 0;
|
||||
std::string bid = "";
|
||||
u32 version = 0;
|
||||
|
||||
public:
|
||||
DownloadCheatsPage(uint64_t tid);
|
||||
std::string GetBuilID(uint64_t tid);
|
||||
std::string GetBuilIDFromFile(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);
|
||||
void ShowCheatsContent(nlohmann::ordered_json titles);
|
||||
void GetBuildID();
|
||||
void GetBuildIDFromDmnt();
|
||||
void GetVersion();
|
||||
void GetBuildIDFromFile();
|
||||
void WriteCheats(std::string cheatContent);
|
||||
void DeleteCheats();
|
||||
|
||||
typedef struct {
|
||||
u64 base;
|
||||
|
@ -36,4 +36,24 @@ class DownloadCheatsPage : public brls::AppletFrame
|
|||
DmntMemoryRegionExtents address_space_extents;
|
||||
u8 main_nso_build_id[0x20];
|
||||
} 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);
|
||||
};
|
|
@ -8,10 +8,14 @@ class ListDownloadTab : public brls::List
|
|||
private:
|
||||
brls::ListItem* listItem;
|
||||
brls::ListItem *cheatslipsItem;
|
||||
brls::ListItem *gbatempItem;
|
||||
brls::Label *notFound;
|
||||
brls::Label *description;
|
||||
brls::Label *cheatSlipLabel;
|
||||
brls::Label *cheatsLabel;
|
||||
int size;
|
||||
void createCheatSlipItem();
|
||||
void creategbatempItem();
|
||||
|
||||
public:
|
||||
ListDownloadTab(const archiveType type);
|
||||
brls::View* getDefaultFocus() override;
|
||||
|
|
|
@ -18,8 +18,10 @@
|
|||
"delete_all": "Delete all cheats",
|
||||
"deleting": "Deleting...",
|
||||
"cheastlips_title": "Cheatslips cheats",
|
||||
"gbatemp_title": "GBAtemp cheats",
|
||||
"get_gbatemp": "Download GBAtemp.net cheat codes",
|
||||
"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.",
|
||||
"delete_file": "Delete existing cheat file",
|
||||
"cheatslips_error": "Could not fetch selected cheat codes/invalid token.",
|
||||
|
@ -34,7 +36,10 @@
|
|||
"exclude_titles": "Exclude titles",
|
||||
"exclude_titles_desc": "You can turn off cheat updates with this menu",
|
||||
"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": {
|
||||
"downloading": "Downloading...",
|
||||
|
|
|
@ -11,15 +11,23 @@
|
|||
|
||||
namespace i18n = brls::i18n;
|
||||
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();
|
||||
label = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
cheatSlips ? "menus/cheats/cheatslips_select"_i18n : "menus/cheats/label"_i18n,
|
||||
true
|
||||
);
|
||||
switch(type){
|
||||
case appPageType::base:
|
||||
this->setTitle("menus/cheats/installed"_i18n);
|
||||
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);
|
||||
|
||||
NsApplicationRecord record;
|
||||
|
@ -34,7 +42,7 @@ AppPage::AppPage(const bool cheatSlips) : AppletFrame(true, true)
|
|||
|
||||
titles = fs::readLineByLine(UPDATED_TITLES_PATH);
|
||||
|
||||
if(!titles.empty() || cheatSlips) {
|
||||
if(!titles.empty() || type == appPageType::cheatSlips || type == appPageType::gbatempCheats) {
|
||||
while (true)
|
||||
{
|
||||
rc = nsListApplicationRecord(&record, sizeof(record), i, &recordCount);
|
||||
|
@ -51,17 +59,23 @@ AppPage::AppPage(const bool cheatSlips) : AppletFrame(true, true)
|
|||
i++;
|
||||
continue;
|
||||
}
|
||||
if(!cheatSlips && titles.find(util::formatApplicationId(tid)) == titles.end()) {
|
||||
if(type == appPageType::base && titles.find(util::formatApplicationId(tid)) == titles.end()) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
listItem = new brls::ListItem(std::string(langEntry->name), "", util::formatApplicationId(tid));
|
||||
listItem->setThumbnail(controlData.icon, sizeof(controlData.icon));
|
||||
if(cheatSlips){
|
||||
listItem->getClickEvent()->subscribe([&, tid](brls::View* view) {
|
||||
brls::Application::pushView(new DownloadCheatsPage(tid));
|
||||
});
|
||||
|
||||
switch(type){
|
||||
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);
|
||||
|
|
|
@ -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.");
|
||||
|
||||
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");
|
||||
changes.push_back("\uE016 Added option to set a payload to /bootloader/update.bin");
|
||||
|
||||
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");
|
||||
changes.push_back("\uE016 Fixed app self-update");
|
||||
|
@ -47,7 +47,7 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
|
|||
changes.push_back("\uE016 Improved japanese translation");
|
||||
|
||||
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");
|
||||
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.");
|
||||
|
||||
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");
|
||||
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");
|
||||
|
||||
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");
|
||||
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.");
|
||||
|
||||
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");
|
||||
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");
|
||||
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.");
|
||||
|
||||
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");
|
||||
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--){
|
||||
listItem = new brls::ListItem(verTitles[i]);
|
||||
change = changes[i];
|
||||
|
|
|
@ -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) {
|
||||
std::string request;
|
||||
request = downloadPage(url, headers, body);
|
||||
std::string request = downloadPage(url, headers, body);
|
||||
|
||||
if(json::accept(request)) return nlohmann::ordered_json::parse(request);
|
||||
else return nlohmann::ordered_json::object();
|
||||
|
|
|
@ -11,27 +11,117 @@ namespace i18n = brls::i18n;
|
|||
using namespace i18n::literals;
|
||||
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);
|
||||
|
||||
std::string bid = "";
|
||||
if(CurrentCfw::running_cfw == CFW::ams)
|
||||
bid = GetBuilID(tid);
|
||||
if(bid == "")
|
||||
bid = GetBuilIDFromFile(tid);
|
||||
|
||||
list = new brls::List();
|
||||
label = new brls::Label(
|
||||
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
|
||||
);
|
||||
list->addView(label);
|
||||
|
||||
if(bid != "") {
|
||||
if(this->bid != "") {
|
||||
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()) {
|
||||
for (const auto& p : cheatsInfo["cheats"].items()) {
|
||||
json cheat = p.value();
|
||||
|
@ -58,7 +148,7 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
|
|||
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;
|
||||
for(auto& e : toggles){
|
||||
if(e.first->getToggleState()){
|
||||
|
@ -75,7 +165,7 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
|
|||
if(token.find("token") != token.end()) {
|
||||
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()) {
|
||||
for (const auto& p : cheatsInfo["cheats"].items()) {
|
||||
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;
|
||||
}
|
||||
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->getClickEvent()->subscribe([this, tid, bid](brls::View* view) {
|
||||
DeleteCheats(tid, bid);
|
||||
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();
|
||||
|
@ -145,50 +235,8 @@ DownloadCheatsPage::DownloadCheatsPage(uint64_t tid) : AppletFrame(true, true)
|
|||
list->addView(del);
|
||||
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) {
|
||||
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 DownloadCheatsPage_CheatSlips::GetCheatsTitle(json cheat) {
|
||||
std::string res = "";
|
||||
if(cheat.find("titles") != cheat.end()) {
|
||||
for(auto& p : cheat["titles"]){
|
||||
|
@ -202,48 +250,7 @@ std::string DownloadCheatsPage::GetCheatsTitle(json cheat) {
|
|||
return res;
|
||||
}
|
||||
|
||||
void DownloadCheatsPage::WriteCheats(uint64_t tid, std::string bid, std::string cheatContent) {
|
||||
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) {
|
||||
void DownloadCheatsPage_CheatSlips::ShowCheatsContent(nlohmann::ordered_json titles) {
|
||||
brls::AppletFrame* appView = new brls::AppletFrame(true, true);
|
||||
brls::List* list = new brls::List();
|
||||
brls::ListItem* listItem;
|
||||
|
@ -256,4 +263,63 @@ void DownloadCheatsPage::ShowCheatsContent(nlohmann::ordered_json titles) {
|
|||
}
|
||||
appView->setContentView(list);
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,68 +121,85 @@ ListDownloadTab::ListDownloadTab(const archiveType type) :
|
|||
}
|
||||
|
||||
if(type == archiveType::cheats){
|
||||
cheatSlipLabel = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"menus/cheats/cheatslips_label"_i18n,
|
||||
true
|
||||
cheatsLabel = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"menus/cheats/cheats_label"_i18n,
|
||||
true
|
||||
);
|
||||
this->addView(cheatSlipLabel);
|
||||
this->size += 1;
|
||||
cheatslipsItem = new brls::ListItem("menus/cheats/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));
|
||||
this->addView(cheatsLabel);
|
||||
creategbatempItem();
|
||||
createCheatSlipItem();
|
||||
}
|
||||
}
|
||||
|
||||
void ListDownloadTab::createCheatSlipItem() {
|
||||
this->size += 1;
|
||||
cheatslipsItem = new brls::ListItem("menus/cheats/get_cheatslips"_i18n);
|
||||
cheatslipsItem->setHeight(LISTITEM_HEIGHT);
|
||||
cheatslipsItem->getClickEvent()->subscribe([&](brls::View* view) {
|
||||
if(std::filesystem::exists(TOKEN_PATH)) {
|
||||
brls::Application::pushView(new AppPage(appPageType::cheatSlips));
|
||||
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 = download::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(appPageType::cheatSlips));
|
||||
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 = download::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/cheats/cheatslips_wrong_id"_i18n + "\n" + "menus/cheats/kb_error"_i18n);
|
||||
brls::GenericEvent::Callback callback = [dialog](brls::View* view) {
|
||||
dialog->close();
|
||||
};
|
||||
dialog->addButton("menus/common/ok"_i18n, callback);
|
||||
dialog->setCancelable(true);
|
||||
dialog->open();
|
||||
return true;
|
||||
}
|
||||
brls::Dialog* dialog = new brls::Dialog("menus/cheats/cheatslips_wrong_id"_i18n + "\n" + "menus/cheats/kb_error"_i18n);
|
||||
brls::GenericEvent::Callback callback = [dialog](brls::View* view) {
|
||||
dialog->close();
|
||||
};
|
||||
dialog->addButton("menus/common/ok"_i18n, callback);
|
||||
dialog->setCancelable(true);
|
||||
dialog->open();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
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()
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <switch.h>
|
||||
#include "utils.hpp"
|
||||
#include "fs.hpp"
|
||||
#include "current_cfw.hpp"
|
||||
|
@ -8,9 +7,11 @@
|
|||
#include "main_frame.hpp"
|
||||
#include "reboot_payload.h"
|
||||
#include "unistd.h"
|
||||
#include <switch.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
namespace i18n = brls::i18n;
|
||||
using namespace i18n::literals;
|
||||
|
||||
|
|
Loading…
Reference in a new issue