Просмотр исходного кода

UI: Move DLC RomFS dumping under normal RomFS dumping.
Also removed it from DLC manager.

Evan Husted 1 год назад
Родитель
Сommit
04ba762710

+ 76 - 1
src/Ryujinx/Assets/locales.json

@@ -2297,6 +2297,56 @@
         "zh_TW": "從應用程式的目前配置中提取 RomFS 分區 (包含更新)"
       }
     },
+    {
+      "ID": "GameListContextMenuExtractDataAocRomFS",
+      "Translations": {
+        "ar_SA": "",
+        "de_DE": "",
+        "el_GR": "",
+        "en_US": "DLC RomFS",
+        "es_ES": "",
+        "fr_FR": "RomFS de DLC",
+        "he_IL": "",
+        "it_IT": "",
+        "ja_JP": "",
+        "ko_KR": "",
+        "no_NO": "",
+        "pl_PL": "",
+        "pt_BR": "",
+        "ru_RU": "",
+        "sv_SE": "",
+        "th_TH": "",
+        "tr_TR": "",
+        "uk_UA": "",
+        "zh_CN": "",
+        "zh_TW": ""
+      }
+    },
+    {
+      "ID": "GameListContextMenuExtractDataAocRomFSToolTip",
+      "Translations": {
+        "ar_SA": "",
+        "de_DE": "",
+        "el_GR": "",
+        "en_US": "Extract the RomFS from a selected DLC file",
+        "es_ES": "",
+        "fr_FR": "Extraire les RomFS d'un fichier DLC choisi",
+        "he_IL": "",
+        "it_IT": "",
+        "ja_JP": "",
+        "ko_KR": "",
+        "no_NO": "",
+        "pl_PL": "",
+        "pt_BR": "",
+        "ru_RU": "",
+        "sv_SE": "",
+        "th_TH": "",
+        "tr_TR": "",
+        "uk_UA": "",
+        "zh_CN": "",
+        "zh_TW": ""
+      }
+    },
     {
       "ID": "GameListContextMenuExtractDataLogo",
       "Translations": {
@@ -22896,6 +22946,31 @@
         "zh_CN": "什么都没有",
         "zh_TW": "無法啟動 (Nothing)"
       }
+    },
+    {
+      "ID": "ExtractAocListHeader",
+      "Translations": {
+        "ar_SA": "",
+        "de_DE": "",
+        "el_GR": "",
+        "en_US": "Select a DLC to Extract",
+        "es_ES": "",
+        "fr_FR": "Choisissez un DLC à extraire",
+        "he_IL": "",
+        "it_IT": "",
+        "ja_JP": "",
+        "ko_KR": "",
+        "no_NO": "",
+        "pl_PL": "",
+        "pt_BR": "",
+        "ru_RU": "",
+        "sv_SE": "",
+        "th_TH": "",
+        "tr_TR": "",
+        "uk_UA": "",
+        "zh_CN": "",
+        "zh_TW": ""
+      }
     }
   ]
-}
+}

+ 6 - 7
src/Ryujinx/Common/ApplicationHelper.cs

@@ -296,13 +296,13 @@ namespace Ryujinx.Ava.Common
             extractorThread.Start();
         }
         
-        public static void ExtractAoc(string destination, NcaSectionType ncaSectionType, string updateFilePath, string updateName)
+        public static void ExtractAoc(string destination, string updateFilePath, string updateName)
         {
             var cancellationToken = new CancellationTokenSource();
 
             UpdateWaitWindow waitingDialog = new(
                 RyujinxApp.FormatTitle(LocaleKeys.DialogNcaExtractionTitle),
-                LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, ncaSectionType, Path.GetFileName(updateFilePath)),
+                LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogNcaExtractionMessage, NcaSectionType.Data, Path.GetFileName(updateFilePath)),
                 cancellationToken);
 
             Thread extractorThread = new(() =>
@@ -352,7 +352,7 @@ namespace Ryujinx.Ava.Common
                     ? IntegrityCheckLevel.ErrorOnInvalid
                     : IntegrityCheckLevel.None;
 
-                int index = Nca.GetSectionIndexFromType(ncaSectionType, publicDataNca.Header.ContentType);
+                int index = Nca.GetSectionIndexFromType(NcaSectionType.Data, publicDataNca.Header.ContentType);
 
                 try
                 {
@@ -410,14 +410,13 @@ namespace Ryujinx.Ava.Common
                 }
             })
             {
-                Name = "GUI.NcaSectionExtractorThread",
+                Name = "GUI.AocExtractorThread",
                 IsBackground = true,
             };
             extractorThread.Start();
         }
 
