Compare commits

...

14 Commits

Author SHA1 Message Date
GreemDev
23eb9a3043 improvement: Make the updater log a special error message in some cases
specifically about potentially not being connected to the internet on a connection error or name resolution error
2025-09-05 03:12:15 -05:00
GreemDev
931ec44406 [ci skip] fix: <Reset> text in Pokemon Scarlet/Violet play report rich presence 2025-09-05 03:02:16 -05:00
GreemDev
d68efa98ba [ci skip] Update NuGet packages 2025-09-05 02:25:05 -05:00
GreemDev
ded76801d1 removal: Installing keys from a zip
Also cleaned up a bit
2025-09-04 19:04:50 -05:00
GreemDev
6084df7473 Silksong compatibility entry and RPC image 2025-09-04 16:23:38 -05:00
LotP1
f3953c6039 Fix a crash when no controller is connected 2025-09-04 16:18:07 -05:00
LotP1
91f5247e7f add missing field 2025-09-04 16:17:59 -05:00
LotP1
5658402c6b fix spelling 2025-09-04 16:17:53 -05:00
LotP1
1b2c93e188 Add version comment 2025-09-04 16:14:38 -05:00
LotP1
9e599ff325 remove stub 2025-09-04 16:14:18 -05:00
LotP1
7a5f430b59 hle: Basic event handle implementation for IApplicationFunctions 210
Lets Hollow Knight: Silksong boot.
2025-09-04 16:14:03 -05:00
shinyoyo
1e340ce2f3 Update Simplified Chinese translation. (ryubing/ryujinx!139)
See merge request ryubing/ryujinx!139
2025-09-03 15:49:14 -05:00
WilliamWsyHK
dbb4e63e1e Update zh-TW translation (ryubing/ryujinx!130)
See merge request ryubing/ryujinx!130
2025-09-03 03:28:37 -05:00
Hack茶ん
d00ab52fa2 Update Korean translation (ryubing/ryujinx!138)
See merge request ryubing/ryujinx!138
2025-09-03 03:26:33 -05:00
17 changed files with 217 additions and 232 deletions

View File

@@ -19,8 +19,8 @@
<PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/> <PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
<PackageVersion Include="Concentus" Version="2.2.2" /> <PackageVersion Include="Concentus" Version="2.2.2" />
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageVersion Include="DiscordRichPresence" Version="1.6.1.70" />
<PackageVersion Include="DynamicData" Version="9.0.4" /> <PackageVersion Include="DynamicData" Version="9.4.1" />
<PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" /> <PackageVersion Include="FluentAvaloniaUI" Version="2.0.5" />
<PackageVersion Include="Humanizer" Version="2.14.1" /> <PackageVersion Include="Humanizer" Version="2.14.1" />
<PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" /> <PackageVersion Include="Microsoft.CodeAnalysis.Analyzers" Version="3.3.4" />
@@ -42,11 +42,11 @@
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" /> <PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" /> <PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.29" /> <PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.44" />
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.29" /> <PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.44" />
<PackageVersion Include="Gommon" Version="2.7.1.1" /> <PackageVersion Include="Gommon" Version="2.7.2.1" />
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" /> <PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
<PackageVersion Include="Sep" Version="0.6.0" /> <PackageVersion Include="Sep" Version="0.11.1" />
<PackageVersion Include="shaderc.net" Version="0.1.0" /> <PackageVersion Include="shaderc.net" Version="0.1.0" />
<PackageVersion Include="SharpZipLib" Version="1.4.2" /> <PackageVersion Include="SharpZipLib" Version="1.4.2" />
<PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" /> <PackageVersion Include="Silk.NET.Vulkan" Version="2.22.0" />

View File

