1
0
Fork 0
mirror of https://github.com/HamletDuFromage/aio-switch-updater.git synced 2024-10-18 02:21:43 +01:00

Added internet settings editor and web browser

This commit is contained in:
flb 2021-01-03 00:22:45 +01:00
parent 2ed12fa1e3
commit 12147ff18f
17 changed files with 443 additions and 13 deletions

2
.gitignore vendored
View file

@ -1,4 +1,4 @@
.vscode/
#.vscode/
build/
screenshots/
switch/

24
.vscode/c_cpp_properties.json vendored Normal file
View file

@ -0,0 +1,24 @@
{
"configurations": [
{
"name": "DKP Aarch64",
"includePath": [
"${workspaceFolder}/**",
"${DEVKITPRO}/devkitA64/include/**",
"${DEVKITPRO}/devkitA64/aarch64-none-elf/include/**",
"${DEVKITPRO}/libnx/include/**",
"${DEVKITPRO}/portlibs/switch/include/**"
],
"defines": [
"DEBUG",
"SWITCH",
"__SWITCH__"
],
"compilerPath": "${DEVKITPRO}/devkitA64/bin/aarch64-none-elf-g++",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
}

74
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,74 @@
{
"files.associations": {
"sstream": "cpp",
"format": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"regex": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"new": "cpp",
"ostream": "cpp",
"ranges": "cpp",
"shared_mutex": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"buffer": "cpp",
"internet": "cpp",
"socket": "cpp",
"variant": "cpp"
}
}

View file

@ -45,7 +45,7 @@ DATA := data
INCLUDES := include lib/zipper/include
APP_TITLE := All-in-One Switch Updater
APP_AUTHOR := HamletDuFromage
APP_VERSION := 1.3.2
APP_VERSION := 1.4.0
TARGET := $(notdir $(CURDIR))-v$(APP_VERSION)
ROMFS := resources

View file

@ -36,6 +36,8 @@ Downloads and extracts daily-updated cheat code. The program will only extract c
- Change software color scheme of Joy-Cons. Additional color profiles can be found in the releases and should be copied to `config/aio-switch-updater/jc_profiles.json`.
- Change software color scheme of Pro controllers (has to be paired as Player 1). Additional color profiles can be found in the releases and should be copied to `config/aio-switch-updater/pc_profiles.json`.
- View which of your games got cheat codes from the app.
- Launch the Switch's web browser.
- Edit internet settings (DNS, IP address, MTU, etc). Add you own configs to `config/aio-switch-updater/internet.json`. You can find a template in the root of the repo.
## Screenshots
![ss](https://user-images.githubusercontent.com/61667930/93691403-30fb2e80-fad4-11ea-9701-7992a1de53e0.jpg)

View file

@ -37,6 +37,7 @@
#define CHEATS_FILENAME "/config/aio-switch-updater/cheats.zip"
#define CHEATS_EXCLUDE "/config/aio-switch-updater/exclude.txt"
#define FILES_IGNORE "/config/aio-switch-updater/preserve.txt"
#define INTERNET_JSON "/config/aio-switch-updater/internet.json"
#define UPDATED_TITLES_PATH "/config/aio-switch-updater/updated.dat"
#define CHEATS_VERSION "/config/aio-switch-updater/cheats_version.dat"
#define AMS_CONTENTS "/atmosphere/contents/"

28
include/net_page.hpp Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include <borealis.hpp>
#include <switch.h>
#include <json.hpp>
#include "constants.hpp"
#include "main_frame.hpp"
#include <fstream>
#include <filesystem>
#include <tuple>
#include <iomanip>
#define AF_INET 2
class NetPage : public brls::AppletFrame
{
private:
brls::List* list;
brls::Label* label;
std::vector<brls::ListItem*> listItems;
brls::ListItem* cancel;
public:
NetPage();
std::string ipToString(u8* ip);
int stringToIp(std::string ip, u8* out);
};

View file

@ -10,6 +10,7 @@
#include "language_option_page.hpp"
#include "JC_page.hpp"
#include "PC_page.hpp"
#include "net_page.hpp"
#include "extract.hpp"
#include "utils.hpp"
//#include "ntcp.hpp"
@ -27,6 +28,8 @@ class ToolsTab : public brls::List
brls::ListItem* language;
brls::ListItem* cleanUp;
brls::ListItem* ntcp;
brls::ListItem* netSettings;
brls::ListItem* browser;
brls::StagedAppletFrame* stagedFrame;

14
internet.json Normal file
View file

@ -0,0 +1,14 @@
[
{
"ip_addr": "10.13.222.222",
"subnet_mask": "255.255.0.0",
"gateway": "10.13.37.1",
"mtu": 1500,
"name": "ACNH lan-play"
},
{
"dns1": "1.1.1.1",
"dns2": "1.0.0.1",
"name": "Cloudfare DNS"
}
]

View file

@ -3,5 +3,15 @@
"BODY": "2d2d2d",
"BTN": "e6e6e6",
"name": "Default black"
},
{
"BODY": "82FF96",
"BTN": "0A1E0A",
"name": "ACNH green"
},
{
"BODY": "96F5F5",
"BTN": "0A1E28",
"name": "ACNH blue"
}
]

View file

@ -6,7 +6,7 @@
"app_page.cpp":"",
"app_title": "Installed cheats",
"app_label": "The following titles have recieved cheat code updates the last time you used the app. Please note that despite having been downloaded for a game, cheats may not match its current update.",
"app_label": "The following titles have received cheat code updates the last time you used the app. Please note that despite having been downloaded for a game, cheats may not match its current update.",
"text_download": "Downloading:\nLatest cheat codes\n\nFrom:\n",
"text_download_list": "Download latest cheat codes",
"text_title": "Getting cheat codes",
@ -48,6 +48,8 @@
"v1_3_1_text": "\uE016 Small fixes for bugs causing hangs.",
"v1_3_2": "v1.3.2",
"v1_3_2_text": "\uE016 Added ability to change the internet color of Pro controllers.\n\uE016 Added the ability to preserve specific files when updating.\n\uE016 Added the ability to clean up downloaded archives.",
"v1_4_0": "v1.4.0",
"v1_4_0_text": "\uE016 Added possibility to use pre-set network settings. Add your own in `config/aio-switch-updater/internet.json.\n\uE016 Added web browser.",
"Ok_button": "Ok",
"cheats_page.cpp":"",
@ -99,6 +101,7 @@
"jc_change": "Changing color. Make sure the Joy-Con are docked. If the process hangs, try docking/undocking the JCs.",
"jc_all_": "All done! You may need to dock/undock your Joy-Cons for the change to take effect.",
"pro_con": "Pro-Con color swapper",
"pc_you_can" : "You can change the internal color of your Pro controller. Make sure it's set to Player 1.",
"pc_color": "Pro controller color swapper",
"pc_backing": "Backing up the color profile",
@ -162,6 +165,8 @@
"tool_all_done": " All done!",
"tool_changelog": "Changelog",
"tool_cleanUp": "Clean up downloaded files",
"tool_net_settings": "Edit internet settings",
"tool_browser": "Web Brower",
"utils.cpp":"",
"utils_because": "Because of the size of the FW archive, downloading firmwares in Applet Mode is not supported. Please launch the app with full RAM access.",
@ -177,7 +182,12 @@
"reboot_rcm" : "The Switch will now launch reboot to a special payload in order to finalise the install.",
"hekate_dialogue" : "Do you want to also download Hekate?\nIf not, the Switch will now launch reboot to a special payload in order to finalise the install.",
"Yes" : "Yes",
"No" : "No"
"No" : "No",
"go_back" : "Go back",
"Confirm_button" : "Confirm",
"Cancel_button" : "Cancel"
}

