From 514121d8c133baf711c19a9ca1dfa585f6043f6d Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Wed, 24 Apr 2024 23:28:12 +0200 Subject: [PATCH] Reorder stuff. --- Penumbra/Api/Api/ModSettingsApi.cs | 3 +- Penumbra/Api/Api/TemporaryApi.cs | 2 +- Penumbra/Api/TempModManager.cs | 2 +- .../Cache/CollectionCacheManager.cs | 2 +- .../Collections/Manager/CollectionEditor.cs | 2 +- .../Collections/Manager/CollectionStorage.cs | 2 +- .../Manager/ModCollectionMigration.cs | 2 +- Penumbra/Collections/ModCollection.cs | 2 +- Penumbra/Collections/ModCollectionSave.cs | 2 +- Penumbra/Communication/ModSettingChanged.cs | 2 +- Penumbra/Import/TexToolsImporter.ModPack.cs | 4 +- Penumbra/Meta/MetaFileManager.cs | 2 +- Penumbra/Mods/Editor/DuplicateManager.cs | 3 +- Penumbra/Mods/Editor/FileRegistry.cs | 2 +- Penumbra/Mods/Editor/IMod.cs | 3 +- Penumbra/Mods/Editor/ModEditor.cs | 3 +- Penumbra/Mods/Editor/ModFileCollection.cs | 2 +- Penumbra/Mods/Editor/ModFileEditor.cs | 2 +- Penumbra/Mods/Editor/ModMerger.cs | 2 +- Penumbra/Mods/Editor/ModMetaEditor.cs | 2 +- Penumbra/Mods/Editor/ModNormalizer.cs | 3 +- Penumbra/Mods/Editor/ModSwapEditor.cs | 2 +- .../Mods/{Subclasses => Groups}/IModGroup.cs | 86 +---- Penumbra/Mods/Groups/ModSaveGroup.cs | 57 +++ .../{Subclasses => Groups}/MultiModGroup.cs | 30 +- .../{Subclasses => Groups}/SingleModGroup.cs | 28 +- Penumbra/Mods/ItemSwap/ItemSwapContainer.cs | 2 +- Penumbra/Mods/Manager/ModCacheManager.cs | 1 - Penumbra/Mods/Manager/ModMigration.cs | 4 +- Penumbra/Mods/Manager/ModOptionEditor.cs | 4 +- Penumbra/Mods/Mod.cs | 5 +- Penumbra/Mods/ModCreator.cs | 4 +- Penumbra/Mods/ModLocalData.cs | 20 +- Penumbra/Mods/ModMeta.cs | 24 +- .../{Subclasses => Settings}/ModPriority.cs | 2 +- .../{Subclasses => Settings}/ModSettings.cs | 5 +- .../Mods/{Subclasses => Settings}/Setting.cs | 2 +- .../{Subclasses => Settings}/SettingList.cs | 2 +- Penumbra/Mods/SubMods/DefaultSubMod.cs | 30 ++ .../IModDataContainer.cs | 27 +- .../{Subclasses => SubMods}/IModOption.cs | 8 +- Penumbra/Mods/SubMods/MultiSubMod.cs | 92 +++++ Penumbra/Mods/SubMods/SingleSubMod.cs | 82 ++++ Penumbra/Mods/Subclasses/SubMod.cs | 352 ------------------ Penumbra/Mods/TemporaryMod.cs | 6 +- Penumbra/Penumbra.csproj | 4 + Penumbra/Services/ConfigMigrationService.cs | 2 +- Penumbra/Services/SaveService.cs | 2 +- Penumbra/UI/AdvancedWindow/ItemSwapTab.cs | 3 +- .../UI/AdvancedWindow/ModEditWindow.Files.cs | 2 +- .../ModEditWindow.QuickImport.cs | 2 +- Penumbra/UI/AdvancedWindow/ModEditWindow.cs | 2 +- Penumbra/UI/AdvancedWindow/ModMergeTab.cs | 2 +- Penumbra/UI/ModsTab/ModFileSystemSelector.cs | 2 +- Penumbra/UI/ModsTab/ModPanelConflictsTab.cs | 2 +- Penumbra/UI/ModsTab/ModPanelEditTab.cs | 3 +- Penumbra/UI/ModsTab/ModPanelSettingsTab.cs | 4 +- Penumbra/UI/ModsTab/ModPanelTabBar.cs | 1 - 58 files changed, 416 insertions(+), 539 deletions(-) rename Penumbra/Mods/{Subclasses => Groups}/IModGroup.cs (50%) create mode 100644 Penumbra/Mods/Groups/ModSaveGroup.cs rename Penumbra/Mods/{Subclasses => Groups}/MultiModGroup.cs (83%) rename Penumbra/Mods/{Subclasses => Groups}/SingleModGroup.cs (85%) rename Penumbra/Mods/{Subclasses => Settings}/ModPriority.cs (98%) rename Penumbra/Mods/{Subclasses => Settings}/ModSettings.cs (98%) rename Penumbra/Mods/{Subclasses => Settings}/Setting.cs (98%) rename Penumbra/Mods/{Subclasses => Settings}/SettingList.cs (97%) create mode 100644 Penumbra/Mods/SubMods/DefaultSubMod.cs rename Penumbra/Mods/{Subclasses => SubMods}/IModDataContainer.cs (80%) rename Penumbra/Mods/{Subclasses => SubMods}/IModOption.cs (72%) create mode 100644 Penumbra/Mods/SubMods/MultiSubMod.cs create mode 100644 Penumbra/Mods/SubMods/SingleSubMod.cs delete mode 100644 Penumbra/Mods/Subclasses/SubMod.cs diff --git a/Penumbra/Api/Api/ModSettingsApi.cs b/Penumbra/Api/Api/ModSettingsApi.cs index e145e027..039fbfa9 100644 --- a/Penumbra/Api/Api/ModSettingsApi.cs +++ b/Penumbra/Api/Api/ModSettingsApi.cs @@ -8,8 +8,9 @@ using Penumbra.Communication; using Penumbra.Interop.PathResolving; using Penumbra.Mods; using Penumbra.Mods.Editor; +using Penumbra.Mods.Groups; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; namespace Penumbra.Api.Api; diff --git a/Penumbra/Api/Api/TemporaryApi.cs b/Penumbra/Api/Api/TemporaryApi.cs index b4ffa8f4..38d080cc 100644 --- a/Penumbra/Api/Api/TemporaryApi.cs +++ b/Penumbra/Api/Api/TemporaryApi.cs @@ -5,7 +5,7 @@ using Penumbra.Collections.Manager; using Penumbra.GameData.Actors; using Penumbra.GameData.Interop; using Penumbra.Meta.Manipulations; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.String.Classes; namespace Penumbra.Api.Api; diff --git a/Penumbra/Api/TempModManager.cs b/Penumbra/Api/TempModManager.cs index 7d682338..aee2b447 100644 --- a/Penumbra/Api/TempModManager.cs +++ b/Penumbra/Api/TempModManager.cs @@ -6,7 +6,7 @@ using Penumbra.Services; using Penumbra.String.Classes; using Penumbra.Collections.Manager; using Penumbra.Communication; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; namespace Penumbra.Api; diff --git a/Penumbra/Collections/Cache/CollectionCacheManager.cs b/Penumbra/Collections/Cache/CollectionCacheManager.cs index 4b5c4337..c1296414 100644 --- a/Penumbra/Collections/Cache/CollectionCacheManager.cs +++ b/Penumbra/Collections/Cache/CollectionCacheManager.cs @@ -8,7 +8,7 @@ using Penumbra.Interop.ResourceLoading; using Penumbra.Meta; using Penumbra.Mods; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; using Penumbra.String.Classes; diff --git a/Penumbra/Collections/Manager/CollectionEditor.cs b/Penumbra/Collections/Manager/CollectionEditor.cs index 4af19e6b..0243de1e 100644 --- a/Penumbra/Collections/Manager/CollectionEditor.cs +++ b/Penumbra/Collections/Manager/CollectionEditor.cs @@ -2,7 +2,7 @@ using OtterGui; using Penumbra.Api.Enums; using Penumbra.Mods; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; namespace Penumbra.Collections.Manager; diff --git a/Penumbra/Collections/Manager/CollectionStorage.cs b/Penumbra/Collections/Manager/CollectionStorage.cs index 2da2a569..4e2fb7b7 100644 --- a/Penumbra/Collections/Manager/CollectionStorage.cs +++ b/Penumbra/Collections/Manager/CollectionStorage.cs @@ -5,7 +5,7 @@ using Penumbra.Communication; using Penumbra.Mods; using Penumbra.Mods.Editor; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; namespace Penumbra.Collections.Manager; diff --git a/Penumbra/Collections/Manager/ModCollectionMigration.cs b/Penumbra/Collections/Manager/ModCollectionMigration.cs index 053f0a2b..89743aa2 100644 --- a/Penumbra/Collections/Manager/ModCollectionMigration.cs +++ b/Penumbra/Collections/Manager/ModCollectionMigration.cs @@ -1,6 +1,6 @@ using Penumbra.Mods; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; using Penumbra.Util; diff --git a/Penumbra/Collections/ModCollection.cs b/Penumbra/Collections/ModCollection.cs index e666b151..4580e37a 100644 --- a/Penumbra/Collections/ModCollection.cs +++ b/Penumbra/Collections/ModCollection.cs @@ -1,7 +1,7 @@ using Penumbra.Mods; using Penumbra.Mods.Manager; using Penumbra.Collections.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; namespace Penumbra.Collections; diff --git a/Penumbra/Collections/ModCollectionSave.cs b/Penumbra/Collections/ModCollectionSave.cs index acc38d83..e6bb069b 100644 --- a/Penumbra/Collections/ModCollectionSave.cs +++ b/Penumbra/Collections/ModCollectionSave.cs @@ -2,7 +2,7 @@ using Newtonsoft.Json.Linq; using Penumbra.Services; using Newtonsoft.Json; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; namespace Penumbra.Collections; diff --git a/Penumbra/Communication/ModSettingChanged.cs b/Penumbra/Communication/ModSettingChanged.cs index 968f78a7..a7da345b 100644 --- a/Penumbra/Communication/ModSettingChanged.cs +++ b/Penumbra/Communication/ModSettingChanged.cs @@ -4,7 +4,7 @@ using Penumbra.Api.Api; using Penumbra.Api.Enums; using Penumbra.Collections; using Penumbra.Mods; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; namespace Penumbra.Communication; diff --git a/Penumbra/Import/TexToolsImporter.ModPack.cs b/Penumbra/Import/TexToolsImporter.ModPack.cs index b9cdda71..eb6d0b0c 100644 --- a/Penumbra/Import/TexToolsImporter.ModPack.cs +++ b/Penumbra/Import/TexToolsImporter.ModPack.cs @@ -3,7 +3,9 @@ using OtterGui; using Penumbra.Api.Enums; using Penumbra.Import.Structs; using Penumbra.Mods; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.Util; using ZipArchive = SharpCompress.Archives.Zip.ZipArchive; diff --git a/Penumbra/Meta/MetaFileManager.cs b/Penumbra/Meta/MetaFileManager.cs index 0e2e638b..cd99396b 100644 --- a/Penumbra/Meta/MetaFileManager.cs +++ b/Penumbra/Meta/MetaFileManager.cs @@ -11,7 +11,7 @@ using Penumbra.Interop.Services; using Penumbra.Interop.Structs; using Penumbra.Meta.Files; using Penumbra.Mods; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; using Penumbra.Services; using ResidentResourceManager = Penumbra.Interop.Services.ResidentResourceManager; diff --git a/Penumbra/Mods/Editor/DuplicateManager.cs b/Penumbra/Mods/Editor/DuplicateManager.cs index 92ec58b9..31aacbe1 100644 --- a/Penumbra/Mods/Editor/DuplicateManager.cs +++ b/Penumbra/Mods/Editor/DuplicateManager.cs @@ -1,6 +1,7 @@ using OtterGui.Classes; +using Penumbra.Mods.Groups; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String.Classes; diff --git a/Penumbra/Mods/Editor/FileRegistry.cs b/Penumbra/Mods/Editor/FileRegistry.cs index 44d349ce..a484c8c2 100644 --- a/Penumbra/Mods/Editor/FileRegistry.cs +++ b/Penumbra/Mods/Editor/FileRegistry.cs @@ -1,4 +1,4 @@ -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; namespace Penumbra.Mods.Editor; diff --git a/Penumbra/Mods/Editor/IMod.cs b/Penumbra/Mods/Editor/IMod.cs index c4c4be2f..d4c881e9 100644 --- a/Penumbra/Mods/Editor/IMod.cs +++ b/Penumbra/Mods/Editor/IMod.cs @@ -1,6 +1,7 @@ using OtterGui.Classes; using Penumbra.Meta.Manipulations; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; using Penumbra.String.Classes; namespace Penumbra.Mods.Editor; diff --git a/Penumbra/Mods/Editor/ModEditor.cs b/Penumbra/Mods/Editor/ModEditor.cs index 1118f890..e1c5962f 100644 --- a/Penumbra/Mods/Editor/ModEditor.cs +++ b/Penumbra/Mods/Editor/ModEditor.cs @@ -1,6 +1,7 @@ using OtterGui; using OtterGui.Compression; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; +using Penumbra.Mods.SubMods; namespace Penumbra.Mods.Editor; diff --git a/Penumbra/Mods/Editor/ModFileCollection.cs b/Penumbra/Mods/Editor/ModFileCollection.cs index ede35914..551d04cf 100644 --- a/Penumbra/Mods/Editor/ModFileCollection.cs +++ b/Penumbra/Mods/Editor/ModFileCollection.cs @@ -1,5 +1,5 @@ using OtterGui; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; namespace Penumbra.Mods.Editor; diff --git a/Penumbra/Mods/Editor/ModFileEditor.cs b/Penumbra/Mods/Editor/ModFileEditor.cs index 11e35334..00685c94 100644 --- a/Penumbra/Mods/Editor/ModFileEditor.cs +++ b/Penumbra/Mods/Editor/ModFileEditor.cs @@ -1,5 +1,5 @@ using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String.Classes; diff --git a/Penumbra/Mods/Editor/ModMerger.cs b/Penumbra/Mods/Editor/ModMerger.cs index 541c84ae..0f629bc7 100644 --- a/Penumbra/Mods/Editor/ModMerger.cs +++ b/Penumbra/Mods/Editor/ModMerger.cs @@ -5,7 +5,7 @@ using OtterGui.Classes; using Penumbra.Api.Enums; using Penumbra.Communication; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String.Classes; using Penumbra.UI.ModsTab; diff --git a/Penumbra/Mods/Editor/ModMetaEditor.cs b/Penumbra/Mods/Editor/ModMetaEditor.cs index 88e48f0f..dee700d5 100644 --- a/Penumbra/Mods/Editor/ModMetaEditor.cs +++ b/Penumbra/Mods/Editor/ModMetaEditor.cs @@ -1,6 +1,6 @@ using Penumbra.Meta.Manipulations; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; namespace Penumbra.Mods.Editor; diff --git a/Penumbra/Mods/Editor/ModNormalizer.cs b/Penumbra/Mods/Editor/ModNormalizer.cs index db00a1c7..e2088b32 100644 --- a/Penumbra/Mods/Editor/ModNormalizer.cs +++ b/Penumbra/Mods/Editor/ModNormalizer.cs @@ -3,8 +3,9 @@ using Dalamud.Interface.Internal.Notifications; using OtterGui; using OtterGui.Classes; using OtterGui.Tasks; +using Penumbra.Mods.Groups; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; namespace Penumbra.Mods.Editor; diff --git a/Penumbra/Mods/Editor/ModSwapEditor.cs b/Penumbra/Mods/Editor/ModSwapEditor.cs index 64788cf3..3247cfdf 100644 --- a/Penumbra/Mods/Editor/ModSwapEditor.cs +++ b/Penumbra/Mods/Editor/ModSwapEditor.cs @@ -1,6 +1,6 @@ using Penumbra.Mods; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; using Penumbra.Util; diff --git a/Penumbra/Mods/Subclasses/IModGroup.cs b/Penumbra/Mods/Groups/IModGroup.cs similarity index 50% rename from Penumbra/Mods/Subclasses/IModGroup.cs rename to Penumbra/Mods/Groups/IModGroup.cs index 5c500793..dc5150cf 100644 --- a/Penumbra/Mods/Subclasses/IModGroup.cs +++ b/Penumbra/Mods/Groups/IModGroup.cs @@ -1,11 +1,11 @@ -using FFXIVClientStructs.FFXIV.Client.UI.Agent; using Newtonsoft.Json; using Penumbra.Api.Enums; using Penumbra.Meta.Manipulations; -using Penumbra.Services; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.Groups; public interface ITexToolsGroup { @@ -16,22 +16,22 @@ public interface IModGroup { public const int MaxMultiOptions = 63; - public Mod Mod { get; } - public string Name { get; } - public string Description { get; } - public GroupType Type { get; } - public ModPriority Priority { get; set; } - public Setting DefaultSettings { get; set; } + public Mod Mod { get; } + public string Name { get; } + public string Description { get; } + public GroupType Type { get; } + public ModPriority Priority { get; set; } + public Setting DefaultSettings { get; set; } public FullPath? FindBestMatch(Utf8GamePath gamePath); - public int AddOption(Mod mod, string name, string description = ""); + public int AddOption(Mod mod, string name, string description = ""); - public IReadOnlyList Options { get; } + public IReadOnlyList Options { get; } public IReadOnlyList DataContainers { get; } - public bool IsOption { get; } + public bool IsOption { get; } public IModGroup Convert(GroupType type); - public bool MoveOption(int optionIdxFrom, int optionIdxTo); + public bool MoveOption(int optionIdxFrom, int optionIdxTo); public int GetIndex(); @@ -88,67 +88,15 @@ public interface IModGroup public static (int Redirections, int Swaps, int Manips) GetCountsBase(IModGroup group) { var redirectionCount = 0; - var swapCount = 0; - var manipCount = 0; + var swapCount = 0; + var manipCount = 0; foreach (var option in group.DataContainers) { redirectionCount += option.Files.Count; - swapCount += option.FileSwaps.Count; - manipCount += option.Manipulations.Count; + swapCount += option.FileSwaps.Count; + manipCount += option.Manipulations.Count; } return (redirectionCount, swapCount, manipCount); } } - -public readonly struct ModSaveGroup : ISavable -{ - private readonly DirectoryInfo _basePath; - private readonly IModGroup? _group; - private readonly int _groupIdx; - private readonly DefaultSubMod? _defaultMod; - private readonly bool _onlyAscii; - - public ModSaveGroup(Mod mod, int groupIdx, bool onlyAscii) - { - _basePath = mod.ModPath; - _groupIdx = groupIdx; - if (_groupIdx < 0) - _defaultMod = mod.Default; - else - _group = mod.Groups[_groupIdx]; - _onlyAscii = onlyAscii; - } - - public ModSaveGroup(DirectoryInfo basePath, IModGroup group, int groupIdx, bool onlyAscii) - { - _basePath = basePath; - _group = group; - _groupIdx = groupIdx; - _onlyAscii = onlyAscii; - } - - public ModSaveGroup(DirectoryInfo basePath, DefaultSubMod @default, bool onlyAscii) - { - _basePath = basePath; - _groupIdx = -1; - _defaultMod = @default; - _onlyAscii = onlyAscii; - } - - public string ToFilename(FilenameService fileNames) - => fileNames.OptionGroupFile(_basePath.FullName, _groupIdx, _group?.Name ?? string.Empty, _onlyAscii); - - public void Save(StreamWriter writer) - { - using var j = new JsonTextWriter(writer); - j.Formatting = Formatting.Indented; - var serializer = new JsonSerializer { Formatting = Formatting.Indented }; - j.WriteStartObject(); - if (_groupIdx >= 0) - _group!.WriteJson(j, serializer); - else - IModDataContainer.WriteModData(j, serializer, _defaultMod!, _basePath); - j.WriteEndObject(); - } -} diff --git a/Penumbra/Mods/Groups/ModSaveGroup.cs b/Penumbra/Mods/Groups/ModSaveGroup.cs new file mode 100644 index 00000000..ed81f42f --- /dev/null +++ b/Penumbra/Mods/Groups/ModSaveGroup.cs @@ -0,0 +1,57 @@ +using Newtonsoft.Json; +using Penumbra.Mods.SubMods; +using Penumbra.Services; + +namespace Penumbra.Mods.Groups; + +public readonly struct ModSaveGroup : ISavable +{ + private readonly DirectoryInfo _basePath; + private readonly IModGroup? _group; + private readonly int _groupIdx; + private readonly DefaultSubMod? _defaultMod; + private readonly bool _onlyAscii; + + public ModSaveGroup(Mod mod, int groupIdx, bool onlyAscii) + { + _basePath = mod.ModPath; + _groupIdx = groupIdx; + if (_groupIdx < 0) + _defaultMod = mod.Default; + else + _group = mod.Groups[_groupIdx]; + _onlyAscii = onlyAscii; + } + + public ModSaveGroup(DirectoryInfo basePath, IModGroup group, int groupIdx, bool onlyAscii) + { + _basePath = basePath; + _group = group; + _groupIdx = groupIdx; + _onlyAscii = onlyAscii; + } + + public ModSaveGroup(DirectoryInfo basePath, DefaultSubMod @default, bool onlyAscii) + { + _basePath = basePath; + _groupIdx = -1; + _defaultMod = @default; + _onlyAscii = onlyAscii; + } + + public string ToFilename(FilenameService fileNames) + => fileNames.OptionGroupFile(_basePath.FullName, _groupIdx, _group?.Name ?? string.Empty, _onlyAscii); + + public void Save(StreamWriter writer) + { + using var j = new JsonTextWriter(writer); + j.Formatting = Formatting.Indented; + var serializer = new JsonSerializer { Formatting = Formatting.Indented }; + j.WriteStartObject(); + if (_groupIdx >= 0) + _group!.WriteJson(j, serializer); + else + IModDataContainer.WriteModData(j, serializer, _defaultMod!, _basePath); + j.WriteEndObject(); + } +} diff --git a/Penumbra/Mods/Subclasses/MultiModGroup.cs b/Penumbra/Mods/Groups/MultiModGroup.cs similarity index 83% rename from Penumbra/Mods/Subclasses/MultiModGroup.cs rename to Penumbra/Mods/Groups/MultiModGroup.cs index f194350a..f39f2e70 100644 --- a/Penumbra/Mods/Subclasses/MultiModGroup.cs +++ b/Penumbra/Mods/Groups/MultiModGroup.cs @@ -6,9 +6,11 @@ using OtterGui.Classes; using OtterGui.Filesystem; using Penumbra.Api.Enums; using Penumbra.Meta.Manipulations; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.Groups; /// Groups that allow all available options to be selected at once. public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup @@ -16,11 +18,11 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup public GroupType Type => GroupType.Multi; - public Mod Mod { get; set; } = mod; - public string Name { get; set; } = "Group"; - public string Description { get; set; } = "A non-exclusive group of settings."; - public ModPriority Priority { get; set; } - public Setting DefaultSettings { get; set; } + public Mod Mod { get; set; } = mod; + public string Name { get; set; } = "Group"; + public string Description { get; set; } = "A non-exclusive group of settings."; + public ModPriority Priority { get; set; } + public Setting DefaultSettings { get; set; } public readonly List OptionData = []; public IReadOnlyList Options @@ -45,7 +47,7 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup var subMod = new MultiSubMod(mod, this) { - Name = name, + Name = name, Description = description, }; OptionData.Add(subMod); @@ -56,9 +58,9 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup { var ret = new MultiModGroup(mod) { - Name = json[nameof(Name)]?.ToObject() ?? string.Empty, - Description = json[nameof(Description)]?.ToObject() ?? string.Empty, - Priority = json[nameof(Priority)]?.ToObject() ?? ModPriority.Default, + Name = json[nameof(Name)]?.ToObject() ?? string.Empty, + Description = json[nameof(Description)]?.ToObject() ?? string.Empty, + Priority = json[nameof(Priority)]?.ToObject() ?? ModPriority.Default, DefaultSettings = json[nameof(DefaultSettings)]?.ToObject() ?? Setting.Zero, }; if (ret.Name.Length == 0) @@ -93,9 +95,9 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup case GroupType.Single: var single = new SingleModGroup(Mod) { - Name = Name, - Description = Description, - Priority = Priority, + Name = Name, + Description = Description, + Priority = Priority, DefaultSettings = DefaultSettings.TurnMulti(OptionData.Count), }; single.OptionData.AddRange(OptionData.Select(o => o.ConvertToSingle(Mod, single))); @@ -152,7 +154,7 @@ public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup => IModGroup.GetCountsBase(this); public Setting FixSetting(Setting setting) - => new(setting.Value & ((1ul << OptionData.Count) - 1)); + => new(setting.Value & (1ul << OptionData.Count) - 1); /// Create a group without a mod only for saving it in the creator. internal static MultiModGroup CreateForSaving(string name) diff --git a/Penumbra/Mods/Subclasses/SingleModGroup.cs b/Penumbra/Mods/Groups/SingleModGroup.cs similarity index 85% rename from Penumbra/Mods/Subclasses/SingleModGroup.cs rename to Penumbra/Mods/Groups/SingleModGroup.cs index d1a3b6d1..6011185a 100644 --- a/Penumbra/Mods/Subclasses/SingleModGroup.cs +++ b/Penumbra/Mods/Groups/SingleModGroup.cs @@ -4,9 +4,11 @@ using OtterGui; using OtterGui.Filesystem; using Penumbra.Api.Enums; using Penumbra.Meta.Manipulations; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.Groups; /// Groups that allow only one of their available options to be selected. public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup @@ -14,11 +16,11 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup public GroupType Type => GroupType.Single; - public Mod Mod { get; set; } = mod; - public string Name { get; set; } = "Option"; - public string Description { get; set; } = "A mutually exclusive group of settings."; - public ModPriority Priority { get; set; } - public Setting DefaultSettings { get; set; } + public Mod Mod { get; set; } = mod; + public string Name { get; set; } = "Option"; + public string Description { get; set; } = "A mutually exclusive group of settings."; + public ModPriority Priority { get; set; } + public Setting DefaultSettings { get; set; } public readonly List OptionData = []; @@ -34,7 +36,7 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup { var subMod = new SingleSubMod(mod, this) { - Name = name, + Name = name, Description = description, }; OptionData.Add(subMod); @@ -55,9 +57,9 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup var options = json["Options"]; var ret = new SingleModGroup(mod) { - Name = json[nameof(Name)]?.ToObject() ?? string.Empty, - Description = json[nameof(Description)]?.ToObject() ?? string.Empty, - Priority = json[nameof(Priority)]?.ToObject() ?? ModPriority.Default, + Name = json[nameof(Name)]?.ToObject() ?? string.Empty, + Description = json[nameof(Description)]?.ToObject() ?? string.Empty, + Priority = json[nameof(Priority)]?.ToObject() ?? ModPriority.Default, DefaultSettings = json[nameof(DefaultSettings)]?.ToObject() ?? Setting.Zero, }; if (ret.Name.Length == 0) @@ -82,9 +84,9 @@ public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup case GroupType.Multi: var multi = new MultiModGroup(Mod) { - Name = Name, - Description = Description, - Priority = Priority, + Name = Name, + Description = Description, + Priority = Priority, DefaultSettings = Setting.Multi((int)DefaultSettings.Value), }; multi.OptionData.AddRange(OptionData.Select((o, i) => o.ConvertToMulti(Mod, multi, new ModPriority(i)))); diff --git a/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs b/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs index 21b9ef2c..1545811e 100644 --- a/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs +++ b/Penumbra/Mods/ItemSwap/ItemSwapContainer.cs @@ -7,7 +7,7 @@ using Penumbra.String.Classes; using Penumbra.Meta; using Penumbra.Mods.Editor; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; namespace Penumbra.Mods.ItemSwap; diff --git a/Penumbra/Mods/Manager/ModCacheManager.cs b/Penumbra/Mods/Manager/ModCacheManager.cs index 4f9e8648..3ff1a333 100644 --- a/Penumbra/Mods/Manager/ModCacheManager.cs +++ b/Penumbra/Mods/Manager/ModCacheManager.cs @@ -2,7 +2,6 @@ using Penumbra.Communication; using Penumbra.GameData.Data; using Penumbra.GameData.Enums; using Penumbra.Meta.Manipulations; -using Penumbra.Mods.Subclasses; using Penumbra.Services; namespace Penumbra.Mods.Manager; diff --git a/Penumbra/Mods/Manager/ModMigration.cs b/Penumbra/Mods/Manager/ModMigration.cs index 8c4a5674..f160d5bd 100644 --- a/Penumbra/Mods/Manager/ModMigration.cs +++ b/Penumbra/Mods/Manager/ModMigration.cs @@ -2,7 +2,9 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using OtterGui; using Penumbra.Api.Enums; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String.Classes; diff --git a/Penumbra/Mods/Manager/ModOptionEditor.cs b/Penumbra/Mods/Manager/ModOptionEditor.cs index 4d3a5717..b66fec17 100644 --- a/Penumbra/Mods/Manager/ModOptionEditor.cs +++ b/Penumbra/Mods/Manager/ModOptionEditor.cs @@ -4,7 +4,9 @@ using OtterGui.Classes; using OtterGui.Filesystem; using Penumbra.Api.Enums; using Penumbra.Meta.Manipulations; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String.Classes; using Penumbra.Util; diff --git a/Penumbra/Mods/Mod.cs b/Penumbra/Mods/Mod.cs index 5c02213e..fc84afcc 100644 --- a/Penumbra/Mods/Mod.cs +++ b/Penumbra/Mods/Mod.cs @@ -1,9 +1,10 @@ using OtterGui; using OtterGui.Classes; -using Penumbra.Collections.Cache; using Penumbra.Meta.Manipulations; using Penumbra.Mods.Editor; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; namespace Penumbra.Mods; diff --git a/Penumbra/Mods/ModCreator.cs b/Penumbra/Mods/ModCreator.cs index c1236037..e8113ee1 100644 --- a/Penumbra/Mods/ModCreator.cs +++ b/Penumbra/Mods/ModCreator.cs @@ -9,8 +9,10 @@ using Penumbra.GameData.Data; using Penumbra.Import; using Penumbra.Import.Structs; using Penumbra.Meta; +using Penumbra.Mods.Groups; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String.Classes; diff --git a/Penumbra/Mods/ModLocalData.cs b/Penumbra/Mods/ModLocalData.cs index 51fe8d58..beda0dc7 100644 --- a/Penumbra/Mods/ModLocalData.cs +++ b/Penumbra/Mods/ModLocalData.cs @@ -5,29 +5,25 @@ using Penumbra.Services; namespace Penumbra.Mods; -public readonly struct ModLocalData : ISavable +public readonly struct ModLocalData(Mod mod) : ISavable { public const int FileVersion = 3; - private readonly Mod _mod; - - public ModLocalData(Mod mod) - => _mod = mod; - public string ToFilename(FilenameService fileNames) - => fileNames.LocalDataFile(_mod); + => fileNames.LocalDataFile(mod); public void Save(StreamWriter writer) { var jObject = new JObject { { nameof(FileVersion), JToken.FromObject(FileVersion) }, - { nameof(Mod.ImportDate), JToken.FromObject(_mod.ImportDate) }, - { nameof(Mod.LocalTags), JToken.FromObject(_mod.LocalTags) }, - { nameof(Mod.Note), JToken.FromObject(_mod.Note) }, - { nameof(Mod.Favorite), JToken.FromObject(_mod.Favorite) }, + { nameof(Mod.ImportDate), JToken.FromObject(mod.ImportDate) }, + { nameof(Mod.LocalTags), JToken.FromObject(mod.LocalTags) }, + { nameof(Mod.Note), JToken.FromObject(mod.Note) }, + { nameof(Mod.Favorite), JToken.FromObject(mod.Favorite) }, }; - using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented }; + using var jWriter = new JsonTextWriter(writer); + jWriter.Formatting = Formatting.Indented; jObject.WriteTo(jWriter); } diff --git a/Penumbra/Mods/ModMeta.cs b/Penumbra/Mods/ModMeta.cs index d29cdb9c..870d6d4f 100644 --- a/Penumbra/Mods/ModMeta.cs +++ b/Penumbra/Mods/ModMeta.cs @@ -4,31 +4,27 @@ using Penumbra.Services; namespace Penumbra.Mods; -public readonly struct ModMeta : ISavable +public readonly struct ModMeta(Mod mod) : ISavable { public const uint FileVersion = 3; - private readonly Mod _mod; - - public ModMeta(Mod mod) - => _mod = mod; - public string ToFilename(FilenameService fileNames) - => fileNames.ModMetaPath(_mod); + => fileNames.ModMetaPath(mod); public void Save(StreamWriter writer) { var jObject = new JObject { { nameof(FileVersion), JToken.FromObject(FileVersion) }, - { nameof(Mod.Name), JToken.FromObject(_mod.Name) }, - { nameof(Mod.Author), JToken.FromObject(_mod.Author) }, - { nameof(Mod.Description), JToken.FromObject(_mod.Description) }, - { nameof(Mod.Version), JToken.FromObject(_mod.Version) }, - { nameof(Mod.Website), JToken.FromObject(_mod.Website) }, - { nameof(Mod.ModTags), JToken.FromObject(_mod.ModTags) }, + { nameof(Mod.Name), JToken.FromObject(mod.Name) }, + { nameof(Mod.Author), JToken.FromObject(mod.Author) }, + { nameof(Mod.Description), JToken.FromObject(mod.Description) }, + { nameof(Mod.Version), JToken.FromObject(mod.Version) }, + { nameof(Mod.Website), JToken.FromObject(mod.Website) }, + { nameof(Mod.ModTags), JToken.FromObject(mod.ModTags) }, }; - using var jWriter = new JsonTextWriter(writer) { Formatting = Formatting.Indented }; + using var jWriter = new JsonTextWriter(writer); + jWriter.Formatting = Formatting.Indented; jObject.WriteTo(jWriter); } } diff --git a/Penumbra/Mods/Subclasses/ModPriority.cs b/Penumbra/Mods/Settings/ModPriority.cs similarity index 98% rename from Penumbra/Mods/Subclasses/ModPriority.cs rename to Penumbra/Mods/Settings/ModPriority.cs index a99c12ed..993bd577 100644 --- a/Penumbra/Mods/Subclasses/ModPriority.cs +++ b/Penumbra/Mods/Settings/ModPriority.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.Settings; [JsonConverter(typeof(Converter))] public readonly record struct ModPriority(int Value) : diff --git a/Penumbra/Mods/Subclasses/ModSettings.cs b/Penumbra/Mods/Settings/ModSettings.cs similarity index 98% rename from Penumbra/Mods/Subclasses/ModSettings.cs rename to Penumbra/Mods/Settings/ModSettings.cs index 2ddabdb8..db9e0521 100644 --- a/Penumbra/Mods/Subclasses/ModSettings.cs +++ b/Penumbra/Mods/Settings/ModSettings.cs @@ -1,12 +1,11 @@ using OtterGui; using OtterGui.Filesystem; using Penumbra.Api.Enums; -using Penumbra.Meta.Manipulations; using Penumbra.Mods.Editor; +using Penumbra.Mods.Groups; using Penumbra.Mods.Manager; -using Penumbra.String.Classes; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.Settings; /// Contains the settings for a given mod. public class ModSettings diff --git a/Penumbra/Mods/Subclasses/Setting.cs b/Penumbra/Mods/Settings/Setting.cs similarity index 98% rename from Penumbra/Mods/Subclasses/Setting.cs rename to Penumbra/Mods/Settings/Setting.cs index 18b1e4ca..231529b8 100644 --- a/Penumbra/Mods/Subclasses/Setting.cs +++ b/Penumbra/Mods/Settings/Setting.cs @@ -1,7 +1,7 @@ using Newtonsoft.Json; using OtterGui; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.Settings; [JsonConverter(typeof(Converter))] public readonly record struct Setting(ulong Value) diff --git a/Penumbra/Mods/Subclasses/SettingList.cs b/Penumbra/Mods/Settings/SettingList.cs similarity index 97% rename from Penumbra/Mods/Subclasses/SettingList.cs rename to Penumbra/Mods/Settings/SettingList.cs index ea1e447f..67b1b947 100644 --- a/Penumbra/Mods/Subclasses/SettingList.cs +++ b/Penumbra/Mods/Settings/SettingList.cs @@ -1,4 +1,4 @@ -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.Settings; public class SettingList : List { diff --git a/Penumbra/Mods/SubMods/DefaultSubMod.cs b/Penumbra/Mods/SubMods/DefaultSubMod.cs new file mode 100644 index 00000000..ced0cd0d --- /dev/null +++ b/Penumbra/Mods/SubMods/DefaultSubMod.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json.Linq; +using Penumbra.Meta.Manipulations; +using Penumbra.Mods.Editor; +using Penumbra.Mods.Groups; +using Penumbra.String.Classes; + +namespace Penumbra.Mods.SubMods; + +public class DefaultSubMod(IMod mod) : IModDataContainer +{ + public const string FullName = "Default Option"; + + internal readonly IMod Mod = mod; + + public Dictionary Files { get; set; } = []; + public Dictionary FileSwaps { get; set; } = []; + public HashSet Manipulations { get; set; } = []; + + IMod IModDataContainer.Mod + => Mod; + + IModGroup? IModDataContainer.Group + => null; + + public void AddDataTo(Dictionary redirections, HashSet manipulations) + => ((IModDataContainer)this).AddDataTo(redirections, manipulations); + + public (int GroupIndex, int DataIndex) GetDataIndices() + => (-1, 0); +} diff --git a/Penumbra/Mods/Subclasses/IModDataContainer.cs b/Penumbra/Mods/SubMods/IModDataContainer.cs similarity index 80% rename from Penumbra/Mods/Subclasses/IModDataContainer.cs rename to Penumbra/Mods/SubMods/IModDataContainer.cs index a26beb2a..18b3b23f 100644 --- a/Penumbra/Mods/Subclasses/IModDataContainer.cs +++ b/Penumbra/Mods/SubMods/IModDataContainer.cs @@ -2,18 +2,19 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Penumbra.Meta.Manipulations; using Penumbra.Mods.Editor; +using Penumbra.Mods.Groups; using Penumbra.String.Classes; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.SubMods; public interface IModDataContainer { - public IMod Mod { get; } + public IMod Mod { get; } public IModGroup? Group { get; } - public Dictionary Files { get; set; } - public Dictionary FileSwaps { get; set; } - public HashSet Manipulations { get; set; } + public Dictionary Files { get; set; } + public Dictionary FileSwaps { get; set; } + public HashSet Manipulations { get; set; } public void AddDataTo(Dictionary redirections, HashSet manipulations) { @@ -28,24 +29,24 @@ public interface IModDataContainer public string GetName() => this switch { - IModOption o => o.FullName, + IModOption o => o.FullName, DefaultSubMod => DefaultSubMod.FullName, - _ => $"Container {GetDataIndices().DataIndex + 1}", + _ => $"Container {GetDataIndices().DataIndex + 1}", }; public string GetFullName() => this switch { - IModOption o => o.FullName, - DefaultSubMod => DefaultSubMod.FullName, + IModOption o => o.FullName, + DefaultSubMod => DefaultSubMod.FullName, _ when Group != null => $"{Group.Name}: Container {GetDataIndices().DataIndex + 1}", - _ => $"Container {GetDataIndices().DataIndex + 1}", + _ => $"Container {GetDataIndices().DataIndex + 1}", }; public static void Clone(IModDataContainer from, IModDataContainer to) { - to.Files = new Dictionary(from.Files); - to.FileSwaps = new Dictionary(from.FileSwaps); + to.Files = new Dictionary(from.Files); + to.FileSwaps = new Dictionary(from.FileSwaps); to.Manipulations = [.. from.Manipulations]; } @@ -126,3 +127,5 @@ public interface IModDataContainer } } } + +public interface IModDataOption : IModOption, IModDataContainer; diff --git a/Penumbra/Mods/Subclasses/IModOption.cs b/Penumbra/Mods/SubMods/IModOption.cs similarity index 72% rename from Penumbra/Mods/Subclasses/IModOption.cs rename to Penumbra/Mods/SubMods/IModOption.cs index f66ce44e..f1ce1d4c 100644 --- a/Penumbra/Mods/Subclasses/IModOption.cs +++ b/Penumbra/Mods/SubMods/IModOption.cs @@ -1,17 +1,17 @@ using Newtonsoft.Json; using Newtonsoft.Json.Linq; -namespace Penumbra.Mods.Subclasses; +namespace Penumbra.Mods.SubMods; public interface IModOption { - public string Name { get; set; } - public string FullName { get; } + public string Name { get; set; } + public string FullName { get; } public string Description { get; set; } public static void Load(JToken json, IModOption option) { - option.Name = json[nameof(Name)]?.ToObject() ?? string.Empty; + option.Name = json[nameof(Name)]?.ToObject() ?? string.Empty; option.Description = json[nameof(Description)]?.ToObject() ?? string.Empty; } diff --git a/Penumbra/Mods/SubMods/MultiSubMod.cs b/Penumbra/Mods/SubMods/MultiSubMod.cs new file mode 100644 index 00000000..00216b77 --- /dev/null +++ b/Penumbra/Mods/SubMods/MultiSubMod.cs @@ -0,0 +1,92 @@ +using Newtonsoft.Json.Linq; +using OtterGui; +using Penumbra.Meta.Manipulations; +using Penumbra.Mods.Editor; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; +using Penumbra.String.Classes; + +namespace Penumbra.Mods.SubMods; + +public class MultiSubMod(Mod mod, MultiModGroup group) : IModDataOption +{ + internal readonly Mod Mod = mod; + internal readonly MultiModGroup Group = group; + + public string Name { get; set; } = "Option"; + + public string FullName + => $"{Group.Name}: {Name}"; + + public string Description { get; set; } = string.Empty; + public ModPriority Priority { get; set; } = ModPriority.Default; + + public Dictionary Files { get; set; } = []; + public Dictionary FileSwaps { get; set; } = []; + public HashSet Manipulations { get; set; } = []; + + IMod IModDataContainer.Mod + => Mod; + + IModGroup IModDataContainer.Group + => Group; + + + public MultiSubMod(Mod mod, MultiModGroup group, JToken json) + : this(mod, group) + { + IModOption.Load(json, this); + IModDataContainer.Load(json, this, mod.ModPath); + Priority = json[nameof(IModGroup.Priority)]?.ToObject() ?? ModPriority.Default; + } + + public MultiSubMod Clone(Mod mod, MultiModGroup group) + { + var ret = new MultiSubMod(mod, group) + { + Name = Name, + Description = Description, + Priority = Priority, + }; + IModDataContainer.Clone(this, ret); + + return ret; + } + + public SingleSubMod ConvertToSingle(Mod mod, SingleModGroup group) + { + var ret = new SingleSubMod(mod, group) + { + Name = Name, + Description = Description, + }; + IModDataContainer.Clone(this, ret); + return ret; + } + + public void AddDataTo(Dictionary redirections, HashSet manipulations) + => ((IModDataContainer)this).AddDataTo(redirections, manipulations); + + public static MultiSubMod CreateForSaving(string name, string description, ModPriority priority) + => new(null!, null!) + { + Name = name, + Description = description, + Priority = priority, + }; + + public (int GroupIndex, int DataIndex) GetDataIndices() + => (Group.GetIndex(), GetDataIndex()); + + public (int GroupIndex, int OptionIndex) GetOptionIndices() + => (Group.GetIndex(), GetDataIndex()); + + private int GetDataIndex() + { + var dataIndex = Group.DataContainers.IndexOf(this); + if (dataIndex < 0) + throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod."); + + return dataIndex; + } +} diff --git a/Penumbra/Mods/SubMods/SingleSubMod.cs b/Penumbra/Mods/SubMods/SingleSubMod.cs new file mode 100644 index 00000000..499ab192 --- /dev/null +++ b/Penumbra/Mods/SubMods/SingleSubMod.cs @@ -0,0 +1,82 @@ +using Newtonsoft.Json.Linq; +using OtterGui; +using Penumbra.Meta.Manipulations; +using Penumbra.Mods.Editor; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; +using Penumbra.String.Classes; + +namespace Penumbra.Mods.SubMods; + +public class SingleSubMod(Mod mod, SingleModGroup group) : IModDataOption +{ + internal readonly Mod Mod = mod; + internal readonly SingleModGroup Group = group; + + public string Name { get; set; } = "Option"; + + public string FullName + => $"{Group.Name}: {Name}"; + + public string Description { get; set; } = string.Empty; + + IMod IModDataContainer.Mod + => Mod; + + IModGroup IModDataContainer.Group + => Group; + + public Dictionary Files { get; set; } = []; + public Dictionary FileSwaps { get; set; } = []; + public HashSet Manipulations { get; set; } = []; + + public SingleSubMod(Mod mod, SingleModGroup group, JToken json) + : this(mod, group) + { + IModOption.Load(json, this); + IModDataContainer.Load(json, this, mod.ModPath); + } + + public SingleSubMod Clone(Mod mod, SingleModGroup group) + { + var ret = new SingleSubMod(mod, group) + { + Name = Name, + Description = Description, + }; + IModDataContainer.Clone(this, ret); + + return ret; + } + + public MultiSubMod ConvertToMulti(Mod mod, MultiModGroup group, ModPriority priority) + { + var ret = new MultiSubMod(mod, group) + { + Name = Name, + Description = Description, + Priority = priority, + }; + IModDataContainer.Clone(this, ret); + + return ret; + } + + public void AddDataTo(Dictionary redirections, HashSet manipulations) + => ((IModDataContainer)this).AddDataTo(redirections, manipulations); + + public (int GroupIndex, int DataIndex) GetDataIndices() + => (Group.GetIndex(), GetDataIndex()); + + public (int GroupIndex, int OptionIndex) GetOptionIndices() + => (Group.GetIndex(), GetDataIndex()); + + private int GetDataIndex() + { + var dataIndex = Group.DataContainers.IndexOf(this); + if (dataIndex < 0) + throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod."); + + return dataIndex; + } +} diff --git a/Penumbra/Mods/Subclasses/SubMod.cs b/Penumbra/Mods/Subclasses/SubMod.cs deleted file mode 100644 index a2425eb7..00000000 --- a/Penumbra/Mods/Subclasses/SubMod.cs +++ /dev/null @@ -1,352 +0,0 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using OtterGui; -using Penumbra.Meta.Manipulations; -using Penumbra.Mods.Editor; -using Penumbra.String.Classes; - -namespace Penumbra.Mods.Subclasses; - -public interface IModDataOption : IModOption, IModDataContainer; - -public class SingleSubMod(Mod mod, SingleModGroup group) : IModDataOption -{ - internal readonly Mod Mod = mod; - internal readonly SingleModGroup Group = group; - - public string Name { get; set; } = "Option"; - - public string FullName - => $"{Group.Name}: {Name}"; - - public string Description { get; set; } = string.Empty; - - IMod IModDataContainer.Mod - => Mod; - - IModGroup IModDataContainer.Group - => Group; - - public Dictionary Files { get; set; } = []; - public Dictionary FileSwaps { get; set; } = []; - public HashSet Manipulations { get; set; } = []; - - public SingleSubMod(Mod mod, SingleModGroup group, JToken json) - : this(mod, group) - { - IModOption.Load(json, this); - IModDataContainer.Load(json, this, mod.ModPath); - } - - public SingleSubMod Clone(Mod mod, SingleModGroup group) - { - var ret = new SingleSubMod(mod, group) - { - Name = Name, - Description = Description, - }; - IModDataContainer.Clone(this, ret); - - return ret; - } - - public MultiSubMod ConvertToMulti(Mod mod, MultiModGroup group, ModPriority priority) - { - var ret = new MultiSubMod(mod, group) - { - Name = Name, - Description = Description, - Priority = priority, - }; - IModDataContainer.Clone(this, ret); - - return ret; - } - - public void AddDataTo(Dictionary redirections, HashSet manipulations) - => ((IModDataContainer)this).AddDataTo(redirections, manipulations); - - public (int GroupIndex, int DataIndex) GetDataIndices() - => (Group.GetIndex(), GetDataIndex()); - - public (int GroupIndex, int OptionIndex) GetOptionIndices() - => (Group.GetIndex(), GetDataIndex()); - - private int GetDataIndex() - { - var dataIndex = Group.DataContainers.IndexOf(this); - if (dataIndex < 0) - throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod."); - - return dataIndex; - } -} - -public class MultiSubMod(Mod mod, MultiModGroup group) : IModDataOption -{ - internal readonly Mod Mod = mod; - internal readonly MultiModGroup Group = group; - - public string Name { get; set; } = "Option"; - - public string FullName - => $"{Group.Name}: {Name}"; - - public string Description { get; set; } = string.Empty; - public ModPriority Priority { get; set; } = ModPriority.Default; - - public Dictionary Files { get; set; } = []; - public Dictionary FileSwaps { get; set; } = []; - public HashSet Manipulations { get; set; } = []; - - IMod IModDataContainer.Mod - => Mod; - - IModGroup IModDataContainer.Group - => Group; - - - public MultiSubMod(Mod mod, MultiModGroup group, JToken json) - : this(mod, group) - { - IModOption.Load(json, this); - IModDataContainer.Load(json, this, mod.ModPath); - Priority = json[nameof(IModGroup.Priority)]?.ToObject() ?? ModPriority.Default; - } - - public MultiSubMod Clone(Mod mod, MultiModGroup group) - { - var ret = new MultiSubMod(mod, group) - { - Name = Name, - Description = Description, - Priority = Priority, - }; - IModDataContainer.Clone(this, ret); - - return ret; - } - - public SingleSubMod ConvertToSingle(Mod mod, SingleModGroup group) - { - var ret = new SingleSubMod(mod, group) - { - Name = Name, - Description = Description, - }; - IModDataContainer.Clone(this, ret); - return ret; - } - - public void AddDataTo(Dictionary redirections, HashSet manipulations) - => ((IModDataContainer)this).AddDataTo(redirections, manipulations); - - public static MultiSubMod CreateForSaving(string name, string description, ModPriority priority) - => new(null!, null!) - { - Name = name, - Description = description, - Priority = priority, - }; - - public (int GroupIndex, int DataIndex) GetDataIndices() - => (Group.GetIndex(), GetDataIndex()); - - public (int GroupIndex, int OptionIndex) GetOptionIndices() - => (Group.GetIndex(), GetDataIndex()); - - private int GetDataIndex() - { - var dataIndex = Group.DataContainers.IndexOf(this); - if (dataIndex < 0) - throw new Exception($"Group {Group.Name} from SubMod {Name} does not contain this SubMod."); - - return dataIndex; - } -} - -public class DefaultSubMod(IMod mod) : IModDataContainer -{ - public const string FullName = "Default Option"; - - public string Description - => string.Empty; - - internal readonly IMod Mod = mod; - - public Dictionary Files { get; set; } = []; - public Dictionary FileSwaps { get; set; } = []; - public HashSet Manipulations { get; set; } = []; - - IMod IModDataContainer.Mod - => Mod; - - IModGroup? IModDataContainer.Group - => null; - - - public DefaultSubMod(Mod mod, JToken json) - : this(mod) - { - IModDataContainer.Load(json, this, mod.ModPath); - } - - public void AddDataTo(Dictionary redirections, HashSet manipulations) - => ((IModDataContainer)this).AddDataTo(redirections, manipulations); - - public (int GroupIndex, int DataIndex) GetDataIndices() - => (-1, 0); -} - - -//public sealed class SubMod(IMod mod, IModGroup group) : IModOption -//{ -// public string Name { get; set; } = "Default"; -// -// public string FullName -// => Group == null ? "Default Option" : $"{Group.Name}: {Name}"; -// -// public string Description { get; set; } = string.Empty; -// -// internal readonly IMod Mod = mod; -// internal readonly IModGroup? Group = group; -// -// internal (int GroupIdx, int OptionIdx) GetIndices() -// { -// if (IsDefault) -// return (-1, 0); -// -// var groupIdx = Mod.Groups.IndexOf(Group); -// if (groupIdx < 0) -// throw new Exception($"Group {Group.Name} from SubMod {Name} is not contained in Mod {Mod.Name}."); -// -// return (groupIdx, GetOptionIndex()); -// } -// -// private int GetOptionIndex() -// { -// var optionIndex = Group switch -// { -// null => 0, -// SingleModGroup single => single.OptionData.IndexOf(this), -// MultiModGroup multi => multi.OptionData.IndexOf(p => p.Mod == this), -// _ => throw new Exception($"Group {Group.Name} from SubMod {Name} has unknown type {typeof(Group)}"), -// }; -// if (optionIndex < 0) -// throw new Exception($"Group {Group!.Name} from SubMod {Name} does not contain this SubMod."); -// -// return optionIndex; -// } -// -// public static SubMod CreateDefault(IMod mod) -// => new(mod, null!); -// -// [MemberNotNullWhen(false, nameof(Group))] -// public bool IsDefault -// => Group == null; -// -// public void AddData(Dictionary redirections, HashSet manipulations) -// { -// foreach (var (path, file) in Files) -// redirections.TryAdd(path, file); -// -// foreach (var (path, file) in FileSwaps) -// redirections.TryAdd(path, file); -// manipulations.UnionWith(Manipulations); -// } -// -// public Dictionary FileData = []; -// public Dictionary FileSwapData = []; -// public HashSet ManipulationData = []; -// -// public IReadOnlyDictionary Files -// => FileData; -// -// public IReadOnlyDictionary FileSwaps -// => FileSwapData; -// -// public IReadOnlySet Manipulations -// => ManipulationData; -// -// public void Load(DirectoryInfo basePath, JToken json, out ModPriority priority) -// { -// FileData.Clear(); -// FileSwapData.Clear(); -// ManipulationData.Clear(); -// -// // Every option has a name, but priorities are only relevant for multi group options. -// Name = json[nameof(Name)]?.ToObject() ?? string.Empty; -// Description = json[nameof(Description)]?.ToObject() ?? string.Empty; -// priority = json[nameof(IModGroup.Priority)]?.ToObject() ?? ModPriority.Default; -// -// var files = (JObject?)json[nameof(Files)]; -// if (files != null) -// foreach (var property in files.Properties()) -// { -// if (Utf8GamePath.FromString(property.Name, out var p, true)) -// FileData.TryAdd(p, new FullPath(basePath, property.Value.ToObject())); -// } -// -// var swaps = (JObject?)json[nameof(FileSwaps)]; -// if (swaps != null) -// foreach (var property in swaps.Properties()) -// { -// if (Utf8GamePath.FromString(property.Name, out var p, true)) -// FileSwapData.TryAdd(p, new FullPath(property.Value.ToObject()!)); -// } -// -// var manips = json[nameof(Manipulations)]; -// if (manips != null) -// foreach (var s in manips.Children().Select(c => c.ToObject()) -// .Where(m => m.Validate())) -// ManipulationData.Add(s); -// } -// -// -// /// Create a sub mod without a mod or group only for saving it in the creator. -// internal static SubMod CreateForSaving(string name) -// => new(null!, null!) -// { -// Name = name, -// }; -// -// -// public static void WriteSubMod(JsonWriter j, JsonSerializer serializer, SubMod mod, DirectoryInfo basePath, ModPriority? priority) -// { -// j.WriteStartObject(); -// j.WritePropertyName(nameof(Name)); -// j.WriteValue(mod.Name); -// j.WritePropertyName(nameof(Description)); -// j.WriteValue(mod.Description); -// if (priority != null) -// { -// j.WritePropertyName(nameof(IModGroup.Priority)); -// j.WriteValue(priority.Value.Value); -// } -// -// j.WritePropertyName(nameof(mod.Files)); -// j.WriteStartObject(); -// foreach (var (gamePath, file) in mod.Files) -// { -// if (file.ToRelPath(basePath, out var relPath)) -// { -// j.WritePropertyName(gamePath.ToString()); -// j.WriteValue(relPath.ToString()); -// } -// } -// -// j.WriteEndObject(); -// j.WritePropertyName(nameof(mod.FileSwaps)); -// j.WriteStartObject(); -// foreach (var (gamePath, file) in mod.FileSwaps) -// { -// j.WritePropertyName(gamePath.ToString()); -// j.WriteValue(file.ToString()); -// } -// -// j.WriteEndObject(); -// j.WritePropertyName(nameof(mod.Manipulations)); -// serializer.Serialize(j, mod.Manipulations); -// j.WriteEndObject(); -// } -//} diff --git a/Penumbra/Mods/TemporaryMod.cs b/Penumbra/Mods/TemporaryMod.cs index 393369d4..d08c8b06 100644 --- a/Penumbra/Mods/TemporaryMod.cs +++ b/Penumbra/Mods/TemporaryMod.cs @@ -2,8 +2,10 @@ using OtterGui.Classes; using Penumbra.Collections; using Penumbra.Meta.Manipulations; using Penumbra.Mods.Editor; +using Penumbra.Mods.Groups; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String.Classes; @@ -46,7 +48,7 @@ public class TemporaryMod : IMod => Array.Empty(); public TemporaryMod() - => Default = new(this); + => Default = new DefaultSubMod(this); public void SetFile(Utf8GamePath gamePath, FullPath fullPath) => Default.Files[gamePath] = fullPath; diff --git a/Penumbra/Penumbra.csproj b/Penumbra/Penumbra.csproj index c8961579..0ec1fd44 100644 --- a/Penumbra/Penumbra.csproj +++ b/Penumbra/Penumbra.csproj @@ -93,6 +93,10 @@ + + + + diff --git a/Penumbra/Services/ConfigMigrationService.cs b/Penumbra/Services/ConfigMigrationService.cs index e775d81a..fafaa0e5 100644 --- a/Penumbra/Services/ConfigMigrationService.cs +++ b/Penumbra/Services/ConfigMigrationService.cs @@ -10,7 +10,7 @@ using Penumbra.Interop.Services; using Penumbra.Mods; using Penumbra.Mods.Editor; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.UI; using Penumbra.UI.Classes; using Penumbra.UI.ResourceWatcher; diff --git a/Penumbra/Services/SaveService.cs b/Penumbra/Services/SaveService.cs index 801e0c1d..8d3cb641 100644 --- a/Penumbra/Services/SaveService.cs +++ b/Penumbra/Services/SaveService.cs @@ -2,7 +2,7 @@ using OtterGui.Classes; using OtterGui.Log; using OtterGui.Services; using Penumbra.Mods; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Groups; namespace Penumbra.Services; diff --git a/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs b/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs index 5125a5b2..77bdb161 100644 --- a/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs +++ b/Penumbra/UI/AdvancedWindow/ItemSwapTab.cs @@ -13,9 +13,10 @@ using Penumbra.GameData.Enums; using Penumbra.GameData.Structs; using Penumbra.Meta; using Penumbra.Mods; +using Penumbra.Mods.Groups; using Penumbra.Mods.ItemSwap; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; using Penumbra.UI.Classes; diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.Files.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.Files.cs index 94f1d577..107c56e6 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.Files.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.Files.cs @@ -4,7 +4,7 @@ using OtterGui; using OtterGui.Classes; using OtterGui.Raii; using Penumbra.Mods.Editor; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; using Penumbra.UI.Classes; diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.QuickImport.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.QuickImport.cs index 70854fe7..55b7e748 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.QuickImport.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.QuickImport.cs @@ -8,7 +8,7 @@ using Penumbra.GameData.Files; using Penumbra.Interop.ResourceTree; using Penumbra.Mods; using Penumbra.Mods.Editor; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.String.Classes; namespace Penumbra.UI.AdvancedWindow; diff --git a/Penumbra/UI/AdvancedWindow/ModEditWindow.cs b/Penumbra/UI/AdvancedWindow/ModEditWindow.cs index 21d14f78..dbb88fb7 100644 --- a/Penumbra/UI/AdvancedWindow/ModEditWindow.cs +++ b/Penumbra/UI/AdvancedWindow/ModEditWindow.cs @@ -21,7 +21,7 @@ using Penumbra.Meta; using Penumbra.Mods; using Penumbra.Mods.Editor; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.Services; using Penumbra.String; using Penumbra.String.Classes; diff --git a/Penumbra/UI/AdvancedWindow/ModMergeTab.cs b/Penumbra/UI/AdvancedWindow/ModMergeTab.cs index bed31ab8..5dad66b4 100644 --- a/Penumbra/UI/AdvancedWindow/ModMergeTab.cs +++ b/Penumbra/UI/AdvancedWindow/ModMergeTab.cs @@ -4,7 +4,7 @@ using OtterGui; using OtterGui.Raii; using Penumbra.Mods.Editor; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.SubMods; using Penumbra.UI.Classes; namespace Penumbra.UI.AdvancedWindow; diff --git a/Penumbra/UI/ModsTab/ModFileSystemSelector.cs b/Penumbra/UI/ModsTab/ModFileSystemSelector.cs index 11a2d96f..5b6cfa99 100644 --- a/Penumbra/UI/ModsTab/ModFileSystemSelector.cs +++ b/Penumbra/UI/ModsTab/ModFileSystemSelector.cs @@ -14,7 +14,7 @@ using Penumbra.Collections.Manager; using Penumbra.Communication; using Penumbra.Mods; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.Services; using Penumbra.UI.Classes; using MessageService = Penumbra.Services.MessageService; diff --git a/Penumbra/UI/ModsTab/ModPanelConflictsTab.cs b/Penumbra/UI/ModsTab/ModPanelConflictsTab.cs index b2cfaf25..5e3aac48 100644 --- a/Penumbra/UI/ModsTab/ModPanelConflictsTab.cs +++ b/Penumbra/UI/ModsTab/ModPanelConflictsTab.cs @@ -9,7 +9,7 @@ using Penumbra.Collections.Manager; using Penumbra.Meta.Manipulations; using Penumbra.Mods; using Penumbra.Mods.Editor; -using Penumbra.Mods.Subclasses; +using Penumbra.Mods.Settings; using Penumbra.String.Classes; using Penumbra.UI.Classes; diff --git a/Penumbra/UI/ModsTab/ModPanelEditTab.cs b/Penumbra/UI/ModsTab/ModPanelEditTab.cs index c05f1ac1..afbef45d 100644 --- a/Penumbra/UI/ModsTab/ModPanelEditTab.cs +++ b/Penumbra/UI/ModsTab/ModPanelEditTab.cs @@ -11,9 +11,10 @@ using Penumbra.Api.Enums; using Penumbra.Mods; using Penumbra.Mods.Editor; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; using Penumbra.Services; using Penumbra.UI.AdvancedWindow; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; namespace Penumbra.UI.ModsTab; diff --git a/Penumbra/UI/ModsTab/ModPanelSettingsTab.cs b/Penumbra/UI/ModsTab/ModPanelSettingsTab.cs index cb76088c..1326a763 100644 --- a/Penumbra/UI/ModsTab/ModPanelSettingsTab.cs +++ b/Penumbra/UI/ModsTab/ModPanelSettingsTab.cs @@ -8,8 +8,10 @@ using Penumbra.UI.Classes; using Dalamud.Interface.Components; using Penumbra.Collections.Manager; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; using Penumbra.Services; +using Penumbra.Mods.SubMods; +using Penumbra.Mods.Groups; +using Penumbra.Mods.Settings; namespace Penumbra.UI.ModsTab; diff --git a/Penumbra/UI/ModsTab/ModPanelTabBar.cs b/Penumbra/UI/ModsTab/ModPanelTabBar.cs index 1aaa7741..8b09d8b9 100644 --- a/Penumbra/UI/ModsTab/ModPanelTabBar.cs +++ b/Penumbra/UI/ModsTab/ModPanelTabBar.cs @@ -5,7 +5,6 @@ using OtterGui.Raii; using OtterGui.Widgets; using Penumbra.Mods; using Penumbra.Mods.Manager; -using Penumbra.Mods.Subclasses; using Penumbra.UI.AdvancedWindow; namespace Penumbra.UI.ModsTab;