@@ -79,7 +79,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "Editor di Mii", "it_IT": "Editor di Mii",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "Mii 편집기",
"no_NO": "Mii-redigerer", "no_NO": "Mii-redigerer",
"pl_PL": "Edytor Mii", "pl_PL": "Edytor Mii",
"pt_BR": "Editor de Mii", "pt_BR": "Editor de Mii",
@@ -88,7 +88,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Редактор Mii", "uk_UA": "Редактор Mii",
"zh_CN": "", "zh_CN": "Mii 编辑器",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -896,25 +896,25 @@
"ID": "MenuBarFileActionsInstallKeysFromFile", "ID": "MenuBarFileActionsInstallKeysFromFile",
"Translations": { "Translations": {
"ar_SA": "", "ar_SA": "",
"de_DE": "Schlüssel (.KEYS oder .ZIP) installieren", "de_DE": "Schlüssel (.KEYS) installieren",
"el_GR": "", "el_GR": "",
"en_US": "Install Keys (.KEYS or .ZIP)", "en_US": "Install Keys (.KEYS)",
"es_ES": "Instalar keys (.KEYS o .ZIP)", "es_ES": "Instalar keys (.KEYS)",
"fr_FR": "Installer des Clés (.KEYS ou .ZIP)", "fr_FR": "Installer des Clés (.KEYS)",
"he_IL": "", "he_IL": "",
"it_IT": "Installa chiavi (.KEYS o .ZIP)", "it_IT": "Installa chiavi (.KEYS)",
"ja_JP": "", "ja_JP": "",
"ko_KR": "키 설치 (.KEYS 또는 .ZIP)", "ko_KR": "키 설치 (.KEYS)",
"no_NO": "Installer nøkler (.KEYS eller .ZIP)", "no_NO": "Installer nøkler (.KEYS)",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Instalar chaves (.KEYS ou .ZIP", "pt_BR": "Instalar chaves (.KEYS)",
"ru_RU": "Установить ключи (.KEYS или .ZIP)", "ru_RU": "Установить ключи (.KEYS)",
"sv_SE": "Installera nycklar (.KEYS eller .ZIP)", "sv_SE": "Installera nycklar (.KEYS)",
"th_TH": "ติดตั้งคีย์ (.KEYS หรือ .ZIP)", "th_TH": "ติดตั้งคีย์ (.KEYS)",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Встановити ключі (.KEYS або .ZIP)", "uk_UA": "Встановити ключі (.KEYS)",
"zh_CN": "安装密钥(.KEYS 或 .ZIP", "zh_CN": "安装密钥(.KEYS",
"zh_TW": "安裝金鑰(.KEYS 或 .ZIP" "zh_TW": "安裝金鑰(.KEYS"
} }
}, },
{ {
@@ -1054,7 +1054,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "도구",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -1063,7 +1063,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "", "zh_CN": "工具",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -1288,7 +1288,7 @@
"th_TH": "คำถามที่พบบ่อย & คู่มือ", "th_TH": "คำถามที่พบบ่อย & คู่มือ",
"tr_TR": "SSS & Rehberler", "tr_TR": "SSS & Rehberler",
"uk_UA": "FAQ & посібники", "uk_UA": "FAQ & посібники",
"zh_CN": "问答 & 指南", "zh_CN": "常见问题与指南",
"zh_TW": "常見問題 (FAQ) & 指南" "zh_TW": "常見問題 (FAQ) & 指南"
} }
}, },
@@ -1304,7 +1304,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "FAQ & Risoluzione dei problemi", "it_IT": "FAQ & Risoluzione dei problemi",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "자주 묻는 질문 및 문제 해결",
"no_NO": "FAQ & Feilsøkinge", "no_NO": "FAQ & Feilsøkinge",
"pl_PL": "", "pl_PL": "",
"pt_BR": "FAQ & Solução de Problemas", "pt_BR": "FAQ & Solução de Problemas",
@@ -1313,7 +1313,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "FAQ & Усунення несправностей", "uk_UA": "FAQ & Усунення несправностей",
"zh_CN": "", "zh_CN": "常见问题与疑难解答",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -2554,7 +2554,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": null,
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -2988,7 +2988,7 @@
"th_TH": "ตรวจสอบ & ลดขนาดไฟล์ XCI", "th_TH": "ตรวจสอบ & ลดขนาดไฟล์ XCI",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Перевірка & нарізка XCI Файлу", "uk_UA": "Перевірка & нарізка XCI Файлу",
"zh_CN": "检查 & 瘦身 XCI 文件", "zh_CN": "检查并精简 XCI 文件",
"zh_TW": "檢查 & 修剪 XCI 檔案" "zh_TW": "檢查 & 修剪 XCI 檔案"
} }
}, },
@@ -12088,7 +12088,7 @@
"th_TH": "เริ่ม", "th_TH": "เริ่ม",
"tr_TR": "Başlat", "tr_TR": "Başlat",
"uk_UA": "Запустити", "uk_UA": "Запустити",
"zh_CN": "开始", "zh_CN": "启动",
"zh_TW": "開始" "zh_TW": "開始"
} }
}, },
@@ -15564,7 +15564,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "显示与此游戏不兼容的 Amiibo", "zh_CN": "显示与此游戏不兼容的 Amiibo",
"zh_TW": "" "zh_TW": "顯示與此遊戲不相容的 Amiibo"
} }
}, },
{ {
@@ -19254,7 +19254,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "Scegli un FILE compatibile con Switch da caricare", "it_IT": "Scegli un FILE compatibile con Switch da caricare",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "불러올 Switch 호환 파일을 선택",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Escolha um ARQUIVO compatível com Switch para carregar", "pt_BR": "Escolha um ARQUIVO compatível com Switch para carregar",
@@ -19263,7 +19263,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Виберіть ФАЙЛ, сумісний із Switch, для завантаження", "uk_UA": "Виберіть ФАЙЛ, сумісний із Switch, для завантаження",
"zh_CN": "", "zh_CN": "请选择要加载的 Switch 兼容文件",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -19279,7 +19279,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "Scegli unapplicazione DECOMPRESSA compatibile con Switch da caricare", "it_IT": "Scegli unapplicazione DECOMPRESSA compatibile con Switch da caricare",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "불러올 언팩된 Switch 호환 앱을 선택",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Escolha um aplicativo DESCOMPACTADO compatível com Switch para carregar", "pt_BR": "Escolha um aplicativo DESCOMPACTADO compatível com Switch para carregar",
@@ -19288,7 +19288,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Виберіть РОЗПАКОВАНИЙ сумісний із Switch додаток для завантаження", "uk_UA": "Виберіть РОЗПАКОВАНИЙ сумісний із Switch додаток для завантаження",
"zh_CN": "", "zh_CN": "请选择要加载的已解包的 Switch 兼容应用程序",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -19304,7 +19304,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "Scegli una o più CARTELLE da cui caricare in blocco gli aggiornamenti del titolo", "it_IT": "Scegli una o più CARTELLE da cui caricare in blocco gli aggiornamenti del titolo",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "타이틀 업데이트를 대량으로 불러올 폴더를 하나 이상 선택",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Escolha uma ou mais PASTAS para carregar atualizações de título em massa", "pt_BR": "Escolha uma ou mais PASTAS para carregar atualizações de título em massa",
@@ -19313,7 +19313,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Виберіть одну або кілька ПАПОК для масового завантаження оновлень титулів", "uk_UA": "Виберіть одну або кілька ПАПОК для масового завантаження оновлень титулів",
"zh_CN": "", "zh_CN": "请选择一个或多个文件夹来批量加载游戏更新",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -19329,7 +19329,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "Scegli una o più CARTELLE da cui caricare DLC in blocco", "it_IT": "Scegli una o più CARTELLE da cui caricare DLC in blocco",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "DLC를 대량으로 불러올 폴더를 하나 이상 선택",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "Escolha uma ou mais PASTAS para carregar DLC em massa", "pt_BR": "Escolha uma ou mais PASTAS para carregar DLC em massa",
@@ -19338,7 +19338,7 @@
"th_TH": "", "th_TH": "",
"tr_TR": "", "tr_TR": "",
"uk_UA": "Виберіть одну або кілька ПАПОК для масового завантаження DLC", "uk_UA": "Виберіть одну або кілька ПАПОК для масового завантаження DLC",
"zh_CN": "", "zh_CN": "请选择一个或多个文件夹来批量加载 DLC",
"zh_TW": "" "zh_TW": ""
} }
}, },
@@ -23779,7 +23779,7 @@
"he_IL": "", "he_IL": "",
"it_IT": "", "it_IT": "",
"ja_JP": "", "ja_JP": "",
"ko_KR": "", "ko_KR": "상태",
"no_NO": "", "no_NO": "",
"pl_PL": "", "pl_PL": "",
"pt_BR": "", "pt_BR": "",
@@ -23789,7 +23789,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "状态", "zh_CN": "状态",
"zh_TW": "" "zh_TW": "統計"
} }
}, },
{ {
@@ -24214,7 +24214,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "调试", "zh_CN": "调试",
"zh_TW": "" "zh_TW": "除錯"
} }
}, },
{ {
@@ -24239,7 +24239,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "调试", "zh_CN": "调试",
"zh_TW": "" "zh_TW": "除錯"
} }
}, },
{ {
@@ -24264,7 +24264,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "警告: 仅限开发者使用,会降低性能", "zh_CN": "警告: 仅限开发者使用,会降低性能",
"zh_TW": "" "zh_TW": "警告:僅供開發者使用,會降低效能"
} }
}, },
{ {
@@ -24289,7 +24289,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "开启 GDB Stub", "zh_CN": "开启 GDB Stub",
"zh_TW": "" "zh_TW": "啟用 GDB Stub"
} }
}, },
{ {
@@ -24314,7 +24314,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "启用 GDB stub 使得可以调试正在运行的应用程序。仅限开发用途!", "zh_CN": "启用 GDB stub 使得可以调试正在运行的应用程序。仅限开发用途!",
"zh_TW": "" "zh_TW": "啟用 GDB stub 可利用 gdb 除錯正在執行的應用程式。僅供開發使用!"
} }
}, },
{ {
@@ -24339,7 +24339,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "GDB Stub 端口:", "zh_CN": "GDB Stub 端口:",
"zh_TW": "" "zh_TW": "GDB Stub 通訊埠:"
} }
}, },
{ {
@@ -24364,7 +24364,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "启动时暂停应用程序", "zh_CN": "启动时暂停应用程序",
"zh_TW": "" "zh_TW": "執行時暫停應用程式"
} }
}, },
{ {
@@ -24389,7 +24389,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "在执行首条指令前挂起应用程序,这样就可以从最早的点开始调试。", "zh_CN": "在执行首条指令前挂起应用程序,这样就可以从最早的点开始调试。",
"zh_TW": "" "zh_TW": "在執行首項指令前暫停應用程式,以便從最早的點開始除錯。"
} }
}, },
{ {
@@ -24414,7 +24414,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "打开 LDN 游戏列表", "zh_CN": "打开 LDN 游戏列表",
"zh_TW": "" "zh_TW": "開啟 LDN 遊戲瀏覽器"
} }
}, },
{ {
@@ -24439,7 +24439,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "LDN 游戏浏览器 - {0} 个游戏", "zh_CN": "LDN 游戏浏览器 - {0} 个游戏",
"zh_TW": "" "zh_TW": "LDN 遊戲瀏覽器 - {0} 個遊戲"
} }
}, },
{ {
@@ -24464,7 +24464,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "搜索到 {0} 个 LDN 游戏...", "zh_CN": "搜索到 {0} 个 LDN 游戏...",
"zh_TW": "" "zh_TW": "搜尋 {0} 個 LDN 遊戲"
} }
}, },
{ {
@@ -24489,7 +24489,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "什么是 LDN", "zh_CN": "什么是 LDN",
"zh_TW": "" "zh_TW": "LDN 是甚麼? (只有英文)"
} }
}, },
{ {
@@ -24514,7 +24514,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "在 {0} 时从服务器刷新可用游戏", "zh_CN": "在 {0} 时从服务器刷新可用游戏",
"zh_TW": "" "zh_TW": "從 {0} 伺服器重新整理有效的遊戲"
} }
}, },
{ {
@@ -24539,7 +24539,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "玩家计数 - 关闭", "zh_CN": "玩家计数 - 关闭",
"zh_TW": "" "zh_TW": "玩家數量 - 停用"
} }
}, },
{ {
@@ -24564,7 +24564,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "玩家计数 - 递增", "zh_CN": "玩家计数 - 递增",
"zh_TW": "" "zh_TW": "玩家數量 - 遞增"
} }
}, },
{ {
@@ -24589,7 +24589,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "玩家计数 - 递减", "zh_CN": "玩家计数 - 递减",
"zh_TW": "" "zh_TW": "玩家數量 - 遞減"
} }
}, },
{ {
@@ -24614,7 +24614,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "筛选", "zh_CN": "筛选",
"zh_TW": "" "zh_TW": "篩選"
} }
}, },
{ {
@@ -24639,7 +24639,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "仅显示公开游戏", "zh_CN": "仅显示公开游戏",
"zh_TW": "" "zh_TW": "只列出公開遊戲"
} }
}, },
{ {
@@ -24664,7 +24664,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "仅显示可加入的游戏", "zh_CN": "仅显示可加入的游戏",
"zh_TW": "" "zh_TW": "只列出可加入遊戲"
} }
}, },
{ {
@@ -24689,7 +24689,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "主服务器代理", "zh_CN": "主服务器代理",
"zh_TW": "" "zh_TW": "主代理伺服器"
} }
}, },
{ {
@@ -24714,7 +24714,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": null, "zh_CN": null,
"zh_TW": "" "zh_TW": "對等網路 (P2P)"
} }
}, },
{ {
@@ -24739,7 +24739,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "通过 RyuLDN 服务器进行连接 (较慢)。", "zh_CN": "通过 RyuLDN 服务器进行连接 (较慢)。",
"zh_TW": "" "zh_TW": "透過 RyuLDN 伺服器連線 (較慢)。"
} }
}, },
{ {
@@ -24764,7 +24764,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "通过 UPnP 进行点对点连接 (较快)。", "zh_CN": "通过 UPnP 进行点对点连接 (较快)。",
"zh_TW": "" "zh_TW": "透過 UPnP 和對等網路 (P2P) 連線 (較快)。"
} }
}, },
{ {
@@ -24789,7 +24789,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "已创建: {0} ", "zh_CN": "已创建: {0} ",
"zh_TW": "" "zh_TW": "建立於:{0}"
} }
}, },
{ {
@@ -24814,7 +24814,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "玩家 ({0} 之 {1}):", "zh_CN": "玩家 ({0} 之 {1}):",
"zh_TW": "" "zh_TW": "玩家數量 ({1} 之 {0}):"
} }
}, },
{ {
@@ -24839,7 +24839,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "可加入", "zh_CN": "可加入",
"zh_TW": "" "zh_TW": "可加入"
} }
}, },
{ {
@@ -24864,7 +24864,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "如果游戏是公开的或您知道口令则它是可加入的。", "zh_CN": "如果游戏是公开的或您知道口令则它是可加入的。",
"zh_TW": "" "zh_TW": "如果遊戲是公開,或是你已知的網路密碼片語 (passphrase),則為可加入。"
} }
}, },
{ {
@@ -24889,7 +24889,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "不可加入", "zh_CN": "不可加入",
"zh_TW": "" "zh_TW": "不可加入"
} }
}, },
{ {
@@ -24914,7 +24914,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "游戏当前正在进行中。", "zh_CN": "游戏当前正在进行中。",
"zh_TW": "" "zh_TW": "遊戲已在進行中。"
} }
}, },
{ {
@@ -24939,7 +24939,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "公开", "zh_CN": "公开",
"zh_TW": "" "zh_TW": "公開"
} }
}, },
{ {
@@ -24964,7 +24964,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "任何人都可以加入此游戏。", "zh_CN": "任何人都可以加入此游戏。",
"zh_TW": "" "zh_TW": "任何人都可加入此遊戲。"
} }
}, },
{ {
@@ -24989,7 +24989,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "私密", "zh_CN": "私密",
"zh_TW": "" "zh_TW": "私人"
} }
}, },
{ {
@@ -25014,7 +25014,7 @@
"tr_TR": "", "tr_TR": "",
"uk_UA": "", "uk_UA": "",
"zh_CN": "如果您在设置中有某些 LDN 口令则可加入此游戏。", "zh_CN": "如果您在设置中有某些 LDN 口令则可加入此游戏。",
"zh_TW": "" "zh_TW": "你只能加入與 LDN 網路密碼片語 (passphrase) 設定相同的遊戲。"
} }
} }
] ]

