Initial translation support (only english for now)

This commit is contained in:
Huntereb 2019-12-19 19:09:36 -05:00
parent f495a3143f
commit fa22087ceb
23 changed files with 390 additions and 134 deletions

View file

@ -18,7 +18,6 @@ namespace inst::ui {
static void setInstBarPerc(double ourPercent);
static void loadMainMenu();
static void loadInstallScreen();
static std::string finishedMessage();
private:
Rectangle::Ref infoRect;
Rectangle::Ref topRect;

28
include/util/lang.hpp Executable file
View file

@ -0,0 +1,28 @@
#pragma once
#include <string>
#include <sstream>
#include <fstream>
#include "json.hpp"
using json = nlohmann::json;
namespace Language {
void Load();
std::string LanguageEntry(std::string key);
std::string GetRandomMsg();
inline json GetRelativeJson(json j, std::string key) {
std::istringstream ss(key);
std::string token;
while (std::getline(ss, token, '.') && j != nullptr) {
j = j[token];
}
return j;
}
}
inline std::string operator ""_lang (const char* key, size_t size) {
return Language::LanguageEntry(std::string(key, size));
}

189
romfs/lang/en.json Executable file
View file

@ -0,0 +1,189 @@
{
"main":{
"menu": {
"sd": "Install from SD card",
"net": "Install over LAN or internet",
"usb": "Install over USB",
"sig": "Manage signature patches",
"set": "Settings",
"exit": "Exit"
},
"net": {
"title": "Network connection not available",
"desc": "Check that airplane mode is disabled and you're connected to a local network."
},
"usb": {
"warn": {
"title": "Warning!",
"desc": "USB installations may not \"just werk\" on some devices and setups.\nIf you experience issues with USB installations, please don't pull your\nhair out! It's advised to use ns-usbloader for USB installations, or\nLAN/Internet installations instead for remote installation, especially\nwhen paired with an ethernet adapter!\n\nYou have been warned...",
"opt1": "Don't tell me again"
},
"error": {
"title": "No USB connection detected",
"desc": "Plug in to a compatible device to install over USB"
}
},
"applet": {
"title": "Applet Mode not supported",
"desc": "You may experience issues using Awoo Installer in Applet Mode. If you do\nhave problems, please switch to running Awoo Installer over an installed\ntitle (hold R while starting a game) or from a forwarder!"
},
"buttons": "\ue0e0 Select \ue0e1 Exit "
},
"inst": {
"net": {
"help": {
"title": "Help",
"desc": "Files can be installed remotely from your other devices using tools such\nas ns-usbloader in Tinfoil mode. To send files to your Switch, open one\nof these pieces of software on your PC or mobile device, input your\nSwitch's IP address (listed on-screen), select your files, then upload\nto your console! If the software you're using won't let you select\nspecific file types, try renaming the extension to something it accepts.\nAwoo Installer doesn't care about file extensions during net installations!\n\nIf you can't figure it out, just copy your files to your SD card and try\nthe \"Install from SD Card\" option on the main menu!"
},
"src": {
"title": "Where do you want to install from?",
"opt0": "URL",
"opt1": "Google Drive"
},
"url": {
"hint": "Enter the Internet address of a file",
"invalid": "The URL specified is invalid!",
"source_string": " from URL"
},
"gdrive": {
"hint": "Enter the file ID of a public Google Drive file",
"alt_name": "Google Drive File",
"source_string": " from Google Drive"
},
"top_info": "Select what files you want to install from the server, then press the Plus button!",
"top_info1": "Waiting for a connection... Your Switch's IP Address is: ",
"failed": "Failed to perform remote install!",
"transfer_interput": "An error occured during data transfer. Check your network connection.",
"source_string": " over local network",
"buttons": "\ue0e3 Install Over Internet \ue0e2 Help \ue0e1 Cancel ",
"buttons1": "\ue0e0 Select File \ue0e3 Select All \ue0ef Install File(s) \ue0e1 Cancel "
},
"sd": {
"help": {
"title": "Help",
"desc": "Copy your NSP, NSZ, XCI, or XCZ files to your SD card, browse to and\nselect the ones you want to install, then press the Plus button."
},
"top_info": "Select what files you want to install, then press the Plus button!",
"source_string": " from SD card",
"delete_info": " installed! Delete it from the SD card?",
"delete_info_multi": " files installed successfully! Delete them from the SD card?",
"delete_desc": "The original files aren't needed anymore after they've been installed",
"buttons": "\ue0e0 Select File \ue0e3 Select All \ue0ef Install File(s) \ue0e2 Help \ue0e1 Cancel "
},
"usb": {
"help": {
"title": "Help",
"desc": "Files can be installed over USB from other devices using tools such as\nns-usbloader in Tinfoil mode. To send files to your Switch, open one of\nthese pieces of software on your PC, select your files, then upload to\nyour console!\n\nUnfortunately USB installations require a specific setup on some\nplatforms, and can be rather buggy at times. If you can't figure it out,\ngive LAN/internet installs a try, or copy your files to your SD card and\ntry the \"Install from SD Card\" option on the main menu!"
},
"top_info": "USB connection successful! Waiting for list of files to be sent...",
"top_info2": "Select what files you want to install over USB, then press the Plus button!",
"error": "USB transfer timed out or failed",
"source_string": " over USB",
"buttons": "\ue0e2 (Hold) Help \ue0e1 (Hold) Cancel ",
"buttons2": "\ue0e0 Select File \ue0e3 Select All \ue0ef Install File(s) \ue0e1 Cancel "
},
"target": {
"desc0": "Where should ",
"desc1": " be installed to?",
"desc00": "Where should the selected ",
"desc01": " files be installed to?",
"opt0": "SD Card",
"opt1": "Internal Storage"
},
"info_page": {
"top_info0": "Installing ",
"preparing": "Preparing installation...",
"failed": "Failed to install ",
"failed_desc": "Partially installed contents can be removed from the System Settings applet.",
"complete": "Install complete",
"desc0": " files installed successfully!",
"desc1": " installed!",
"downloading": "Downloading ",
"at": " at "
},
"nca_verify": {
"title": "Invalid NCA signature detected!",
"desc": "Improperly signed software should only be installed from trustworthy\nsources. Files containing cartridge repacks and DLC unlockers will always\nshow this warning. You can disable this check in Awoo Installer's settings.\n\nAre you sure you want to continue the installation?",
"opt1": "Yes, I understand the risks",
"error": "The requested NCA is not properly signed: "
},
"finished": [
"Enjoy your \"legal backups\"!",
"I'm sure after you give the game a try you'll have tons of fun actually buying it!",
"You buy gamu right? Nintendo-san thanka-you for your purchase!",
"Bypassing DRM is great, isn't it?",
"You probably saved like six trees by not buying the game! All that plastic goes somewhere!",
"Nintendo ninjas have been dispatched to your current location.",
"And we didn't even have to shove a political ideology down your throat to get here!"
]
},
"sig": {
"install": "Install",
"uninstall": "Uninstall",
"update": "Update",
"version_text": "You currently have signature patches installed for up to HOS version ",
"title0": "Install signature patches?",
"desc0": "Signature patches are required for installing and playing official software.",
"backup_failed": "Could not back up Hekate patches.ini! Install anyway?",
"backup_failed_desc": "If you don't use Hekate you can ignore this warning.",
"download_failed": "Could not download signature patches",
"download_failed_desc": "You may have supplied an invalid source in Awoo Installer's settings,\nor the host may just be down right now.",
"version_text2": "Your signature patches have been updated for up to HOS version ",
"install_complete": "Install complete!",
"complete_desc": "Restart your console to apply",
"restart": "Restart",
"later": "I'll do it later",
"extract_failed": "Could not extract files!",
"restore_failed": "Unable to restore original Hekate patches.ini! Continue uninstalling?",
"uninstall_complete": "Uninstall complete",
"remove_failed": "Unable to remove signature patches",
"remove_failed_desc": "Files may have been renamed or deleted",
"generic_error": "Failed to install signature patches!"
},
"options": {
"menu_items": {
"ignore_firm": "Ignore minimum firmware version required by titles",
"nca_verify": "Verify NCA signatures before installation",
"boost_mode": "Enable \"boost mode\" during installations",
"ask_delete": "Ask to delete original files after installation",
"auto_update": "Check for updates to Awoo Installer automatically",
"gay_option": "Remove anime",
"sig_url": "Signature patches source URL: ",
"check_update": "Check for updates to Awoo Installer",
"credits": "Credits"
},
"nca_warn": {
"title": "Warning!",
"desc": "Some installable files may contain malicious contents! Only disable this\nfeature if you are absolutely certain the software you will be installing\nis trustworthy!\n\nDo you still want to disable NCA signature verification?",
"opt1": "Yes, I want a brick"
},
"sig_hint": "Enter the URL to obtain Signature Patches from",
"update": {
"title": "Update available",
"desc0": "Awoo Installer ",
"desc1": " is available now! Ready to update?",
"opt0": "Update",
"top_info": "Updating to Awoo Installer ",
"bot_info": "Downloading Awoo Installer ",
"complete": "Update complete!",
"failed": "Update failed!",
"end_desc": "The software will now be closed.",
"title_check_fail": "No updates found",
"desc_check_fail": "You are on the latest version of Awoo Installer!"
},
"credits": {
"title": "Thanks to the following people!",
"desc": "- HookedBehemoth for A LOT of contributions\n- Adubbz and other contributors for Tinfoil\n- XorTroll for Plutonium and Goldleaf\n- blawar (wife beater) and nicoboss for NSZ support\n- The kind folks at the AtlasNX Discuck (or at least some of them)\n- The also kind folks at the RetroNX Discuck (of no direct involvement)\n- namako8982 for the Momiji art\n- TheXzoron for being a baka"
},
"title": "Change Awoo Installer's settings!",
"buttons": "\ue0e0 Select/Change \ue0e1 Cancel "
},
"common": {
"ok": "OK",
"cancel": "Cancel",
"close": "Close",
"yes": "Yes",
"no": "No",
"cancel_desc": "Press B to cancel"
}
}

View file

@ -29,6 +29,7 @@ SOFTWARE.
#include "util/error.hpp"
#include "util/debug.h"
#include "util/util.hpp"
#include "util/lang.hpp"
#include "ui/instPage.hpp"
namespace tin::install::nsp
@ -125,13 +126,13 @@ namespace tin::install::nsp
int downloadProgress = (int)(((double)bufferedPlaceholderWriter.GetSizeBuffered() / (double)bufferedPlaceholderWriter.GetTotalDataSize()) * 100.0);
inst::ui::instPage::setInstInfoText("Downloading " + inst::util::formatUrlString(ncaFileName) + " at " + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstBarPerc((double)downloadProgress);
}
}
inst::ui::instPage::setInstBarPerc(100);
inst::ui::instPage::setInstInfoText("Installing " + ncaFileName + "...");
inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "...");
inst::ui::instPage::setInstBarPerc(0);
while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsHttpNsp)
{
@ -143,7 +144,7 @@ namespace tin::install::nsp
thrd_join(curlThread, NULL);
thrd_join(writeThread, NULL);
if (stopThreadsHttpNsp) THROW_FORMAT("An error occured during data transfer. Check your network connection.");
if (stopThreadsHttpNsp) THROW_FORMAT(("inst.net.transfer_interput"_lang).c_str());
}
void HTTPNSP::BufferData(void* buf, off_t offset, size_t size)

