Auto-upload almost working.

This commit is contained in:
J-D-K 2025-07-25 21:36:58 -04:00
parent 851d969e9c
commit 721585c117
52 changed files with 3761 additions and 1345 deletions

View File

@ -2,6 +2,7 @@
#include "appstates/BaseState.hpp"
#include "data/data.hpp"
#include "fslib.hpp"
#include "remote/remote.hpp"
#include "sdl.hpp"
#include "system/Timer.hpp"
#include "ui/Menu.hpp"
@ -53,7 +54,8 @@ class BackupMenuState final : public BaseState
{
data::User *user{};
data::TitleInfo *titleInfo{};
fslib::Path path{};
fslib::Path path{}; // This and
remote::Item *remoteItem{}; // this are set when needed.
BackupMenuState *spawningState{};
};
// clang-format on
@ -77,6 +79,9 @@ class BackupMenuState final : public BaseState
/// @brief Directory listing of the above.
fslib::Directory m_directoryListing{};
/// @brief Remote storage listing of the current parent.
remote::Storage::DirectoryListing m_remoteListing{};
/// @brief This is the scrolling text at the top.
ui::TextScroll m_titleScroll{};
@ -140,8 +145,9 @@ class BackupMenuState final : public BaseState
/// @brief Just creates the pop-up that says Save is empty or w/e.
void pop_save_empty();
inline bool is_system_save_data()
inline bool user_is_system()
{
return m_saveType == FsSaveDataType_System || m_saveType == FsSaveDataType_SystemBcat;
const uint8_t saveType = m_user->get_account_save_type();
return saveType == FsSaveDataType_System || saveType == FsSaveDataType_SystemBcat;
}
};

View File