View File

@@ -1450,6 +1450,7 @@
0100F7300ED2C000,"Hoggy2",,playable,2022-10-10 13:53:35 0100F7300ED2C000,"Hoggy2",,playable,2022-10-10 13:53:35
0100F7E00C70E000,"Hogwarts Legacy",UE4;slow,ingame,2024-09-03 19:53:58 0100F7E00C70E000,"Hogwarts Legacy",UE4;slow,ingame,2024-09-03 19:53:58
0100633007D48000,"Hollow Knight",nvdec,playable,2023-01-16 15:44:56 0100633007D48000,"Hollow Knight",nvdec,playable,2023-01-16 15:44:56
010013C00E930000,"Hollow Knight: Silksong",,playable,2025-09-04 17:23:22
0100F2100061E800,"Hollow0",UE4;gpu,ingame,2021-03-03 23:42:56 0100F2100061E800,"Hollow0",UE4;gpu,ingame,2021-03-03 23:42:56
0100342009E16000,"Holy Potatoes! What The Hell?!",,playable,2020-07-03 10:48:56 0100342009E16000,"Holy Potatoes! What The Hell?!",,playable,2020-07-03 10:48:56
010071B00C904000,"HoPiKo",,playable,2021-01-13 20:12:38 010071B00C904000,"HoPiKo",,playable,2021-01-13 20:12:38
1 title_id game_name labels status last_updated
1450 0100F7300ED2C000 Hoggy2 playable 2022-10-10 13:53:35
1451 0100F7E00C70E000 Hogwarts Legacy UE4;slow ingame 2024-09-03 19:53:58
1452 0100633007D48000 Hollow Knight nvdec playable 2023-01-16 15:44:56
1453 010013C00E930000 Hollow Knight: Silksong playable 2025-09-04 17:23:22
1454 0100F2100061E800 Hollow0 UE4;gpu ingame 2021-03-03 23:42:56
1455 0100342009E16000 Holy Potatoes! What The Hell?! playable 2020-07-03 10:48:56
1456 010071B00C904000 HoPiKo playable 2021-01-13 20:12:38

