5 Commits

Author SHA1 Message Date
ITotalJustice
d50bcb650f fix crash if nro has corrupted asset entry, bump version for new release 0.10.2 -> 0.10.3
the nro that caused this was ClkrstQuery.nro

fixes #141
2025-05-21 17:29:18 +01:00
⭐️NINIKA⭐️
4244be9592 Fix handling of unicode filenames in usb_install_pc.py (#143) 2025-05-20 12:45:59 +01:00
Ny'hrarr
a7fc19e28a Pt patches (#140)
* Update pt.json

* Translate new keys

* Translate FTP, USB and GameCard menus

* Update pt.json

* Update pt.json

* Add missing comma and translate more entries

* Fix case

* Update pt.json

* Update pt.json
2025-05-20 09:00:39 +01:00
ITotalJustice
cf192fca85 fix hbmenu not being updated due to faulty string compare, bump version 0.10.1 -> 0.10.2 2025-05-19 20:34:22 +01:00
xHR
041bb2bbe5 Added Ukranian language (#139) 2025-05-19 19:57:15 +01:00
9 changed files with 409 additions and 36 deletions

View File

@@ -1,6 +1,6 @@
{ {
"[Applet Mode]": "[Modo Applet]", "[Applet Mode]": "[Modo applet]",
"No Internet": "Sem Internet", "No Internet": "Sem internet",
"Files": "Arquivos", "Files": "Arquivos",
"Apps": "Aplicativos", "Apps": "Aplicativos",
"Store": "Loja", "Store": "Loja",
@@ -48,6 +48,7 @@
"Filter": "Filtro", "Filter": "Filtro",
"Sort": "Organizar por", "Sort": "Organizar por",
"Order": "Ordem", "Order": "Ordem",
"Layout": "Exibição",
"Search": "Buscar", "Search": "Buscar",
"Updated": "Atualizado", "Updated": "Atualizado",
"Updated (Star)": "Atualizado (favoritos)", "Updated (Star)": "Atualizado (favoritos)",
@@ -64,6 +65,9 @@
"Ascending": "Ascendente", "Ascending": "Ascendente",
"Ascending (Up)": "Ascendente (cima)", "Ascending (Up)": "Ascendente (cima)",
"Asc": "Asc.", "Asc": "Asc.",
"List": "Lista",
"Icon": "Ícones",
"Grid": "Grade",
"Menu Options": "Opções do menu", "Menu Options": "Opções do menu",
"Theme": "Tema", "Theme": "Tema",
@@ -107,7 +111,7 @@
"Install location": "Local de instalação", "Install location": "Local de instalação",
"Show install warning": "Mostrar aviso de instalação", "Show install warning": "Mostrar aviso de instalação",
"Text scroll speed": "Rolagem do texto", "Text scroll speed": "Rolagem do texto",
"Set right-side menu": "Menu direito (R)", "Set right-side menu": "Menu do botão R",
"FileBrowser": "Arquivos", "FileBrowser": "Arquivos",
"%zd files": "%zd arquivo(s)", "%zd files": "%zd arquivo(s)",
@@ -133,7 +137,7 @@
"View as text (unfinished)": "Ver como texto (inacabado)", "View as text (unfinished)": "Ver como texto (inacabado)",
"Ignore read only": "Ignorar somente leitura", "Ignore read only": "Ignorar somente leitura",
"Mount": "Montar", "Mount": "Montar",
"Empty...": "Vazio...", "Empty...": "Vazio",
"Open with DayBreak?": "Abrir com DayBreak?", "Open with DayBreak?": "Abrir com DayBreak?",
"Launch ": "Iniciar ", "Launch ": "Iniciar ",
"Launch option for: ": "Opções de inicialização para: ", "Launch option for: ": "Opções de inicialização para: ",
@@ -143,8 +147,8 @@
"Homebrew Options": "Opções de aplicativo", "Homebrew Options": "Opções de aplicativo",
"Hide Sphaira": "Esconder sphaira", "Hide Sphaira": "Esconder sphaira",
"Install Forwarder": "Instalar atalho (forwarder)", "Install Forwarder": "Instalar atalho (forwarder)",
"WARNING: Installing forwarders will lead to a ban!": "AVISO: Instalar atalhos pode\nresultar em um banimento!", "WARNING: Installing forwarders will lead to a ban!": "AVISO: Instalar atalhos pode resultar em um banimento!",
"Installing Forwarder": "Instalando forwarder", "Installing Forwarder": "Instalando forwarder...",
"Creating Program": "Criando Program", "Creating Program": "Criando Program",
"Creating Control": "Criando Control", "Creating Control": "Criando Control",
"Creating Meta": "Criando Meta", "Creating Meta": "Criando Meta",
@@ -157,10 +161,11 @@
"Starred ": "Favoritado ", "Starred ": "Favoritado ",
"AppStore": "Loja", "AppStore": "Loja",
"Appstore": "Loja",
"Filter: %s | Sort: %s | Order: %s": "Filtro: %s | Por: %s | Ordem: %s", "Filter: %s | Sort: %s | Order: %s": "Filtro: %s | Por: %s | Ordem: %s",
"AppStore Options": "Opções da loja", "AppStore Options": "Opções da loja",
"All": "Todos", "All": "Todos",
"Games": "Jogos", "Games": "Softwares",
"Emulators": "Emuladores", "Emulators": "Emuladores",
"Tools": "Ferramentas", "Tools": "Ferramentas",
"Themes": "Temas", "Themes": "Temas",
@@ -173,14 +178,29 @@
"More by Author": "Mais deste autor", "More by Author": "Mais deste autor",
"Leave Feedback": "Deixar um feedback", "Leave Feedback": "Deixar um feedback",
"Game Options": "Opções de jogo", "Game Options": "Opções de software",
"Launch random game": "Iniciar jogo aleatório", "Launch random game": "Iniciar um software aleatório",
"List meta records": "Listar registro de metadados", "List meta records": "Registro de conteúdos",
"Entries": "Entradas", "Entries": "Entradas",
"Delete entity": "Excluir entidade",
"Hide forwarders": "Ocultar atalhos (forwarders)", "Hide forwarders": "Ocultar atalhos (forwarders)",
"Dump": "Exportar",
"Select content to dump": "Exportação de conteúdo",
"Dump All": "Exportar tudo",
"Dump Application": "Exportar software base",
"Dump Patch": "Exportar atualização",
"Dump AddOnContent": "Exportar DLCs",
"Dump DataPatch": "Exportar patch de dados",
"Select dump location": "Selecione o local de exportação",
"microSD card (/dumps/NSP/)": "Cartão microSD (/dump/NSP/)",
"USB transfer (Switch 2 Switch)": "Transferência via USB (Switch 2 Switch)",
"/dev/null (Speed Test)": "Teste de velocidade (/dev/null)",
"Dumping": "Extraindo...",
"Dump successfull!": "Extração foi concluída com sucesso.",
"Dump failed!": "Extração falhou.",
"Irs": "Câmera de movimento IR", "Irs": "Câmera de movimento IR",
"IRS": "Câmera de movimento IR",
"IRS (Infrared Joycon Camera)": "Câmera de movimento IR", "IRS (Infrared Joycon Camera)": "Câmera de movimento IR",
"Ambient Noise Level: ": "Nível de ruído ambiente: ", "Ambient Noise Level: ": "Nível de ruído ambiente: ",
"Controller": "Controle", "Controller": "Controle",
@@ -234,19 +254,21 @@
"Install Options": "Opções de instalação", "Install Options": "Opções de instalação",
"Install options": "Opções de instalação", "Install options": "Opções de instalação",
"Enable sysmmc": "Habilitar sysMMC",
"Enable emummc": "Habilitar emuMMC",
"Boost CPU clock": "Aumentar clock da CPU", "Boost CPU clock": "Aumentar clock da CPU",
"Allow downgrade": "Permitir downgrade", "Allow downgrade": "Permitir downgrade",
"Skip if already installed": "Pular se já instalado", "Skip if already installed": "Pular se já instalado",
"Ticket only": "Instalar apenas ticket", "Ticket only": "Instalar apenas ticket",
"Patch ticket": "Fazer patch de ticket", "Patch ticket": "Fazer patch de ticket",
"Skip base": "Pular base", "Skip base": "Pular software base",
"Skip patch": "Pular patch", "Skip patch": "Pular atualizações",
"Skip dlc": "Pular DLC", "Skip dlc": "Pular DLCs",
"Skip data patch": "Pular patch de dados", "Skip data patch": "Pular patch de dados",
"Skip ticket": "Pular ticket", "Skip ticket": "Pular ticket",
"skip NCA hash verify": "Pular verificação de hash NCA", "skip NCA hash verify": "Pular checagem de hash NCA",
"Skip RSA header verify": "Pular verificação de header RSA", "Skip RSA header verify": "Pular checagem de header RSA",
"Skip RSA NPDM verify": "Pular verificação de NPDM RSA", "Skip RSA NPDM verify": "Pular checagem de NPDM RSA",
"Ignore distribution bit": "Ignorar bit de distribuição", "Ignore distribution bit": "Ignorar bit de distribuição",
"Convert to standard crypto": "Convertr para crypto padrão", "Convert to standard crypto": "Convertr para crypto padrão",
"Lower master key": "Reduzir a master key", "Lower master key": "Reduzir a master key",
@@ -260,8 +282,8 @@
"FTP Install (EXPERIMENTAL)": "Instalação via FTP (EXPERIMENTAL)", "FTP Install (EXPERIMENTAL)": "Instalação via FTP (EXPERIMENTAL)",
"USB": "USB", "USB": "USB",
"GameCard": "Cartão de jogo", "GameCard": "Cartão de jogo",
"Disable MTP for usb install": "Escuta MTP desabilitada temporáriamente", "Disable MTP for usb install": "Escuta MTP desabilitada temporáriamente.",
"Re-enabled MTP": "Escuta MTP reabilitada", "Re-enabled MTP": "Escuta MTP reabilitada.",
"Waiting for connection...": "Aguardando conexão...", "Waiting for connection...": "Aguardando conexão...",
"Transferring data...": "Transferindo dados...", "Transferring data...": "Transferindo dados...",
"Ftp install success!": "Instalação via FTP concluída com sucesso.", "Ftp install success!": "Instalação via FTP concluída com sucesso.",
@@ -287,7 +309,7 @@
"Installing ": "Instalando ", "Installing ": "Instalando ",
"Uninstalling ": "Desinstalando ", "Uninstalling ": "Desinstalando ",
"Deleting ": "Excluindo ", "Deleting ": "Excluindo ",
"Deleting": "Excluindo", "Deleting": "Excluindo...",
"Pasting ": "Colando ", "Pasting ": "Colando ",
"Pasting": "Colando ", "Pasting": "Colando ",
"Removing ": "Removendo ", "Removing ": "Removendo ",
@@ -303,24 +325,26 @@
"Loading": "Carregando", "Loading": "Carregando",
"Empty!": "Vazio", "Empty!": "Vazio",
"Not Ready...": "Não está pronto...", "Not Ready...": "Não está pronto...",
"Error loading page!": "Erro ao carregar página", "Error loading page!": "Erro ao carregar página.",
"Update avaliable: ": "Atualização disponível: ", "Update avaliable: ": "Atualização disponível: ",
"Download update: ": "Baixar autalização: ", "Download update: ": "Baixar autalização: ",
"Updated to ": "Atualizado para ", "Updated to ": "Atualizado para ",
"Press OK to restart Sphaira": "Selecione OK para reiniciar o sphaira", "Press OK to restart Sphaira": "Selecione OK para reiniciar o sphaira.",
"Restart Sphaira?": "Reiniciar sphaira?", "Restart Sphaira?": "Reiniciar sphaira?",
"Failed to download update": "Falha ao baixar a atualização", "Failed to download update": "Falha ao baixar a atualização.",
"Restore hbmenu?": "Restaurar hbmenu?", "Restore hbmenu?": "Restaurar hbmenu?",
"Failed to find /switch/hbmenu.nro\nUse the Appstore to re-install hbmenu": "Falha ao buscar /switch/hbmenu.nro\nUse a AppStore para reinstalar o hbmenu", "Failed to find /switch/hbmenu.nro\nUse the Appstore to re-install hbmenu": "Falha ao buscar /switch/hbmenu.nro\nUse a loja (AppStore) para reinstalar o hbmenu.",
"Failed to restore hbmenu, please re-download hbmenu": "Falha ao restaurar o hbmenu, baixe o hbmenu novamente", "Failed to restore hbmenu, please re-download hbmenu": "Falha ao restaurar o hbmenu, baixe o hbmenu novamente.",
"Failed to restore hbmenu, using sphaira instead": "Falha ao restaurar hbmenu, usando sphaira", "Failed to restore hbmenu, using sphaira instead": "Falha ao restaurar hbmenu, usando sphaira.",
"Restored hbmenu, closing sphaira": "hbmenu restaurado, fechando sphaira", "Restored hbmenu, closing sphaira": "hbmenu restaurado, fechando sphaira.",
"Restored hbmenu": "hbmenu restaurado", "Restored hbmenu": "hbmenu restaurado.",
"Delete Selected files?": "Excluir os arquivos selecionados?", "Delete Selected files?": "Excluir os arquivos selecionados?",
"Completely remove ": "Remover completamente ", "Completely remove ": "Remover completamente ",
"Delete successfull!": "Exclusão foi concluída com sucesso.",
"Delete failed!": "Exclusão falhou",
"Are you sure you want to delete ": "Você tem certeza que quer excluir ", "Are you sure you want to delete ": "Você tem certeza que quer excluir ",
"Are you sure you wish to cancel?": "Você tem certeza que quer cancelar?", "Are you sure you wish to cancel?": "Você tem certeza que quer cancelar?",
"Audio disabled due to suspended game": "Áudio desativado devido ao software suspenso", "Audio disabled due to suspended game": "Áudio desativado devido ao software suspenso.",
"If this message appears repeatedly, please open an issue.": "Se esta mensagem aparecer repetidamente, abra um issue." "If this message appears repeatedly, please open an issue.": "Se esta mensagem aparecer repetidamente, abra um issue."
} }

326
assets/romfs/i18n/uk.json Normal file
View File

@@ -0,0 +1,326 @@
{
"[Applet Mode]": "[Режим Аплету]",
"No Internet": "Без інтернету",
"Files": "Файли",
"Apps": "Програми",
"Store": "Магазин",
"Menu": "Меню",
"Options": "Налаштування",
"OK": "ОК",
"Back": "Назад",
"Select": "Вибрати",
"Open": "Відкрити",
"Launch": "Запустити",
"Info": "Інфо",
"Install": "Встановити",
"Delete": "Видалити",
"Restart": "Перезапустити",
"Changelog": "Журнал змін",
"Details": "Деталі",
"Update": "Оновити",
"Remove": "Видалити",
"Restore": "Відновити",
"Download": "Завантажити",
"Next": "Наступний",
"Prev": "Попередній",
"Next Page": "Наступна сторінка",
"Prev Page": "Попередня сторінка",
"Unstar": "Прибрати з обраного",
"Star": "Позначити зіркою",
"System memory": "Пам'ять консолі",
"microSD card": "SD-карта",
"Sd": "SD-карта",
"Image System memory": "Фото | Пам'ять консолі",
"Image microSD card": "Фото | SD-карта",
"Slow": "Повільно",
"Normal": "Нормально",
"Fast": "Швидко",
"Yes": "Так",
"No": "Ні",
"On": "Увімк.",
"Off": "Вимк.",
"Enable": "Увімк.",
"Enabled": "Увімк.",
"Disabled": "Вимк.",
"Sort By": "Сортувати за",
"Sort Options": "Опції сортування",
"Filter": "Фільтр",
"Sort": "Сортування",
"Order": "Порядок",
"Search": "Пошук",
"Updated": "Оновлено",
"Updated (Star)": "Оновлено (Зірка)",
"Downloads": "Завантаження",
"Size": "Розмір",
"Size (Star)": "Розмір (Зірка)",
"Alphabetical": "За алфавітом",
"Alphabetical (Star)": "За алфавітом (Зірка)",
"Likes": "Вподобання",
"ID": "ID",
"Descending": "За спаданням",
"Descending (down)": "За спаданням (вниз)",
"Desc": "Спад.",
"Ascending": "За зростанням",
"Ascending (Up)": "За зростанням (вгору)",
"Asc": "Зрост.",
"Menu Options": "Опції меню",
"Theme": "Тема",
"Theme Options": "Опції теми",
"Select Theme": "Вибрати тему",
"Shuffle": "Перемішати",
"Music": "Музика",
"12 Hour Time": "12-годинний формат часу",
"Download Default Music": "Завантажити музику за замовчуванням",
"Network": "Мережа",
"Network Options": "Опції мережі",
"Ftp": "FTP",
"Mtp": "MTP",
"Nxlink": "Nxlink",
"Nxlink Connected": "Nxlink підключено",
"Nxlink Upload": "Nxlink | Завантаження",
"Nxlink Finished": "Nxlink | Завершено",
"Switch-Handheld!": "Switch - Портатив!",
"Switch-Docked!": "Switch - Докований!",
"Language": "Мова",
"Auto": "Автоматично",
"English": "English",
"Japanese": "日本語",
"French": "Français",
"German": "Deutsch",
"Italian": "Italiano",
"Spanish": "Español",
"Chinese": "中文",
"Korean": "한국어",
"Dutch": "Nederlands",
"Portuguese": "Português",
"Russian": "Русский",
"Swedish": "Svenska",
"Vietnamese": "Tiếng Việt",
"Logging": "Логування",
"Replace hbmenu on exit": "Заміна hbmenu при виході",
"Misc": "Різне",
"Misc Options": "Опції різного",
"Web": "Веб",
"Install forwarders": "Встановити форвардери",
"Install location": "Місце встановлення",
"Show install warning": "Попередж. при встанов.",
"Text scroll speed": "Швидк. прокрутки",
"Set right-side menu": "Праве меню",
"FileBrowser": "Файловий менеджер",
"%zd files": "%zd файл(и)",
"%zd dirs": "%zd тек(и)",
"File Options": "Опції файлів",
"Show Hidden": "Показати приховані",
"Folders First": "Теки спочатку",
"Hidden Last": "Приховані в кінці",
"Cut": "Вирізати",
"Copy": "Копіювати",
"Paste": "Вставити",
"Paste ": "Вставити: ",
" file(s)?": " файл(и)?",
"Rename": "Перейменувати",
"Compress to zip": "Стиснути в zip",
"Set New File Name": "Введіть нове ім'я файлу",
"Advanced": "Додатково",
"Advanced Options": "Додаткові опції",
"Create File": "Створити файл",
"Set File Name": "Введіть ім'я файлу",
"Create Folder": "Створити теку",
"Set Folder Name": "Введіть ім'я теки",
"View as text (unfinished)": "Переглянути як текст (незавершено)",
"Ignore read only": "Ігнорувати лише читання",
"Mount": "Монтувати",
"Empty...": "Пусто...",
"Open with DayBreak?": "Відкрити за допомогою DayBreak?",
"Launch ": "Запустити ",
"Launch option for: ": "Опція запуску для: ",
"Select launcher for: ": "Виберіть лаунчер для: ",
"Homebrew": "Домашні програми",
"Homebrew Options": "Опції домашніх програм",
"Hide Sphaira": "Приховати Sphaira",
"Install Forwarder": "Встановити форвардер",
"WARNING: Installing forwarders will lead to a ban!": "УВАГА: Встановлення форвардерів може призвести до бану!",
"Installing Forwarder": "Встановлення форвардера",
"Creating Program": "Створення програми",
"Creating Control": "Створення контролера",
"Creating Meta": "Створення метаданих",
"Writing Nca": "Запис NCA",
"Updating ncm databse": "Оновлення бази даних NCM",
"Pushing application record": "Запис даних програми",
"Installed!": "Встановлено!",
"Failed to install forwarder": "Не вдалося встановити форвардер",
"Unstarred ": "Знято зірку з ",
"Starred ": "Позначено зіркою ",
"AppStore": "Магазин програм",
"Filter: %s | Sort: %s | Order: %s": "Фільтр: %s | Сорт.: %s | Порядок: %s",
"AppStore Options": "Опції магазину програм",
"All": "Всі",
"Games": "Ігри",
"Emulators": "Емулятори",
"Tools": "Інструменти",
"Themes": "Теми",
"Legacy": "Доступні оновлення",
"version: %s": "версія: %s",
"updated: %s": "оновлено: %s",
"category: %s": "категорія: %s",
"extracted: %.2f MiB": "розмір: %.2f MiB",
"app_dls: %s": "завантажень: %s",
"More by Author": "Більше від автора",
"Leave Feedback": "Залишити відгук",
"Game Options": "Опції ігор",
"Launch random game": "Запустити випадкову гру",
"List meta records": "Список метаданих записів",
"Entries": "Записи",
"Delete entity": "Видалити сутність",
"Hide forwarders": "Приховати форвардери",
"Irs": "ІЧ-сенсор",
"IRS (Infrared Joycon Camera)": "ІЧ (Інфрачервона камера Joycon)",
"Ambient Noise Level: ": "Рівень навколишнього шуму: ",
"Controller": "Контролер",
"Pad ": "Геймпад ",
" (Available)": " (Доступно)",
" (Unsupported)": " (Не підтримується)",
" (Unconnected)": " (Не підключено)",
"HandHeld": "Портативний режим",
"Rotation": "Обертання",
"0 (Sideways)": "0° (Збоку)",
"90 (Flat)": "90° (Плоско)",
"180 (-Sideways)": "180° (-Збоку)",
"270 (Upside down)": "270° (Догори дном)",
"Colour": "Колір",
"Grey": "Сірий",
"Ironbow": "Ironbow",
"Green": "Зелений",
"Red": "Червоний",
"Blue": "Синій",
"Light Target": "Ціль освітлення",
"All leds": "Всі світлодіоди",
"Bright group": "Яскрава група",
"Dim group": "Тьмяна група",
"None": "Немає",
"Gain": "Підсилення",
"Negative Image": "Негативне зображення",
"Normal image": "Нормальне зображення",
"Trimming Format": "Формат обрізки",
"External Light Filter": "Фільтр зовнішнього освітлення",
"Load Default": "Завантажити типові",
"Format": "Формат",
"320x240": "320×240",
"160x120": "160×120",
"80x60": "80×60",
"40x30": "40×30",
"20x15": "20×15",
"Themezer": "Themezer",
"Themezer Options": "Опції Themezer",
"Nsfw": "NSFW",
"Page": "Сторінка",
"Page %zu / %zu": "Сторінка %zu / %zu",
"Enter Page Number": "Введіть номер сторінки",
"Bad Page": "Неправильна сторінка",
"Download theme?": "Завантажити тему?",
"GitHub": "GitHub",
"Downloading json": "Завантаження JSON",
"Select asset to download for ": "Виберіть ресурс для завантаження для ",
"Install Options": "Опції встановлення",
"Install options": "Опції встановлення",
"Boost CPU clock": "Розігнати CPU",
"Allow downgrade": "Дозволити відкат",
"Skip if already installed": "Пропуск, якщо встановл.",
"Ticket only": "Тільки тікет",
"Patch ticket": "Змінити тікет",
"Skip base": "Пропустити базу",
"Skip patch": "Пропустити патч",
"Skip dlc": "Пропустити DLC",
"Skip data patch": "Пропустити патч даних",
"Skip ticket": "Пропустити тікет",
"skip NCA hash verify": "Пропуск перевірку хешу NCA",
"Skip RSA header verify": "Пропуск перевірку заголовка RSA",
"Skip RSA NPDM verify": "Пропуск перевірку NPDM RSA",
"Ignore distribution bit": "Ігнорувати біт розподілу",
"Convert to standard crypto": "Конвертувати у стандартне шифрування",
"Lower master key": "Знизити майстер-ключ",
"Lower system version": "Знизити версію системи",
"Install Selected files?": "Встановити вибрані файли?",
"Installed": "Встановлено",
"Installed ": "Встановлено ",
"FTP Install": "Встановлення через FTP",
"USB Install": "Встановлення через USB",
"GameCard Install": "Встановлення з картриджа",
"FTP Install (EXPERIMENTAL)": "Встановлення через FTP (ЕКСПЕРИМЕНТАЛЬНО)",
"USB": "USB",
"GameCard": "Картридж",
"Disable MTP for usb install": "Вимкнути MTP для встановлення через USB",
"Re-enabled MTP": "MTP знову увімкнено",
"Waiting for connection...": "Очікування підключення...",
"Transferring data...": "Передача даних...",
"Ftp install success!": "Встановлення через FTP успішно завершено.",
"Ftp install failed!": "Встановлення через FTP не вдалося.",
"Usb install success!": "Встановлення через USB успішно завершено.",
"Usb install failed!": "Встановлення через USB не вдалося.",
"Gc install success!": "Встановлення з картриджа успішно завершено.",
"Gc install failed!": "Встановлення з картриджа не вдалося.",
"Installed via usb": "Встановлено через USB",
"Failed to install via FTP, press B to exit...": "Не вдалося встановити через FTP, натисніть B для виходу...",
"Failed to init usb, press B to exit...": "Не вдалося ініціалізувати USB, натисніть B для виходу...",
"Press B to exit...": "Натисніть B для виходу...",
"Connection Type: WiFi | Strength:": "Тип підключення: WiFi | Сила сигналу:",
"Connection Type: WiFi | Strength: ": "Тип підключення: WiFi | Сила сигналу: ",
"Connection Type: Ethernet": "Тип підключення: Ethernet",
"Connection Type: None": "Тип підключення: Немає",
"Host:": "Хост:",
"Port:": "Порт:",
"Username:": "Ім'я користувача:",
"Password:": "Пароль:",
"SSID:": "SSID:",
"Passphrase:": "Кодова фраза:",
"Installing ": "Встановлення ",
"Uninstalling ": "Видалення ",
"Deleting ": "Видалення ",
"Deleting": "Видалення",
"Pasting ": "Вставлення ",
"Pasting": "Вставлення",
"Removing ": "Видалення ",
"Scanning ": "Сканування ",
"Creating ": "Створення ",
"Copying ": "Копіювання ",
"Trying to load ": "Спроба завантажити ",
"Downloading ": "Завантаження ",
"Downloaded ": "Завантажено ",
"Removed ": "Видалено ",
"Checking MD5": "Перевірка MD5",
"Loading...": "Завантаження...",
"Loading": "Завантаження",
"Empty!": "Пусто!",
"Not Ready...": "Не готово...",
"Error loading page!": "Помилка завантаження сторінки!",
"Update avaliable: ": "Доступне оновлення: ",
"Download update: ": "Завантажити оновлення: ",
"Updated to ": "Оновлено до ",
"Press OK to restart Sphaira": "Натисніть OK для перезапуску Sphaira",
"Restart Sphaira?": "Перезапустити Sphaira?",
"Failed to download update": "Не вдалося завантажити оновлення",
"Restore hbmenu?": "Відновити hbmenu?",
"Failed to find /switch/hbmenu.nro\nUse the Appstore to re-install hbmenu": "Не вдалося знайти /switch/hbmenu.nro\nВикористовуйте Магазин програм для перевстановлення hbmenu",
"Failed to restore hbmenu, please re-download hbmenu": "Не вдалося відновити hbmenu, будь ласка, завантажте hbmenu знову",
"Failed to restore hbmenu, using sphaira instead": "Не вдалося відновити hbmenu, замість цього використовується Sphaira",
"Restored hbmenu, closing sphaira": "hbmenu відновлено, закриття Sphaira",
"Restored hbmenu": "hbmenu відновлено",
"Delete Selected files?": "Видалити вибрані файли?",
"Completely remove ": "Повністю видалити ",
"Are you sure you want to delete ": "Ви впевнені, що хочете видалити ",
"Are you sure you wish to cancel?": "Ви впевнені, що хочете скасувати?",
"Audio disabled due to suspended game": "Аудіо вимкнено через призупинену програму",
"If this message appears repeatedly, please open an issue.": "Якщо це повідомлення з'являється повторно, будь ласка, повідомте про проблему."
}

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
set(sphaira_VERSION 0.10.1) set(sphaira_VERSION 0.10.3)
project(sphaira project(sphaira
VERSION ${sphaira_VERSION} VERSION ${sphaira_VERSION}

View File

@@ -127,6 +127,10 @@ public:
void ScanThemes(const std::string& path); void ScanThemes(const std::string& path);
void ScanThemeEntries(); void ScanThemeEntries();
// helper that converts 1.2.3 to a u32 used for comparisons.
static auto GetVersionFromString(const char* str) -> u32;
static auto IsVersionNewer(const char* current, const char* new_version) -> u32;
static auto IsApplication() -> bool { static auto IsApplication() -> bool {
const auto type = appletGetAppletType(); const auto type = appletGetAppletType();
return type == AppletType_Application || type == AppletType_SystemApplication; return type == AppletType_Application || type == AppletType_SystemApplication;

View File

@@ -719,7 +719,7 @@ void App::SetReplaceHbmenuEnable(bool enable) {
} }
if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) { if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) {
if (std::strcmp(sphaira_nacp.display_version, hbmenu_nacp.display_version) < 0) { if (IsVersionNewer(sphaira_nacp.display_version, hbmenu_nacp.display_version)) {
if (R_FAILED(rc = fs.copy_entire_file(sphaira_path, "/hbmenu.nro"))) { if (R_FAILED(rc = fs.copy_entire_file(sphaira_path, "/hbmenu.nro"))) {
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path.s, rc, R_MODULE(rc), R_DESCRIPTION(rc)); log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path.s, rc, R_MODULE(rc), R_DESCRIPTION(rc));
} else { } else {
@@ -1744,7 +1744,7 @@ App::~App() {
// found sphaira, now lets get compare version // found sphaira, now lets get compare version
if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) { if (R_SUCCEEDED(rc) && !std::strcmp(sphaira_nacp.lang[0].name, "sphaira")) {
if (std::strcmp(hbmenu_nacp.display_version, sphaira_nacp.display_version) < 0) { if (IsVersionNewer(hbmenu_nacp.display_version, sphaira_nacp.display_version)) {
if (R_FAILED(rc = fs.copy_entire_file(GetExePath(), sphaira_path))) { if (R_FAILED(rc = fs.copy_entire_file(GetExePath(), sphaira_path))) {
log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path.s, rc, R_MODULE(rc), R_DESCRIPTION(rc)); log_write("failed to copy entire file: %s 0x%X module: %u desc: %u\n", sphaira_path.s, rc, R_MODULE(rc), R_DESCRIPTION(rc));
} else { } else {
@@ -1782,6 +1782,16 @@ App::~App() {
ini_putl("paths", "timestamp", timestamp, App::CONFIG_PATH); ini_putl("paths", "timestamp", timestamp, App::CONFIG_PATH);
} }
auto App::GetVersionFromString(const char* str) -> u32 {
u32 major{}, minor{}, macro{};
std::sscanf(str, "%u.%u.%u", &major, &minor, &macro);
return MAKEHOSVERSION(major, minor, macro);
}
auto App::IsVersionNewer(const char* current, const char* new_version) -> u32 {
return GetVersionFromString(current) < GetVersionFromString(new_version);
}
void App::createFramebufferResources() { void App::createFramebufferResources() {
this->swapchain = nullptr; this->swapchain = nullptr;

View File

@@ -78,6 +78,7 @@ bool init(long index) {
case 11: setLanguage = SetLanguage_RU; break; // "Russian" case 11: setLanguage = SetLanguage_RU; break; // "Russian"
case 12: lang_name = "se"; break; // "Swedish" case 12: lang_name = "se"; break; // "Swedish"
case 13: lang_name = "vi"; break; // "Vietnamese" case 13: lang_name = "vi"; break; // "Vietnamese"
case 14: lang_name = "uk"; break; // "Ukrainian"
} }
switch (setLanguage) { switch (setLanguage) {
@@ -86,7 +87,7 @@ bool init(long index) {
case SetLanguage_DE: lang_name = "de"; break; case SetLanguage_DE: lang_name = "de"; break;
case SetLanguage_IT: lang_name = "it"; break; case SetLanguage_IT: lang_name = "it"; break;
case SetLanguage_ES: lang_name = "es"; break; case SetLanguage_ES: lang_name = "es"; break;
case SetLanguage_ZHCN: lang_name = "zh"; break; case SetLanguage_ZHCN: lang_name = "zh"; break;
case SetLanguage_KO: lang_name = "ko"; break; case SetLanguage_KO: lang_name = "ko"; break;
case SetLanguage_NL: lang_name = "nl"; break; case SetLanguage_NL: lang_name = "nl"; break;
case SetLanguage_PT: lang_name = "pt"; break; case SetLanguage_PT: lang_name = "pt"; break;

View File

@@ -57,6 +57,7 @@ auto nro_parse_internal(fs::FsNative& fs, const fs::FsPath& path, NroEntry& entr
// some .nro (vgedit) have bad nacp, fake the nacp // some .nro (vgedit) have bad nacp, fake the nacp
if (asset.magic != NROASSETHEADER_MAGIC || asset.nacp.offset == 0 || asset.nacp.size != sizeof(entry.nacp)) { if (asset.magic != NROASSETHEADER_MAGIC || asset.nacp.offset == 0 || asset.nacp.size != sizeof(entry.nacp)) {
std::memset(&asset, 0, sizeof(asset));
std::memset(&entry.nacp, 0, sizeof(entry.nacp)); std::memset(&entry.nacp, 0, sizeof(entry.nacp));
// get the name without the .nro // get the name without the .nro
@@ -157,6 +158,11 @@ auto nro_scan_internal(const fs::FsPath& path, std::vector<NroEntry>& nros, bool
} }
auto nro_get_icon_internal(FsFile* f, u64 size, u64 offset) -> std::vector<u8> { auto nro_get_icon_internal(FsFile* f, u64 size, u64 offset) -> std::vector<u8> {
// protect again really messed up sizes.
if (size > 1024 * 1024) {
return {};
}
std::vector<u8> icon; std::vector<u8> icon;
u64 bytes_read{}; u64 bytes_read{};
icon.resize(size); icon.resize(size);

View File

@@ -212,7 +212,7 @@ MainMenu::MainMenu() {
const auto version = yyjson_get_str(tag_key); const auto version = yyjson_get_str(tag_key);
R_UNLESS(version, false); R_UNLESS(version, false);
if (!std::strcmp(APP_VERSION, version)) { if (!App::IsVersionNewer(APP_VERSION, version)) {
m_update_state = UpdateState::None; m_update_state = UpdateState::None;
return true; return true;
} }
@@ -269,6 +269,7 @@ MainMenu::MainMenu() {
language_items.push_back("Russian"_i18n); language_items.push_back("Russian"_i18n);
language_items.push_back("Swedish"_i18n); language_items.push_back("Swedish"_i18n);
language_items.push_back("Vietnamese"_i18n); language_items.push_back("Vietnamese"_i18n);
language_items.push_back("Ukrainian"_i18n);
options->Add(std::make_shared<SidebarEntryCallback>("Theme"_i18n, [](){ options->Add(std::make_shared<SidebarEntryCallback>("Theme"_i18n, [](){
App::DisplayThemeOptions(); App::DisplayThemeOptions();

View File

@@ -101,8 +101,9 @@ def send_nsp_list(nsp_dir, out_ep):
# Add all files with the extension .nsp in the provided dir # Add all files with the extension .nsp in the provided dir
for nsp_path in [f for f in nsp_dir.iterdir() if f.is_file() and (f.suffix in EXTS)]: for nsp_path in [f for f in nsp_dir.iterdir() if f.is_file() and (f.suffix in EXTS)]:
nsp_path_list.append(nsp_path.__str__() + '\n') nsp_path = bytes(nsp_path.__str__(), 'utf8') + b'\n'
nsp_path_list_len += len(nsp_path.__str__()) + 1 nsp_path_list.append(nsp_path)
nsp_path_list_len += len(nsp_path)
print('Sending header...') print('Sending header...')