From fa22087cebc3062e3d9d9ed906cf1d1686681596 Mon Sep 17 00:00:00 2001 From: Huntereb Date: Thu, 19 Dec 2019 19:09:36 -0500 Subject: [PATCH] Initial translation support (only english for now) --- include/ui/instPage.hpp | 1 - include/util/lang.hpp | 28 +++++ romfs/lang/en.json | 189 +++++++++++++++++++++++++++++++++ source/install/http_nsp.cpp | 7 +- source/install/http_xci.cpp | 7 +- source/install/install_nsp.cpp | 7 +- source/install/install_xci.cpp | 12 +-- source/install/sdmc_nsp.cpp | 3 +- source/install/sdmc_xci.cpp | 3 +- source/install/usb_nsp.cpp | 10 +- source/install/usb_xci.cpp | 10 +- source/netInstall.cpp | 25 +++-- source/sdInstall.cpp | 19 ++-- source/sigInstall.cpp | 29 ++--- source/ui/MainApplication.cpp | 3 + source/ui/instPage.cpp | 6 -- source/ui/mainPage.cpp | 23 ++-- source/ui/netInstPage.cpp | 27 ++--- source/ui/optionsPage.cpp | 43 ++++---- source/ui/sdInstPage.cpp | 11 +- source/ui/usbInstPage.cpp | 13 +-- source/usbInstall.cpp | 17 +-- source/util/lang.cpp | 31 ++++++ 23 files changed, 390 insertions(+), 134 deletions(-) create mode 100755 include/util/lang.hpp create mode 100755 romfs/lang/en.json create mode 100755 source/util/lang.cpp diff --git a/include/ui/instPage.hpp b/include/ui/instPage.hpp index 798d3e7..f920687 100755 --- a/include/ui/instPage.hpp +++ b/include/ui/instPage.hpp @@ -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; diff --git a/include/util/lang.hpp b/include/util/lang.hpp new file mode 100755 index 0000000..61a7132 --- /dev/null +++ b/include/util/lang.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#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)); +} \ No newline at end of file diff --git a/romfs/lang/en.json b/romfs/lang/en.json new file mode 100755 index 0000000..044b6ac --- /dev/null +++ b/romfs/lang/en.json @@ -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" + } +} \ No newline at end of file diff --git a/source/install/http_nsp.cpp b/source/install/http_nsp.cpp index 732fa9b..d4733fa 100755 --- a/source/install/http_nsp.cpp +++ b/source/install/http_nsp.cpp @@ -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) diff --git a/source/install/http_xci.cpp b/source/install/http_xci.cpp index adec27a..84544f8 100755 --- a/source/install/http_xci.cpp +++ b/source/install/http_xci.cpp @@ -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) diff --git a/source/install/install_nsp.cpp b/source/install/install_nsp.cpp index 3b4d72a..1e15e16 100755 --- a/source/install/install_nsp.cpp +++ b/source/install/install_nsp.cpp @@ -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; diff --git a/source/install/install_xci.cpp b/source/install/install_xci.cpp index 223eb87..6e1eb46 100755 --- a/source/install/install_xci.cpp +++ b/source/install/install_xci.cpp @@ -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; diff --git a/source/install/sdmc_nsp.cpp b/source/install/sdmc_nsp.cpp index bf8b6b9..909a50c 100755 --- a/source/install/sdmc_nsp.cpp +++ b/source/install/sdmc_nsp.cpp @@ -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) { diff --git a/source/install/sdmc_xci.cpp b/source/install/sdmc_xci.cpp index 2e4432d..4671bc9 100755 --- a/source/install/sdmc_xci.cpp +++ b/source/install/sdmc_xci.cpp @@ -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) { diff --git a/source/install/usb_nsp.cpp b/source/install/usb_nsp.cpp index ee6639a..0491fb7 100755 --- a/source/install/usb_nsp.cpp +++ b/source/install/usb_nsp.cpp @@ -22,7 +22,6 @@ SOFTWARE. #include "install/usb_nsp.hpp" - #include #include #include @@ -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); } diff --git a/source/install/usb_xci.cpp b/source/install/usb_xci.cpp index 9be2054..1f5a35a 100755 --- a/source/install/usb_xci.cpp +++ b/source/install/usb_xci.cpp @@ -22,7 +22,6 @@ SOFTWARE. #include "install/usb_xci.hpp" - #include #include #include @@ -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); } diff --git a/source/netInstall.cpp b/source/netInstall.cpp index 33292bf..24008b2 100755 --- a/source/netInstall.cpp +++ b/source/netInstall.cpp @@ -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 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 {}; } } diff --git a/source/sdInstall.cpp b/source/sdInstall.cpp index c99eb08..fbb7d90 100755 --- a/source/sdInstall.cpp +++ b/source/sdInstall.cpp @@ -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 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(); } diff --git a/source/sigInstall.cpp b/source/sigInstall.cpp index 2c517e8..22175bf 100755 --- a/source/sigInstall.cpp +++ b/source/sigInstall.cpp @@ -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(); } diff --git a/source/ui/MainApplication.cpp b/source/ui/MainApplication.cpp index 79d1a96..0490588 100755 --- a/source/ui/MainApplication.cpp +++ b/source/ui/MainApplication.cpp @@ -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(); diff --git a/source/ui/instPage.cpp b/source/ui/instPage.cpp index cb2bfda..d2a2d01 100755 --- a/source/ui/instPage.cpp +++ b/source/ui/instPage.cpp @@ -66,12 +66,6 @@ namespace inst::ui { mainApp->CallForRender(); } - std::string instPage::finishedMessage() { - std::vector 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) { } } diff --git a/source/ui/mainPage.cpp b/source/ui/mainPage.cpp index 4bc870b..8599f25 100755 --- a/source/ui/mainPage.cpp +++ b/source/ui/mainPage.cpp @@ -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() { diff --git a/source/ui/netInstPage.cpp b/source/ui/netInstPage.cpp index 6f976f4..92b7dda 100755 --- a/source/ui/netInstPage.cpp +++ b/source/ui/netInstPage.cpp @@ -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(); diff --git a/source/ui/optionsPage.cpp b/source/ui/optionsPage.cpp index c30aeff..72a9c02 100755 --- a/source/ui/optionsPage.cpp +++ b/source/ui/optionsPage.cpp @@ -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 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; diff --git a/source/ui/sdInstPage.cpp b/source/ui/sdInstPage.cpp index f6b40ba..b2daa6a 100755 --- a/source/ui/sdInstPage.cpp +++ b/source/ui/sdInstPage.cpp @@ -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") { diff --git a/source/ui/usbInstPage.cpp b/source/ui/usbInstPage.cpp index d374124..3d85424 100755 --- a/source/ui/usbInstPage.cpp +++ b/source/ui/usbInstPage.cpp @@ -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; diff --git a/source/usbInstall.cpp b/source/usbInstall.cpp index 99e404c..e305822 100755 --- a/source/usbInstall.cpp +++ b/source/usbInstall.cpp @@ -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 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(); } diff --git a/source/util/lang.cpp b/source/util/lang.cpp new file mode 100755 index 0000000..851929b --- /dev/null +++ b/source/util/lang.cpp @@ -0,0 +1,31 @@ +#include "util/lang.hpp" + +#include + +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 GetRandomMsg() { + json j = Language::GetRelativeJson(lang, "inst.finished"); + srand(time(NULL)); + return(j[rand() % j.size()]); + } +} \ No newline at end of file