-        public static async Task ExtractAoc(IStorageProvider storageProvider, NcaSectionType ncaSectionType,
-            string updateFilePath, string updateName)
+        public static async Task ExtractAoc(IStorageProvider storageProvider, string updateFilePath, string updateName)
         {
             var result = await storageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
             {
@@ -430,7 +429,7 @@ namespace Ryujinx.Ava.Common
                 return;
             }
 
-            ExtractAoc(result[0].Path.LocalPath, ncaSectionType, updateFilePath, updateName);
+            ExtractAoc(result[0].Path.LocalPath, updateFilePath, updateName);
         }
 
 

+ 1 - 1
src/Ryujinx/Common/Models/DownloadableContentModel.cs

@@ -6,7 +6,7 @@ namespace Ryujinx.Ava.Common.Models
         public bool IsBundled { get; } = System.IO.Path.GetExtension(ContainerPath)?.ToLower() == ".xci";
 
         public string FileName => System.IO.Path.GetFileName(ContainerPath);
-        public string TitleIdStr => TitleId.ToString("x16");
+        public string TitleIdStr => TitleId.ToString("x16").ToUpper();
         public ulong TitleIdBase => TitleId & ~0x1FFFUL;
     }
 }

+ 1 - 6
src/Ryujinx/Ryujinx.csproj

@@ -173,10 +173,5 @@
   <ItemGroup>
     <Folder Include="Assets\Fonts\Mono\" />
   </ItemGroup>
-  <ItemGroup>
-    <Compile Update="UI\Applet\UserSelectorDialog.axaml.cs">
-      <DependentUpon>UserSelectorDialog.axaml</DependentUpon>
-      <SubType>Code</SubType>
-    </Compile>
-  </ItemGroup>
+
 </Project>

+ 4 - 0
src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml

@@ -106,6 +106,10 @@
             Click="ExtractApplicationRomFs_Click"
             Header="{ext:Locale GameListContextMenuExtractDataRomFS}"
             ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataRomFSToolTip}" />
+        <MenuItem
+            Click="ExtractAocRomFs_Click"
+            Header="{ext:Locale GameListContextMenuExtractDataAocRomFS}"
+            ToolTip.Tip="{ext:Locale GameListContextMenuExtractDataAocRomFSToolTip}" />
         <MenuItem
             Click="ExtractApplicationLogo_Click"
             Header="{ext:Locale GameListContextMenuExtractDataLogo}"

+ 20 - 0
src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs

@@ -3,10 +3,13 @@ using Avalonia.Interactivity;
 using Avalonia.Markup.Xaml;
 using Avalonia.Platform.Storage;
 using Avalonia.Threading;
+using FluentAvalonia.UI.Controls;
+using LibHac;
 using LibHac.Fs;
 using LibHac.Tools.FsSystem.NcaUtils;
 using Ryujinx.Ava.Common;
 using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Common.Models;
 using Ryujinx.Ava.UI.Helpers;
 using Ryujinx.Ava.UI.ViewModels;
 using Ryujinx.Ava.UI.Windows;
@@ -14,6 +17,7 @@ using Ryujinx.Ava.Utilities;
 using Ryujinx.Ava.Utilities.AppLibrary;
 using Ryujinx.Common.Configuration;
 using Ryujinx.Common.Helper;
+using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS;
 using SkiaSharp;
 using System;
@@ -279,6 +283,22 @@ namespace Ryujinx.Ava.UI.Controls
                     viewModel.SelectedApplication.Path,
                     viewModel.SelectedApplication.Name);
         }
