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:
parent
17e259b90e
commit
335eed75ef
2 changed files with 45 additions and 23 deletions
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue