mirror of
https://github.com/HamletDuFromage/aio-switch-updater.git
synced 2024-12-29 10:56:01 +00:00
Allow offline extraction of cheats (https://github.com/HamletDuFromage/aio-switch-updater/issues/107), Fixed extraction of the the complete cheat archive (https://github.com/HamletDuFromage/aio-switch-updater/issues/163), Fixed display bug for cheats extraction (https://github.com/HamletDuFromage/aio-switch-updater/issues/164)
This commit is contained in:
parent
b0c4e6d1fd
commit
fbe876b050
9 changed files with 81 additions and 71 deletions
2
Makefile
2
Makefile
|
@ -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.16.1
|
APP_VERSION := 2.16.2
|
||||||
TARGET := $(notdir $(CURDIR))
|
TARGET := $(notdir $(CURDIR))
|
||||||
|
|
||||||
ROMFS := resources
|
ROMFS := resources
|
||||||
|
|
|
@ -31,8 +31,8 @@ namespace extract {
|
||||||
std::vector<std::string> getInstalledTitlesNs();
|
std::vector<std::string> getInstalledTitlesNs();
|
||||||
std::vector<std::string> excludeTitles(const std::string& path, const std::vector<std::string>& listedTitles);
|
std::vector<std::string> excludeTitles(const std::string& path, const std::vector<std::string>& listedTitles);
|
||||||
void writeTitlesToFile(const std::set<std::string>& titles, const std::string& path);
|
void writeTitlesToFile(const std::set<std::string>& titles, const std::string& path);
|
||||||
void extractCheats(const std::string& zipPath, std::vector<std::string> titles, CFW cfw, bool credits = false);
|
void extractCheats(const std::string& zipPath, const std::vector<std::string>& titles, CFW cfw, const std::string& version, bool extractAll = false);
|
||||||
void extractAllCheats(const std::string& zipPath, CFW cfw);
|
void extractAllCheats(const std::string& zipPath, CFW cfw, const std::string& version);
|
||||||
void removeCheats();
|
void removeCheats();
|
||||||
void removeOrphanedCheats();
|
void removeOrphanedCheats();
|
||||||
bool removeCheatsDirectory(const std::string& entry);
|
bool removeCheatsDirectory(const std::string& entry);
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace util {
|
||||||
bool isArchive(const std::string& path);
|
bool isArchive(const std::string& path);
|
||||||
void downloadArchive(const std::string& url, contentType type);
|
void downloadArchive(const std::string& url, contentType type);
|
||||||
void downloadArchive(const std::string& url, contentType type, long& status_code);
|
void downloadArchive(const std::string& url, contentType type, long& status_code);
|
||||||
void extractArchive(contentType type, const std::string& tag = "0");
|
void extractArchive(contentType type, const std::string& version = "");
|
||||||
std::string formatListItemTitle(const std::string& str, size_t maxScore = 140);
|
std::string formatListItemTitle(const std::string& str, size_t maxScore = 140);
|
||||||
std::string formatApplicationId(u64 ApplicationId);
|
std::string formatApplicationId(u64 ApplicationId);
|
||||||
std::vector<std::string> fetchPayloads();
|
std::vector<std::string> fetchPayloads();
|
||||||
|
@ -36,8 +36,9 @@ namespace util {
|
||||||
int showDialogBox(const std::string& text, const std::string& opt1, const std::string& opt2);
|
int showDialogBox(const std::string& text, const std::string& opt1, const std::string& opt2);
|
||||||
std::string getLatestTag(const std::string& url);
|
std::string getLatestTag(const std::string& url);
|
||||||
std::string downloadFileToString(const std::string& url);
|
std::string downloadFileToString(const std::string& url);
|
||||||
void saveVersion(const std::string& version, const std::string& path);
|
std::string getCheatsVersion();
|
||||||
std::string readVersion(const std::string& path);
|
void saveToFile(const std::string& text, const std::string& path);
|
||||||
|
std::string readFile(const std::string& path);
|
||||||
bool isErista();
|
bool isErista();
|
||||||
void removeSysmodulesFlags(const std::string& directory);
|
void removeSysmodulesFlags(const std::string& directory);
|
||||||
std::string lowerCase(const std::string& str);
|
std::string lowerCase(const std::string& str);
|
||||||
|
|
|
@ -217,6 +217,9 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
|
||||||
verTitles.push_back("v2.16.1");
|
verTitles.push_back("v2.16.1");
|
||||||
changes.push_back("\uE016 Updated Japanese localisation (https://github.com/yyoossk).\n\uE016 Updated German localisation (https://github.com/MSco).\n\uE016 Added ability to manually launch aiosu_rcm.bin.");
|
changes.push_back("\uE016 Updated Japanese localisation (https://github.com/yyoossk).\n\uE016 Updated German localisation (https://github.com/MSco).\n\uE016 Added ability to manually launch aiosu_rcm.bin.");
|
||||||
|
|
||||||
|
verTitles.push_back("v2.16.2");
|
||||||
|
changes.push_back("\uE016 Allow offline extraction of cheats.\n\uE016 Fixed extraction of the the complete cheat archive.\n\uE016 Fixed display bug for cheats extraction.");
|
||||||
|
|
||||||
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];
|
||||||
|
|
|
@ -53,31 +53,22 @@ CheatsPage::CheatsPage() : AppletFrame(true, true)
|
||||||
});
|
});
|
||||||
list->addView(item);
|
list->addView(item);
|
||||||
|
|
||||||
std::string cheatsVer = util::downloadFileToString(CHEATS_URL_VERSION);
|
std::string cheatsVer = util::getCheatsVersion();
|
||||||
if (cheatsVer != "") {
|
if (cheatsVer != "") {
|
||||||
item = new brls::ListItem("menus/cheats/dl_all"_i18n);
|
item = new brls::ListItem("menus/cheats/dl_all"_i18n);
|
||||||
item->getClickEvent()->subscribe([cheatsVer](brls::View* view) {
|
item->getClickEvent()->subscribe([cheatsVer](brls::View* view) {
|
||||||
std::string url;
|
std::string url = CurrentCfw::running_cfw == CFW::sxos ? CHEATS_URL_TITLES : CHEATS_URL_CONTENTS;
|
||||||
switch (CurrentCfw::running_cfw) {
|
|
||||||
case CFW::sxos:
|
|
||||||
url = CHEATS_URL_TITLES;
|
|
||||||
break;
|
|
||||||
case CFW::ams:
|
|
||||||
url = CHEATS_URL_CONTENTS;
|
|
||||||
break;
|
|
||||||
case CFW::rnx:
|
|
||||||
url = CHEATS_URL_CONTENTS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
std::string text(fmt::format("menus/main/get_cheats"_i18n, cheatsVer) + "menus/common/from"_i18n + url);
|
std::string text(fmt::format("menus/main/get_cheats"_i18n, cheatsVer) + "menus/common/from"_i18n + url);
|
||||||
brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame();
|
brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame();
|
||||||
stagedFrame->setTitle("menus/cheats/dl_all"_i18n);
|
stagedFrame->setTitle("menus/cheats/dl_all"_i18n);
|
||||||
stagedFrame->addStage(
|
stagedFrame->addStage(
|
||||||
new ConfirmPage(stagedFrame, text));
|
new ConfirmPage(stagedFrame, text));
|
||||||
|
if (cheatsVer != "offline") {
|
||||||
stagedFrame->addStage(
|
stagedFrame->addStage(
|
||||||
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [url]() { util::downloadArchive(url, contentType::cheats); }));
|
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [url]() { util::downloadArchive(url, contentType::cheats); }));
|
||||||
|
}
|
||||||
stagedFrame->addStage(
|
stagedFrame->addStage(
|
||||||
new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, []() { extract::extractAllCheats(CHEATS_ZIP_PATH, CurrentCfw::running_cfw); }));
|
new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, [cheatsVer]() { extract::extractAllCheats(CHEATS_ZIP_PATH, CurrentCfw::running_cfw, cheatsVer); }));
|
||||||
stagedFrame->addStage(
|
stagedFrame->addStage(
|
||||||
new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true));
|
new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true));
|
||||||
brls::Application::pushView(stagedFrame);
|
brls::Application::pushView(stagedFrame);
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "download.hpp"
|
|
||||||
#include "current_cfw.hpp"
|
#include "current_cfw.hpp"
|
||||||
|
#include "download.hpp"
|
||||||
#include "fs.hpp"
|
#include "fs.hpp"
|
||||||
#include "main_frame.hpp"
|
#include "main_frame.hpp"
|
||||||
#include "progress_event.hpp"
|
#include "progress_event.hpp"
|
||||||
|
@ -180,51 +180,57 @@ namespace extract {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void extractCheats(const std::string& zipPath, std::vector<std::string> titles, CFW cfw, bool credits)
|
void extractCheats(const std::string& zipPath, const std::vector<std::string>& titles, CFW cfw, const std::string& version, bool extractAll)
|
||||||
{
|
{
|
||||||
zipper::Unzipper unzipper(zipPath);
|
zipper::Unzipper unzipper(zipPath);
|
||||||
std::vector<zipper::ZipEntry> entries = unzipper.entries();
|
std::vector<zipper::ZipEntry> entries = unzipper.entries();
|
||||||
int offset = computeOffset(cfw);
|
int offset = computeOffset(cfw);
|
||||||
|
|
||||||
|
if (!extractAll) {
|
||||||
ProgressEvent::instance().setTotalSteps(titles.size() + 1);
|
ProgressEvent::instance().setTotalSteps(titles.size() + 1);
|
||||||
for (const auto& title : titles) {
|
for (const auto& title : titles) {
|
||||||
if (ProgressEvent::instance().getInterupt()) {
|
if (ProgressEvent::instance().getInterupt()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
auto matches = entries | std::views::filter([&title, offset](zipper::ZipEntry entry) {
|
auto matches = entries | std::views::filter([&title, offset](zipper::ZipEntry entry) {
|
||||||
|
if ((int)entry.name.size() > offset + 16 + 7) {
|
||||||
return caselessCompare((title.substr(0, 13)), entry.name.substr(offset, 13)) && caselessCompare(entry.name.substr(offset + 16, 7), "/cheats");
|
return caselessCompare((title.substr(0, 13)), entry.name.substr(offset, 13)) && caselessCompare(entry.name.substr(offset + 16, 7), "/cheats");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
for (const auto& match : matches) {
|
for (const auto& match : matches) {
|
||||||
unzipper.extractEntry(match.name);
|
unzipper.extractEntry(match.name);
|
||||||
|
}
|
||||||
ProgressEvent::instance().incrementStep(1);
|
ProgressEvent::instance().incrementStep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unzipper.close();
|
else {
|
||||||
download::downloadFile(CHEATS_URL_VERSION, CHEATS_VERSION, OFF);
|
|
||||||
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
|
|
||||||
}
|
|
||||||
|
|
||||||
void extractAllCheats(const std::string& zipPath, CFW cfw)
|
|
||||||
{
|
|
||||||
zipper::Unzipper unzipper(zipPath);
|
|
||||||
std::vector<zipper::ZipEntry> entries = unzipper.entries();
|
|
||||||
int offset = computeOffset(cfw);
|
|
||||||
|
|
||||||
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
|
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
|
||||||
for (const auto& entry : entries) {
|
for (const auto& entry : entries) {
|
||||||
if (ProgressEvent::instance().getInterupt()) {
|
if (ProgressEvent::instance().getInterupt()) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (((int)entry.name.size() == offset + 16 + 4) && (isBID(entry.name.substr(offset, 16)))) {
|
|
||||||
|
if ((int)entry.name.size() > offset + 16 + 7 && caselessCompare(entry.name.substr(offset + 16, 7), "/cheats")) {
|
||||||
unzipper.extractEntry(entry.name);
|
unzipper.extractEntry(entry.name);
|
||||||
}
|
}
|
||||||
ProgressEvent::instance().incrementStep(1);
|
ProgressEvent::instance().incrementStep(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
unzipper.close();
|
unzipper.close();
|
||||||
download::downloadFile(CHEATS_URL_VERSION, CHEATS_VERSION, OFF);
|
if (version != "offline" && version != "") {
|
||||||
|
util::saveToFile(version, CHEATS_VERSION);
|
||||||
|
}
|
||||||
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
|
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void extractAllCheats(const std::string& zipPath, CFW cfw, const std::string& version)
|
||||||
|
{
|
||||||
|
extractCheats(zipPath, {}, cfw, version, true);
|
||||||
|
}
|
||||||
|
|
||||||
bool isBID(const std::string& bid)
|
bool isBID(const std::string& bid)
|
||||||
{
|
{
|
||||||
for (char const& c : bid) {
|
for (char const& c : bid) {
|
||||||
|
|
|
@ -63,10 +63,10 @@ void ListDownloadTab::createList(contentType type)
|
||||||
stagedFrame->setTitle(fmt::format("menus/main/getting"_i18n, contentTypeNames[(int)type].data()));
|
stagedFrame->setTitle(fmt::format("menus/main/getting"_i18n, contentTypeNames[(int)type].data()));
|
||||||
stagedFrame->addStage(new ConfirmPage(stagedFrame, text));
|
stagedFrame->addStage(new ConfirmPage(stagedFrame, text));
|
||||||
if (type != contentType::payloads) {
|
if (type != contentType::payloads) {
|
||||||
if (type != contentType::cheats || this->newCheatsVer != this->currentCheatsVer || !std::filesystem::exists(CHEATS_ZIP_PATH)) {
|
if (type != contentType::cheats || (this->newCheatsVer != this->currentCheatsVer && this->newCheatsVer != "offline")) {
|
||||||
stagedFrame->addStage(new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [this, type, url]() { util::downloadArchive(url, type); }));
|
stagedFrame->addStage(new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [this, type, url]() { util::downloadArchive(url, type); }));
|
||||||
}
|
}
|
||||||
stagedFrame->addStage(new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, [this, type]() { util::extractArchive(type); }));
|
stagedFrame->addStage(new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, [this, type]() { util::extractArchive(type, this->newCheatsVer); }));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fs::createTree(BOOTLOADER_PL_PATH);
|
fs::createTree(BOOTLOADER_PL_PATH);
|
||||||
|
@ -143,8 +143,8 @@ void ListDownloadTab::setDescription(contentType type)
|
||||||
"menus/main/bootloaders_text"_i18n);
|
"menus/main/bootloaders_text"_i18n);
|
||||||
break;
|
break;
|
||||||
case contentType::cheats:
|
case contentType::cheats:
|
||||||
this->newCheatsVer = util::downloadFileToString(CHEATS_URL_VERSION);
|
this->newCheatsVer = util::getCheatsVersion();
|
||||||
this->currentCheatsVer = util::readVersion(CHEATS_VERSION);
|
this->currentCheatsVer = util::readFile(CHEATS_VERSION);
|
||||||
description->setText("menus/main/cheats_text"_i18n + this->currentCheatsVer);
|
description->setText("menus/main/cheats_text"_i18n + this->currentCheatsVer);
|
||||||
break;
|
break;
|
||||||
case contentType::payloads:
|
case contentType::payloads:
|
||||||
|
|
|
@ -37,7 +37,7 @@ ToolsTab::ToolsTab(const std::string& tag, const nlohmann::ordered_json& payload
|
||||||
stagedFrame->addStage(
|
stagedFrame->addStage(
|
||||||
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, []() { util::downloadArchive(APP_URL, contentType::app); }));
|
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, []() { util::downloadArchive(APP_URL, contentType::app); }));
|
||||||
stagedFrame->addStage(
|
stagedFrame->addStage(
|
||||||
new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, [tag]() { util::extractArchive(contentType::app, tag); }));
|
new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, [tag]() { util::extractArchive(contentType::app); }));
|
||||||
stagedFrame->addStage(
|
stagedFrame->addStage(
|
||||||
new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true));
|
new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true));
|
||||||
brls::Application::pushView(stagedFrame);
|
brls::Application::pushView(stagedFrame);
|
||||||
|
@ -48,7 +48,7 @@ ToolsTab::ToolsTab(const std::string& tag, const nlohmann::ordered_json& payload
|
||||||
|
|
||||||
cheats = new brls::ListItem("menus/tools/cheats"_i18n);
|
cheats = new brls::ListItem("menus/tools/cheats"_i18n);
|
||||||
cheats->getClickEvent()->subscribe([](brls::View* view) {
|
cheats->getClickEvent()->subscribe([](brls::View* view) {
|
||||||
brls::Application::pushView(new CheatsPage());
|
brls::PopupFrame::open("menus/cheats/menu"_i18n, new CheatsPage(), "", "");
|
||||||
});
|
});
|
||||||
cheats->setHeight(LISTITEM_HEIGHT);
|
cheats->setHeight(LISTITEM_HEIGHT);
|
||||||
|
|
||||||
|
@ -139,6 +139,7 @@ ToolsTab::ToolsTab(const std::string& tag, const nlohmann::ordered_json& payload
|
||||||
std::filesystem::remove(CFW_ZIP_PATH);
|
std::filesystem::remove(CFW_ZIP_PATH);
|
||||||
std::filesystem::remove(FW_ZIP_PATH);
|
std::filesystem::remove(FW_ZIP_PATH);
|
||||||
std::filesystem::remove(CHEATS_ZIP_PATH);
|
std::filesystem::remove(CHEATS_ZIP_PATH);
|
||||||
|
std::filesystem::remove(CHEATS_VERSION);
|
||||||
std::filesystem::remove(SIGPATCHES_ZIP_PATH);
|
std::filesystem::remove(SIGPATCHES_ZIP_PATH);
|
||||||
fs::removeDir(AMS_DIRECTORY_PATH);
|
fs::removeDir(AMS_DIRECTORY_PATH);
|
||||||
fs::removeDir(SEPT_DIRECTORY_PATH);
|
fs::removeDir(SEPT_DIRECTORY_PATH);
|
||||||
|
|
|
@ -140,7 +140,7 @@ namespace util {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void extractArchive(contentType type, const std::string& tag)
|
void extractArchive(contentType type, const std::string& version)
|
||||||
{
|
{
|
||||||
chdir(ROOT_PATH);
|
chdir(ROOT_PATH);
|
||||||
crashIfNotArchive(type);
|
crashIfNotArchive(type);
|
||||||
|
@ -151,7 +151,7 @@ namespace util {
|
||||||
case contentType::cheats: {
|
case contentType::cheats: {
|
||||||
std::vector<std::string> titles = extract::getInstalledTitlesNs();
|
std::vector<std::string> titles = extract::getInstalledTitlesNs();
|
||||||
titles = extract::excludeTitles(CHEATS_EXCLUDE, titles);
|
titles = extract::excludeTitles(CHEATS_EXCLUDE, titles);
|
||||||
extract::extractCheats(CHEATS_FILENAME, titles, CurrentCfw::running_cfw);
|
extract::extractCheats(CHEATS_FILENAME, titles, CurrentCfw::running_cfw, version);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case contentType::fw:
|
case contentType::fw:
|
||||||
|
@ -256,22 +256,30 @@ namespace util {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveVersion(const std::string& version, const std::string& path)
|
std::string getCheatsVersion()
|
||||||
{
|
{
|
||||||
std::ofstream newVersion(path);
|
std::string res = util::downloadFileToString(CHEATS_URL_VERSION);
|
||||||
newVersion << version << std::endl;
|
if (res == "" && isArchive(CHEATS_ZIP_PATH)) {
|
||||||
|
res = "offline";
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string readVersion(const std::string& path)
|
void saveToFile(const std::string& text, const std::string& path)
|
||||||
{
|
{
|
||||||
std::fstream versionFile;
|
std::ofstream file(path);
|
||||||
std::string version = "0";
|
file << text << std::endl;
|
||||||
if (std::filesystem::exists(path)) {
|
|
||||||
versionFile.open(path, std::fstream::in);
|
|
||||||
versionFile >> version;
|
|
||||||
versionFile.close();
|
|
||||||
}
|
}
|
||||||
return version;
|
|
||||||
|
std::string readFile(const std::string& path)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::string text = "";
|
||||||
|
std::ifstream file(path);
|
||||||
|
if (file.good()) {
|
||||||
|
file >> text;
|
||||||
|
}
|
||||||
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isErista()
|
bool isErista()
|
||||||
|
|
Loading…
Reference in a new issue