@ -93,6 +93,7 @@ class ConfirmState final : public BaseState
{
m_startingTickCount = SDL_GetTicks64();
m_yesText = m_holdText[0];
ConfirmState::center_yes();
}
else if (holdSustained)
{

View File

@ -0,0 +1,25 @@
#pragma once
#include "fslib.hpp"
#include "system/ProgressTask.hpp"
#include "system/defines.hpp"
#include <condition_variable>
#include <mutex>
#include <vector>
namespace curl
{
// clang-format off
struct DownloadStruct
{
std::mutex lock{};
std::condition_variable condition{};
std::vector<byte> sharedBuffer{};
bool bufferReady{};
fslib::File *dest{};
sys::ProgressTask *task{};
size_t offset{};
size_t fileSize{};
};
// clang-format on
}

View File

@ -1,4 +1,5 @@
#pragma once
#include "curl/DownloadStruct.hpp"
#include "curl/UploadStruct.hpp"
#include "fslib.hpp"
@ -99,6 +100,18 @@ namespace curl
/// @return Number of bytes written to the file.
size_t write_data_to_file(const char *buffer, size_t size, size_t count, fslib::File *target);
/// @brief Threaded version of the above.
/// @param buffer Incoming data from curl
/// @param size size
/// @param count count
/// @param download Struct containing data for threaded download.
/// @return size * count
size_t download_file_threaded(const char *buffer, size_t size, size_t count, curl::DownloadStruct *download);
/// @brief Function used to download files threaded.
/// @param download Struct shared by both threads.
void download_write_thread_function(curl::DownloadStruct &download);
/// @brief Gets the value of a header from an array of headers.
/// @param array Array of headers to search.
/// @param header Header to search for.

View File

@ -1,4 +1,5 @@
#pragma once
#include <string_view>
namespace logger
{
@ -9,4 +10,6 @@ namespace logger
/// @param format Format of string.
/// @param arguments Va arguments.
void log(const char *format, ...);
void log_straight(std::string_view string);
} // namespace logger

View File

@ -18,7 +18,7 @@ namespace remote
/// @brief Uploads the file from source. File name is used to name the file.
/// @param source Path to upload the file from.
bool upload_file(const fslib::Path &source, sys::ProgressTask *task = nullptr) override;
bool upload_file(const fslib::Path &source, std::string_view name, sys::ProgressTask *task = nullptr) override;
/// @brief Patches or updates the file on Google Drive.
/// @param file Pointer to the item containing the data needed to update the file.
@ -28,7 +28,9 @@ namespace remote
/// @brief Downloads a file from Google Drive.
/// @param file Pointer to the item containing data to download the file.
/// @param destination Location to write the downloaded file to.
bool download_file(const remote::Item *file, const fslib::Path &destination) override;
bool download_file(const remote::Item *file,
const fslib::Path &destination,
sys::ProgressTask *task = nullptr) override;
/// @brief Deletes an item from Google Drive.
/// @param item Pointer to item containing data to delete the item.

View File

@ -61,7 +61,7 @@ namespace remote
/// @brief Uploads a file from the SD card to the remote.
/// @param source Path to the file to upload.
virtual bool upload_file(const fslib::Path &source, sys::ProgressTask *task = nullptr) = 0;
virtual bool upload_file(const fslib::Path &source, std::string_view name, sys::ProgressTask *task = nullptr) = 0;
/// @brief Patches or updates a file on the remote.
/// @param item Item to be updated.
@ -71,7 +71,9 @@ namespace remote
/// @brief Downloads a file from the remote.
/// @param item Item to download.
/// @param destination Path to download the file to.
virtual bool download_file(const remote::Item *file, const fslib::Path &destination) = 0;
virtual bool download_file(const remote::Item *file,
const fslib::Path &destination,
sys::ProgressTask *task = nullptr) = 0;
/// @brief Searches the list for a file matching name and the current parent.
/// @param name Name of the file to search for.

View File

@ -18,7 +18,9 @@ namespace remote
/// @brief Uploads a file to the webdav server. File name is retrieved from the path.
/// @param source Local path of the file to upload.
bool upload_file(const fslib::Path &source, sys::ProgressTask *task = nullptr) override;
bool upload_file(const fslib::Path &source,
std::string_view remoteName,
sys::ProgressTask *task = nullptr) override;
/// @brief Patches or updates a file on the WebDav server.
/// @param file Pointer to the file to update.
@ -28,7 +30,9 @@ namespace remote
/// @brief Downloads the passed file from the WebDav server.
/// @param file Pointer to the file to download.
/// @param destination Path to write the downloaded data from.
bool download_file(const remote::Item *item, const fslib::Path &destination) override;
bool download_file(const remote::Item *item,
const fslib::Path &destination,
sys::ProgressTask *task = nullptr) override;
/// @brief Deletes the target item from the WebDav server.
/// @param item Item to delete.

View File

@ -23,13 +23,16 @@ namespace sys
/// @param current The current progress value.
void update_current(double current);
/// @brief Increases the current progress by a set amount.
void increase_current(double amount);
/// @brief Returns the goal value.
/// @return Goal
double get_goal() const;
/// @brief Returns the current progress.
/// @return Current progress.
double get_current() const;
double get_progress() const;
private:
// Current value and goal

View File

@ -3,26 +3,37 @@
#include "system/ProgressTask.hpp"
#include "system/Task.hpp"
#include <string>
namespace tasks
{
namespace backup
{
/// @brief Task/thread function executed when a new backup is created.
void create_new_backup(sys::ProgressTask *task,
data::User *user,
data::TitleInfo *titleInfo,
fslib::Path target,
BackupMenuState *spawningState,
bool killTask = true);
void create_new_backup_local(sys::ProgressTask *task,
data::User *user,
data::TitleInfo *titleInfo,
fslib::Path target,
BackupMenuState *spawningState,
bool killTask = true);
void create_new_backup_remote(sys::ProgressTask *task,
data::User *user,
data::TitleInfo *titleInfo,
std::string remoteName,
BackupMenuState *spawningState,
bool killTask = true);
/// @brief Overwrites a pre-existing backup.
void overwrite_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
void overwrite_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
void overwrite_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
/// @brief Restores a backup
void restore_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
void restore_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
void restore_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData);
/// @brief Deletes a backup
void delete_backup(sys::Task *task, BackupMenuState::TaskData taskData);
void delete_backup_local(sys::Task *task, BackupMenuState::TaskData taskData);
void delete_backup_remote(sys::Task *task, BackupMenuState::TaskData taskData);
/// @brief Uploads a backup
void upload_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData);

View File

@ -1,5 +1,6 @@
#pragma once
#include "system/Timer.hpp"
#include <mutex>
#include <string>
#include <vector>
@ -10,25 +11,25 @@ namespace ui
typedef struct
{
// Y coordinate
double m_y;
double y{};
// Target Y coordinate
double m_targetY;
double targetY{};
// Width of the message.
size_t m_width;
size_t width{};
// Message string.
std::string m_message;
std::string message{};
// Timer.
sys::Timer m_timer;
sys::Timer timer{};
} PopMessage;
class PopMessageManager
{
public:
// No copying.
PopMessageManager(const PopMessageManager &) = delete;
PopMessageManager(PopMessageManager &&) = delete;
PopMessageManager(const PopMessageManager &) = delete;
PopMessageManager(PopMessageManager &&) = delete;
PopMessageManager &operator=(const PopMessageManager &) = delete;
PopMessageManager &operator=(PopMessageManager &&) = delete;
PopMessageManager &operator=(PopMessageManager &&) = delete;
/// @brief Updates and processes message queue.
static void update();
@ -37,13 +38,10 @@ namespace ui
static void render();
/// @brief Pushes a new message to the queue for processing.
/// @param displayTicks Number of ticks for the message to be displayed until it is purged.
/// @param format Format of message.
/// @param args Arguments for message.
static void push_message(int displayTicks, const char *format, ...);
static void push_message(int displayTicks, std::string_view message);
/// @brief The default duration of ticks for messages to be shown.
static constexpr int DEFAULT_MESSAGE_TICKS = 2500;
static constexpr int DEFAULT_TICKS = 2500;
private:
// Only one instance allowed.

View File

@ -1,150 +1,215 @@
{
"TranslationInfo": [
"Übersetzt von: %s",
"NULL"
"BackupMenu": [
"0: Neues Backup"
],
"BackupMenuConfirmations": [
"0: Bist du sicher, dass du #%s# wirklich überschreiben möchtest?",
"1: Bist du sicher, dass du #%s# wirklich wiederherstellen möchtest?",
"2: Bist du sicher, dass du #%s# wirklich löschen möchtest?"
],
"BackupMenuPops": [
"0: Speicherdaten sind leer!",
"1: Backup ist leer!",
"2: Fehler beim Zurücksetzen der Speicherdaten!",
"3: Fehler beim Öffnen der ZIP-Datei zum Lesen!",
"4: Fehler beim Löschen des Backups!",
"5: Fehler beim Erstellen des Backups!",
"6: Schreiben auf das System ist deaktiviert!",
"7: ZIP-Datei konnte nicht zum Lesen geöffnet werden!"
],
"BackupMenuStatus": [
"0: Verarbeite Metadatei der Speicherdaten...",
"1: Lade #%s# in den Cloud-Speicher hoch...",
"2: Aktualisiere #%s# im Cloud-Speicher..."
],
"ControlGuides": [
"[A] Auswählen [Y] Alle Speicherstände ausgeben [X] Benutzeroptionen",
"[A] Auswählen [L] [R] Springen [Y] Favorit [X] Titeloptionen [B] Zurück",
"[A] Auswählen [Y] Wiederherstellen [X] Löschen [ZR] Hochladen [B] Schließen",
"[A] Umschalten [X] Standardwerte [B] Zurück"
],
"SaveDataTypes": [
"System",
"Konto",
"BCAT",
"Gerät",
"Temporär",
"Cache",
"System BCAT"
],
"SettingsMenu": [
"JKSV-Ausgabeverzeichnis festlegen.",
"Blacklist bearbeiten",
"Gerätespeicher mit Benutzern einbeziehen: %s",
"Automatisches Backup bei Wiederherstellung: %s",
"Backups automatisch benennen: %s",
"Backups automatisch in den entfernten Speicher hochladen: %s",
"Zum Löschen von Backups gedrückt halten: %s",
"Zum Wiederherstellen von Backups gedrückt halten: %s",
"Zum Überschreiben von Backups gedrückt halten: %s",
"Nur mountbare Titel auflisten: %s",
"Systemspeicherstände des Kontos anzeigen: %s",
"Schreiben in Systemspeicher und NAND aktivieren: %s",
"Speicherstände in ZIP exportieren: %s",
"ZIP-Komprimierungsstufe: %u",
"Titelsortierungstyp: %s",
"Textmenü (JKSM) Modus: %s",
"Englisch erzwingen: %s",
"Papierkorb aktivieren: %s",
"Animationsskalierung: %.02f"
"0: [A] Auswählen [Y] Alle Speicherdaten sichern [X] Benutzeroptionen",
"1: [A] Auswählen [L] [R] Springen [Y] Favorit [X] Titeloptionen [B] Zurück",
"2: [A] Auswählen [Y] Wiederherstellen [X] Löschen [ZR] Hochladen [B] Schließen",
"3: [A] Umschalten [X] Standardwerte [B] Zurück"
],
"ExtrasMenu": [
"Titel neu laden",
"SD-zu-SD-Browser",
"BIS: ProfInfoF",
"BIS: Sicher",
"BIS: System",
"BIS: Benutzer",
"Prozess beenden",
"Systemspeicher mounten"
"0: Daten zurücksetzen",
"1: SD zu SD Browser",
"2: ProdInfoF",
"3: Sicher",
"4: System",
"5: Benutzer",
"6: Prozess beenden"
],
"OnOff": [
"Aus",
">Ein>"
"ExtrasPops": [
"0: Daten wurden zurückgesetzt!",
"1: Zurücksetzen der Daten fehlgeschlagen!"
],
"BackupMenu": [
"Neues Backup"
"GeneralPops": [
"0: JKSV kann nicht beendet werden, während Aufgaben laufen!"
],
"CopyingFiles": [
"Kopiere #%s#...",
"Komprimiere #%s# zu ZIP...",
"Dekomprimiere #%s# aus ZIP..."
"GoogleDriveStrings": [
"0: Um fortzufahren, gehe zu #%s# und gib >%s> ein!",
"1: Erfolgreich bei Google Drive angemeldet!",
"2: Anmeldung bei Google Drive fehlgeschlagen!"
],
"HoldingStrings": [
"0: Halte [A] gedrückt",
"1: Halte [A] weiter gedrückt",
"2: Fast geschafft! [A] gedrückt halten"
],
"IOStatuses": [
"0: Kopiere #%s#...",
"1: Komprimiere #%s# in ZIP...",
"2: Dekomprimiere #%s# aus ZIP...",
"3: Lösche #%s#..."
],
"IOPops": [
"0: Fehler beim Schreiben auf das Gerät!"
],
"KeyboardStrings": [
"Geben Sie einen neuen Backup-Namen ein.",
"Cache-Index eingeben.",
"Neuen Ausgabepfad für JKSV eingeben",
"Prozess-ID zum Beenden eingeben.",
"Systemspeicher-ID eingeben",
"Geben Sie einen neuen Namen für das Zielobjekt ein.",
"Geben Sie einen Namen für den neuen Ordner ein.",
"Neuen Namen für das Ausgabeverzeichnis von %s eingeben.",
"Geben Sie an, wie viel erweitert werden soll (in MB)."
]
}
{
"0: Gib einen neuen Namen für das Backup ein.",
"1: Cache-Index eingeben.",
"2: Gib einen neuen Ausgabepfad für JKSV ein",
"3: Gib die Prozess-ID zum Beenden ein.",
"4: Gib eine System-Speicher-ID ein",
"5: Gib einen neuen Namen für das Zielobjekt ein.",
"6: Gib einen Namen für den neuen Ordner ein.",
"7: Gib einen neuen Ausgabepfadnamen für %s ein.",
"8: Gib an, um wie viel erweitert werden soll (in MB)."
],
"OnOff": [
"0: Aus",
"1: >Ein>"
],
"SaveCreatePops": [
"0: Speicherdaten für #%s# erstellt!",
"1: Fehler beim Erstellen der Speicherdaten!",
"2: Fehler beim Löschen der Speicherdaten!"
],
"SaveDataTypes": [
"0: System",
"1: Benutzerkonto",
"2: BCAT",
"3: Gerät",
"4: Temporär",
"5: Cache",
"6: System-BCAT"
],
"SettingsDescriptions": [
"0: Legt das Arbeitsverzeichnis für JKSV fest. Der Standardwert ist `sdmc:/JKSV`.",
"1: Ermöglicht das Entfernen von Titeln aus der Blacklist.",
"2: Beinhaltet Geräte- oder gemeinsame Speicherstände mit Benutzern.",
"3: Erstellt automatisch ein Backup beim Wiederherstellen eines anderen.",
"4: Vergibt automatisch Backup-Namen und überspringt die Tastatureingabe.",
"5: Lädt Backups automatisch zu Google Drive oder WebDav hoch und löscht sie lokal.",
"6: Ob das Halten von [A] für drei Sekunden erforderlich ist, um Backups zu löschen.",
"7: Ob das Halten von [A] für drei Sekunden erforderlich ist, um Backups wiederherzustellen.",
"8: Ob das Halten von [A] für drei Sekunden erforderlich ist, um Backups zu überschreiben.",
"9: Zeigt nur Speicherdaten an, die JKSV erfolgreich öffnen kann.",
"10: Zeigt System-Speicherstände mit zugeordneten Benutzerkonten.",
"11: Aktiviert das Wiederherstellen von Systemdaten und Schreiben auf NAND-Partitionen.",
"12: Exportiert Speicherdaten als ZIP-Archive anstelle von entpackten Ordnern.",
"13: Kompressions- oder Deflate-Level beim Schreiben in ZIP. Der Standardwert ist 6. Niedrigere Werte sind schneller, bieten aber weniger Kompression und Platzersparnis. Null bedeutet keine Kompression.",
"14: Steuert, wie Titel sortiert und angezeigt werden.",
"15: Zeigt Titel als Textmenüs wie im ursprünglichen JKSM auf dem 3DS anstatt als Icons.",
"16: Erzwingt Englisch als Sprache anstelle der erkannten Systemsprache.",
"17: Verschiebt gelöschte Backups in den _TRASH_-Ordner anstatt sie dauerhaft zu löschen.",
"18: Legt die Geschwindigkeit von Übergängen und Animationen fest. Geringere Werte sind schneller."
],
"SettingsMenu": [
"0: JKSV-Ausgabeverzeichnis festlegen.",
"1: Blacklist bearbeiten",
"2: Gerätedaten mit Benutzern einbeziehen: %s",
"3: Automatisch Backup bei Wiederherstellung: %s",
"4: Backup automatisch benennen: %s",
"5: Backups automatisch in Cloud hochladen: %s",
"6: Halten zum Löschen von Backups: %s",
"7: Halten zum Wiederherstellen von Backups: %s",
"8: Halten zum Überschreiben von Backups: %s",
"9: Nur mountbare Titel anzeigen: %s",
"10: Kontenbezogene Systemdaten anzeigen: %s",
"11: Schreiben auf Systemdaten und NAND erlauben: %s",
"12: Speicherdaten als ZIP exportieren: %s",
"13: ZIP-Kompressionsstufe: %u",
"14: Titel-Sortiertyp: %s",
"15: Textmenümodus (JKSM): %s",
"16: Englisch erzwingen: %s",
"17: Papierkorb aktivieren: %s",
"18: Animationsskalierung: %.02f"
],
"SortTypes": [
"0: Alphabetisch",
"1: Meistgespielt",
"2: Zuletzt gespielt"
],
"TitleInfo": [
"0: App-ID: %016lX",
"1: Speicher-ID: %016lx",
"2: Erstes Spiel: %x - %X",
"3: Letztes Spiel: %x - %X",
"4: Spielzeit: %02d:%02d:%02d",
"5: Starts: %i",
"6: Speichertyp: %s"
],
"TitleOptionConfirmations": [
"0: Bist du sicher, dass du #%s# auf die Blacklist setzen möchtest? Danach erscheint der Titel nicht mehr in der Liste.",
"1: Bist du sicher, dass du alle derzeitigen Backups für #%s# löschen möchtest? *Dies kann nicht rückgängig gemacht werden!*",
"2: Bist du sicher, dass du die Speicherdaten für #%s# zurücksetzen möchtest? *Dies löscht die aktuellen Speicherdaten so, als wäre das Spiel nie gestartet worden!*",
"3: Bist du sicher, dass du `%s`'s Speicherdaten für #%s# löschen möchtest? *Dies wird sie dauerhaft vom System entfernen.*"
],
"TitleOptionPops": [
"0: Alle Backups für `%s` gelöscht!",
"1: Alle Backups konnten nicht gelöscht werden!",
"2: Fehler beim Zurücksetzen der Speicherdaten!",
"3: Speicherdaten erfolgreich zurückgesetzt!",
"4: SVI-Datei erfolgreich exportiert!",
"5: Fehler beim Exportieren der SVI-Datei!",
"6: Diese Option ist für Systemdaten nicht verfügbar!",
"7: Pfad konnte nicht zur Verwendung bereinigt werden!",
"8: Ausgabeverzeichnis auf #%s# gesetzt.",
"9: Fehler beim Setzen des neuen Ausgabepfads!",
"10: Speicherdaten erfolgreich erweitert!",
"11: Erweiterung der Speicherdaten fehlgeschlagen!"
],
"TitleOptionStatus": [
"0: Lösche alle Backups für #%s#.",
"1: Setze Speicherdaten für #%s# zurück.",
"2: Lösche `%s`'s Speicherdaten für #%s#...",
"3: Erweitere `%s`'s Speicherdaten für #%s#..."
],
"TitleOptions": [
"0: Informationen",
"1: Titel auf Blacklist setzen",
"2: Ausgabeverzeichnis ändern",
"3: Im Dateimodus öffnen",
"4: Alle Speicher-Backups löschen",
"5: Speicherdaten zurücksetzen.",
"6: Speicherdaten vom System löschen",
"7: Speicherdaten erweitern",
"8: SVI-Datei exportieren"
],
"TranslationInfo": [
"Übersetzt von: %s",
"NULL"
"0: Übersetzt von: %s",
"1: NULL"
],
"ControlGuides": [
"[A] Auswählen [Y] Alle Speicherstände ausgeben [X] Benutzeroptionen",
"[A] Auswählen [L] [R] Springen [Y] Favorit [X] Titeloptionen [B] Zurück",
"[A] Auswählen [Y] Wiederherstellen [X] Löschen [ZR] Hochladen [B] Schließen",
"[A] Umschalten [X] Standardwerte [B] Zurück"
"UserOptionConfirmations": [
"0: Bist du sicher, dass du die Speicherdaten für jeden gefundenen Titel für `%s` sichern willst? Dies kann eine Weile dauern.",
"1: Bist du sicher, dass du für alle gefundenen Titel auf deinem System Speicherdaten für `%s` erstellen möchtest? Dies kann eine Weile dauern.",
"2: Bist du sicher, dass du alle Speicherdaten für `%s` löschen möchtest? *Dies ist PERMANENT und kann nicht rückgängig gemacht werden.*"
],
"SaveDataTypes": [
"System",
"Konto",
"BCAT",
"Gerät",
"Temporär",
"Cache",
"System BCAT"
"UserOptionStatus": [
"0: Erstelle Speicherdaten für #%s#...",
"1: Lösche Speicherdaten für #%s#..."
],
"SettingsMenu": [
"JKSV-Ausgabeverzeichnis festlegen.",
"Blacklist bearbeiten",
"Gerätespeicher mit Benutzern einbeziehen: %s",
"Automatisches Backup bei Wiederherstellung: %s",
"Backups automatisch benennen: %s",
"Backups automatisch in den entfernten Speicher hochladen: %s",
"Zum Löschen von Backups gedrückt halten: %s",
"Zum Wiederherstellen von Backups gedrückt halten: %s",
"Zum Überschreiben von Backups gedrückt halten: %s",
"Nur mountbare Titel auflisten: %s",
"Systemspeicherstände des Kontos anzeigen: %s",
"Schreiben in Systemspeicher und NAND aktivieren: %s",
"Speicherstände in ZIP exportieren: %s",
"ZIP-Komprimierungsstufe: %u",
"Titelsortierungstyp: %s",
"Textmenü (JKSM) Modus: %s",
"Englisch erzwingen: %s",
"Papierkorb aktivieren: %s",
"Animationsskalierung: %.02f"
"UserOptions": [
"0: Alles für `%s` sichern",
"1: Speicherdaten für `%s` erstellen",
"2: Alle Speicherdaten für `%s` erstellen",
"3: Alle Speicherdaten für `%s` löschen"
],
"ExtrasMenu": [
"Titel neu laden",
"SD-zu-SD-Browser",
"BIS: ProfInfoF",
"BIS: Sicher",
"BIS: System",
"BIS: Benutzer",
"Prozess beenden",
"Systemspeicher mounten"
"WebDavStrings": [
"0: WebDav erfolgreich gestartet!",
"1: WebDav fehlgeschlagen!"
],
"OnOff": [
"Aus",
">Ein>"
],
"BackupMenu": [
"Neues Backup"
],
"CopyingFiles": [
"Kopiere #%s#...",
"Komprimiere #%s# zu ZIP...",
"Dekomprimiere #%s# aus ZIP..."
],
"KeyboardStrings": [
"Geben Sie einen neuen Backup-Namen ein.",
"Cache-Index eingeben.",
"Neuen Ausgabepfad für JKSV eingeben",
"Prozess-ID zum Beenden eingeben.",
"Systemspeicher-ID eingeben",
"Geben Sie einen neuen Namen für das Zielobjekt ein.",
"Geben Sie einen Namen für den neuen Ordner ein.",
"Neuen Namen für das Ausgabeverzeichnis von %s eingeben.",
"Geben Sie an, wie viel erweitert werden soll (in MB)."
"YesNo": [
"0: Ja [A]",
"1: Nein [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Translated By: %s",
"ChatGPT :^)"
"BackupMenu": [
"0: Commence New Backup, Wot!"
],
"BackupMenuConfirmations": [
"0: Are you quite certain you wish to overwrite #%s#? That would be frightfully final.",
"1: Are you absolutely sure youd like to restore #%s#? No turning back now, old chap.",
"2: Are you truly intent on deleting #%s#? It shall vanish into the ether!"
],
"BackupMenuPops": [
"0: Oh bother — the save data appears to be dreadfully empty!",
"1: Nothing to backup, Im afraid!",
"2: Dash it all! An error occurred whilst resetting the save data!",
"3: Egad! Couldnt open the ZIP file for a spot of reading!",
"4: A tragic mishap occurred whilst attempting to delete the backup!",
"5: Calamity! The backup couldnt be created!",
"6: Writing to the system is jolly well off-limits!",
"7: Blimey! Couldnt open the zip for reading!"
],
"BackupMenuStatus": [
"0: Perusing the metadata of the save data, pip pip...",
"1: Off it goes! Uploading #%s# to the cloud posthaste...",
"2: Spiffing! Updating #%s# on remote storage..."
],
"ControlGuides": [
"[A] Select [Y] Dump All Saves [X] User Options",
"[A] Select [L] [R] Hop About [Y] Favourite [X] Title Options [B] Back",
"[A] Select [Y] Restore [X] Delete [ZR] Upload [B] Close",
"[A] Toggle [X] Defaults [B] Back"
],
"SaveDataTypes": [
"System",
"Account",
"BCAT",
"Device",
"Temporary",
"Cache",
"System BCAT"
],
"SettingsMenu": [
"Set JKSV output folder.",
"Edit Blacklist",
"Include Device Saves with users: %s",
"Auto-backup on restore: %s",
"Auto-name backups: %s",
"Auto-upload backups to remote storage: %s",
"Hold to delete backups: %s",
"Hold to restore backups: %s",
"Hold to overwrite backups: %s",
"Only list mountable titles: %s",
"Show account system saves: %s",
"Enable writing to system saves and NAND: %s",
"Export saves to ZIP: %s",
"Zip compression level: %u",
"Title sort type: %s",
"Text menu (JKSM) mode: %s",
"Force Queen's English: %s",
"Enable rubbish bin: %s",
"Animation scaling: %.02f"
"0: [A] Select [Y] Dump All Saves [X] User Options",
"1: [A] Select [L] [R] Skip About [Y] Favourite [X] Title Shenanigans [B] Retreat",
"2: [A] Select [Y] Restore [X] Obliterate [ZR] Send Skyward [B] Close",
"3: [A] Toggle [X] Defaults [B] Back, Toodle-oo"
],
"ExtrasMenu": [
"Reload Titles",
"SD to SD Browser",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"Terminate Process",
"Mount System Save"
"0: Give the Data a Good Reinitialise",
"1: Peruse SD to SD",
"2: ProdInfoF (whatever that is!)",
"3: Rather Safe",
"4: System, God Save the Queen",
"5: User, bless 'em",
"6: Terminate the Rascally Process"
],
"OnOff": [
"Off",
">On, Mate>"
"ExtrasPops": [
"0: Capital! Data has been splendidly reinitialised!",
"1: Oh dear — data reinitialisations gone all pear-shaped!"
],
"BackupMenu": [
"New Backup"
"GeneralPops": [
"0: Hold your horses! JKSV wont be toddling off while tasks are underway!"
],
"CopyingFiles": [
"Copying #%s#, guv...",
"Compressing #%s# to a lovely ZIP...",
"Decompressing #%s# from that ZIP..."
"GoogleDriveStrings": [
"0: Right then! To carry on, nip over to #%s# and pop in >%s> like a proper gent!",
"1: Bravo! Successfully signed in to Google Drive!",
"2: Dreadfully sorry — couldnt manage the Google Drive sign-in!"
],
"HoldingStrings": [
"0: Hold [A], old bean!",
"1: Keep holding [A], stiff upper lip and all that!",
"2: Almost there, just a tick! [A]"
],
"IOStatuses": [
"0: Just copying #%s# — steady on!",
"1: Compressing #%s# into a proper ZIP... quite tidy.",
"2: Extracting #%s# from ZIP, mind the gap...",
"3: Deleting #%s#... off it goes!"
],
"IOPops": [
"0: By Jove! Couldnt commit the data to the device!"
],
"KeyboardStrings": [
"Enter a jolly new backup name.",
"Enter cache index, chap.",
"Pop in a new output path for JKSV, cheers!",
"Input process ID to terminate, old bean.",
"Enter a system save ID, govna.",
"Provide a smashing new name for the target item.",
"Enter a name for the spiffing new folder.",
"Enter a new output folder name for %s, ta.",
"Specify how much to expand (in MB), eh?"
"0: Kindly enter a new name for your backup, wont you?",
"1: Do enter the cache index, theres a good lad.",
"2: Please provide a splendid new output path for JKSV.",
"3: Enter the process ID youd like to, erm, dispatch.",
"4: Be a sport and enter a system save ID.",
"5: Enter a dashing new name for the target item.",
"6: What shall we call this charming new folder?",
"7: Pray, enter a new output folder name for %s.",
"8: Indicate the expansion size (in MB), tally-ho!"
],
"OnOff": [
"0: Off, naturally",
"1: >On, indubitably>"
],
"SaveCreatePops": [
"0: Huzzah! Save data created for #%s#!",
"1: Dreadful shame — failed to create save data!",
"2: Blast! Couldnt delete the save data!"
],
"SaveDataTypes": [
"0: System (very official)",
"1: Account (jolly private)",
"2: BCAT (whatever that means)",
"3: Device (mind the hardware)",
"4: Temporary (like a British summer)",
"5: Cache (a secret stash!)",
"6: System BCAT (double trouble!)"
],
"SettingsDescriptions": [
"0: Sets JKSVs working directory. Defaults `sdmc:/JKSV`, dont you know.",
"1: Lets you strike titles from the blacklist with the wrath of a headmaster.",
"2: Includes device saves with users, should you dare.",
"3: Makes a backup automagically when restoring — frightfully efficient.",
"4: Auto-names backups and bypasses that bothersome keyboard.",
"5: Uploads backups to Google Drive or WebDav and bins the originals, jolly smart.",
"6: Hold [A] for three whole seconds before deleting, stiff upper thumb required.",
"7: Hold [A] for three whole seconds before restoring, for good measure.",
"8: Hold [A] again — yes, again! — for three seconds to overwrite, heavens.",
"9: Shows only save data that JKSV can open without throwing a tantrum.",
"10: Reveals system saves with account IDs, if youre feeling nosy.",
"11: Enables writing to system saves and NAND, frightfully risky business.",
"12: Exports save data to ZIPs instead of unpacked nonsense.",
"13: Controls the ZIP compression level. 6 is the gentlemans choice. 0 is just lazy.",
"14: Governs how titles are sorted and arranged. Alphabetical, most splendid.",
"15: Changes the UI to an old-school text list, retro chic!",
"16: Forces English, the Queens own, regardless of your rebellious system settings.",
"17: Moves deleted backups to _TRASH_ instead of immediate vaporisation.",
"18: Sets animation speed — quicker than a fox hunt, if you like."
],
"SettingsMenu": [
"0: Set JKSV output folder, proper and tidy.",
"1: Edit the blacklist — banish those unworthy titles!",
"2: Include device saves with users: %s",
"3: Auto-backup on restore: %s (clever, that)",
"4: Auto-name backups: %s (splendidly efficient)",
"5: Auto-upload backups to remote storage: %s",
"6: Hold to delete backups: %s (stiff fingers needed!)",
"7: Hold to restore backups: %s",
"8: Hold to overwrite backups: %s",
"9: Only show titles fit to be mounted: %s",
"10: Show account system saves: %s (if you must)",
"11: Enable writing to system saves and NAND: %s (you daredevil!)",
"12: Export saves to ZIP: %s",
"13: Zip compression level: %u (very technical!)",
"14: Title sort type: %s",
"15: Text menu (JKSM) mode: %s (retro is the new posh)",
"16: Force English: %s (God Save the UI)",
"17: Enable trash bin: %s (less barbaric)",
"18: Animation scaling: %.02f (whizz bang!)"
],
"SortTypes": [
"0: Alphabetically — as it should be",
"1: Most Played — by the rabble, no doubt",
"2: Last Played — how very impulsive"
],
"TitleInfo": [
"0: App ID: %016lX (very official)",
"1: Save ID: %016lx (by Jove!)",
"2: First Played: %x - %X (a grand day)",
"3: Last Played: %x - %X (only yesterday!)",
"4: Play Time: %02d:%02d:%02d (proper dedication!)",
"5: Launches: %i (crikey!)",
"6: Save Type: %s (the classy kind)"
],
"TitleOptionConfirmations": [
"0: Are you sure you want to blacklist #%s#? It shant appear again, not even at high tea!",
"1: Really delete all backups for #%s#? Thats frightfully permanent, old sport!",
"2: Reset save data for #%s#? It shall be as though it never trod this Earth!",
"3: Delete `%s`s save data for #%s#? A grim and irreversible act, indeed."
],
"TitleOptionPops": [
"0: All backups for `%s` have been jolly well obliterated!",
"1: Couldnt delete all backups — how beastly inconvenient!",
"2: Save data reset failed! Bad show!",
"3: Save data reset complete! Jolly good!",
"4: SVI file exported splendidly!",
"5: Exporting SVI file failed — how dreadfully embarrassing!",
"6: This option isnt for system saves, I'm afraid. Too risky!",
"7: Path sanitisation failed — what a mess!",
"8: Output folder now set to #%s#. Smashing!",
"9: Failed to set new output path — how terribly awkward!",
"10: Save data extended like a proper estate lawn!",
"11: Extension failed — the shame!"
],
"TitleOptionStatus": [
"0: Deleting all backups for #%s#... stiff drink required.",
"1: Resetting save data for #%s#... good luck!",
"2: Deleting `%s`s save data for #%s#... tally-ho!",
"3: Extending `%s`s save data for #%s#... pip pip!"
],
"TitleOptions": [
"0: Information, quite informative really",
"1: Blacklist Title, toss it out with the rubbish",
"2: Change Output folder, spruce things up",
"3: Open in File Mode, if you dare",
"4: Delete all save backups, like a proper purge",
"5: Reset save data. Fresh as a daisy.",
"6: Delete save data from system — ruthless!",
"7: Extend save data — jolly big of you",
"8: Export SVI file — terribly fancy"
],
"TranslationInfo": [
"0: Translated by: %s (splendid effort!)",
"1: NULL (nothing to see here)"
],
"UserOptionConfirmations": [
"0: Are you quite sure you want to backup all save data for `%s`? It may take yonks!",
"1: Create save data for all titles on your system for `%s`? A daunting task indeed!",
"2: Delete all save data for `%s`? Heavens! Thats *utterly irreversible!*"
],
"UserOptionStatus": [
"0: Creating save data for #%s#... good show!",
"1: Deleting save data for #%s#... stiff upper lip!"
],
"UserOptions": [
"0: Dump all for `%s`, and be done with it",
"1: Create Save Data for `%s` (give it life!)",
"2: Create All Save Data for `%s`, the whole lot!",
"3: Delete All Save Data for `%s`, with finality!"
],
"WebDavStrings": [
"0: WebDav is up and running, cheerio!",
"1: WebDavs had a bit of a wobble!"
],
"YesNo": [
"0: Yes [A], absolutely",
"1: No [B], heavens no!"
]
}

View File

@ -15,12 +15,14 @@
"4: Error occurred deleting backup!",
"5: Error creating backup!",
"6: Writing to system is disabled!",
"7: Unable to open zip for reading!"
"7: Unable to open zip for reading!",
"8: Error writing save meta data file!",
"9: Error downloading file!",
"10: Error uploading file!",
"11: Error processing save data meta!"
],
"BackupMenuStatus": [
"0: Processing save data meta file...",
"1: Uploading #%s# to remote storage...",
"2: Updating #%s# on remote storage..."
"0: Processing save data meta file..."
],
"ControlGuides": [
"0: [A] Select [Y] Dump All Saves [X] User Options",
@ -58,7 +60,10 @@
"0: Copying #%s#...",
"1: Compressing #%s# to ZIP...",
"2: Decompressing #%s# from ZIP...",
"3: Deleting #%s#..."
"3: Deleting #%s#...",
"4: Downloading #%s#...",
"5: Uploading #%s# to remote storage...",
"6: Updating #%s# on remote storage..."
],
"IOPops": [
"0: Error committing data to device!"

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Traducido por: %s",
"NULL"
"BackupMenu": [
"0: Nueva copia de seguridad"
],
"BackupMenuConfirmations": [
"0: ¿Está seguro de que realmente desea sobrescribir #%s#?",
"1: ¿Está seguro de que realmente desea restaurar #%s#?",
"2: ¿Está seguro de que realmente desea eliminar #%s#?"
],
"BackupMenuPops": [
"0: ¡Los datos guardados están vacíos!",
"1: ¡La copia de seguridad está vacía!",
"2: ¡Error al restablecer los datos guardados!",
"3: ¡Error al abrir el archivo ZIP para leer!",
"4: ¡Ocurrió un error al eliminar la copia de seguridad!",
"5: ¡Error al crear la copia de seguridad!",
"6: ¡La escritura en el sistema está deshabilitada!",
"7: ¡No se puede abrir el zip para leer!"
],
"BackupMenuStatus": [
"0: Procesando archivo de metadatos de los datos guardados...",
"1: Subiendo #%s# al almacenamiento remoto...",
"2: Actualizando #%s# en el almacenamiento remoto..."
],
"ControlGuides": [
"[A] Seleccionar [Y] Volcar todas las partidas guardadas [X] Opciones del usuario",
"[A] Seleccionar [L] [R] Saltar [Y] Favorito [X] Opciones de título [B] Atrás",
"[A] Seleccionar [Y] Restaurar [X] Eliminar [ZR] Subir [B] Cerrar",
"[A] Alternar [X] Valores predeterminados [B] Atrás"
],
"SaveDataTypes": [
"Sistema",
"Cuenta",
"BCAT",
"Dispositivo",
"Temporal",
"Caché",
"BCAT del sistema"
],
"SettingsMenu": [
"Establecer carpeta de salida de JKSV.",
"Editar lista negra",
"Incluir partidas guardadas del dispositivo con los usuarios: %s",
"Copia de seguridad automática al restaurar: %s",
"Nombres automáticos para copias de seguridad: %s",
"Subir automáticamente las copias de seguridad al almacenamiento remoto: %s",
"Mantener presionado para eliminar copias de seguridad: %s",
"Mantener presionado para restaurar copias de seguridad: %s",
"Mantener presionado para sobrescribir copias de seguridad: %s",
"Listar solo títulos montables: %s",
"Mostrar partidas guardadas del sistema de la cuenta: %s",
"Habilitar escritura en partidas guardadas del sistema y NAND: %s",
"Exportar partidas guardadas a ZIP: %s",
"Nivel de compresión ZIP: %u",
"Tipo de ordenación de títulos: %s",
"Modo de menú de texto (JKSM): %s",
"Forzar inglés: %s",
"Habilitar papelera de reciclaje: %s",
"Escalado de animaciones: %.02f"
"0: [A] Seleccionar [Y] Volcar todas las partidas [X] Opciones de usuario",
"1: [A] Seleccionar [L] [R] Saltar [Y] Favorito [X] Opciones de título [B] Atrás",
"2: [A] Seleccionar [Y] Restaurar [X] Eliminar [ZR] Subir [B] Cerrar",
"3: [A] Alternar [X] Predeterminados [B] Atrás"
],
"ExtrasMenu": [
"Recargar títulos",
"Navegador SD a SD",
"BIS: ProfInfoF",
"BIS: Seguro",
"BIS: Sistema",
"BIS: Usuario",
"Terminar proceso",
"Montar partida guardada del sistema"
"0: Reinicializar datos",
"1: Navegador SD a SD",
"2: ProdInfoF",
"3: Seguro",
"4: Sistema",
"5: Usuario",
"6: Terminar proceso"
],
"OnOff": [
"Apagado",
">Encendido>"
"ExtrasPops": [
"0: ¡Datos reinicializados!",
"1: ¡La reinicialización de datos falló!"
],
"BackupMenu": [
"Nueva copia de seguridad"
"GeneralPops": [
"0: ¡No se puede salir de JKSV mientras se ejecutan tareas!"
],
"CopyingFiles": [
"Copiando #%s#...",
"Comprimiendo #%s# a ZIP...",
"Descomprimiendo #%s# desde ZIP..."
"GoogleDriveStrings": [
"0: Para continuar, vaya a #%s# e introduzca >%s>!",
"1: ¡Sesión iniciada con éxito en Google Drive!",
"2: ¡Error al iniciar sesión en Google Drive!"
],
"HoldingStrings": [
"0: Mantener pulsado [A]",
"1: Siga manteniendo [A]",
"2: ¡Casi está! [A]"
],
"IOStatuses": [
"0: Copiando #%s#...",
"1: Comprimiendo #%s# a ZIP...",
"2: Descomprimiendo #%s# desde ZIP...",
"3: Eliminando #%s#..."
],
"IOPops": [
"0: ¡Error al confirmar datos en el dispositivo!"
],
"KeyboardStrings": [
"Introduce un nuevo nombre para la copia de seguridad.",
"Introduce el índice de caché.",
"Introduce una nueva ruta de salida para JKSV",
"Introduce el ID del proceso a terminar.",
"Introduce un ID de partida guardada del sistema",
"Introduce un nuevo nombre para el elemento de destino.",
"Introduce un nombre para la nueva carpeta.",
"Introduce un nuevo nombre para la carpeta de salida de %s.",
"Introduce cuánto expandir (en MB)."
"0: Introduzca un nuevo nombre para la copia de seguridad.",
"1: Introduzca el índice de caché.",
"2: Introduzca una nueva ruta de salida para JKSV",
"3: Introduzca el ID del proceso a terminar.",
"4: Introduzca un ID de guardado del sistema",
"5: Introduzca un nuevo nombre para el elemento objetivo.",
"6: Introduzca un nombre para la nueva carpeta.",
"7: Introduzca un nuevo nombre para la carpeta de salida de %s.",
"8: Introduzca cuánto expandir (en MB)."
],
"OnOff": [
"0: Apagado",
"1: >Encendido>"
],
"SaveCreatePops": [
"0: ¡Datos guardados creados para #%s#!",
"1: ¡Error al crear datos guardados!",
"2: ¡Error al eliminar datos guardados!"
],
"SaveDataTypes": [
"0: Sistema",
"1: Cuenta",
"2: BCAT",
"3: Dispositivo",
"4: Temporal",
"5: Caché",
"6: BCAT del sistema"
],
"SettingsDescriptions": [
"0: Establece el directorio de trabajo para JKSV. El valor predeterminado es `sdmc:/JKSV`.",
"1: Permite eliminar títulos de la lista negra.",
"2: Incluye guardados del dispositivo o compartidos con usuarios.",
"3: Crea una copia de seguridad automáticamente al restaurar otra.",
"4: Nombra automáticamente las copias de seguridad y omite el teclado.",
"5: Sube automáticamente las copias de seguridad a Google Drive o WebDav y las elimina localmente.",
"6: Indica si es necesario mantener [A] presionado durante tres segundos para eliminar copias de seguridad.",
"7: Indica si es necesario mantener [A] presionado durante tres segundos para restaurar copias de seguridad.",
"8: Indica si es necesario mantener [A] presionado durante tres segundos para sobrescribir copias de seguridad.",
"9: Solo muestra datos guardados que JKSV puede abrir correctamente.",
"10: Muestra guardados del sistema que tienen una ID de cuenta asociada.",
"11: Permite restaurar guardados del sistema y escribir en particiones NAND.",
"12: Exporta datos guardados a archivos ZIP en lugar de carpetas descomprimidas.",
"13: Nivel de compresión o deflate utilizado al escribir ZIP. El valor predeterminado es 6. Valores más bajos son más rápidos, pero ofrecen menos compresión y ahorro de espacio. Cero significa almacenar sin compresión.",
"14: Controla la forma en que se ordenan y muestran los títulos.",
"15: Muestra los títulos como menús de texto como el JKSM original en 3DS en lugar de cuadrículas de iconos.",
"16: Fuerza el uso del inglés como idioma en lugar del idioma del sistema detectado.",
"17: Mueve las copias de seguridad eliminadas a la carpeta _TRASH_ en lugar de eliminarlas permanentemente.",
"18: Establece la velocidad a la que ocurren las transiciones y animaciones. Un valor menor es más rápido."
],
"SettingsMenu": [
"0: Establecer carpeta de salida de JKSV.",
"1: Editar lista negra",
"2: Incluir guardados del dispositivo con usuarios: %s",
"3: Copia automática al restaurar: %s",
"4: Nombrar automáticamente las copias de seguridad: %s",
"5: Subir copias automáticamente a almacenamiento remoto: %s",
"6: Mantener para eliminar copias: %s",
"7: Mantener para restaurar copias: %s",
"8: Mantener para sobrescribir copias: %s",
"9: Listar solo títulos montables: %s",
"10: Mostrar guardados de cuenta del sistema: %s",
"11: Permitir escritura en guardados del sistema y NAND: %s",
"12: Exportar guardados a ZIP: %s",
"13: Nivel de compresión ZIP: %u",
"14: Tipo de ordenación de títulos: %s",
"15: Modo menú de texto (JKSM): %s",
"16: Forzar inglés: %s",
"17: Activar papelera: %s",
"18: Escala de animación: %.02f"
],
"SortTypes": [
"0: Alfabéticamente",
"1: Más jugados",
"2: Último jugado"
],
"TitleInfo": [
"0: ID de la aplicación: %016lX",
"1: ID de guardado: %016lx",
"2: Primera vez jugado: %x - %X",
"3: Última vez jugado: %x - %X",
"4: Tiempo de juego: %02d:%02d:%02d",
"5: Lanzamientos: %i",
"6: Tipo de guardado: %s"
],
"TitleOptionConfirmations": [
"0: ¿Está seguro de que desea añadir #%s# a su lista negra? Una vez hecho, ya no aparecerá en ninguna lista o selección de títulos.",
"1: ¿Está seguro de que desea eliminar todas las copias de seguridad actuales para #%s#? *¡Esto no se puede deshacer!*",
"2: ¿Está seguro de que desea restablecer los datos guardados para #%s#? *¡Esto eliminará los datos guardados actuales como si el título nunca se hubiera ejecutado!*",
"3: ¿Está seguro de que desea eliminar los datos guardados de `%s` para #%s#? *Esto los eliminará permanentemente del sistema.*"
],
"TitleOptionPops": [
"0: ¡Todas las copias de seguridad eliminadas para `%s`!",
"1: ¡Error al eliminar todas las copias de seguridad!",
"2: ¡Error al restablecer los datos guardados!",
"3: ¡Datos guardados restablecidos correctamente!",
"4: ¡Archivo SVI exportado correctamente!",
"5: ¡Error al exportar el archivo SVI!",
"6: ¡Esta opción no está disponible para los guardados del sistema!",
"7: ¡No se pudo sanitizar la ruta para su uso!",
"8: Carpeta de salida establecida en #%s#.",
"9: ¡Error al establecer la nueva ruta de salida!",
"10: ¡Datos guardados extendidos correctamente!",
"11: ¡Error al extender los datos guardados!"
],
"TitleOptionStatus": [
"0: Eliminando todas las copias de seguridad para #%s#.",
"1: Restableciendo datos guardados para #%s#.",
"2: Eliminando datos guardados de #%s# para #%s#...",
"3: Extendiendo datos guardados de `%s` para #%s#..."
],
"TitleOptions": [
"0: Información",
"1: Lista negra del título",
"2: Cambiar carpeta de salida",
"3: Abrir en modo archivo",
"4: Eliminar todas las copias de seguridad",
"5: Restablecer datos guardados.",
"6: Eliminar datos guardados del sistema",
"7: Extender datos guardados",
"8: Exportar archivo SVI"
],
"TranslationInfo": [
"0: Traducido por: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: ¿Está seguro de que desea hacer una copia de seguridad de los datos guardados para cada título encontrado para `%s`? Esto puede tardar un rato.",
"1: ¿Está seguro de que desea crear datos guardados para todos los títulos encontrados en su sistema para `%s`? Esto puede tardar un rato.",
"2: ¿Está seguro de que desea eliminar todos los datos guardados para `%s`? Esto es *PERMANENTE* y no se puede deshacer."
],
"UserOptionStatus": [
"0: Creando datos guardados para #%s#...",
"1: Eliminando datos guardados para #%s#..."
],
"UserOptions": [
"0: Volcar todo para `%s`",
"1: Crear datos guardados para `%s`",
"2: Crear todos los datos guardados para `%s`",
"3: Eliminar todos los datos guardados para `%s`"
],
"WebDavStrings": [
"0: ¡WebDav iniciado con éxito!",
"1: ¡WebDav falló!"
],
"YesNo": [
"0: Sí [A]",
"1: No [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Traducido por: %s",
"NULL"
"BackupMenu": [
"0: Nueva copia de seguridad"
],
"BackupMenuConfirmations": [
"0: ¿Está seguro de que realmente desea sobrescribir #%s#?",
"1: ¿Está seguro de que realmente desea restaurar #%s#?",
"2: ¿Está seguro de que realmente desea eliminar #%s#?"
],
"BackupMenuPops": [
"0: ¡Los datos guardados están vacíos!",
"1: ¡La copia de seguridad está vacía!",
"2: ¡Error al restablecer los datos guardados!",
"3: ¡Error al abrir el archivo ZIP para lectura!",
"4: ¡Ocurrió un error al eliminar la copia de seguridad!",
"5: ¡Error al crear la copia de seguridad!",
"6: ¡La escritura en el sistema está deshabilitada!",
"7: ¡No se puede abrir el zip para lectura!"
],
"BackupMenuStatus": [
"0: Procesando archivo de metadatos de los datos guardados...",
"1: Subiendo #%s# al almacenamiento remoto...",
"2: Actualizando #%s# en el almacenamiento remoto..."
],
"ControlGuides": [
"[A] Seleccionar [Y] Volcar todas las partidas guardadas [X] Opciones de usuario",
"[A] Seleccionar [L] [R] Saltar [Y] Favorito [X] Opciones de título [B] Atrás",
"[A] Seleccionar [Y] Restaurar [X] Eliminar [ZR] Subir [B] Cerrar",
"[A] Alternar [X] Valores predeterminados [B] Atrás"
],
"SaveDataTypes": [
"Sistema",
"Cuenta",
"BCAT",
"Dispositivo",
"Temporal",
"Caché",
"BCAT del sistema"
],
"SettingsMenu": [
"Establecer carpeta de salida de JKSV.",
"Editar lista negra",
"Incluir partidas guardadas de dispositivos con los usuarios: %s",
"Copia de seguridad automática al restaurar: %s",
"Asignar nombres automáticamente a las copias de seguridad: %s",
"Subir automáticamente las copias de seguridad al almacenamiento remoto: %s",
"Mantener presionado para eliminar copias de seguridad: %s",
"Mantener presionado para restaurar copias de seguridad: %s",
"Mantener presionado para sobrescribir copias de seguridad: %s",
"Listar solo títulos montables: %s",
"Mostrar partidas guardadas del sistema de la cuenta: %s",
"Habilitar escritura en partidas guardadas del sistema y NAND: %s",
"Exportar partidas guardadas a ZIP: %s",
"Nivel de compresión ZIP: %u",
"Tipo de ordenamiento de títulos: %s",
"Modo de menú de texto (JKSM): %s",
"Forzar inglés: %s",
"Habilitar papelera de reciclaje: %s",
"Escalado de animación: %.02f"
"0: [A] Seleccionar [Y] Volcar todas las partidas [X] Opciones de usuario",
"1: [A] Seleccionar [L] [R] Saltar [Y] Favorito [X] Opciones de título [B] Atrás",
"2: [A] Seleccionar [Y] Restaurar [X] Eliminar [ZR] Subir [B] Cerrar",
"3: [A] Alternar [X] Predeterminados [B] Atrás"
],
"ExtrasMenu": [
"Recargar títulos",
"Navegador de SD a SD",
"BIS: ProfInfoF",
"BIS: Seguro",
"BIS: Sistema",
"BIS: Usuario",
"Finalizar proceso",
"Montar partida guardada del sistema"
"0: Reinicializar datos",
"1: Navegador SD a SD",
"2: ProdInfoF",
"3: Seguro",
"4: Sistema",
"5: Usuario",
"6: Terminar proceso"
],
"OnOff": [
"Apagado",
">Encendido>"
"ExtrasPops": [
"0: ¡Datos reinicializados!",
"1: ¡La reinicialización de datos falló!"
],
"BackupMenu": [
"Nueva copia de seguridad"
"GeneralPops": [
"0: ¡No se puede salir de JKSV mientras se ejecutan tareas!"
],
"CopyingFiles": [
"Copiando #%s#...",
"Comprimiendo #%s# a ZIP...",
"Descomprimiendo #%s# desde ZIP..."
"GoogleDriveStrings": [
"0: Para continuar, vaya a #%s# e ingrese >%s>!",
"1: ¡Sesión iniciada con éxito en Google Drive!",
"2: ¡Error al iniciar sesión en Google Drive!"
],
"HoldingStrings": [
"0: Mantener presionado [A]",
"1: Sigue manteniendo [A]",
"2: ¡Casi listo! [A]"
],
"IOStatuses": [
"0: Copiando #%s#...",
"1: Comprimiendo #%s# a ZIP...",
"2: Descomprimiendo #%s# desde ZIP...",
"3: Eliminando #%s#..."
],
"IOPops": [
"0: ¡Error al guardar datos en el dispositivo!"
],
"KeyboardStrings": [
"Introduce un nuevo nombre para la copia de seguridad.",
"Introduce el índice de caché.",
"Introduce una nueva ruta de salida para JKSV",
"Introduce el ID del proceso a finalizar.",
"Introduce un ID de partida guardada del sistema",
"Introduce un nuevo nombre para el elemento de destino.",
"Introduce un nombre para la nueva carpeta.",
"Introduce un nuevo nombre para la carpeta de salida de %s.",
"Introduce cuánto expandir (en MB)."
"0: Ingresa un nuevo nombre para la copia de seguridad.",
"1: Ingresa el índice de caché.",
"2: Ingresa una nueva ruta de salida para JKSV",
"3: Ingresa el ID del proceso a terminar.",
"4: Ingresa un ID de guardado del sistema",
"5: Ingresa un nuevo nombre para el elemento objetivo.",
"6: Ingresa un nombre para la nueva carpeta.",
"7: Ingresa un nuevo nombre para la carpeta de salida de %s.",
"8: Ingresa cuánto expandir (en MB)."
],
"OnOff": [
"0: Apagado",
"1: >Encendido>"
],
"SaveCreatePops": [
"0: ¡Datos guardados creados para #%s#!",
"1: ¡Error al crear datos guardados!",
"2: ¡Error al eliminar datos guardados!"
],
"SaveDataTypes": [
"0: Sistema",
"1: Cuenta",
"2: BCAT",
"3: Dispositivo",
"4: Temporal",
"5: Caché",
"6: BCAT del sistema"
],
"SettingsDescriptions": [
"0: Establece el directorio de trabajo para JKSV. El valor predeterminado es `sdmc:/JKSV`.",
"1: Permite eliminar títulos de la lista negra.",
"2: Incluye guardados del dispositivo o compartidos con usuarios.",
"3: Crea una copia de seguridad automáticamente al restaurar otra.",
"4: Nombra automáticamente las copias de seguridad y omite el teclado.",
"5: Sube automáticamente las copias de seguridad a Google Drive o WebDav y las elimina localmente.",
"6: Indica si es necesario mantener presionado [A] durante tres segundos para eliminar copias de seguridad.",
"7: Indica si es necesario mantener presionado [A] durante tres segundos para restaurar copias de seguridad.",
"8: Indica si es necesario mantener presionado [A] durante tres segundos para sobrescribir copias de seguridad.",
"9: Solo muestra datos guardados que JKSV puede abrir correctamente.",
"10: Muestra guardados del sistema que tienen una ID de cuenta asociada.",
"11: Permite restaurar guardados del sistema y escribir en particiones NAND.",
"12: Exporta datos guardados a archivos ZIP en lugar de carpetas descomprimidas.",
"13: Nivel de compresión o deflate utilizado al escribir ZIP. El valor predeterminado es 6. Valores más bajos son más rápidos, pero ofrecen menos compresión y ahorro de espacio. Cero significa almacenar sin compresión.",
"14: Controla la forma en que se ordenan y muestran los títulos.",
"15: Muestra los títulos como menús de texto como el JKSM original en 3DS en lugar de cuadrículas de iconos.",
"16: Fuerza el uso del inglés como idioma en lugar del idioma del sistema detectado.",
"17: Mueve las copias de seguridad eliminadas a la carpeta _TRASH_ en lugar de eliminarlas permanentemente.",
"18: Establece la velocidad a la que ocurren las transiciones y animaciones. Un valor menor es más rápido."
],
"SettingsMenu": [
"0: Establecer carpeta de salida de JKSV.",
"1: Editar lista negra",
"2: Incluir guardados del dispositivo con usuarios: %s",
"3: Copia automática al restaurar: %s",
"4: Nombrar automáticamente las copias de seguridad: %s",
"5: Subir copias automáticamente a almacenamiento remoto: %s",
"6: Mantener para eliminar copias: %s",
"7: Mantener para restaurar copias: %s",
"8: Mantener para sobrescribir copias: %s",
"9: Listar solo títulos montables: %s",
"10: Mostrar guardados de cuenta del sistema: %s",
"11: Permitir escritura en guardados del sistema y NAND: %s",
"12: Exportar guardados a ZIP: %s",
"13: Nivel de compresión ZIP: %u",
"14: Tipo de ordenación de títulos: %s",
"15: Modo menú de texto (JKSM): %s",
"16: Forzar inglés: %s",
"17: Activar papelera: %s",
"18: Escala de animación: %.02f"
],
"SortTypes": [
"0: Alfabéticamente",
"1: Más jugados",
"2: Último jugado"
],
"TitleInfo": [
"0: ID de la aplicación: %016lX",
"1: ID de guardado: %016lx",
"2: Primera vez jugado: %x - %X",
"3: Última vez jugado: %x - %X",
"4: Tiempo de juego: %02d:%02d:%02d",
"5: Lanzamientos: %i",
"6: Tipo de guardado: %s"
],
"TitleOptionConfirmations": [
"0: ¿Está seguro de que desea añadir #%s# a su lista negra? Una vez hecho, ya no aparecerá en ninguna lista o selección de títulos.",
"1: ¿Está seguro de que desea eliminar todas las copias de seguridad actuales para #%s#? *¡Esto no se puede deshacer!*",
"2: ¿Está seguro de que desea restablecer los datos guardados para #%s#? *¡Esto eliminará los datos guardados actuales como si el título nunca se hubiera ejecutado!*",
"3: ¿Está seguro de que desea eliminar los datos guardados de `%s` para #%s#? *Esto los eliminará permanentemente del sistema.*"
],
"TitleOptionPops": [
"0: ¡Todas las copias de seguridad eliminadas para `%s`!",
"1: ¡Error al eliminar todas las copias de seguridad!",
"2: ¡Error al restablecer los datos guardados!",
"3: ¡Datos guardados restablecidos correctamente!",
"4: ¡Archivo SVI exportado correctamente!",
"5: ¡Error al exportar el archivo SVI!",
"6: ¡Esta opción no está disponible para los guardados del sistema!",
"7: ¡No se pudo sanitizar la ruta para su uso!",
"8: Carpeta de salida establecida en #%s#.",
"9: ¡Error al establecer la nueva ruta de salida!",
"10: ¡Datos guardados extendidos correctamente!",
"11: ¡Error al extender los datos guardados!"
],
"TitleOptionStatus": [
"0: Eliminando todas las copias de seguridad para #%s#.",
"1: Restableciendo datos guardados para #%s#.",
"2: Eliminando datos guardados de #%s# para #%s#...",
"3: Extendiendo datos guardados de `%s` para #%s#..."
],
"TitleOptions": [
"0: Información",
"1: Lista negra del título",
"2: Cambiar carpeta de salida",
"3: Abrir en modo archivo",
"4: Eliminar todas las copias de seguridad",
"5: Restablecer datos guardados.",
"6: Eliminar datos guardados del sistema",
"7: Extender datos guardados",
"8: Exportar archivo SVI"
],
"TranslationInfo": [
"0: Traducido por: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: ¿Está seguro de que desea hacer una copia de seguridad de los datos guardados para cada título encontrado para `%s`? Esto puede tardar un momento.",
"1: ¿Está seguro de que desea crear datos guardados para todos los títulos encontrados en su sistema para `%s`? Esto puede tardar un momento.",
"2: ¿Está seguro de que desea eliminar todos los datos guardados para `%s`? Esto es *PERMANENTE* y no se puede deshacer."
],
"UserOptionStatus": [
"0: Creando datos guardados para #%s#...",
"1: Eliminando datos guardados para #%s#..."
],
"UserOptions": [
"0: Volcar todo para `%s`",
"1: Crear datos guardados para `%s`",
"2: Crear todos los datos guardados para `%s`",
"3: Eliminar todos los datos guardados para `%s`"
],
"WebDavStrings": [
"0: ¡WebDav iniciado con éxito!",
"1: ¡WebDav falló!"
],
"YesNo": [
"0: Sí [A]",
"1: No [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Traduit par : %s",
"NULL"
"BackupMenu": [
"0: Nouvelle sauvegarde"
],
"BackupMenuConfirmations": [
"0: Êtes-vous sûr de vouloir vraiment écraser #%s# ?",
"1: Êtes-vous sûr de vouloir vraiment restaurer #%s# ?",
"2: Êtes-vous sûr de vouloir vraiment supprimer #%s# ?"
],
"BackupMenuPops": [
"0: Les données sauvegardées sont vides !",
"1: La sauvegarde est vide !",
"2: Erreur lors de la réinitialisation des données sauvegardées !",
"3: Erreur lors de l'ouverture du fichier ZIP en lecture !",
"4: Une erreur est survenue lors de la suppression de la sauvegarde !",
"5: Erreur lors de la création de la sauvegarde !",
"6: Lécriture dans le système est désactivée !",
"7: Impossible douvrir le zip en lecture !"
],
"BackupMenuStatus": [
"0: Traitement du fichier méta des données sauvegardées...",
"1: Téléversement de #%s# vers le stockage distant...",
"2: Mise à jour de #%s# sur le stockage distant..."
],
"ControlGuides": [
"[A] Sélectionner [Y] Exporter toutes les sauvegardes [X] Options utilisateur",
"[A] Sélectionner [L] [R] Sauter [Y] Favori [X] Options du titre [B] Retour",
"[A] Sélectionner [Y] Restaurer [X] Supprimer [ZR] Télécharger [B] Fermer",
"[A] Basculer [X] Valeurs par défaut [B] Retour"
],
"SaveDataTypes": [
"Système",
"Compte",
"BCAT",
"Appareil",
"Temporaire",
"Cache",
"BCAT Système"
],
"SettingsMenu": [
"Définir le dossier de sortie de JKSV.",
"Modifier la liste noire",
"Inclure les sauvegardes des appareils avec les utilisateurs : %s",
"Sauvegarde automatique lors de la restauration : %s",
"Nommer automatiquement les sauvegardes : %s",
"Téléverser automatiquement les sauvegardes vers le stockage distant : %s",
"Maintenir pour supprimer les sauvegardes : %s",
"Maintenir pour restaurer les sauvegardes : %s",
"Maintenir pour écraser les sauvegardes : %s",
"Lister uniquement les titres montables : %s",
"Afficher les sauvegardes système des comptes : %s",
"Activer l'écriture dans les sauvegardes système et NAND : %s",
"Exporter les sauvegardes au format ZIP : %s",
"Niveau de compression ZIP : %u",
"Type de tri des titres : %s",
"Mode menu texte (JKSM) : %s",
"Forcer l'anglais : %s",
"Activer la corbeille : %s",
"Échelle d'animation : %.02f"
"0: [A] Sélectionner [Y] Sauvegarder tout [X] Options utilisateur",
"1: [A] Sélectionner [L] [R] Saut [Y] Favori [X] Options du titre [B] Retour",
"2: [A] Sélectionner [Y] Restaurer [X] Supprimer [ZR] Téléverser [B] Fermer",
"3: [A] Basculer [X] Par défaut [B] Retour"
],
"ExtrasMenu": [
"Recharger les titres",
"Navigateur SD vers SD",
"BIS : ProfInfoF",
"BIS : Sécurisé",
"BIS : Système",
"BIS : Utilisateur",
"Terminer le processus",
"Monter la sauvegarde système"
"0: Réinitialiser les données",
"1: Navigateur SD vers SD",
"2: ProdInfoF",
"3: Sécurité",
"4: Système",
"5: Utilisateur",
"6: Terminer le processus"
],
"OnOff": [
"Désactivé",
">Activé>"
"ExtrasPops": [
"0: Données réinitialisées !",
"1: Échec de la réinitialisation des données !"
],
"BackupMenu": [
"Nouvelle sauvegarde"
"GeneralPops": [
"0: Impossible de quitter JKSV pendant que des tâches sont en cours !"
],
"CopyingFiles": [
"Copie de #%s# en cours...",
"Compression de #%s# au format ZIP...",
"Décompression de #%s# à partir du ZIP..."
"GoogleDriveStrings": [
"0: Pour continuer, rendez-vous sur #%s# et saisissez >%s> !",
"1: Connexion à Google Drive réussie !",
"2: Échec de la connexion à Google Drive !"
],
"HoldingStrings": [
"0: Maintenez [A]",
"1: Continuez de maintenir [A]",
"2: Presque là ! [A]"
],
"IOStatuses": [
"0: Copie de #%s# en cours...",
"1: Compression de #%s# en ZIP...",
"2: Décompression de #%s# depuis ZIP...",
"3: Suppression de #%s#..."
],
"IOPops": [
"0: Erreur lors de lenregistrement des données sur le périphérique !"
],
"KeyboardStrings": [
"Entrez un nouveau nom pour la sauvegarde.",
"Entrez l'index du cache.",
"Entrez un nouveau chemin de sortie pour JKSV",
"Entrez l'ID du processus à terminer.",
"Entrez un ID de sauvegarde système",
"Entrez un nouveau nom pour l'élément cible.",
"Entrez un nom pour le nouveau dossier.",
"Entrez un nouveau nom pour le dossier de sortie de %s.",
"Entrez la taille à étendre (en Mo)."
"0: Entrez un nouveau nom de sauvegarde.",
"1: Entrez lindex du cache.",
"2: Entrez un nouveau chemin de sortie pour JKSV",
"3: Entrez lID du processus à terminer.",
"4: Entrez un ID de sauvegarde système",
"5: Entrez un nouveau nom pour lélément cible.",
"6: Entrez un nom pour le nouveau dossier.",
"7: Entrez un nouveau nom de dossier de sortie pour %s.",
"8: Entrez la taille dextension (en Mo)."
],
"OnOff": [
"0: Désactivé",
"1: >Activé>"
],
"SaveCreatePops": [
"0: Données sauvegardées créées pour #%s#!",
"1: Erreur lors de la création des données sauvegardées !",
"2: Erreur lors de la suppression des données sauvegardées !"
],
"SaveDataTypes": [
"0: Système",
"1: Compte",
"2: BCAT",
"3: Appareil",
"4: Temporaire",
"5: Cache",
"6: BCAT système"
],
"SettingsDescriptions": [
"0: Définit le répertoire de travail pour JKSV. La valeur par défaut est `sdmc:/JKSV`.",
"1: Permet de retirer des titres de la liste noire.",
"2: Inclut les sauvegardes dappareil ou partagées avec les utilisateurs.",
"3: Crée une sauvegarde automatiquement lors de la restauration dune autre.",
"4: Nomme automatiquement les sauvegardes et évite le clavier.",
"5: Téléverse automatiquement les sauvegardes sur Google Drive ou WebDav et les supprime localement.",
"6: Indique si maintenir [A] trois secondes est requis pour supprimer les sauvegardes.",
"7: Indique si maintenir [A] trois secondes est requis pour restaurer les sauvegardes.",
"8: Indique si maintenir [A] trois secondes est requis pour écraser les sauvegardes.",
"9: Affiche uniquement les sauvegardes que JKSV peut ouvrir avec succès.",
"10: Affiche les sauvegardes système liées à un compte.",
"11: Permet de restaurer les sauvegardes système et décrire sur les partitions NAND.",
"12: Exporte les données sauvegardées en archives ZIP au lieu de dossiers décompressés.",
"13: Niveau de compression utilisé lors de lécriture ZIP. La valeur par défaut est 6. Les valeurs plus basses sont plus rapides mais compressent moins. Zéro signifie sans compression.",
"14: Contrôle la manière dont les titres sont triés et affichés.",
"15: Affiche les titres en menus texte comme le JKSM original sur 3DS au lieu de grilles dicônes.",
"16: Force lusage de langlais comme langue au lieu de la langue système détectée.",
"17: Déplace les sauvegardes supprimées dans le dossier _TRASH_ au lieu de les supprimer définitivement.",
"18: Définit la vitesse des transitions et animations. Plus bas est plus rapide."
],
"SettingsMenu": [
"0: Définir le dossier de sortie JKSV.",
"1: Modifier la liste noire",
"2: Inclure les sauvegardes appareil avec les utilisateurs : %s",
"3: Sauvegarde automatique lors de la restauration : %s",
"4: Nommer automatiquement les sauvegardes : %s",
"5: Téléversement automatique des sauvegardes vers stockage distant : %s",
"6: Maintenir pour supprimer les sauvegardes : %s",
"7: Maintenir pour restaurer les sauvegardes : %s",
"8: Maintenir pour écraser les sauvegardes : %s",
"9: Lister uniquement les titres montables : %s",
"10: Afficher les sauvegardes système liées au compte : %s",
"11: Autoriser lécriture sur sauvegardes système et NAND : %s",
"12: Exporter les sauvegardes en ZIP : %s",
"13: Niveau de compression ZIP : %u",
"14: Type de tri des titres : %s",
"15: Mode menu texte (JKSM) : %s",
"16: Forcer langlais : %s",
"17: Activer la corbeille : %s",
"18: Échelle danimation : %.02f"
],
"SortTypes": [
"0: Alphabétique",
"1: Plus joués",
"2: Dernier joué"
],
"TitleInfo": [
"0: ID de lapplication : %016lX",
"1: ID de sauvegarde : %016lx",
"2: Première partie : %x - %X",
"3: Dernière partie : %x - %X",
"4: Temps de jeu : %02d:%02d:%02d",
"5: Lancements : %i",
"6: Type de sauvegarde : %s"
],
"TitleOptionConfirmations": [
"0: Êtes-vous sûr de vouloir ajouter #%s# à votre liste noire ? Une fois fait, il napparaîtra plus dans aucune liste ou sélection de titres.",
"1: Êtes-vous sûr de vouloir supprimer toutes les sauvegardes actuelles pour #%s# ? *Ceci est irréversible !*",
"2: Êtes-vous sûr de vouloir réinitialiser les données sauvegardées pour #%s# ? *Cela supprimera les données sauvegardées comme si le titre navait jamais été lancé !*",
"3: Êtes-vous sûr de vouloir supprimer les données sauvegardées de `%s` pour #%s# ? *Cela les supprimera définitivement du système.*"
],
"TitleOptionPops": [
"0: Toutes les sauvegardes supprimées pour `%s` !",
"1: Échec de la suppression de toutes les sauvegardes !",
"2: Erreur lors de la réinitialisation des données sauvegardées !",
"3: Données sauvegardées réinitialisées avec succès !",
"4: Fichier SVI exporté avec succès !",
"5: Erreur lors de lexport du fichier SVI !",
"6: Cette option nest pas disponible pour les sauvegardes système !",
"7: Impossible de nettoyer le chemin pour utilisation !",
"8: Dossier de sortie défini sur #%s#.",
"9: Erreur lors de la définition du nouveau chemin de sortie !",
"10: Données sauvegardées étendues avec succès !",
"11: Échec de lextension des données sauvegardées !"
],
"TitleOptionStatus": [
"0: Suppression de toutes les sauvegardes pour #%s#.",
"1: Réinitialisation des données sauvegardées pour #%s#.",
"2: Suppression des données sauvegardées de #%s# pour #%s#...",
"3: Extension des données sauvegardées de `%s` pour #%s#..."
],
"TitleOptions": [
"0: Informations",
"1: Liste noire du titre",
"2: Changer le dossier de sortie",
"3: Ouvrir en mode fichier",
"4: Supprimer toutes les sauvegardes",
"5: Réinitialiser les données sauvegardées.",
"6: Supprimer les données sauvegardées du système",
"7: Étendre les données sauvegardées",
"8: Exporter le fichier SVI"
],
"TranslationInfo": [
"0: Traduit par : %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: Êtes-vous sûr de vouloir sauvegarder les données de chaque titre trouvé pour `%s` ? Cela peut prendre un moment.",
"1: Êtes-vous sûr de vouloir créer des données sauvegardées pour tous les titres trouvés sur votre système pour `%s` ? Cela peut prendre un moment.",
"2: Êtes-vous sûr de vouloir supprimer toutes les données sauvegardées pour `%s` ? Ceci est *IRRÉVERSIBLE* et ne peut pas être annulé."
],
"UserOptionStatus": [
"0: Création des données sauvegardées pour #%s#...",
"1: Suppression des données sauvegardées pour #%s#..."
],
"UserOptions": [
"0: Tout sauvegarder pour `%s`",
"1: Créer des données sauvegardées pour `%s`",
"2: Créer toutes les données sauvegardées pour `%s`",
"3: Supprimer toutes les données sauvegardées pour `%s`"
],
"WebDavStrings": [
"0: WebDav démarré avec succès !",
"1: Échec de WebDav !"
],
"YesNo": [
"0: Oui [A]",
"1: Non [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Traduit par : %s",
"NULL"
"BackupMenu": [
"0: Nouvelle sauvegarde"
],
"BackupMenuConfirmations": [
"0: Êtes-vous sûr de vouloir vraiment écraser #%s# ?",
"1: Êtes-vous sûr de vouloir vraiment restaurer #%s# ?",
"2: Êtes-vous sûr de vouloir vraiment supprimer #%s# ?"
],
"BackupMenuPops": [
"0: Les données sauvegardées sont vides !",
"1: La sauvegarde est vide !",
"2: Erreur lors de la réinitialisation des données sauvegardées !",
"3: Erreur lors de louverture du fichier ZIP en lecture !",
"4: Une erreur est survenue lors de la suppression de la sauvegarde !",
"5: Erreur lors de la création de la sauvegarde !",
"6: Lécriture dans le système est désactivée !",
"7: Impossible douvrir le fichier zip en lecture !"
],
"BackupMenuStatus": [
"0: Traitement du fichier méta des données sauvegardées…",
"1: Téléversement de #%s# vers le stockage distant…",
"2: Mise à jour de #%s# sur le stockage distant…"
],
"ControlGuides": [
"[A] Sélectionner [Y] Exporter toutes les sauvegardes [X] Options utilisateur",
"[A] Sélectionner [L] [R] Sauter [Y] Favori [X] Options du titre [B] Retour",
"[A] Sélectionner [Y] Restaurer [X] Supprimer [ZR] Téléverser [B] Fermer",
"[A] Basculer [X] Valeurs par défaut [B] Retour"
],
"SaveDataTypes": [
"Système",
"Compte",
"BCAT",
"Appareil",
"Temporaire",
"Cache",
"BCAT Système"
],
"SettingsMenu": [
"Définir le dossier de sortie de JKSV.",
"Modifier la liste noire",
"Inclure les sauvegardes des appareils avec les utilisateurs : %s",
"Sauvegarde automatique lors de la restauration : %s",
"Nommer automatiquement les sauvegardes : %s",
"Téléverser automatiquement les sauvegardes au stockage distant : %s",
"Maintenir pour supprimer les sauvegardes : %s",
"Maintenir pour restaurer les sauvegardes : %s",
"Maintenir pour écraser les sauvegardes : %s",
"Lister uniquement les titres montables : %s",
"Afficher les sauvegardes système des comptes : %s",
"Activer l'écriture dans les sauvegardes système et NAND : %s",
"Exporter les sauvegardes en format ZIP : %s",
"Niveau de compression ZIP : %u",
"Type de tri des titres : %s",
"Mode menu texte (JKSM) : %s",
"Forcer l'anglais : %s",
"Activer la corbeille : %s",
"Échelle d'animation : %.02f"
"0: [A] Sélectionner [Y] Sauvegarder tout [X] Options utilisateur",
"1: [A] Sélectionner [L] [R] Saut [Y] Favori [X] Options du titre [B] Retour",
"2: [A] Sélectionner [Y] Restaurer [X] Supprimer [ZR] Téléverser [B] Fermer",
"3: [A] Basculer [X] Par défaut [B] Retour"
],
"ExtrasMenu": [
"Recharger les titres",
"Navigateur SD vers SD",
"BIS : ProfInfoF",
"BIS : Sécurisé",
"BIS : Système",
"BIS : Utilisateur",
"Terminer le processus",
"Monter la sauvegarde système"
"0: Réinitialiser les données",
"1: Navigateur SD vers SD",
"2: ProdInfoF",
"3: Sécurité",
"4: Système",
"5: Utilisateur",
"6: Terminer le processus"
],
"OnOff": [
"Désactivé",
">Activé>"
"ExtrasPops": [
"0: Données réinitialisées !",
"1: Échec de la réinitialisation des données !"
],
"BackupMenu": [
"Nouvelle sauvegarde"
"GeneralPops": [
"0: Impossible de quitter JKSV pendant que des tâches sont en cours !"
],
"CopyingFiles": [
"Copie de #%s# en cours...",
"Compression de #%s# au format ZIP...",
"Décompression de #%s# depuis le ZIP..."
"GoogleDriveStrings": [
"0: Pour continuer, rendez-vous sur #%s# et saisissez >%s> !",
"1: Connexion à Google Drive réussie !",
"2: Échec de la connexion à Google Drive !"
],
"HoldingStrings": [
"0: Maintenez [A]",
"1: Continuez de maintenir [A]",
"2: Presque là ! [A]"
],
"IOStatuses": [
"0: Copie de #%s# en cours…",
"1: Compression de #%s# en ZIP…",
"2: Décompression de #%s# depuis ZIP…",
"3: Suppression de #%s#…"
],
"IOPops": [
"0: Erreur lors de lenregistrement des données sur le périphérique !"
],
"KeyboardStrings": [
"Entrez un nouveau nom pour la sauvegarde.",
"Entrez l'index du cache.",
"Entrez un nouveau chemin de sortie pour JKSV",
"Entrez l'ID du processus à terminer.",
"Entrez un ID de sauvegarde système",
"Entrez un nouveau nom pour l'élément cible.",
"Entrez un nom pour le nouveau dossier.",
"Entrez un nouveau nom pour le dossier de sortie de %s.",
"Entrez la taille à étendre (en Mo)."
"0: Entrez un nouveau nom de sauvegarde.",
"1: Entrez lindex du cache.",
"2: Entrez un nouveau chemin de sortie pour JKSV",
"3: Entrez lID du processus à terminer.",
"4: Entrez un ID de sauvegarde système",
"5: Entrez un nouveau nom pour lélément cible.",
"6: Entrez un nom pour le nouveau dossier.",
"7: Entrez un nouveau nom de dossier de sortie pour %s.",
"8: Entrez la taille dextension (en Mo)."
],
"OnOff": [
"0: Désactivé",
"1: >Activé>"
],
"SaveCreatePops": [
"0: Données sauvegardées créées pour #%s#!",
"1: Erreur lors de la création des données sauvegardées !",
"2: Erreur lors de la suppression des données sauvegardées !"
],
"SaveDataTypes": [
"0: Système",
"1: Compte",
"2: BCAT",
"3: Appareil",
"4: Temporaire",
"5: Cache",
"6: BCAT système"
],
"SettingsDescriptions": [
"0: Définit le répertoire de travail pour JKSV. La valeur par défaut est `sdmc:/JKSV`.",
"1: Permet de retirer des titres de la liste noire.",
"2: Inclut les sauvegardes dappareil ou partagées avec les utilisateurs.",
"3: Crée une sauvegarde automatiquement lors de la restauration dune autre.",
"4: Nomme automatiquement les sauvegardes et évite le clavier.",
"5: Téléverse automatiquement les sauvegardes sur Google Drive ou WebDav et les supprime localement.",
"6: Indique si maintenir [A] trois secondes est requis pour supprimer les sauvegardes.",
"7: Indique si maintenir [A] trois secondes est requis pour restaurer les sauvegardes.",
"8: Indique si maintenir [A] trois secondes est requis pour écraser les sauvegardes.",
"9: Affiche uniquement les sauvegardes que JKSV peut ouvrir avec succès.",
"10: Affiche les sauvegardes système liées à un compte.",
"11: Permet de restaurer les sauvegardes système et décrire sur les partitions NAND.",
"12: Exporte les données sauvegardées en archives ZIP au lieu de dossiers décompressés.",
"13: Niveau de compression utilisé lors de lécriture ZIP. La valeur par défaut est 6. Les valeurs plus basses sont plus rapides mais compressent moins. Zéro signifie sans compression.",
"14: Contrôle la manière dont les titres sont triés et affichés.",
"15: Affiche les titres en menus texte comme le JKSM original sur 3DS au lieu de grilles dicônes.",
"16: Force lusage de langlais comme langue au lieu de la langue système détectée.",
"17: Déplace les sauvegardes supprimées dans le dossier _TRASH_ au lieu de les supprimer définitivement.",
"18: Définit la vitesse des transitions et animations. Plus bas est plus rapide."
],
"SettingsMenu": [
"0: Définir le dossier de sortie JKSV.",
"1: Modifier la liste noire",
"2: Inclure les sauvegardes appareil avec les utilisateurs : %s",
"3: Sauvegarde automatique lors de la restauration : %s",
"4: Nommer automatiquement les sauvegardes : %s",
"5: Téléversement automatique des sauvegardes vers stockage distant : %s",
"6: Maintenir pour supprimer les sauvegardes : %s",
"7: Maintenir pour restaurer les sauvegardes : %s",
"8: Maintenir pour écraser les sauvegardes : %s",
"9: Lister uniquement les titres montables : %s",
"10: Afficher les sauvegardes système liées au compte : %s",
"11: Autoriser lécriture sur sauvegardes système et NAND : %s",
"12: Exporter les sauvegardes en ZIP : %s",
"13: Niveau de compression ZIP : %u",
"14: Type de tri des titres : %s",
"15: Mode menu texte (JKSM) : %s",
"16: Forcer langlais : %s",
"17: Activer la corbeille : %s",
"18: Échelle danimation : %.02f"
],
"SortTypes": [
"0: Alphabétique",
"1: Plus joués",
"2: Dernier joué"
],
"TitleInfo": [
"0: ID de lapplication : %016lX",
"1: ID de sauvegarde : %016lx",
"2: Première partie : %x - %X",
"3: Dernière partie : %x - %X",
"4: Temps de jeu : %02d:%02d:%02d",
"5: Lancements : %i",
"6: Type de sauvegarde : %s"
],
"TitleOptionConfirmations": [
"0: Êtes-vous sûr de vouloir ajouter #%s# à votre liste noire ? Une fois fait, il napparaîtra plus dans aucune liste ou sélection de titres.",
"1: Êtes-vous sûr de vouloir supprimer toutes les sauvegardes actuelles pour #%s# ? *Ceci est irréversible !*",
"2: Êtes-vous sûr de vouloir réinitialiser les données sauvegardées pour #%s# ? *Cela supprimera les données sauvegardées comme si le titre navait jamais été lancé !*",
"3: Êtes-vous sûr de vouloir supprimer les données sauvegardées de `%s` pour #%s# ? *Cela les supprimera définitivement du système.*"
],
"TitleOptionPops": [
"0: Toutes les sauvegardes supprimées pour `%s` !",
"1: Échec de la suppression de toutes les sauvegardes !",
"2: Erreur lors de la réinitialisation des données sauvegardées !",
"3: Données sauvegardées réinitialisées avec succès !",
"4: Fichier SVI exporté avec succès !",
"5: Erreur lors de lexport du fichier SVI !",
"6: Cette option nest pas disponible pour les sauvegardes système !",
"7: Impossible de nettoyer le chemin pour utilisation !",
"8: Dossier de sortie défini sur #%s#.",
"9: Erreur lors de la définition du nouveau chemin de sortie !",
"10: Données sauvegardées étendues avec succès !",
"11: Échec de lextension des données sauvegardées !"
],
"TitleOptionStatus": [
"0: Suppression de toutes les sauvegardes pour #%s#.",
"1: Réinitialisation des données sauvegardées pour #%s#.",
"2: Suppression des données sauvegardées de #%s# pour #%s#…",
"3: Extension des données sauvegardées de `%s` pour #%s#…"
],
"TitleOptions": [
"0: Informations",
"1: Liste noire du titre",
"2: Changer le dossier de sortie",
"3: Ouvrir en mode fichier",
"4: Supprimer toutes les sauvegardes",
"5: Réinitialiser les données sauvegardées.",
"6: Supprimer les données sauvegardées du système",
"7: Étendre les données sauvegardées",
"8: Exporter le fichier SVI"
],
"TranslationInfo": [
"0: Traduit par : %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: Êtes-vous sûr de vouloir sauvegarder les données de chaque titre trouvé pour `%s` ? Cela peut prendre un moment.",
"1: Êtes-vous sûr de vouloir créer des données sauvegardées pour tous les titres trouvés sur votre système pour `%s` ? Cela peut prendre un moment.",
"2: Êtes-vous sûr de vouloir supprimer toutes les données sauvegardées pour `%s` ? Ceci est *IRRÉVERSIBLE* et ne peut pas être annulé."
],
"UserOptionStatus": [
"0: Création des données sauvegardées pour #%s#…",
"1: Suppression des données sauvegardées pour #%s#…"
],
"UserOptions": [
"0: Tout sauvegarder pour `%s`",
"1: Créer des données sauvegardées pour `%s`",
"2: Créer toutes les données sauvegardées pour `%s`",
"3: Supprimer toutes les données sauvegardées pour `%s`"
],
"WebDavStrings": [
"0: WebDav démarré avec succès !",
"1: Échec de WebDav !"
],
"YesNo": [
"0: Oui [A]",
"1: Non [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Tradotto da: %s",
"NULL"
"BackupMenu": [
"0: Nuovo backup"
],
"BackupMenuConfirmations": [
"0: Sei sicuro di voler davvero sovrascrivere #%s#?",
"1: Sei sicuro di voler davvero ripristinare #%s#?",
"2: Sei sicuro di voler davvero eliminare #%s#?"
],
"BackupMenuPops": [
"0: I dati di salvataggio sono vuoti!",
"1: Il backup è vuoto!",
"2: Errore durante il reset dei dati di salvataggio!",
"3: Errore nell'apertura del file ZIP per la lettura!",
"4: Errore durante l'eliminazione del backup!",
"5: Errore durante la creazione del backup!",
"6: La scrittura sul sistema è disabilitata!",
"7: Impossibile aprire il file zip per la lettura!"
],
"BackupMenuStatus": [
"0: Elaborazione del file meta dei dati di salvataggio...",
"1: Caricamento di #%s# nello storage remoto...",
"2: Aggiornamento di #%s# nello storage remoto..."
],
"ControlGuides": [
"[A] Seleziona [Y] Esporta tutti i salvataggi [X] Opzioni utente",
"[A] Seleziona [L] [R] Salta [Y] Preferito [X] Opzioni titolo [B] Indietro",
"[A] Seleziona [Y] Ripristina [X] Elimina [ZR] Carica [B] Chiudi",
"[A] Attiva/Disattiva [X] Valori predefiniti [B] Indietro"
],
"SaveDataTypes": [
"Sistema",
"Account",
"BCAT",
"Dispositivo",
"Temporaneo",
"Cache",
"BCAT di sistema"
],
"SettingsMenu": [
"Imposta la cartella di output di JKSV.",
"Modifica la blacklist",
"Includi salvataggi del dispositivo con gli utenti: %s",
"Backup automatico al ripristino: %s",
"Assegna nomi automatici ai backup: %s",
"Carica automaticamente i backup sullo spazio di archiviazione remoto: %s",
"Tieni premuto per eliminare i backup: %s",
"Tieni premuto per ripristinare i backup: %s",
"Tieni premuto per sovrascrivere i backup: %s",
"Elenca solo i titoli montabili: %s",
"Mostra i salvataggi di sistema dell'account: %s",
"Abilita la scrittura nei salvataggi di sistema e NAND: %s",
"Esporta i salvataggi in formato ZIP: %s",
"Livello di compressione ZIP: %u",
"Tipo di ordinamento titoli: %s",
"Modalità menu testuale (JKSM): %s",
"Forza l'inglese: %s",
"Abilita il cestino: %s",
"Scala animazioni: %.02f"
"0: [A] Seleziona [Y] Esporta tutti i salvataggi [X] Opzioni utente",
"1: [A] Seleziona [L] [R] Salta [Y] Preferito [X] Opzioni titolo [B] Indietro",
"2: [A] Seleziona [Y] Ripristina [X] Elimina [ZR] Carica [B] Chiudi",
"3: [A] Attiva/disattiva [X] Predefiniti [B] Indietro"
],
"ExtrasMenu": [
"Ricarica i titoli",
"Esplora SD su SD",
"BIS: ProfInfoF",
"BIS: Sicuro",
"BIS: Sistema",
"BIS: Utente",
"Termina processo",
"Monta il salvataggio di sistema"
"0: Reinizializza dati",
"1: Browser SD verso SD",
"2: ProdInfoF",
"3: Sicurezza",
"4: Sistema",
"5: Utente",
"6: Termina processo"
],
"OnOff": [
"Spento",
">Acceso>"
"ExtrasPops": [
"0: Dati reinizializzati!",
"1: Reinizo dei dati fallito!"
],
"BackupMenu": [
"Nuovo backup"
"GeneralPops": [
"0: Impossibile uscire da JKSV mentre ci sono attività in esecuzione!"
],
"CopyingFiles": [
"Copia di #%s# in corso...",
"Compressione di #%s# in formato ZIP...",
"Decompressione di #%s# da ZIP..."
"GoogleDriveStrings": [
"0: Per continuare, vai su #%s# e inserisci >%s>!",
"1: Accesso a Google Drive effettuato con successo!",
"2: Accesso a Google Drive fallito!"
],
"HoldingStrings": [
"0: Tieni premuto [A]",
"1: Continua a tenere premuto [A]",
"2: Quasi fatto! [A]"
],
"IOStatuses": [
"0: Copia di #%s# in corso...",
"1: Compressione di #%s# in ZIP...",
"2: Decompressione di #%s# da ZIP...",
"3: Eliminazione di #%s# in corso..."
],
"IOPops": [
"0: Errore durante il salvataggio dei dati sul dispositivo!"
],
"KeyboardStrings": [
"Inserisci un nuovo nome per il backup.",
"Inserisci l'indice della cache.",
"Inserisci un nuovo percorso di output per JKSV",
"Inserisci l'ID del processo da terminare.",
"Inserisci un ID di salvataggio di sistema",
"Inserisci un nuovo nome per l'elemento di destinazione.",
"Inserisci un nome per la nuova cartella.",
"Inserisci un nuovo nome per la cartella di output di %s.",
"Inserisci quanto espandere (in MB)."
"0: Inserisci un nuovo nome per il backup.",
"1: Inserisci indice cache.",
"2: Inserisci un nuovo percorso di output per JKSV",
"3: Inserisci ID processo da terminare.",
"4: Inserisci un ID salvataggio sistema",
"5: Inserisci un nuovo nome per l'elemento target.",
"6: Inserisci un nome per la nuova cartella.",
"7: Inserisci un nuovo nome per la cartella di output di %s.",
"8: Inserisci quanto espandere (in MB)."
],
"OnOff": [
"0: Spento",
"1: >Acceso>"
],
"SaveCreatePops": [
"0: Dati di salvataggio creati per #%s#!",
"1: Errore durante la creazione dei dati di salvataggio!",
"2: Errore durante l'eliminazione dei dati di salvataggio!"
],
"SaveDataTypes": [
"0: Sistema",
"1: Account",
"2: BCAT",
"3: Dispositivo",
"4: Temporaneo",
"5: Cache",
"6: BCAT di sistema"
],
"SettingsDescriptions": [
"0: Imposta la directory di lavoro per JKSV. Il valore predefinito è `sdmc:/JKSV`.",
"1: Permette di rimuovere titoli dalla lista nera.",
"2: Include salvataggi di dispositivo o condivisi con gli utenti.",
"3: Crea automaticamente un backup quando se ne ripristina un altro.",
"4: Nomina automaticamente i backup e salta la tastiera.",
"5: Carica automaticamente i backup su Google Drive o WebDav e li elimina localmente.",
"6: Indica se tenere premuto [A] per tre secondi è richiesto per eliminare i backup.",
"7: Indica se tenere premuto [A] per tre secondi è richiesto per ripristinare i backup.",
"8: Indica se tenere premuto [A] per tre secondi è richiesto per sovrascrivere i backup.",
"9: Mostra solo i dati di salvataggio che JKSV può aprire con successo.",
"10: Mostra i salvataggi di sistema che hanno un ID account associato.",
"11: Permette di ripristinare salvataggi di sistema e scrivere sulle partizioni NAND.",
"12: Esporta i dati di salvataggio in archivi ZIP invece di cartelle non compresse.",
"13: Livello di compressione o deflate usato per scrivere ZIP. Il valore predefinito è 6. Valori più bassi sono più veloci ma offrono meno compressione. Zero significa senza compressione.",
"14: Controlla come i titoli sono ordinati e mostrati.",
"15: Mostra i titoli come menu di testo come nel JKSM originale su 3DS invece delle griglie di icone.",
"16: Forza luso dellinglese come lingua invece di quella di sistema rilevata.",
"17: Sposta i backup eliminati nella cartella _TRASH_ invece di eliminarli permanentemente.",
"18: Imposta la velocità con cui avvengono transizioni e animazioni. Più basso è più veloce."
],
"SettingsMenu": [
"0: Imposta la cartella di output di JKSV.",
"1: Modifica lista nera",
"2: Includi salvataggi dispositivo con gli utenti: %s",
"3: Backup automatico al ripristino: %s",
"4: Nomina automatica backup: %s",
"5: Caricamento automatico backup su storage remoto: %s",
"6: Tieni premuto per eliminare backup: %s",
"7: Tieni premuto per ripristinare backup: %s",
"8: Tieni premuto per sovrascrivere backup: %s",
"9: Mostra solo titoli montabili: %s",
"10: Mostra salvataggi sistema con account: %s",
"11: Abilita scrittura su salvataggi sistema e NAND: %s",
"12: Esporta salvataggi in ZIP: %s",
"13: Livello compressione ZIP: %u",
"14: Tipo ordinamento titoli: %s",
"15: Modalità menu testo (JKSM): %s",
"16: Forza inglese: %s",
"17: Abilita cestino: %s",
"18: Scala animazioni: %.02f"
],
"SortTypes": [
"0: Alfabetico",
"1: Più giocati",
"2: Ultima partita"
],
"TitleInfo": [
"0: ID App: %016lX",
"1: ID Salvataggio: %016lx",
"2: Prima partita: %x - %X",
"3: Ultima partita: %x - %X",
"4: Tempo di gioco: %02d:%02d:%02d",
"5: Lanci: %i",
"6: Tipo di salvataggio: %s"
],
"TitleOptionConfirmations": [
"0: Sei sicuro di voler aggiungere #%s# alla lista nera? Una volta fatto, non apparirà più in nessuna lista o selezione titoli.",
"1: Sei sicuro di voler eliminare tutti i backup attuali per #%s#? *Questa azione è irreversibile!*",
"2: Sei sicuro di voler resettare i dati di salvataggio per #%s#? *Questo eliminerà i dati come se il titolo non fosse mai stato avviato!*",
"3: Sei sicuro di voler eliminare i dati di salvataggio di `%s` per #%s#? *Questa azione li cancellerà definitivamente dal sistema.*"
],
"TitleOptionPops": [
"0: Tutti i backup eliminati per `%s`!",
"1: Fallito nell'eliminazione di tutti i backup!",
"2: Errore nel reset dei dati di salvataggio!",
"3: Dati di salvataggio resettati con successo!",
"4: File SVI esportato con successo!",
"5: Errore nell'esportazione del file SVI!",
"6: Questa opzione non è disponibile per i salvataggi di sistema!",
"7: Impossibile sanificare il percorso per l'uso!",
"8: Cartella di output impostata su #%s#.",
"9: Errore nell'impostazione del nuovo percorso di output!",
"10: Dati di salvataggio estesi con successo!",
"11: Estensione dei dati di salvataggio fallita!"
],
"TitleOptionStatus": [
"0: Eliminazione di tutti i backup per #%s#.",
"1: Reset dei dati di salvataggio per #%s#.",
"2: Eliminazione dei dati di salvataggio di #%s# per #%s#...",
"3: Estensione dei dati di salvataggio di `%s` per #%s#..."
],
"TitleOptions": [
"0: Informazioni",
"1: Lista nera titolo",
"2: Cambia cartella di output",
"3: Apri in modalità file",
"4: Elimina tutti i backup",
"5: Resetta dati di salvataggio.",
"6: Elimina dati di salvataggio dal sistema",
"7: Estendi dati di salvataggio",
"8: Esporta file SVI"
],
"TranslationInfo": [
"0: Tradotto da: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: Sei sicuro di voler fare il backup dei dati di salvataggio per ogni titolo trovato per `%s`? Questo potrebbe richiedere del tempo.",
"1: Sei sicuro di voler creare dati di salvataggio per tutti i titoli trovati sul tuo sistema per `%s`? Questo potrebbe richiedere del tempo.",
"2: Sei sicuro di voler eliminare tutti i dati di salvataggio per `%s`? Questa è unoperazione *PERMANENTE* e non può essere annullata."
],
"UserOptionStatus": [
"0: Creazione dei dati di salvataggio per #%s#...",
"1: Eliminazione dei dati di salvataggio per #%s#..."
],
"UserOptions": [
"0: Esporta tutto per `%s`",
"1: Crea dati di salvataggio per `%s`",
"2: Crea tutti i dati di salvataggio per `%s`",
"3: Elimina tutti i dati di salvataggio per `%s`"
],
"WebDavStrings": [
"0: WebDav avviato con successo!",
"1: WebDav fallito!"
],
"YesNo": [
"0: Sì [A]",
"1: No [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"翻訳者: %s",
"NULL"
"BackupMenu": [
"0: 新しいバックアップ"
],
"BackupMenuConfirmations": [
"0: 本当に #%s# を上書きしてもよろしいですか?",
"1: 本当に #%s# を復元してもよろしいですか?",
"2: 本当に #%s# を削除してもよろしいですか?"
],
"BackupMenuPops": [
"0: セーブデータが空です!",
"1: バックアップが空です!",
"2: セーブデータのリセット中にエラーが発生しました!",
"3: ZIPファイルの読み込み中にエラーが発生しました",
"4: バックアップの削除中にエラーが発生しました!",
"5: バックアップの作成中にエラーが発生しました!",
"6: システムへの書き込みが無効になっています!",
"7: ZIPの読み込みができません"
],
"BackupMenuStatus": [
"0: セーブデータのメタファイルを処理しています...",
"1: #%s# をリモートストレージにアップロードしています...",
"2: #%s# をリモートストレージで更新しています..."
],
"ControlGuides": [
"[A] 選択 [Y] すべてのセーブをダンプ [X] ユーザーオプション",
"[A] 選択 [L] [R] ジャンプ [Y] お気に入り [X] タイトルオプション [B] 戻る",
"[A] 選択 [Y] 復元 [X] 削除 [ZR] アップロード [B] 閉じる",
"[A] 切り替え [X] デフォルト [B] 戻る"
],
"SaveDataTypes": [
"システム",
"アカウント",
"BCAT",
"デバイス",
"一時的",
"キャッシュ",
"システム BCAT"
],
"SettingsMenu": [
"JKSV出力フォルダを設定",
"ブラックリストを編集",
"ユーザーと一緒にデバイスセーブを含める: %s",
"復元時に自動バックアップ: %s",
"バックアップの自動命名: %s",
"バックアップをリモートストレージに自動アップロード: %s",
"バックアップを削除するには長押し: %s",
"バックアップを復元するには長押し: %s",
"バックアップを上書きするには長押し: %s",
"マウント可能なタイトルのみをリスト表示: %s",
"アカウントシステムセーブを表示: %s",
"システムセーブとNANDへの書き込みを有効にする: %s",
"セーブをZIPにエクスポート: %s",
"ZIP圧縮レベル: %u",
"タイトルの並び替えタイプ: %s",
"テキストメニューJKSMモード: %s",
"強制英語: %s",
"ゴミ箱を有効にする: %s",
"アニメーションのスケーリング: %.02f"
"0: [A] 選択 [Y] すべてのセーブをダンプ [X] ユーザーオプション",
"1: [A] 選択 [L] [R] ジャンプ [Y] お気に入り [X] タイトルオプション [B] 戻る",
"2: [A] 選択 [Y] 復元 [X] 削除 [ZR] アップロード [B] 閉じる",
"3: [A] トグル [X] デフォルト [B] 戻る"
],
"ExtrasMenu": [
"タイトルを再読み込み",
"SD to SD ブラウザ",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"プロセスを終了",
"システムセーブをマウント"
"0: データの再初期化",
"1: SDからSDブラウザへ",
"2: ProdInfoF",
"3: セーフ",
"4: システム",
"5: ユーザー",
"6: プロセス終了"
],
"OnOff": [
"オフ",
">オン>"
"ExtrasPops": [
"0: データを再初期化しました!",
"1: データの再初期化に失敗しました!"
],
"BackupMenu": [
"新しいバックアップ"
"GeneralPops": [
"0: タスク実行中のためJKSVを終了できません"
],
"CopyingFiles": [
"#%s# をコピー中...",
"#%s# をZIPに圧縮中...",
"#%s# をZIPから解凍中..."
"GoogleDriveStrings": [
"0: 続行するには、 #%s# にアクセスし >%s> を入力してください!",
"1: Google Driveに正常にサインインしました",
"2: Google Driveのサインインに失敗しました"
],
"HoldingStrings": [
"0: [A] を押し続ける",
"1: [A] を押し続けています",
"2: もう少し! [A]"
],
"IOStatuses": [
"0: #%s# をコピーしています...",
"1: #%s# をZIPに圧縮しています...",
"2: #%s# をZIPから展開しています...",
"3: #%s# を削除しています..."
],
"IOPops": [
"0: デバイスへのデータ書き込みエラー!"
],
"KeyboardStrings": [
"新しいバックアップ名を入力してください。",
"キャッシュインデックスを入力してください。",
"JKSVの新しい出力パスを入力してください。",
"終了するプロセスIDを入力してください。",
"システムセーブIDを入力してください。",
"ターゲットアイテムの新しい名前を入力してください。",
"新しいフォルダの名前を入力してください。",
"%s の新しい出力フォルダ名を入力してください。",
"拡張する量MB単位を入力してください。"
"0: 新しいバックアップ名を入力してください。",
"1: キャッシュインデックスを入力してください。",
"2: JKSVの新しい出力パスを入力してください。",
"3: 終了するプロセスIDを入力してください。",
"4: システムセーブIDを入力してください。",
"5: 対象アイテムの新しい名前を入力してください。",
"6: 新しいフォルダー名を入力してください。",
"7: %s の新しい出力フォルダー名を入力してください。",
"8: どれくらい拡張するか入力してくださいMB単位。"
],
"OnOff": [
"0: オフ",
"1: >オン>"
],
"SaveCreatePops": [
"0: #%s# のセーブデータを作成しました!",
"1: セーブデータの作成中にエラーが発生しました!",
"2: セーブデータの削除中にエラーが発生しました!"
],
"SaveDataTypes": [
"0: システム",
"1: アカウント",
"2: BCAT",
"3: デバイス",
"4: 一時的",
"5: キャッシュ",
"6: システムBCAT"
],
"SettingsDescriptions": [
"0: JKSVの作業ディレクトリを設定します。デフォルト値は `sdmc:/JKSV` です。",
"1: ブラックリストからタイトルを削除できます。",
"2: デバイスまたは共有セーブをユーザーと一緒に含めます。",
"3: 他のバックアップを復元するときに自動でバックアップを作成します。",
"4: バックアップの自動命名とキーボードをスキップします。",
"5: バックアップをGoogle DriveやWebDavに自動アップロードし、ローカルから削除します。",
"6: バックアップを削除するのに[A]を3秒間保持する必要があるかどうか。",
"7: バックアップを復元するのに[A]を3秒間保持する必要があるかどうか。",
"8: バックアップを上書きするのに[A]を3秒間保持する必要があるかどうか。",
"9: JKSVが正常に開けるセーブデータのみを表示します。",
"10: アカウントIDが紐づくシステムセーブを表示します。",
"11: システムセーブの復元とNANDパーティションへの書き込みを有効にします。",
"12: セーブデータを展開フォルダーではなくZIPアーカイブとしてエクスポートします。",
"13: ZIP書き込み時の圧縮またはデフレレベル。デフォルトは6。低い値は高速ですが圧縮率と容量節約は劣ります。0は圧縮なし。",
"14: タイトルの並び順と表示方法を制御します。",
"15: 3DSのJKSMのようなテキストメニューでタイトルを表示しますアイコングリッドではなく。",
"16: システム言語ではなく英語を強制使用します。",
"17: 削除されたバックアップを永久削除せずに_TRASH_フォルダーに移動します。",
"18: トランジションとアニメーションの速度を設定します。低いほど速いです。"
],
"SettingsMenu": [
"0: JKSVの出力フォルダーを設定します。",
"1: ブラックリスト編集",
"2: ユーザーとデバイスセーブを含める: %s",
"3: 復元時に自動バックアップ: %s",
"4: 自動バックアップ名付け: %s",
"5: バックアップをリモートストレージに自動アップロード: %s",
"6: バックアップ削除時に保持: %s",
"7: バックアップ復元時に保持: %s",
"8: バックアップ上書き時に保持: %s",
"9: マウント可能なタイトルのみ表示: %s",
"10: アカウントシステムセーブを表示: %s",
"11: システムセーブとNANDへの書き込みを有効化: %s",
"12: セーブをZIPでエクスポート: %s",
"13: ZIP圧縮レベル: %u",
"14: タイトルの並べ替えタイプ: %s",
"15: テキストメニューJKSMモード: %s",
"16: 英語強制: %s",
"17: ゴミ箱有効化: %s",
"18: アニメーションスケーリング: %.02f"
],
"SortTypes": [
"0: アルファベット順",
"1: よく遊ばれている",
"2: 最後に遊ばれた"
],
"TitleInfo": [
"0: アプリID: %016lX",
"1: セーブID: %016lx",
"2: 初回プレイ: %x - %X",
"3: 最終プレイ: %x - %X",
"4: プレイ時間: %02d:%02d:%02d",
"5: 起動回数: %i",
"6: セーブタイプ: %s"
],
"TitleOptionConfirmations": [
"0: #%s# をブラックリストに追加してもよろしいですか?追加すると、タイトルリストや選択に表示されなくなります。",
"1: #%s# の現在の全バックアップを削除してもよろしいですか?*この操作は元に戻せません!*",
"2: #%s# のセーブデータをリセットしてもよろしいですか?*タイトルが起動されていなかったかのようにデータが削除されます!*",
"3: `%s` の #%s# のセーブデータを削除してもよろしいですか?*これはシステムから完全に削除されます。*"
],
"TitleOptionPops": [
"0: `%s` の全バックアップを削除しました!",
"1: 全バックアップの削除に失敗しました!",
"2: セーブデータのリセット中にエラーが発生しました!",
"3: セーブデータを正常にリセットしました!",
"4: SVIファイルを正常にエクスポートしました",
"5: SVIファイルのエクスポートに失敗しました",
"6: このオプションはシステムセーブでは使用できません!",
"7: 使用するためのパスを正規化できませんでした!",
"8: 出力フォルダを #%s# に設定しました。",
"9: 新しい出力パスの設定に失敗しました!",
"10: セーブデータを正常に拡張しました!",
"11: セーブデータの拡張に失敗しました!"
],
"TitleOptionStatus": [
"0: #%s# の全バックアップを削除中。",
"1: #%s# のセーブデータをリセット中。",
"2: #%s# の `%s` のセーブデータを削除中...",
"3: `%s` の #%s# のセーブデータを拡張中..."
],
"TitleOptions": [
"0: 情報",
"1: タイトルをブラックリストに追加",
"2: 出力フォルダを変更",
"3: ファイルモードで開く",
"4: すべてのバックアップを削除",
"5: セーブデータをリセット",
"6: システムからセーブデータを削除",
"7: セーブデータを拡張",
"8: SVIファイルをエクスポート"
],
"TranslationInfo": [
"0: 翻訳者: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: `%s` のすべてのタイトルのセーブデータをバックアップしてもよろしいですか?時間がかかる場合があります。",
"1: `%s` のすべてのタイトルのセーブデータを作成してもよろしいですか?時間がかかる場合があります。",
"2: `%s` のすべてのセーブデータを削除してもよろしいですか?これは*永久的*で元に戻せません。"
],
"UserOptionStatus": [
"0: #%s# のセーブデータを作成中...",
"1: #%s# のセーブデータを削除中..."
],
"UserOptions": [
"0: `%s` のすべてをダンプ",
"1: `%s` のセーブデータを作成",
"2: `%s` のすべてのセーブデータを作成",
"3: `%s` のすべてのセーブデータを削除"
],
"WebDavStrings": [
"0: WebDavを正常に開始しました",
"1: WebDavが失敗しました"
],
"YesNo": [
"0: はい [A]",
"1: いいえ [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"번역자: %s",
"NULL"
"BackupMenu": [
"0: 새 백업"
],
"BackupMenuConfirmations": [
"0: 정말 #%s# 을(를) 덮어쓰시겠습니까?",
"1: 정말 #%s# 을(를) 복원하시겠습니까?",
"2: 정말 #%s# 을(를) 삭제하시겠습니까?"
],
"BackupMenuPops": [
"0: 저장 데이터가 비어 있습니다!",
"1: 백업이 비어 있습니다!",
"2: 저장 데이터 초기화 오류!",
"3: ZIP 파일을 읽는 중 오류 발생!",
"4: 백업 삭제 중 오류 발생!",
"5: 백업 생성 중 오류 발생!",
"6: 시스템 쓰기가 비활성화되어 있습니다!",
"7: ZIP을 열 수 없습니다!"
],
"BackupMenuStatus": [
"0: 저장 데이터 메타 파일 처리 중...",
"1: #%s# 를 원격 저장소에 업로드 중...",
"2: 원격 저장소에서 #%s# 업데이트 중..."
],
"ControlGuides": [
"[A] 선택 [Y] 모든 세이브 덤프 [X] 사용자 옵션",
"[A] 선택 [L] [R] 점프 [Y] 즐겨찾기 [X] 타이틀 옵션 [B] 뒤로",
"[A] 선택 [Y] 복원 [X] 삭제 [ZR] 업로드 [B] 닫기",
"[A] 전환 [X] 기본값 [B] 뒤로"
],
"SaveDataTypes": [
"시스템",
"계정",
"BCAT",
"장치",
"임시",
"캐시",
"시스템 BCAT"
],
"SettingsMenu": [
"JKSV 출력 폴더 설정",
"블랙리스트 편집",
"사용자와 함께 장치 세이브 포함: %s",
"복원 시 자동 백업: %s",
"백업 자동 이름 지정: %s",
"백업을 원격 저장소에 자동 업로드: %s",
"백업을 삭제하려면 길게 누르세요: %s",
"백업을 복원하려면 길게 누르세요: %s",
"백업을 덮어쓰려면 길게 누르세요: %s",
"마운트 가능한 타이틀만 목록에 표시: %s",
"계정 시스템 세이브 표시: %s",
"시스템 세이브 및 NAND에 쓰기 활성화: %s",
"세이브를 ZIP으로 내보내기: %s",
"ZIP 압축 수준: %u",
"타이틀 정렬 유형: %s",
"텍스트 메뉴 (JKSM) 모드: %s",
"영어 강제 적용: %s",
"휴지통 활성화: %s",
"애니메이션 크기 조정: %.02f"
"0: [A] 선택 [Y] 모든 저장 덤프 [X] 사용자 옵션",
"1: [A] 선택 [L] [R] 점프 [Y] 즐겨찾기 [X] 타이틀 옵션 [B] 뒤로",
"2: [A] 선택 [Y] 복원 [X] 삭제 [ZR] 업로드 [B] 닫기",
"3: [A] 토글 [X] 기본값 [B] 뒤로"
],
"ExtrasMenu": [
"타이틀 다시 로드",
"SD to SD 브라우저",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"프로세스 종료",
"시스템 세이브 마운트"
"0: 데이터 재초기화",
"1: SD에서 SD 브라우저로",
"2: ProdInfoF",
"3: 안전 모드",
"4: 시스템",
"5: 사용자",
"6: 프로세스 종료"
],
"OnOff": [
"끄기",
">켜기>"
"ExtrasPops": [
"0: 데이터가 재초기화되었습니다!",
"1: 데이터 재초기화 실패!"
],
"BackupMenu": [
"새 백업"
"GeneralPops": [
"0: 작업 중에는 JKSV를 종료할 수 없습니다!"
],
"CopyingFiles": [
"#%s# 복사 중...",
"#%s# ZIP으로 압축 중...",
"#%s# ZIP에서 압축 해제 중..."
"GoogleDriveStrings": [
"0: 계속하려면 #%s# 에서 >%s> 를 입력하세요!",
"1: Google Drive에 성공적으로 로그인했습니다!",
"2: Google Drive 로그인 실패!"
],
"HoldingStrings": [
"0: [A] 를 누르고 있음",
"1: 계속 [A] 를 누르고 있음",
"2: 거의 완료! [A]"
],
"IOStatuses": [
"0: #%s# 복사 중...",
"1: #%s# 를 ZIP으로 압축 중...",
"2: ZIP에서 #%s# 를 압축 해제 중...",
"3: #%s# 삭제 중..."
],
"IOPops": [
"0: 장치에 데이터 커밋 오류!"
],
"KeyboardStrings": [
"새 백업 이름을 입력하세요.",
"캐시 인덱스를 입력하세요.",
"JKSV의 새로운 출력 경로를 입력하세요.",
"종료할 프로세스 ID를 입력하세요.",
"시스템 세이브 ID를 입력하세요.",
"대상 항목의 새 이름을 입력하세요.",
"새 폴더 이름을 입력하세요.",
"%s의 새 출력 폴더 이름을 입력하세요.",
"확장할 용량(MB 단위)을 입력하세요."
"0: 새 백업 이름을 입력하세요.",
"1: 캐시 인덱스를 입력하세요.",
"2: JKSV의 새 출력 경로를 입력하세요.",
"3: 종료할 프로세스 ID를 입력하세요.",
"4: 시스템 저장 ID를 입력하세요.",
"5: 대상 항목의 새 이름을 입력하세요.",
"6: 새 폴더 이름을 입력하세요.",
"7: %s 의 새 출력 폴더 이름을 입력하세요.",
"8: 확장할 용량(MB 단위)을 입력하세요."
],
"OnOff": [
"0: 꺼짐",
"1: >켜짐>"
],
"SaveCreatePops": [
"0: #%s# 에 대한 저장 데이터가 생성되었습니다!",
"1: 저장 데이터 생성 오류!",
"2: 저장 데이터 삭제 오류!"
],
"SaveDataTypes": [
"0: 시스템",
"1: 계정",
"2: BCAT",
"3: 장치",
"4: 임시",
"5: 캐시",
"6: 시스템 BCAT"
],
"SettingsDescriptions": [
"0: JKSV 작업 디렉터리를 설정합니다. 기본값은 `sdmc:/JKSV` 입니다.",
"1: 블랙리스트에서 타이틀을 제거할 수 있습니다.",
"2: 장치 또는 공유 저장 데이터를 사용자와 함께 포함합니다.",
"3: 다른 백업을 복원할 때 자동으로 백업을 생성합니다.",
"4: 백업 이름을 자동 지정하고 키보드를 건너뜁니다.",
"5: 백업을 Google Drive 또는 WebDav에 자동 업로드하고 로컬에서 삭제합니다.",
"6: 백업 삭제 시 [A] 를 3초간 누르고 있어야 하는지 여부.",
"7: 백업 복원 시 [A] 를 3초간 누르고 있어야 하는지 여부.",
"8: 백업 덮어쓰기 시 [A] 를 3초간 누르고 있어야 하는지 여부.",
"9: JKSV가 성공적으로 열 수 있는 저장 데이터만 표시합니다.",
"10: 계정 ID가 연결된 시스템 저장을 표시합니다.",
"11: 시스템 저장 복원 및 NAND 파티션 쓰기를 활성화합니다.",
"12: 저장 데이터를 풀린 폴더 대신 ZIP 아카이브로 내보냅니다.",
"13: ZIP 쓰기 시 사용하는 압축 또는 디플레이트 수준입니다. 기본값은 6입니다. 낮은 값은 더 빠르지만 압축 및 저장 공간 절약은 적습니다. 0은 저장(압축 안 함)입니다.",
"14: 타이틀의 정렬 및 표시 방식을 제어합니다.",
"15: 3DS의 원래 JKSM처럼 아이콘 그리드 대신 텍스트 메뉴로 타이틀을 표시합니다.",
"16: 감지된 시스템 언어 대신 영어를 강제로 사용합니다.",
"17: 삭제된 백업을 영구 삭제하지 않고 _TRASH_ 폴더로 이동합니다.",
"18: 전환 및 애니메이션 속도를 설정합니다. 낮을수록 빠릅니다."
],
"SettingsMenu": [
"0: JKSV 출력 폴더 설정.",
"1: 블랙리스트 편집",
"2: 사용자와 장치 저장 포함: %s",
"3: 복원 시 자동 백업: %s",
"4: 자동 백업 이름 지정: %s",
"5: 백업을 원격 저장소에 자동 업로드: %s",
"6: 백업 삭제 시 유지: %s",
"7: 백업 복원 시 유지: %s",
"8: 백업 덮어쓰기 시 유지: %s",
"9: 마운트 가능한 타이틀만 나열: %s",
"10: 계정 시스템 저장 표시: %s",
"11: 시스템 저장 및 NAND 쓰기 활성화: %s",
"12: 저장을 ZIP으로 내보내기: %s",
"13: ZIP 압축 수준: %u",
"14: 타이틀 정렬 유형: %s",
"15: 텍스트 메뉴 (JKSM) 모드: %s",
"16: 영어 강제 사용: %s",
"17: 휴지통 활성화: %s",
"18: 애니메이션 스케일링: %.02f"
],
"SortTypes": [
"0: 알파벳순",
"1: 가장 많이 플레이한 순",
"2: 마지막 플레이 순"
],
"TitleInfo": [
"0: 앱 ID: %016lX",
"1: 저장 ID: %016lx",
"2: 처음 플레이한 시간: %x - %X",
"3: 마지막 플레이한 시간: %x - %X",
"4: 플레이 시간: %02d:%02d:%02d",
"5: 실행 횟수: %i",
"6: 저장 유형: %s"
],
"TitleOptionConfirmations": [
"0: #%s# 을(를) 블랙리스트에 추가하시겠습니까? 추가하면 타이틀 목록이나 선택에 더 이상 표시되지 않습니다.",
"1: #%s# 의 현재 모든 백업을 삭제하시겠습니까? *이 작업은 취소할 수 없습니다!*",
"2: #%s# 의 저장 데이터를 재설정하시겠습니까? *이 작업은 타이틀이 실행된 적이 없는 것처럼 저장 데이터를 삭제합니다!*",
"3: `%s` 의 #%s# 저장 데이터를 삭제하시겠습니까? *시스템에서 영구 삭제됩니다.*"
],
"TitleOptionPops": [
"0: `%s` 의 모든 백업을 삭제했습니다!",
"1: 모든 백업 삭제에 실패했습니다!",
"2: 저장 데이터 재설정 오류!",
"3: 저장 데이터를 성공적으로 재설정했습니다!",
"4: SVI 파일을 성공적으로 내보냈습니다!",
"5: SVI 파일 내보내기 오류!",
"6: 이 옵션은 시스템 저장에 사용할 수 없습니다!",
"7: 사용할 경로를 정리하지 못했습니다!",
"8: 출력 폴더를 #%s# 로 설정했습니다.",
"9: 새 출력 경로 설정 오류!",
"10: 저장 데이터를 성공적으로 확장했습니다!",
"11: 저장 데이터 확장 실패!"
],
"TitleOptionStatus": [
"0: #%s# 의 모든 백업을 삭제 중입니다.",
"1: #%s# 의 저장 데이터를 재설정 중입니다.",
"2: #%s# 의 `%s` 저장 데이터를 삭제 중...",
"3: `%s` 의 #%s# 저장 데이터를 확장 중..."
],
"TitleOptions": [
"0: 정보",
"1: 타이틀 블랙리스트",
"2: 출력 폴더 변경",
"3: 파일 모드로 열기",
"4: 모든 저장 백업 삭제",
"5: 저장 데이터 재설정",
"6: 시스템에서 저장 데이터 삭제",
"7: 저장 데이터 확장",
"8: SVI 파일 내보내기"
],
"TranslationInfo": [
"0: 번역자: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: `%s` 의 모든 타이틀 저장 데이터를 백업하시겠습니까? 시간이 걸릴 수 있습니다.",
"1: `%s` 의 모든 타이틀 저장 데이터를 생성하시겠습니까? 시간이 걸릴 수 있습니다.",
"2: `%s` 의 모든 저장 데이터를 삭제하시겠습니까? *이 작업은 영구적이며 취소할 수 없습니다.*"
],
"UserOptionStatus": [
"0: #%s# 의 저장 데이터를 생성 중입니다...",
"1: #%s# 의 저장 데이터를 삭제 중입니다..."
],
"UserOptions": [
"0: `%s` 의 모든 덤프",
"1: `%s` 의 저장 데이터 생성",
"2: `%s` 의 모든 저장 데이터 생성",
"3: `%s` 의 모든 저장 데이터 삭제"
],
"WebDavStrings": [
"0: WebDav가 정상적으로 시작되었습니다!",
"1: WebDav 실패!"
],
"YesNo": [
"0: 예 [A]",
"1: 아니요 [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Vertaald door: %s",
"NULL"
"BackupMenu": [
"0: Nieuwe back-up"
],
"BackupMenuConfirmations": [
"0: Weet je zeker dat je #%s# echt wilt overschrijven?",
"1: Weet je zeker dat je #%s# echt wilt herstellen?",
"2: Weet je zeker dat je #%s# echt wilt verwijderen?"
],
"BackupMenuPops": [
"0: Opslaggegevens zijn leeg!",
"1: Back-up is leeg!",
"2: Fout bij het resetten van opslaggegevens!",
"3: Fout bij het openen van ZIP-bestand voor lezen!",
"4: Fout bij het verwijderen van back-up!",
"5: Fout bij het maken van back-up!",
"6: Schrijven naar systeem is uitgeschakeld!",
"7: Kan zip niet openen om te lezen!"
],
"BackupMenuStatus": [
"0: Metadata van opslaggegevens verwerken...",
"1: Uploaden van #%s# naar externe opslag...",
"2: Bijwerken van #%s# in externe opslag..."
],
"ControlGuides": [
"[A] Selecteer [Y] Dump alle saves [X] Gebruikersopties",
"[A] Selecteer [L] [R] Spring [Y] Favoriet [X] Titelopties [B] Terug",
"[A] Selecteer [Y] Herstellen [X] Verwijderen [ZR] Uploaden [B] Sluiten",
"[A] Schakel [X] Standaardinstellingen [B] Terug"
],
"SaveDataTypes": [
"Systeem",
"Account",
"BCAT",
"Apparaat",
"Tijdelijk",
"Cache",
"Systeem BCAT"
],
"SettingsMenu": [
"Stel JKSV uitvoermap in",
"Bewerk Zwarte lijst",
"Voeg apparaat saves toe voor gebruikers: %s",
"Auto-backup bij herstellen: %s",
"Automatisch back-ups naamgeven: %s",
"Automatisch back-ups naar externe opslag uploaden: %s",
"Houd ingedrukt om back-ups te verwijderen: %s",
"Houd ingedrukt om back-ups te herstellen: %s",
"Houd ingedrukt om back-ups te overschrijven: %s",
"Toon alleen mountbare titels: %s",
"Toon account systeem saves: %s",
"Schrijven naar systeem saves en NAND inschakelen: %s",
"Saves naar ZIP exporteren: %s",
"ZIP compressieniveau: %u",
"Titel sorteertype: %s",
"Tekstmenu (JKSM) modus: %s",
"Forceer Engels: %s",
"Schakel prullenbak in: %s",
"Animatieschaal: %.02f"
"0: [A] Selecteren [Y] Alle opslagen dumpen [X] Gebruikersopties",
"1: [A] Selecteren [L] [R] Springen [Y] Favoriet [X] Titelaanpassingen [B] Terug",
"2: [A] Selecteren [Y] Herstellen [X] Verwijderen [ZR] Uploaden [B] Sluiten",
"3: [A] Wisselen [X] Standaardwaarden [B] Terug"
],
"ExtrasMenu": [
"Laad titels opnieuw",
"SD naar SD browser",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"Stop proces",
"Mount systeem save"
"0: Gegevens opnieuw initialiseren",
"1: SD naar SD-browser",
"2: ProdInfoF",
"3: Veilige modus",
"4: Systeem",
"5: Gebruiker",
"6: Procese beëindigen"
],
"OnOff": [
"Uit",
">Aan>"
"ExtrasPops": [
"0: Gegevens opnieuw geïnitialiseerd!",
"1: Fout bij opnieuw initialiseren van gegevens!"
],
"BackupMenu": [
"Nieuwe back-up"
"GeneralPops": [
"0: Kan JKSV niet afsluiten terwijl er taken worden uitgevoerd!"
],
"CopyingFiles": [
"Bezig met kopiëren #%s#...",
"Bezig met comprimeren #%s# naar ZIP...",
"Bezig met decompressen #%s# van ZIP..."
"GoogleDriveStrings": [
"0: Ga naar #%s# en voer >%s> in om verder te gaan!",
"1: Succesvol aangemeld bij Google Drive!",
"2: Aanmelding bij Google Drive mislukt!"
],
"HoldingStrings": [
"0: Houd [A] ingedrukt",
"1: Blijf [A] ingedrukt houden",
"2: Bijna daar! [A]"
],
"IOStatuses": [
"0: Kopiëren van #%s#...",
"1: Comprimeren van #%s# naar ZIP...",
"2: Uitpakken van #%s# uit ZIP...",
"3: Verwijderen van #%s#..."
],
"IOPops": [
"0: Fout bij het opslaan van gegevens op het apparaat!"
],
"KeyboardStrings": [
"Voer een nieuwe back-up naam in.",
"Voer de cache-index in.",
"Voer een nieuw uitvoerpad voor JKSV in.",
"Voer het proces-ID in om te stoppen.",
"Voer een systeem save-ID in.",
"Voer een nieuwe naam in voor het doelitem.",
"Voer een naam in voor de nieuwe map.",
"Voer een nieuwe uitvoermapnaam in voor %s.",
"Voer in hoeveel je wilt uitbreiden (in MB)."
"0: Voer een nieuwe naam voor de back-up in.",
"1: Voer de cache-index in.",
"2: Voer een nieuw uitvoerpád in voor JKSV",
"3: Voer het proces-ID in om te beëindigen.",
"4: Voer een systeem-opslag-ID in",
"5: Voer een nieuwe naam voor het doelobject in.",
"6: Voer een naam in voor de nieuwe map.",
"7: Voer een nieuwe uitvoermapnaam in voor %s.",
"8: Voer in hoeveel er uitgebreid moet worden (MB)."
],
"OnOff": [
"0: Uit",
"1: >Aan>"
],
"SaveCreatePops": [
"0: Opslaggegevens aangemaakt voor #%s#!",
"1: Fout bij het aanmaken van opslaggegevens!",
"2: Fout bij het verwijderen van opslaggegevens!"
],
"SaveDataTypes": [
"0: Systeem",
"1: Account",
"2: BCAT",
"3: Apparaat",
"4: Tijdelijk",
"5: Cache",
"6: Systeem-BCAT"
],
"SettingsDescriptions": [
"0: Stelt de werkmap voor JKSV in. De standaardwaarde is `sdmc:/JKSV`.",
"1: Hiermee kunt u titels uit de zwarte lijst verwijderen.",
"2: Neemt apparaat- of gedeelde opslagen op bij gebruikers.",
"3: Maakt automatisch een back-up wanneer er één wordt hersteld.",
"4: Geeft automatisch namen aan back-ups en slaat toetsenbord over.",
"5: Uploadt automatisch back-ups naar Google Drive of WebDav en verwijdert ze lokaal.",
"6: Geeft aan of [A] drie seconden ingedrukt moet worden gehouden om back-ups te verwijderen.",
"7: Geeft aan of [A] drie seconden ingedrukt moet worden gehouden om back-ups te herstellen.",
"8: Geeft aan of [A] drie seconden ingedrukt moet worden gehouden om back-ups te overschrijven.",
"9: Toont alleen opslagen die JKSV met succes kan openen.",
"10: Toont systeemopslagen gekoppeld aan een account-ID.",
"11: Maakt herstel van systeemopslagen en schrijven naar NAND-partities mogelijk.",
"12: Exporteert opslaggegevens als ZIP-archieven in plaats van uitgepakte mappen.",
"13: Compressie- of deflate-niveau gebruikt bij het schrijven naar ZIP. De standaardwaarde is 6. Lagere waarden zijn sneller, maar bieden minder compressie en ruimtebesparing. Nul betekent geen compressie.",
"14: Regelt hoe titels worden gesorteerd en weergegeven.",
"15: Toont titels als tekstmenus zoals in de originele JKSM op 3DS in plaats van icoonroosters.",
"16: Dwingt Engels af als taal in plaats van de gedetecteerde systeemt taal.",
"17: Verplaatst verwijderde back-ups naar de _TRASH_-map in plaats van ze permanent te verwijderen.",
"18: Stelt de snelheid van overgangen en animaties in. Lagere waarden zijn sneller."
],
"SettingsMenu": [
"0: Stel de uitvoermap voor JKSV in.",
"1: Zwarte lijst bewerken",
"2: Apparaatopslagen opnemen bij gebruikers: %s",
"3: Automatische back-up bij herstel: %s",
"4: Automatische naamgeving van back-ups: %s",
"5: Automatische upload van back-ups naar externe opslag: %s",
"6: Houd ingedrukt om back-ups te verwijderen: %s",
"7: Houd ingedrukt om back-ups te herstellen: %s",
"8: Houd ingedrukt om back-ups te overschrijven: %s",
"9: Alleen koppelbare titels weergeven: %s",
"10: Systeemopslagen van account tonen: %s",
"11: Schrijven naar systeemopslagen en NAND inschakelen: %s",
"12: Opslagen exporteren naar ZIP: %s",
"13: ZIP-compressieniveau: %u",
"14: Sorteertype titels: %s",
"15: Tekstmenu-modus (JKSM): %s",
"16: Engels afdwingen: %s",
"17: Prullenbak inschakelen: %s",
"18: Animatieschaling: %.02f"
],
"SortTypes": [
"0: Alfabetisch",
"1: Meest gespeeld",
"2: Laatst gespeeld"
],
"TitleInfo": [
"0: App-ID: %016lX",
"1: Opslag-ID: %016lx",
"2: Eerste gespeeld: %x - %X",
"3: Laatste gespeeld: %x - %X",
"4: Speeltijd: %02d:%02d:%02d",
"5: Aantal keren gestart: %i",
"6: Opslagtype: %s"
],
"TitleOptionConfirmations": [
"0: Weet je zeker dat je #%s# aan je zwarte lijst wilt toevoegen? Zodra dat gebeurt verschijnt het niet meer in enige titelkeuze.",
"1: Weet je zeker dat je alle huidige back-ups voor #%s# wilt verwijderen? *Dit kan niet ongedaan gemaakt worden!*",
"2: Weet je zeker dat je de opslaggegevens voor #%s# wilt terugzetten? *Dit verwijdert de gegevens alsof de titel nooit is gestart!*",
"3: Weet je zeker dat je de opslaggegevens van `%s` voor #%s# wilt verwijderen? *Dit verwijdert ze permanent uit het systeem.*"
],
"TitleOptionPops": [
"0: Alle back-ups verwijderd voor `%s`!",
"1: Verwijderen van alle back-ups mislukt!",
"2: Fout bij het resetten van opslaggegevens!",
"3: Opslaggegevens succesvol gereset!",
"4: SVI-bestand succesvol geëxporteerd!",
"5: Fout bij het exporteren van SVI-bestand!",
"6: Deze optie is niet beschikbaar voor systeemopslagen!",
"7: Kan het pad niet saneren voor gebruik!",
"8: Uitvoermap ingesteld op #%s#.",
"9: Fout bij het instellen van nieuw uitvoerpad!",
"10: Opslaggegevens succesvol uitgebreid!",
"11: Uitbreiding van opslaggegevens mislukt!"
],
"TitleOptionStatus": [
"0: Alle back-ups verwijderen voor #%s#.",
"1: Opslaggegevens resetten voor #%s#.",
"2: Opslaggegevens verwijderen van #%s# voor #%s#...",
"3: Opslaggegevens uitbreiden van `%s` voor #%s#..."
],
"TitleOptions": [
"0: Informatie",
"1: Titel toevoegen aan zwarte lijst",
"2: Verander uitvoermap",
"3: Open in bestandsmodus",
"4: Verwijder alle back-ups",
"5: Reset opslaggegevens.",
"6: Verwijder opslaggegevens uit het systeem",
"7: Breid opslaggegevens uit",
"8: Exporteer SVI-bestand"
],
"TranslationInfo": [
"0: Vertaald door: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: Weet je zeker dat je opslaggegevens wilt back-uppen voor alle titels gevonden voor `%s`? Dit kan even duren.",
"1: Weet je zeker dat je opslaggegevens wilt aanmaken voor alle titels op je systeem voor `%s`? Dit kan even duren.",
"2: Weet je zeker dat je alle opslaggegevens voor `%s` wilt verwijderen? Dit is *PERMANENT* en kan niet worden teruggedraaid."
],
"UserOptionStatus": [
"0: Opslaggegevens aanmaken voor #%s#...",
"1: Opslaggegevens verwijderen voor #%s#..."
],
"UserOptions": [
"0: Alles dumpen voor `%s`",
"1: Opslaggegevens aanmaken voor `%s`",
"2: Alle opslaggegevens aanmaken voor `%s`",
"3: Alle opslaggegevens verwijderen voor `%s`"
],
"WebDavStrings": [
"0: WebDav succesvol gestart!",
"1: WebDav mislukt!"
],
"YesNo": [
"0: Ja [A]",
"1: Nee [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Traduzido por: %s",
"NULL"
"BackupMenu": [
"0: Novo Backup"
],
"BackupMenuConfirmations": [
"0: Tem a certeza de que quer mesmo substituir #%s#?",
"1: Tem a certeza de que quer mesmo restaurar #%s#?",
"2: Tem a certeza de que quer mesmo apagar #%s#?"
],
"BackupMenuPops": [
"0: Dados guardados estão vazios!",
"1: Backup está vazio!",
"2: Erro ao reiniciar dados guardados!",
"3: Erro ao abrir ficheiro ZIP para leitura!",
"4: Ocorreu um erro ao apagar o backup!",
"5: Erro ao criar backup!",
"6: Escrita no sistema está desativada!",
"7: Incapaz de abrir zip para leitura!"
],
"BackupMenuStatus": [
"0: A processar ficheiro meta dos dados guardados...",
"1: A carregar #%s# para armazenamento remoto...",
"2: A atualizar #%s# no armazenamento remoto..."
],
"ControlGuides": [
"[A] Selecionar [Y] Dump de todos os saves [X] Opções do usuário",
"[A] Selecionar [L] [R] Pular [Y] Favoritos [X] Opções de título [B] Voltar",
"[A] Selecionar [Y] Restaurar [X] Excluir [ZR] Carregar [B] Fechar",
"[A] Alternar [X] Padrões [B] Voltar"
],
"SaveDataTypes": [
"Sistema",
"Conta",
"BCAT",
"Dispositivo",
"Temporário",
"Cache",
"Sistema BCAT"
],
"SettingsMenu": [
"Defina a pasta de saída do JKSV.",
"Editar Lista Negra",
"Incluir Saves de Dispositivos com usuários: %s",
"Backup automático ao restaurar: %s",
"Nomeação automática de backups: %s",
"Carregar backups automaticamente para o armazenamento remoto: %s",
"Manter pressionado para excluir backups: %s",
"Manter pressionado para restaurar backups: %s",
"Manter pressionado para sobrescrever backups: %s",
"Listar apenas títulos montáveis: %s",
"Mostrar saves de sistema de conta: %s",
"Habilitar escrita em saves de sistema e NAND: %s",
"Exportar saves para ZIP: %s",
"Nível de compressão do ZIP: %u",
"Tipo de ordenação de títulos: %s",
"Modo de menu de texto (JKSM): %s",
"Forçar inglês: %s",
"Habilitar lixeira: %s",
"Escala de animação: %.02f"
"0: [A] Selecionar [Y] Exportar Todos os Saves [X] Opções do Utilizador",
"1: [A] Selecionar [L] [R] Saltar [Y] Favorito [X] Opções do Título [B] Voltar",
"2: [A] Selecionar [Y] Restaurar [X] Apagar [ZR] Carregar [B] Fechar",
"3: [A] Alternar [X] Predefinições [B] Voltar"
],
"ExtrasMenu": [
"Recarregar Títulos",
"Navegador SD para SD",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"Finalizar Processo",
"Montar Save de Sistema"
"0: Reinicializar Dados",
"1: Navegador SD para SD",
"2: ProdInfoF",
"3: Seguro",
"4: Sistema",
"5: Utilizador",
"6: Terminar Processo"
],
"OnOff": [
"Desligado",
">Ligado>"
"ExtrasPops": [
"0: Dados reinicializados!",
"1: Falha na reinicialização dos dados!"
],
"BackupMenu": [
"Novo Backup"
"GeneralPops": [
"0: Incapaz de sair do JKSV enquanto tarefas estão em execução!"
],
"CopyingFiles": [
"Copiando #%s#...",
"Comprimindo #%s# para ZIP...",
"Descomprimindo #%s# de ZIP..."
"GoogleDriveStrings": [
"0: Para continuar, aceda a #%s# e insira >%s>!",
"1: Sessão iniciada com sucesso no Google Drive!",
"2: Falha ao iniciar sessão no Google Drive!"
],
"HoldingStrings": [
"0: Mantenha [A]",
"1: Continue a manter [A]",
"2: Quase lá! [A]"
],
"IOStatuses": [
"0: A copiar #%s#...",
"1: A comprimir #%s# para ZIP...",
"2: A descomprimir #%s# do ZIP...",
"3: A apagar #%s#..."
],
"IOPops": [
"0: Erro ao gravar dados no dispositivo!"
],
"KeyboardStrings": [
"Digite um novo nome para o backup.",
"Digite o índice do cache.",
"Digite um novo caminho de saída para o JKSV.",
"Digite o ID do processo para finalizar.",
"Digite o ID do save de sistema.",
"Digite um novo nome para o item de destino.",
"Digite um nome para a nova pasta.",
"Digite um novo nome de pasta de saída para %s.",
"Digite o quanto expandir (em MB)."
"0: Introduza um novo nome para o backup.",
"1: Introduza o índice da cache.",
"2: Introduza um novo caminho de saída para o JKSV",
"3: Introduza o ID do processo a terminar.",
"4: Introduza um ID de save do sistema",
"5: Introduza um novo nome para o item alvo.",
"6: Introduza um nome para a nova pasta.",
"7: Introduza um novo nome para a pasta de saída para %s.",
"8: Introduza quanto expandir (em MB)."
],
"OnOff": [
"0: Desligado",
"1: >Ligado>"
],
"SaveCreatePops": [
"0: Dados guardados criados para #%s#!",
"1: Erro ao criar dados guardados!",
"2: Erro ao apagar dados guardados!"
],
"SaveDataTypes": [
"0: Sistema",
"1: Conta",
"2: BCAT",
"3: Dispositivo",
"4: Temporário",
"5: Cache",
"6: BCAT do Sistema"
],
"SettingsDescriptions": [
"0: Define a diretoria de trabalho para o JKSV. O valor por defeito é `sdmc:/JKSV`.",
"1: Permite remover títulos da lista negra.",
"2: Inclui saves de dispositivo ou partilhados com utilizadores.",
"3: Cria um backup automaticamente ao restaurar outro.",
"4: Dá nomes automáticos aos backups e ignora o teclado.",
"5: Faz upload automático dos backups para Google Drive ou WebDav e apaga-os localmente.",
"6: Define se é necessário manter [A] pressionado por três segundos para apagar backups.",
"7: Define se é necessário manter [A] pressionado por três segundos para restaurar backups.",
"8: Define se é necessário manter [A] pressionado por três segundos para sobrescrever backups.",
"9: Mostra apenas saves que o JKSV consegue abrir com sucesso.",
"10: Mostra saves de sistema com ID de conta associada.",
"11: Permite restaurar saves de sistema e gravar nas partições NAND.",
"12: Exporta saves para ficheiros ZIP em vez de pastas descompactadas.",
"13: Nível de compressão ou deflate usado ao escrever para ZIP. O valor padrão é 6. Valores mais baixos são mais rápidos, mas oferecem menos compressão e poupança de espaço. Zero é armazenar, ou sem compressão.",
"14: Controla a forma como os títulos são ordenados e exibidos.",
"15: Exibe títulos como menus de texto, como no JKSM original do 3DS, em vez de grelhas de ícones.",
"16: Força o uso do inglês como idioma em vez do idioma do sistema detectado.",
"17: Move backups apagados para a pasta _TRASH_ em vez de os apagar permanentemente.",
"18: Define a velocidade a que as transições e animações ocorrem. Valores mais baixos são mais rápidos."
],
"SettingsMenu": [
"0: Definir pasta de saída do JKSV.",
"1: Editar lista negra",
"2: Incluir saves de dispositivo com utilizadores: %s",
"3: Backup automático na restauração: %s",
"4: Nomear backups automaticamente: %s",
"5: Fazer upload automático de backups para armazenamento remoto: %s",
"6: Manter para apagar backups: %s",
"7: Manter para restaurar backups: %s",
"8: Manter para sobrescrever backups: %s",
"9: Apenas listar títulos montáveis: %s",
"10: Mostrar saves de sistema de conta: %s",
"11: Ativar escrita em saves de sistema e NAND: %s",
"12: Exportar saves para ZIP: %s",
"13: Nível de compressão ZIP: %u",
"14: Tipo de ordenação de título: %s",
"15: Modo de menu de texto (JKSM): %s",
"16: Forçar inglês: %s",
"17: Ativar reciclagem: %s",
"18: Escala de animação: %.02f"
],
"SortTypes": [
"0: Alfabeticamente",
"1: Mais Jogados",
"2: Últimos Jogados"
],
"TitleInfo": [
"0: ID do App: %016lX",
"1: ID do Save: %016lx",
"2: Primeiro Jogar: %x - %X",
"3: Último Jogar: %x - %X",
"4: Tempo de Jogo: %02d:%02d:%02d",
"5: Inícios: %i",
"6: Tipo de Save: %s"
],
"TitleOptionConfirmations": [
"0: Tem a certeza que quer adicionar #%s# à sua lista negra? Uma vez adicionado, não aparecerá em nenhuma lista ou seleção de títulos.",
"1: Tem a certeza que quer apagar todos os backups atuais para #%s#? *Isto não pode ser desfeito!*",
"2: Tem a certeza que quer reiniciar os dados guardados para #%s#? *Isto apagará os dados guardados como se o título nunca tivesse sido executado!*",
"3: Tem a certeza que quer apagar os dados guardados de `%s` para #%s#? *Isto apagará permanentemente do sistema.*"
],
"TitleOptionPops": [
"0: Todos os backups apagados para `%s`!",
"1: Falha ao apagar todos os backups!",
"2: Erro ao reiniciar dados guardados!",
"3: Dados guardados reiniciados com sucesso!",
"4: Ficheiro SVI exportado com sucesso!",
"5: Erro ao exportar ficheiro SVI!",
"6: Esta opção não está disponível para saves de sistema!",
"7: Não foi possível sanitizar o caminho para uso!",
"8: Pasta de saída definida para #%s#.",
"9: Erro ao definir novo caminho de saída!",
"10: Dados guardados estendidos com sucesso!",
"11: Falha ao estender dados guardados!"
],
"TitleOptionStatus": [
"0: A apagar todos os backups para #%s#.",
"1: A reiniciar dados guardados para #%s#.",
"2: A apagar dados guardados de `%s` para #%s#...",
"3: A estender dados guardados de `%s` para #%s#..."
],
"TitleOptions": [
"0: Informação",
"1: Lista negra do título",
"2: Alterar pasta de saída",
"3: Abrir em modo ficheiro",
"4: Apagar todos os backups guardados",
"5: Reiniciar dados guardados.",
"6: Apagar dados guardados do sistema",
"7: Estender dados guardados",
"8: Exportar ficheiro SVI"
],
"TranslationInfo": [
"0: Traduzido por: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: Tem a certeza que quer fazer backup dos dados guardados de todos os títulos encontrados para `%s`? Isto pode demorar algum tempo.",
"1: Tem a certeza que quer criar dados guardados para todos os títulos encontrados no seu sistema para `%s`? Isto pode demorar algum tempo.",
"2: Tem a certeza que quer apagar todos os dados guardados para `%s`? Isto é *PERMANENTE* e não pode ser desfeito."
],
"UserOptionStatus": [
"0: A criar dados guardados para #%s#...",
"1: A apagar dados guardados para #%s#..."
],
"UserOptions": [
"0: Exportar tudo para `%s`",
"1: Criar dados guardados para `%s`",
"2: Criar todos os dados guardados para `%s`",
"3: Apagar todos os dados guardados para `%s`"
],
"WebDavStrings": [
"0: WebDav iniciado com sucesso!",
"1: Falha no WebDav!"
],
"YesNo": [
"0: Sim [A]",
"1: Não [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Traduzido por: %s",
"NULL"
"BackupMenu": [
"0: Novo Backup"
],
"BackupMenuConfirmations": [
"0: Tem certeza de que deseja realmente sobrescrever #%s#?",
"1: Tem certeza de que deseja realmente restaurar #%s#?",
"2: Tem certeza de que deseja realmente excluir #%s#?"
],
"BackupMenuPops": [
"0: Os dados salvos estão vazios!",
"1: O backup está vazio!",
"2: Erro ao redefinir dados salvos!",
"3: Erro ao abrir arquivo ZIP para leitura!",
"4: Ocorreu um erro ao excluir o backup!",
"5: Erro ao criar backup!",
"6: Escrita no sistema está desabilitada!",
"7: Não foi possível abrir o zip para leitura!"
],
"BackupMenuStatus": [
"0: Processando arquivo meta dos dados salvos...",
"1: Enviando #%s# para o armazenamento remoto...",
"2: Atualizando #%s# no armazenamento remoto..."
],
"ControlGuides": [
"[A] Selecionar [Y] Dump de todos os saves [X] Opções do usuário",
"[A] Selecionar [L] [R] Pular [Y] Favoritos [X] Opções de título [B] Voltar",
"[A] Selecionar [Y] Restaurar [X] Excluir [ZR] Carregar [B] Fechar",
"[A] Alternar [X] Padrões [B] Voltar"
],
"SaveDataTypes": [
"Sistema",
"Conta",
"BCAT",
"Dispositivo",
"Temporário",
"Cache",
"Sistema BCAT"
],
"SettingsMenu": [
"Defina a pasta de saída do JKSV.",
"Editar Lista Negra",
"Incluir Saves de Dispositivos com usuários: %s",
"Backup automático ao restaurar: %s",
"Nomeação automática de backups: %s",
"Carregar backups automaticamente para o armazenamento remoto: %s",
"Manter pressionado para excluir backups: %s",
"Manter pressionado para restaurar backups: %s",
"Manter pressionado para sobrescrever backups: %s",
"Listar apenas títulos montáveis: %s",
"Mostrar saves de sistema de conta: %s",
"Habilitar escrita em saves de sistema e NAND: %s",
"Exportar saves para ZIP: %s",
"Nível de compressão do ZIP: %u",
"Tipo de ordenação de títulos: %s",
"Modo de menu de texto (JKSM): %s",
"Forçar inglês: %s",
"Habilitar lixeira: %s",
"Escala de animação: %.02f"
"0: [A] Selecionar [Y] Exportar Todos os Saves [X] Opções do Usuário",
"1: [A] Selecionar [L] [R] Pular [Y] Favorito [X] Opções do Título [B] Voltar",
"2: [A] Selecionar [Y] Restaurar [X] Excluir [ZR] Enviar [B] Fechar",
"3: [A] Alternar [X] Padrões [B] Voltar"
],
"ExtrasMenu": [
"Recarregar Títulos",
"Navegador SD para SD",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"Finalizar Processo",
"Montar Save de Sistema"
"0: Reinicializar Dados",
"1: Navegador SD para SD",
"2: ProdInfoF",
"3: Seguro",
"4: Sistema",
"5: Usuário",
"6: Encerrar Processo"
],
"OnOff": [
"Desligado",
">Ligado>"
"ExtrasPops": [
"0: Dados reinicializados!",
"1: Falha na reinicialização dos dados!"
],
"BackupMenu": [
"Novo Backup"
"GeneralPops": [
"0: Não é possível sair do JKSV enquanto tarefas estiverem em execução!"
],
"CopyingFiles": [
"Copiando #%s#...",
"Comprimindo #%s# para ZIP...",
"Descomprimindo #%s# de ZIP..."
"GoogleDriveStrings": [
"0: Para continuar, acesse #%s# e digite >%s>!",
"1: Login realizado com sucesso no Google Drive!",
"2: Falha no login do Google Drive!"
],
"HoldingStrings": [
"0: Segure [A]",
"1: Continue segurando [A]",
"2: Quase lá! [A]"
],
"IOStatuses": [
"0: Copiando #%s#...",
"1: Comprimindo #%s# para ZIP...",
"2: Descomprimindo #%s# do ZIP...",
"3: Excluindo #%s#..."
],
"IOPops": [
"0: Erro ao gravar dados no dispositivo!"
],
"KeyboardStrings": [
"Digite um novo nome para o backup.",
"Digite o índice do cache.",
"Digite um novo caminho de saída para o JKSV.",
"Digite o ID do processo para finalizar.",
"Digite o ID do save de sistema.",
"Digite um novo nome para o item de destino.",
"Digite um nome para a nova pasta.",
"Digite um novo nome de pasta de saída para %s.",
"Digite o quanto expandir (em MB)."
"0: Digite um novo nome para o backup.",
"1: Digite o índice do cache.",
"2: Digite um novo caminho de saída para o JKSV",
"3: Digite o ID do processo para encerrar.",
"4: Digite um ID de save do sistema",
"5: Digite um novo nome para o item alvo.",
"6: Digite um nome para a nova pasta.",
"7: Digite um novo nome para a pasta de saída para %s.",
"8: Digite quanto expandir (em MB)."
],
"OnOff": [
"0: Desligado",
"1: >Ligado>"
],
"SaveCreatePops": [
"0: Dados salvos criados para #%s#!",
"1: Erro ao criar dados salvos!",
"2: Erro ao excluir dados salvos!"
],
"SaveDataTypes": [
"0: Sistema",
"1: Conta",
"2: BCAT",
"3: Dispositivo",
"4: Temporário",
"5: Cache",
"6: BCAT do Sistema"
],
"SettingsDescriptions": [
"0: Define o diretório de trabalho para o JKSV. O valor padrão é `sdmc:/JKSV`.",
"1: Permite remover títulos da lista negra.",
"2: Inclui saves de dispositivo ou compartilhados com usuários.",
"3: Cria um backup automaticamente ao restaurar outro.",
"4: Nomes automáticos para backups e pula o teclado.",
"5: Faz upload automático dos backups para Google Drive ou WebDav e apaga-os localmente.",
"6: Define se é necessário segurar [A] por três segundos para excluir backups.",
"7: Define se é necessário segurar [A] por três segundos para restaurar backups.",
"8: Define se é necessário segurar [A] por três segundos para sobrescrever backups.",
"9: Mostra apenas saves que o JKSV consegue abrir com sucesso.",
"10: Mostra saves de sistema que têm um ID de conta vinculado.",
"11: Permite restaurar saves de sistema e escrever nas partições NAND.",
"12: Exporta saves para arquivos ZIP em vez de pastas descompactadas.",
"13: Nível de compressão ou deflate usado ao escrever para ZIP. O padrão é 6. Valores mais baixos são mais rápidos, mas oferecem menos compressão e economia de espaço. Zero significa armazenar, sem compressão.",
"14: Controla como os títulos são ordenados e exibidos.",
"15: Exibe títulos como menus de texto, como no JKSM original do 3DS, em vez de grade de ícones.",
"16: Força o uso do inglês como idioma em vez do idioma do sistema detectado.",
"17: Move backups apagados para a pasta _TRASH_ em vez de apagá-los permanentemente.",
"18: Define a velocidade das transições e animações. Valores mais baixos são mais rápidos."
],
"SettingsMenu": [
"0: Definir pasta de saída do JKSV.",
"1: Editar lista negra",
"2: Incluir saves de dispositivo com usuários: %s",
"3: Backup automático ao restaurar: %s",
"4: Nomear backups automaticamente: %s",
"5: Upload automático de backups para armazenamento remoto: %s",
"6: Segurar para excluir backups: %s",
"7: Segurar para restaurar backups: %s",
"8: Segurar para sobrescrever backups: %s",
"9: Listar apenas títulos montáveis: %s",
"10: Mostrar saves de sistema de conta: %s",
"11: Habilitar escrita em saves de sistema e NAND: %s",
"12: Exportar saves para ZIP: %s",
"13: Nível de compressão ZIP: %u",
"14: Tipo de ordenação de título: %s",
"15: Modo menu de texto (JKSM): %s",
"16: Forçar inglês: %s",
"17: Habilitar lixeira: %s",
"18: Escala de animação: %.02f"
],
"SortTypes": [
"0: Alfabeticamente",
"1: Mais Jogados",
"2: Últimos Jogados"
],
"TitleInfo": [
"0: ID do App: %016lX",
"1: ID do Save: %016lx",
"2: Primeiro Jogar: %x - %X",
"3: Último Jogar: %x - %X",
"4: Tempo de Jogo: %02d:%02d:%02d",
"5: Inícios: %i",
"6: Tipo de Save: %s"
],
"TitleOptionConfirmations": [
"0: Tem certeza de que deseja adicionar #%s# à sua lista negra? Depois disso, não aparecerá em nenhuma lista ou seleção de títulos.",
"1: Tem certeza de que deseja excluir todos os backups atuais para #%s#? *Isso não pode ser desfeito!*",
"2: Tem certeza de que deseja redefinir os dados salvos para #%s#? *Isso apagará os dados salvos como se o título nunca tivesse sido jogado!*",
"3: Tem certeza de que deseja excluir os dados salvos de `%s` para #%s#? *Isso excluirá permanentemente do sistema.*"
],
"TitleOptionPops": [
"0: Todos os backups excluídos para `%s`!",
"1: Falha ao excluir todos os backups!",
"2: Erro ao redefinir dados salvos!",
"3: Dados salvos redefinidos com sucesso!",
"4: Arquivo SVI exportado com sucesso!",
"5: Erro ao exportar arquivo SVI!",
"6: Esta opção não está disponível para saves de sistema!",
"7: Não foi possível sanitizar o caminho para uso!",
"8: Pasta de saída definida para #%s#.",
"9: Erro ao definir novo caminho de saída!",
"10: Dados salvos estendidos com sucesso!",
"11: Falha ao estender dados salvos!"
],
"TitleOptionStatus": [
"0: Excluindo todos os backups para #%s#.",
"1: Redefinindo dados salvos para #%s#.",
"2: Excluindo dados salvos de `%s` para #%s#...",
"3: Estendendo dados salvos de `%s` para #%s#..."
],
"TitleOptions": [
"0: Informações",
"1: Lista negra do título",
"2: Alterar pasta de saída",
"3: Abrir em modo arquivo",
"4: Excluir todos os backups salvos",
"5: Redefinir dados salvos.",
"6: Excluir dados salvos do sistema",
"7: Estender dados salvos",
"8: Exportar arquivo SVI"
],
"TranslationInfo": [
"0: Traduzido por: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: Tem certeza de que deseja fazer backup dos dados salvos de todos os títulos encontrados para `%s`? Isso pode levar algum tempo.",
"1: Tem certeza de que deseja criar dados salvos para todos os títulos encontrados no seu sistema para `%s`? Isso pode levar algum tempo.",
"2: Tem certeza de que deseja excluir todos os dados salvos para `%s`? Isso é *PERMANENTE* e não pode ser desfeito."
],
"UserOptionStatus": [
"0: Criando dados salvos para #%s#...",
"1: Excluindo dados salvos para #%s#..."
],
"UserOptions": [
"0: Exportar tudo para `%s`",
"1: Criar dados salvos para `%s`",
"2: Criar todos os dados salvos para `%s`",
"3: Excluir todos os dados salvos para `%s`"
],
"WebDavStrings": [
"0: WebDav iniciado com sucesso!",
"1: Falha no WebDav!"
],
"YesNo": [
"0: Sim [A]",
"1: Não [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"Переведено: %s",
"NULL"
"BackupMenu": [
"0: Новый бэкап"
],
"BackupMenuConfirmations": [
"0: Вы действительно хотите перезаписать #%s#?",
"1: Вы действительно хотите восстановить #%s#?",
"2: Вы действительно хотите удалить #%s#?"
],
"BackupMenuPops": [
"0: Сохраненные данные пусты!",
"1: Резервная копия пуста!",
"2: Ошибка сброса сохраненных данных!",
"3: Ошибка при открытии ZIP-файла для чтения!",
"4: Произошла ошибка при удалении резервной копии!",
"5: Ошибка создания резервной копии!",
"6: Запись в систему отключена!",
"7: Не удалось открыть архив ZIP для чтения!"
],
"BackupMenuStatus": [
"0: Обработка метафайла сохраненных данных...",
"1: Загрузка #%s# в удаленное хранилище...",
"2: Обновление #%s# в удаленном хранилище..."
],
"ControlGuides": [
"[A] Выбрать [Y] Сохранить все [X] Опции пользователя",
"[A] Выбрать [L] [R] Прыжок [Y] Избранное [X] Опции титула [B] Назад",
"[A] Выбрать [Y] Восстановить [X] Удалить [ZR] Загрузить [B] Закрыть",
"[A] Переключить [X] По умолчанию [B] Назад"
],
"SaveDataTypes": [
"Система",
"Аккаунт",
"BCAT",
"Устройство",
"Временные",
"Кэш",
"Системный BCAT"
],
"SettingsMenu": [
"Установить папку вывода JKSV.",
"Редактировать черный список",
"Включить сохранения устройств с пользователями: %s",
"Автозапас при восстановлении: %s",
"Автоматическое именование резервных копий: %s",
"Автоматическая загрузка резервных копий на удаленное хранилище: %s",
"Удерживайте для удаления резервных копий: %s",
"Удерживайте для восстановления резервных копий: %s",
"Удерживайте для перезаписи резервных копий: %s",
"Отображать только монтируемые титулы: %s",
"Показывать системные сохранения аккаунта: %s",
"Разрешить запись в системные сохранения и NAND: %s",
"Экспортировать сохранения в ZIP: %s",
"Уровень сжатия ZIP: %u",
"Тип сортировки титулов: %s",
"Режим текстового меню (JKSM): %s",
"Принудительный английский: %s",
"Включить корзину: %s",
"Масштабирование анимации: %.02f"
"0: [A] Выбрать [Y] Выгрузить все сохранения [X] Опции пользователя",
"1: [A] Выбрать [L] [R] Прыжок [Y] В избранное [X] Опции заголовка [B] Назад",
"2: [A] Выбрать [Y] Восстановить [X] Удалить [ZR] Загрузить [B] Закрыть",
"3: [A] Переключить [X] По умолчанию [B] Назад"
],
"ExtrasMenu": [
"Перезагрузить титулы",
"SD на SD браузер",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"Завершить процесс",
"Монтировать системное сохранение"
"0: Переинициализировать данные",
"1: SD в SD браузер",
"2: ProdInfoF",
"3: Безопасно",
"4: Система",
"5: Пользователь",
"6: Завершить процесс"
],
"OnOff": [
"Выключено",
">Включено>"
"ExtrasPops": [
"0: Данные переинициализированы!",
"1: Не удалось переинициализировать данные!"
],
"BackupMenu": [
"Новый резервный файл"
"GeneralPops": [
"0: Невозможно выйти из JKSV, пока выполняются задачи!"
],
"CopyingFiles": [
"Копирование #%s#...",
"Сжатие #%s# в ZIP...",
"Распаковка #%s# из ZIP..."
"GoogleDriveStrings": [
"0: Для продолжения перейдите к #%s# и введите >%s>!",
"1: Успешный вход в Google Drive!",
"2: Вход в Google Drive не удался!"
],
"HoldingStrings": [
"0: Удерживайте [A]",
"1: Продолжайте удерживать [A]",
"2: Почти готово! [A]"
],
"IOStatuses": [
"0: Копирование #%s#...",
"1: Сжатие #%s# в ZIP...",
"2: Распаковка #%s# из ZIP...",
"3: Удаление #%s#..."
],
"IOPops": [
"0: Ошибка записи данных на устройство!"
],
"KeyboardStrings": [
"Введите новое имя резервной копии.",
"Введите индекс кэша.",
"Введите новый путь вывода для JKSV.",
"Введите ID процесса для завершения.",
"Введите ID системного сохранения.",
"Введите новое имя для целевого элемента.",
"Введите имя для новой папки.",
"Введите новое имя выходной папки для %s.",
"Введите, на сколько расширить (в МБ)."
"0: Введите новое имя резервной копии.",
"1: Введите индекс кэша.",
"2: Введите новый путь вывода для JKSV",
"3: Введите ID процесса для завершения.",
"4: Введите ID сохранения системы",
"5: Введите новое имя для целевого объекта.",
"6: Введите имя новой папки.",
"7: Введите новое имя папки вывода для %s.",
"8: Введите размер расширения (в МБ)."
],
"OnOff": [
"0: Выкл",
"1: >Вкл>"
],
"SaveCreatePops": [
"0: Сохраненные данные созданы для #%s#!",
"1: Ошибка при создании сохраненных данных!",
"2: Ошибка при удалении сохраненных данных!"
],
"SaveDataTypes": [
"0: Система",
"1: Аккаунт",
"2: BCAT",
"3: Устройство",
"4: Временное",
"5: Кэш",
"6: Системный BCAT"
],
"SettingsDescriptions": [
"0: Устанавливает рабочий каталог для JKSV. Значение по умолчанию — `sdmc:/JKSV`.",
"1: Позволяет удалять игры из черного списка.",
"2: Включает данные устройств или общие сохранения пользователей.",
"3: Автоматически создает резервную копию при восстановлении другой.",
"4: Автоматически именует резервные копии и пропускает клавиатуру.",
"5: Автоматически загружает резервные копии на Google Drive или WebDav и удаляет их локально.",
"6: Требуется ли удерживать [A] в течение трех секунд для удаления резервных копий.",
"7: Требуется ли удерживать [A] в течение трех секунд для восстановления резервных копий.",
"8: Требуется ли удерживать [A] в течение трех секунд для перезаписи резервных копий.",
"9: Показывать только те сохранения, которые JKSV может открыть.",
"10: Показывать сохранения системы, связанные с учетной записью.",
"11: Включить восстановление системных сохранений и запись в NAND-разделы.",
"12: Экспортировать сохранения в архивы ZIP вместо распакованных папок.",
"13: Уровень сжатия или дефляции при записи ZIP. По умолчанию 6. Меньшие значения быстрее, но с меньшим сжатием и экономией места. Ноль — без сжатия.",
"14: Управляет сортировкой и отображением игр.",
"15: Показывать игры в виде текстовых меню, как в оригинальном JKSM для 3DS, вместо сетки иконок.",
"16: Принудительно использовать английский язык вместо системного.",
"17: Перемещать удаленные резервные копии в папку _TRASH_, а не удалять окончательно.",
"18: Устанавливает скорость анимаций и переходов. Меньше — быстрее."
],
"SettingsMenu": [
"0: Установить папку вывода JKSV.",
"1: Редактировать черный список",
"2: Включить сохранения устройства с пользователями: %s",
"3: Автоматический бэкап при восстановлении: %s",
"4: Автоимя для бэкапов: %s",
"5: Автоматическая загрузка бэкапов в удаленное хранилище: %s",
"6: Удерживать для удаления бэкапов: %s",
"7: Удерживать для восстановления бэкапов: %s",
"8: Удерживать для перезаписи бэкапов: %s",
"9: Показывать только монтируемые игры: %s",
"10: Показать сохранения учетных записей: %s",
"11: Включить запись в системные сохранения и NAND: %s",
"12: Экспорт в ZIP: %s",
"13: Уровень сжатия ZIP: %u",
"14: Тип сортировки игр: %s",
"15: Режим текстового меню (JKSM): %s",
"16: Принудительный английский: %s",
"17: Включить корзину: %s",
"18: Масштаб анимации: %.02f"
],
"SortTypes": [
"0: По алфавиту",
"1: По количеству игр",
"2: По последнему запуску"
],
"TitleInfo": [
"0: ID приложения: %016lX",
"1: ID сохранения: %016lx",
"2: Первый запуск: %x - %X",
"3: Последний запуск: %x - %X",
"4: Время игры: %02d:%02d:%02d",
"5: Запуски: %i",
"6: Тип сохранения: %s"
],
"TitleOptionConfirmations": [
"0: Вы уверены, что хотите добавить #%s# в черный список? После этого он не будет отображаться в списках и выборе игр.",
"1: Вы уверены, что хотите удалить все текущие резервные копии для #%s#? *Это нельзя отменить!*",
"2: Вы уверены, что хотите сбросить сохраненные данные для #%s#? *Это удалит текущие данные, как будто игра никогда не запускалась!*",
"3: Вы уверены, что хотите удалить сохраненные данные `%s` для #%s#? *Это навсегда удалит их из системы.*"
],
"TitleOptionPops": [
"0: Все резервные копии для `%s` удалены!",
"1: Не удалось удалить все резервные копии!",
"2: Ошибка сброса сохраненных данных!",
"3: Сохраненные данные успешно сброшены!",
"4: Файл SVI успешно экспортирован!",
"5: Ошибка при экспорте файла SVI!",
"6: Эта опция недоступна для системных сохранений!",
"7: Не удалось очистить путь для использования!",
"8: Папка вывода установлена на #%s#.",
"9: Ошибка установки нового пути вывода!",
"10: Данные успешно расширены!",
"11: Ошибка расширения данных!"
],
"TitleOptionStatus": [
"0: Удаление всех резервных копий для #%s#.",
"1: Сброс сохраненных данных для #%s#.",
"2: Удаление сохраненных данных `%s` для #%s#...",
"3: Расширение сохраненных данных `%s` для #%s#..."
],
"TitleOptions": [
"0: Информация",
"1: Добавить в черный список",
"2: Изменить папку вывода",
"3: Открыть в файловом режиме",
"4: Удалить все резервные копии",
"5: Сбросить сохраненные данные.",
"6: Удалить сохраненные данные из системы",
"7: Расширить сохраненные данные",
"8: Экспортировать файл SVI"
],
"TranslationInfo": [
"0: Переведено: %s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: Вы уверены, что хотите сделать резервную копию сохраненных данных для всех найденных игр для `%s`? Это может занять некоторое время.",
"1: Вы уверены, что хотите создать сохраненные данные для всех игр на вашей системе для `%s`? Это может занять некоторое время.",
"2: Вы уверены, что хотите удалить все сохраненные данные для `%s`? Это *НЕОБРАТИМО* и не может быть отменено."
],
"UserOptionStatus": [
"0: Создание сохраненных данных для #%s#...",
"1: Удаление сохраненных данных для #%s#..."
],
"UserOptions": [
"0: Выгрузить все для `%s`",
"1: Создать сохраненные данные для `%s`",
"2: Создать все сохраненные данные для `%s`",
"3: Удалить все сохраненные данные для `%s`"
],
"WebDavStrings": [
"0: WebDav успешно запущен!",
"1: Ошибка WebDav!"
],
"YesNo": [
"0: Да [A]",
"1: Нет [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"翻译者: %s",
"NULL"
"BackupMenu": [
"0: 新备份"
],
"BackupMenuConfirmations": [
"0: 您确定要覆盖 #%s# 吗?",
"1: 您确定要恢复 #%s# 吗?",
"2: 您确定要删除 #%s# 吗?"
],
"BackupMenuPops": [
"0: 存档数据为空!",
"1: 备份为空!",
"2: 重置存档数据时出错!",
"3: 打开ZIP文件读取时出错",
"4: 删除备份时出错!",
"5: 创建备份时出错!",
"6: 写入系统已禁用!",
"7: 无法打开ZIP读取"
],
"BackupMenuStatus": [
"0: 正在处理存档数据元文件…",
"1: 正在上传 #%s# 到远程存储…",
"2: 正在更新远程存储中的 #%s#…"
],
"ControlGuides": [
"[A] 选择 [Y] 导出所有保存 [X] 用户选项",
"[A] 选择 [L] [R] 跳跃 [Y] 收藏 [X] 标题选项 [B] 返回",
"[A] 选择 [Y] 恢复 [X] 删除 [ZR] 上传 [B] 关闭",
"[A] 切换 [X] 默认 [B] 返回"
],
"SaveDataTypes": [
"系统",
"账户",
"BCAT",
"设备",
"临时",
"缓存",
"系统 BCAT"
],
"SettingsMenu": [
"设置 JKSV 输出文件夹。",
"编辑黑名单",
"与用户一起包含设备保存: %s",
"恢复时自动备份: %s",
"自动命名备份: %s",
"自动上传备份到远程存储: %s",
"长按删除备份: %s",
"长按恢复备份: %s",
"长按覆盖备份: %s",
"仅列出可挂载的标题: %s",
"显示账户系统保存: %s",
"启用写入系统保存和NAND: %s",
"将保存导出为ZIP: %s",
"ZIP 压缩级别: %u",
"标题排序类型: %s",
"文本菜单JKSM模式: %s",
"强制使用英语: %s",
"启用回收站: %s",
"动画缩放: %.02f"
"0: [A] 选择 [Y] 导出所有存档 [X] 用户选项",
"1: [A] 选择 [L] [R] 跳转 [Y] 收藏 [X] 标题选项 [B] 返回",
"2: [A] 选择 [Y] 恢复 [X] 删除 [ZR] 上传 [B] 关闭",
"3: [A] 切换 [X] 默认 [B] 返回"
],
"ExtrasMenu": [
"重新加载标题",
"SD 到 SD 浏览器",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"终止进程",
"挂载系统保存"
"0: 重新初始化数据",
"1: SD 到 SD 浏览器",
"2: ProdInfoF",
"3: 安全",
"4: 系统",
"5: 用户",
"6: 终止进程"
],
"OnOff": [
"关闭",
">开启>"
"ExtrasPops": [
"0: 数据已重新初始化!",
"1: 重新初始化数据失败!"
],
"BackupMenu": [
"新建备份"
"GeneralPops": [
"0: 任务运行时无法退出 JKSV"
],
"CopyingFiles": [
"正在复制 #%s#...",
"正在将 #%s# 压缩为ZIP...",
"正在从ZIP解压 #%s#..."
"GoogleDriveStrings": [
"0: 继续请访问 #%s# 并输入 >%s>",
"1: 成功登录 Google Drive",
"2: 登录 Google Drive 失败!"
],
"HoldingStrings": [
"0: 按住 [A]",
"1: 继续按住 [A]",
"2: 快完成了![A]"
],
"IOStatuses": [
"0: 正在复制 #%s#…",
"1: 正在压缩 #%s# 到 ZIP…",
"2: 正在从 ZIP 解压 #%s#…",
"3: 正在删除 #%s#…"
],
"IOPops": [
"0: 提交数据到设备时出错!"
],
"KeyboardStrings": [
"输入一个新的备份名称。",
"输入缓存索引。",
"输入一个新的 JKSV 输出路径。",
"输入要终止的进程ID。",
"输入系统保存ID。",
"输入目标项的新名称。",
"输入新文件夹名称。",
"输入 %s 的新输出文件夹名称。",
"输入扩展量以MB为单位。"
"0: 输入新的备份名称。",
"1: 输入缓存索引。",
"2: 输入 JKSV 的新输出路径",
"3: 输入要终止的进程 ID。",
"4: 输入系统存档 ID",
"5: 输入目标项目的新名称。",
"6: 输入新文件夹名称。",
"7: 输入 %s 的新输出文件夹名称。",
"8: 输入扩展大小MB。"
],
"OnOff": [
"0: 关闭",
"1: >开启>"
],
"SaveCreatePops": [
"0: 为 #%s# 创建了存档数据!",
"1: 创建存档数据时出错!",
"2: 删除存档数据时出错!"
],
"SaveDataTypes": [
"0: 系统",
"1: 账户",
"2: BCAT",
"3: 设备",
"4: 临时",
"5: 缓存",
"6: 系统 BCAT"
],
"SettingsDescriptions": [
"0: 设置 JKSV 的工作目录。默认值为 `sdmc:/JKSV`。",
"1: 允许您从黑名单中移除标题。",
"2: 包括设备或共享存档与用户。",
"3: 恢复时自动创建备份。",
"4: 自动命名备份并跳过键盘。",
"5: 自动上传备份到 Google Drive 或 WebDav 并在本地删除。",
"6: 是否需要按住 [A] 三秒以删除备份。",
"7: 是否需要按住 [A] 三秒以恢复备份。",
"8: 是否需要按住 [A] 三秒以覆盖备份。",
"9: 仅显示 JKSV 能成功打开的存档数据。",
"10: 显示与账户 ID 绑定的系统存档。",
"11: 启用恢复系统存档并写入 NAND 分区。",
"12: 导出存档数据为 ZIP 压缩包而非解压文件夹。",
"13: 写入 ZIP 时的压缩或压缩等级。默认值为 6。数值越低速度越快但压缩率和节省空间减少。0 表示存储或无压缩。",
"14: 控制标题的排序和显示方式。",
"15: 显示标题为文本菜单,像原版 JKSM 在 3DS 上,而非图标网格。",
"16: 强制使用英文而非系统检测语言。",
"17: 删除的备份移动到 _TRASH_ 文件夹而非永久删除。",
"18: 设置过渡和动画速度。值越低越快。"
],
"SettingsMenu": [
"0: 设置 JKSV 输出文件夹。",
"1: 编辑黑名单",
"2: 包括带有用户的设备存档:%s",
"3: 恢复时自动备份:%s",
"4: 自动命名备份:%s",
"5: 自动上传备份到远程存储:%s",
"6: 按住删除备份:%s",
"7: 按住恢复备份:%s",
"8: 按住覆盖备份:%s",
"9: 仅列出可挂载的标题:%s",
"10: 显示账户系统存档:%s",
"11: 启用写入系统存档和 NAND%s",
"12: 导出保存到 ZIP%s",
"13: ZIP 压缩等级:%u",
"14: 标题排序类型:%s",
"15: 文本菜单JKSM模式%s",
"16: 强制英文:%s",
"17: 启用回收站:%s",
"18: 动画缩放:%.02f"
],
"SortTypes": [
"0: 按字母顺序",
"1: 最多游玩",
"2: 最近游玩"
],
"TitleInfo": [
"0: 应用 ID%016lX",
"1: 存档 ID%016lx",
"2: 首次游玩:%x - %X",
"3: 最后游玩:%x - %X",
"4: 游玩时间:%02d:%02d:%02d",
"5: 启动次数:%i",
"6: 存档类型:%s"
],
"TitleOptionConfirmations": [
"0: 确定要将 #%s# 加入黑名单吗?一旦加入,将不再出现在任何标题列表或选择中。",
"1: 确定要删除 #%s# 的所有当前存档备份吗?*此操作不可撤销!*",
"2: 确定要重置 #%s# 的存档数据吗?*这将删除当前存档数据,好像游戏从未运行过!*",
"3: 确定要删除 `%s` 的 #%s# 存档数据吗?*这将永久从系统中删除。*"
],
"TitleOptionPops": [
"0: 已删除 `%s` 的所有备份!",
"1: 删除所有备份失败!",
"2: 重置存档数据失败!",
"3: 存档数据重置成功!",
"4: SVI 文件导出成功!",
"5: 导出 SVI 文件失败!",
"6: 该选项对系统存档不可用!",
"7: 无法清理路径以供使用!",
"8: 输出文件夹已设置为 #%s#。",
"9: 设置新输出路径失败!",
"10: 存档数据扩展成功!",
"11: 存档数据扩展失败!"
],
"TitleOptionStatus": [
"0: 正在删除 #%s# 的所有备份。",
"1: 正在重置 #%s# 的存档数据。",
"2: 正在删除 `%s` 的 #%s# 存档数据…",
"3: 正在扩展 `%s` 的 #%s# 存档数据…"
],
"TitleOptions": [
"0: 信息",
"1: 加入黑名单",
"2: 更改输出文件夹",
"3: 以文件模式打开",
"4: 删除所有存档备份",
"5: 重置存档数据。",
"6: 从系统删除存档数据",
"7: 扩展存档数据",
"8: 导出 SVI 文件"
],
"TranslationInfo": [
"0: 翻译者:%s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: 确定要备份 `%s` 的所有找到的标题的存档数据吗?这可能需要一些时间。",
"1: 确定要为系统中所有找到的 `%s` 标题创建存档数据吗?这可能需要一些时间。",
"2: 确定要删除 `%s` 的所有存档数据吗?*此操作不可撤销*。"
],
"UserOptionStatus": [
"0: 正在创建 #%s# 的存档数据…",
"1: 正在删除 #%s# 的存档数据…"
],
"UserOptions": [
"0: 导出 `%s` 的所有数据",
"1: 为 `%s` 创建存档数据",
"2: 为 `%s` 创建所有存档数据",
"3: 删除 `%s` 的所有存档数据"
],
"WebDavStrings": [
"0: WebDav 启动成功!",
"1: WebDav 启动失败!"
],
"YesNo": [
"0: 是 [A]",
"1: 否 [B]"
]
}

View File

@ -1,75 +1,215 @@
{
"TranslationInfo": [
"翻譯者: %s",
"NULL"
"BackupMenu": [
"0: 新備份"
],
"BackupMenuConfirmations": [
"0: 您確定要覆蓋 #%s# 嗎?",
"1: 您確定要還原 #%s# 嗎?",
"2: 您確定要刪除 #%s# 嗎?"
],
"BackupMenuPops": [
"0: 存檔資料為空!",
"1: 備份為空!",
"2: 重置存檔資料時出錯!",
"3: 打開 ZIP 檔案以讀取時出錯!",
"4: 刪除備份時發生錯誤!",
"5: 建立備份時出錯!",
"6: 系統寫入已被禁用!",
"7: 無法開啟 ZIP 讀取!"
],
"BackupMenuStatus": [
"0: 正在處理存檔資料元檔案...",
"1: 正在上傳 #%s# 至遠端儲存空間...",
"2: 正在更新遠端儲存空間中的 #%s# ..."
],
"ControlGuides": [
"[A] 選擇 [Y] 匯出所有儲存 [X] 使用者選項",
"[A] 選擇 [L] [R] 跳躍 [Y] 收藏 [X] 標題選項 [B] 返回",
"[A] 選擇 [Y] 恢復 [X] 刪除 [ZR] 上傳 [B] 關閉",
"[A] 切換 [X] 預設 [B] 返回"
],
"SaveDataTypes": [
"系統",
"帳號",
"BCAT",
"設備",
"臨時",
"快取",
"系統 BCAT"
],
"SettingsMenu": [
"設定 JKSV 輸出資料夾。",
"編輯黑名單",
"與使用者一起包含設備儲存: %s",
"恢復時自動備份: %s",
"自動命名備份: %s",
"自動將備份上傳至遠端儲存: %s",
"長按刪除備份: %s",
"長按恢復備份: %s",
"長按覆寫備份: %s",
"僅列出可掛載標題: %s",
"顯示帳號系統儲存: %s",
"啟用寫入系統儲存和 NAND: %s",
"將儲存匯出為 ZIP: %s",
"ZIP 壓縮等級: %u",
"標題排序類型: %s",
"文字選單JKSM模式: %s",
"強制使用英文: %s",
"啟用回收桶: %s",
"動畫縮放: %.02f"
"0: [A] 選擇 [Y] 匯出所有存檔 [X] 使用者選項",
"1: [A] 選擇 [L] [R] 跳轉 [Y] 收藏 [X] 標題選項 [B] 返回",
"2: [A] 選擇 [Y] 還原 [X] 刪除 [ZR] 上傳 [B] 關閉",
"3: [A] 切換 [X] 預設 [B] 返回"
],
"ExtrasMenu": [
"重新載入標題",
"SD 到 SD 瀏覽器",
"BIS: ProfInfoF",
"BIS: Safe",
"BIS: System",
"BIS: User",
"終止進程",
"掛載系統儲存"
"0: 重新初始化資料",
"1: SD 到 SD 瀏覽器",
"2: ProdInfoF",
"3: 安全",
"4: 系統",
"5: 使用者",
"6: 終止程序"
],
"OnOff": [
"關閉",
">開啟>"
"ExtrasPops": [
"0: 資料已重新初始化!",
"1: 重新初始化資料失敗!"
],
"BackupMenu": [
"新增備份"
"GeneralPops": [
"0: 任務運行中無法退出 JKSV"
],
"CopyingFiles": [
"正在複製 #%s#...",
"正在將 #%s# 壓縮為 ZIP...",
"正在從 ZIP 解壓 #%s#..."
"GoogleDriveStrings": [
"0: 請前往 #%s# 並輸入 >%s> 以繼續!",
"1: 成功登入 Google 雲端硬碟!",
"2: 登入 Google 雲端硬碟失敗!"
],
"HoldingStrings": [
"0: 按住 [A]",
"1: 繼續按住 [A]",
"2: 快完成了![A]"
],
"IOStatuses": [
"0: 正在複製 #%s# ...",
"1: 正在壓縮 #%s# 至 ZIP ...",
"2: 正在從 ZIP 解壓縮 #%s# ...",
"3: 正在刪除 #%s# ..."
],
"IOPops": [
"0: 提交資料至裝置時出錯!"
],
"KeyboardStrings": [
"輸入一個新的備份名稱。",
"輸入快取索引。",
"輸入新的 JKSV 輸出路徑。",
"輸入要終止的進程ID。",
"輸入系統儲存ID。",
"輸入目標項目的新名稱。",
"輸入新資料夾名稱。",
"輸入 %s 的新輸出資料夾名稱。",
"輸入擴展量(以 MB 為單位)。"
"0: 輸入新的備份名稱。",
"1: 輸入快取索引。",
"2: 輸入 JKSV 的新輸出路徑",
"3: 輸入要終止的程序 ID。",
"4: 輸入系統存檔 ID",
"5: 輸入目標項目的新名稱。",
"6: 輸入新資料夾名稱。",
"7: 輸入 %s 的新輸出資料夾名稱。",
"8: 輸入擴展大小MB。"
],
"OnOff": [
"0: 關閉",
"1: >開啟>"
],
"SaveCreatePops": [
"0: 為 #%s# 建立了存檔資料!",
"1: 建立存檔資料時出錯!",
"2: 刪除存檔資料時出錯!"
],
"SaveDataTypes": [
"0: 系統",
"1: 帳號",
"2: BCAT",
"3: 裝置",
"4: 臨時",
"5: 快取",
"6: 系統 BCAT"
],
"SettingsDescriptions": [
"0: 設定 JKSV 的工作目錄。預設值為 `sdmc:/JKSV`。",
"1: 允許您從黑名單中移除標題。",
"2: 包含裝置或共用存檔與使用者。",
"3: 還原時自動建立備份。",
"4: 自動命名備份並跳過鍵盤。",
"5: 自動上傳備份至 Google 雲端硬碟或 WebDav 並於本地刪除。",
"6: 是否需按住 [A] 三秒以刪除備份。",
"7: 是否需按住 [A] 三秒以還原備份。",
"8: 是否需按住 [A] 三秒以覆寫備份。",
"9: 僅顯示 JKSV 能成功開啟的存檔資料。",
"10: 顯示綁定帳號 ID 的系統存檔。",
"11: 啟用還原系統存檔並寫入 NAND 分割區。",
"12: 匯出存檔資料為 ZIP 壓縮檔而非解壓資料夾。",
"13: 寫入 ZIP 時的壓縮等級。預設為 6。值越低速度越快但壓縮率與節省空間較少。0 為存儲或無壓縮。",
"14: 控制標題排序與顯示方式。",
"15: 以文字選單顯示標題,類似 3DS 原版 JKSM而非圖示網格。",
"16: 強制使用英文而非系統偵測語言。",
"17: 刪除的備份移至 _TRASH_ 資料夾而非永久刪除。",
"18: 設定過渡與動畫速度。數值越低越快。"
],
"SettingsMenu": [
"0: 設定 JKSV 輸出資料夾。",
"1: 編輯黑名單",
"2: 包含帶使用者的裝置存檔:%s",
"3: 還原時自動備份:%s",
"4: 自動命名備份:%s",
"5: 自動上傳備份至遠端儲存:%s",
"6: 按住刪除備份:%s",
"7: 按住還原備份:%s",
"8: 按住覆寫備份:%s",
"9: 僅列出可掛載標題:%s",
"10: 顯示帳號系統存檔:%s",
"11: 啟用寫入系統存檔及 NAND%s",
"12: 匯出存檔至 ZIP%s",
"13: ZIP 壓縮等級:%u",
"14: 標題排序類型:%s",
"15: 文字選單JKSM模式%s",
"16: 強制英文:%s",
"17: 啟用垃圾桶:%s",
"18: 動畫縮放:%.02f"
],
"SortTypes": [
"0: 按字母順序",
"1: 最多遊玩",
"2: 最近遊玩"
],
"TitleInfo": [
"0: 應用程式 ID%016lX",
"1: 存檔 ID%016lx",
"2: 首次遊玩:%x - %X",
"3: 最後遊玩:%x - %X",
"4: 遊玩時間:%02d:%02d:%02d",
"5: 啟動次數:%i",
"6: 存檔類型:%s"
],
"TitleOptionConfirmations": [
"0: 確定要將 #%s# 加入黑名單嗎?加入後將不會再出現在任何標題列表或選擇中。",
"1: 確定要刪除 #%s# 所有當前存檔備份嗎?*此操作無法復原!*",
"2: 確定要重置 #%s# 的存檔資料嗎?*這將刪除目前的存檔資料,彷彿遊戲從未執行過!*",
"3: 確定要刪除 `%s` 的 #%s# 存檔資料嗎?*此動作將永久從系統中刪除。*"
],
"TitleOptionPops": [
"0: 已刪除 `%s` 的所有備份!",
"1: 刪除所有備份失敗!",
"2: 重置存檔資料失敗!",
"3: 存檔資料重置成功!",
"4: SVI 檔案匯出成功!",
"5: 匯出 SVI 檔案失敗!",
"6: 此選項對系統存檔不可用!",
"7: 無法清理路徑供使用!",
"8: 輸出資料夾設定為 #%s#。",
"9: 設定新輸出路徑失敗!",
"10: 存檔資料延伸成功!",
"11: 存檔資料延伸失敗!"
],
"TitleOptionStatus": [
"0: 正在刪除 #%s# 的所有備份。",
"1: 正在重置 #%s# 的存檔資料。",
"2: 正在刪除 `%s` 的 #%s# 存檔資料...",
"3: 正在延伸 `%s` 的 #%s# 存檔資料..."
],
"TitleOptions": [
"0: 資訊",
"1: 加入黑名單標題",
"2: 更改輸出資料夾",
"3: 以檔案模式開啟",
"4: 刪除所有存檔備份",
"5: 重置存檔資料。",
"6: 從系統刪除存檔資料",
"7: 延伸存檔資料",
"8: 匯出 SVI 檔案"
],
"TranslationInfo": [
"0: 翻譯者:%s",
"1: NULL"
],
"UserOptionConfirmations": [
"0: 確定要備份 `%s` 所有找到的標題的存檔資料嗎?這可能需要一些時間。",
"1: 確定要為系統中找到的所有 `%s` 標題建立存檔資料嗎?這可能需要一些時間。",
"2: 確定要刪除 `%s` 的所有存檔資料嗎?*此操作不可復原*。"
],
"UserOptionStatus": [
"0: 正在建立 #%s# 的存檔資料...",
"1: 正在刪除 #%s# 的存檔資料..."
],
"UserOptions": [
"0: 匯出 `%s` 的所有資料",
"1: 為 `%s` 建立存檔資料",
"2: 為 `%s` 建立所有存檔資料",
"3: 刪除 `%s` 的所有存檔資料"
],
"WebDavStrings": [
"0: WebDav 啟動成功!",
"1: WebDav 啟動失敗!"
],
"YesNo": [
"0: 是 [A]",
"1: 否 [B]"
]
}

View File

@ -10,7 +10,6 @@
#include "fslib.hpp"
#include "input.hpp"
#include "keyboard.hpp"
#include "remote/remote.hpp"
#include "sdl.hpp"
#include "strings.hpp"
#include "stringutil.hpp"
@ -58,6 +57,7 @@ BackupMenuState::~BackupMenuState()
sm_slidePanel->clear_elements();
sm_slidePanel->reset();
sm_backupMenu->reset();
remote::Storage *remote = remote::get_remote_storage();
if (remote && remote->is_initialized()) { remote->return_to_root(); }
@ -116,9 +116,10 @@ void BackupMenuState::render()
void BackupMenuState::refresh()
{
const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD);
remote::Storage *remote = remote::get_remote_storage();
m_directoryListing.open(m_directoryPath);
if (!m_directoryListing) { return; }
if (!autoUpload && !m_directoryListing) { return; }
sm_backupMenu->reset();
m_menuEntries.clear();
@ -128,10 +129,10 @@ void BackupMenuState::refresh()
if (remote && remote->is_initialized())
{
const std::string_view prefix = remote->get_prefix();
remote::Storage::DirectoryListing listing = remote->get_directory_listing();
const std::string_view prefix = remote->get_prefix();
m_remoteListing = remote->get_directory_listing();
int index{};
for (const remote::Item *item : listing)
for (const remote::Item *item : m_remoteListing)
{
const std::string_view name = item->get_name();
const std::string option = stringutil::get_formatted_string("%s %s", prefix.data(), name.data());
@ -212,9 +213,10 @@ void BackupMenuState::initialize_remote_storage()
void BackupMenuState::name_and_create_backup()
{
const bool autoName = config::get_by_key(config::keys::AUTO_NAME_BACKUPS);
const bool exportZip = config::get_by_key(config::keys::EXPORT_TO_ZIP) || config::get_by_key(config::keys::AUTO_UPLOAD);
const bool zrHeld = input::button_held(HidNpadButton_ZR);
const bool autoName = config::get_by_key(config::keys::AUTO_NAME_BACKUPS);
const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD);
const bool exportZip = config::get_by_key(config::keys::EXPORT_TO_ZIP);
const bool zrHeld = input::button_held(HidNpadButton_ZR);
const char *keyboardHeader = strings::get_by_name(strings::names::KEYBOARD, 0);
const bool autoNamed = (autoName || zrHeld); // This can be eval'd here.
char name[SIZE_NAME_LENGTH + 1] = {0};
@ -224,43 +226,71 @@ void BackupMenuState::name_and_create_backup()
const bool named = autoNamed || keyboard::get_input(SwkbdType_QWERTY, name, keyboardHeader, name, SIZE_NAME_LENGTH);
if (!named) { return; }
fslib::Path target{m_directoryPath / name};
const bool hasZipExt = std::strstr(target.full_path(), STRING_ZIP_EXT); // This might not be the best check.
if (exportZip && !hasZipExt) { target += STRING_ZIP_EXT; }
else if (!exportZip && !hasZipExt)
const bool hasZipExt = std::strstr(name, STRING_ZIP_EXT); // This might not be the best check.
std::shared_ptr<ProgressState> backupTask{};
if (autoUpload)
{
const bool targetExists = fslib::directory_exists(target);
const bool targetCreated = !targetExists && fslib::create_directory(target);
if (!hasZipExt) { std::strncat(name, STRING_ZIP_EXT, SIZE_NAME_LENGTH); }
backupTask = std::make_shared<ProgressState>(tasks::backup::create_new_backup_remote,
m_user,
m_titleInfo,
std::string{name},
this,
true);
}
auto newBackupTask =
std::make_shared<ProgressState>(tasks::backup::create_new_backup, m_user, m_titleInfo, target, this, true);
StateManager::push_state(newBackupTask);
else
{
fslib::Path target{m_directoryPath / name};
if (exportZip && !hasZipExt) { target += STRING_ZIP_EXT; }
else if (!exportZip && !hasZipExt)
{
const bool targetExists = fslib::directory_exists(target);
const bool targetCreated = !targetExists && fslib::create_directory(target);
}
backupTask =
std::make_shared<ProgressState>(tasks::backup::create_new_backup_local, m_user, m_titleInfo, target, this, true);
}
if (backupTask) { StateManager::push_state(backupTask); }
}
void BackupMenuState::confirm_overwrite()
{
remote::Storage *remote = remote::get_remote_storage();
const int selected = sm_backupMenu->get_selected();
const MenuEntry &entry = m_menuEntries.at(selected);
const bool holdRequired = config::get_by_key(config::keys::HOLD_FOR_OVERWRITE);
const char *confirmTemplate = strings::get_by_name(strings::names::BACKUPMENU_CONFS, 0);
m_dataStruct->path = m_directoryPath / m_directoryListing[entry.index];
const std::string query = stringutil::get_formatted_string(confirmTemplate, m_directoryListing[entry.index]);
auto confirm = std::make_shared<ProgressConfirm>(query, holdRequired, tasks::backup::overwrite_backup, m_dataStruct);
StateManager::push_state(confirm);
std::shared_ptr<ProgressConfirm> confirm{};
if (entry.type == MenuEntryType::Remote && remote && remote->is_initialized())
{
m_dataStruct->remoteItem = m_remoteListing.at(entry.index);
const std::string query =
stringutil::get_formatted_string(confirmTemplate, m_dataStruct->remoteItem->get_name().data());
confirm = std::make_shared<ProgressConfirm>(query, holdRequired, tasks::backup::overwrite_backup_remote, m_dataStruct);
}
else if (entry.type == MenuEntryType::Local)
{
const std::string query = stringutil::get_formatted_string(confirmTemplate, m_directoryListing[entry.index]);
m_dataStruct->path = m_directoryPath / m_directoryListing[entry.index];
confirm = std::make_shared<ProgressConfirm>(query, holdRequired, tasks::backup::overwrite_backup_local, m_dataStruct);
}
if (confirm) { StateManager::push_state(confirm); }
}
void BackupMenuState::confirm_restore()
{
const int selected = sm_backupMenu->get_selected();
const MenuEntry &entry = m_menuEntries.at(selected);
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const bool holdRequired = config::get_by_key(config::keys::HOLD_FOR_RESTORATION);
const char *confirmTemplate = strings::get_by_name(strings::names::BACKUPMENU_CONFS, 1);
const char *popBackupEmpty = strings::get_by_name(strings::names::BACKUPMENU_POPS, 1);
const char *popSysNotAllowed = strings::get_by_name(strings::names::BACKUPMENU_POPS, 6);
const bool isSystem = BackupMenuState::is_system_save_data();
const bool isSystem = BackupMenuState::user_is_system();
const bool allowSystem = config::get_by_key(config::keys::ALLOW_WRITING_TO_SYSTEM);
const bool isValidRestore = !isSystem || allowSystem;
if (!isValidRestore)
@ -269,19 +299,30 @@ void BackupMenuState::confirm_restore()
return;
}
const fslib::Path target = m_directoryPath / m_directoryListing[entry.index];
const bool targetIsDirectory = fslib::directory_exists(target);
const bool backupIsGood = targetIsDirectory ? fs::directory_has_contents(target) : fs::zip_has_contents(target);
if (!backupIsGood)
std::shared_ptr<ProgressConfirm> confirm{};
if (entry.type == MenuEntryType::Local)
{
ui::PopMessageManager::push_message(popTicks, popBackupEmpty);
return;
const fslib::Path target = m_directoryPath / m_directoryListing[entry.index];
const bool targetIsDirectory = fslib::directory_exists(target);
const bool backupIsGood = targetIsDirectory ? fs::directory_has_contents(target) : fs::zip_has_contents(target);
if (!backupIsGood)
{
ui::PopMessageManager::push_message(popTicks, popBackupEmpty);
return;
}
m_dataStruct->path = target;
const std::string query = stringutil::get_formatted_string(confirmTemplate, m_directoryListing[entry.index]);
confirm = std::make_shared<ProgressConfirm>(query, holdRequired, tasks::backup::restore_backup_local, m_dataStruct);
}
else if (entry.type == MenuEntryType::Remote)
{
remote::Item *target = m_remoteListing[entry.index];
const std::string query = stringutil::get_formatted_string(confirmTemplate, target->get_name().data());
m_dataStruct->remoteItem = target;
confirm = std::make_shared<ProgressConfirm>(query, holdRequired, tasks::backup::restore_backup_remote, m_dataStruct);
}
m_dataStruct->path = target;
const std::string query = stringutil::get_formatted_string(confirmTemplate, m_directoryListing[entry.index]);
auto confirm = std::make_shared<ProgressConfirm>(query, holdRequired, tasks::backup::restore_backup, m_dataStruct);
StateManager::push_state(confirm);
if (confirm) { StateManager::push_state(confirm); }
}
void BackupMenuState::confirm_delete()
@ -290,10 +331,21 @@ void BackupMenuState::confirm_delete()
const MenuEntry &entry = m_menuEntries.at(selected);
const bool holdRequired = config::get_by_key(config::keys::HOLD_FOR_DELETION);
const char *confirmTemplate = strings::get_by_name(strings::names::BACKUPMENU_CONFS, 2);
m_dataStruct->path = m_directoryPath / m_directoryListing[entry.index];
const std::string query = stringutil::get_formatted_string(confirmTemplate, m_directoryListing[entry.index]);
auto confirm = std::make_shared<TaskConfirm>(query, holdRequired, tasks::backup::delete_backup, m_dataStruct);
std::shared_ptr<TaskConfirm> confirm{};
if (entry.type == MenuEntryType::Local)
{
m_dataStruct->path = m_directoryPath / m_directoryListing[entry.index];
const std::string query = stringutil::get_formatted_string(confirmTemplate, m_directoryListing[entry.index]);
confirm = std::make_shared<TaskConfirm>(query, holdRequired, tasks::backup::delete_backup_local, m_dataStruct);
}
else if (entry.type == MenuEntryType::Remote)
{
m_dataStruct->remoteItem = m_remoteListing.at(entry.index);
const std::string query =
stringutil::get_formatted_string(confirmTemplate, m_dataStruct->remoteItem->get_name().data());
confirm = std::make_shared<TaskConfirm>(query, holdRequired, tasks::backup::delete_backup_remote, m_dataStruct);
}
StateManager::push_state(confirm);
}
@ -312,7 +364,7 @@ void BackupMenuState::upload_backup()
void BackupMenuState::pop_save_empty()
{
const int ticks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int ticks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popEmpty = strings::get_by_name(strings::names::BACKUPMENU_POPS, 0);
ui::PopMessageManager::push_message(ticks, popEmpty);
}

View File

@ -75,7 +75,7 @@ void ExtrasMenuState::initialize_menu()
void ExtrasMenuState::reinitialize_data()
{
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popSuccess = strings::get_by_name(strings::names::EXTRASMENU_POPS, 0);
const char *popFailure = strings::get_by_name(strings::names::EXTRASMENU_POPS, 1);

View File

@ -13,7 +13,7 @@
void ProgressState::update()
{
sys::ProgressTask *task = static_cast<sys::ProgressTask *>(m_task.get());
const double current = task->get_current();
const double current = task->get_progress();
// Base routine.
BaseTask::update();

View File

@ -97,6 +97,9 @@ static void create_save_data(sys::Task *task,
if (error::is_null(task)) { return; }
const char *statusTemplate = strings::get_by_name(strings::names::USEROPTION_STATUS, 0);
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popSuccess = strings::get_by_name(strings::names::SAVECREATE_POPS, 8);
const char *popFailed = strings::get_by_name(strings::names::SAVECREATE_POPS, 9);
{
const std::string status = stringutil::get_formatted_string(statusTemplate, titleInfo->get_title());
@ -105,15 +108,10 @@ static void create_save_data(sys::Task *task,
if (fs::create_save_data_for(targetUser, titleInfo))
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
strings::get_by_name(strings::names::SAVECREATE_POPS, 0),
titleInfo->get_title());
}
else
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
strings::get_by_name(strings::names::SAVECREATE_POPS, 1));
const std::string popMessage = stringutil::get_formatted_string(popSuccess, titleInfo->get_title());
ui::PopMessageManager::push_message(popTicks, popMessage);
}
else { ui::PopMessageManager::push_message(popTicks, popFailed); }
spawningState->data_and_view_refresh_required();

View File

@ -162,7 +162,7 @@ void TitleOptionState::update()
FsSaveDataInfo *saveInfo = m_user->get_save_info_by_id(m_titleInfo->get_application_id());
if (fs::is_system_save_data(saveInfo) && !config::get_by_key(config::keys::ALLOW_WRITING_TO_SYSTEM))
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 6));
return;
}
@ -187,7 +187,7 @@ void TitleOptionState::update()
FsSaveDataInfo *saveInfo = m_user->get_save_info_by_id(m_titleInfo->get_application_id());
if (fs::is_system_save_data(saveInfo) && !config::get_by_key(config::keys::ALLOW_WRITING_TO_SYSTEM))
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 6));
return;
}
@ -214,7 +214,7 @@ void TitleOptionState::update()
FsSaveDataInfo *saveInfo = m_user->get_save_info_by_id(m_titleInfo->get_application_id());
if (fs::is_system_save_data(saveInfo) && !config::get_by_key(config::keys::ALLOW_WRITING_TO_SYSTEM))
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 6));
return;
}
@ -279,71 +279,61 @@ static void blacklist_title(sys::Task *task, std::shared_ptr<TitleOptionState::D
static void change_output_path(data::TitleInfo *targetTitle)
{
// This is where we're writing the path.
char pathBuffer[0x200] = {0};
static constexpr size_t SIZE_PATH_BUFFER = 0x200;
const char *headerTemplate = strings::get_by_name(strings::names::KEYBOARD, 7);
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popSuccess = strings::get_by_name(strings::names::TITLEOPTION_POPS, 1);
const char *popFailure = strings::get_by_name(strings::names::TITLEOPTION_POPS, 0);
const char *pathSafeTitle = targetTitle->get_path_safe_title();
// Header string.
std::string headerString =
stringutil::get_formatted_string(strings::get_by_name(strings::names::KEYBOARD, 7), targetTitle->get_title());
// Try to get input.
if (!keyboard::get_input(SwkbdType_QWERTY, targetTitle->get_path_safe_title(), headerString, pathBuffer, 0x200)) { return; }
// Try to make sure it will work.
if (!stringutil::sanitize_string_for_path(pathBuffer, pathBuffer, 0x200))
const std::string headerString = stringutil::get_formatted_string(headerTemplate, targetTitle->get_title());
char pathBuffer[SIZE_PATH_BUFFER] = {0};
const bool inputIsValid = keyboard::get_input(SwkbdType_QWERTY, pathSafeTitle, headerString, pathBuffer, SIZE_PATH_BUFFER);
const bool sanitized = inputIsValid && stringutil::sanitize_string_for_path(pathBuffer, pathBuffer, SIZE_PATH_BUFFER);
if (!inputIsValid || !sanitized)
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 0));
ui::PopMessageManager::push_message(popTicks, popFailure);
return;
}
// Rename folder to match so there are no issues.
fslib::Path oldPath = config::get_working_directory() / targetTitle->get_path_safe_title();
fslib::Path newPath = config::get_working_directory() / pathBuffer;
if (fslib::directory_exists(oldPath) && !fslib::rename_directory(oldPath, newPath))
const fslib::Path workDir = config::get_working_directory();
const fslib::Path oldPath{workDir / targetTitle->get_path_safe_title()};
const fslib::Path newPath{workDir / pathBuffer};
const bool dirExists = fslib::directory_exists(oldPath);
const bool renameFailed = dirExists && error::fslib(fslib::rename_directory(oldPath, newPath));
if (dirExists && renameFailed)
{
// Bail if this fails, because something is really wrong.
logger::log("Error setting new output path: %s", fslib::error::get_string());
ui::PopMessageManager::push_message(popTicks, popFailure);
return;
}
// Add it to config and set target title to use it.
targetTitle->set_path_safe_title(pathBuffer, std::strlen(pathBuffer));
config::add_custom_path(targetTitle->get_application_id(), pathBuffer);
// Pop so we know stuff happened.
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 1),
pathBuffer);
const std::string popMessage = stringutil::get_formatted_string(popSuccess, pathBuffer);
ui::PopMessageManager::push_message(popTicks, popMessage);
}
static void delete_all_backups_for_title(sys::Task *task, std::shared_ptr<TitleOptionState::DataStruct> dataStruct)
{
if (error::is_null(task)) { return; }
data::TitleInfo *titleInfo = dataStruct->titleInfo;
const char *statusTemplate = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 0);
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popSuccess = strings::get_by_name(strings::names::TITLEOPTION_POPS, 0);
const char *popFailure = strings::get_by_name(strings::names::TITLEOPTION_POPS, 1);
{
const std::string status = stringutil::get_formatted_string(statusTemplate, titleInfo->get_title());
task->set_status(status);
}
fslib::Path titlePath = config::get_working_directory() / titleInfo->get_path_safe_title();
const fslib::Path titlePath{config::get_working_directory() / titleInfo->get_path_safe_title()};
const bool deleteFailed = error::fslib(fslib::delete_directory_recursively(titlePath));
if (deleteFailed) { ui::PopMessageManager::push_message(popTicks, popFailure); }
else { const std::string popMessage = stringutil::get_formatted_string(popSuccess, titleInfo->get_title()); }
// Just call this and nuke the folder.
if (!fslib::delete_directory_recursively(titlePath))
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 1));
}
else
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 0),
titleInfo->get_title());
}
task->finished();
}
@ -356,7 +346,7 @@ static void reset_save_data(sys::Task *task, std::shared_ptr<TitleOptionState::D
const uint64_t applicationID = titleInfo->get_application_id();
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popFailed = strings::get_by_name(strings::names::TITLEOPTION_POPS, 2);
const char *popSucceeded = strings::get_by_name(strings::names::TITLEOPTION_POPS, 3);
@ -419,7 +409,7 @@ static void extend_save_data(sys::Task *task, std::shared_ptr<TitleOptionState::
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(titleInfo->get_application_id());
const char *statusTemplate = strings::get_by_name(strings::names::TITLEOPTION_STATUS, 3);
const char *keyboardHeader = strings::get_by_name(strings::names::KEYBOARD, 8);
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popSuccess = strings::get_by_name(strings::names::TITLEOPTION_POPS, 10);
const char *popFailed = strings::get_by_name(strings::names::TITLEOPTION_POPS, 11);
if (error::is_null(task) || error::is_null(saveInfo)) { return; }
@ -466,7 +456,7 @@ static void export_svi_file(data::TitleInfo *titleInfo)
{
logger::log("SVI for %016llX already exists!", titleInfo->get_application_id());
// Just show this and bail.
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 5));
return;
}
@ -476,7 +466,7 @@ static void export_svi_file(data::TitleInfo *titleInfo)
if (!sviFile)
{
logger::log("Error exporting SVI file: %s", fslib::error::get_string());
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 5));
}
@ -489,6 +479,6 @@ static void export_svi_file(data::TitleInfo *titleInfo)
sviFile.write(titleInfo->get_control_data(), sizeof(NsApplicationControlData));
// Show this so we know things happened.jpg
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::TITLEOPTION_POPS, 4));
}

View File

@ -231,7 +231,7 @@ static void create_all_save_data_for_user(sys::Task *task, std::shared_ptr<UserO
UserOptionState *spawningState = dataStruct->spawningState;
auto &titleInfoMap = data::get_title_info_map();
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *statusTemplate = strings::get_by_name(strings::names::USEROPTION_STATUS, 0);
const char *popFailure = strings::get_by_name(strings::names::SAVECREATE_POPS, 0);
const FsSaveDataType saveType = user->get_account_save_type();
@ -261,7 +261,7 @@ static void delete_all_save_data_for_user(sys::Task *task, std::shared_ptr<UserO
UserOptionState *spawningState = dataStruct->spawningState;
const char *statusTemplate = strings::get_by_name(strings::names::USEROPTION_STATUS, 1); // Borrowed. No duplication.
const char *popFailed = strings::get_by_name(strings::names::SAVECREATE_POPS, 2);
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const size_t totalDataEntries = user->get_total_data_entries();
std::vector<uint64_t> applicationIDs;

View File

@ -1,6 +1,7 @@
#include "config.hpp"
#include "JSON.hpp"
#include "error.hpp"
#include "logger.hpp"
#include "stringutil.hpp"
@ -43,7 +44,7 @@ static void read_array_to_vector(std::vector<uint64_t> &vector, json_object *arr
// Just in case. Shouldn't happen though.
vector.clear();
size_t arrayLength = json_object_array_length(array);
const size_t arrayLength = json_object_array_length(array);
for (size_t i = 0; i < arrayLength; i++)
{
json_object *arrayEntry = json_object_array_get_idx(array, i);
@ -54,9 +55,13 @@ static void read_array_to_vector(std::vector<uint64_t> &vector, json_object *arr
void config::initialize()
{
if (!fslib::directory_exists(PATH_CONFIG_FOLDER) && !fslib::create_directories_recursively(PATH_CONFIG_FOLDER))
// This is so we don't constantly construct new Paths
const fslib::Path configDir{PATH_CONFIG_FOLDER};
const bool configDirExists = fslib::directory_exists(configDir);
const bool configDirError = !configDirExists && error::fslib(fslib::create_directories_recursively(configDir));
if (!configDirExists && configDirError)
{
logger::log("Error creating config folder: %s.", fslib::error::get_string());
config::reset_to_default();
return;
}
@ -77,17 +82,17 @@ void config::initialize()
json_object *configValue = json_object_iter_peek_value(&configIterator);
// These are exemptions.
if (std::strcmp(keyName, config::keys::WORKING_DIRECTORY.data()) == 0)
{
s_workingDirectory = json_object_get_string(configValue);
}
else if (std::strcmp(keyName, config::keys::UI_ANIMATION_SCALE.data()) == 0)
{
s_uiAnimationScaling = json_object_get_double(configValue);
}
else if (std::strcmp(keyName, config::keys::FAVORITES.data()) == 0) { read_array_to_vector(s_favorites, configValue); }
else if (std::strcmp(keyName, config::keys::BLACKLIST.data()) == 0) { read_array_to_vector(s_blacklist, configValue); }
const bool workingDirectory = std::strcmp(keyName, config::keys::WORKING_DIRECTORY.data()) == 0;
const bool animationScaling = std::strcmp(keyName, config::keys::UI_ANIMATION_SCALE.data()) == 0;
const bool favorites = std::strcmp(keyName, config::keys::FAVORITES.data()) == 0;
const bool blacklist = std::strcmp(keyName, config::keys::BLACKLIST.data()) == 0;
if (workingDirectory) { s_workingDirectory = json_object_get_string(configValue); }
else if (animationScaling) { s_uiAnimationScaling = json_object_get_double(configValue); }
else if (favorites) { read_array_to_vector(s_favorites, configValue); }
else if (blacklist) { read_array_to_vector(s_blacklist, configValue); }
else { s_configMap[keyName] = json_object_get_uint64(configValue); }
json_object_iter_next(&configIterator);
}
@ -178,32 +183,27 @@ void config::save()
json::add_object(configJSON, config::keys::BLACKLIST.data(), blacklistArray);
// Write config file
fslib::File configFile(PATH_CONFIG_FILE,
fslib::File configFile{PATH_CONFIG_FILE,
FsOpenMode_Create | FsOpenMode_Write,
std::strlen(json_object_get_string(configJSON.get())));
std::strlen(json_object_get_string(configJSON.get()))};
if (configFile) { configFile << json_object_get_string(configJSON.get()); }
}
if (!s_pathMap.empty())
{
// Paths file.
json::Object pathsJSON = json::new_object(json_object_new_object);
// Loop through map and write stuff.
for (auto &[applicationID, path] : s_pathMap)
for (const auto &[applicationID, path] : s_pathMap)
{
// Get ID as hex string.
std::string idHex = stringutil::get_formatted_string("%016llX", applicationID);
// path
json_object *pathObject = json_object_new_string(path.c_str());
const std::string idHex = stringutil::get_formatted_string("%016llX", applicationID);
// Add to pathsJSON object.
json_object *pathObject = json_object_new_string(path.c_str());
json::add_object(pathsJSON, idHex.c_str(), pathObject);
}
// Write it.
fslib::File pathsFile(PATH_PATHS_PATH,
FsOpenMode_Create | FsOpenMode_Write,
std::strlen(json_object_get_string(pathsJSON.get())));
if (pathsFile) { pathsFile << json_object_get_string(pathsJSON.get()); }
if (pathsFile.is_open()) { pathsFile << json_object_get_string(pathsJSON.get()); }
}
}
@ -244,8 +244,8 @@ void config::add_remove_favorite(uint64_t applicationID)
bool config::is_favorite(uint64_t applicationID)
{
if (std::find(s_favorites.begin(), s_favorites.end(), applicationID) == s_favorites.end()) { return false; }
const auto findID = std::find(s_favorites.begin(), s_favorites.end(), applicationID);
if (findID == s_favorites.end()) { return false; }
return true;
}
@ -258,8 +258,8 @@ void config::add_remove_blacklist(uint64_t applicationID)
bool config::is_blacklisted(uint64_t applicationID)
{
if (std::find(s_blacklist.begin(), s_blacklist.end(), applicationID) == s_blacklist.end()) { return false; }
const bool found = std::find(s_blacklist.begin(), s_blacklist.end(), applicationID) == s_blacklist.end();
if (found) { return false; }
return true;
}
@ -271,13 +271,12 @@ void config::add_custom_path(uint64_t applicationID, std::string_view customPath
bool config::has_custom_path(uint64_t applicationID)
{
if (s_pathMap.find(applicationID) == s_pathMap.end()) { return false; }
return true;
}
void config::get_custom_path(uint64_t applicationID, char *pathOut, size_t pathOutSize)
{
const auto findPath = s_pathMap.find(applicationID);
if (s_pathMap.find(applicationID) == s_pathMap.end()) { return; }
std::memcpy(pathOut, s_pathMap[applicationID].c_str(), s_pathMap[applicationID].length());
}

View File

@ -4,10 +4,13 @@
#include "logger.hpp"
#include "stringutil.hpp"
#include <cstring>
namespace
{
/// @brief Size of the buffer used for uploading files.
constexpr size_t SIZE_UPLOAD_BUFFER = 0x10000;
constexpr size_t SIZE_UPLOAD_BUFFER = 0x10000;
constexpr size_t SIZE_DOWNLOAD_THRESHOLD = 0x400000;
} // namespace
bool curl::initialize() { return curl_global_init(CURL_GLOBAL_ALL) == CURLE_OK; }
@ -62,6 +65,68 @@ size_t curl::write_data_to_file(const char *buffer, size_t size, size_t count, f
return target->write(buffer, size * count);
}
size_t curl::download_file_threaded(const char *buffer, size_t size, size_t count, curl::DownloadStruct *download)
{
std::mutex &lock = download->lock;
std::condition_variable &condition = download->condition;
std::vector<byte> &sharedBuffer = download->sharedBuffer;
bool &bufferReady = download->bufferReady;
sys::ProgressTask *task = download->task;
size_t &offset = download->offset;
size_t &fileSize = download->fileSize;
const size_t downloadSize = size * count;
const std::span<const byte> bufferSpan{reinterpret_cast<const byte *>(buffer), downloadSize};
{
std::unique_lock<std::mutex> bufferLock(lock);
condition.wait(bufferLock, [&]() { return bufferReady == false; });
sharedBuffer.append_range(bufferSpan);
const size_t sharedSize = sharedBuffer.size();
if (sharedSize >= SIZE_DOWNLOAD_THRESHOLD || offset + downloadSize >= fileSize)
{
bufferReady = true;
condition.notify_one();
}
offset += downloadSize;
}
if (task) { task->increase_current(static_cast<double>(downloadSize)); }
return downloadSize;
}
void curl::download_write_thread_function(curl::DownloadStruct &download)
{
std::mutex &lock = download.lock;
std::condition_variable &condition = download.condition;
std::vector<byte> &sharedBuffer = download.sharedBuffer;
bool &bufferReady = download.bufferReady;
fslib::File *dest = download.dest;
size_t fileSize = download.fileSize;
auto localBuffer = std::make_unique<byte[]>(SIZE_DOWNLOAD_THRESHOLD + 0x100000); // Gonna give this some room.
for (size_t i = 0; i < fileSize;)
{
size_t bufferSize{};
{
std::unique_lock<std::mutex> bufferLock(lock);
condition.wait(bufferLock, [&]() { return bufferReady == true; });
bufferSize = sharedBuffer.size();
std::memcpy(localBuffer.get(), sharedBuffer.data(), bufferSize);
sharedBuffer.clear();
bufferReady = false;
condition.notify_one();
}
dest->write(localBuffer.get(), bufferSize);
i += bufferSize;
}
}
bool curl::get_header_value(const curl::HeaderArray &array, std::string_view header, std::string &valueOut)
{
for (const std::string &currentHeader : array)
@ -129,7 +194,7 @@ void curl::prepare_get(curl::Handle &curl)
// Setup basic request.
curl::set_option(curl, CURLOPT_HTTPGET, 1L);
curl::set_option(curl, CURLOPT_ACCEPT_ENCODING, ""); // I think this is how you set the defaults for this?
// curl::set_option(curl, CURLOPT_ACCEPT_ENCODING, "");
}
void curl::prepare_post(curl::Handle &curl)
@ -137,7 +202,7 @@ void curl::prepare_post(curl::Handle &curl)
curl::reset_handle(curl);
curl::set_option(curl, CURLOPT_POST, 1L);
curl::set_option(curl, CURLOPT_ACCEPT_ENCODING, "");
// curl::set_option(curl, CURLOPT_ACCEPT_ENCODING, "");
}
void curl::prepare_upload(curl::Handle &curl)
@ -145,5 +210,5 @@ void curl::prepare_upload(curl::Handle &curl)
curl::reset_handle(curl);
curl::set_option(curl, CURLOPT_UPLOAD, 1L);
curl::set_option(curl, CURLOPT_ACCEPT_ENCODING, ""); // Not really sure this will have any affect here...
// curl::set_option(curl, CURLOPT_ACCEPT_ENCODING, "");
}

View File

@ -1,6 +1,7 @@
#include "fs/io.hpp"
#include "error.hpp"
#include "fs/SaveMetaData.hpp"
#include "fslib.hpp"
#include "strings.hpp"
#include "stringutil.hpp"
@ -66,7 +67,7 @@ void fs::copy_file(const fslib::Path &source,
{
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 0);
const char *popErrorCommitting = strings::get_by_name(strings::names::IO_POPS, 0);
const int popticks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popticks = ui::PopMessageManager::DEFAULT_TICKS;
fslib::File sourceFile{source, FsOpenMode_Read};
fslib::File destFile{destination, FsOpenMode_Create | FsOpenMode_Write, sourceFile.get_size()};
@ -152,6 +153,8 @@ void fs::copy_directory(const fslib::Path &source,
const int64_t dirCount = sourceDir.get_count();
for (int64_t i = 0; i < dirCount; i++)
{
if (sourceDir[i] == fs::NAME_SAVE_META) { continue; }
const fslib::Path fullSource{source / sourceDir[i]};
const fslib::Path fullDest{destination / sourceDir[i]};
if (sourceDir.is_directory(i))

View File

@ -166,7 +166,7 @@ void fs::copy_zip_to_directory(fs::MiniUnzip &unzip,
sys::ProgressTask *task)
{
if (!unzip.reset()) { return; }
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popCommitFailed = strings::get_by_name(strings::names::IO_POPS, 0);
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 2);
const bool needCommits = journalSize > 0 && !commitDevice.empty();

View File

@ -18,16 +18,12 @@ sdl::SharedTexture gfxutil::create_generic_icon(std::string_view text,
sdl::SharedTexture icon =
sdl::TextureManager::create_load_texture(text, 256, 256, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET);
// Clear it to background color.
icon->clear(background);
// Get the centered X and Y coordinates.
int textX = (SIZE_ICON_WIDTH / 2) - (sdl::text::get_width(fontSize, text.data()) / 2);
int textY = (SIZE_ICON_HEIGHT / 2) - (fontSize / 2);
const int textX = (SIZE_ICON_WIDTH / 2) - (sdl::text::get_width(fontSize, text.data()) / 2);
const int textY = (SIZE_ICON_HEIGHT / 2) - (fontSize / 2);
// Render the text to the icon.
icon->clear(background);
sdl::text::render(icon->get(), textX, textY, fontSize, sdl::text::NO_TEXT_WRAP, foreground, text.data());
// Return shared_ptr
return icon;
}

View File

@ -1,5 +1,7 @@
#include "keyboard.hpp"
#include "error.hpp"
#include <string>
bool keyboard::get_input(SwkbdType keyboardType,
@ -8,7 +10,6 @@ bool keyboard::get_input(SwkbdType keyboardType,
char *stringOut,
size_t stringLength)
{
// Setup keyboard.
SwkbdConfig keyboard;
swkbdCreate(&keyboard, 0);
swkbdConfigSetBlurBackground(&keyboard, true);
@ -19,12 +20,9 @@ bool keyboard::get_input(SwkbdType keyboardType,
swkbdConfigSetStringLenMax(&keyboard, stringLength);
swkbdConfigSetKeySetDisableBitmask(&keyboard, SwkbdKeyDisableBitmask_ForwardSlash | SwkbdKeyDisableBitmask_Backslash);
// If it fails, just return.
if (R_FAILED(swkbdShow(&keyboard, stringOut, stringLength))) { return false; }
const bool swkbdError = error::libnx(swkbdShow(&keyboard, stringOut, stringLength));
const bool empty = std::char_traits<char>::length(stringOut) == 0;
if (swkbdError || empty) { return false; }
// If the string is empty, assume failure or cancel.
if (std::char_traits<char>::length(stringOut) == 0) { return false; }
// I wish this was more like the 3DS keyboard cause that actually returned what button was pressed...
return true;
}

View File

@ -40,3 +40,11 @@ void logger::log(const char *format, ...)
logFile << vaBuffer << "\n";
logFile.flush();
}
void logger::log_straight(std::string_view string)
{
std::scoped_lock<std::mutex> logLock(s_logLock);
fslib::File logFile{s_logFilePath, FsOpenMode_Append};
logFile << string.data() << "\n";
logFile.flush();
}

View File

@ -2,11 +2,7 @@
remote::Form::Form(const remote::Form &form) { m_form = form.m_form; }
remote::Form::Form(remote::Form &&form)
{
m_form = form.m_form;
form.m_form.clear();
}
remote::Form::Form(remote::Form &&form) { m_form = std::move(form.m_form); }
remote::Form &remote::Form::operator=(const remote::Form &form)
{
@ -16,8 +12,7 @@ remote::Form &remote::Form::operator=(const remote::Form &form)
remote::Form &remote::Form::operator=(remote::Form &&form)
{
m_form = form.m_form;
form.m_form.clear();
m_form = std::move(form.m_form);
return *this;
}

View File

@ -143,10 +143,10 @@ bool remote::GoogleDrive::create_directory(std::string_view name)
return true;
}
bool remote::GoogleDrive::upload_file(const fslib::Path &source, sys::ProgressTask *task)
bool remote::GoogleDrive::upload_file(const fslib::Path &source, std::string_view name, sys::ProgressTask *task)
{
if (!GoogleDrive::token_is_valid() && !GoogleDrive::refresh_token()) { return false; }
const char *statusTemplate = strings::get_by_name(strings::names::BACKUPMENU_STATUS, 1);
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 5);
fslib::File sourceFile(source, FsOpenMode_Read);
if (!sourceFile)
@ -165,7 +165,7 @@ bool remote::GoogleDrive::upload_file(const fslib::Path &source, sys::ProgressTa
// Json to post.
json::Object postJson = json::new_object(json_object_new_object);
json_object *driveName = json_object_new_string(source.get_filename());
json_object *driveName = json_object_new_string(name.data());
json::add_object(postJson, JSON_KEY_NAME, driveName);
if (!m_parent.empty())
{
@ -304,33 +304,45 @@ bool remote::GoogleDrive::patch_file(remote::Item *file, const fslib::Path &sour
return true;
}
bool remote::GoogleDrive::download_file(const remote::Item *file, const fslib::Path &destination)
bool remote::GoogleDrive::download_file(const remote::Item *file, const fslib::Path &destination, sys::ProgressTask *task)
{
if (!GoogleDrive::token_is_valid() && !GoogleDrive::refresh_token()) { return false; }
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 4);
// Try to open the file too before continuing. Using a starting size speeds up write calls later.
fslib::File destinationFile(destination, FsOpenMode_Create | FsOpenMode_Write, file->get_size());
if (!destinationFile)
fslib::File destFile{destination, FsOpenMode_Create | FsOpenMode_Write, file->get_size()};
if (!destFile)
{
logger::log("Error downloading file: local file could not be opened for writing!");
return false;
}
if (task)
{
const std::string status = stringutil::get_formatted_string(statusTemplate, file->get_name().data());
task->set_status(status);
task->reset(static_cast<double>(file->get_size()));
}
curl::HeaderList header = curl::new_header_list();
curl::append_header(header, m_authHeader);
remote::URL url{URL_DRIVE_FILE_API};
url.append_path(file->get_id()).append_parameter("alt", "media");
std::string response;
curl::DownloadStruct download{.dest = &destFile, .task = task, .fileSize = file->get_size()};
curl::prepare_get(m_curl);
curl::set_option(m_curl, CURLOPT_HTTPHEADER, header.get());
curl::set_option(m_curl, CURLOPT_URL, url.get());
// This is temporary until I get threading figured out again.
curl::set_option(m_curl, CURLOPT_WRITEFUNCTION, curl::write_data_to_file);
curl::set_option(m_curl, CURLOPT_WRITEDATA, &destinationFile);
curl::set_option(m_curl, CURLOPT_WRITEFUNCTION, curl::download_file_threaded);
curl::set_option(m_curl, CURLOPT_WRITEDATA, &download);
// curl::set_option(m_curl, CURLOPT_WRITEFUNCTION, curl::download_file_threaded);
// curl::set_option(m_curl, CURLOPT_WRITEDATA, &download);
std::thread writeThread(curl::download_write_thread_function, std::ref(download));
if (!curl::perform(m_curl)) { return false; }
writeThread.join();
return true;
}

View File

@ -5,33 +5,23 @@ remote::URL::URL(std::string_view base)
remote::URL::URL(const URL &url) { m_url = url.m_url; }
remote::URL::URL(URL &&url)
{
m_url = url.m_url;
// This seems odd, but w/e
url.m_url.clear();
}
remote::URL::URL(URL &&url) { m_url = std::move(url.m_url); }
remote::URL &remote::URL::operator=(const remote::URL &url)
{
m_url = url.m_url;
return *this;
}
remote::URL &remote::URL::operator=(remote::URL &&url)
{
m_url = url.m_url;
url.m_url.clear();
m_url = std::move(url.m_url);
return *this;
}
remote::URL &remote::URL::set_base(std::string_view base)
{
// This will just assign and clear out the old one, I hope.
m_url = base;
return *this;
}
@ -39,12 +29,8 @@ remote::URL &remote::URL::append_path(std::string_view path)
{
// Check both just to be sure because this makes WebDav easier to tackle.
if (m_url.back() != '/' && path.front() != '/') { m_url.append("/"); }
// This is here to make WebDav easier to read and deal with in case of blank basepaths.
if (path.empty()) { return *this; }
m_url.append(path);
return *this;
}

View File

@ -4,6 +4,7 @@
#include "curl/curl.hpp"
#include "logger.hpp"
#include "remote/remote.hpp"
#include "strings.hpp"
#include "stringutil.hpp"
#include <tinyxml2.h>
@ -64,7 +65,6 @@ remote::WebDav::WebDav()
}
if (username) { m_username = json_object_get_string(username); }
if (password) { m_password = json_object_get_string(password); }
// This is the starting point. This will read the entire basepath listing in one go.
@ -115,9 +115,10 @@ bool remote::WebDav::create_directory(std::string_view name)
return true;
}
bool remote::WebDav::upload_file(const fslib::Path &source, sys::ProgressTask *task)
bool remote::WebDav::upload_file(const fslib::Path &source, std::string_view remoteName, sys::ProgressTask *task)
{
static const char *STRING_ERROR_UPLOADING = "Error uploading file: %s";
static constexpr const char *STRING_ERROR_UPLOADING = "Error uploading to WebDav: %s";
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 5);
fslib::File sourceFile{source, FsOpenMode_Read};
if (!sourceFile.is_open())
@ -127,12 +128,19 @@ bool remote::WebDav::upload_file(const fslib::Path &source, sys::ProgressTask *t
}
std::string escapedName;
if (!curl::escape_string(m_curl, source.get_filename(), escapedName))
if (!curl::escape_string(m_curl, remoteName, escapedName))
{
logger::log(STRING_ERROR_UPLOADING, "Failed to escape filename!");
return false;
}
if (task)
{
const std::string status = stringutil::get_formatted_string(statusTemplate, remoteName.data());
task->set_status(status);
task->reset(static_cast<double>(sourceFile.get_size()));
}
remote::URL url{m_origin};
url.append_path(m_parent).append_path(escapedName);
@ -148,7 +156,8 @@ bool remote::WebDav::upload_file(const fslib::Path &source, sys::ProgressTask *t
if (!curl::perform(m_curl)) { return false; }
m_list.emplace_back(source.get_filename(), escapedName, m_parent, sourceFile.get_size(), false);
const std::string id = m_parent + "/" + escapedName;
m_list.emplace_back(remoteName, id, m_parent, sourceFile.get_size(), false);
return true;
}
@ -157,7 +166,7 @@ bool remote::WebDav::patch_file(remote::Item *item, const fslib::Path &source, s
{
static const char *STRING_ERROR_PATCHING = "Error patching file: %s";
fslib::File file(source, FsOpenMode_Read);
fslib::File file{source, FsOpenMode_Read};
if (!file)
{
logger::log(STRING_ERROR_PATCHING, fslib::error::get_string());
@ -165,7 +174,7 @@ bool remote::WebDav::patch_file(remote::Item *item, const fslib::Path &source, s
}
remote::URL url{m_origin};
url.append_path(m_parent).append_path(item->get_id());
url.append_path(item->get_id());
curl::reset_handle(m_curl);
WebDav::append_credentials();
@ -183,28 +192,39 @@ bool remote::WebDav::patch_file(remote::Item *item, const fslib::Path &source, s
return true;
}
bool remote::WebDav::download_file(const remote::Item *item, const fslib::Path &destination)
bool remote::WebDav::download_file(const remote::Item *item, const fslib::Path &destination, sys::ProgressTask *task)
{
static const char *STRING_ERROR_DOWNLOADING = "Error downloading file: %s";
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 4);
fslib::File file(destination, FsOpenMode_Create | FsOpenMode_Write);
if (!file)
fslib::File destFile{destination, FsOpenMode_Create | FsOpenMode_Write, item->get_size()};
if (!destFile)
{
logger::log(STRING_ERROR_DOWNLOADING, fslib::error::get_string());
return false;
}
remote::URL url{m_origin};
url.append_path(m_parent).append_path(item->get_id());
if (task)
{
const std::string status = stringutil::get_formatted_string(statusTemplate, item->get_name().data());
task->set_status(status);
task->reset(static_cast<double>(item->get_size()));
}
remote::URL url{m_origin};
url.append_path(item->get_id());
curl::DownloadStruct download{.dest = &destFile, .task = task, .fileSize = item->get_size()};
curl::reset_handle(m_curl);
WebDav::append_credentials();
curl::set_option(m_curl, CURLOPT_HTTPGET, 1L);
curl::set_option(m_curl, CURLOPT_URL, url.get());
curl::set_option(m_curl, CURLOPT_WRITEFUNCTION, curl::write_data_to_file);
curl::set_option(m_curl, CURLOPT_WRITEDATA, &file);
curl::set_option(m_curl, CURLOPT_WRITEFUNCTION, curl::download_file_threaded);
curl::set_option(m_curl, CURLOPT_WRITEDATA, &download);
std::thread writeThread{curl::download_write_thread_function, std::ref(download)};
if (!curl::perform(m_curl)) { return false; }
writeThread.join();
return true;
}
@ -214,8 +234,9 @@ bool remote::WebDav::delete_item(const remote::Item *item)
static const char *STRING_ERROR_DELETING = "Error deleting item: %s";
remote::URL url{m_origin};
url.append_path(m_parent).append_path(item->get_id());
url.append_path(item->get_id());
if (item->is_directory()) { url.append_slash(); }
logger::log(url.get());
curl::reset_handle(m_curl);
WebDav::append_credentials();
@ -224,19 +245,23 @@ bool remote::WebDav::delete_item(const remote::Item *item)
if (!curl::perform(m_curl)) { return false; }
if (curl::get_response_code(m_curl) != 204)
const long code = curl::get_response_code(m_curl);
if (code != 204) // This can be any of these, I think?
{
logger::log(STRING_ERROR_DELETING, "Deletion failed!");
return false;
}
auto findFile = Storage::find_file_by_name(item->get_name());
if (findFile == m_list.end()) { return false; }
m_list.erase(findFile);
return true;
}
void remote::WebDav::append_credentials()
{
if (!m_username.empty()) { curl::set_option(m_curl, CURLOPT_USERNAME, m_username.c_str()); }
if (!m_password.empty()) { curl::set_option(m_curl, CURLOPT_PASSWORD, m_password.c_str()); }
}

View File

@ -50,7 +50,7 @@ void remote::initialize_google_drive()
if (!drive->is_initialized()) { return; }
// Can't forget this.
drive_set_jksv_root(drive);
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::GOOGLE_DRIVE, 1));
}
@ -60,12 +60,12 @@ void remote::initialize_webdav()
if (s_storage->is_initialized())
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::WEBDAV, 0));
}
else
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::WEBDAV, 1));
}
}
@ -103,12 +103,12 @@ static void drive_sign_in(sys::Task *task, remote::GoogleDrive *drive)
// Run this quick so the root is set correctly.
drive_set_jksv_root(drive);
// Show everyone I did it!
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::GOOGLE_DRIVE, 1));
}
else
{
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_MESSAGE_TICKS,
ui::PopMessageManager::push_message(ui::PopMessageManager::DEFAULT_TICKS,
strings::get_by_name(strings::names::GOOGLE_DRIVE, 2));
}

View File

@ -8,9 +8,11 @@ void sys::ProgressTask::reset(double goal)
void sys::ProgressTask::update_current(double current) { m_current = current; }
void sys::ProgressTask::increase_current(double amount) { m_current += amount; }
double sys::ProgressTask::get_goal() const { return m_goal; }
double sys::ProgressTask::get_current() const
double sys::ProgressTask::get_progress() const
{
// Reminder: Never divide by zero. It ends badly every time!
return m_goal > 0 ? m_current / m_goal : 0;

View File

@ -17,14 +17,10 @@ void sys::Timer::start(uint64_t triggerTicks)
bool sys::Timer::is_triggered()
{
uint64_t currentTicks = SDL_GetTicks64();
// Nope
const uint64_t currentTicks = SDL_GetTicks64();
if (currentTicks - m_startingTicks < m_triggerTicks) { return false; }
// Reset starting ticks.
m_startingTicks = currentTicks;
// Trigger me timbers~
return true;
}

View File

@ -14,17 +14,17 @@
namespace
{
constexpr const char *STRING_ZIP_EXT = ".zip";
constexpr size_t SIZE_SAVE_META = sizeof(fs::SaveMetaData);
}
void tasks::backup::create_new_backup(sys::ProgressTask *task,
data::User *user,
data::TitleInfo *titleInfo,
fslib::Path target,
BackupMenuState *spawningState,
bool killTask)
void tasks::backup::create_new_backup_local(sys::ProgressTask *task,
data::User *user,
data::TitleInfo *titleInfo,
fslib::Path target,
BackupMenuState *spawningState,
bool killTask)
{
if (error::is_null(task)) { return; }
static constexpr size_t SIZE_SAVE_META = sizeof(fs::SaveMetaData);
const bool autoUpload = config::get_by_key(config::keys::AUTO_UPLOAD);
const bool hasZipExt = std::strstr(target.full_path(), STRING_ZIP_EXT);
@ -69,7 +69,73 @@ void tasks::backup::create_new_backup(sys::ProgressTask *task,
if (killTask) { task->finished(); }
}
void tasks::backup::overwrite_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
void tasks::backup::create_new_backup_remote(sys::ProgressTask *task,
data::User *user,
data::TitleInfo *titleInfo,
std::string remoteName,
BackupMenuState *spawningState,
bool killTask)
{
remote::Storage *remote = remote::get_remote_storage();
if (error::is_null(task) || error::is_null(user) || error::is_null(titleInfo) || error::is_null(spawningState) ||
error::is_null(remote))
{
return;
}
const uint64_t applicationID = titleInfo->get_application_id();
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *uploadTemplate = strings::get_by_name(strings::names::BACKUPMENU_STATUS, 1);
const char *popErrorCreating = strings::get_by_name(strings::names::BACKUPMENU_POPS, 5);
const char *popErrorDeleting = strings::get_by_name(strings::names::BACKUPMENU_POPS, 4);
const char *popMetaFailed = strings::get_by_name(strings::names::BACKUPMENU_POPS, 8);
if (error::is_null(saveInfo))
{
task->finished();
return;
}
// Since we're uploading this right away, no point in it being in the "right" place.
const fslib::Path tempPath{"sdmc:/temp.zip"};
fs::MiniZip zip{tempPath};
if (!zip.is_open())
{
ui::PopMessageManager::push_message(popTicks, popErrorCreating);
task->finished();
return;
}
fs::SaveMetaData saveMeta{};
const bool hasMeta = fs::fill_save_meta_data(saveInfo, saveMeta);
const bool metaOpened = hasMeta && zip.open_new_file(fs::NAME_SAVE_META);
const bool metaWritten = metaOpened && zip.write(&saveMeta, SIZE_SAVE_META);
const bool metaClosed = metaWritten && zip.close_current_file();
if (hasMeta && (!metaOpened || !metaWritten || !metaClosed)) // This isn't fatal.
{
ui::PopMessageManager::push_message(popTicks, popMetaFailed);
}
fs::copy_directory_to_zip(fs::DEFAULT_SAVE_ROOT, zip, task);
zip.close();
{
const std::string status = stringutil::get_formatted_string(uploadTemplate, remoteName.data());
task->set_status(status);
}
remote->upload_file(tempPath, remoteName, task);
// Finally nuke the local one.
const bool deleteError = error::fslib(fslib::delete_file(tempPath));
if (deleteError) { ui::PopMessageManager::push_message(popTicks, popErrorDeleting); }
spawningState->refresh();
if (killTask) { task->finished(); }
}
void tasks::backup::overwrite_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
{
if (error::is_null(task)) { return; }
@ -77,19 +143,71 @@ void tasks::backup::overwrite_backup(sys::ProgressTask *task, BackupMenuState::T
data::TitleInfo *titleInfo = taskData->titleInfo;
const fslib::Path &target = taskData->path;
BackupMenuState *spawningState = taskData->spawningState;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popErrorDeleting = strings::get_by_name(strings::names::BACKUPMENU_POPS, 4);
const bool isDirectory = fslib::directory_exists(target);
const bool dirFailed = isDirectory && error::fslib(fslib::delete_directory_recursively(target));
const bool fileFailed = !isDirectory && error::fslib(fslib::delete_file(target));
if (dirFailed && fileFailed)
{
ui::PopMessageManager::push_message(popTicks, popErrorDeleting);
task->finished();
return;
}
create_new_backup(task, user, titleInfo, target, spawningState);
tasks::backup::create_new_backup_local(task, user, titleInfo, target, spawningState);
}
void tasks::backup::restore_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
void tasks::backup::overwrite_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
{
if (error::is_null(task)) { return; }
remote::Storage *remote = remote::get_remote_storage();
data::User *user = taskData->user;
data::TitleInfo *titleInfo = taskData->titleInfo;
const uint64_t applicationID = titleInfo->get_application_id();
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
remote::Item *target = taskData->remoteItem;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popErrorDeleting = strings::get_by_name(strings::names::BACKUPMENU_POPS, 4);
const char *popErrorMeta = strings::get_by_name(strings::names::BACKUPMENU_POPS, 8);
if (error::is_null(remote) || error::is_null(saveInfo) || error::is_null(target) || !remote->is_initialized())
{
task->finished();
return;
}
const fslib::Path tempPath{"sdmc:/temp.zip"};
fs::MiniZip zip{tempPath};
if (!zip.is_open())
{
task->finished();
return;
}
// This is repetitive but there's no other way to really accomplish this.
fs::SaveMetaData saveMeta{};
const bool hasMeta = fs::fill_save_meta_data(saveInfo, saveMeta);
const bool metaOpened = hasMeta && zip.open_new_file(fs::NAME_SAVE_META);
const bool metaWritten = metaOpened && zip.write(&saveMeta, SIZE_SAVE_META);
const bool metaClosed = metaWritten && zip.close_current_file();
if (hasMeta && (!metaOpened || !metaWritten || !metaClosed))
{
ui::PopMessageManager::push_message(popTicks, popErrorMeta);
}
fs::copy_directory_to_zip(fs::DEFAULT_SAVE_ROOT, zip, task);
zip.close();
remote->patch_file(target, tempPath, task);
const bool deleteError = error::fslib(fslib::delete_file(tempPath));
if (deleteError) { ui::PopMessageManager::push_message(popTicks, popErrorDeleting); };
task->finished();
}
void tasks::backup::restore_backup_local(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
{
static constexpr size_t SIZE_META = sizeof(fs::SaveMetaData);
@ -110,7 +228,7 @@ void tasks::backup::restore_backup(sys::ProgressTask *task, BackupMenuState::Tas
const bool isDir = fslib::directory_exists(target);
const bool hasZipExt = std::strstr(target.full_path(), STRING_ZIP_EXT);
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popErrorResetting = strings::get_by_name(strings::names::BACKUPMENU_POPS, 2);
const char *popErrorCreating = strings::get_by_name(strings::names::BACKUPMENU_POPS, 5);
const char *popErrorOpenZip = strings::get_by_name(strings::names::EXTRASMENU_POPS, 7);
@ -130,7 +248,7 @@ void tasks::backup::restore_backup(sys::ProgressTask *task, BackupMenuState::Tas
autoTarget = target.sub_path(lastSlash) / "AUTO - " + safeNickname + " - " + stringutil::get_date_string();
if (exportZip) { autoTarget += ".zip"; };
tasks::backup::create_new_backup(task, user, titleInfo, autoTarget, spawningState, false);
tasks::backup::create_new_backup_local(task, user, titleInfo, autoTarget, spawningState, false);
}
const bool resetError = error::fslib(fslib::delete_directory_recursively(fs::DEFAULT_SAVE_ROOT));
@ -178,12 +296,67 @@ void tasks::backup::restore_backup(sys::ProgressTask *task, BackupMenuState::Tas
task->finished();
}
void tasks::backup::delete_backup(sys::Task *task, BackupMenuState::TaskData taskData)
void tasks::backup::restore_backup_remote(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
{
if (error::is_null(task)) { return; }
data::User *user = taskData->user;
data::TitleInfo *titleInfo = taskData->titleInfo;
const uint64_t applicationID = titleInfo->get_application_id();
const FsSaveDataInfo *saveInfo = user->get_save_info_by_id(applicationID);
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *popErrorOpeningZip = strings::get_by_name(strings::names::BACKUPMENU_POPS, 3);
const char *popErrorDeleting = strings::get_by_name(strings::names::BACKUPMENU_POPS, 4);
const char *popErrorDownloading = strings::get_by_name(strings::names::BACKUPMENU_POPS, 9);
const char *popErrorProcessingMeta = strings::get_by_name(strings::names::BACKUPMENU_POPS, 11);
remote::Storage *remote = remote::get_remote_storage();
if (!remote || !remote->is_initialized())
{
task->finished();
return;
}
remote::Item *target = taskData->remoteItem;
const char *statusDownloading = strings::get_by_name(strings::names::IO_STATUSES, 4);
const fslib::Path tempPath{"sdmc:/temp.zip"};
const bool downloaded = remote->download_file(target, tempPath, task);
if (!downloaded)
{
ui::PopMessageManager::push_message(popTicks, popErrorDownloading);
task->finished();
return;
}
fs::MiniUnzip backup{tempPath};
if (!backup.is_open())
{
ui::PopMessageManager::push_message(popTicks, popErrorOpeningZip);
task->finished();
return;
}
{
fs::SaveMetaData saveMeta{};
const bool hasMeta = backup.locate_file(fs::NAME_SAVE_META);
const bool loadMeta = hasMeta && backup.read(&saveMeta, SIZE_SAVE_META) == SIZE_SAVE_META;
const bool processMeta = loadMeta && fs::process_save_meta_data(saveInfo, saveMeta);
if (hasMeta && (!loadMeta || !processMeta)) { ui::PopMessageManager::push_message(popTicks, popErrorProcessingMeta); }
}
const bool deleteError = error::fslib(fslib::delete_file(tempPath));
if (deleteError) { ui::PopMessageManager::push_message(popTicks, popErrorDeleting); }
task->finished();
}
void tasks::backup::delete_backup_local(sys::Task *task, BackupMenuState::TaskData taskData)
{
if (error::is_null(task)) { return; }
const fslib::Path &path = taskData->path;
BackupMenuState *spawningState = taskData->spawningState;
const int popTicks = ui::PopMessageManager::DEFAULT_MESSAGE_TICKS;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 3);
const char *popFailed = strings::get_by_name(strings::names::BACKUPMENU_POPS, 4);
@ -200,15 +373,40 @@ void tasks::backup::delete_backup(sys::Task *task, BackupMenuState::TaskData tas
task->finished();
}
void tasks::backup::delete_backup_remote(sys::Task *task, BackupMenuState::TaskData taskData)
{
remote::Storage *remote = remote::get_remote_storage();
if (error::is_null(task) || error::is_null(remote) || !remote->is_initialized()) { return; }
remote::Item *target = taskData->remoteItem;
BackupMenuState *spawningState = taskData->spawningState;
const int popTicks = ui::PopMessageManager::DEFAULT_TICKS;
const char *statusTemplate = strings::get_by_name(strings::names::IO_STATUSES, 3);
const char *popFailed = strings::get_by_name(strings::names::BACKUPMENU_POPS, 4);
{
const std::string status = stringutil::get_formatted_string(statusTemplate, target->get_name().data());
task->set_status(status);
}
const bool deleted = remote->delete_item(target);
if (!deleted) { ui::PopMessageManager::push_message(popTicks, popFailed); }
spawningState->refresh();
task->finished();
}
void tasks::backup::upload_backup(sys::ProgressTask *task, BackupMenuState::TaskData taskData)
{
remote::Storage *remote = remote::get_remote_storage();
if (error::is_null(task) || error::is_null(remote)) { return; }
BackupMenuState *spawningState = taskData->spawningState;
// The backup menu should've made sure the remote is pointing to the correct location.
const fslib::Path &path = taskData->path;
remote->upload_file(path, task);
remote->upload_file(path, path.get_filename(), task);
spawningState->refresh();
task->finished();
}

View File

@ -2,11 +2,17 @@
void ui::ColorMod::update()
{
if (m_direction && (m_colorMod += 6) >= 0x72) { m_direction = false; }
else if (!m_direction && (m_colorMod -= 3) <= 0x00) { m_direction = true; }
const bool changeDown = m_direction && ((m_colorMod += 6) >= 0x72);
const bool changeUp = !m_direction && ((m_colorMod -= 3) <= 0x00);
if (changeDown) { m_direction = false; }
else if (changeUp) { m_direction = true; }
}
ui::ColorMod::operator sdl::Color() const
{
return {static_cast<uint32_t>((0x88 + m_colorMod) << 16 | (0xC5 + (m_colorMod / 2)) << 8 | 0xFF)};
uint32_t color{};
color |= static_cast<uint32_t>((0x88 + m_colorMod) << 16);
color |= static_cast<uint64_t>((0xC5 + (m_colorMod / 2)) << 8);
color |= 0xFF;
return sdl::Color{color};
}

View File

@ -12,7 +12,8 @@ void ui::IconMenu::render(SDL_Texture *target, bool hasFocus)
{
if (hasFocus) { m_colorMod.update(); }
for (int i = 0, tempY = m_y; i < static_cast<int>(m_options.size()); i++, tempY += m_optionHeight)
const int optionCount = m_options.size();
for (int i = 0, tempY = m_y; i < optionCount; i++, tempY += m_optionHeight)
{
// Clear target.
m_optionTarget->clear(colors::TRANSPARENT);
@ -28,7 +29,6 @@ void ui::IconMenu::render(SDL_Texture *target, bool hasFocus)
void ui::IconMenu::add_option(sdl::SharedTexture newOption)
{
// Parent needs a text option to work correctly.
Menu::add_option("ICON");
Menu::add_option("ICON"); // Parent class needs text for this to work correctly.
m_options.push_back(newOption);
}

View File

@ -32,25 +32,28 @@ ui::Menu::Menu(int x, int y, int width, int fontSize, int renderTargetHeight)
void ui::Menu::update(bool hasFocus)
{
// Bail if there's nothing to update.
if (m_options.empty()) { return; }
int optionsSize = m_options.size();
if (input::button_pressed(HidNpadButton_AnyUp) && --m_selected < 0) { m_selected = optionsSize - 1; }
else if (input::button_pressed(HidNpadButton_AnyDown) && ++m_selected >= optionsSize) { m_selected = 0; }
else if (input::button_pressed(HidNpadButton_AnyLeft) && (m_selected -= m_scrollLength) < 0) { m_selected = 0; }
else if (input::button_pressed(HidNpadButton_AnyRight) && (m_selected += m_scrollLength) >= optionsSize)
{
m_selected = optionsSize - 1;
}
else if (input::button_pressed(HidNpadButton_L) && (m_selected -= m_scrollLength * 3) < 0) { m_selected = 0; }
else if (input::button_pressed(HidNpadButton_R) && (m_selected += m_scrollLength * 3) >= optionsSize)
{
m_selected = optionsSize - 1;
}
const bool upPressed = input::button_pressed(HidNpadButton_AnyUp);
const bool downPressed = input::button_pressed(HidNpadButton_AnyDown);
const bool leftPressed = input::button_pressed(HidNpadButton_AnyLeft);
const bool rightPressed = input::button_pressed(HidNpadButton_AnyRight);
const bool lShoulderPressed = input::button_pressed(HidNpadButton_L);
const bool rShoulderPressed = input::button_pressed(HidNpadButton_R);
const int optionsSize = m_options.size();
const bool wrapSelectedUp = upPressed && --m_selected < 0;
const bool wrapSelectedDown = downPressed && ++m_selected >= optionsSize;
const bool stopSelectedLeft = leftPressed && (m_selected -= m_scrollLength) < 0;
const bool stopSelectedRight = rightPressed && (m_selected += m_scrollLength) >= optionsSize;
const bool stopShoulderLeft = lShoulderPressed && (m_selected -= m_scrollLength * 3) < 0;
const bool stopShoulderRight = rShoulderPressed && (m_selected += m_scrollLength * 3) >= optionsSize;
if (wrapSelectedUp || stopSelectedRight || stopShoulderRight) { m_selected = optionsSize - 1; }
else if (wrapSelectedDown || stopSelectedLeft || stopShoulderLeft) { m_selected = 0; }
// Don't bother continuing further if there's no reason to scroll.
if (static_cast<int>(m_options.size()) <= m_maxDisplayOptions) { return; }
if (optionsSize <= m_maxDisplayOptions) { return; }
if (m_selected < m_scrollLength) { m_targetY = m_originalY; }
else if (m_selected >= static_cast<int>(m_options.size()) - (m_maxDisplayOptions - m_scrollLength))

View File

@ -20,85 +20,71 @@ void ui::PopMessageManager::update()
// Grab instance.
PopMessageManager &manager = PopMessageManager::get_instance();
auto &messageQueue = manager.m_messageQueue;
auto &messages = manager.m_messages;
// Bail if the queue is empty.
if (!manager.m_messageQueue.empty())
if (!messageQueue.empty())
{
// Loop through the queue and process it so we don't wind up with black characters.
for (auto &[displayTicks, currentMessage] : manager.m_messageQueue)
for (auto &[displayTicks, currentMessage] : messageQueue)
{
// New message.
manager.m_messages.push_back({.m_y = 720,
.m_targetY = 720,
.m_width = sdl::text::get_width(32, currentMessage.c_str()) + 32,
.m_message = currentMessage,
.m_timer = sys::Timer(displayTicks)});
const size_t messageWidth = sdl::text::get_width(32, currentMessage.c_str()) + 32;
const ui::PopMessage newMessage = {.y = 720,
.targetY = 720,
.width = messageWidth,
.message = std::move(currentMessage),
.timer = sys::Timer{displayTicks}};
messages.push_back(std::move(newMessage));
}
// Clear the queue.
manager.m_messageQueue.clear();
messageQueue.clear();
}
// Update all the messages.
// This is the first Y position a message should be displayed at.;
double currentY = 594.0f;
double animationScaling = config::get_animation_scaling();
for (size_t i = 0; i < manager.m_messages.size(); i++)
double currentY = 594.0f;
const double animationScaling = config::get_animation_scaling();
const int messageCount = messages.size();
for (int i = 0; i < messageCount; i++)
{
// Save myself a shit load of typing.
ui::PopMessage &currentMessage = manager.m_messages.at(i);
// Purge it and continue if needed.
if (currentMessage.m_timer.is_triggered())
ui::PopMessage &message = messages.at(i);
if (message.timer.is_triggered())
{
manager.m_messages.erase(manager.m_messages.begin() + i);
messages.erase(messages.begin() + i);
continue;
}
// Make sure Y coordinate is correct.
if (currentMessage.m_targetY != currentY) { currentMessage.m_targetY = currentY; }
if (currentMessage.m_y != currentMessage.m_targetY)
{
currentMessage.m_y += (currentMessage.m_targetY - currentMessage.m_y) / animationScaling;
}
if (message.targetY != currentY) { message.targetY = currentY; }
if (message.y != message.targetY) { message.y += (message.targetY - message.y) / animationScaling; }
currentY -= 56;
}
}
void ui::PopMessageManager::render()
{
// Get instance.
PopMessageManager &manager = PopMessageManager::get_instance();
auto &messages = manager.m_messages;
// Loop and render.
for (auto &popMessage : manager.m_messages)
for (const auto &message : messages)
{
// Render a dialog box around it.
ui::render_dialog_box(NULL, 20, popMessage.m_y - 6, popMessage.m_width, 52);
// Render the actual text.
sdl::text::render(NULL, 36, popMessage.m_y, 32, sdl::text::NO_TEXT_WRAP, colors::WHITE, popMessage.m_message.c_str());
ui::render_dialog_box(nullptr, 20, message.y - 6, message.width, 52);
sdl::text::render(nullptr, 36, message.y, 32, sdl::text::NO_TEXT_WRAP, colors::WHITE, message.message.c_str());
}
}
void ui::PopMessageManager::push_message(int displayTicks, const char *format, ...)
void ui::PopMessageManager::push_message(int displayTicks, std::string_view message)
{
// VA args.
char vaBuffer[VA_BUFFER_SIZE] = {0};
std::va_list vaList;
va_start(vaList, format);
vsnprintf(vaBuffer, VA_BUFFER_SIZE, format, vaList);
va_end(vaList);
// Get instance.
PopMessageManager &manager = PopMessageManager::get_instance();
std::mutex &messageMutex = manager.m_messageMutex;
auto &messageQueue = manager.m_messageQueue;
auto &messages = manager.m_messages;
// Make sure we're not pushing two of the same message.
if (!manager.m_messages.empty() && manager.m_messages.back().m_message.compare(vaBuffer) == 0)
{
// Bail and don't push it to the queue because it matches.
return;
}
// Push it to the queue.
std::scoped_lock<std::mutex> messageLock(manager.m_messageMutex);
manager.m_messageQueue.push_back(std::make_pair(displayTicks, vaBuffer));
const bool empty = messages.empty();
const bool backMatches = !empty && messages.back().message == message;
if (backMatches) { return; }
auto queuePair = std::make_pair(displayTicks, std::string{message});
std::scoped_lock<std::mutex> messageLock(messageMutex);
messageQueue.push_back(std::move(queuePair));
}