diff --git a/src/Ryujinx.HLE/HOS/ModLoader.cs b/src/Ryujinx.HLE/HOS/ModLoader.cs index 0f2e09da6..c652024cf 100644 --- a/src/Ryujinx.HLE/HOS/ModLoader.cs +++ b/src/Ryujinx.HLE/HOS/ModLoader.cs @@ -296,7 +296,7 @@ namespace Ryujinx.HLE.HOS AddModsFromDirectory(mods, applicationDir, modMetadata); } - public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong applicationId) + public static void QueryContentsDir(ModCache mods, DirectoryInfo contentsDir, ulong applicationId, ulong[] installedDlcs) { if (!contentsDir.Exists) { @@ -311,6 +311,16 @@ namespace Ryujinx.HLE.HOS { QueryApplicationDir(mods, applicationDir, applicationId); } + + foreach (ulong installedDlcId in installedDlcs) + { + DirectoryInfo dlcModDir = FindApplicationDir(contentsDir, $"{installedDlcId:x16}"); + + if (dlcModDir != null) + { + QueryApplicationDir(mods, dlcModDir, applicationId); + } + } } private static int QueryCheatsDir(ModCache mods, DirectoryInfo cheatsDir) @@ -417,7 +427,7 @@ namespace Ryujinx.HLE.HOS { foreach ((ulong applicationId, ModCache cache) in modCaches) { - QueryContentsDir(cache, searchDir, applicationId); + QueryContentsDir(cache, searchDir, applicationId, Array.Empty()); } return true; diff --git a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs index dbf320465..245a51425 100644 --- a/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs +++ b/src/Ryujinx/UI/Controls/ApplicationContextMenu.axaml.cs @@ -128,7 +128,11 @@ namespace Ryujinx.Ava.UI.Controls public async void OpenModManager_Click(object sender, RoutedEventArgs args) { if (sender is MenuItem { DataContext: MainWindowViewModel { SelectedApplication: not null } viewModel }) - await ModManagerWindow.Show(viewModel.SelectedApplication.Id, viewModel.SelectedApplication.Name); + await ModManagerWindow.Show( + viewModel.SelectedApplication.Id, + viewModel.SelectedApplication.IdBase, + viewModel.ApplicationLibrary, + viewModel.SelectedApplication.Name); } public async void PurgePtcCache_Click(object sender, RoutedEventArgs args) diff --git a/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs b/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs index 603d8f7c5..cda7e34cf 100644 --- a/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs +++ b/src/Ryujinx/UI/ViewModels/ModManagerViewModel.cs @@ -7,6 +7,7 @@ using Gommon; using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; +using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Common.Configuration; using Ryujinx.Common.Logging; using Ryujinx.Common.Utilities; @@ -29,6 +30,7 @@ namespace Ryujinx.Ava.UI.ViewModels private string _search; private readonly ulong _applicationId; + private readonly ulong[] _installedDlcIds; private readonly IStorageProvider _storageProvider; private static readonly ModMetadataJsonSerializerContext _serializerContext = new(JsonHelper.GetDefaultSerializerOptions()); @@ -61,18 +63,23 @@ namespace Ryujinx.Ava.UI.ViewModels get => string.Format(LocaleManager.Instance[LocaleKeys.ModWindowHeading], Mods.Count); } - public ModManagerViewModel(ulong applicationId) + public ModManagerViewModel(ulong applicationId, ulong applicationIdBase, ApplicationLibrary appLibrary) { _applicationId = applicationId; + _installedDlcIds = appLibrary.DownloadableContents.Keys + .Where(x => x.TitleIdBase == applicationIdBase) + .Select(x => x.TitleId) + .ToArray(); + _modJsonPath = Path.Combine(AppDataManager.GamesDirPath, applicationId.ToString("x16"), "mods.json"); _storageProvider = RyujinxApp.MainWindow.StorageProvider; - LoadMods(applicationId); + LoadMods(applicationId, _installedDlcIds); } - private void LoadMods(ulong applicationId) + private void LoadMods(ulong applicationId, ulong[] installedDlcIds) { Mods.Clear(); SelectedMods.Clear(); @@ -84,7 +91,7 @@ namespace Ryujinx.Ava.UI.ViewModels bool inSd = path == ModLoader.GetSdModsBasePath(); ModLoader.ModCache modCache = new(); - ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId); + ModLoader.QueryContentsDir(modCache, new DirectoryInfo(Path.Combine(path, "contents")), applicationId, _installedDlcIds); foreach (ModLoader.Mod mod in modCache.RomfsDirs) { @@ -278,7 +285,7 @@ namespace Ryujinx.Ava.UI.ViewModels File.Copy(file, file.Replace(directory.Parent.ToString(), destinationDir), true); } - LoadMods(_applicationId); + LoadMods(_applicationId, _installedDlcIds); } public async void Add() diff --git a/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs index e0ba9e419..a9767bcca 100644 --- a/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/CheatWindow.axaml.cs @@ -64,7 +64,7 @@ namespace Ryujinx.Ava.UI.Windows ModLoader.ModCache mods = new(); - ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue); + ModLoader.QueryContentsDir(mods, new DirectoryInfo(Path.Combine(modsBasePath, "contents")), titleIdValue, []); string currentCheatFile = string.Empty; string buildId = string.Empty; diff --git a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs index 3d70917f0..cb483b404 100644 --- a/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs +++ b/src/Ryujinx/UI/Windows/ModManagerWindow.axaml.cs @@ -6,6 +6,7 @@ using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.UI.Helpers; using Ryujinx.Ava.UI.Models; using Ryujinx.Ava.UI.ViewModels; +using Ryujinx.Ava.Utilities.AppLibrary; using Ryujinx.Common.Helper; using System.Threading.Tasks; using Button = Avalonia.Controls.Button; @@ -23,21 +24,21 @@ namespace Ryujinx.Ava.UI.Windows InitializeComponent(); } - public ModManagerWindow(ulong titleId) + public ModManagerWindow(ulong titleId, ulong titleIdBase, ApplicationLibrary applicationLibrary) { - DataContext = ViewModel = new ModManagerViewModel(titleId); + DataContext = ViewModel = new ModManagerViewModel(titleId, titleIdBase, applicationLibrary); InitializeComponent(); } - public static async Task Show(ulong titleId, string titleName) + public static async Task Show(ulong titleId, ulong titleIdBase, ApplicationLibrary appLibrary, string titleName) { ContentDialog contentDialog = new() { PrimaryButtonText = string.Empty, SecondaryButtonText = string.Empty, CloseButtonText = string.Empty, - Content = new ModManagerWindow(titleId), + Content = new ModManagerWindow(titleId, titleIdBase, appLibrary), Title = string.Format(LocaleManager.Instance[LocaleKeys.ModWindowTitle], titleName, titleId.ToString("X16")), };