View File

@@ -182,6 +182,7 @@ namespace Ryujinx.Common
"01001cc01b2d4000", // Goat Simulator 3 "01001cc01b2d4000", // Goat Simulator 3
"01003620068ea000", // Hand of Fate 2 "01003620068ea000", // Hand of Fate 2
"0100f7e00c70e000", // Hogwarts Legacy "0100f7e00c70e000", // Hogwarts Legacy
"010013c00e930000", // Hollow Knight: Silksong
"010085500130a000", // Lego City: Undercover "010085500130a000", // Lego City: Undercover
"010073c01af34000", // LEGO Horizon Adventures "010073c01af34000", // LEGO Horizon Adventures
"0100d71004694000", // Minecraft "0100d71004694000", // Minecraft

View File

@@ -501,53 +501,13 @@ namespace Ryujinx.HLE.FileSystem
using FileStream file = File.OpenRead(keysSource); using FileStream file = File.OpenRead(keysSource);
switch (info.Extension) if (info.Extension is ".keys")
{ {
case ".zip": VerifyKeysFile(keysSource);
using (ZipArchive archive = ZipFile.OpenRead(keysSource)) File.Copy(keysSource, Path.Combine(installDirectory, info.Name), true);
{ }
InstallKeysFromZip(archive, installDirectory); else
} throw new InvalidFirmwarePackageException("Input file is not a valid key package");
break;
case ".keys":
VerifyKeysFile(keysSource);
File.Copy(keysSource, Path.Combine(installDirectory, info.Name), true);
break;
default:
throw new InvalidFirmwarePackageException("Input file is not a valid key package");
}
}
private static void InstallKeysFromZip(ZipArchive archive, string installDirectory)
{
string temporaryDirectory = Path.Combine(installDirectory, "temp");
if (Directory.Exists(temporaryDirectory))
{
Directory.Delete(temporaryDirectory, true);
}
Directory.CreateDirectory(temporaryDirectory);
foreach (ZipArchiveEntry entry in archive.Entries)
{
if (Path.GetExtension(entry.FullName).Equals(".keys", StringComparison.OrdinalIgnoreCase))
{
string extractDestination = Path.Combine(temporaryDirectory, entry.Name);
entry.ExtractToFile(extractDestination, overwrite: true);
try
{
VerifyKeysFile(extractDestination);
File.Move(extractDestination, Path.Combine(installDirectory, entry.Name), true);
}
catch (Exception)
{
Directory.Delete(temporaryDirectory, true);
throw;
}
}
}
Directory.Delete(temporaryDirectory, true);
} }
private void FinishInstallation(string temporaryDirectory, string registeredDirectory) private void FinishInstallation(string temporaryDirectory, string registeredDirectory)

