Delete default meta entries from archives and api added mods if not configured otherwise.

This commit is contained in:
Ottermandias 2024-08-29 17:47:51 +02:00
parent f8e3b6777f
commit f5e6132462
14 changed files with 95 additions and 73 deletions

View file

@ -82,7 +82,7 @@ public class ModsApi : IPenumbraApiMods, IApiService, IDisposable
!= Path.TrimEndingDirectorySeparator(Path.GetFullPath(dir.Parent.FullName))) != Path.TrimEndingDirectorySeparator(Path.GetFullPath(dir.Parent.FullName)))
return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args); return ApiHelpers.Return(PenumbraApiEc.InvalidArgument, args);
_modManager.AddMod(dir); _modManager.AddMod(dir, true);
if (_config.MigrateImportedModelsToV6) if (_config.MigrateImportedModelsToV6)
{ {
_migrationManager.MigrateMdlDirectory(dir.FullName, false); _migrationManager.MigrateMdlDirectory(dir.FullName, false);

View file

@ -225,7 +225,7 @@ public class DuplicateManager(ModManager modManager, SaveService saveService, Co
if (!useModManager || !modManager.TryGetMod(modDirectory.Name, string.Empty, out var mod)) if (!useModManager || !modManager.TryGetMod(modDirectory.Name, string.Empty, out var mod))
{ {
mod = new Mod(modDirectory); mod = new Mod(modDirectory);
modManager.Creator.ReloadMod(mod, true, out _); modManager.Creator.ReloadMod(mod, true, true, out _);
} }
Clear(); Clear();

View file

@ -151,7 +151,7 @@ public class ModFileEditor(ModFileCollection files, ModManager modManager, Commu
if (deletions <= 0) if (deletions <= 0)
return; return;
modManager.Creator.ReloadMod(mod, false, out _); modManager.Creator.ReloadMod(mod, false, false, out _);
files.UpdateAll(mod, option); files.UpdateAll(mod, option);
} }

View file

@ -256,7 +256,7 @@ public class ModMerger : IDisposable, IService
if (dir == null) if (dir == null)
throw new Exception($"Could not split off mods, unable to create new mod with name {modName}."); throw new Exception($"Could not split off mods, unable to create new mod with name {modName}.");
_mods.AddMod(dir); _mods.AddMod(dir, false);
result = _mods[^1]; result = _mods[^1];
if (mods.Count == 1) if (mods.Count == 1)
{ {

View file

@ -3,12 +3,15 @@ using OtterGui.Services;
using Penumbra.Meta; using Penumbra.Meta;
using Penumbra.Meta.Files; using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations; using Penumbra.Meta.Manipulations;
using Penumbra.Mods.Manager; using Penumbra.Mods.Manager.OptionEditor;
using Penumbra.Mods.SubMods; using Penumbra.Mods.SubMods;
namespace Penumbra.Mods.Editor; namespace Penumbra.Mods.Editor;
public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManager, ImcChecker imcChecker) : MetaDictionary, IService public class ModMetaEditor(
ModGroupEditor groupEditor,
MetaFileManager metaFileManager,
ImcChecker imcChecker) : MetaDictionary, IService
{ {
public sealed class OtherOptionData : HashSet<string> public sealed class OtherOptionData : HashSet<string>
{ {
@ -64,11 +67,11 @@ public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManage
Changes = false; Changes = false;
} }
public bool DeleteDefaultValues(MetaDictionary dict) public static bool DeleteDefaultValues(MetaFileManager metaFileManager, ImcChecker imcChecker, MetaDictionary dict)
{ {
var clone = dict.Clone(); var clone = dict.Clone();
dict.Clear(); dict.Clear();
var ret = false; var count = 0;
foreach (var (key, value) in clone.Imc) foreach (var (key, value) in clone.Imc)
{ {
var defaultEntry = imcChecker.GetDefaultEntry(key, false); var defaultEntry = imcChecker.GetDefaultEntry(key, false);
@ -79,7 +82,7 @@ public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManage
else else
{ {
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}."); Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
ret = true; ++count;
} }
} }
@ -93,7 +96,7 @@ public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManage
else else
{ {
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}."); Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
ret = true; ++count;
} }
} }
@ -107,7 +110,7 @@ public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManage
else else
{ {
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}."); Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
ret = true; ++count;
} }
} }
@ -121,7 +124,7 @@ public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManage
else else
{ {
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}."); Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
ret = true; ++count;
} }
} }
@ -135,7 +138,7 @@ public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManage
else else
{ {
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}."); Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
ret = true; ++count;
} }
} }
@ -149,22 +152,26 @@ public class ModMetaEditor(ModManager modManager, MetaFileManager metaFileManage
else else
{ {
Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}."); Penumbra.Log.Verbose($"Deleted default-valued meta-entry {key}.");
ret = true; ++count;
} }
} }
return ret; if (count <= 0)
return false;
Penumbra.Log.Debug($"Deleted {count} default-valued meta-entries from a mod option.");
return true;
} }
public void DeleteDefaultValues() public void DeleteDefaultValues()
=> Changes = DeleteDefaultValues(this); => Changes = DeleteDefaultValues(metaFileManager, imcChecker, this);
public void Apply(IModDataContainer container) public void Apply(IModDataContainer container)
{ {
if (!Changes) if (!Changes)
return; return;
modManager.OptionEditor.SetManipulations(container, this); groupEditor.SetManipulations(container, this);
Changes = false; Changes = false;
} }
} }

