mirror of
https://github.com/HamletDuFromage/aio-switch-updater.git
synced 2024-11-24 18:42:05 +00:00
Add Custom Downloads tab
This commit is contained in:
parent
7b34afc414
commit
d71dcc1807
13 changed files with 83 additions and 62 deletions
2
Makefile
2
Makefile
|
@ -22,7 +22,7 @@ DATA := data
|
|||
INCLUDES := include /lib/borealis/library/include/borealis/extern/nlohmann
|
||||
APP_TITLE := All-in-One Switch Updater
|
||||
APP_AUTHOR := HamletDuFromage
|
||||
APP_VERSION := 2.19.3
|
||||
APP_VERSION := 2.20.0
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
|
||||
ROMFS := resources
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<img src = "https://user-images.githubusercontent.com/61667930/93691188-7833f000-fad1-11ea-866d-42e19be54425.jpg"\><br>
|
||||
</p>
|
||||
|
||||
A Nintendo Switch homebrew app to download and update CFWs, sigpatches, FWs and cheat codes. Supports Atmosphère, ReiNX and SXOS.
|
||||
A Nintendo Switch homebrew app to download and update CFWs, FWs and cheat codes. Supports Atmosphère, ReiNX and SXOS.
|
||||
|
||||
Works on **unpatched** (Erista) and **patched** (v2/Mariko) Switches.
|
||||
|
||||
|
@ -27,13 +27,12 @@ Copy the `aio-switch-updater/` directory to `/switch/` on your sdcard.
|
|||
- Update the Atmosphère Switch Custom Firmware. AIO-Switch-Updater uses a custom RCM payload to finalise the install as it can't be performed while HOS is running.
|
||||
- If you would like to preserve additional files or directories, write their path (one line each) in `/config/aio-switch-updater/preserve.txt` and they won't be overwritten when updating.
|
||||
- Place [this file](https://github.com/HamletDuFromage/aio-switch-updater/blob/master/copy_files.txt) in `/config/aio-switch-updater/copy_files.txt` in order to have specific copy operations performed after each download. This is mainly meant for users with trinkets who want payloads automatically copied to a directory.
|
||||
- A custom Atmosphère url can be entered in [this file](https://github.com/HamletDuFromage/aio-switch-updater/blob/master/customPacks.json). Once moved to `/config/aio-switch-updater/customPacks.json`, it will show on the `Update Atmopshère` menu. This can be used to support third-party packs through AIO-Switch-Updater
|
||||
|
||||
### ⬦ Update Hekate/Payload
|
||||
- Download and update Hekate, as well as a selection of RCM payloads
|
||||
|
||||
### ⬦ Update Sigpatches
|
||||
- Dowload sigpatches, which are patches required to launch homebrew .NSPs on the Atmosphère CFW.
|
||||
### ⬦ Custom Downloads
|
||||
- A custom Atmosphère url can be entered in [this file](https://github.com/HamletDuFromage/aio-switch-updater/blob/master/custom_packs.json). Once moved to `/config/aio-switch-updater/custom_packs.json`, it will show on the `Custom Download` menu. This can be used to support third-party packs through AIO-Switch-Updater. Non-Atmosphère downloads can also be added in the `misc` category.
|
||||
|
||||
### ⬦ Download firmwares
|
||||
- Download firmware files to `/firmware` that can then be installed using DayBreak.
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"Name of pack": "link_to_zip",
|
||||
"Name of anther pack": "link_to_zip"
|
||||
}
|
9
custom_packs.json
Normal file
9
custom_packs.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"ams": {
|
||||
"Name of Atmosphère pack": "link_to_zip",
|
||||
"Name of anther pack": "link_to_zip"
|
||||
},
|
||||
"misc": {
|
||||
"name of download": "link"
|
||||
}
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
"cfw": true,
|
||||
"cheats": true,
|
||||
"firmwares": true,
|
||||
"sigpatches": true,
|
||||
"jccolor": true,
|
||||
"pccolor": true,
|
||||
"downloadpayload": true,
|
||||
|
|
|
@ -4,23 +4,24 @@
|
|||
#include <json.hpp>
|
||||
#include <set>
|
||||
|
||||
#include "constants.hpp"
|
||||
|
||||
class AmsTab : public brls::List
|
||||
{
|
||||
private:
|
||||
brls::ListItem* listItem;
|
||||
brls::Label* description;
|
||||
int size = 0;
|
||||
bool erista;
|
||||
contentType type;
|
||||
nlohmann::ordered_json hekate;
|
||||
std::string GetRepoName(const std::string& repo);
|
||||
std::set<std::string> GetLastDownloadedModules(const std::string& json_path);
|
||||
void CreateStagedFrames(const std::string& text, const std::string& url, const std::string& operation, bool erista, bool hekate = false, const std::string& text_hekate = "", const std::string& hekate_url = "");
|
||||
void CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate = true);
|
||||
void CreateStagedFrames(const std::string& text, const std::string& url, bool erista, bool ams = true, bool hekate = false, const std::string& text_hekate = "", const std::string& hekate_url = "");
|
||||
void CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate = true, bool ams = true);
|
||||
nlohmann::ordered_json SortDeepseaModules(const nlohmann::ordered_json& modules);
|
||||
void ShowCustomDeepseaBuilder(nlohmann::ordered_json& modules);
|
||||
|
||||
public:
|
||||
AmsTab(const nlohmann::json& nxlinks, const bool erista = true, const bool hideStandardEntries = false);
|
||||
AmsTab(const nlohmann::json& nxlinks, const bool erista = true, const bool custom = false);
|
||||
};
|
||||
|
||||
class UnTogglableListItem : public brls::ToggleListItem
|
||||
|
|
|
@ -18,7 +18,6 @@ constexpr const char APP_FILENAME[] = "/config/aio-switch-updater/app.zip";
|
|||
|
||||
constexpr const char NXLINKS_URL[] = "https://raw.githubusercontent.com/HamletDuFromage/nx-links/master/nx-links.json";
|
||||
|
||||
constexpr const char SIGPATCHES_URL[] = "https://raw.githubusercontent.com/HamletDuFromage/nx-links/master/sigpatches.json";
|
||||
constexpr const char SIGPATCHES_FILENAME[] = "/config/aio-switch-updater/sigpatches.zip";
|
||||
constexpr const char HEKATE_IPL_PATH[] = "/bootloader/hekate_ipl.ini";
|
||||
|
||||
|
@ -41,7 +40,7 @@ constexpr const char DEEPSEA_META_JSON[] = "https://builder.teamneptune.net/meta
|
|||
constexpr const char DEEPSEA_BUILD_URL[] = "https://builder.teamneptune.net/build/";
|
||||
constexpr const char DEEPSEA_PACKAGE_PATH[] = "/config/deepsea/customPackage.json";
|
||||
|
||||
constexpr const char CUSTOM_PACKS_PATH[] = "/config/aio-switch-updater/customPacks.json";
|
||||
constexpr const char CUSTOM_PACKS_PATH[] = "/config/aio-switch-updater/custom_packs.json";
|
||||
|
||||
constexpr const char CHEATS_URL_TITLES[] = "https://github.com/HamletDuFromage/switch-cheats-db/releases/latest/download/titles.zip";
|
||||
constexpr const char CHEATS_URL_CONTENTS[] = "https://github.com/HamletDuFromage/switch-cheats-db/releases/latest/download/contents.zip";
|
||||
|
|
|
@ -13,7 +13,6 @@ private:
|
|||
std::string currentCheatsVer = "";
|
||||
std::string newCheatsVer = "";
|
||||
contentType type;
|
||||
int size = 0;
|
||||
void createList();
|
||||
void createList(contentType type);
|
||||
void createCheatSlipItem();
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
"new_update": " - New app update available",
|
||||
"about": "About",
|
||||
"update_ams": "Update Atmosphère",
|
||||
"custom_downloads": "Custom Downloads",
|
||||
"update_cfw": "Update CFW",
|
||||
"update_bootloaders": "Update bootloaders",
|
||||
"update_sigpatches": "Update sigpatches",
|
||||
|
@ -191,7 +192,10 @@
|
|||
"cant_fetch_deepsea": "Couldn't fetch packages. Open a Github issue if this persists.",
|
||||
"build_your_deepsea": "Build your own custom DeepSea package by selecting packages",
|
||||
"getting_ams": "Getting Atmosphère",
|
||||
"custom_packs_label": "\u25c6 Here are packs listed in the {} file. Be aware that those are not endorsed by AIO-Switch-Updater so make sure you trust their source."
|
||||
"custom_packs_label": "\u25c6 Here are packs listed in the {} file. Be aware that those are not endorsed by AIO-Switch-Updater so make sure you trust their source.",
|
||||
"custom_packs_ams": "\u25c6 Downloads containing the Atmosphère custom firmware.",
|
||||
"custom_packs_misc": "\u25c6 Downloads containing homebrew and tools.",
|
||||
"custom_download" : "Custom Download"
|
||||
},
|
||||
"firmware": {
|
||||
"launch_daybreak": "Do you want to launch Daybreak to install the downloaded sysupdate?"
|
||||
|
|
|
@ -15,22 +15,22 @@
|
|||
namespace i18n = brls::i18n;
|
||||
using namespace i18n::literals;
|
||||
|
||||
AmsTab::AmsTab(const nlohmann::json& nxlinks, const bool erista, const bool hideStandardEntries) : brls::List()
|
||||
AmsTab::AmsTab(const nlohmann::json& nxlinks, const bool erista, const bool custom) : brls::List()
|
||||
{
|
||||
this->erista = erista;
|
||||
this->hekate = util::getValueFromKey(nxlinks, "hekate");
|
||||
auto cfws = util::getValueFromKey(nxlinks, "cfws");
|
||||
|
||||
if (!hideStandardEntries) {
|
||||
this->description = new brls::Label(brls::LabelStyle::DESCRIPTION, "menus/main/ams_text"_i18n + (CurrentCfw::running_cfw == CFW::ams ? "\n" + "menus/ams_update/current_ams"_i18n + CurrentCfw::getAmsInfo() : "") + (erista ? "\n" + "menus/ams_update/erista_rev"_i18n : "\n" + "menus/ams_update/mariko_rev"_i18n), true);
|
||||
this->addView(description);
|
||||
if (!custom) {
|
||||
this->type = contentType::ams_cfw;
|
||||
auto cfws = util::getValueFromKey(nxlinks, "cfws");
|
||||
|
||||
this->addView(new brls::Label(brls::LabelStyle::DESCRIPTION, "menus/main/ams_text"_i18n + (CurrentCfw::running_cfw == CFW::ams ? "\n" + "menus/ams_update/current_ams"_i18n + CurrentCfw::getAmsInfo() : "") + (erista ? "\n" + "menus/ams_update/erista_rev"_i18n : "\n" + "menus/ams_update/mariko_rev"_i18n), true));
|
||||
CreateDownloadItems(util::getValueFromKey(cfws, "Atmosphere"));
|
||||
|
||||
description = new brls::Label(
|
||||
this->addView(new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"menus/ams_update/deepsea_label"_i18n,
|
||||
true);
|
||||
this->addView(description);
|
||||
true));
|
||||
|
||||
listItem = new brls::ListItem("menus/ams_update/get_custom_deepsea"_i18n);
|
||||
listItem->setHeight(LISTITEM_HEIGHT);
|
||||
|
@ -40,25 +40,36 @@ AmsTab::AmsTab(const nlohmann::json& nxlinks, const bool erista, const bool hide
|
|||
this->ShowCustomDeepseaBuilder(modules);
|
||||
});
|
||||
this->addView(listItem);
|
||||
|
||||
CreateDownloadItems(util::getValueFromKey(cfws, "DeepSea"), false);
|
||||
}
|
||||
|
||||
auto custom_pack = fs::parseJsonFile(CUSTOM_PACKS_PATH);
|
||||
if (custom_pack.size() != 0) {
|
||||
description = new brls::Label(
|
||||
else {
|
||||
auto custom_pack = fs::parseJsonFile(CUSTOM_PACKS_PATH);
|
||||
this->addView(new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
fmt::format("menus/ams_update/custom_packs_label"_i18n, CUSTOM_PACKS_PATH),
|
||||
true);
|
||||
this->addView(description);
|
||||
|
||||
CreateDownloadItems(cfws.size() ? custom_pack : nlohmann::ordered_json::object(), true); // TODO: better way to check for availability of the links
|
||||
true));
|
||||
if (custom_pack.contains("ams") && custom_pack["ams"].size() != 0) {
|
||||
this->type = contentType::ams_cfw;
|
||||
this->addView(new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"menus/ams_update/custom_packs_ams"_i18n,
|
||||
true));
|
||||
CreateDownloadItems(custom_pack["ams"], true); // TODO: check for internet
|
||||
}
|
||||
if (custom_pack.contains("misc") && custom_pack["misc"].size() != 0) {
|
||||
this->type = contentType::bootloaders;
|
||||
this->addView(new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"menus/ams_update/custom_packs_misc"_i18n,
|
||||
true));
|
||||
CreateDownloadItems(custom_pack["misc"], false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AmsTab::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate)
|
||||
void AmsTab::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool hekate, bool ams)
|
||||
{
|
||||
std::string operation("menus/ams_update/getting_ams"_i18n);
|
||||
std::vector<std::pair<std::string, std::string>> links;
|
||||
links = download::getLinksFromJson(cfw_links);
|
||||
if (links.size()) {
|
||||
|
@ -71,19 +82,19 @@ void AmsTab::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool h
|
|||
std::string text("menus/common/download"_i18n + link.first + "menus/common/from"_i18n + url);
|
||||
listItem = new brls::ListItem(link.first);
|
||||
listItem->setHeight(LISTITEM_HEIGHT);
|
||||
listItem->getClickEvent()->subscribe([this, text, text_hekate, url, hekate_url, operation, hekate](brls::View* view) {
|
||||
listItem->getClickEvent()->subscribe([this, text, text_hekate, url, hekate_url, hekate, ams](brls::View* view) {
|
||||
if (!erista && !std::filesystem::exists(MARIKO_PAYLOAD_PATH)) {
|
||||
brls::Application::crash("menus/errors/mariko_payload_missing"_i18n);
|
||||
}
|
||||
else {
|
||||
CreateStagedFrames(text, url, operation, erista, hekate, text_hekate, hekate_url);
|
||||
CreateStagedFrames(text, url, erista, ams, hekate, text_hekate, hekate_url);
|
||||
}
|
||||
});
|
||||
this->addView(listItem);
|
||||
}
|
||||
}
|
||||
else {
|
||||
description = new brls::Label(
|
||||
brls::Label* description = new brls::Label(
|
||||
brls::LabelStyle::SMALL,
|
||||
"menus/main/links_not_found"_i18n,
|
||||
true);
|
||||
|
@ -92,16 +103,16 @@ void AmsTab::CreateDownloadItems(const nlohmann::ordered_json& cfw_links, bool h
|
|||
}
|
||||
}
|
||||
|
||||
void AmsTab::CreateStagedFrames(const std::string& text, const std::string& url, const std::string& operation, bool erista, bool hekate, const std::string& text_hekate, const std::string& hekate_url)
|
||||
void AmsTab::CreateStagedFrames(const std::string& text, const std::string& url, bool erista, bool ams, bool hekate, const std::string& text_hekate, const std::string& hekate_url)
|
||||
{
|
||||
brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame();
|
||||
stagedFrame->setTitle(operation);
|
||||
stagedFrame->setTitle(this->type == contentType::ams_cfw ? "menus/ams_update/getting_ams"_i18n : "menus/ams_update/custom_download"_i18n);
|
||||
stagedFrame->addStage(
|
||||
new ConfirmPage(stagedFrame, text));
|
||||
stagedFrame->addStage(
|
||||
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [url]() { util::downloadArchive(url, contentType::ams_cfw); }));
|
||||
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [&, url]() { util::downloadArchive(url, this->type); }));
|
||||
stagedFrame->addStage(
|
||||
new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, []() { util::extractArchive(contentType::ams_cfw); }));
|
||||
new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, [&]() { util::extractArchive(this->type); }));
|
||||
if (hekate) {
|
||||
stagedFrame->addStage(
|
||||
new DialoguePage_ams(stagedFrame, text_hekate, erista));
|
||||
|
@ -110,8 +121,10 @@ void AmsTab::CreateStagedFrames(const std::string& text, const std::string& url,
|
|||
stagedFrame->addStage(
|
||||
new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, []() { util::extractArchive(contentType::bootloaders); }));
|
||||
}
|
||||
stagedFrame->addStage(
|
||||
new ConfirmPage(stagedFrame, "menus/ams_update/reboot_rcm"_i18n, false, true, erista));
|
||||
if (ams)
|
||||
stagedFrame->addStage(new ConfirmPage(stagedFrame, "menus/ams_update/reboot_rcm"_i18n, false, true, erista));
|
||||
else
|
||||
stagedFrame->addStage(new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true));
|
||||
brls::Application::pushView(stagedFrame);
|
||||
}
|
||||
|
||||
|
@ -207,7 +220,6 @@ void AmsTab::ShowCustomDeepseaBuilder(nlohmann::ordered_json& modules)
|
|||
|
||||
this->CreateStagedFrames("menus/common/download"_i18n + "Custom DeepSea package" + "menus/common/from"_i18n + request_url,
|
||||
request_url,
|
||||
"menus/ams_update/get_custom_deepsea"_i18n,
|
||||
this->erista);
|
||||
return true;
|
||||
});
|
||||
|
|
|
@ -249,6 +249,10 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
|
|||
verTitles.push_back("v2.19.3");
|
||||
changes.push_back("\uE016 Fix wrong bid for titles overriden by HBL.\n\uE016 Improve Korean localisation (https://github.com/DDinghoya).\n\uE016 Improve Italian localisation (https://github.com/clamintus).");
|
||||
|
||||
verTitles.push_back("v2.20.0");
|
||||
changes.push_back("\uE016 Significantly increase extraction speed (https://github.com/PoloNX).\n\uE016 Create a \"Custom Downloads\" tab that supports user-provided links for Atmosphère packs as well as regular downloads.");
|
||||
|
||||
|
||||
for (int i = verTitles.size() - 1; i >= 0; i--) {
|
||||
listItem = new brls::ListItem(verTitles[i]);
|
||||
change = changes[i];
|
||||
|
|
|
@ -53,9 +53,8 @@ namespace extract {
|
|||
return size; // in B
|
||||
}
|
||||
|
||||
void preWork(const std::string& archivePath, const std::string& workingPath)
|
||||
void ensureAvailableStorage(const std::string& archivePath)
|
||||
{
|
||||
chdir(workingPath.c_str());
|
||||
s64 uncompressedSize = getUncompressedSize(archivePath);
|
||||
s64 freeStorage;
|
||||
|
||||
|
@ -91,7 +90,7 @@ namespace extract {
|
|||
|
||||
void extract(const std::string& archivePath, const std::string& workingPath, int overwriteInis, std::function<void()> func)
|
||||
{
|
||||
preWork(archivePath, workingPath);
|
||||
ensureAvailableStorage(archivePath);
|
||||
|
||||
unzFile zfile = unzOpen(archivePath.c_str());
|
||||
unz_global_info gi;
|
||||
|
@ -107,28 +106,28 @@ namespace extract {
|
|||
char szFilename[0x301] = "";
|
||||
unzOpenCurrentFile(zfile);
|
||||
unzGetCurrentFileInfo(zfile, NULL, szFilename, sizeof(szFilename), NULL, 0, NULL, 0);
|
||||
std::string filename = szFilename;
|
||||
std::string filename = workingPath + szFilename;
|
||||
|
||||
if (ProgressEvent::instance().getInterupt()) {
|
||||
unzCloseCurrentFile(zfile);
|
||||
break;
|
||||
}
|
||||
if (appPath != workingPath + filename) {
|
||||
if ((overwriteInis == 0 && filename.substr(filename.length() - 4) == ".ini") || std::find_if(ignoreList.begin(), ignoreList.end(), [&filename, &workingPath](std::string ignored) {
|
||||
u8 res = (workingPath + filename).find(ignored);
|
||||
if (appPath != filename) {
|
||||
if ((overwriteInis == 0 && filename.substr(filename.length() - 4) == ".ini") || std::find_if(ignoreList.begin(), ignoreList.end(), [&filename](std::string ignored) {
|
||||
u8 res = (filename).find(ignored);
|
||||
return (res == 0 || res == 1); }) != ignoreList.end()) {
|
||||
if (!std::filesystem::exists(workingPath + filename)) {
|
||||
if (!std::filesystem::exists(filename)) {
|
||||
extractEntry(filename, zfile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((filename == "atmosphere/package3") || (filename == "atmosphere/stratosphere.romfs")) {
|
||||
if ((filename == "/atmosphere/package3") || (filename == "/atmosphere/stratosphere.romfs")) {
|
||||
extractEntry(filename + ".aio", zfile);
|
||||
}
|
||||
else {
|
||||
extractEntry(filename, zfile);
|
||||
if (filename.substr(0, 13) == "hekate_ctcaer") {
|
||||
fs::copyFile(workingPath + filename, UPDATE_BIN_PATH);
|
||||
fs::copyFile(filename, UPDATE_BIN_PATH);
|
||||
if (CurrentCfw::running_cfw == CFW::ams && util::showDialogBoxBlocking(fmt::format("menus/utils/set_hekate_reboot_payload"_i18n, UPDATE_BIN_PATH, REBOOT_PAYLOAD_PATH), "menus/common/yes"_i18n, "menus/common/no"_i18n) == 0) {
|
||||
fs::copyFile(UPDATE_BIN_PATH, REBOOT_PAYLOAD_PATH);
|
||||
}
|
||||
|
@ -235,7 +234,7 @@ namespace extract {
|
|||
|
||||
void extractCheats(const std::string& archivePath, const std::vector<std::string>& titles, CFW cfw, const std::string& version, bool extractAll)
|
||||
{
|
||||
preWork(archivePath, "/");
|
||||
ensureAvailableStorage(archivePath);
|
||||
|
||||
unzFile zfile = unzOpen(archivePath.c_str());
|
||||
unz_global_info gi;
|
||||
|
|
|
@ -41,20 +41,20 @@ MainFrame::MainFrame() : TabFrame()
|
|||
this->addTab("menus/main/about"_i18n, new AboutTab());
|
||||
|
||||
if (!util::getBoolValue(hideStatus, "atmosphere"))
|
||||
this->addTab("menus/main/update_ams"_i18n, new AmsTab(nxlinks, erista, util::getBoolValue(hideStatus, "atmosphereentries")));
|
||||
this->addTab("menus/main/update_ams"_i18n, new AmsTab(nxlinks, erista, false));
|
||||
|
||||
if (!util::getBoolValue(hideStatus, "cfw"))
|
||||
this->addTab("menus/main/update_bootloaders"_i18n, new ListDownloadTab(contentType::bootloaders, nxlinks));
|
||||
|
||||
if (!util::getBoolValue(hideStatus, "sigpatches"))
|
||||
this->addTab("menus/main/update_sigpatches"_i18n, new ListDownloadTab(contentType::sigpatches, nxlinks));
|
||||
|
||||
if (!util::getBoolValue(hideStatus, "firmwares"))
|
||||
this->addTab("menus/main/download_firmware"_i18n, new ListDownloadTab(contentType::fw, nxlinks));
|
||||
|
||||
if (!util::getBoolValue(hideStatus, "cheats"))
|
||||
this->addTab("menus/main/download_cheats"_i18n, new ListDownloadTab(contentType::cheats));
|
||||
|
||||
if (!util::getBoolValue(hideStatus, "custom"))
|
||||
this->addTab("menus/main/custom_downloads"_i18n, new AmsTab(nxlinks, erista, true));
|
||||
|
||||
if (!util::getBoolValue(hideStatus, "tools"))
|
||||
this->addTab("menus/main/tools"_i18n, new ToolsTab(tag, util::getValueFromKey(nxlinks, "payloads"), erista, hideStatus));
|
||||
|
||||
|
|
Loading…
Reference in a new issue