View File

@@ -31,11 +31,13 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
private readonly KEvent _friendInvitationStorageChannelEvent; private readonly KEvent _friendInvitationStorageChannelEvent;
private readonly KEvent _notificationStorageChannelEvent; private readonly KEvent _notificationStorageChannelEvent;
private readonly KEvent _healthWarningDisappearedSystemEvent; private readonly KEvent _healthWarningDisappearedSystemEvent;
private readonly KEvent _unknownEvent;
private int _gpuErrorDetectedSystemEventHandle; private int _gpuErrorDetectedSystemEventHandle;
private int _friendInvitationStorageChannelEventHandle; private int _friendInvitationStorageChannelEventHandle;
private int _notificationStorageChannelEventHandle; private int _notificationStorageChannelEventHandle;
private int _healthWarningDisappearedSystemEventHandle; private int _healthWarningDisappearedSystemEventHandle;
private int _unknownEventHandle;
private bool _gamePlayRecordingState; private bool _gamePlayRecordingState;
@@ -50,6 +52,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
_friendInvitationStorageChannelEvent = new KEvent(system.KernelContext); _friendInvitationStorageChannelEvent = new KEvent(system.KernelContext);
_notificationStorageChannelEvent = new KEvent(system.KernelContext); _notificationStorageChannelEvent = new KEvent(system.KernelContext);
_healthWarningDisappearedSystemEvent = new KEvent(system.KernelContext); _healthWarningDisappearedSystemEvent = new KEvent(system.KernelContext);
_unknownEvent = new KEvent(system.KernelContext);
_horizon = system.LibHacHorizonManager.AmClient; _horizon = system.LibHacHorizonManager.AmClient;
} }
@@ -647,6 +650,23 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.Applicati
return ResultCode.Success; return ResultCode.Success;
} }
[CommandCmif(210)] // 20.0.0+
// GetUnknownEvent() -> handle<copy>
public ResultCode GetUnknownEvent(ServiceCtx context)
{
if (_unknownEventHandle == 0)
{
if (context.Process.HandleTable.GenerateHandle(_unknownEvent.ReadableEvent, out _unknownEventHandle) != Result.Success)
{
throw new InvalidOperationException("Out of handles!");
}
}
context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_unknownEventHandle);
return ResultCode.Success;
}
[CommandCmif(1001)] // 10.0.0+ [CommandCmif(1001)] // 10.0.0+
// PrepareForJit() // PrepareForJit()

View File