View file

@ -26,6 +26,7 @@ SOFTWARE.
#include "data/buffered_placeholder_writer.hpp"
#include "util/error.hpp"
#include "util/util.hpp"
#include "util/lang.hpp"
#include "ui/instPage.hpp"
namespace tin::install::xci
@ -126,7 +127,7 @@ namespace tin::install::xci
LOG_DEBUG("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed);
#endif
inst::ui::instPage::setInstInfoText("Downloading " + inst::util::formatUrlString(ncaFileName) + " at " + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstBarPerc((double)downloadProgress);
}
}
@ -136,7 +137,7 @@ namespace tin::install::xci
u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000;
#endif
inst::ui::instPage::setInstInfoText("Installing " + ncaFileName + "...");
inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "...");
inst::ui::instPage::setInstBarPerc(0);
while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsHttpXci)
{
@ -151,7 +152,7 @@ namespace tin::install::xci
thrd_join(curlThread, NULL);
thrd_join(writeThread, NULL);
if (stopThreadsHttpXci) THROW_FORMAT("An error occured during data transfer. Check your network connection.");
if (stopThreadsHttpXci) THROW_FORMAT(("inst.net.transfer_interput"_lang).c_str());
}
void HTTPXCI::BufferData(void* buf, off_t offset, size_t size)

View file

