4 Commits

Author SHA1 Message Date
ITotalJustice
17b341d83a fix ncz install due to write offset being applied twice, fix zlt, bump version 0.11.2 -> 0.11.3
bug was introduced in 6b56b7f.
2025-05-29 01:45:15 +01:00
redraz
391234ea7b Update Russian translation (#155) 2025-05-28 23:24:43 +01:00
ITotalJustice
92eb3a9ecd add some default url entries, add option to enter custom url.
see #135
2025-05-28 20:02:51 +01:00
ITotalJustice
491445a12f Revert "remove Web menu"
This reverts commit 2d7763444e.
2025-05-28 18:46:30 +01:00
7 changed files with 143 additions and 24 deletions

View File

@@ -8,10 +8,10 @@
"An error occurred": "Произошла ошибка",
"If this message appears repeatedly, please open an issue.": "Если ошибка появляется неоднократно, пожалуйста, откройте issue",
"Menu Options": "Параметры меню",
"Menu Options": "Опции меню",
"Menu": "Меню",
"Theme": "Тема",
"Theme Options": "Параметры темы",
"Theme Options": "Опции темы",
"Select Theme": "Выбор темы",
"Music": "Музыка",
"12 Hour Time": "12-часовое время",
@@ -20,13 +20,15 @@
"Overwrite current default music?": "Переписать текущую стандартную музыку?",
"Network": "Сеть",
"Network Options": "Параметры сети",
"Network Options": "Опции сети",
"Ftp": "FTP",
"Mtp": "MTP",
"Nxlink": "NXLink",
"Nxlink Connected": "NXLink подключён",
"Nxlink Upload": "NXLink отправка",
"Nxlink Finished": "NXLink завершено",
"Hdd": "HDD",
"Hdd write protect": "Защита HDD от записи",
"Language": "Язык",
"Auto": "Авто",
@@ -46,9 +48,9 @@
"Ukrainian": "Українська",
"Misc": "Прочее",
"Misc Options": "Прочие параметры",
"Misc Options": "Прочие опции",
"Games": "Игры",
"Game Options": "Параметры игр",
"Game Options": "Опции игр",
"Hide forwarders": "Скрыть форвардеры",
"Launch random game": "Запустить случайную игру",
"List meta records": "Список мета-записей",
@@ -75,7 +77,7 @@
"Delete failed!": "Ошибка удаления!",
"Themezer": "Themezer",
"Themezer Options": "Параметры Themezer",
"Themezer Options": "Опции Themezer",
"Nsfw": "NSFW",
"Page": "Страница",
"Page %zu / %zu": "Страница %zu / %zu",
@@ -169,7 +171,7 @@
"Load Default": "По умолчанию",
"Advanced": "Продвинутые",
"Advanced Options": "Расширенные параметры",
"Advanced Options": "Расширенные опции",
"Logging": "Журналирование",
"Replace hbmenu on exit": "Замена hbmenu при выходе",
"Restore hbmenu?": "Восстановить hbmenu?",
@@ -181,20 +183,22 @@
"Restored hbmenu": "hbmenu восстановлен",
"Restart Sphaira?": "Перезапустить Sphaira?",
"Press OK to restart Sphaira": "Нажмите OK для перезапуска Sphaira",
"Boost CPU during transfer": "Разгон CPU при передаче",
"Text scroll speed": "Скорость текста",
"Slow": "Медленная",
"Normal": "Обычная",
"Fast": "Быстрая",
"Set left-side menu": "Меню слева",
"Set right-side menu": "Меню справа",
"Install options": "Параметры установки",
"Install Options": "Параметры установки",
"Install options": "Опции установки",
"Install Options": "Опции установки",
"Enable sysmmc": "Включить на сиснанде",
"Enable emummc": "Включить на эмунанде",
"Show install warning": "Предупрежд. при установке",
"Install location": "Место установки",
"System memory": "NAND",
"microSD card": "microSD",
"Boost CPU clock": "Использовать разгон CPU",
"Boost CPU clock": "Разгон CPU",
"Allow downgrade": "Разрешить даунгрейд",
"Skip if already installed": "Пропуск установленного",
"Ticket only": "Только тикет",
@@ -203,17 +207,24 @@
"Skip dlc": "Пропустить DLC",
"Skip data patch": "Пропустить патч данных",
"Skip ticket": "Пропустить тикет",
"skip NCA hash verify": "Не проверять NCA hash",
"Skip NCA hash verify": "Не проверять NCA hash",
"Skip RSA header verify": "Не проверять RSA header",
"Skip RSA NPDM verify": "Не проверять RSA NPDM",
"Ignore distribution bit": "Игнор. бит распределения",
"Convert to standard crypto": "Конверт. в стандарт. крипт.",
"Lower master key": "Снизить мастер-ключ",
"Lower system version": "Снизить версию системы",
"Dump options": "Опции дампа",
"Dump Options": "Опции дампа",
"Created nested folder": "Создать вложенную папку",
"Append folder with .xci": "Добавить папку с .xci",
"Trim XCI": "Обрезать .xci",
"Label trimmed XCI": "Пометить обрезанный .xci",
"Multi-threaded USB transfer": "Многоядерная USB передача",
"Homebrew": "Homebrew",
"Apps": "Приложения",
"Homebrew Options": "Параметры Homebrew",
"Homebrew Options": "Опции Homebrew",
"Hide Sphaira": "Скрыть Sphaira",
"Install Forwarder": "Установить форвардер",
"WARNING: Installing forwarders will lead to a ban!": "ВНИМАНИЕ: \nУстановка в сиснанд приведет к бану!",
@@ -232,8 +243,8 @@
"AppStore": "AppStore",
"Appstore": "AppStore",
"Store": "Магазин",
"Filter: %s | Sort: %s | Order: %s": "Показывать: %s | Сорт: %s | Порядок: %s",
"AppStore Options": "Параметры AppStore",
"Filter: %s | Sort: %s | Order: %s": "Показывать: %s | Сортировка: %s | Порядок: %s",
"AppStore Options": "Опции AppStore",
"Info": "Информация",
"Changelog": "Список изменений",
"Details": "Подробности",
@@ -245,14 +256,16 @@
"More by Author": "Другие приложения автора",
"Leave Feedback": "Оставить отзыв",
"FileBrowser": "Файловый менеджер",
"FileBrowser": "Файлы",
"Files": "Файлы",
"%zd files": "%zd файлы",
"%zd dirs": "%zd разделы",
"File Options": "Параметры файла",
"File Options": "Опции файла",
"Show Hidden": "Показать скрытые",
"Folders First": "Папки в начале",
"Hidden Last": "Скрытые в конце",
"Split": "Разделить",
"Close": "Закрыть",
"Cut": "Вырезать",
"Copy": "Копировать",
"Copying ": "Копирование ",
@@ -264,7 +277,7 @@
"Rename": "Переименовать",
"Set New File Name": "Задайте новое имя файла",
"Extract zip": "Распаковать .zip",
"Extract Options": "Параметры распаковки",
"Extract Options": "Опции распаковки",
"Extract here": "Распаковать сюда",
"Extract to root": "Распаковать в корень",
"Are you sure you want to extract to root?": "Вы уверены, что хотите распаковать в корень?",
@@ -274,7 +287,7 @@
"Extract success!": "Распаковка успешна!",
"Extract failed!": "Сбой распаковки!",
"Compress to zip": "Сжать в .zip",
"Compress Options": "Параметры сжатия",
"Compress Options": "Опции сжатия",
"Compress": "Сжать",
"Compress to...": "Сжать в...",
"Compressing ": "Сжатие ",
@@ -291,6 +304,8 @@
"Uploading": "Отправка",
"Upload successfull!": "Отправка успешна!",
"Upload failed!": "Сбой Отправки!",
"Hash": "Хэш",
"Hash Options": "Опции хэша",
"View as text (unfinished)": "Открыть как текст (не доделано)",
"Ignore read only": "Игнор. только для чтения",
"Mount": "Монтирован",
@@ -300,11 +315,12 @@
"Empty...": "Пусто...",
"Open with DayBreak?": "Открыть с помощью DayBreak?",
"Launch ": "Запуск ",
"Launch option for: ": "Параметры запуска для: ",
"Launch option for: ": "Опции запуска для: ",
"Select launcher for: ": "Выберите загрузчик для: ",
"Close FileBrowser?": "Закрыть Файлы?",
"Sort By": "Сортировка",
"Sort Options": "Параметры сортировки",
"Sort Options": "Опции сортировки",
"Filter": "Показывать",
"All": "Всё",
"Emulators": "Эмуляторы",
@@ -334,7 +350,7 @@
"Grid": "Сетка",
"Search": "Поиск",
"Options": "Параметры",
"Options": "Опции",
"OK": "ОК",
"Back": "Назад",
"Select": "Выбрать",

View File

@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.13)
set(sphaira_VERSION 0.11.2)
set(sphaira_VERSION 0.11.3)
project(sphaira
VERSION ${sphaira_VERSION}
@@ -74,6 +74,7 @@ add_executable(sphaira
source/nxlink.cpp
source/owo.cpp
source/swkbd.cpp
source/web.cpp
source/hasher.cpp
source/i18n.cpp
source/ftpsrv_helper.cpp

10
sphaira/include/web.hpp Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
#include <switch.h>
#include <string>
namespace sphaira {
auto WebShow(const std::string& url) -> Result;
} // namespace sphaira

View File

@@ -19,6 +19,8 @@
#include "defines.hpp"
#include "i18n.hpp"
#include "ftpsrv_helper.hpp"
#include "web.hpp"
#include "swkbd.hpp"
#include <nanovg_dk.h>
#include <minIni.h>
@@ -1624,6 +1626,34 @@ void App::DisplayMiscOptions(bool left_side) {
App::Push(e.func(ui::menu::MenuFlag_None));
}));
}
if (App::IsApplication()) {
options->Add(std::make_shared<ui::SidebarEntryCallback>("Web"_i18n, [](){
// add some default entries, will use a config file soon so users can set their own.
ui::PopupList::Items items;
items.emplace_back("https://lite.duckduckgo.com/lite");
items.emplace_back("https://dns.switchbru.com");
items.emplace_back("https://gbatemp.net");
items.emplace_back("https://github.com/ITotalJustice/sphaira/wiki");
items.emplace_back("Enter custom URL"_i18n);
App::Push(std::make_shared<ui::PopupList>(
"Select URL"_i18n, items, [items](auto op_index){
if (op_index) {
const auto index = *op_index;
if (index == items.size() - 1) {
std::string out;
if (R_SUCCEEDED(swkbd::ShowText(out, "Enter URL", "https://")) && !out.empty()) {
WebShow(out);
}
} else {
WebShow(items[index]);
}
}
}
));
}));
}
}
void App::DisplayAdvancedOptions(bool left_side) {

View File

@@ -293,7 +293,7 @@ Result UsbDs::WaitTransferCompletion(UsbSessionEndpoint ep, u64 timeout) {
}
Result UsbDs::TransferAsync(UsbSessionEndpoint ep, void *buffer, u32 remaining, u32 size, u32 *out_urb_id) {
if (remaining == size && size == m_max_packet_size) {
if (remaining == size && !(size % (u32)m_max_packet_size)) {
log_write("[USBDS] SetZlt(true)\n");
R_TRY(usbDsEndpoint_SetZlt(m_endpoints[ep], true));
} else {

62
sphaira/source/web.cpp Normal file
View File

@@ -0,0 +1,62 @@
#include "web.hpp"
#include "log.hpp"
#include "app.hpp"
#include "defines.hpp"
#include <cstring>
namespace sphaira {
auto WebShow(const std::string& url) -> Result {
WebCommonConfig config{};
WebCommonReply reply{};
WebExitReason reason{};
AccountUid account_uid{};
char last_url[FS_MAX_PATH]{};
size_t last_url_len{};
// WebBackgroundKind_Unknown1 = shows background
// WebBackgroundKind_Unknown2 = shows background faded
if (R_FAILED(accountGetPreselectedUser(&account_uid))) {
log_write("failed: accountGetPreselectedUser\n");
if (R_FAILED(accountTrySelectUserWithoutInteraction(&account_uid, false))) {
log_write("failed: accountTrySelectUserWithoutInteraction\n");
if (R_FAILED(accountGetLastOpenedUser(&account_uid))) {
log_write("failed: accountGetLastOpenedUser\n");
}
}
}
if (R_FAILED(webPageCreate(&config, url.c_str()))) { log_write("failed: webPageCreate\n"); }
if (R_FAILED(webConfigSetWhitelist(&config, ".*"))) { log_write("failed: webConfigSetWhitelist\n"); }
if (R_FAILED(webConfigSetEcClientCert(&config, true))) { log_write("failed: webConfigSetEcClientCert\n"); }
if (R_FAILED(webConfigSetScreenShot(&config, true))) { log_write("failed: webConfigSetScreenShot\n"); }
if (R_FAILED(webConfigSetBootDisplayKind(&config, WebBootDisplayKind_Black))) { log_write("failed: webConfigSetBootDisplayKind\n"); }
if (R_FAILED(webConfigSetBackgroundKind(&config, WebBackgroundKind_Default))) { log_write("failed: webConfigSetBackgroundKind\n"); }
if (R_FAILED(webConfigSetPointer(&config, true))) { log_write("failed: webConfigSetPointer\n"); }
if (R_FAILED(webConfigSetLeftStickMode(&config, WebLeftStickMode_Pointer))) { log_write("failed: webConfigSetLeftStickMode\n"); }
if (R_FAILED(webConfigSetBootAsMediaPlayer(&config, false))) { log_write("failed: webConfigSetBootAsMediaPlayer\n"); }
if (R_FAILED(webConfigSetJsExtension(&config, true))) { log_write("failed: webConfigSetJsExtension\n"); }
if (R_FAILED(webConfigSetMediaPlayerAutoClose(&config, false))) { log_write("failed: webConfigSetMediaPlayerAutoClose\n"); }
if (R_FAILED(webConfigSetPageCache(&config, true))) { log_write("failed: webConfigSetPageCache\n"); }
if (R_FAILED(webConfigSetFooterFixedKind(&config, WebFooterFixedKind_Default))) { log_write("failed: webConfigSetFooterFixedKind\n"); }
if (R_FAILED(webConfigSetPageFade(&config, true))) { log_write("failed: webConfigSetPageFade\n"); }
if (R_FAILED(webConfigSetPageScrollIndicator(&config, true))) { log_write("failed: webConfigSetPageScrollIndicator\n"); }
// if (R_FAILED(webConfigSetMediaPlayerSpeedControl(&config, true))) { log_write("failed: webConfigSetMediaPlayerSpeedControl\n"); }
if (R_FAILED(webConfigSetBootMode(&config, WebSessionBootMode_AllForeground))) { log_write("failed: webConfigSetBootMode\n"); }
if (R_FAILED(webConfigSetTransferMemory(&config, true))) { log_write("failed: webConfigSetTransferMemory\n"); }
if (R_FAILED(webConfigSetTouchEnabledOnContents(&config, true))) { log_write("failed: webConfigSetTouchEnabledOnContents\n"); }
// if (R_FAILED(webConfigSetMediaPlayerUi(&config, true))) { log_write("failed: webConfigSetMediaPlayerUi\n"); }
if (R_FAILED(webConfigSetWebAudio(&config, false))) { log_write("failed: webConfigSetWebAudio\n"); }
if (R_FAILED(webConfigSetPageCache(&config, true))) { log_write("failed: webConfigSetPageCache\n"); }
// if (R_FAILED(webConfigSetBootLoadingIcon(&config, true))) { log_write("failed: webConfigSetBootLoadingIcon\n"); }
if (R_FAILED(webConfigSetUid(&config, account_uid))) { log_write("failed: webConfigSetUid\n"); }
if (R_FAILED(webConfigShow(&config, &reply))) { log_write("failed: webConfigShow\n"); }
if (R_FAILED(webReplyGetExitReason(&reply, &reason))) { log_write("failed: webReplyGetExitReason\n"); }
if (R_FAILED(webReplyGetLastUrl(&reply, last_url, sizeof(last_url), &last_url_len))) { log_write("failed: webReplyGetLastUrl\n"); }
log_write("last url: %s\n", last_url);
R_SUCCEED();
}
} // namespace sphaira

View File

@@ -704,7 +704,7 @@ Result Yati::writeFuncInternal(ThreadData* t) {
s64 off{};
while (off < buf.size() && t->write_offset < t->write_size && R_SUCCEEDED(t->GetResults())) {
const auto wsize = std::min<s64>(t->read_buffer_size, buf.size() - off);
R_TRY(ncmContentStorageWritePlaceHolder(std::addressof(cs), std::addressof(t->nca->placeholder_id), t->write_offset + off, buf.data() + off, wsize));
R_TRY(ncmContentStorageWritePlaceHolder(std::addressof(cs), std::addressof(t->nca->placeholder_id), t->write_offset, buf.data() + off, wsize));
off += wsize;
t->write_offset += wsize;