mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-13 12:14:17 +01:00
Add automatic reduplication for ui files in pmps, test.
This commit is contained in:
parent
6beb2416dc
commit
40be298d67
6 changed files with 145 additions and 39 deletions
|
|
@ -3,13 +3,15 @@ using OtterGui;
|
|||
using OtterGui.Classes;
|
||||
using OtterGui.Services;
|
||||
using OtterGui.Tasks;
|
||||
using Penumbra.Mods.Groups;
|
||||
using Penumbra.Mods.Manager;
|
||||
using Penumbra.Mods.SubMods;
|
||||
using Penumbra.Services;
|
||||
using Penumbra.String.Classes;
|
||||
|
||||
namespace Penumbra.Mods.Editor;
|
||||
|
||||
public class ModNormalizer(ModManager _modManager, Configuration _config) : IService
|
||||
public class ModNormalizer(ModManager modManager, Configuration config, SaveService saveService) : IService
|
||||
{
|
||||
private readonly List<List<Dictionary<Utf8GamePath, FullPath>>> _redirections = [];
|
||||
|
||||
|
|
@ -39,6 +41,103 @@ public class ModNormalizer(ModManager _modManager, Configuration _config) : ISer
|
|||
Worker = TrackedTask.Run(NormalizeSync);
|
||||
}
|
||||
|
||||
public void NormalizeUi(DirectoryInfo modDirectory)
|
||||
{
|
||||
if (!config.AutoReduplicateUiOnImport)
|
||||
return;
|
||||
|
||||
if (modManager.Creator.LoadMod(modDirectory, false) is not { } mod)
|
||||
return;
|
||||
|
||||
Dictionary<FullPath, List<(IModDataContainer, Utf8GamePath)>> paths = [];
|
||||
Dictionary<IModDataContainer, string> containers = [];
|
||||
foreach (var container in mod.AllDataContainers)
|
||||
{
|
||||
foreach (var (gamePath, path) in container.Files)
|
||||
{
|
||||
if (!gamePath.Path.StartsWith("ui/"u8))
|
||||
continue;
|
||||
|
||||
if (!paths.TryGetValue(path, out var list))
|
||||
{
|
||||
list = [];
|
||||
paths.Add(path, list);
|
||||
}
|
||||
|
||||
list.Add((container, gamePath));
|
||||
containers.TryAdd(container, string.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var container in containers.Keys.ToList())
|
||||
{
|
||||
if (container.Group == null)
|
||||
containers[container] = mod.ModPath.FullName;
|
||||
else
|
||||
{
|
||||
var groupDir = ModCreator.NewOptionDirectory(mod.ModPath, container.Group.Name, config.ReplaceNonAsciiOnImport);
|
||||
var optionDir = ModCreator.NewOptionDirectory(groupDir, container.GetName(), config.ReplaceNonAsciiOnImport);
|
||||
containers[container] = optionDir.FullName;
|
||||
}
|
||||
}
|
||||
|
||||
var anyChanges = 0;
|
||||
var modRootLength = mod.ModPath.FullName.Length + 1;
|
||||
foreach (var (file, gamePaths) in paths)
|
||||
{
|
||||
if (gamePaths.Count < 2)
|
||||
continue;
|
||||
|
||||
var keptPath = false;
|
||||
foreach (var (container, gamePath) in gamePaths)
|
||||
{
|
||||
var directory = containers[container];
|
||||
var relPath = new Utf8RelPath(gamePath).ToString();
|
||||
var newFilePath = Path.Combine(directory, relPath);
|
||||
if (newFilePath == file.FullName)
|
||||
{
|
||||
Penumbra.Log.Verbose($"[UIReduplication] Kept {file.FullName[modRootLength..]} because new path was identical.");
|
||||
keptPath = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(newFilePath)!);
|
||||
File.Copy(file.FullName, newFilePath, false);
|
||||
Penumbra.Log.Verbose($"[UIReduplication] Copied {file.FullName[modRootLength..]} to {newFilePath[modRootLength..]}.");
|
||||
container.Files[gamePath] = new FullPath(newFilePath);
|
||||
++anyChanges;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Penumbra.Log.Error(
|
||||
$"[UIReduplication] Failed to copy {file.FullName[modRootLength..]} to {newFilePath[modRootLength..]}:\n{ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (keptPath)
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
File.Delete(file.FullName);
|
||||
Penumbra.Log.Verbose($"[UIReduplication] Deleted {file.FullName[modRootLength..]} because no new path matched.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Penumbra.Log.Error($"[UIReduplication] Failed to delete {file.FullName[modRootLength..]}:\n{ex}");
|
||||
}
|
||||
}
|
||||
|
||||
if (anyChanges == 0)
|
||||
return;
|
||||
|
||||
saveService.Save(SaveType.ImmediateSync, new ModSaveGroup(mod.Default, config.ReplaceNonAsciiOnImport));
|
||||
saveService.SaveAllOptionGroups(mod, false, config.ReplaceNonAsciiOnImport);
|
||||
Penumbra.Log.Information($"[UIReduplication] Saved groups after {anyChanges} changes.");
|
||||
}
|
||||
|
||||
private void NormalizeSync()
|
||||
{
|
||||
try
|
||||
|
|
@ -168,7 +267,7 @@ public class ModNormalizer(ModManager _modManager, Configuration _config) : ISer
|
|||
// Normalize all other options.
|
||||
foreach (var (group, groupIdx) in Mod.Groups.WithIndex())
|
||||
{
|
||||
var groupDir = ModCreator.CreateModFolder(directory, group.Name, _config.ReplaceNonAsciiOnImport, true);
|
||||
var groupDir = ModCreator.CreateModFolder(directory, group.Name, config.ReplaceNonAsciiOnImport, true);
|
||||
_redirections[groupIdx + 1].EnsureCapacity(group.DataContainers.Count);
|
||||
for (var i = _redirections[groupIdx + 1].Count; i < group.DataContainers.Count; ++i)
|
||||
_redirections[groupIdx + 1].Add([]);
|
||||
|
|
@ -188,7 +287,7 @@ public class ModNormalizer(ModManager _modManager, Configuration _config) : ISer
|
|||
void HandleSubMod(DirectoryInfo groupDir, IModDataContainer option, Dictionary<Utf8GamePath, FullPath> newDict)
|
||||
{
|
||||
var name = option.GetName();
|
||||
var optionDir = ModCreator.CreateModFolder(groupDir, name, _config.ReplaceNonAsciiOnImport, true);
|
||||
var optionDir = ModCreator.CreateModFolder(groupDir, name, config.ReplaceNonAsciiOnImport, true);
|
||||
|
||||
newDict.Clear();
|
||||
newDict.EnsureCapacity(option.Files.Count);
|
||||
|
|
@ -277,10 +376,10 @@ public class ModNormalizer(ModManager _modManager, Configuration _config) : ISer
|
|||
|
||||
private void ApplyRedirections()
|
||||
{
|
||||
_modManager.OptionEditor.SetFiles(Mod.Default, _redirections[0][0]);
|
||||
modManager.OptionEditor.SetFiles(Mod.Default, _redirections[0][0]);
|
||||
foreach (var (group, groupIdx) in Mod.Groups.WithIndex())
|
||||
foreach (var (container, containerIdx) in group.DataContainers.WithIndex())
|
||||
_modManager.OptionEditor.SetFiles(container, _redirections[groupIdx + 1][containerIdx]);
|
||||
modManager.OptionEditor.SetFiles(container, _redirections[groupIdx + 1][containerIdx]);
|
||||
|
||||
++Step;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue