mirror of
https://github.com/HamletDuFromage/aio-switch-updater.git
synced 2024-12-28 02:16:03 +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
|
||||
APP_TITLE := All-in-One Switch Updater
|
||||
APP_AUTHOR := HamletDuFromage
|
||||
APP_VERSION := 2.16.1
|
||||
APP_VERSION := 2.16.2
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
|
||||
ROMFS := resources
|
||||
|
|
|
@ -31,8 +31,8 @@ namespace extract {
|
|||
std::vector<std::string> getInstalledTitlesNs();
|
||||
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 extractCheats(const std::string& zipPath, std::vector<std::string> titles, CFW cfw, bool credits = false);
|
||||
void extractAllCheats(const std::string& zipPath, CFW cfw);
|
||||
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, const std::string& version);
|
||||
void removeCheats();
|
||||
void removeOrphanedCheats();
|
||||
bool removeCheatsDirectory(const std::string& entry);
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace util {
|
|||
bool isArchive(const std::string& path);
|
||||
void downloadArchive(const std::string& url, contentType type);
|
||||
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 formatApplicationId(u64 ApplicationId);
|
||||
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);
|
||||
std::string getLatestTag(const std::string& url);
|
||||
std::string downloadFileToString(const std::string& url);
|
||||
void saveVersion(const std::string& version, const std::string& path);
|
||||
std::string readVersion(const std::string& path);
|
||||
std::string getCheatsVersion();
|
||||
void saveToFile(const std::string& text, const std::string& path);
|
||||
std::string readFile(const std::string& path);
|
||||
bool isErista();
|
||||
void removeSysmodulesFlags(const std::string& directory);
|
||||
std::string lowerCase(const std::string& str);
|
||||
|
|
|
@ -217,6 +217,9 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
|
|||
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.");
|
||||
|
||||
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--) {
|
||||
listItem = new brls::ListItem(verTitles[i]);
|
||||
change = changes[i];
|
||||
|
|
|
@ -53,31 +53,22 @@ CheatsPage::CheatsPage() : AppletFrame(true, true)
|
|||
});
|
||||
list->addView(item);
|
||||
|
||||
std::string cheatsVer = util::downloadFileToString(CHEATS_URL_VERSION);
|
||||
std::string cheatsVer = util::getCheatsVersion();
|
||||
if (cheatsVer != "") {
|
||||
item = new brls::ListItem("menus/cheats/dl_all"_i18n);
|
||||
item->getClickEvent()->subscribe([cheatsVer](brls::View* view) {
|
||||
std::string url;
|
||||
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 url = CurrentCfw::running_cfw == CFW::sxos ? CHEATS_URL_TITLES : CHEATS_URL_CONTENTS;
|
||||
std::string text(fmt::format("menus/main/get_cheats"_i18n, cheatsVer) + "menus/common/from"_i18n + url);
|
||||
brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame();
|
||||
stagedFrame->setTitle("menus/cheats/dl_all"_i18n);
|
||||
stagedFrame->addStage(
|
||||
new ConfirmPage(stagedFrame, text));
|
||||
if (cheatsVer != "offline") {
|
||||
stagedFrame->addStage(
|
||||
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [url]() { util::downloadArchive(url, contentType::cheats); }));
|
||||
}
|
||||
stagedFrame->addStage(
|
||||
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, [url]() { util::downloadArchive(url, contentType::cheats); }));
|
||||
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(
|
||||
new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true));
|
||||
brls::Application::pushView(stagedFrame);
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "download.hpp"
|
||||
#include "current_cfw.hpp"
|
||||
#include "download.hpp"
|
||||
#include "fs.hpp"
|
||||
#include "main_frame.hpp"
|
||||
#include "progress_event.hpp"
|
||||
|
@ -180,49 +180,55 @@ namespace extract {
|
|||
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);
|
||||
std::vector<zipper::ZipEntry> entries = unzipper.entries();
|
||||
int offset = computeOffset(cfw);
|
||||
|
||||
ProgressEvent::instance().setTotalSteps(titles.size() + 1);
|
||||
for (const auto& title : titles) {
|
||||
if (ProgressEvent::instance().getInterupt()) {
|
||||
break;
|
||||
if (!extractAll) {
|
||||
ProgressEvent::instance().setTotalSteps(titles.size() + 1);
|
||||
for (const auto& title : titles) {
|
||||
if (ProgressEvent::instance().getInterupt()) {
|
||||
break;
|
||||
}
|
||||
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");
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
for (const auto& match : matches) {
|
||||
unzipper.extractEntry(match.name);
|
||||
}
|
||||
ProgressEvent::instance().incrementStep(1);
|
||||
}
|
||||
auto matches = entries | std::views::filter([&title, offset](zipper::ZipEntry entry) {
|
||||
return caselessCompare((title.substr(0, 13)), entry.name.substr(offset, 13)) && caselessCompare(entry.name.substr(offset + 16, 7), "/cheats");
|
||||
});
|
||||
for (const auto& match : matches) {
|
||||
unzipper.extractEntry(match.name);
|
||||
}
|
||||
else {
|
||||
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
|
||||
for (const auto& entry : entries) {
|
||||
if (ProgressEvent::instance().getInterupt()) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ((int)entry.name.size() > offset + 16 + 7 && caselessCompare(entry.name.substr(offset + 16, 7), "/cheats")) {
|
||||
unzipper.extractEntry(entry.name);
|
||||
}
|
||||
ProgressEvent::instance().incrementStep(1);
|
||||
}
|
||||
}
|
||||
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());
|
||||
}
|
||||
|
||||
void extractAllCheats(const std::string& zipPath, CFW cfw)
|
||||
void extractAllCheats(const std::string& zipPath, CFW cfw, const std::string& version)
|
||||
{
|
||||
zipper::Unzipper unzipper(zipPath);
|
||||
std::vector<zipper::ZipEntry> entries = unzipper.entries();
|
||||
int offset = computeOffset(cfw);
|
||||
|
||||
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
|
||||
for (const auto& entry : entries) {
|
||||
if (ProgressEvent::instance().getInterupt()) {
|
||||
break;
|
||||
}
|
||||
if (((int)entry.name.size() == offset + 16 + 4) && (isBID(entry.name.substr(offset, 16)))) {
|
||||
unzipper.extractEntry(entry.name);
|
||||
}
|
||||
ProgressEvent::instance().incrementStep(1);
|
||||
}
|
||||
unzipper.close();
|
||||
download::downloadFile(CHEATS_URL_VERSION, CHEATS_VERSION, OFF);
|
||||
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
|
||||
extractCheats(zipPath, {}, cfw, version, true);
|
||||
}
|
||||
|
||||
bool isBID(const std::string& bid)
|
||||
|
|
|
@ -63,10 +63,10 @@ void ListDownloadTab::createList(contentType type)
|
|||
stagedFrame->setTitle(fmt::format("menus/main/getting"_i18n, contentTypeNames[(int)type].data()));
|
||||
stagedFrame->addStage(new ConfirmPage(stagedFrame, text));
|
||||
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/extracting"_i18n, [this, type]() { util::extractArchive(type); }));
|
||||
stagedFrame->addStage(new WorkerPage(stagedFrame, "menus/common/extracting"_i18n, [this, type]() { util::extractArchive(type, this->newCheatsVer); }));
|
||||
}
|
||||
else {
|
||||
fs::createTree(BOOTLOADER_PL_PATH);
|
||||
|
@ -143,8 +143,8 @@ void ListDownloadTab::setDescription(contentType type)
|
|||
"menus/main/bootloaders_text"_i18n);
|
||||
break;
|
||||
case contentType::cheats:
|
||||
this->newCheatsVer = util::downloadFileToString(CHEATS_URL_VERSION);
|
||||
this->currentCheatsVer = util::readVersion(CHEATS_VERSION);
|
||||
this->newCheatsVer = util::getCheatsVersion();
|
||||
this->currentCheatsVer = util::readFile(CHEATS_VERSION);
|
||||
description->setText("menus/main/cheats_text"_i18n + this->currentCheatsVer);
|
||||
break;
|
||||
case contentType::payloads:
|
||||
|
|
|
@ -37,7 +37,7 @@ ToolsTab::ToolsTab(const std::string& tag, const nlohmann::ordered_json& payload
|
|||
stagedFrame->addStage(
|
||||
new WorkerPage(stagedFrame, "menus/common/downloading"_i18n, []() { util::downloadArchive(APP_URL, contentType::app); }));
|
||||
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(
|
||||
new ConfirmPage(stagedFrame, "menus/common/all_done"_i18n, true));
|
||||
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->getClickEvent()->subscribe([](brls::View* view) {
|
||||
brls::Application::pushView(new CheatsPage());
|
||||
brls::PopupFrame::open("menus/cheats/menu"_i18n, new CheatsPage(), "", "");
|
||||
});
|
||||
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(FW_ZIP_PATH);
|
||||
std::filesystem::remove(CHEATS_ZIP_PATH);
|
||||
std::filesystem::remove(CHEATS_VERSION);
|
||||
std::filesystem::remove(SIGPATCHES_ZIP_PATH);
|
||||
fs::removeDir(AMS_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);
|
||||
crashIfNotArchive(type);
|
||||
|
@ -151,7 +151,7 @@ namespace util {
|
|||
case contentType::cheats: {
|
||||
std::vector<std::string> titles = extract::getInstalledTitlesNs();
|
||||
titles = extract::excludeTitles(CHEATS_EXCLUDE, titles);
|
||||
extract::extractCheats(CHEATS_FILENAME, titles, CurrentCfw::running_cfw);
|
||||
extract::extractCheats(CHEATS_FILENAME, titles, CurrentCfw::running_cfw, version);
|
||||
break;
|
||||
}
|
||||
case contentType::fw:
|
||||
|
@ -256,22 +256,30 @@ namespace util {
|
|||
return str;
|
||||
}
|
||||
|
||||
void saveVersion(const std::string& version, const std::string& path)
|
||||
std::string getCheatsVersion()
|
||||
{
|
||||
std::ofstream newVersion(path);
|
||||
newVersion << version << std::endl;
|
||||
std::string res = util::downloadFileToString(CHEATS_URL_VERSION);
|
||||
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::string version = "0";
|
||||
if (std::filesystem::exists(path)) {
|
||||
versionFile.open(path, std::fstream::in);
|
||||
versionFile >> version;
|
||||
versionFile.close();
|
||||
std::ofstream file(path);
|
||||
file << text << std::endl;
|
||||
}
|
||||
|
||||
std::string readFile(const std::string& path)
|
||||
{
|
||||
|
||||
std::string text = "";
|
||||
std::ifstream file(path);
|
||||
if (file.good()) {
|
||||
file >> text;
|
||||
}
|
||||
return version;
|
||||
return text;
|
||||
}
|
||||
|
||||
bool isErista()
|
||||
|
|
Loading…
Reference in a new issue