Reorder stuff.

This commit is contained in:
Ottermandias 2024-04-24 23:28:12 +02:00
parent 6b1743b776
commit 514121d8c1
58 changed files with 416 additions and 539 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -1,4 +1,4 @@
using Penumbra.Mods.Subclasses;
using Penumbra.Mods.SubMods;
using Penumbra.String.Classes;
namespace Penumbra.Mods.Editor;

View file

@ -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;

View file

@ -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;

View file

@ -1,5 +1,5 @@
using OtterGui;
using Penumbra.Mods.Subclasses;
using Penumbra.Mods.SubMods;
using Penumbra.String.Classes;
namespace Penumbra.Mods.Editor;

View file

@ -1,5 +1,5 @@
using Penumbra.Mods.Manager;
using Penumbra.Mods.Subclasses;
using Penumbra.Mods.SubMods;
using Penumbra.Services;
using Penumbra.String.Classes;

View file

@ -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;

View file

@ -1,6 +1,6 @@
using Penumbra.Meta.Manipulations;
using Penumbra.Mods.Manager;
using Penumbra.Mods.Subclasses;
using Penumbra.Mods.SubMods;
namespace Penumbra.Mods.Editor;

View file

@ -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;

View file

@ -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;

View file

@ -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
{
@ -100,55 +100,3 @@ public interface IModGroup
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();
}
}

View file

@ -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();
}
}

View file

@ -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;
/// <summary> Groups that allow all available options to be selected at once. </summary>
public sealed class MultiModGroup(Mod mod) : IModGroup, ITexToolsGroup
@ -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);
/// <summary> Create a group without a mod only for saving it in the creator. </summary>
internal static MultiModGroup CreateForSaving(string name)

View file

@ -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;
/// <summary> Groups that allow only one of their available options to be selected. </summary>
public sealed class SingleModGroup(Mod mod) : IModGroup, ITexToolsGroup

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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) :

View file

@ -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;
/// <summary> Contains the settings for a given mod. </summary>
public class ModSettings

View file

@ -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)

View file

@ -1,4 +1,4 @@
namespace Penumbra.Mods.Subclasses;
namespace Penumbra.Mods.Settings;
public class SettingList : List<Setting>
{

View file

@ -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<Utf8GamePath, FullPath> Files { get; set; } = [];
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
public HashSet<MetaManipulation> Manipulations { get; set; } = [];
IMod IModDataContainer.Mod
=> Mod;
IModGroup? IModDataContainer.Group
=> null;
public void AddDataTo(Dictionary<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> manipulations)
=> ((IModDataContainer)this).AddDataTo(redirections, manipulations);
public (int GroupIndex, int DataIndex) GetDataIndices()
=> (-1, 0);
}

View file

@ -2,9 +2,10 @@ 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
{
@ -126,3 +127,5 @@ public interface IModDataContainer
}
}
}
public interface IModDataOption : IModOption, IModDataContainer;

View file

@ -1,7 +1,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Penumbra.Mods.Subclasses;
namespace Penumbra.Mods.SubMods;
public interface IModOption
{

View file

@ -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<Utf8GamePath, FullPath> Files { get; set; } = [];
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
public HashSet<MetaManipulation> 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>() ?? 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<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> 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;
}
}

View file

@ -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<Utf8GamePath, FullPath> Files { get; set; } = [];
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
public HashSet<MetaManipulation> 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<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> 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;
}
}

View file

@ -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<Utf8GamePath, FullPath> Files { get; set; } = [];
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
public HashSet<MetaManipulation> 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<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> 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<Utf8GamePath, FullPath> Files { get; set; } = [];
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
public HashSet<MetaManipulation> 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>() ?? 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<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> 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<Utf8GamePath, FullPath> Files { get; set; } = [];
public Dictionary<Utf8GamePath, FullPath> FileSwaps { get; set; } = [];
public HashSet<MetaManipulation> 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<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> 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<Utf8GamePath, FullPath> redirections, HashSet<MetaManipulation> 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<Utf8GamePath, FullPath> FileData = [];
// public Dictionary<Utf8GamePath, FullPath> FileSwapData = [];
// public HashSet<MetaManipulation> ManipulationData = [];
//
// public IReadOnlyDictionary<Utf8GamePath, FullPath> Files
// => FileData;
//
// public IReadOnlyDictionary<Utf8GamePath, FullPath> FileSwaps
// => FileSwapData;
//
// public IReadOnlySet<MetaManipulation> 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>() ?? string.Empty;
// Description = json[nameof(Description)]?.ToObject<string>() ?? string.Empty;
// priority = json[nameof(IModGroup.Priority)]?.ToObject<ModPriority>() ?? 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<Utf8RelPath>()));
// }
//
// 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<string>()!));
// }
//
// var manips = json[nameof(Manipulations)];
// if (manips != null)
// foreach (var s in manips.Children().Select(c => c.ToObject<MetaManipulation>())
// .Where(m => m.Validate()))
// ManipulationData.Add(s);
// }
//
//
// /// <summary> Create a sub mod without a mod or group only for saving it in the creator. </summary>
// 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();
// }
//}

View file

@ -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<IModGroup>();
public TemporaryMod()
=> Default = new(this);
=> Default = new DefaultSubMod(this);
public void SetFile(Utf8GamePath gamePath, FullPath fullPath)
=> Default.Files[gamePath] = fullPath;

View file

@ -93,6 +93,10 @@
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Mods\Subclasses\" />
</ItemGroup>
<Target Name="GetGitHash" BeforeTargets="GetAssemblyVersion" Returns="InformationalVersion">
<Exec Command="git rev-parse --short HEAD" ConsoleToMSBuild="true" StandardOutputImportance="low" ContinueOnError="true">
<Output TaskParameter="ExitCode" PropertyName="GitCommitHashSuccess" />

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;