View file

@ -46,7 +46,7 @@ public class ModNormalizer(ModManager modManager, Configuration config, SaveServ
if (!config.AutoReduplicateUiOnImport) if (!config.AutoReduplicateUiOnImport)
return; return;
if (modManager.Creator.LoadMod(modDirectory, false) is not { } mod) if (modManager.Creator.LoadMod(modDirectory, false, false) is not { } mod)
return; return;
Dictionary<FullPath, List<(IModDataContainer, Utf8GamePath)>> paths = []; Dictionary<FullPath, List<(IModDataContainer, Utf8GamePath)>> paths = [];

View file

@ -79,7 +79,7 @@ public class ModImportManager(ModManager modManager, Configuration config, ModEd
return false; return false;
} }
modManager.AddMod(directory); modManager.AddMod(directory, true);
mod = modManager.LastOrDefault(); mod = modManager.LastOrDefault();
return mod != null && mod.ModPath == directory; return mod != null && mod.ModPath == directory;
} }

View file

@ -81,13 +81,13 @@ public sealed class ModManager : ModStorage, IDisposable, IService
} }
/// <summary> Load a new mod and add it to the manager if successful. </summary> /// <summary> Load a new mod and add it to the manager if successful. </summary>
public void AddMod(DirectoryInfo modFolder) public void AddMod(DirectoryInfo modFolder, bool deleteDefaultMeta)
{ {
if (this.Any(m => m.ModPath.Name == modFolder.Name)) if (this.Any(m => m.ModPath.Name == modFolder.Name))
return; return;
Creator.SplitMultiGroups(modFolder); Creator.SplitMultiGroups(modFolder);
var mod = Creator.LoadMod(modFolder, true); var mod = Creator.LoadMod(modFolder, true, deleteDefaultMeta);
if (mod == null) if (mod == null)
return; return;
@ -141,7 +141,7 @@ public sealed class ModManager : ModStorage, IDisposable, IService
var oldName = mod.Name; var oldName = mod.Name;
_communicator.ModPathChanged.Invoke(ModPathChangeType.StartingReload, mod, mod.ModPath, mod.ModPath); _communicator.ModPathChanged.Invoke(ModPathChangeType.StartingReload, mod, mod.ModPath, mod.ModPath);
if (!Creator.ReloadMod(mod, true, out var metaChange)) if (!Creator.ReloadMod(mod, true, false, out var metaChange))
{ {
Penumbra.Log.Warning(mod.Name.Length == 0 Penumbra.Log.Warning(mod.Name.Length == 0
? $"Reloading mod {oldName} has failed, new name is empty. Removing from loaded mods instead." ? $"Reloading mod {oldName} has failed, new name is empty. Removing from loaded mods instead."
@ -206,7 +206,7 @@ public sealed class ModManager : ModStorage, IDisposable, IService
dir.Refresh(); dir.Refresh();
mod.ModPath = dir; mod.ModPath = dir;
if (!Creator.ReloadMod(mod, false, out var metaChange)) if (!Creator.ReloadMod(mod, false, false, out var metaChange))
{ {
Penumbra.Log.Error($"Error reloading moved mod {mod.Name}."); Penumbra.Log.Error($"Error reloading moved mod {mod.Name}.");
return; return;
@ -332,7 +332,7 @@ public sealed class ModManager : ModStorage, IDisposable, IService
var queue = new ConcurrentQueue<Mod>(); var queue = new ConcurrentQueue<Mod>();
Parallel.ForEach(BasePath.EnumerateDirectories(), options, dir => Parallel.ForEach(BasePath.EnumerateDirectories(), options, dir =>
{ {
var mod = Creator.LoadMod(dir, false); var mod = Creator.LoadMod(dir, false, false);
if (mod != null) if (mod != null)
queue.Enqueue(mod); queue.Enqueue(mod);
}); });

View file

@ -82,7 +82,7 @@ public static partial class ModMigration
foreach (var (gamePath, swapPath) in swaps) foreach (var (gamePath, swapPath) in swaps)
mod.Default.FileSwaps.Add(gamePath, swapPath); mod.Default.FileSwaps.Add(gamePath, swapPath);
creator.IncorporateMetaChanges(mod.Default, mod.ModPath, true); creator.IncorporateMetaChanges(mod.Default, mod.ModPath, true, true);
foreach (var group in mod.Groups) foreach (var group in mod.Groups)
saveService.ImmediateSave(new ModSaveGroup(group, creator.Config.ReplaceNonAsciiOnImport)); saveService.ImmediateSave(new ModSaveGroup(group, creator.Config.ReplaceNonAsciiOnImport));
@ -182,7 +182,7 @@ public static partial class ModMigration
Description = option.OptionDesc, Description = option.OptionDesc,
}; };
AddFilesToSubMod(subMod, mod.ModPath, option, seenMetaFiles); AddFilesToSubMod(subMod, mod.ModPath, option, seenMetaFiles);
creator.IncorporateMetaChanges(subMod, mod.ModPath, false); creator.IncorporateMetaChanges(subMod, mod.ModPath, false, true);
return subMod; return subMod;
} }
@ -196,7 +196,7 @@ public static partial class ModMigration
Priority = priority, Priority = priority,
}; };
AddFilesToSubMod(subMod, mod.ModPath, option, seenMetaFiles); AddFilesToSubMod(subMod, mod.ModPath, option, seenMetaFiles);
creator.IncorporateMetaChanges(subMod, mod.ModPath, false); creator.IncorporateMetaChanges(subMod, mod.ModPath, false, true);
return subMod; return subMod;
} }

