mirror of
https://github.com/HamletDuFromage/aio-switch-updater.git
synced 2024-12-28 18:36:02 +00:00
Made ini avoidance more robust, added a download payload option and cleaned stuff up
This commit is contained in:
parent
1b56d6f15a
commit
2feb6901d6
17 changed files with 150 additions and 61 deletions
2
Makefile
2
Makefile
|
@ -45,7 +45,7 @@ DATA := data
|
|||
INCLUDES := include lib/minizip/include
|
||||
APP_TITLE := AIO Switch Updater
|
||||
APP_AUTHOR := HamletDuFromage
|
||||
APP_VERSION := 1.0.3
|
||||
APP_VERSION := 1.1.0
|
||||
|
||||
#ROMFS := $(BUILD)/romfs
|
||||
BOREALIS_PATH := lib/borealis
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "JC_color_swapper.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "confirm_page.hpp"
|
||||
#include "worker_page.hpp"
|
||||
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
#include <borealis.hpp>
|
||||
#include <chrono>
|
||||
#include <algorithm>
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "download.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "main_frame.hpp"
|
||||
|
||||
class ConfirmPage : public brls::View
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#define CFW_URL "https://hamletdufromage.github.io/switch-cfw/cfw.html"
|
||||
#define CFW_FILENAME "/config/aio-switch-updater/cfw.zip"
|
||||
|
||||
#define PAYLOAD_URL "https://hamletdufromage.github.io/switch-payloads/payloads.html"
|
||||
|
||||
#define CHEATS_RELEASE_URL "https://github.com/HamletDuFromage/switch-cheats-db/releases/tag/v1.0"
|
||||
#define CHEATS_URL_TITLES "https://github.com/HamletDuFromage/switch-cheats-db/releases/download/v1.0/titles.zip"
|
||||
#define CHEATS_URL_CONTENTS "https://github.com/HamletDuFromage/switch-cheats-db/releases/download/v1.0/contents.zip"
|
||||
|
|
17
include/download_payload_page.hpp
Normal file
17
include/download_payload_page.hpp
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "confirm_page.hpp"
|
||||
#include "worker_page.hpp"
|
||||
|
||||
class DownloadPayloadPage : public brls::AppletFrame
|
||||
{
|
||||
private:
|
||||
brls::Label* label;
|
||||
brls::Label* notFound;
|
||||
brls::List* list;
|
||||
std::vector<brls::ListItem*> items;
|
||||
|
||||
public:
|
||||
DownloadPayloadPage();
|
||||
};
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "progress_event.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
static constexpr u32 MaxTitleCount = 64000;
|
||||
|
||||
|
@ -39,6 +38,7 @@ typedef struct Title {
|
|||
} Title;
|
||||
|
||||
void extract(const char* filename, const char* workingPath = ROOT_PATH, int overwriteInis = 1);
|
||||
void extract(const char * filename, const char* workingPath, const char* toExclude);
|
||||
std::string formatApplicationId(u64 ApplicationId);
|
||||
std::vector<Title> getInstalledTitlesNs();
|
||||
std::vector<Title> excludeTitles(const char* path, std::vector<Title> listedTitles);
|
||||
|
|
|
@ -4,15 +4,12 @@
|
|||
#include <string>
|
||||
#include "download.hpp"
|
||||
#include "extract.hpp"
|
||||
#include "constants.hpp"
|
||||
#include "confirm_page.hpp"
|
||||
#include "worker_page.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
class ListDownloadTab : public brls::List
|
||||
{
|
||||
private:
|
||||
std::tuple<std::vector<std::string>, std::vector<std::string>> links;
|
||||
std::vector<brls::ListItem*> linkItems;
|
||||
brls::Label *notFound;
|
||||
brls::Label *description;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include <borealis.hpp>
|
||||
|
||||
#include "utils.hpp"
|
||||
#include "about_tab.hpp"
|
||||
#include "list_download_tab.hpp"
|
||||
#include "tools_tab.hpp"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "worker_page.hpp"
|
||||
#include "app_page.hpp"
|
||||
#include "payload_page.hpp"
|
||||
#include "download_payload_page.hpp"
|
||||
#include "JC_page.hpp"
|
||||
#include "extract.hpp"
|
||||
#include "utils.hpp"
|
||||
|
@ -18,6 +19,7 @@ class ToolsTab : public brls::List
|
|||
brls::ListItem* JCcolor;
|
||||
brls::ListItem* updateApp;
|
||||
brls::ListItem* rebootPayload;
|
||||
brls::ListItem* downloadPaysload;
|
||||
brls::StagedAppletFrame* stagedFrame;
|
||||
|
||||
public:
|
||||
|
|
|
@ -23,4 +23,5 @@ std::string formatApplicationId(u64 ApplicationId);
|
|||
std::set<std::string> readLineByLine(const char * path);
|
||||
std::vector<std::string> fetchPayloads();
|
||||
void shut_down(bool reboot = false);
|
||||
int showDialogBox(std::string text, std::string opt1, std::string opt2);
|
||||
std::string getLatestTag(const char *url);
|
|
@ -1,5 +1,4 @@
|
|||
#include "confirm_page.hpp"
|
||||
#include <algorithm>
|
||||
|
||||
ConfirmPage::ConfirmPage(brls::StagedAppletFrame* frame, std::string text, bool done): done(done)
|
||||
{
|
||||
|
|
|
@ -174,7 +174,6 @@ std::string fetchTitle(const char *url){
|
|||
/* check for errors */
|
||||
std::string ver = "-1";
|
||||
std::string s = std::string(chunk.memory);
|
||||
//std::cout << "start html " << s.substr(0, 199) << std::endl;
|
||||
std::regex rgx("<title>.+</title>");
|
||||
std::smatch match;
|
||||
if (std::regex_search(s, match, rgx)){
|
||||
|
|
51
source/download_payload_page.cpp
Normal file
51
source/download_payload_page.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include "download_payload_page.hpp"
|
||||
|
||||
DownloadPayloadPage::DownloadPayloadPage() : AppletFrame(true, true)
|
||||
{
|
||||
this->setTitle("Download payloads");
|
||||
list = new brls::List();
|
||||
label = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"Select a payload to download to " + std::string(BOOTLOADER_PL_PATH) + ".",
|
||||
true
|
||||
);
|
||||
list->addView(label);
|
||||
std::tuple<std::vector<std::string>, std::vector<std::string>> links = fetchLinks(PAYLOAD_URL);
|
||||
int nbLinks = std::get<0>(links).size();
|
||||
if(nbLinks){
|
||||
items.reserve(nbLinks);
|
||||
for (int i = 0; i<nbLinks; i++){
|
||||
std::string url = std::get<1>(links)[i];
|
||||
std::string path = std::string(BOOTLOADER_PL_PATH) + std::get<0>(links)[i];
|
||||
std::string text("Downloading:\n" + std::get<0>(links)[i] + "\n\nFrom:\n" + url);
|
||||
items[i] = new brls::ListItem(std::get<0>(links)[i]);
|
||||
items[i]->getClickEvent()->subscribe([&, text, url, path](brls::View* view) {
|
||||
createTree(BOOTLOADER_PL_PATH);
|
||||
brls::StagedAppletFrame* stagedFrame = new brls::StagedAppletFrame();
|
||||
stagedFrame->setTitle("Getting payload");
|
||||
stagedFrame->addStage(
|
||||
new ConfirmPage(stagedFrame, text)
|
||||
);
|
||||
stagedFrame->addStage(
|
||||
new WorkerPage(stagedFrame, "Downloading...", [url, path](){downloadFile(url.c_str(), path.c_str(), OFF);})
|
||||
);
|
||||
stagedFrame->addStage(
|
||||
new ConfirmPage(stagedFrame, "All done!", true)
|
||||
);
|
||||
brls::Application::pushView(stagedFrame);
|
||||
});
|
||||
list->addView(items[i]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
notFound = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"Could not find a download link, make sure the Switch has access to the internet.\n"\
|
||||
"If this problem persists, please open an issue on Github",
|
||||
true
|
||||
);
|
||||
notFound->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
list->addView(notFound);
|
||||
}
|
||||
this->setContentView(list);
|
||||
}
|
|
@ -9,8 +9,12 @@ void extract(const char * filename, const char* workingPath, int overwriteInis){
|
|||
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
|
||||
for (int i = 0; i < (int) entries.size(); i++){
|
||||
if(overwriteInis == 0){
|
||||
if(entries[i].name.substr(entries[i].name.length() - 4) != ".ini")
|
||||
if(entries[i].name.substr(entries[i].name.length() - 4) == ".ini"){
|
||||
if(!std::filesystem::exists("/" + entries[i].name)) unzipper.extractEntry(entries[i].name);
|
||||
}
|
||||
else{
|
||||
unzipper.extractEntry(entries[i].name);
|
||||
}
|
||||
}
|
||||
else
|
||||
unzipper.extractEntry(entries[i].name);
|
||||
|
@ -21,6 +25,28 @@ void extract(const char * filename, const char* workingPath, int overwriteInis){
|
|||
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
|
||||
}
|
||||
|
||||
void extract(const char * filename, const char* workingPath, const char* toExclude){
|
||||
ProgressEvent::instance().reset();
|
||||
ProgressEvent::instance().setStep(1);
|
||||
chdir(workingPath);
|
||||
zipper::Unzipper unzipper(filename);
|
||||
std::vector<zipper::ZipEntry> entries = unzipper.entries();
|
||||
ProgressEvent::instance().setTotalSteps(entries.size() + 1);
|
||||
for (int i = 0; i < (int) entries.size(); i++){
|
||||
if("/" + entries[i].name == toExclude){
|
||||
if(!std::filesystem::exists(toExclude)) {
|
||||
unzipper.extractEntry(entries[i].name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unzipper.extractEntry(entries[i].name);
|
||||
}
|
||||
|
||||
ProgressEvent::instance().setStep(i);
|
||||
}
|
||||
unzipper.close();
|
||||
ProgressEvent::instance().setStep(ProgressEvent::instance().getMax());
|
||||
}
|
||||
|
||||
std::vector<Title> getInstalledTitlesNs(){
|
||||
// This function has been cobbled together from the "app_controldata" example in devkitpro.
|
||||
|
@ -76,7 +102,6 @@ std::vector<Title> getInstalledTitlesNs(){
|
|||
|
||||
if (R_FAILED(rc)) {
|
||||
totalFailed++;
|
||||
std::cout << "nsGetApplicationControlData() failed: 0x" << std::hex << rc << " for Title ID: " << formatApplicationId(recs[i].application_id) << std::endl;
|
||||
}
|
||||
|
||||
if (outsize < sizeof(buf->nacp)) {
|
||||
|
@ -165,17 +190,20 @@ void extractCheats(const char * zipPath, std::vector<Title> titles, CFW cfw, boo
|
|||
switch(cfw){
|
||||
case ams:
|
||||
offset = std::string(CONTENTS_PATH).length();
|
||||
createTree(AMS_CONTENTS);
|
||||
std::filesystem::create_directory(AMS_PATH);
|
||||
std::filesystem::create_directory(AMS_CONTENTS);
|
||||
chdir(AMS_PATH);
|
||||
break;
|
||||
case rnx:
|
||||
offset = std::string(CONTENTS_PATH).length();
|
||||
createTree(REINX_CONTENTS);
|
||||
std::filesystem::create_directory(REINX_PATH);
|
||||
std::filesystem::create_directory(REINX_CONTENTS);
|
||||
chdir(REINX_PATH);
|
||||
break;
|
||||
case sxos:
|
||||
offset = std::string(TITLES_PATH).length();
|
||||
createTree(SXOS_TITLES);
|
||||
std::filesystem::create_directory(SXOS_PATH);
|
||||
std::filesystem::create_directory(SXOS_TITLES);
|
||||
chdir(SXOS_PATH);
|
||||
break;
|
||||
}
|
||||
|
@ -217,11 +245,6 @@ void extractCheats(const char * zipPath, std::vector<Title> titles, CFW cfw, boo
|
|||
k++;
|
||||
}
|
||||
}
|
||||
brls::Logger::debug("Titles size:");
|
||||
std::cout << titles.size() << std::endl;
|
||||
|
||||
brls::Logger::debug("Parents size:");
|
||||
std::cout << parents.size() << std::endl;
|
||||
|
||||
size_t lastL = 0;
|
||||
std::string name;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
ListDownloadTab::ListDownloadTab(archiveType type) :
|
||||
brls::List()
|
||||
{
|
||||
std::tuple<std::vector<std::string>, std::vector<std::string>> links;
|
||||
std::string operation = "Getting ";
|
||||
this->description = new brls::Label(brls::LabelStyle::DESCRIPTION, "", true);
|
||||
switch(type){
|
||||
|
@ -89,13 +90,13 @@ ListDownloadTab::ListDownloadTab(archiveType type) :
|
|||
}
|
||||
else{
|
||||
notFound = new brls::Label(
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"Could not find a download link, make sure the Switch has access to the internet.\n"\
|
||||
"If this problem persists, please open an issue on Github",
|
||||
true
|
||||
);
|
||||
notFound->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
this->addView(notFound);
|
||||
brls::LabelStyle::DESCRIPTION,
|
||||
"Could not find a download link, make sure the Switch has access to the internet.\n"\
|
||||
"If this problem persists, please open an issue on Github",
|
||||
true
|
||||
);
|
||||
notFound->setHorizontalAlign(NVG_ALIGN_CENTER);
|
||||
this->addView(notFound);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -31,6 +31,18 @@ ToolsTab::ToolsTab() : brls::List()
|
|||
});
|
||||
this->addView(JCcolor);
|
||||
|
||||
downloadPaysload = new brls::ListItem("Dowload payloads to " + std::string(BOOTLOADER_PL_PATH));
|
||||
downloadPaysload->getClickEvent()->subscribe([&](brls::View* view){
|
||||
brls::Application::pushView(new DownloadPayloadPage());
|
||||
});
|
||||
this->addView(downloadPaysload);
|
||||
|
||||
rebootPayload = new brls::ListItem("Shut down / Inject payload");
|
||||
rebootPayload->getClickEvent()->subscribe([&](brls::View* view){
|
||||
brls::Application::pushView(new PayloadPage());
|
||||
});
|
||||
this->addView(rebootPayload);
|
||||
|
||||
std::string tag = getLatestTag(TAGS_INFO);
|
||||
if(!tag.empty()){
|
||||
updateApp = new brls::ListItem("Update the app (v" + tag +")");
|
||||
|
@ -54,11 +66,4 @@ ToolsTab::ToolsTab() : brls::List()
|
|||
});
|
||||
this->addView(updateApp);
|
||||
}
|
||||
|
||||
rebootPayload = new brls::ListItem("Shut down / Inject payload");
|
||||
rebootPayload->getClickEvent()->subscribe([&](brls::View* view){
|
||||
brls::Application::pushView(new PayloadPage());
|
||||
});
|
||||
this->addView(rebootPayload);
|
||||
|
||||
}
|
|
@ -75,40 +75,41 @@ void downloadArchive(std::string url, archiveType type){
|
|||
|
||||
int dialogResult = -1;
|
||||
|
||||
void extractArchive(archiveType type){
|
||||
int overwriteInis = -1;
|
||||
std::vector<Title> titles;
|
||||
brls::Dialog* dialog = new brls::Dialog("Do you want to overwrite existing .ini files?");
|
||||
brls::GenericEvent::Callback noCallback = [dialog](brls::View* view) {
|
||||
int showDialogBox(std::string text, std::string opt1, std::string opt2){
|
||||
int result = -1;
|
||||
brls::Dialog* dialog = new brls::Dialog(text);
|
||||
brls::GenericEvent::Callback callback1 = [dialog](brls::View* view) {
|
||||
dialogResult = 0;
|
||||
dialog->close();
|
||||
};
|
||||
brls::GenericEvent::Callback yesCallback = [dialog](brls::View* view) {
|
||||
brls::GenericEvent::Callback callback2 = [dialog](brls::View* view) {
|
||||
dialogResult = 1;
|
||||
dialog->close();
|
||||
};
|
||||
dialog->addButton("No", noCallback);
|
||||
dialog->addButton("Yes", yesCallback);
|
||||
dialog->addButton(opt1, callback1);
|
||||
dialog->addButton(opt2, callback2);
|
||||
dialog->setCancelable(false);
|
||||
dialog->open();
|
||||
while(result == -1){
|
||||
usleep(1);
|
||||
result = dialogResult;
|
||||
}
|
||||
dialogResult = -1;
|
||||
return result;
|
||||
}
|
||||
|
||||
void extractArchive(archiveType type){
|
||||
int overwriteInis = 0;
|
||||
std::vector<Title> titles;
|
||||
switch(type){
|
||||
case sigpatches:
|
||||
if(isArchive(SIGPATCHES_FILENAME)) {
|
||||
std::string backup(HEKATE_IPL_PATH);
|
||||
backup += ".old";
|
||||
if(std::filesystem::exists(HEKATE_IPL_PATH)){
|
||||
dialog->open();
|
||||
while(overwriteInis == -1){
|
||||
usleep(1);
|
||||
overwriteInis = dialogResult;
|
||||
}
|
||||
dialogResult = -1;
|
||||
overwriteInis = showDialogBox("Do you want to overwrite existing " + std::string(HEKATE_IPL_PATH) +"?", "No", "Yes");
|
||||
if(overwriteInis == 0){
|
||||
std::filesystem::remove(backup);
|
||||
std::filesystem::rename(HEKATE_IPL_PATH, backup);
|
||||
extract(SIGPATCHES_FILENAME);
|
||||
std::filesystem::remove(HEKATE_IPL_PATH);
|
||||
std::filesystem::rename(backup, HEKATE_IPL_PATH);
|
||||
extract(SIGPATCHES_FILENAME, ROOT_PATH, HEKATE_IPL_PATH);
|
||||
}
|
||||
else{
|
||||
extract(SIGPATCHES_FILENAME);
|
||||
|
@ -133,12 +134,7 @@ void extractArchive(archiveType type){
|
|||
extract(APP_FILENAME);
|
||||
break;
|
||||
case cfw:
|
||||
dialog->open();
|
||||
while(overwriteInis == -1){
|
||||
usleep(1);
|
||||
overwriteInis = dialogResult;
|
||||
}
|
||||
dialogResult = -1;
|
||||
overwriteInis = showDialogBox("Do you want to overwrite existing .ini config files?", "No", "Yes");
|
||||
extract(CFW_FILENAME, ROOT_PATH, overwriteInis);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue