0
0
Fork 0
mirror of https://github.com/GreemDev/Ryujinx.git synced 2024-12-22 18:05:46 +00:00

UI: Extract the 256x256 thumbnail too when extracting the logo.

This commit is contained in:
Evan Husted 2024-10-10 21:39:50 -05:00
parent 17e259b90e
commit 335eed75ef
2 changed files with 45 additions and 23 deletions

View file

@ -141,20 +141,8 @@ namespace Ryujinx.Ava.Common
} }
} }
public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0) public static void ExtractSection(string destination, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
{ {
var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
AllowMultiple = false,
});
if (result.Count == 0)
{
return;
}
var destination = result[0].Path.LocalPath;
var cancellationToken = new CancellationTokenSource(); var cancellationToken = new CancellationTokenSource();
UpdateWaitWindow waitingDialog = new( UpdateWaitWindow waitingDialog = new(
@ -172,11 +160,11 @@ namespace Ryujinx.Ava.Common
Nca patchNca = null; Nca patchNca = null;
string extension = Path.GetExtension(titleFilePath).ToLower(); string extension = Path.GetExtension(titleFilePath).ToLower();
if (extension == ".nsp" || extension == ".pfs0" || extension == ".xci") if (extension is ".nsp" or ".pfs0" or ".xci")
{ {
IFileSystem pfs; IFileSystem pfs;
if (extension == ".xci") if (extension is ".xci")
{ {
pfs = new Xci(_virtualFileSystem.KeySet, file.AsStorage()).OpenPartition(XciPartitionType.Secure); pfs = new Xci(_virtualFileSystem.KeySet, file.AsStorage()).OpenPartition(XciPartitionType.Secure);
} }
@ -194,7 +182,7 @@ namespace Ryujinx.Ava.Common
pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure(); pfs.OpenFile(ref ncaFile.Ref, fileEntry.FullPath.ToU8Span(), OpenMode.Read).ThrowIfFailure();
Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage()); Nca nca = new(_virtualFileSystem.KeySet, ncaFile.Get.AsStorage());
if (nca.Header.ContentType == NcaContentType.Program) if (nca.Header.ContentType is NcaContentType.Program)
{ {
int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program); int dataIndex = Nca.GetSectionIndexFromType(NcaSectionType.Data, NcaContentType.Program);
if (nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection()) if (nca.SectionExists(NcaSectionType.Data) && nca.Header.GetFsHeader(dataIndex).IsPatchSection())
@ -208,12 +196,12 @@ namespace Ryujinx.Ava.Common
} }
} }
} }
else if (extension == ".nca") else if (extension is ".nca")
{ {
mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage()); mainNca = new Nca(_virtualFileSystem.KeySet, file.AsStorage());
} }
if (mainNca == null) if (mainNca is null)
{ {
Logger.Error?.Print(LogClass.Application, "Extraction failure. The main NCA was not present in the selected file"); Logger.Error?.Print(LogClass.Application, "Extraction failure. The main NCA was not present in the selected file");
@ -232,7 +220,7 @@ namespace Ryujinx.Ava.Common
: IntegrityCheckLevel.None; : IntegrityCheckLevel.None;
(Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, checkLevel, programIndex, out _); (Nca updatePatchNca, _) = mainNca.GetUpdateData(_virtualFileSystem, checkLevel, programIndex, out _);
if (updatePatchNca != null) if (updatePatchNca is not null)
{ {
patchNca = updatePatchNca; patchNca = updatePatchNca;
} }
@ -242,7 +230,7 @@ namespace Ryujinx.Ava.Common
try try
{ {
bool sectionExistsInPatch = false; bool sectionExistsInPatch = false;
if (patchNca != null) if (patchNca is not null)
{ {
sectionExistsInPatch = patchNca.CanOpenSection(index); sectionExistsInPatch = patchNca.CanOpenSection(index);
} }
@ -309,6 +297,23 @@ namespace Ryujinx.Ava.Common
extractorThread.Start(); extractorThread.Start();
} }
public static async Task ExtractSection(IStorageProvider storageProvider, NcaSectionType ncaSectionType, string titleFilePath, string titleName, int programIndex = 0)
{
var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
AllowMultiple = false,
});
if (result.Count == 0)
{
return;
}
ExtractSection(result[0].Path.LocalPath, ncaSectionType, titleFilePath, titleName, programIndex);
}
public static (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath, CancellationToken token) public static (Result? result, bool canceled) CopyDirectory(FileSystemClient fs, string sourcePath, string destPath, CancellationToken token)
{ {
Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All); Result rc = fs.OpenDirectory(out DirectoryHandle sourceHandle, sourcePath.ToU8Span(), OpenDirectoryMode.All);

View file

@ -1,6 +1,7 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Platform.Storage;
using LibHac.Fs; using LibHac.Fs;
using LibHac.Tools.FsSystem.NcaUtils; using LibHac.Tools.FsSystem.NcaUtils;
using Ryujinx.Ava.Common; using Ryujinx.Ava.Common;
@ -325,13 +326,29 @@ namespace Ryujinx.Ava.UI.Controls
{ {
var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel; var viewModel = (sender as MenuItem)?.DataContext as MainWindowViewModel;
if (viewModel?.SelectedApplication != null) if (viewModel?.SelectedApplication is { } selectedApp)
{ {
await ApplicationHelper.ExtractSection( var result = await viewModel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
viewModel.StorageProvider, {
Title = LocaleManager.Instance[LocaleKeys.FolderDialogExtractTitle],
AllowMultiple = false,
});
if (result.Count == 0)
{
return;
}
ApplicationHelper.ExtractSection(
result[0].Path.LocalPath,
NcaSectionType.Logo, NcaSectionType.Logo,
viewModel.SelectedApplication.Path, viewModel.SelectedApplication.Path,
viewModel.SelectedApplication.Name); viewModel.SelectedApplication.Name);
var iconFile = await result[0].CreateFileAsync(selectedApp.IdString + ".png");
await using var fileStream = await iconFile.OpenWriteAsync();
fileStream.Write(selectedApp.Icon);
} }
} }