removal: Installing keys from a zip

Also cleaned up a bit
This commit is contained in:
GreemDev
2025-09-04 19:04:50 -05:00
parent 6084df7473
commit ded76801d1
5 changed files with 63 additions and 151 deletions

View File

@@ -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"
} }
}, },
{ {

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

@@ -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

@@ -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>