View file

@ -4,7 +4,7 @@ namespace i18n = brls::i18n;
using namespace i18n::literals;
PCPage::PCPage() : AppletFrame(true, true)
{
this->setTitle("menus/joy_con"_i18n );
this->setTitle("menus/pro_con"_i18n );
list = new brls::List();
std::string labelText = "menus/pc_you_can"_i18n;
label = new brls::Label(brls::LabelStyle::DESCRIPTION, labelText, true);

View file

@ -58,6 +58,9 @@ ChangelogPage::ChangelogPage() : AppletFrame(true, true)
verTitles.push_back("menus/v1_3_2"_i18n );
changes.push_back("menus/v1_3_2_text"_i18n );
verTitles.push_back("menus/v1_4_0"_i18n );
changes.push_back("menus/v1_4_0_text"_i18n );
int nbVersions = verTitles.size();
items.reserve(nbVersions);
for(int i = nbVersions -1 ; i >= 0; i--){

View file

@ -1,5 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
//#include <stdio.h>
//#include <stdlib.h>
#include <string>
#include <switch.h>
@ -10,8 +10,8 @@
#include "utils.hpp"
#include <string.h>
#include <stdio.h>
//#include <string.h>
//#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/errno.h>
@ -24,7 +24,7 @@
namespace i18n = brls::i18n;
using namespace i18n::literals;
TimeServiceType __nx_time_service_type = TimeServiceType_System;
//TimeServiceType __nx_time_service_type = TimeServiceType_System;
int main(int argc, char* argv[])
{

View file

@ -13,7 +13,7 @@ MainFrame::MainFrame() : TabFrame()
this->addTab("menus/main_about"_i18n , new AboutTab());
this->addSeparator();
//this->addSeparator();
this->addTab("menus/main_update_ams"_i18n , new AmsTab());
this->addTab("menus/main_update_cfw"_i18n , new ListDownloadTab(cfw));

216
source/net_page.cpp Normal file
View file

@ -0,0 +1,216 @@
#include "net_page.hpp"
#include <iostream>
#include <arpa/inet.h>
namespace i18n = brls::i18n;
using namespace i18n::literals;
using json = nlohmann::json;
NetPage::NetPage() : AppletFrame(true, true)
{
this->setTitle("menus/net_settings"_i18n );
nifmInitialize(NifmServiceType_User);
NifmNetworkProfileData profile;
nifmGetCurrentNetworkProfile (&profile);
nifmExit();
int uuid = 0;
for (int j = 0; j < 16; j++) uuid += int(profile.uuid.uuid[j]);
std::string labelText = "";
if(uuid){
labelText = "IP Adress: " + ipToString(profile.ip_setting_data.ip_address_setting.current_addr.addr)
+"\nSubnet Mask: " + ipToString(profile.ip_setting_data.ip_address_setting.subnet_mask.addr)
+"\nGateway: " + ipToString(profile.ip_setting_data.ip_address_setting.gateway.addr)
+"\nMTU: " + std::to_string(unsigned(profile.ip_setting_data.mtu));
if(profile.ip_setting_data.dns_setting.is_automatic){
labelText += "\nDNS: Automatic";
}
else{
labelText += "\nPrimary DNS: " + ipToString(profile.ip_setting_data.dns_setting.primary_dns_server.addr)
+"\nSecondary DNS: "+ ipToString(profile.ip_setting_data.dns_setting.secondary_dns_server.addr);
}
}
else{
labelText = "Please connect to internet to use this feature.";
}
list = new brls::List();
label = new brls::Label(brls::LabelStyle::DESCRIPTION, labelText, true);
list->addView(label);
//ip_addr
//subnet_mask
//gateway
//dns1
//dns2
//mtu
//ip_auto
//dns_auto
if(uuid){
std::fstream profilesFile;
json profiles;
if(std::filesystem::exists(INTERNET_JSON)){
profilesFile.open(INTERNET_JSON, std::fstream::in);
profilesFile >> profiles;
profilesFile.close();
profiles.push_back(json::object({
{"name", "90DNS (Europe)"},
{"dns1", "163.172.141.219"},
{"dns2", "207.246.121.77"}
}));
}
else{
profiles = {{
{"name", "90DNS (Europe)"},
{"dns1", "163.172.141.219"},
{"dns2", "207.246.121.77"}
}};
}
profiles.push_back(json::object({
{"name", "90DNS (USA)"},
{"dns1", "207.246.121.77"},
{"dns2", "163.172.141.219"}
}));
profiles.push_back(json::object({
{"name", "Google DNS"},
{"dns1", "8.8.8.8"},
{"dns2", "8.8.4.4"}
}));
profiles.push_back(json::object({
{"name", "Automatic IP Address"},
{"ip_auto", true}
}));
profiles.push_back(json::object({
{"name", "Automatic DNS"},
{"dns_auto", true}
}));
profiles.push_back(json::object({
{"ip_addr", "10.13.111.111"},
{"subnet_mask", "255.255.0.0"},
{"gateway", "10.13.37.1"},
{"mtu", 1500},
{"name", "ACNH lan-play"}
}));
int nbProfiles = profiles.size();
listItems.reserve(nbProfiles);
int iter = 0;
for (const auto& p : profiles.items()){
json values = p.value();
if(values.find("name") != values.end()) listItems[iter] = new brls::ListItem(values["name"]);
else listItems[iter] = new brls::ListItem("Unnamed");
listItems[iter]->getClickEvent()->subscribe([&, values](brls::View* view){
brls::Dialog* dialog = new brls::Dialog(values.dump(0).substr(1, values.dump(0).size() - 2));
brls::GenericEvent::Callback callbackOk = [&, dialog, values](brls::View* view) {
nifmInitialize(NifmServiceType_Admin);
NifmNetworkProfileData profile;
nifmGetCurrentNetworkProfile (&profile);
unsigned char buf[sizeof(struct in6_addr)];
if(values.find("ip_addr") != values.end()){
if(inet_pton(AF_INET, std::string(values["ip_addr"]).c_str(), buf)){
profile.ip_setting_data.ip_address_setting.is_automatic = u8(0);
//nifmSetNetworkProfile(&profile, &profile.uuid);
stringToIp(std::string(values["ip_addr"]), profile.ip_setting_data.ip_address_setting.current_addr.addr);
}
}
if(values.find("subnet_mask") != values.end()){
if(inet_pton(AF_INET, std::string(values["subnet_mask"]).c_str(), buf)){
stringToIp(std::string(values["subnet_mask"]), profile.ip_setting_data.ip_address_setting.subnet_mask.addr);
}
}
if(values.find("gateway") != values.end()){
if(inet_pton(AF_INET, std::string(values["gateway"]).c_str(), buf)){
stringToIp(std::string(values["gateway"]), profile.ip_setting_data.ip_address_setting.gateway.addr);
}
}
if(values.find("dns1") != values.end()){
if(inet_pton(AF_INET, std::string(values["dns1"]).c_str(), buf)){
profile.ip_setting_data.dns_setting.is_automatic = u8(0);
stringToIp(std::string(values["dns1"]), profile.ip_setting_data.dns_setting.primary_dns_server.addr);
//std::cout << unsigned(profile.ip_setting_data.dns_setting.primary_dns_server.addr[0]) << std::endl;
}
}
if(values.find("dns2") != values.end()){
if(inet_pton(AF_INET, std::string(values["dns2"]).c_str(), buf)){
profile.ip_setting_data.dns_setting.is_automatic = u8(0);
stringToIp(std::string(values["dns2"]), profile.ip_setting_data.dns_setting.secondary_dns_server.addr);
}
}
if(values.find("mtu") != values.end()){
profile.ip_setting_data.mtu = u16(values["mtu"]);
/* try{
u8 mtu = u8(std::stoi(std::string(values["mtu"])));
profile.ip_setting_data.mtu = mtu;
}
catch(const std::invalid_argument& ia){} */
}
if(values.find("ip_auto") != values.end()){
profile.ip_setting_data.ip_address_setting.is_automatic = u8(values["ip_auto"]);
}
if(values.find("dns_auto") != values.end()){
profile.ip_setting_data.dns_setting.is_automatic = u8(values["dns_auto"]);
}
nifmSetNetworkProfile(&profile, &profile.uuid);
nifmSetWirelessCommunicationEnabled(true);
nifmExit();
usleep(2500000); //Wait to avoid crashes when leaving too fast
dialog->close();
//brls::Application::pushView(new NetPage());
};
brls::GenericEvent::Callback callbackNo = [dialog](brls::View* view) {
dialog->close();
};
dialog->addButton("menus/Confirm_button"_i18n , callbackOk);
dialog->addButton("menus/Cancel_button"_i18n , callbackNo);
dialog->setCancelable(false);
dialog->open();
});
list->addView(listItems[iter]);
iter++;
}
}
else{
cancel = new brls::ListItem("menus/go_back"_i18n);
cancel->getClickEvent()->subscribe([&](brls::View* view){
brls::Application::pushView(new MainFrame());
});
list->addView(cancel);
}
this->setContentView(list);
}
std::string NetPage::ipToString(u8* ip){
std::string res = "";
for (size_t i = 0; i < 3; i++){
res += std::to_string(unsigned(ip[i]));
res += ".";
}
res += std::to_string(unsigned(ip[4]));
return res;
}
int NetPage::stringToIp(std::string ip, u8 *out){
size_t start;
size_t end = 0;
int i = 0;
while ((start = ip.find_first_not_of(".", end)) != std::string::npos)
{
end = ip.find(".", start);
out[i] = u8(std::stoi(ip.substr(start, end - start)));
i++;
}
return 0;
}

View file

@ -54,6 +54,50 @@ ToolsTab::ToolsTab(std::string tag) : brls::List()
ntcp->setHeight(LISTITEM_HEIGHT);
this->addView(ntcp); */
netSettings = new brls::ListItem("menus/tool_net_settings"_i18n );
netSettings->getClickEvent()->subscribe([&](brls::View* view){
brls::Application::pushView(new NetPage());
});
netSettings->setHeight(LISTITEM_HEIGHT);
this->addView(netSettings);
browser = new brls::ListItem("menus/tool_browser"_i18n );
browser->getClickEvent()->subscribe([&](brls::View* view){
Result rc=0;
char url[0xc00] = {0};
strcpy(url, "https://duckduckgo.com");
int at = appletGetAppletType();
std::string error = "";
if(at == AppletType_Application) { // Running as a title
WebCommonConfig conf;
WebCommonReply out;
rc = webPageCreate(&conf, url);
if (R_FAILED(rc))
error += "Error starting Browser\nLookup error code for more info " + rc;
webConfigSetJsExtension(&conf, true);
webConfigSetPageCache(&conf, true);
webConfigSetBootLoadingIcon(&conf, true);
webConfigSetWhitelist(&conf, ".*");
rc = webConfigShow(&conf, &out);
if (R_FAILED(rc))
error += "Error starting Browser\nLookup error code for more info " + rc;
} else { // Running under applet
error += "Running in applet mode\nPlease launch hbmenu by holding R on an APP (e.g. a game) NOT an applet (e.g. Gallery)";
}
if(!error.empty()){
brls::Dialog* dialog = new brls::Dialog(error);
brls::GenericEvent::Callback callback = [dialog](brls::View* view) {
dialog->close();
};
dialog->addButton("menus/Ok_button"_i18n , callback);
dialog->setCancelable(true);
dialog->open();
}
});
browser->setHeight(LISTITEM_HEIGHT);
this->addView(browser);
cleanUp = new brls::ListItem("menus/tool_cleanUp"_i18n );
cleanUp->getClickEvent()->subscribe([&](brls::View* view){
std::filesystem::remove(AMS_ZIP_PATH);
@ -117,3 +161,4 @@ ToolsTab::ToolsTab(std::string tag) : brls::List()
language->setHeight(LISTITEM_HEIGHT);
this->addView(language); */
}