@ -34,8 +34,9 @@ SOFTWARE.
#include "util/title_util.hpp"
#include "util/debug.h"
#include "util/error.hpp"
#include "ui/MainApplication.hpp"
#include "util/util.hpp"
#include "util/lang.hpp"
#include "ui/MainApplication.hpp"
namespace inst::ui {
extern MainApplication *mainApp;
@ -112,10 +113,10 @@ namespace tin::install::nsp
if (!Crypto::rsa2048PssVerify(&header->magic, 0x200, header->fixed_key_sig, Crypto::NCAHeaderSignature))
{
std::thread audioThread(inst::util::playAudio,"romfs:/audio/bark.wav");
int rc = inst::ui::mainApp->CreateShowDialog("Invalid NCA signature detected!", "Improperly signed software should only be installed from trustworthy\nsources. Files containing cartridge repacks and DLC unlockers will always\nshow this warning. You can disable this check in Awoo Installer's settings.\n\nAre you sure you want to continue the installation?", {"Cancel", "Yes, I understand the risks"}, false);
int rc = inst::ui::mainApp->CreateShowDialog("inst.nca_verify.title"_lang, "inst.nca_verify.desc"_lang, {"common.cancel"_lang, "inst.nca_verify.opt1"_lang}, false);
audioThread.join();
if (rc != 1)
THROW_FORMAT(("The requested NCA (" + tin::util::GetNcaIdString(ncaId) + ") is not properly signed").c_str());
THROW_FORMAT(("inst.nca_verify.error"_lang + tin::util::GetNcaIdString(ncaId)).c_str());
m_declinedValidation = true;
}
delete header;

View file

@ -29,10 +29,10 @@ SOFTWARE.
#include "util/error.hpp"
#include "util/config.hpp"
#include "util/crypto.hpp"
#include "install/nca.hpp"
#include "sdInstall.hpp"
#include "ui/MainApplication.hpp"
#include "util/util.hpp"
#include "util/lang.hpp"
#include "install/nca.hpp"
#include "ui/MainApplication.hpp"
namespace inst::ui {
extern MainApplication *mainApp;
@ -108,11 +108,11 @@ namespace tin::install::xci
if (!Crypto::rsa2048PssVerify(&header->magic, 0x200, header->fixed_key_sig, Crypto::NCAHeaderSignature))
{
std::thread audioThread(inst::util::playAudio,"romfs:/audio/awoo.wav");
int rc = inst::ui::mainApp->CreateShowDialog("Invalid NCA signature detected!", "Improperly signed software should only be installed from trustworthy\nsources. Files containing cartridge repacks and DLC unlockers will always\nshow this warning. You can disable this check in Awoo Installer's settings.\n\nAre you sure you want to continue the installation?", {"Cancel", "Yes, I understand the risks"}, false);
std::thread audioThread(inst::util::playAudio,"romfs:/audio/bark.wav");
int rc = inst::ui::mainApp->CreateShowDialog("inst.nca_verify.title"_lang, "inst.nca_verify.desc"_lang, {"common.cancel"_lang, "inst.nca_verify.opt1"_lang}, false);
audioThread.join();
if (rc != 1)
THROW_FORMAT(("The requested NCA (" + tin::util::GetNcaIdString(ncaId) + ") is not properly signed").c_str());
THROW_FORMAT(("inst.nca_verify.error"_lang + tin::util::GetNcaIdString(ncaId)).c_str());
m_declinedValidation = true;
}
delete header;

View file

@ -3,6 +3,7 @@
#include "debug.h"
#include "nx/nca_writer.h"
#include "ui/instPage.hpp"
#include "util/lang.hpp"
namespace tin::install::nsp
{
@ -37,7 +38,7 @@ namespace tin::install::nsp
try
{
inst::ui::instPage::setInstInfoText("Installing " + ncaFileName + "...");
inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "...");
inst::ui::instPage::setInstBarPerc(0);
while (fileOff < ncaSize)
{

View file

@ -3,6 +3,7 @@
#include "debug.h"
#include "nx/nca_writer.h"
#include "ui/instPage.hpp"
#include "util/lang.hpp"
namespace tin::install::xci
{
@ -37,7 +38,7 @@ namespace tin::install::xci
try
{
inst::ui::instPage::setInstInfoText("Installing " + ncaFileName + "...");
inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "...");
inst::ui::instPage::setInstBarPerc(0);
while (fileOff < ncaSize)
{

View file

@ -22,7 +22,6 @@ SOFTWARE.
#include "install/usb_nsp.hpp"
#include <switch.h>
#include <algorithm>
#include <malloc.h>
@ -34,6 +33,7 @@ SOFTWARE.
#include "util/debug.h"
#include "util/util.hpp"
#include "util/usb_comms_awoo.h"
#include "util/lang.hpp"
#include "ui/instPage.hpp"
@ -70,7 +70,7 @@ namespace tin::install::nsp
while (sizeRemaining && !stopThreadsUsbNsp)
{
tmpSizeRead = awoo_usbCommsRead(buf, std::min(sizeRemaining, (u64)0x1000000));
if (tmpSizeRead == 0) THROW_FORMAT("USB transfer timed out or failed");
if (tmpSizeRead == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str());
sizeRemaining -= tmpSizeRead;
while (true)
@ -153,7 +153,7 @@ namespace tin::install::nsp
LOG_DEBUG("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed);
#endif
inst::ui::instPage::setInstInfoText("Downloading " + inst::util::formatUrlString(ncaFileName) + " at " + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstBarPerc((double)downloadProgress);
}
}
@ -163,7 +163,7 @@ namespace tin::install::nsp
u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000;
#endif
inst::ui::instPage::setInstInfoText("Installing " + ncaFileName + "...");
inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "...");
inst::ui::instPage::setInstBarPerc(0);
while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsUsbNsp)
{
@ -186,7 +186,7 @@ namespace tin::install::nsp
LOG_DEBUG("buffering 0x%lx-0x%lx\n", offset, offset + size);
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(m_nspName, offset, size);
u8* tempBuffer = (u8*)memalign(0x1000, header.dataSize);
if (tin::util::USBRead(tempBuffer, header.dataSize) == 0) THROW_FORMAT("USB transfer timed out or failed");
if (tin::util::USBRead(tempBuffer, header.dataSize) == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str());
memcpy(buf, tempBuffer, header.dataSize);
free(tempBuffer);
}

View file

@ -22,7 +22,6 @@ SOFTWARE.
#include "install/usb_xci.hpp"
#include <switch.h>
#include <algorithm>
#include <malloc.h>
@ -34,6 +33,7 @@ SOFTWARE.
#include "util/debug.h"
#include "util/util.hpp"
#include "util/usb_comms_awoo.h"
#include "util/lang.hpp"
#include "ui/instPage.hpp"
namespace tin::install::xci
@ -69,7 +69,7 @@ namespace tin::install::xci
while (sizeRemaining && !stopThreadsUsbXci)
{
tmpSizeRead = awoo_usbCommsRead(buf, std::min(sizeRemaining, (u64)0x1000000));
if (tmpSizeRead == 0) THROW_FORMAT("USB transfer timed out or failed");
if (tmpSizeRead == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str());
sizeRemaining -= tmpSizeRead;
while (true)
@ -152,7 +152,7 @@ namespace tin::install::xci
LOG_DEBUG("> Download Progress: %lu/%lu MB (%i%s) (%.2f MB/s)\r", downloadSizeMB, totalSizeMB, downloadProgress, "%", speed);
#endif
inst::ui::instPage::setInstInfoText("Downloading " + inst::util::formatUrlString(ncaFileName) + " at " + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstInfoText("inst.info_page.downloading"_lang + inst::util::formatUrlString(ncaFileName) + "inst.info_page.at"_lang + std::to_string(speed).substr(0, std::to_string(speed).size()-4) + "MB/s");
inst::ui::instPage::setInstBarPerc((double)downloadProgress);
}
}
@ -162,7 +162,7 @@ namespace tin::install::xci
u64 totalSizeMB = bufferedPlaceholderWriter.GetTotalDataSize() / 1000000;
#endif
inst::ui::instPage::setInstInfoText("Installing " + ncaFileName + "...");
inst::ui::instPage::setInstInfoText("inst.info_page.top_info0"_lang + ncaFileName + "...");
inst::ui::instPage::setInstBarPerc(0);
while (!bufferedPlaceholderWriter.IsPlaceholderComplete() && !stopThreadsUsbXci)
{
@ -185,7 +185,7 @@ namespace tin::install::xci
LOG_DEBUG("buffering 0x%lx-0x%lx\n", offset, offset + size);
tin::util::USBCmdHeader header = tin::util::USBCmdManager::SendFileRangeCmd(m_xciName, offset, size);
u8* tempBuffer = (u8*)memalign(0x1000, header.dataSize);
if (tin::util::USBRead(tempBuffer, header.dataSize) == 0) THROW_FORMAT("USB transfer timed out or failed");
if (tin::util::USBRead(tempBuffer, header.dataSize) == 0) THROW_FORMAT(("inst.usb.error"_lang).c_str());
memcpy(buf, tempBuffer, header.dataSize);
free(tempBuffer);
}

View file

@ -39,6 +39,7 @@ SOFTWARE.
#include "util/config.hpp"
#include "util/util.hpp"
#include "util/curl.hpp"
#include "util/lang.hpp"
#include "ui/MainApplication.hpp"
#include "ui/instPage.hpp"
@ -138,7 +139,7 @@ namespace netInstStuff{
try {
for (urlItr = 0; urlItr < ourUrlList.size(); urlItr++) {
LOG_DEBUG("%s %s\n", "Install request from", ourUrlList[urlItr].c_str());
inst::ui::instPage::setTopInstInfoText("Installing " + urlNames[urlItr] + ourSource);
inst::ui::instPage::setTopInstInfoText("inst.info_page.top_info0"_lang + urlNames[urlItr] + ourSource);
std::unique_ptr<tin::install::Install> installTask;
if (inst::curl::downloadToBuffer(ourUrlList[urlItr], 0x100, 0x103) == "HEAD") {
@ -150,7 +151,7 @@ namespace netInstStuff{
}
LOG_DEBUG("%s\n", "Preparing installation");
inst::ui::instPage::setInstInfoText("Preparing installation...");
inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang);
inst::ui::instPage::setInstBarPerc(0);
installTask->Prepare();
installTask->Begin();
@ -160,10 +161,10 @@ namespace netInstStuff{
LOG_DEBUG("Failed to install");
LOG_DEBUG("%s", e.what());
fprintf(stdout, "%s", e.what());
inst::ui::instPage::setInstInfoText("Failed to install " + urlNames[urlItr]);
inst::ui::instPage::setInstInfoText("inst.info_page.failed"_lang + urlNames[urlItr]);
inst::ui::instPage::setInstBarPerc(0);
std::thread audioThread(inst::util::playAudio,"romfs:/audio/bark.wav");
inst::ui::mainApp->CreateShowDialog("Failed to install " + urlNames[urlItr] + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("inst.info_page.failed"_lang + urlNames[urlItr] + "!", "inst.info_page.failed_desc"_lang + "\n\n" + (std::string)e.what(), {"common.ok"_lang}, true);
audioThread.join();
nspInstalled = false;
}
@ -174,17 +175,17 @@ namespace netInstStuff{
inst::util::setClockSpeed(2, previousClockValues[2]);
}
LOG_DEBUG("%s\n", "Telling the server we're done installing");
LOG_DEBUG("Telling the server we're done installing\n");
// Send 1 byte ack to close the server
u8 ack = 0;
tin::network::WaitSendNetworkData(m_clientSocket, &ack, sizeof(u8));
if(nspInstalled) {
inst::ui::instPage::setInstInfoText("Install complete");
inst::ui::instPage::setInstInfoText("inst.info_page.complete"_lang);
inst::ui::instPage::setInstBarPerc(100);
std::thread audioThread(inst::util::playAudio,"romfs:/audio/awoo.wav");
if (ourUrlList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourUrlList.size()) + " files installed successfully!", inst::ui::instPage::finishedMessage(), {"OK"}, true);
else inst::ui::mainApp->CreateShowDialog(urlNames[0] + " installed!", inst::ui::instPage::finishedMessage(), {"OK"}, true);
if (ourUrlList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourUrlList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true);
else inst::ui::mainApp->CreateShowDialog(urlNames[0] + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true);
audioThread.join();
}
@ -217,7 +218,7 @@ namespace netInstStuff{
}
std::string ourIPAddress = inst::util::getIPAddress();
inst::ui::mainApp->netinstPage->pageInfoText->SetText("Waiting for a connection... Your Switch's IP Address is: " + ourIPAddress);
inst::ui::mainApp->netinstPage->pageInfoText->SetText("inst.net.top_info1"_lang + ourIPAddress);
inst::ui::mainApp->CallForRender();
LOG_DEBUG("%s %s\n", "Switch IP is ", ourIPAddress.c_str());
LOG_DEBUG("%s\n", "Waiting for network");
@ -248,7 +249,7 @@ namespace netInstStuff{
}
if (kDown & KEY_X)
{
inst::ui::mainApp->CreateShowDialog("Help", "Files can be installed remotely from your other devices using tools such\nas ns-usbloader in Tinfoil mode. To send files to your Switch, open one\nof these pieces of software on your PC or mobile device, input your\nSwitch's IP address (listed on-screen), select your files, then upload\nto your console! If the software you're using won't let you select\nspecific file types, try renaming the extension to something it accepts.\nAwoo Installer doesn't care about file extensions during net installations!\n\nIf you can't figure it out, just copy your files to your SD card and try\nthe \"Install from SD Card\" option on the main menu!", {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("inst.net.help.title"_lang, "inst.net.help.desc"_lang, {"common.ok"_lang}, true);
}
struct sockaddr_in client;
@ -279,8 +280,6 @@ namespace netInstStuff{
// Split the string up into individual URLs
std::stringstream urlStream(urlBuf.get());
std::string segment;
std::string nspExt = ".nsp";
std::string nszExt = ".nsz";
while (std::getline(urlStream, segment, '\n')) urls.push_back(segment);
@ -300,7 +299,7 @@ namespace netInstStuff{
LOG_DEBUG("Failed to perform remote install!\n");
LOG_DEBUG("%s", e.what());
fprintf(stdout, "%s", e.what());
inst::ui::mainApp->CreateShowDialog("Failed to perform remote install!", (std::string)e.what(), {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("inst.net.failed"_lang, (std::string)e.what(), {"common.ok"_lang}, true);
return {};
}
}

View file

@ -37,6 +37,7 @@ SOFTWARE.
#include "util/error.hpp"
#include "util/config.hpp"
#include "util/util.hpp"
#include "util/lang.hpp"
#include "ui/MainApplication.hpp"
#include "ui/instPage.hpp"
@ -68,7 +69,7 @@ namespace nspInstStuff {
try
{
for (titleItr = 0; titleItr < ourTitleList.size(); titleItr++) {
inst::ui::instPage::setTopInstInfoText("Installing " + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 40, true) + " from SD card");
inst::ui::instPage::setTopInstInfoText("inst.info_page.top_info0"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 40, true) + "inst.sd.source_string"_lang);
std::unique_ptr<tin::install::Install> installTask;
if (ourTitleList[titleItr].extension() == ".xci" || ourTitleList[titleItr].extension() == ".xcz") {
@ -80,7 +81,7 @@ namespace nspInstStuff {
}
LOG_DEBUG("%s\n", "Preparing installation");
inst::ui::instPage::setInstInfoText("Preparing installation...");
inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang);
inst::ui::instPage::setInstBarPerc(0);
installTask->Prepare();
installTask->Begin();
@ -91,10 +92,10 @@ namespace nspInstStuff {
LOG_DEBUG("Failed to install");
LOG_DEBUG("%s", e.what());
fprintf(stdout, "%s", e.what());
inst::ui::instPage::setInstInfoText("Failed to install " + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true));
inst::ui::instPage::setInstInfoText("inst.info_page.failed"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true));
inst::ui::instPage::setInstBarPerc(0);
std::thread audioThread(inst::util::playAudio,"romfs:/audio/bark.wav");
inst::ui::mainApp->CreateShowDialog("Failed to install " + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true) + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("inst.info_page.failed"_lang + inst::util::shortenString(ourTitleList[titleItr].filename().string(), 42, true) + "!", "inst.info_page.failed_desc"_lang + "\n\n" + (std::string)e.what(), {"common.ok"_lang}, true);
audioThread.join();
nspInstalled = false;
}
@ -113,21 +114,21 @@ namespace nspInstStuff {
}
if(nspInstalled) {
inst::ui::instPage::setInstInfoText("Install complete");
inst::ui::instPage::setInstInfoText("inst.info_page.complete"_lang);
inst::ui::instPage::setInstBarPerc(100);
std::thread audioThread(inst::util::playAudio,"romfs:/audio/awoo.wav");
if (ourTitleList.size() > 1) {
if (inst::config::deletePrompt) {
if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + " files installed successfully! Delete them from the SD card?", "The original files aren't needed anymore after they've been installed", {"No","Yes"}, false) == 1) {
if(inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.sd.delete_info_multi"_lang, "inst.sd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) {
for (long unsigned int i = 0; i < ourTitleList.size(); i++) {
if (std::filesystem::exists(ourTitleList[i])) std::filesystem::remove(ourTitleList[i]);
}
}
} else inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + " files installed successfully!", inst::ui::instPage::finishedMessage(), {"OK"}, true);
} else inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true);
} else {
if (inst::config::deletePrompt) {
if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 32, true) + " installed! Delete it from the SD card?", "The original file isn't needed anymore after it's been installed", {"No","Yes"}, false) == 1) if (std::filesystem::exists(ourTitleList[0])) std::filesystem::remove(ourTitleList[0]);
} else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 42, true) + " installed!", inst::ui::instPage::finishedMessage(), {"OK"}, true);
if(inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 32, true) + "inst.sd.delete_info"_lang, "inst.sd.delete_desc"_lang, {"common.no"_lang,"common.yes"_lang}, false) == 1) if (std::filesystem::exists(ourTitleList[0])) std::filesystem::remove(ourTitleList[0]);
} else inst::ui::mainApp->CreateShowDialog(inst::util::shortenString(ourTitleList[0].filename().string(), 42, true) + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true);
}
audioThread.join();
}