View file

@ -39,7 +39,7 @@ public class ModGroupEditor(
ImcModGroupEditor imcEditor, ImcModGroupEditor imcEditor,
CommunicatorService communicator, CommunicatorService communicator,
SaveService saveService, SaveService saveService,
Configuration Config) : IService Configuration config) : IService
{ {
public SingleModGroupEditor SingleEditor public SingleModGroupEditor SingleEditor
=> singleEditor; => singleEditor;
@ -57,7 +57,7 @@ public class ModGroupEditor(
return; return;
group.DefaultSettings = defaultOption; group.DefaultSettings = defaultOption;
saveService.QueueSave(new ModSaveGroup(group, Config.ReplaceNonAsciiOnImport)); saveService.QueueSave(new ModSaveGroup(group, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.DefaultOptionChanged, group.Mod, group, null, null, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.DefaultOptionChanged, group.Mod, group, null, null, -1);
} }
@ -68,9 +68,9 @@ public class ModGroupEditor(
if (oldName == newName || !VerifyFileName(group.Mod, group, newName, true)) if (oldName == newName || !VerifyFileName(group.Mod, group, newName, true))
return; return;
saveService.ImmediateDelete(new ModSaveGroup(group, Config.ReplaceNonAsciiOnImport)); saveService.ImmediateDelete(new ModSaveGroup(group, config.ReplaceNonAsciiOnImport));
group.Name = newName; group.Name = newName;
saveService.ImmediateSave(new ModSaveGroup(group, Config.ReplaceNonAsciiOnImport)); saveService.ImmediateSave(new ModSaveGroup(group, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.GroupRenamed, group.Mod, group, null, null, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.GroupRenamed, group.Mod, group, null, null, -1);
} }
@ -81,7 +81,7 @@ public class ModGroupEditor(
var idx = group.GetIndex(); var idx = group.GetIndex();
communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, group, null, null, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, mod, group, null, null, -1);
mod.Groups.RemoveAt(idx); mod.Groups.RemoveAt(idx);
saveService.SaveAllOptionGroups(mod, false, Config.ReplaceNonAsciiOnImport); saveService.SaveAllOptionGroups(mod, false, config.ReplaceNonAsciiOnImport);
communicator.ModOptionChanged.Invoke(ModOptionChangeType.GroupDeleted, mod, null, null, null, idx); communicator.ModOptionChanged.Invoke(ModOptionChangeType.GroupDeleted, mod, null, null, null, idx);
} }
@ -93,7 +93,7 @@ public class ModGroupEditor(
if (!mod.Groups.Move(idxFrom, groupIdxTo)) if (!mod.Groups.Move(idxFrom, groupIdxTo))
return; return;
saveService.SaveAllOptionGroups(mod, false, Config.ReplaceNonAsciiOnImport); saveService.SaveAllOptionGroups(mod, false, config.ReplaceNonAsciiOnImport);
communicator.ModOptionChanged.Invoke(ModOptionChangeType.GroupMoved, mod, group, null, null, idxFrom); communicator.ModOptionChanged.Invoke(ModOptionChangeType.GroupMoved, mod, group, null, null, idxFrom);
} }
@ -104,7 +104,7 @@ public class ModGroupEditor(
return; return;
group.Priority = newPriority; group.Priority = newPriority;
saveService.QueueSave(new ModSaveGroup(group, Config.ReplaceNonAsciiOnImport)); saveService.QueueSave(new ModSaveGroup(group, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.PriorityChanged, group.Mod, group, null, null, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.PriorityChanged, group.Mod, group, null, null, -1);
} }
@ -115,7 +115,7 @@ public class ModGroupEditor(
return; return;
group.Description = newDescription; group.Description = newDescription;
saveService.QueueSave(new ModSaveGroup(group, Config.ReplaceNonAsciiOnImport)); saveService.QueueSave(new ModSaveGroup(group, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.DisplayChange, group.Mod, group, null, null, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.DisplayChange, group.Mod, group, null, null, -1);
} }
@ -126,7 +126,7 @@ public class ModGroupEditor(
return; return;
option.Name = newName; option.Name = newName;
saveService.QueueSave(new ModSaveGroup(option.Group, Config.ReplaceNonAsciiOnImport)); saveService.QueueSave(new ModSaveGroup(option.Group, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.DisplayChange, option.Mod, option.Group, option, null, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.DisplayChange, option.Mod, option.Group, option, null, -1);
} }
@ -137,7 +137,7 @@ public class ModGroupEditor(
return; return;
option.Description = newDescription; option.Description = newDescription;
saveService.QueueSave(new ModSaveGroup(option.Group, Config.ReplaceNonAsciiOnImport)); saveService.QueueSave(new ModSaveGroup(option.Group, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.DisplayChange, option.Mod, option.Group, option, null, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.DisplayChange, option.Mod, option.Group, option, null, -1);
} }
@ -149,7 +149,7 @@ public class ModGroupEditor(
communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, (Mod)subMod.Mod, subMod.Group, null, subMod, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, (Mod)subMod.Mod, subMod.Group, null, subMod, -1);
subMod.Manipulations.SetTo(manipulations); subMod.Manipulations.SetTo(manipulations);
saveService.Save(saveType, new ModSaveGroup(subMod, Config.ReplaceNonAsciiOnImport)); saveService.Save(saveType, new ModSaveGroup(subMod, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionMetaChanged, (Mod)subMod.Mod, subMod.Group, null, subMod, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionMetaChanged, (Mod)subMod.Mod, subMod.Group, null, subMod, -1);
} }
@ -161,13 +161,13 @@ public class ModGroupEditor(
communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, (Mod)subMod.Mod, subMod.Group, null, subMod, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, (Mod)subMod.Mod, subMod.Group, null, subMod, -1);
subMod.Files.SetTo(replacements); subMod.Files.SetTo(replacements);
saveService.Save(saveType, new ModSaveGroup(subMod, Config.ReplaceNonAsciiOnImport)); saveService.Save(saveType, new ModSaveGroup(subMod, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionFilesChanged, (Mod)subMod.Mod, subMod.Group, null, subMod, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionFilesChanged, (Mod)subMod.Mod, subMod.Group, null, subMod, -1);
} }
/// <summary> Forces a file save of the given container's group. </summary> /// <summary> Forces a file save of the given container's group. </summary>
public void ForceSave(IModDataContainer subMod, SaveType saveType = SaveType.Queue) public void ForceSave(IModDataContainer subMod, SaveType saveType = SaveType.Queue)
=> saveService.Save(saveType, new ModSaveGroup(subMod, Config.ReplaceNonAsciiOnImport)); => saveService.Save(saveType, new ModSaveGroup(subMod, config.ReplaceNonAsciiOnImport));
/// <summary> Add additional file redirections to a given option, keeping already existing ones. Only fires an event if anything is actually added.</summary> /// <summary> Add additional file redirections to a given option, keeping already existing ones. Only fires an event if anything is actually added.</summary>
public void AddFiles(IModDataContainer subMod, IReadOnlyDictionary<Utf8GamePath, FullPath> additions) public void AddFiles(IModDataContainer subMod, IReadOnlyDictionary<Utf8GamePath, FullPath> additions)
@ -176,7 +176,7 @@ public class ModGroupEditor(
subMod.Files.AddFrom(additions); subMod.Files.AddFrom(additions);
if (oldCount != subMod.Files.Count) if (oldCount != subMod.Files.Count)
{ {
saveService.QueueSave(new ModSaveGroup(subMod, Config.ReplaceNonAsciiOnImport)); saveService.QueueSave(new ModSaveGroup(subMod, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionFilesAdded, (Mod)subMod.Mod, subMod.Group, null, subMod, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionFilesAdded, (Mod)subMod.Mod, subMod.Group, null, subMod, -1);
} }
} }
@ -189,7 +189,7 @@ public class ModGroupEditor(
communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, (Mod)subMod.Mod, subMod.Group, null, subMod, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.PrepareChange, (Mod)subMod.Mod, subMod.Group, null, subMod, -1);
subMod.FileSwaps.SetTo(swaps); subMod.FileSwaps.SetTo(swaps);
saveService.Save(saveType, new ModSaveGroup(subMod, Config.ReplaceNonAsciiOnImport)); saveService.Save(saveType, new ModSaveGroup(subMod, config.ReplaceNonAsciiOnImport));
communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionSwapsChanged, (Mod)subMod.Mod, subMod.Group, null, subMod, -1); communicator.ModOptionChanged.Invoke(ModOptionChangeType.OptionSwapsChanged, (Mod)subMod.Mod, subMod.Group, null, subMod, -1);
} }