+        
+        public async void ExtractAocRomFs_Click(object sender, RoutedEventArgs args)
+        {
+            if (sender is not MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel })
+                return;
+
+            DownloadableContentModel selectedDlc = await DlcSelectView.Show(viewModel.SelectedApplication.IdBase, viewModel.ApplicationLibrary);
+            
+            if (selectedDlc is not null)
+            {
+                await ApplicationHelper.ExtractAoc(
+                    viewModel.StorageProvider,
+                    selectedDlc.ContainerPath,
+                    selectedDlc.FileName);
+            }
+        }
 
         public async void ExtractApplicationLogo_Click(object sender, RoutedEventArgs args)
         {

+ 1 - 2
src/Ryujinx/UI/Controls/ApplicationListView.axaml

@@ -2,11 +2,10 @@
     x:Class="Ryujinx.Ava.UI.Controls.ApplicationListView"
     xmlns="https://github.com/avaloniaui"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:controls="clr-namespace:Ryujinx.Ava.UI.Controls"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
+    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     d:DesignHeight="450"
     d:DesignWidth="800"
     Focusable="True"

+ 67 - 0
src/Ryujinx/UI/Controls/DlcSelectView.axaml

@@ -0,0 +1,67 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+             xmlns:helpers="using:Ryujinx.Ava.UI.Helpers"
+             xmlns:ext="using:Ryujinx.Ava.Common.Markup"
+             xmlns:models="using:Ryujinx.Ava.Common.Models"
+             xmlns:viewModels="using:Ryujinx.Ava.UI.ViewModels"
+             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
+             x:Class="Ryujinx.Ava.UI.Controls.DlcSelectView"
+             x:DataType="viewModels:DlcSelectViewModel">
+    <Grid RowDefinitions="*,Auto,*">
+        <TextBlock
+            Classes="h1"
+            Margin="5, -5, 0, 15"
+            HorizontalAlignment="Center"
+            VerticalAlignment="Center"
+            TextWrapping="Wrap"
+            Text="{ext:Locale ExtractAocListHeader}" />
+        <ScrollViewer Grid.Row="2">
+            <ListBox
+                AutoScrollToSelectedItem="False"
+                SelectionMode="Single"
+                Background="Transparent"
+                SelectedItem="{Binding SelectedDlc}"
+                ItemsSource="{Binding Dlcs}">
+                <ListBox.DataTemplates>
+                    <DataTemplate
+                        DataType="models:DownloadableContentModel">
+                        <Panel Margin="10" Background="Transparent">
+                            <Grid ColumnDefinitions="*,Auto">
+                                <Grid
+                                    Grid.Column="0" ColumnDefinitions="*,Auto">
+                                    <TextBlock
+                                        Grid.Column="0"
+                                        HorizontalAlignment="Left"
+                                        VerticalAlignment="Center"
+                                        MaxLines="2"
+                                        TextWrapping="Wrap"
+                                        TextTrimming="CharacterEllipsis">
+                                        <TextBlock.Text>
+                                            <MultiBinding Converter="{x:Static helpers:DownloadableContentLabelConverter.Instance}">
+                                                <Binding Path="FileName" />
+                                                <Binding Path="IsBundled" />
+                                            </MultiBinding>
+                                        </TextBlock.Text>
+                                    </TextBlock>
+                                    <TextBlock
+                                        Grid.Column="1"
+                                        Margin="10, 0, 0, 0"
+                                        HorizontalAlignment="Left"
+                                        VerticalAlignment="Center"
+                                        Text="{Binding TitleIdStr}" />
+                                </Grid>
+                            </Grid>
+                        </Panel>
+                    </DataTemplate>
+                </ListBox.DataTemplates>
+                <ListBox.Styles>
+                    <Style Selector="ListBoxItem">
+                        <Setter Property="Background" Value="Transparent" />
+                    </Style>
+                </ListBox.Styles>
+            </ListBox>
+        </ScrollViewer>
+    </Grid>
+</UserControl>

+ 55 - 0
src/Ryujinx/UI/Controls/DlcSelectView.axaml.cs

@@ -0,0 +1,55 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+using Avalonia.Styling;
+using FluentAvalonia.UI.Controls;
+using LibHac.Tools.FsSystem.NcaUtils;
+using Ryujinx.Ava.Common;
+using Ryujinx.Ava.Common.Locale;
+using Ryujinx.Ava.Common.Models;
+using Ryujinx.Ava.UI.Helpers;
+using Ryujinx.Ava.UI.ViewModels;
+using Ryujinx.Ava.Utilities.AppLibrary;
+using Ryujinx.Ava.Utilities.Compat;
+using System.Threading.Tasks;
+
+namespace Ryujinx.Ava.UI.Controls
+{
+    public partial class DlcSelectView : UserControl
+    {
+        public DlcSelectView()
+        {
+            InitializeComponent();
+        }
+
+        #nullable enable
+        public static async Task<DownloadableContentModel?> Show(ulong selectedTitleId, ApplicationLibrary appLibrary)
+        #nullable disable
+        {
+            DlcSelectViewModel viewModel = new(selectedTitleId, appLibrary);
+
+            ContentDialog contentDialog = new()
+            {
+                PrimaryButtonText = LocaleManager.Instance[LocaleKeys.Continue],
+                SecondaryButtonText = string.Empty,
+                CloseButtonText = string.Empty,
+                Content = new DlcSelectView { DataContext = viewModel }
+            };
+
+            Style closeButton = new(x => x.Name("CloseButton"));
+            closeButton.Setters.Add(new Setter(WidthProperty, 80d));
+
+            Style closeButtonParent = new(x => x.Name("CommandSpace"));
+            closeButtonParent.Setters.Add(new Setter(HorizontalAlignmentProperty,
+                Avalonia.Layout.HorizontalAlignment.Right));
+
+            contentDialog.Styles.Add(closeButton);
+            contentDialog.Styles.Add(closeButtonParent);
+
+            await ContentDialogHelper.ShowAsync(contentDialog);
+
+            return viewModel.SelectedDlc;
+        }
+    }
+}
+

+ 1 - 1
src/Ryujinx/UI/Controls/NavigationDialogHost.axaml.cs

@@ -69,7 +69,7 @@ namespace Ryujinx.Ava.UI.Controls
             VirtualFileSystem ownerVirtualFileSystem,
             HorizonClient ownerHorizonClient)
         {
-            var content = new NavigationDialogHost(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient);
+            NavigationDialogHost content = new(ownerAccountManager, ownerContentManager, ownerVirtualFileSystem, ownerHorizonClient);
             ContentDialog contentDialog = new()
             {
                 Title = LocaleManager.Instance[LocaleKeys.UserProfileWindowTitle],

+ 25 - 0
src/Ryujinx/UI/ViewModels/DlcSelectViewModel.cs

@@ -0,0 +1,25 @@
+using CommunityToolkit.Mvvm.ComponentModel;
+using Ryujinx.Ava.Common.Models;
+using Ryujinx.Ava.Utilities.AppLibrary;
+using System.Linq;
+
+namespace Ryujinx.Ava.UI.ViewModels
+{
+    public partial class DlcSelectViewModel : BaseModel
+    {
+        [ObservableProperty] private DownloadableContentModel[] _dlcs;
+        #nullable enable
+        [ObservableProperty] private DownloadableContentModel? _selectedDlc;
+        #nullable disable
+        
+        public DlcSelectViewModel(ulong titleId, ApplicationLibrary appLibrary)
+        {
+            _dlcs = appLibrary.DownloadableContents.Items
+                .Where(x => x.Dlc.TitleIdBase == titleId)
+                .Select(x => x.Dlc)
+                .OrderBy(it => it.IsBundled ? 0 : 1)
+                .ThenBy(it => it.TitleId)
+                .ToArray();
+        }
+    }
+}

+ 2 - 15
src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml

@@ -7,7 +7,6 @@
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     xmlns:viewModels="clr-namespace:Ryujinx.Ava.UI.ViewModels"
     xmlns:ui="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
-    xmlns:pi="using:Projektanker.Icons.Avalonia"
     xmlns:helpers="clr-namespace:Ryujinx.Ava.UI.Helpers"
     xmlns:models="clr-namespace:Ryujinx.Ava.Common.Models"
     Width="500"
@@ -15,9 +14,6 @@
     mc:Ignorable="d"
     x:DataType="viewModels:DownloadableContentManagerViewModel"
     Focusable="True">
-    <UserControl.Resources>
-        <helpers:DownloadableContentLabelConverter x:Key="DownloadableContentLabel" />
-    </UserControl.Resources>
     <Grid RowDefinitions="Auto,Auto,*,Auto">
         <StackPanel
             Grid.Row="0"
@@ -102,7 +98,7 @@
                                         TextWrapping="Wrap"
                                         TextTrimming="CharacterEllipsis">
                                         <TextBlock.Text>
-                                            <MultiBinding Converter="{StaticResource DownloadableContentLabel}">
+                                            <MultiBinding Converter="{x:Static helpers:DownloadableContentLabelConverter.Instance}">
                                                 <Binding Path="FileName" />
                                                 <Binding Path="IsBundled" />
                                             </MultiBinding>
@@ -113,22 +109,13 @@
                                         Margin="10 0"
                                         HorizontalAlignment="Left"
                                         VerticalAlignment="Center"
-                                        Text="{Binding TitleId}" />
+                                        Text="{Binding TitleIdStr}" />
                                 </Grid>
                                 <StackPanel
                                     Grid.Column="1"
                                     Spacing="10"
                                     Orientation="Horizontal"
                                     HorizontalAlignment="Right">
-                                    <Button 
-                                        VerticalAlignment="Center"
-                                        HorizontalAlignment="Right"
-                                        Padding="10"
-                                        MinWidth="0"
-                                        MinHeight="0"
-                                        Click="DlcItem_DumpRomfs">
-                                        <ui:SymbolIcon Symbol="MoveToFolder"/>
-                                    </Button>
                                     <Button
                                         VerticalAlignment="Center"
                                         HorizontalAlignment="Right"

+ 0 - 13
src/Ryujinx/UI/Windows/DownloadableContentManagerWindow.axaml.cs

@@ -95,18 +95,5 @@ namespace Ryujinx.Ava.UI.Windows
                 }
             }
         }
-        
-        private async void DlcItem_DumpRomfs(object sender, RoutedEventArgs e)
-        {
-            if (sender is not Button { DataContext: DownloadableContentModel dlc }) return;
-            if (RyujinxApp.MainWindow.ViewModel is not { } viewModel)
-                return;
-            
-            await ApplicationHelper.ExtractAoc(
-                viewModel.StorageProvider,
-                NcaSectionType.Data,
-                dlc.ContainerPath,
-                dlc.FileName);
-        }
     }
 }