View file

@ -5,6 +5,7 @@
#include "util/util.hpp"
#include "util/unzip.hpp"
#include "util/config.hpp"
#include "util/lang.hpp"
namespace inst::ui {
extern MainApplication *mainApp;
@ -16,48 +17,48 @@ namespace sig {
try {
std::string patchesVersion = inst::util::readTextFromFile("sdmc:/atmosphere/exefs_patches/es_patches/patches.txt");
std::string versionText = "";
std::string installButtonText = "Install";
std::string installButtonText = "sig.install"_lang;
if (patchesVersion != "") {
versionText = "\n\nYou currently have signature patches installed for up to HOS version " + patchesVersion + ".";
installButtonText = "Update";
versionText = "\n\n" + "sig.version_text"_lang + patchesVersion + ".";
installButtonText = "sig.update"_lang;
}
int ourResult = inst::ui::mainApp->CreateShowDialog("Install signature patches?", "Signature patches are required for installing and playing official software." + versionText, {installButtonText, "Uninstall", "Cancel"}, true);
int ourResult = inst::ui::mainApp->CreateShowDialog("sig.title0"_lang, "sig.desc0"_lang + versionText, {installButtonText, "sig.uninstall"_lang, "common.cancel"_lang}, true);
if (ourResult == 0) {
if (inst::util::getIPAddress() == "1.0.0.127") {
inst::ui::mainApp->CreateShowDialog("Network connection not available", "Check that airplane mode is disabled and you're connected to a local network.", {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("main.net.title"_lang, "main.net.desc"_lang, {"common.ok"_lang}, true);
return;
}
if (!inst::util::copyFile("sdmc:/bootloader/patches.ini", inst::config::appDir + "/patches.ini.old")) {
if (inst::ui::mainApp->CreateShowDialog("Could not back up Hekate patches.ini! Install anyway?", "If you don't use Hekate you can ignore this warning.", {"Yes", "No"}, false)) return;
if (inst::ui::mainApp->CreateShowDialog("sig.backup_failed"_lang, "sig.backup_failed_desc"_lang, {"common.yes"_lang, "common.no"_lang}, false)) return;
}
std::string ourPath = inst::config::appDir + "/patches.zip";
bool didDownload = inst::curl::downloadFile(inst::config::sigPatchesUrl, ourPath.c_str());
bool didExtract = false;
if (didDownload) didExtract = inst::zip::extractFile(ourPath, "sdmc:/");
else {
inst::ui::mainApp->CreateShowDialog("Could not download signature patches", "You may have supplied an invalid source in Awoo Installer's settings,\nor the host may just be down right now.", {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("sig.download_failed"_lang, "sig.download_failed_desc"_lang, {"common.ok"_lang}, true);
return;
}
std::filesystem::remove(ourPath);
if (didExtract) {
patchesVersion = inst::util::readTextFromFile("sdmc:/atmosphere/exefs_patches/es_patches/patches.txt");
versionText = "";
if (patchesVersion != "") versionText = "Your signature patches have been updated for up to HOS version " + patchesVersion + "! ";
if (inst::ui::mainApp->CreateShowDialog("Install complete!", versionText + "\n\nRestart your console to apply!", {"Restart", "I'll do it later"}, false) == 0) bpcRebootSystem();
if (patchesVersion != "") versionText = "sig.version_text2"_lang + patchesVersion + "! ";
if (inst::ui::mainApp->CreateShowDialog("sig.install_complete"_lang, versionText + "\n\n" + "sig.complete_desc"_lang, {"sig.restart"_lang, "sig.later"_lang}, false) == 0) bpcRebootSystem();
}
else {
inst::ui::mainApp->CreateShowDialog("Could not extract files!", "", {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("sig.extract_failed"_lang, "", {"common.ok"_lang}, true);
return;
}
return;
} else if (ourResult == 1) {
if (!inst::util::copyFile( inst::config::appDir + "/patches.ini.old", "sdmc:/bootloader/patches.ini")) {
if (inst::ui::mainApp->CreateShowDialog("Unable to restore original Hekate patches.ini! Continue uninstalling?", "", {"Yes", "No"}, false)) return;
if (inst::ui::mainApp->CreateShowDialog("sig.restore_failed"_lang, "", {"common.yes"_lang, "common.no"_lang}, false)) return;
} else std::filesystem::remove(inst::config::appDir + "/patches.ini.old");
if (inst::util::removeDirectory("sdmc:/atmosphere/exefs_patches/es_patches")) {
if (inst::ui::mainApp->CreateShowDialog("Uninstall complete", "Restart your console to apply", {"Restart", "I'll do it later"}, false) == 0) bpcRebootSystem();
if (inst::ui::mainApp->CreateShowDialog("sig.uninstall_complete"_lang, "sig.complete_desc"_lang, {"sig.restart"_lang, "sig.later"_lang}, false) == 0) bpcRebootSystem();
}
else inst::ui::mainApp->CreateShowDialog("Unable to remove signature patches", "Files may have been renamed or deleted", {"OK"}, true);
else inst::ui::mainApp->CreateShowDialog("sig.remove_failed"_lang, "sig.remove_failed_desc"_lang, {"common.ok"_lang}, true);
} else return;
}
catch (std::exception& e)
@ -65,7 +66,7 @@ namespace sig {
LOG_DEBUG("Failed to install Signature Patches");
LOG_DEBUG("%s", e.what());
fprintf(stdout, "%s", e.what());
inst::ui::mainApp->CreateShowDialog("Failed to install Signature Patches!", (std::string)e.what(), {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("sig.generic_error"_lang, (std::string)e.what(), {"common.ok"_lang}, true);
}
bpcExit();
}

View file

@ -1,4 +1,5 @@
#include "ui/MainApplication.hpp"
#include "util/lang.hpp"
namespace inst::ui {
MainApplication *mainApp;
@ -6,6 +7,8 @@ namespace inst::ui {
void MainApplication::OnLoad() {
mainApp = this;
Language::Load();
this->mainPage = MainPage::New();
this->netinstPage = netInstPage::New();
this->sdinstPage = sdInstPage::New();

View file

@ -66,12 +66,6 @@ namespace inst::ui {
mainApp->CallForRender();
}
std::string instPage::finishedMessage() {
std::vector<std::string> finishMessages = {"Enjoy your \"legal backups\"!", "I'm sure after you give the game a try you'll have tons of fun actually buying it!", "You buy gamu right? Nintendo-san thanka-you for your purchase!", "Bypassing DRM is great, isn't it?", "You probably saved like six trees by not buying the game! All that plastic goes somewhere!", "Nintendo ninjas have been dispatched to your current location.", "And we didn't even have to shove a political ideology down your throat to get here!"};
srand(time(NULL));
return(finishMessages[rand() % finishMessages.size()]);
}
void instPage::onInput(u64 Down, u64 Up, u64 Held, pu::ui::Touch Pos) {
}
}

View file

@ -4,6 +4,7 @@
#include "ui/mainPage.hpp"
#include "util/util.hpp"
#include "util/config.hpp"
#include "util/lang.hpp"
#include "sigInstall.hpp"
#include "data/buffered_placeholder_writer.hpp"
@ -20,7 +21,7 @@ namespace inst::ui {
tin::data::NUM_BUFFER_SEGMENTS = 2;
if (menuLoaded) {
inst::ui::appletFinished = true;
mainApp->CreateShowDialog("Applet Mode not supported", "You may experience issues using Awoo Installer in Applet Mode. If you do\nhave problems, please switch to running Awoo Installer over an installed\ntitle (hold R while starting a game) or from a forwarder!", {"OK"}, true);
mainApp->CreateShowDialog("main.applet.title"_lang, "main.applet.desc"_lang, {"common.ok"_lang}, true);
}
} else if (!appletFinished) {
inst::ui::appletFinished = true;
@ -42,27 +43,27 @@ namespace inst::ui {
this->titleImage = Image::New(0, 0, "romfs:/images/logo.png");
this->appVersionText = TextBlock::New(480, 49, "v" + inst::config::appVersion, 22);
this->appVersionText->SetColor(COLOR("#FFFFFFFF"));
this->butText = TextBlock::New(10, 678, "\ue0e0 Select \ue0e1 Exit ", 24);
this->butText = TextBlock::New(10, 678, "main.buttons"_lang, 24);
this->butText->SetColor(COLOR("#FFFFFFFF"));
this->optionMenu = pu::ui::elm::Menu::New(0, 95, 1280, COLOR("#67000000"), 94, 6);
this->optionMenu->SetOnFocusColor(COLOR("#00000033"));
this->optionMenu->SetScrollbarColor(COLOR("#170909FF"));
this->installMenuItem = pu::ui::elm::MenuItem::New("Install from SD card");
this->installMenuItem = pu::ui::elm::MenuItem::New("main.menu.sd"_lang);
this->installMenuItem->SetColor(COLOR("#FFFFFFFF"));
this->installMenuItem->SetIcon("romfs:/images/icons/micro-sd.png");
this->netInstallMenuItem = pu::ui::elm::MenuItem::New("Install over LAN or internet");
this->netInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.net"_lang);
this->netInstallMenuItem->SetColor(COLOR("#FFFFFFFF"));
this->netInstallMenuItem->SetIcon("romfs:/images/icons/cloud-download.png");
this->usbInstallMenuItem = pu::ui::elm::MenuItem::New("Install over USB");
this->usbInstallMenuItem = pu::ui::elm::MenuItem::New("main.menu.usb"_lang);
this->usbInstallMenuItem->SetColor(COLOR("#FFFFFFFF"));
this->usbInstallMenuItem->SetIcon("romfs:/images/icons/usb-port.png");
this->sigPatchesMenuItem = pu::ui::elm::MenuItem::New("Manage signature patches");
this->sigPatchesMenuItem = pu::ui::elm::MenuItem::New("main.menu.sig"_lang);
this->sigPatchesMenuItem->SetColor(COLOR("#FFFFFFFF"));
this->sigPatchesMenuItem->SetIcon("romfs:/images/icons/wrench.png");
this->settingsMenuItem = pu::ui::elm::MenuItem::New("Settings");
this->settingsMenuItem = pu::ui::elm::MenuItem::New("main.menu.set"_lang);
this->settingsMenuItem->SetColor(COLOR("#FFFFFFFF"));
this->settingsMenuItem->SetIcon("romfs:/images/icons/settings.png");
this->exitMenuItem = pu::ui::elm::MenuItem::New("Exit");
this->exitMenuItem = pu::ui::elm::MenuItem::New("main.menu.exit"_lang);
this->exitMenuItem->SetColor(COLOR("#FFFFFFFF"));
this->exitMenuItem->SetIcon("romfs:/images/icons/exit-run.png");
if (std::filesystem::exists(inst::config::appDir + "/awoo_main.png")) this->awooImage = Image::New(410, 190, inst::config::appDir + "/awoo_main.png");
@ -95,7 +96,7 @@ namespace inst::ui {
void MainPage::netInstallMenuItem_Click() {
if (inst::util::getIPAddress() == "1.0.0.127") {
inst::ui::mainApp->CreateShowDialog("Network connection not available", "Check that airplane mode is disabled and you're connected to a local network.", {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("main.net.title"_lang, "main.net.desc"_lang, {"common.ok"_lang}, true);
return;
}
mainApp->netinstPage->startNetwork();
@ -103,13 +104,13 @@ namespace inst::ui {
void MainPage::usbInstallMenuItem_Click() {
if (!inst::config::usbAck) {
if (mainApp->CreateShowDialog("Warning!", "USB installations may not \"just werk\" on some devices and setups.\nIf you experience issues with USB installations, please don't pull your\nhair out! It's advised to use ns-usbloader for USB installations, or\nLAN/Internet installations instead for remote installation, especially\nwhen paired with an ethernet adapter!\n\nYou have been warned...", {"OK", "Don't tell me again"}, false) == 1) {
if (mainApp->CreateShowDialog("main.usb.warn.title"_lang, "main.usb.warn.desc"_lang, {"common.ok"_lang, "main.usb.warn.opt1"_lang}, false) == 1) {
inst::config::usbAck = true;
inst::config::setConfig();
}
}
if (inst::util::getUsbState() == 5) mainApp->usbinstPage->startUsb();
else mainApp->CreateShowDialog("No USB connection detected", "Plug in to a compatible device to install over USB", {"OK"}, false);
else mainApp->CreateShowDialog("main.usb.error.title"_lang, "main.usb.error.desc"_lang, {"common.ok"_lang}, false);
}
void MainPage::sigPatchesMenuItem_Click() {

View file

@ -6,6 +6,7 @@
#include "util/util.hpp"
#include "util/config.hpp"
#include "util/curl.hpp"
#include "util/lang.hpp"
#include "netInstall.hpp"
#define COLOR(hex) pu::ui::Color::FromHex(hex)
@ -74,7 +75,7 @@ namespace inst::ui {
}
void netInstPage::startNetwork() {
this->butText->SetText("\ue0e3 Install Over Internet \ue0e2 Help \ue0e1 Cancel ");
this->butText->SetText("inst.net.buttons"_lang);
this->menu->SetVisible(false);
this->menu->ClearItems();
this->infoImage->SetVisible(true);
@ -85,29 +86,29 @@ namespace inst::ui {
return;
} else if (this->ourUrls[0] == "supplyUrl") {
std::string keyboardResult;
switch (mainApp->CreateShowDialog("Where do you want to install from?", "Press B to cancel", {"URL", "Google Drive"}, false)) {
switch (mainApp->CreateShowDialog("inst.net.src.title"_lang, "common.cancel_desc"_lang, {"inst.net.src.opt0"_lang, "inst.net.src.opt1"_lang}, false)) {
case 0:
keyboardResult = inst::util::softwareKeyboard("Enter the Internet address of a file", lastUrl, 500);
keyboardResult = inst::util::softwareKeyboard("inst.net.url.hint"_lang, lastUrl, 500);
if (keyboardResult.size() > 0) {
lastUrl = keyboardResult;
if (inst::util::formatUrlString(keyboardResult) == "" || keyboardResult == "https://" || keyboardResult == "http://") {
mainApp->CreateShowDialog("The URL specified is invalid!", "", {"OK"}, false);
mainApp->CreateShowDialog("inst.net.url.invalid"_lang, "", {"common.ok"_lang}, false);
break;
}
sourceString = " from URL";
sourceString = "inst.net.url.source_string"_lang;
this->selectedUrls = {keyboardResult};
this->startInstall(true);
return;
}
break;
case 1:
keyboardResult = inst::util::softwareKeyboard("Enter the file ID of a public Google Drive file", lastFileID, 50);
keyboardResult = inst::util::softwareKeyboard("inst.net.gdrive_hint"_lang, lastFileID, 50);
if (keyboardResult.size() > 0) {
lastFileID = keyboardResult;
std::string fileName = inst::util::getDriveFileName(keyboardResult);
if (fileName.size() > 0) this->alternativeNames = {fileName};
else this->alternativeNames = {"Google Drive File"};
sourceString = " from Google Drive";
else this->alternativeNames = {"inst.net.gdrive.alt_name"_lang};
sourceString = "inst.net.gdrive.source_string"_lang;
this->selectedUrls = {"https://www.googleapis.com/drive/v3/files/" + keyboardResult + "?key=" + inst::config::gAuthKey + "&alt=media"};
this->startInstall(true);
return;
@ -118,9 +119,9 @@ namespace inst::ui {
return;
} else {
mainApp->CallForRender(); // If we re-render a few times during this process the main screen won't flicker
sourceString = " over local network";
this->pageInfoText->SetText("Select what files you want to install from the server, then press the Plus button!");
this->butText->SetText("\ue0e0 Select File \ue0e3 Select All \ue0ef Install File(s) \ue0e1 Cancel ");
sourceString = "inst.net.source_string"_lang;
this->pageInfoText->SetText("inst.net.top_info"_lang);
this->butText->SetText("inst.net.buttons"_lang);
this->drawMenuItems(true);
this->menu->SetSelectedIndex(0);
mainApp->CallForRender();
@ -136,8 +137,8 @@ namespace inst::ui {
std::string ourUrlString;
if (this->alternativeNames.size() > 0) ourUrlString = inst::util::shortenString(this->alternativeNames[0], 32, true);
else ourUrlString = inst::util::shortenString(inst::util::formatUrlString(this->selectedUrls[0]), 32, true);
dialogResult = mainApp->CreateShowDialog("Where should " + ourUrlString + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
} else dialogResult = mainApp->CreateShowDialog("Where should the selected " + std::to_string(this->selectedUrls.size()) + " files be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
dialogResult = mainApp->CreateShowDialog("inst.target.desc0"_lang + ourUrlString + "inst.target.desc1"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false);
} else dialogResult = mainApp->CreateShowDialog("inst.target.desc00"_lang + std::to_string(this->selectedUrls.size()) + "inst.target.desc01"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false);
if (dialogResult == -1 && !urlMode) return;
else if (dialogResult == -1 && urlMode) {
this->startNetwork();

View file

@ -7,6 +7,7 @@
#include "util/util.hpp"
#include "util/config.hpp"
#include "util/curl.hpp"
#include "util/lang.hpp"
#include "ui/instPage.hpp"
#define COLOR(hex) pu::ui::Color::FromHex(hex)
@ -24,9 +25,9 @@ namespace inst::ui {
this->titleImage = Image::New(0, 0, "romfs:/images/logo.png");
this->appVersionText = TextBlock::New(480, 49, "v" + inst::config::appVersion, 22);
this->appVersionText->SetColor(COLOR("#FFFFFFFF"));
this->pageInfoText = TextBlock::New(10, 109, "Change Awoo Installer's settings!", 30);
this->pageInfoText = TextBlock::New(10, 109, "options.title"_lang, 30);
this->pageInfoText->SetColor(COLOR("#FFFFFFFF"));
this->butText = TextBlock::New(10, 678, "\ue0e0 Select/Change \ue0e1 Cancel ", 24);
this->butText = TextBlock::New(10, 678, "options.buttons"_lang, 24);
this->butText->SetColor(COLOR("#FFFFFFFF"));
this->menu = pu::ui::elm::Menu::New(0, 156, 1280, COLOR("#FFFFFF00"), 84, (506 / 84));
this->menu->SetOnFocusColor(COLOR("#00000033"));
@ -43,11 +44,11 @@ namespace inst::ui {
}
void optionsPage::askToUpdate(std::vector<std::string> updateInfo) {
if (!mainApp->CreateShowDialog("Update available", "Awoo Installer " + updateInfo[0] + " is available now! Ready to update?", {"Update", "Cancel"}, false)) {
if (!mainApp->CreateShowDialog("options.update.title"_lang, "options.update.desc0"_lang + updateInfo[0] + "options.update.desc1"_lang, {"options.update.opt0"_lang, "common.cancel"_lang}, false)) {
inst::ui::instPage::loadInstallScreen();
inst::ui::instPage::setTopInstInfoText("Updating to Awoo Installer " + updateInfo[0]);
inst::ui::instPage::setTopInstInfoText("options.update.top_info"_lang + updateInfo[0]);
inst::ui::instPage::setInstBarPerc(0);
inst::ui::instPage::setInstInfoText("Downloading Awoo Installer " + updateInfo[0]);
inst::ui::instPage::setInstInfoText("options.update.bot_info"_lang + updateInfo[0]);
try {
romfsExit();
std::string curName = inst::config::appDir + "/Awoo-Installer.nro";
@ -55,9 +56,9 @@ namespace inst::ui {
inst::curl::downloadFile(updateInfo[1], downloadName.c_str(), 0, true);
if (std::filesystem::exists(curName)) std::filesystem::remove(curName);
std::filesystem::rename(downloadName, curName);
mainApp->CreateShowDialog("Update complete!", "The software will now be closed.", {"OK"}, false);
mainApp->CreateShowDialog("options.update.complete"_lang, "options.update.end_desc"_lang, {"common.ok"_lang}, false);
} catch (...) {
mainApp->CreateShowDialog("Update failed!", "The software will now be closed.", {"OK"}, false);
mainApp->CreateShowDialog("options.update.failed"_lang, "options.update.end_desc"_lang, {"common.ok"_lang}, false);
}
mainApp->FadeOut();
mainApp->Close();
@ -72,37 +73,37 @@ namespace inst::ui {
void optionsPage::setMenuText() {
this->menu->ClearItems();
auto ignoreFirmOption = pu::ui::elm::MenuItem::New("Ignore minimum firmware version required by titles");
auto ignoreFirmOption = pu::ui::elm::MenuItem::New("options.menu_items.ignore_firm"_lang);
ignoreFirmOption->SetColor(COLOR("#FFFFFFFF"));
ignoreFirmOption->SetIcon(this->getMenuOptionIcon(inst::config::ignoreReqVers));
this->menu->AddItem(ignoreFirmOption);
auto validateOption = pu::ui::elm::MenuItem::New("Verify NCA signatures before installation");
auto validateOption = pu::ui::elm::MenuItem::New("options.menu_items.nca_verify"_lang);
validateOption->SetColor(COLOR("#FFFFFFFF"));
validateOption->SetIcon(this->getMenuOptionIcon(inst::config::validateNCAs));
this->menu->AddItem(validateOption);
auto overclockOption = pu::ui::elm::MenuItem::New("Enable \"boost mode\" during installations");
auto overclockOption = pu::ui::elm::MenuItem::New("options.menu_items.boost_mode"_lang);
overclockOption->SetColor(COLOR("#FFFFFFFF"));
overclockOption->SetIcon(this->getMenuOptionIcon(inst::config::overClock));
this->menu->AddItem(overclockOption);
auto deletePromptOption = pu::ui::elm::MenuItem::New("Ask to delete original files after installation");
auto deletePromptOption = pu::ui::elm::MenuItem::New("options.menu_items.ask_delete"_lang);
deletePromptOption->SetColor(COLOR("#FFFFFFFF"));
deletePromptOption->SetIcon(this->getMenuOptionIcon(inst::config::deletePrompt));
this->menu->AddItem(deletePromptOption);
auto autoUpdateOption = pu::ui::elm::MenuItem::New("Check for updates to Awoo Installer automatically");
auto autoUpdateOption = pu::ui::elm::MenuItem::New("options.menu_items.auto_update"_lang);
autoUpdateOption->SetColor(COLOR("#FFFFFFFF"));
autoUpdateOption->SetIcon(this->getMenuOptionIcon(inst::config::autoUpdate));
this->menu->AddItem(autoUpdateOption);
auto gayModeOption = pu::ui::elm::MenuItem::New("Remove anime");
auto gayModeOption = pu::ui::elm::MenuItem::New("options.menu_items.gay_option"_lang);
gayModeOption->SetColor(COLOR("#FFFFFFFF"));
gayModeOption->SetIcon(this->getMenuOptionIcon(inst::config::gayMode));
this->menu->AddItem(gayModeOption);
auto sigPatchesUrlOption = pu::ui::elm::MenuItem::New("Signature patches source URL: " + inst::util::shortenString(inst::config::sigPatchesUrl, 42, false));
auto sigPatchesUrlOption = pu::ui::elm::MenuItem::New("options.menu_items.sig_url"_lang + inst::util::shortenString(inst::config::sigPatchesUrl, 42, false));
sigPatchesUrlOption->SetColor(COLOR("#FFFFFFFF"));
this->menu->AddItem(sigPatchesUrlOption);
auto updateOption = pu::ui::elm::MenuItem::New("Check for updates to Awoo Installer");
auto updateOption = pu::ui::elm::MenuItem::New("options.menu_items.check_update"_lang);
updateOption->SetColor(COLOR("#FFFFFFFF"));
this->menu->AddItem(updateOption);
auto creditsOption = pu::ui::elm::MenuItem::New("Credits");
auto creditsOption = pu::ui::elm::MenuItem::New("options.menu_items.credits"_lang);
creditsOption->SetColor(COLOR("#FFFFFFFF"));
this->menu->AddItem(creditsOption);
}
@ -122,7 +123,7 @@ namespace inst::ui {
break;
case 1:
if (inst::config::validateNCAs) {
if (inst::ui::mainApp->CreateShowDialog("Warning!", "Some installable files may contain malicious contents! Only disable this\nfeature if you are absolutely certain the software you will be installing\nis trustworthy!\n\nDo you still want to disable NCA signature verification?", {"Cancel", "Yes, I want a brick"}, false) == 1) inst::config::validateNCAs = false;
if (inst::ui::mainApp->CreateShowDialog("options.nca_warn.title"_lang, "options.nca_warn.desc"_lang, {"common.cancel"_lang, "options.nca_warn.opt1"_lang}, false) == 1) inst::config::validateNCAs = false;
} else inst::config::validateNCAs = true;
inst::config::setConfig();
this->setMenuText();
@ -157,7 +158,7 @@ namespace inst::ui {
this->setMenuText();
break;
case 6:
keyboardResult = inst::util::softwareKeyboard("Enter the URL to obtain Signature Patches from", inst::config::sigPatchesUrl.c_str(), 500);
keyboardResult = inst::util::softwareKeyboard("options.sig_hint"_lang, inst::config::sigPatchesUrl.c_str(), 500);
if (keyboardResult.size() > 0) {
inst::config::sigPatchesUrl = keyboardResult;
inst::config::setConfig();
@ -166,18 +167,18 @@ namespace inst::ui {
break;
case 7:
if (inst::util::getIPAddress() == "1.0.0.127") {
inst::ui::mainApp->CreateShowDialog("Network connection not available", "Check that airplane mode is disabled and you're connected to a local network.", {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("main.net.title"_lang, "main.net.desc"_lang, {"common.ok"_lang}, true);
break;
}
downloadUrl = inst::util::checkForAppUpdate();
if (!downloadUrl.size()) {
mainApp->CreateShowDialog("No updates found", "You are on the latest version of Awoo Installer!", {"OK"}, false);
mainApp->CreateShowDialog("options.update.title_check_fail"_lang, "options.update.desc_check_fail"_lang, {"common.ok"_lang}, false);
break;
}
this->askToUpdate(downloadUrl);
break;
case 8:
inst::ui::mainApp->CreateShowDialog("Thanks to the following people!", "- HookedBehemoth for A LOT of contributions\n- Adubbz and other contributors for Tinfoil\n- XorTroll for Plutonium and Goldleaf\n- blawar (wife beater) and nicoboss for NSZ support\n- The kind folks at the AtlasNX Discuck (or at least some of them)\n- The also kind folks at the RetroNX Discuck (of no direct involvement)\n- namako8982 for the Momiji art\n- TheXzoron for being a baka", {"Close"}, true);
inst::ui::mainApp->CreateShowDialog("options.credits.title"_lang, "options.credits.desc"_lang, {"common.close"_lang}, true);
break;
default:
break;

View file

@ -5,6 +5,7 @@
#include "sdInstall.hpp"
#include "util/util.hpp"
#include "util/config.hpp"
#include "util/lang.hpp"
#define COLOR(hex) pu::ui::Color::FromHex(hex)
@ -21,9 +22,9 @@ namespace inst::ui {
this->titleImage = Image::New(0, 0, "romfs:/images/logo.png");
this->appVersionText = TextBlock::New(480, 49, "v" + inst::config::appVersion, 22);
this->appVersionText->SetColor(COLOR("#FFFFFFFF"));
this->pageInfoText = TextBlock::New(10, 109, "Select what files you want to install, then press the Plus button!", 30);
this->pageInfoText = TextBlock::New(10, 109, "inst.sd.top_info"_lang, 30);
this->pageInfoText->SetColor(COLOR("#FFFFFFFF"));
this->butText = TextBlock::New(10, 678, "\ue0e0 Select File \ue0e3 Select All \ue0ef Install File(s) \ue0e2 Help \ue0e1 Cancel ", 24);
this->butText = TextBlock::New(10, 678, "inst.sd.buttons"_lang, 24);
this->butText->SetColor(COLOR("#FFFFFFFF"));
this->menu = pu::ui::elm::Menu::New(0, 156, 1280, COLOR("#FFFFFF00"), 84, (506 / 84));
this->menu->SetOnFocusColor(COLOR("#00000033"));
@ -114,8 +115,8 @@ namespace inst::ui {
void sdInstPage::startInstall() {
int dialogResult = -1;
if (this->selectedTitles.size() == 1) {
dialogResult = mainApp->CreateShowDialog("Where should " + inst::util::shortenString(std::filesystem::path(this->selectedTitles[0]).filename().string(), 32, true) + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
} else dialogResult = mainApp->CreateShowDialog("Where should the selected " + std::to_string(this->selectedTitles.size()) + " files be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
dialogResult = mainApp->CreateShowDialog("inst.target.desc0"_lang + inst::util::shortenString(std::filesystem::path(this->selectedTitles[0]).filename().string(), 32, true) + "inst.target.desc1"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false);
} else dialogResult = mainApp->CreateShowDialog("inst.target.desc00"_lang + std::to_string(this->selectedTitles.size()) + "inst.target.desc01"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false);
if (dialogResult == -1) return;
nspInstStuff::installNspFromFile(this->selectedTitles, dialogResult);
}
@ -143,7 +144,7 @@ namespace inst::ui {
}
}
if ((Down & KEY_X)) {
inst::ui::mainApp->CreateShowDialog("Help", "Copy your NSP, NSZ, XCI, or XCZ files to your SD card, browse to and\nselect the ones you want to install, then press the Plus button.", {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("inst.sd.help.title"_lang, "inst.sd.help.desc"_lang, {"common.ok"_lang}, true);
}
if (Down & KEY_PLUS) {
if (this->selectedTitles.size() == 0 && this->menu->GetItems()[this->menu->GetSelectedIndex()]->GetIcon() == "romfs:/images/icons/checkbox-blank-outline.png") {

View file

@ -2,6 +2,7 @@
#include "ui/MainApplication.hpp"
#include "util/util.hpp"
#include "util/config.hpp"
#include "util/lang.hpp"
#include "usbInstall.hpp"
@ -65,8 +66,8 @@ namespace inst::ui {
}
void usbInstPage::startUsb() {
this->pageInfoText->SetText("USB connection successful! Waiting for list of files to be sent...");
this->butText->SetText("\ue0e2 (Hold) Help \ue0e1 (Hold) Cancel ");
this->pageInfoText->SetText("inst.usb.top_info"_lang);
this->butText->SetText("inst.usb.buttons"_lang);
this->menu->SetVisible(false);
this->menu->ClearItems();
this->infoImage->SetVisible(true);
@ -78,8 +79,8 @@ namespace inst::ui {
return;
} else {
mainApp->CallForRender(); // If we re-render a few times during this process the main screen won't flicker
this->pageInfoText->SetText("Select what files you want to install over USB, then press the Plus button!");
this->butText->SetText("\ue0e0 Select File \ue0e3 Select All \ue0ef Install File(s) \ue0e1 Cancel ");
this->pageInfoText->SetText("inst.usb.top_info2"_lang);
this->butText->SetText("inst.usb.buttons2"_lang);
this->drawMenuItems(true);
this->menu->SetSelectedIndex(0);
mainApp->CallForRender();
@ -91,8 +92,8 @@ namespace inst::ui {
void usbInstPage::startInstall() {
int dialogResult = -1;
if (this->selectedTitles.size() == 1) dialogResult = mainApp->CreateShowDialog("Where should " + inst::util::shortenString(inst::util::formatUrlString(this->selectedTitles[0]), 32, true) + " be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
else dialogResult = mainApp->CreateShowDialog("Where should the selected " + std::to_string(this->selectedTitles.size()) + " files be installed to?", "Press B to cancel", {"SD Card", "Internal Storage"}, false);
if (this->selectedTitles.size() == 1) dialogResult = mainApp->CreateShowDialog("inst.target.desc0"_lang + inst::util::shortenString(inst::util::formatUrlString(this->selectedTitles[0]), 32, true) + "inst.target.desc1"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false);
else dialogResult = mainApp->CreateShowDialog("inst.target.desc00"_lang + std::to_string(this->selectedTitles.size()) + "inst.target.desc01"_lang, "common.cancel_desc"_lang, {"inst.target.opt0"_lang, "inst.target.opt1"_lang}, false);
if (dialogResult == -1) return;
usbInstStuff::installTitleUsb(this->selectedTitles, dialogResult);
return;

View file

@ -31,6 +31,7 @@ SOFTWARE.
#include "util/usb_util.hpp"
#include "util/util.hpp"
#include "util/config.hpp"
#include "util/lang.hpp"
#include "ui/MainApplication.hpp"
#include "ui/usbInstPage.hpp"
#include "ui/instPage.hpp"
@ -54,7 +55,7 @@ namespace usbInstStuff {
hidScanInput();
u64 kDown = hidKeysDown(CONTROLLER_P1_AUTO);
if (kDown & KEY_B) return {};
if (kDown & KEY_X) inst::ui::mainApp->CreateShowDialog("Help", "Files can be installed over USB from other devices using tools such as\nns-usbloader in Tinfoil mode. To send files to your Switch, open one of\nthese pieces of software on your PC, select your files, then upload to\nyour console!\n\nUnfortunately USB installations require a specific setup on some\nplatforms, and can be rather buggy at times. If you can't figure it out,\ngive LAN/internet installs a try, or copy your files to your SD card and\ntry the \"Install from SD Card\" option on the main menu!", {"OK"}, true);
if (kDown & KEY_X) inst::ui::mainApp->CreateShowDialog("inst.usb.help.title"_lang, "inst.usb.help.desc"_lang, {"common.ok"_lang}, true);
if (inst::util::getUsbState() != 5) return {};
}
@ -100,7 +101,7 @@ namespace usbInstStuff {
try {
for (fileItr = 0; fileItr < ourTitleList.size(); fileItr++) {
inst::ui::instPage::setTopInstInfoText("Installing " + fileNames[fileItr] + " over USB");
inst::ui::instPage::setTopInstInfoText("inst.info_page.top_info0"_lang + fileNames[fileItr] + "inst.usb.source_string"_lang);
std::unique_ptr<tin::install::Install> installTask;
if (ourTitleList[fileItr].compare(ourTitleList[fileItr].size() - 3, 2, "xc") == 0) {
@ -112,7 +113,7 @@ namespace usbInstStuff {
}
LOG_DEBUG("%s\n", "Preparing installation");
inst::ui::instPage::setInstInfoText("Preparing installation...");
inst::ui::instPage::setInstInfoText("inst.info_page.preparing"_lang);
inst::ui::instPage::setInstBarPerc(0);
installTask->Prepare();
@ -123,10 +124,10 @@ namespace usbInstStuff {
LOG_DEBUG("Failed to install");
LOG_DEBUG("%s", e.what());
fprintf(stdout, "%s", e.what());
inst::ui::instPage::setInstInfoText("Failed to install " + fileNames[fileItr]);
inst::ui::instPage::setInstInfoText("inst.info_page.failed"_lang + fileNames[fileItr]);
inst::ui::instPage::setInstBarPerc(0);
std::thread audioThread(inst::util::playAudio,"romfs:/audio/bark.wav");
inst::ui::mainApp->CreateShowDialog("Failed to install " + fileNames[fileItr] + "!", "Partially installed contents can be removed from the System Settings applet.\n\n" + (std::string)e.what(), {"OK"}, true);
inst::ui::mainApp->CreateShowDialog("inst.info_page.failed"_lang + fileNames[fileItr] + "!", "inst.info_page.failed_desc"_lang + "\n\n" + (std::string)e.what(), {"common.ok"_lang}, true);
audioThread.join();
nspInstalled = false;
}
@ -139,11 +140,11 @@ namespace usbInstStuff {
if(nspInstalled) {
tin::util::USBCmdManager::SendExitCmd();
inst::ui::instPage::setInstInfoText("Install complete");
inst::ui::instPage::setInstInfoText("inst.info_page.complete"_lang);
inst::ui::instPage::setInstBarPerc(100);
std::thread audioThread(inst::util::playAudio,"romfs:/audio/awoo.wav");
if (ourTitleList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + " files installed successfully!", inst::ui::instPage::finishedMessage(), {"OK"}, true);
else inst::ui::mainApp->CreateShowDialog(fileNames[0] + " installed!", inst::ui::instPage::finishedMessage(), {"OK"}, true);
if (ourTitleList.size() > 1) inst::ui::mainApp->CreateShowDialog(std::to_string(ourTitleList.size()) + "inst.info_page.desc0"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true);
else inst::ui::mainApp->CreateShowDialog(fileNames[0] + "inst.info_page.desc1"_lang, Language::GetRandomMsg(), {"common.ok"_lang}, true);
audioThread.join();
}

31
source/util/lang.cpp Executable file
View file

@ -0,0 +1,31 @@
#include "util/lang.hpp"
#include <iostream>
namespace Language {
json lang;
void Load() {
std::ifstream ifs("romfs:/lang/en.json");
if (!ifs.good()) {
std::cout << "[FAILED TO LOAD LANGUAGE FILE]" << std::endl;
return;
}
lang = json::parse(ifs);
ifs.close();
}
std::string LanguageEntry(std::string key) {
json j = GetRelativeJson(lang, key);
if (j == nullptr) {
return "didn't find: " + key;
}
return j.get<std::string>();
}
std::string GetRandomMsg() {
json j = Language::GetRelativeJson(lang, "inst.finished");
srand(time(NULL));
return(j[rand() % j.size()]);
}
}