@@ -39,9 +39,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
public ref AtomicStorage<T> GetCurrentAtomicEntryRef() public ref AtomicStorage<T> GetCurrentAtomicEntryRef()
{ {
ulong countAvailaible = Math.Min(Math.Max(0, ReadCurrentCount()), 1); ulong countAvailable = Math.Min(Math.Max(0, ReadCurrentCount()), 1);
if (countAvailaible == 0) if (countAvailable == 0)
{ {
_storage[0] = default; _storage[0] = default;
@@ -54,7 +54,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
while (true) while (true)
{ {
int inputEntryIndex = (int)((index + MaxEntries + 1 - countAvailaible) % MaxEntries); int inputEntryIndex = (int)((index + MaxEntries + 1 - countAvailable) % MaxEntries);
ref AtomicStorage<T> result = ref storageSpan[inputEntryIndex]; ref AtomicStorage<T> result = ref storageSpan[inputEntryIndex];
@@ -63,9 +63,9 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Common
if (samplingNumber0 != samplingNumber1 && (result.SamplingNumber - result.SamplingNumber) != 1) if (samplingNumber0 != samplingNumber1 && (result.SamplingNumber - result.SamplingNumber) != 1)
{ {
ulong tempCount = Math.Min(ReadCurrentCount(), countAvailaible); ulong tempCount = Math.Min(ReadCurrentCount(), countAvailable);
countAvailaible = Math.Min(tempCount, 1); countAvailable = Math.Min(tempCount, 1);
index = ReadCurrentIndex(); index = ReadCurrentIndex();
continue; continue;

View File

@@ -0,0 +1,23 @@
namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
{
struct NpadCondition
{
#pragma warning disable CS0414 // Field is assigned but its value is never used
private uint _00;
private uint _04;
private NpadJoyHoldType _holdType;
private uint _0C;
#pragma warning restore CS0414 // Field is assigned but its value is never used
public static NpadCondition Create()
{
return new NpadCondition()
{
_00 = 0,
_04 = 1,
_holdType = NpadJoyHoldType.Horizontal,
_0C = 1,
};
}
}
}

View File

@@ -41,6 +41,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory.Npad
public NpadLarkType LarkTypeRight; public NpadLarkType LarkTypeRight;
public NpadLuciaType LuciaType; public NpadLuciaType LuciaType;
public uint Unknown43EC; public uint Unknown43EC;
public ulong SixAxisSensorPropertiesArray;
[StructLayout(LayoutKind.Sequential, Size = 123, Pack = 1)] [StructLayout(LayoutKind.Sequential, Size = 123, Pack = 1)]
private struct Reserved2Struct { } private struct Reserved2Struct { }

View File

@@ -52,6 +52,12 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory
/// </summary> /// </summary>
[FieldOffset(0x3DC00)] [FieldOffset(0x3DC00)]
public RingLifo<DebugMouseState> DebugMouse; public RingLifo<DebugMouseState> DebugMouse;
/// <summary>
/// Pad Condition.
/// </summary>
[FieldOffset(0x3e200)]
public NpadCondition Condition;
public static SharedMemory Create() public static SharedMemory Create()
{ {
@@ -61,6 +67,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Types.SharedMemory
TouchScreen = RingLifo<TouchScreenState>.Create(), TouchScreen = RingLifo<TouchScreenState>.Create(),
Mouse = RingLifo<MouseState>.Create(), Mouse = RingLifo<MouseState>.Create(),
Keyboard = RingLifo<KeyboardState>.Create(), Keyboard = RingLifo<KeyboardState>.Create(),
Condition = NpadCondition.Create(),
}; };
Span<NpadState> npadsSpan = result.Npads.AsSpan(); Span<NpadState> npadsSpan = result.Npads.AsSpan();

View File

@@ -1,6 +1,5 @@
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading; using Avalonia.Threading;
using Gommon;
using LibHac; using LibHac;
using LibHac.Account; using LibHac.Account;
using LibHac.Common; using LibHac.Common;
@@ -411,7 +410,7 @@ namespace Ryujinx.Ava.Common
public static async Task ExtractAoc(IStorageProvider storageProvider, string updateFilePath, string updateName) public static async Task ExtractAoc(IStorageProvider storageProvider, string updateFilePath, string updateName)
{ {
Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions Gommon.Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
{ {
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle] Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle]
}); });
@@ -424,7 +423,7 @@ namespace Ryujinx.Ava.Common
public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0) public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
{ {
Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions Gommon.Optional<IStorageFolder> result = await storageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
{ {
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle] Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle]
}); });

View File

@@ -1045,7 +1045,7 @@ namespace Ryujinx.Ava.Systems
_viewModel.Window.TitleBar.ExtendsContentIntoTitleBar = true; _viewModel.Window.TitleBar.ExtendsContentIntoTitleBar = true;
} }
if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUI) if (_viewModel.WindowState is WindowState.FullScreen || _viewModel.StartGamesWithoutUi)
{ {
_viewModel.ShowMenuAndStatusBar = false; _viewModel.ShowMenuAndStatusBar = false;
} }

View File

@@ -117,7 +117,7 @@ namespace Ryujinx.Ava.Systems.AppLibrary
using UniqueRef<IFile> npdmFile = new(); using UniqueRef<IFile> npdmFile = new();
Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read); LibHac.Result result = pfs.OpenFile(ref npdmFile.Ref, "/main.npdm".ToU8Span(), OpenMode.Read);
if (ResultFs.PathNotFound.Includes(result)) if (ResultFs.PathNotFound.Includes(result))
{ {

View File

@@ -97,8 +97,10 @@ namespace Ryujinx.Ava.Systems.PlayReport
//TODO DLC Locations //TODO DLC Locations
_ => FormattedValue.ForceReset _ => FormattedValue.ForceReset
}; };
return $"{playStatus} in {locations}"; return locations.Reset
? FormattedValue.ForceReset
: $"{playStatus} in {locations}";
} }
private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values) private static FormattedValue SuperSmashBrosUltimate_Mode(SparseMultiValue values)

View File