View file

@ -10,6 +10,7 @@ using Penumbra.GameData.Data;
using Penumbra.Import; using Penumbra.Import;
using Penumbra.Import.Structs; using Penumbra.Import.Structs;
using Penumbra.Meta; using Penumbra.Meta;
using Penumbra.Mods.Editor;
using Penumbra.Mods.Groups; using Penumbra.Mods.Groups;
using Penumbra.Mods.Manager; using Penumbra.Mods.Manager;
using Penumbra.Mods.Settings; using Penumbra.Mods.Settings;
@ -20,11 +21,12 @@ using Penumbra.String.Classes;
namespace Penumbra.Mods; namespace Penumbra.Mods;
public partial class ModCreator( public partial class ModCreator(
SaveService _saveService, SaveService saveService,
Configuration config, Configuration config,
ModDataEditor _dataEditor, ModDataEditor dataEditor,
MetaFileManager _metaFileManager, MetaFileManager metaFileManager,
GamePathParser _gamePathParser) : IService GamePathParser gamePathParser,
ImcChecker imcChecker) : IService
{ {
public readonly Configuration Config = config; public readonly Configuration Config = config;
@ -34,7 +36,7 @@ public partial class ModCreator(
try try
{ {
var newDir = CreateModFolder(basePath, newName, Config.ReplaceNonAsciiOnImport, true); var newDir = CreateModFolder(basePath, newName, Config.ReplaceNonAsciiOnImport, true);
_dataEditor.CreateMeta(newDir, newName, Config.DefaultModAuthor, description, "1.0", string.Empty); dataEditor.CreateMeta(newDir, newName, Config.DefaultModAuthor, description, "1.0", string.Empty);
CreateDefaultFiles(newDir); CreateDefaultFiles(newDir);
return newDir; return newDir;
} }
@ -46,7 +48,7 @@ public partial class ModCreator(
} }
/// <summary> Load a mod by its directory. </summary> /// <summary> Load a mod by its directory. </summary>
public Mod? LoadMod(DirectoryInfo modPath, bool incorporateMetaChanges) public Mod? LoadMod(DirectoryInfo modPath, bool incorporateMetaChanges, bool deleteDefaultMetaChanges)
{ {
modPath.Refresh(); modPath.Refresh();
if (!modPath.Exists) if (!modPath.Exists)
@ -56,7 +58,7 @@ public partial class ModCreator(
} }
var mod = new Mod(modPath); var mod = new Mod(modPath);
if (ReloadMod(mod, incorporateMetaChanges, out _)) if (ReloadMod(mod, incorporateMetaChanges, deleteDefaultMetaChanges, out _))
return mod; return mod;
// Can not be base path not existing because that is checked before. // Can not be base path not existing because that is checked before.
@ -65,21 +67,29 @@ public partial class ModCreator(
} }
/// <summary> Reload a mod from its mod path. </summary> /// <summary> Reload a mod from its mod path. </summary>
public bool ReloadMod(Mod mod, bool incorporateMetaChanges, out ModDataChangeType modDataChange) public bool ReloadMod(Mod mod, bool incorporateMetaChanges, bool deleteDefaultMetaChanges, out ModDataChangeType modDataChange)
{ {
modDataChange = ModDataChangeType.Deletion; modDataChange = ModDataChangeType.Deletion;
if (!Directory.Exists(mod.ModPath.FullName)) if (!Directory.Exists(mod.ModPath.FullName))
return false; return false;
modDataChange = _dataEditor.LoadMeta(this, mod); modDataChange = dataEditor.LoadMeta(this, mod);
if (modDataChange.HasFlag(ModDataChangeType.Deletion) || mod.Name.Length == 0) if (modDataChange.HasFlag(ModDataChangeType.Deletion) || mod.Name.Length == 0)
return false; return false;
_dataEditor.LoadLocalData(mod); dataEditor.LoadLocalData(mod);
LoadDefaultOption(mod); LoadDefaultOption(mod);
LoadAllGroups(mod); LoadAllGroups(mod);
if (incorporateMetaChanges) if (incorporateMetaChanges)
IncorporateAllMetaChanges(mod, true); IncorporateAllMetaChanges(mod, true);
if (deleteDefaultMetaChanges && !Config.KeepDefaultMetaChanges)
{
foreach (var container in mod.AllDataContainers)
{
if (ModMetaEditor.DeleteDefaultValues(metaFileManager, imcChecker, container.Manipulations))
saveService.ImmediateSaveSync(new ModSaveGroup(container, Config.ReplaceNonAsciiOnImport));
}
}
return true; return true;
} }
@ -89,13 +99,13 @@ public partial class ModCreator(
{ {
mod.Groups.Clear(); mod.Groups.Clear();
var changes = false; var changes = false;
foreach (var file in _saveService.FileNames.GetOptionGroupFiles(mod)) foreach (var file in saveService.FileNames.GetOptionGroupFiles(mod))
{ {
var group = LoadModGroup(mod, file); var group = LoadModGroup(mod, file);
if (group != null && mod.Groups.All(g => g.Name != group.Name)) if (group != null && mod.Groups.All(g => g.Name != group.Name))
{ {
changes = changes changes = changes
|| _saveService.FileNames.OptionGroupFile(mod.ModPath.FullName, mod.Groups.Count, group.Name, true) || saveService.FileNames.OptionGroupFile(mod.ModPath.FullName, mod.Groups.Count, group.Name, true)
!= Path.Combine(file.DirectoryName!, ReplaceBadXivSymbols(file.Name, true)); != Path.Combine(file.DirectoryName!, ReplaceBadXivSymbols(file.Name, true));
mod.Groups.Add(group); mod.Groups.Add(group);
} }
@ -106,13 +116,13 @@ public partial class ModCreator(
} }
if (changes) if (changes)
_saveService.SaveAllOptionGroups(mod, true, Config.ReplaceNonAsciiOnImport); saveService.SaveAllOptionGroups(mod, true, Config.ReplaceNonAsciiOnImport);
} }
/// <summary> Load the default option for a given mod.</summary> /// <summary> Load the default option for a given mod.</summary>
public void LoadDefaultOption(Mod mod) public void LoadDefaultOption(Mod mod)
{ {
var defaultFile = _saveService.FileNames.OptionGroupFile(mod, -1, Config.ReplaceNonAsciiOnImport); var defaultFile = saveService.FileNames.OptionGroupFile(mod, -1, Config.ReplaceNonAsciiOnImport);
try try
{ {
var jObject = File.Exists(defaultFile) ? JObject.Parse(File.ReadAllText(defaultFile)) : new JObject(); var jObject = File.Exists(defaultFile) ? JObject.Parse(File.ReadAllText(defaultFile)) : new JObject();
@ -157,7 +167,7 @@ public partial class ModCreator(
List<string> deleteList = new(); List<string> deleteList = new();
foreach (var subMod in mod.AllDataContainers) foreach (var subMod in mod.AllDataContainers)
{ {
var (localChanges, localDeleteList) = IncorporateMetaChanges(subMod, mod.ModPath, false); var (localChanges, localDeleteList) = IncorporateMetaChanges(subMod, mod.ModPath, false, true);
changes |= localChanges; changes |= localChanges;
if (delete) if (delete)
deleteList.AddRange(localDeleteList); deleteList.AddRange(localDeleteList);
@ -168,8 +178,8 @@ public partial class ModCreator(
if (!changes) if (!changes)
return; return;
_saveService.SaveAllOptionGroups(mod, false, Config.ReplaceNonAsciiOnImport); saveService.SaveAllOptionGroups(mod, false, Config.ReplaceNonAsciiOnImport);
_saveService.ImmediateSaveSync(new ModSaveGroup(mod.ModPath, mod.Default, Config.ReplaceNonAsciiOnImport)); saveService.ImmediateSaveSync(new ModSaveGroup(mod.ModPath, mod.Default, Config.ReplaceNonAsciiOnImport));
} }
@ -177,7 +187,7 @@ public partial class ModCreator(
/// If .meta or .rgsp files are encountered, parse them and incorporate their meta changes into the mod. /// If .meta or .rgsp files are encountered, parse them and incorporate their meta changes into the mod.
/// If delete is true, the files are deleted afterwards. /// If delete is true, the files are deleted afterwards.
/// </summary> /// </summary>
public (bool Changes, List<string> DeleteList) IncorporateMetaChanges(IModDataContainer option, DirectoryInfo basePath, bool delete) public (bool Changes, List<string> DeleteList) IncorporateMetaChanges(IModDataContainer option, DirectoryInfo basePath, bool delete, bool deleteDefault)
{ {
var deleteList = new List<string>(); var deleteList = new List<string>();
var oldSize = option.Manipulations.Count; var oldSize = option.Manipulations.Count;
@ -194,7 +204,7 @@ public partial class ModCreator(
if (!file.Exists) if (!file.Exists)
continue; continue;
var meta = new TexToolsMeta(_metaFileManager, _gamePathParser, File.ReadAllBytes(file.FullName), var meta = new TexToolsMeta(metaFileManager, gamePathParser, File.ReadAllBytes(file.FullName),
Config.KeepDefaultMetaChanges); Config.KeepDefaultMetaChanges);
Penumbra.Log.Verbose( Penumbra.Log.Verbose(
$"Incorporating {file} as Metadata file of {meta.MetaManipulations.Count} manipulations {deleteString}"); $"Incorporating {file} as Metadata file of {meta.MetaManipulations.Count} manipulations {deleteString}");
@ -207,7 +217,7 @@ public partial class ModCreator(
if (!file.Exists) if (!file.Exists)
continue; continue;
var rgsp = TexToolsMeta.FromRgspFile(_metaFileManager, file.FullName, File.ReadAllBytes(file.FullName), var rgsp = TexToolsMeta.FromRgspFile(metaFileManager, file.FullName, File.ReadAllBytes(file.FullName),
Config.KeepDefaultMetaChanges); Config.KeepDefaultMetaChanges);
Penumbra.Log.Verbose( Penumbra.Log.Verbose(
$"Incorporating {file} as racial scaling file of {rgsp.MetaManipulations.Count} manipulations {deleteString}"); $"Incorporating {file} as racial scaling file of {rgsp.MetaManipulations.Count} manipulations {deleteString}");
@ -223,7 +233,11 @@ public partial class ModCreator(
} }
DeleteDeleteList(deleteList, delete); DeleteDeleteList(deleteList, delete);
return (oldSize < option.Manipulations.Count, deleteList); var changes = oldSize < option.Manipulations.Count;
if (deleteDefault && !Config.KeepDefaultMetaChanges)
changes |= ModMetaEditor.DeleteDefaultValues(metaFileManager, imcChecker, option.Manipulations);
return (changes, deleteList);
} }
/// <summary> /// <summary>
@ -250,7 +264,7 @@ public partial class ModCreator(
group.Priority = priority; group.Priority = priority;
group.DefaultSettings = defaultSettings; group.DefaultSettings = defaultSettings;
group.OptionData.AddRange(subMods.Select(s => s.Clone(group))); group.OptionData.AddRange(subMods.Select(s => s.Clone(group)));
_saveService.ImmediateSaveSync(ModSaveGroup.WithoutMod(baseFolder, group, index, Config.ReplaceNonAsciiOnImport)); saveService.ImmediateSaveSync(ModSaveGroup.WithoutMod(baseFolder, group, index, Config.ReplaceNonAsciiOnImport));
break; break;
} }
case GroupType.Single: case GroupType.Single:
@ -260,7 +274,7 @@ public partial class ModCreator(
group.Priority = priority; group.Priority = priority;
group.DefaultSettings = defaultSettings; group.DefaultSettings = defaultSettings;
group.OptionData.AddRange(subMods.Select(s => s.ConvertToSingle(group))); group.OptionData.AddRange(subMods.Select(s => s.ConvertToSingle(group)));
_saveService.ImmediateSaveSync(ModSaveGroup.WithoutMod(baseFolder, group, index, Config.ReplaceNonAsciiOnImport)); saveService.ImmediateSaveSync(ModSaveGroup.WithoutMod(baseFolder, group, index, Config.ReplaceNonAsciiOnImport));
break; break;
} }
} }
@ -277,7 +291,8 @@ public partial class ModCreator(
foreach (var (_, gamePath, file) in list) foreach (var (_, gamePath, file) in list)
mod.Files.TryAdd(gamePath, file); mod.Files.TryAdd(gamePath, file);
IncorporateMetaChanges(mod, baseFolder, true); IncorporateMetaChanges(mod, baseFolder, true, true);
return mod; return mod;
} }
@ -288,15 +303,15 @@ public partial class ModCreator(
internal void CreateDefaultFiles(DirectoryInfo directory) internal void CreateDefaultFiles(DirectoryInfo directory)
{ {
var mod = new Mod(directory); var mod = new Mod(directory);
ReloadMod(mod, false, out _); ReloadMod(mod, false, false, out _);
foreach (var file in mod.FindUnusedFiles()) foreach (var file in mod.FindUnusedFiles())
{ {
if (Utf8GamePath.FromFile(new FileInfo(file.FullName), directory, out var gamePath)) if (Utf8GamePath.FromFile(new FileInfo(file.FullName), directory, out var gamePath))
mod.Default.Files.TryAdd(gamePath, file); mod.Default.Files.TryAdd(gamePath, file);
} }
IncorporateMetaChanges(mod.Default, directory, true); IncorporateMetaChanges(mod.Default, directory, true, true);
_saveService.ImmediateSaveSync(new ModSaveGroup(mod.ModPath, mod.Default, Config.ReplaceNonAsciiOnImport)); saveService.ImmediateSaveSync(new ModSaveGroup(mod.ModPath, mod.Default, Config.ReplaceNonAsciiOnImport));
} }
/// <summary> Return the name of a new valid directory based on the base directory and the given name. </summary> /// <summary> Return the name of a new valid directory based on the base directory and the given name. </summary>
@ -333,7 +348,7 @@ public partial class ModCreator(
{ {
var mod = new Mod(baseDir); var mod = new Mod(baseDir);
var files = _saveService.FileNames.GetOptionGroupFiles(mod).ToList(); var files = saveService.FileNames.GetOptionGroupFiles(mod).ToList();
var idx = 0; var idx = 0;
var reorder = false; var reorder = false;
foreach (var groupFile in files) foreach (var groupFile in files)

View file

@ -97,7 +97,7 @@ public class TemporaryMod : IMod
defaultMod.Manipulations.UnionWith(manips); defaultMod.Manipulations.UnionWith(manips);
saveService.ImmediateSaveSync(new ModSaveGroup(dir, defaultMod, config.ReplaceNonAsciiOnImport)); saveService.ImmediateSaveSync(new ModSaveGroup(dir, defaultMod, config.ReplaceNonAsciiOnImport));
modManager.AddMod(dir); modManager.AddMod(dir, false);
Penumbra.Log.Information( Penumbra.Log.Information(
$"Successfully generated mod {mod.Name} at {mod.ModPath.FullName} for collection {collection.Identifier}."); $"Successfully generated mod {mod.Name} at {mod.ModPath.FullName} for collection {collection.Identifier}.");
} }

View file

@ -281,7 +281,7 @@ public class ItemSwapTab : IDisposable, ITab, IUiService
if (newDir == null) if (newDir == null)
return; return;
_modManager.AddMod(newDir); _modManager.AddMod(newDir, false);
var mod = _modManager[^1]; var mod = _modManager[^1];
if (!_swapData.WriteMod(_modManager, mod, mod.Default, if (!_swapData.WriteMod(_modManager, mod, mod.Default,
_useFileSwaps ? ItemSwapContainer.WriteType.UseSwaps : ItemSwapContainer.WriteType.NoSwaps)) _useFileSwaps ? ItemSwapContainer.WriteType.UseSwaps : ItemSwapContainer.WriteType.NoSwaps))

View file

@ -180,7 +180,7 @@ public sealed class ModFileSystemSelector : FileSystemSelector<Mod, ModFileSyste
var newDir = _modManager.Creator.CreateEmptyMod(_modManager.BasePath, _newModName); var newDir = _modManager.Creator.CreateEmptyMod(_modManager.BasePath, _newModName);
if (newDir != null) if (newDir != null)
{ {
_modManager.AddMod(newDir); _modManager.AddMod(newDir, false);
_newModName = string.Empty; _newModName = string.Empty;
} }
} }