@@ -7,6 +7,7 @@ using Ryujinx.Common.Logging;
using Ryujinx.Systems.Update.Client; using Ryujinx.Systems.Update.Client;
using Ryujinx.Systems.Update.Common; using Ryujinx.Systems.Update.Common;
using System; using System;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Ryujinx.Ava.Systems namespace Ryujinx.Ava.Systems
@@ -14,16 +15,38 @@ namespace Ryujinx.Ava.Systems
internal static partial class Updater internal static partial class Updater
{ {
private static VersionResponse _versionResponse; private static VersionResponse _versionResponse;
private static UpdateClient _updateClient;
private static UpdateClient CreateUpdateClient() private static async Task<Return<VersionResponse>> QueryLatestVersionAsync()
=> UpdateClient.Builder() {
_updateClient ??= UpdateClient.Builder()
.WithServerEndpoint("https://update.ryujinx.app") // This is the default, and doesn't need to be provided; it's here for transparency. .WithServerEndpoint("https://update.ryujinx.app") // This is the default, and doesn't need to be provided; it's here for transparency.
.WithLogger((format, args, caller) => .WithLogger((format, args, caller) =>
Logger.Info?.Print( Logger.Info?.Print(
LogClass.Application, LogClass.Application,
args.Length is 0 ? format : format.Format(args), args.Length is 0 ? format : format.Format(args),
caller: caller) caller: caller)
); );
try
{
return await _updateClient.QueryLatestAsync(ReleaseInformation.IsCanaryBuild
? ReleaseChannel.Canary
: ReleaseChannel.Stable);
}
catch (HttpRequestException hre)
when (hre.HttpRequestError is HttpRequestError.ConnectionError)
{
return Return<VersionResponse>.Failure(
new MessageError("Connection error occurred. Is your internet down?"));
}
catch (HttpRequestException hre)
when (hre.HttpRequestError is HttpRequestError.NameResolutionError)
{
return Return<VersionResponse>.Failure(
new MessageError("DNS resolution error occurred. Is your internet down?"));
}
}
public static async Task<Optional<(Version Current, Version Incoming)>> CheckVersionAsync(bool showVersionUpToDate = false) public static async Task<Optional<(Version Current, Version Incoming)>> CheckVersionAsync(bool showVersionUpToDate = false)
{ {
@@ -41,22 +64,18 @@ namespace Ryujinx.Ava.Systems
return default; return default;
} }
using UpdateClient updateClient = CreateUpdateClient();
try try
{ {
_versionResponse = await updateClient.QueryLatestAsync(ReleaseInformation.IsCanaryBuild _versionResponse = await QueryLatestVersionAsync().Then(x => x.Unwrap());
? ReleaseChannel.Canary
: ReleaseChannel.Stable);
} }
catch (Exception e) catch (Exception e)
{ {
Logger.Error?.Print(LogClass.Application, $"An error occurred when requesting for updates ({e.GetType().AsFullNamePrettyString()}): {e.Message}"); Logger.Error?.Print(LogClass.Application, $"{e.GetType().AsPrettyString()} thrown when requesting updates: {e.Message}");
_running = false; _running = false;
return default; return default;
} }
if (_versionResponse == null) if (_versionResponse == null)
{ {
// logging is done via the UpdateClient library // logging is done via the UpdateClient library

View File

@@ -562,7 +562,7 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public bool StartGamesWithoutUI public bool StartGamesWithoutUi
{ {
get => ConfigurationState.Instance.UI.StartNoUI; get => ConfigurationState.Instance.UI.StartNoUI;
set set
@@ -974,9 +974,8 @@ namespace Ryujinx.Ava.UI.ViewModels
string dialogTitle = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallTitle); string dialogTitle = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallTitle);
string dialogMessage = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallMessage); string dialogMessage = LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallMessage);
bool alreadyKesyInstalled = ContentManager.AreKeysAlredyPresent(systemDirectory); if (ContentManager.AreKeysAlredyPresent(systemDirectory))
if (alreadyKesyInstalled)
{ {
dialogMessage += LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallSubMessage); dialogMessage += LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogKeysInstallerKeysInstallSubMessage);
} }
@@ -994,7 +993,7 @@ namespace Ryujinx.Ava.UI.ViewModels
if (result == UserResult.Yes) if (result == UserResult.Yes)
{ {
Logger.Info?.Print(LogClass.Application, $"Installing Keys"); Logger.Info?.Print(LogClass.Application, $"Installing keys from {filename}");
Thread thread = new(() => Thread thread = new(() =>
{ {
@@ -1206,15 +1205,14 @@ namespace Ryujinx.Ava.UI.ViewModels
private async Task LoadContentFromFolder(LocaleKeys localeMessageAddedKey, LocaleKeys localeMessageRemovedKey, LoadContentFromFolderDelegate onDirsSelected, LocaleKeys dirSelectDialogTitle) private async Task LoadContentFromFolder(LocaleKeys localeMessageAddedKey, LocaleKeys localeMessageRemovedKey, LoadContentFromFolderDelegate onDirsSelected, LocaleKeys dirSelectDialogTitle)
{ {
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions Optional<IReadOnlyList<IStorageFolder>> result = await StorageProvider.OpenMultiFolderPickerAsync(new FolderPickerOpenOptions
{ {
Title = LocaleManager.Instance[dirSelectDialogTitle], Title = LocaleManager.Instance[dirSelectDialogTitle]
AllowMultiple = true,
}); });
if (result.Count > 0) if (result.TryGet(out IReadOnlyList<IStorageFolder> foldersToLoad))
{ {
List<string> dirs = result.Select(it => it.Path.LocalPath).ToList(); List<string> dirs = foldersToLoad.Select(it => it.Path.LocalPath).ToList();
int numAdded = onDirsSelected(dirs, out int numRemoved); int numAdded = onDirsSelected(dirs, out int numRemoved);
string msg = string.Join("\n", string msg = string.Join("\n",
@@ -1270,51 +1268,26 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
public void TakeScreenshot() public void TakeScreenshot() => AppHost.ScreenshotRequested = true;
{
AppHost.ScreenshotRequested = true;
}
public void HideUi() public void HideUi() => ShowMenuAndStatusBar = false;
{
ShowMenuAndStatusBar = false;
}
public void ToggleStartGamesInFullscreen() public void ToggleStartGamesInFullscreen() => StartGamesInFullscreen = !StartGamesInFullscreen;
{
StartGamesInFullscreen = !StartGamesInFullscreen;
}
public void ToggleStartGamesWithoutUI() public void ToggleStartGamesWithoutUi() => StartGamesWithoutUi = !StartGamesWithoutUi;
{
StartGamesWithoutUI = !StartGamesWithoutUI;
}
public void ToggleShowConsole() public void ToggleShowConsole() => ShowConsole = !ShowConsole;
{
ShowConsole = !ShowConsole;
}
public void SetListMode() public void SetListMode() => Glyph = Glyph.List;
{
Glyph = Glyph.List;
}
public void SetGridMode() public void SetGridMode() => Glyph = Glyph.Grid;
{
Glyph = Glyph.Grid;
}
public void SetAspectRatio(AspectRatio aspectRatio) public void SetAspectRatio(AspectRatio aspectRatio) => ConfigurationState.Instance.Graphics.AspectRatio.Value = aspectRatio;
{
ConfigurationState.Instance.Graphics.AspectRatio.Value = aspectRatio;
}
public async Task InstallFirmwareFromFile() public async Task InstallFirmwareFromFile()
{ {
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
{ {
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType> FileTypeFilter = new List<FilePickerFileType>
{ {
new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes]) new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes])
@@ -1338,69 +1311,50 @@ namespace Ryujinx.Ava.UI.ViewModels
}, },
}); });
if (result.Count > 0) if (result.HasValue)
{ {
await HandleFirmwareInstallation(result[0].Path.LocalPath); await HandleFirmwareInstallation(result.Value.Path.LocalPath);
} }
} }
public async Task InstallFirmwareFromFolder() public async Task InstallFirmwareFromFolder()
{ {
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync();
{
AllowMultiple = false,
});
if (result.Count > 0) if (result.HasValue)
{ {
await HandleFirmwareInstallation(result[0].Path.LocalPath); await HandleFirmwareInstallation(result.Value.Path.LocalPath);
} }
} }
public async Task InstallKeysFromFile() public async Task InstallKeysFromFile()
{ {
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
{ {
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType> FileTypeFilter = new List<FilePickerFileType>
{ {
new(LocaleManager.Instance[LocaleKeys.FileDialogAllTypes])
{
Patterns = ["*.keys", "*.zip"],
AppleUniformTypeIdentifiers = ["com.ryujinx.xci", "public.zip-archive"],
MimeTypes = ["application/keys", "application/zip"],
},
new("KEYS") new("KEYS")
{ {
Patterns = ["*.keys"], Patterns = ["*.keys"],
AppleUniformTypeIdentifiers = ["com.ryujinx.xci"], AppleUniformTypeIdentifiers = ["com.ryujinx.xci"],
MimeTypes = ["application/keys"], MimeTypes = ["application/keys"],
}, },
new("ZIP")
{
Patterns = ["*.zip"],
AppleUniformTypeIdentifiers = ["public.zip-archive"],
MimeTypes = ["application/zip"],
},
}, },
}); });
if (result.Count > 0) if (result.HasValue)
{ {
await HandleKeysInstallation(result[0].Path.LocalPath); await HandleKeysInstallation(result.Value.Path.LocalPath);
} }
} }
public async Task InstallKeysFromFolder() public async Task InstallKeysFromFolder()
{ {
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync();
{
AllowMultiple = false,
});
if (result.Count > 0) if (result.HasValue)
{ {
await HandleKeysInstallation(result[0].Path.LocalPath); await HandleKeysInstallation(result.Value.Path.LocalPath);
} }
} }
@@ -1503,10 +1457,9 @@ namespace Ryujinx.Ava.UI.ViewModels
public async Task OpenFile() public async Task OpenFile()
{ {
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
{ {
Title = LocaleManager.Instance[LocaleKeys.LoadApplicationFromFileDialogTitle], Title = LocaleManager.Instance[LocaleKeys.LoadApplicationFromFileDialogTitle],
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType> FileTypeFilter = new List<FilePickerFileType>
{ {
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats]) new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
@@ -1562,9 +1515,9 @@ namespace Ryujinx.Ava.UI.ViewModels
}, },
}); });
if (result.Count > 0) if (result.HasValue)
{ {
if (ApplicationLibrary.TryGetApplicationsFromFile(result[0].Path.LocalPath, if (ApplicationLibrary.TryGetApplicationsFromFile(result.Value.Path.LocalPath,
out List<ApplicationData> applications)) out List<ApplicationData> applications))
{ {
await LoadApplication(applications[0]); await LoadApplication(applications[0]);
@@ -1596,18 +1549,17 @@ namespace Ryujinx.Ava.UI.ViewModels
public async Task OpenFolder() public async Task OpenFolder()
{ {
IReadOnlyList<IStorageFolder> result = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions Optional<IStorageFolder> result = await StorageProvider.OpenSingleFolderPickerAsync(new FolderPickerOpenOptions
{ {
Title = LocaleManager.Instance[LocaleKeys.LoadUnpackedGameFromFolderDialogTitle], Title = LocaleManager.Instance[LocaleKeys.LoadUnpackedGameFromFolderDialogTitle]
AllowMultiple = false,
}); });
if (result.Count > 0) if (result.TryGet(out IStorageFolder value))
{ {
ApplicationData applicationData = new() ApplicationData applicationData = new()
{ {
Name = Path.GetFileNameWithoutExtension(result[0].Path.LocalPath), Name = Path.GetFileNameWithoutExtension(value.Path.LocalPath),
Path = result[0].Path.LocalPath, Path = value.Path.LocalPath,
}; };
await LoadApplication(applicationData); await LoadApplication(applicationData);
@@ -1812,10 +1764,9 @@ namespace Ryujinx.Ava.UI.ViewModels
{ {
if (AppHost.Device.System.SearchingForAmiibo(out _) && IsGameRunning) if (AppHost.Device.System.SearchingForAmiibo(out _) && IsGameRunning)
{ {
IReadOnlyList<IStorageFile> result = await StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions Optional<IStorageFile> result = await StorageProvider.OpenSingleFilePickerAsync(new FilePickerOpenOptions
{ {
Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle], Title = LocaleManager.Instance[LocaleKeys.OpenFileDialogTitle],
AllowMultiple = false,
FileTypeFilter = new List<FilePickerFileType> FileTypeFilter = new List<FilePickerFileType>
{ {
new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats]) new(LocaleManager.Instance[LocaleKeys.AllSupportedFormats])
@@ -1824,9 +1775,10 @@ namespace Ryujinx.Ava.UI.ViewModels
} }
} }
}); });
if (result.Count > 0)
if (result.HasValue)
{ {
AppHost.Device.System.ScanAmiiboFromBin(result[0].Path.LocalPath); AppHost.Device.System.ScanAmiiboFromBin(result.Value.Path.LocalPath);
} }
} }
} }

View File

@@ -92,14 +92,14 @@
</MenuItem> </MenuItem>
<MenuItem <MenuItem
Padding="0" Padding="0"
Command="{Binding ToggleStartGamesWithoutUI}" Command="{Binding ToggleStartGamesWithoutUi}"
Header="{ext:Locale MenuBarOptionsStartGamesWithoutUI}" Header="{ext:Locale MenuBarOptionsStartGamesWithoutUI}"
Classes="withCheckbox"> Classes="withCheckbox">
<MenuItem.Icon> <MenuItem.Icon>
<CheckBox <CheckBox
MinWidth="{DynamicResource CheckBoxSize}" MinWidth="{DynamicResource CheckBoxSize}"
MinHeight="{DynamicResource CheckBoxSize}" MinHeight="{DynamicResource CheckBoxSize}"
IsChecked="{Binding StartGamesWithoutUI, Mode=TwoWay}" IsChecked="{Binding StartGamesWithoutUi, Mode=TwoWay}"
Padding="0" /> Padding="0" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>