mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Add Filesystem Compression as a toggle and button. Also some auto-formatting.
This commit is contained in:
parent
e26873934b
commit
4e704770cb
21 changed files with 385 additions and 344 deletions
2
OtterGui
2
OtterGui
|
|
@ -1 +1 @@
|
||||||
Subproject commit 51ae60322c22c9d9b49365ad0b9fd60dc3d50296
|
Subproject commit e3e3f42f093b53ad02694810398df5736174d711
|
||||||
|
|
@ -99,6 +99,7 @@ public class Configuration : IPluginConfiguration, ISavable
|
||||||
public bool PrintSuccessfulCommandsToChat { get; set; } = true;
|
public bool PrintSuccessfulCommandsToChat { get; set; } = true;
|
||||||
public bool FixMainWindow { get; set; } = false;
|
public bool FixMainWindow { get; set; } = false;
|
||||||
public bool AutoDeduplicateOnImport { get; set; } = true;
|
public bool AutoDeduplicateOnImport { get; set; } = true;
|
||||||
|
public bool UseFileSystemCompression { get; set; } = true;
|
||||||
public bool EnableHttpApi { get; set; } = true;
|
public bool EnableHttpApi { get; set; } = true;
|
||||||
|
|
||||||
public string DefaultModImportPath { get; set; } = string.Empty;
|
public string DefaultModImportPath { get; set; } = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
@ -7,9 +6,10 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Penumbra.Api;
|
using OtterGui.Compression;
|
||||||
using Penumbra.Import.Structs;
|
using Penumbra.Import.Structs;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
using FileMode = System.IO.FileMode;
|
using FileMode = System.IO.FileMode;
|
||||||
using ZipArchive = SharpCompress.Archives.Zip.ZipArchive;
|
using ZipArchive = SharpCompress.Archives.Zip.ZipArchive;
|
||||||
|
|
@ -38,9 +38,10 @@ public partial class TexToolsImporter : IDisposable
|
||||||
private readonly Configuration _config;
|
private readonly Configuration _config;
|
||||||
private readonly ModEditor _editor;
|
private readonly ModEditor _editor;
|
||||||
private readonly ModManager _modManager;
|
private readonly ModManager _modManager;
|
||||||
|
private readonly FileCompactor _compactor;
|
||||||
|
|
||||||
public TexToolsImporter( int count, IEnumerable< FileInfo > modPackFiles,
|
public TexToolsImporter(int count, IEnumerable<FileInfo> modPackFiles, Action<FileInfo, DirectoryInfo?, Exception?> handler,
|
||||||
Action< FileInfo, DirectoryInfo?, Exception? > handler, Configuration config, ModEditor editor, ModManager modManager)
|
Configuration config, ModEditor editor, ModManager modManager, FileCompactor compactor)
|
||||||
{
|
{
|
||||||
_baseDirectory = modManager.BasePath;
|
_baseDirectory = modManager.BasePath;
|
||||||
_tmpFile = Path.Combine(_baseDirectory.FullName, TempFileName);
|
_tmpFile = Path.Combine(_baseDirectory.FullName, TempFileName);
|
||||||
|
|
@ -48,6 +49,7 @@ public partial class TexToolsImporter : IDisposable
|
||||||
_config = config;
|
_config = config;
|
||||||
_editor = editor;
|
_editor = editor;
|
||||||
_modManager = modManager;
|
_modManager = modManager;
|
||||||
|
_compactor = compactor;
|
||||||
_modPackCount = count;
|
_modPackCount = count;
|
||||||
ExtractedMods = new List<(FileInfo, DirectoryInfo?, Exception?)>(count);
|
ExtractedMods = new List<(FileInfo, DirectoryInfo?, Exception?)>(count);
|
||||||
_token = _cancellation.Token;
|
_token = _cancellation.Token;
|
||||||
|
|
@ -56,9 +58,7 @@ public partial class TexToolsImporter : IDisposable
|
||||||
.ContinueWith(_ =>
|
.ContinueWith(_ =>
|
||||||
{
|
{
|
||||||
foreach (var (file, dir, error) in ExtractedMods)
|
foreach (var (file, dir, error) in ExtractedMods)
|
||||||
{
|
|
||||||
handler(file, dir, error);
|
handler(file, dir, error);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,10 +79,8 @@ public partial class TexToolsImporter : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
if (State != ImporterState.ExtractingModFiles)
|
if (State != ImporterState.ExtractingModFiles)
|
||||||
{
|
|
||||||
ResetStreamDisposer();
|
ResetStreamDisposer();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void ImportFiles()
|
private void ImportFiles()
|
||||||
{
|
{
|
||||||
|
|
@ -127,18 +125,14 @@ public partial class TexToolsImporter : IDisposable
|
||||||
private DirectoryInfo VerifyVersionAndImport(FileInfo modPackFile)
|
private DirectoryInfo VerifyVersionAndImport(FileInfo modPackFile)
|
||||||
{
|
{
|
||||||
if (modPackFile.Extension.ToLowerInvariant() is ".pmp" or ".zip" or ".7z" or ".rar")
|
if (modPackFile.Extension.ToLowerInvariant() is ".pmp" or ".zip" or ".7z" or ".rar")
|
||||||
{
|
|
||||||
return HandleRegularArchive(modPackFile);
|
return HandleRegularArchive(modPackFile);
|
||||||
}
|
|
||||||
|
|
||||||
using var zfs = modPackFile.OpenRead();
|
using var zfs = modPackFile.OpenRead();
|
||||||
using var extractedModPack = ZipArchive.Open(zfs);
|
using var extractedModPack = ZipArchive.Open(zfs);
|
||||||
|
|
||||||
var mpl = FindZipEntry(extractedModPack, "TTMPL.mpl");
|
var mpl = FindZipEntry(extractedModPack, "TTMPL.mpl");
|
||||||
if (mpl == null)
|
if (mpl == null)
|
||||||
{
|
|
||||||
throw new FileNotFoundException("ZIP does not contain a TTMPL.mpl file.");
|
throw new FileNotFoundException("ZIP does not contain a TTMPL.mpl file.");
|
||||||
}
|
|
||||||
|
|
||||||
var modRaw = GetStringFromZipEntry(mpl, Encoding.UTF8);
|
var modRaw = GetStringFromZipEntry(mpl, Encoding.UTF8);
|
||||||
|
|
||||||
|
|
@ -146,17 +140,13 @@ public partial class TexToolsImporter : IDisposable
|
||||||
if (modRaw.Contains("\"TTMPVersion\":"))
|
if (modRaw.Contains("\"TTMPVersion\":"))
|
||||||
{
|
{
|
||||||
if (modPackFile.Extension != ".ttmp2")
|
if (modPackFile.Extension != ".ttmp2")
|
||||||
{
|
|
||||||
Penumbra.Log.Warning($"File {modPackFile.FullName} seems to be a V2 TTMP, but has the wrong extension.");
|
Penumbra.Log.Warning($"File {modPackFile.FullName} seems to be a V2 TTMP, but has the wrong extension.");
|
||||||
}
|
|
||||||
|
|
||||||
return ImportV2ModPack(modPackFile, extractedModPack, modRaw);
|
return ImportV2ModPack(modPackFile, extractedModPack, modRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modPackFile.Extension != ".ttmp")
|
if (modPackFile.Extension != ".ttmp")
|
||||||
{
|
|
||||||
Penumbra.Log.Warning($"File {modPackFile.FullName} seems to be a V1 TTMP, but has the wrong extension.");
|
Penumbra.Log.Warning($"File {modPackFile.FullName} seems to be a V1 TTMP, but has the wrong extension.");
|
||||||
}
|
|
||||||
|
|
||||||
return ImportV1ModPack(modPackFile, extractedModPack, modRaw);
|
return ImportV1ModPack(modPackFile, extractedModPack, modRaw);
|
||||||
}
|
}
|
||||||
|
|
@ -178,9 +168,7 @@ public partial class TexToolsImporter : IDisposable
|
||||||
_tmpFileStream?.Dispose(); // should not happen
|
_tmpFileStream?.Dispose(); // should not happen
|
||||||
_tmpFileStream = new FileStream(_tmpFile, FileMode.Create);
|
_tmpFileStream = new FileStream(_tmpFile, FileMode.Create);
|
||||||
if (_token.IsCancellationRequested)
|
if (_token.IsCancellationRequested)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
s.CopyTo(_tmpFileStream);
|
s.CopyTo(_tmpFileStream);
|
||||||
_tmpFileStream.Dispose();
|
_tmpFileStream.Dispose();
|
||||||
|
|
@ -194,9 +182,7 @@ public partial class TexToolsImporter : IDisposable
|
||||||
// write shitty zip garbage to disk
|
// write shitty zip garbage to disk
|
||||||
var entry = FindZipEntry(file, entryName);
|
var entry = FindZipEntry(file, entryName);
|
||||||
if (entry == null)
|
if (entry == null)
|
||||||
{
|
|
||||||
throw new FileNotFoundException($"ZIP does not contain a file named {entryName}.");
|
throw new FileNotFoundException($"ZIP does not contain a file named {entryName}.");
|
||||||
}
|
|
||||||
|
|
||||||
using var s = entry.OpenEntryStream();
|
using var s = entry.OpenEntryStream();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ public partial class TexToolsImporter
|
||||||
private string _currentOptionName = string.Empty;
|
private string _currentOptionName = string.Empty;
|
||||||
private string _currentFileName = string.Empty;
|
private string _currentFileName = string.Empty;
|
||||||
|
|
||||||
|
|
||||||
public void DrawProgressInfo( Vector2 size )
|
public void DrawProgressInfo( Vector2 size )
|
||||||
{
|
{
|
||||||
if( _modPackCount == 0 )
|
if( _modPackCount == 0 )
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,12 @@ public partial class TexToolsImporter
|
||||||
Penumbra.Log.Information(" -> Importing V1 ModPack");
|
Penumbra.Log.Information(" -> Importing V1 ModPack");
|
||||||
|
|
||||||
var modListRaw = modRaw.Split(
|
var modListRaw = modRaw.Split(
|
||||||
new[] { "\r\n", "\r", "\n" },
|
new[]
|
||||||
|
{
|
||||||
|
"\r\n",
|
||||||
|
"\r",
|
||||||
|
"\n",
|
||||||
|
},
|
||||||
StringSplitOptions.RemoveEmptyEntries
|
StringSplitOptions.RemoveEmptyEntries
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -36,7 +41,8 @@ public partial class TexToolsImporter
|
||||||
|
|
||||||
_currentModDirectory = ModCreator.CreateModFolder(_baseDirectory, Path.GetFileNameWithoutExtension(modPackFile.Name));
|
_currentModDirectory = ModCreator.CreateModFolder(_baseDirectory, Path.GetFileNameWithoutExtension(modPackFile.Name));
|
||||||
// Create a new ModMeta from the TTMP mod list info
|
// Create a new ModMeta from the TTMP mod list info
|
||||||
_modManager.DataEditor.CreateMeta( _currentModDirectory, _currentModName, DefaultTexToolsData.Author, DefaultTexToolsData.Description, null, null );
|
_modManager.DataEditor.CreateMeta(_currentModDirectory, _currentModName, DefaultTexToolsData.Author, DefaultTexToolsData.Description,
|
||||||
|
null, null);
|
||||||
|
|
||||||
// Open the mod data file from the mod pack as a SqPackStream
|
// Open the mod data file from the mod pack as a SqPackStream
|
||||||
_streamDisposer = GetSqPackStreamStream(extractedModPack, "TTMPD.mpd");
|
_streamDisposer = GetSqPackStreamStream(extractedModPack, "TTMPD.mpd");
|
||||||
|
|
@ -52,14 +58,10 @@ public partial class TexToolsImporter
|
||||||
var modList = JsonConvert.DeserializeObject<SimpleModPack>(modRaw, JsonSettings)!;
|
var modList = JsonConvert.DeserializeObject<SimpleModPack>(modRaw, JsonSettings)!;
|
||||||
|
|
||||||
if (modList.TtmpVersion.EndsWith("s"))
|
if (modList.TtmpVersion.EndsWith("s"))
|
||||||
{
|
|
||||||
return ImportSimpleV2ModPack(extractedModPack, modList);
|
return ImportSimpleV2ModPack(extractedModPack, modList);
|
||||||
}
|
|
||||||
|
|
||||||
if (modList.TtmpVersion.EndsWith("w"))
|
if (modList.TtmpVersion.EndsWith("w"))
|
||||||
{
|
|
||||||
return ImportExtendedV2ModPack(extractedModPack, modRaw);
|
return ImportExtendedV2ModPack(extractedModPack, modRaw);
|
||||||
}
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -118,9 +120,7 @@ public partial class TexToolsImporter
|
||||||
var baseName = groupName;
|
var baseName = groupName;
|
||||||
var i = 2;
|
var i = 2;
|
||||||
while (!names.Add(groupName))
|
while (!names.Add(groupName))
|
||||||
{
|
|
||||||
groupName = $"{baseName} ({i++})";
|
groupName = $"{baseName} ({i++})";
|
||||||
}
|
|
||||||
|
|
||||||
return groupName;
|
return groupName;
|
||||||
}
|
}
|
||||||
|
|
@ -136,12 +136,11 @@ public partial class TexToolsImporter
|
||||||
_currentModName = modList.Name;
|
_currentModName = modList.Name;
|
||||||
|
|
||||||
_currentModDirectory = ModCreator.CreateModFolder(_baseDirectory, _currentModName);
|
_currentModDirectory = ModCreator.CreateModFolder(_baseDirectory, _currentModName);
|
||||||
_modManager.DataEditor.CreateMeta( _currentModDirectory, _currentModName, modList.Author, modList.Description, modList.Version, modList.Url );
|
_modManager.DataEditor.CreateMeta(_currentModDirectory, _currentModName, modList.Author, modList.Description, modList.Version,
|
||||||
|
modList.Url);
|
||||||
|
|
||||||
if (_currentNumOptions == 0)
|
if (_currentNumOptions == 0)
|
||||||
{
|
|
||||||
return _currentModDirectory;
|
return _currentModDirectory;
|
||||||
}
|
|
||||||
|
|
||||||
// Open the mod data file from the mod pack as a SqPackStream
|
// Open the mod data file from the mod pack as a SqPackStream
|
||||||
_streamDisposer = GetSqPackStreamStream(extractedModPack, "TTMPD.mpd");
|
_streamDisposer = GetSqPackStreamStream(extractedModPack, "TTMPD.mpd");
|
||||||
|
|
@ -188,11 +187,9 @@ public partial class TexToolsImporter
|
||||||
ExtractSimpleModList(optionFolder, option.ModsJsons);
|
ExtractSimpleModList(optionFolder, option.ModsJsons);
|
||||||
options.Add(_modManager.Creator.CreateSubMod(_currentModDirectory, optionFolder, option));
|
options.Add(_modManager.Creator.CreateSubMod(_currentModDirectory, optionFolder, option));
|
||||||
if (option.IsChecked)
|
if (option.IsChecked)
|
||||||
{
|
|
||||||
defaultSettings = group.SelectionType == GroupType.Multi
|
defaultSettings = group.SelectionType == GroupType.Multi
|
||||||
? ( defaultSettings!.Value | ( 1u << i ) )
|
? defaultSettings!.Value | (1u << i)
|
||||||
: (uint)i;
|
: (uint)i;
|
||||||
}
|
|
||||||
|
|
||||||
++_currentOptionIdx;
|
++_currentOptionIdx;
|
||||||
}
|
}
|
||||||
|
|
@ -242,9 +239,7 @@ public partial class TexToolsImporter
|
||||||
private void ExtractMod(DirectoryInfo outDirectory, SimpleMod mod)
|
private void ExtractMod(DirectoryInfo outDirectory, SimpleMod mod)
|
||||||
{
|
{
|
||||||
if (_streamDisposer is not PenumbraSqPackStream stream)
|
if (_streamDisposer is not PenumbraSqPackStream stream)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
Penumbra.Log.Information($" -> Extracting {mod.FullPath} at {mod.ModOffset:X}");
|
Penumbra.Log.Information($" -> Extracting {mod.FullPath} at {mod.ModOffset:X}");
|
||||||
|
|
||||||
|
|
@ -257,11 +252,9 @@ public partial class TexToolsImporter
|
||||||
extractedFile.Directory?.Create();
|
extractedFile.Directory?.Create();
|
||||||
|
|
||||||
if (extractedFile.FullName.EndsWith(".mdl"))
|
if (extractedFile.FullName.EndsWith(".mdl"))
|
||||||
{
|
|
||||||
ProcessMdl(data.Data);
|
ProcessMdl(data.Data);
|
||||||
}
|
|
||||||
|
|
||||||
File.WriteAllBytes( extractedFile.FullName, data.Data );
|
_compactor.WriteAllBytesAsync(extractedFile.FullName, data.Data, _token).Wait(_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ProcessMdl(byte[] mdl)
|
private static void ProcessMdl(byte[] mdl)
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public partial class TexToolsMeta
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
|
||||||
File.WriteAllBytes(path, data);
|
manager.Compactor.WriteAllBytes(path, data);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -38,17 +38,13 @@ public partial class TexToolsMeta
|
||||||
foreach (var group in manips.GroupBy(ManipToPath))
|
foreach (var group in manips.GroupBy(ManipToPath))
|
||||||
{
|
{
|
||||||
if (group.Key.Length == 0)
|
if (group.Key.Length == 0)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
var bytes = group.Key.EndsWith(".rgsp")
|
var bytes = group.Key.EndsWith(".rgsp")
|
||||||
? WriteRgspFile(manager, group.Key, group)
|
? WriteRgspFile(manager, group.Key, group)
|
||||||
: WriteMetaFile(manager, group.Key, group);
|
: WriteMetaFile(manager, group.Key, group);
|
||||||
if (bytes.Length == 0)
|
if (bytes.Length == 0)
|
||||||
{
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
ret.Add(group.Key, bytes);
|
ret.Add(group.Key, bytes);
|
||||||
}
|
}
|
||||||
|
|
@ -86,7 +82,8 @@ public partial class TexToolsMeta
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Add(RspAttribute.FemaleMinSize, RspAttribute.FemaleMaxSize, RspAttribute.FemaleMinTail, RspAttribute.FemaleMaxTail);
|
Add(RspAttribute.FemaleMinSize, RspAttribute.FemaleMaxSize, RspAttribute.FemaleMinTail, RspAttribute.FemaleMaxTail);
|
||||||
Add( RspAttribute.BustMinX, RspAttribute.BustMinY, RspAttribute.BustMinZ, RspAttribute.BustMaxX, RspAttribute.BustMaxY, RspAttribute.BustMaxZ );
|
Add(RspAttribute.BustMinX, RspAttribute.BustMinY, RspAttribute.BustMinZ, RspAttribute.BustMaxX, RspAttribute.BustMaxY,
|
||||||
|
RspAttribute.BustMaxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m.GetBuffer();
|
return m.GetBuffer();
|
||||||
|
|
@ -131,7 +128,8 @@ public partial class TexToolsMeta
|
||||||
return m.ToArray();
|
return m.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static uint WriteData( MetaFileManager manager, BinaryWriter b, uint offset, MetaManipulation.Type type, IEnumerable< MetaManipulation > manips )
|
private static uint WriteData(MetaFileManager manager, BinaryWriter b, uint offset, MetaManipulation.Type type,
|
||||||
|
IEnumerable<MetaManipulation> manips)
|
||||||
{
|
{
|
||||||
var oldPos = b.BaseStream.Position;
|
var oldPos = b.BaseStream.Position;
|
||||||
b.Seek((int)offset, SeekOrigin.Begin);
|
b.Seek((int)offset, SeekOrigin.Begin);
|
||||||
|
|
@ -142,9 +140,7 @@ public partial class TexToolsMeta
|
||||||
var allManips = manips.ToList();
|
var allManips = manips.ToList();
|
||||||
var baseFile = new ImcFile(manager, allManips[0].Imc);
|
var baseFile = new ImcFile(manager, allManips[0].Imc);
|
||||||
foreach (var manip in allManips)
|
foreach (var manip in allManips)
|
||||||
{
|
|
||||||
manip.Imc.Apply(baseFile);
|
manip.Imc.Apply(baseFile);
|
||||||
}
|
|
||||||
|
|
||||||
var partIdx = allManips[0].Imc.ObjectType is ObjectType.Equipment or ObjectType.Accessory
|
var partIdx = allManips[0].Imc.ObjectType is ObjectType.Equipment or ObjectType.Accessory
|
||||||
? ImcFile.PartIndex(allManips[0].Imc.EquipSlot)
|
? ImcFile.PartIndex(allManips[0].Imc.EquipSlot)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ using OtterGui;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using OtterTex;
|
using OtterTex;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
using Penumbra.UI;
|
using Penumbra.UI;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Runtime.CompilerServices;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using Dalamud.Utility.Signatures;
|
using Dalamud.Utility.Signatures;
|
||||||
using FFXIVClientStructs.FFXIV.Client.System.Memory;
|
using FFXIVClientStructs.FFXIV.Client.System.Memory;
|
||||||
|
using OtterGui.Compression;
|
||||||
using Penumbra.Collections;
|
using Penumbra.Collections;
|
||||||
using Penumbra.Collections.Manager;
|
using Penumbra.Collections.Manager;
|
||||||
using Penumbra.GameData;
|
using Penumbra.GameData;
|
||||||
|
|
@ -26,9 +27,11 @@ public unsafe class MetaFileManager
|
||||||
internal readonly ActiveCollectionData ActiveCollections;
|
internal readonly ActiveCollectionData ActiveCollections;
|
||||||
internal readonly ValidityChecker ValidityChecker;
|
internal readonly ValidityChecker ValidityChecker;
|
||||||
internal readonly IdentifierService Identifier;
|
internal readonly IdentifierService Identifier;
|
||||||
|
internal readonly FileCompactor Compactor;
|
||||||
|
|
||||||
public MetaFileManager(CharacterUtility characterUtility, ResidentResourceManager residentResources, IDataManager gameData,
|
public MetaFileManager(CharacterUtility characterUtility, ResidentResourceManager residentResources, IDataManager gameData,
|
||||||
ActiveCollectionData activeCollections, Configuration config, ValidityChecker validityChecker, IdentifierService identifier)
|
ActiveCollectionData activeCollections, Configuration config, ValidityChecker validityChecker, IdentifierService identifier,
|
||||||
|
FileCompactor compactor)
|
||||||
{
|
{
|
||||||
CharacterUtility = characterUtility;
|
CharacterUtility = characterUtility;
|
||||||
ResidentResources = residentResources;
|
ResidentResources = residentResources;
|
||||||
|
|
@ -37,6 +40,7 @@ public unsafe class MetaFileManager
|
||||||
Config = config;
|
Config = config;
|
||||||
ValidityChecker = validityChecker;
|
ValidityChecker = validityChecker;
|
||||||
Identifier = identifier;
|
Identifier = identifier;
|
||||||
|
Compactor = compactor;
|
||||||
SignatureHelper.Initialise(this);
|
SignatureHelper.Initialise(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Compression;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Files;
|
using Penumbra.GameData.Files;
|
||||||
using Penumbra.Mods.Editor;
|
using Penumbra.Mods.Editor;
|
||||||
|
|
@ -26,10 +27,10 @@ public partial class MdlMaterialEditor
|
||||||
public MdlMaterialEditor(ModFileCollection files)
|
public MdlMaterialEditor(ModFileCollection files)
|
||||||
=> _files = files;
|
=> _files = files;
|
||||||
|
|
||||||
public void SaveAllModels()
|
public void SaveAllModels(FileCompactor compactor)
|
||||||
{
|
{
|
||||||
foreach (var info in _modelFiles)
|
foreach (var info in _modelFiles)
|
||||||
info.Save();
|
info.Save(compactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RestoreAllModels()
|
public void RestoreAllModels()
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using Penumbra.Mods.Editor;
|
using OtterGui.Compression;
|
||||||
using Penumbra.Mods.Subclasses;
|
using Penumbra.Mods.Subclasses;
|
||||||
|
|
||||||
namespace Penumbra.Mods;
|
namespace Penumbra.Mods.Editor;
|
||||||
|
|
||||||
public class ModEditor : IDisposable
|
public class ModEditor : IDisposable
|
||||||
{
|
{
|
||||||
|
|
@ -15,6 +15,7 @@ public class ModEditor : IDisposable
|
||||||
public readonly ModFileCollection Files;
|
public readonly ModFileCollection Files;
|
||||||
public readonly ModSwapEditor SwapEditor;
|
public readonly ModSwapEditor SwapEditor;
|
||||||
public readonly MdlMaterialEditor MdlMaterialEditor;
|
public readonly MdlMaterialEditor MdlMaterialEditor;
|
||||||
|
public readonly FileCompactor Compactor;
|
||||||
|
|
||||||
public Mod? Mod { get; private set; }
|
public Mod? Mod { get; private set; }
|
||||||
public int GroupIdx { get; private set; }
|
public int GroupIdx { get; private set; }
|
||||||
|
|
@ -24,7 +25,8 @@ public class ModEditor : IDisposable
|
||||||
public ISubMod? Option { get; private set; }
|
public ISubMod? Option { get; private set; }
|
||||||
|
|
||||||
public ModEditor(ModNormalizer modNormalizer, ModMetaEditor metaEditor, ModFileCollection files,
|
public ModEditor(ModNormalizer modNormalizer, ModMetaEditor metaEditor, ModFileCollection files,
|
||||||
ModFileEditor fileEditor, DuplicateManager duplicates, ModSwapEditor swapEditor, MdlMaterialEditor mdlMaterialEditor)
|
ModFileEditor fileEditor, DuplicateManager duplicates, ModSwapEditor swapEditor, MdlMaterialEditor mdlMaterialEditor,
|
||||||
|
FileCompactor compactor)
|
||||||
{
|
{
|
||||||
ModNormalizer = modNormalizer;
|
ModNormalizer = modNormalizer;
|
||||||
MetaEditor = metaEditor;
|
MetaEditor = metaEditor;
|
||||||
|
|
@ -33,6 +35,7 @@ public class ModEditor : IDisposable
|
||||||
Duplicates = duplicates;
|
Duplicates = duplicates;
|
||||||
SwapEditor = swapEditor;
|
SwapEditor = swapEditor;
|
||||||
MdlMaterialEditor = mdlMaterialEditor;
|
MdlMaterialEditor = mdlMaterialEditor;
|
||||||
|
Compactor = compactor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadMod(Mod mod)
|
public void LoadMod(Mod mod)
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,11 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Compression;
|
||||||
using Penumbra.GameData.Files;
|
using Penumbra.GameData.Files;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.Mods;
|
namespace Penumbra.Mods.Editor;
|
||||||
|
|
||||||
/// <summary> A class that collects information about skin materials in a model file and handle changes on them. </summary>
|
/// <summary> A class that collects information about skin materials in a model file and handle changes on them. </summary>
|
||||||
public class ModelMaterialInfo
|
public class ModelMaterialInfo
|
||||||
|
|
@ -40,7 +41,7 @@ public class ModelMaterialInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save a changed .mdl file.
|
// Save a changed .mdl file.
|
||||||
public void Save()
|
public void Save(FileCompactor compactor)
|
||||||
{
|
{
|
||||||
if (!Changed)
|
if (!Changed)
|
||||||
return;
|
return;
|
||||||
|
|
@ -50,7 +51,7 @@ public class ModelMaterialInfo
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.IO.File.WriteAllBytes(Path.FullName, File.Write());
|
compactor.WriteAllBytes(Path.FullName, File.Write());
|
||||||
Changed = false;
|
Changed = false;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,6 @@ public class ItemSwapContainer
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if( writeType == WriteType.UseSwaps && file.SwapToModdedExistsInGame && !file.DataWasChanged )
|
if( writeType == WriteType.UseSwaps && file.SwapToModdedExistsInGame && !file.DataWasChanged )
|
||||||
{
|
{
|
||||||
convertedSwaps.TryAdd( file.SwapFromRequestPath, file.SwapToModded );
|
convertedSwaps.TryAdd( file.SwapFromRequestPath, file.SwapToModded );
|
||||||
|
|
@ -73,7 +72,7 @@ public class ItemSwapContainer
|
||||||
var path = file.GetNewPath( directory.FullName );
|
var path = file.GetNewPath( directory.FullName );
|
||||||
var bytes = file.FileData.Write();
|
var bytes = file.FileData.Write();
|
||||||
Directory.CreateDirectory( Path.GetDirectoryName( path )! );
|
Directory.CreateDirectory( Path.GetDirectoryName( path )! );
|
||||||
File.WriteAllBytes( path, bytes );
|
_manager.Compactor.WriteAllBytes( path, bytes );
|
||||||
convertedFiles.TryAdd( file.SwapFromRequestPath, new FullPath( path ) );
|
convertedFiles.TryAdd( file.SwapFromRequestPath, new FullPath( path ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Interface.Internal.Notifications;
|
using Dalamud.Interface.Internal.Notifications;
|
||||||
using Penumbra.Import;
|
using Penumbra.Import;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
|
|
||||||
namespace Penumbra.Mods.Manager;
|
namespace Penumbra.Mods.Manager;
|
||||||
|
|
||||||
|
|
@ -57,7 +58,7 @@ public class ModImportManager : IDisposable
|
||||||
if (files.Length == 0)
|
if (files.Length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_import = new TexToolsImporter(files.Length, files, AddNewMod, _config, _modEditor, _modManager);
|
_import = new TexToolsImporter(files.Length, files, AddNewMod, _config, _modEditor, _modManager, _modEditor.Compactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Importing
|
public bool Importing
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Compression;
|
||||||
using OtterGui.Log;
|
using OtterGui.Log;
|
||||||
using Penumbra.Api;
|
using Penumbra.Api;
|
||||||
using Penumbra.Collections.Cache;
|
using Penumbra.Collections.Cache;
|
||||||
|
|
@ -62,7 +63,8 @@ public static class ServiceManager
|
||||||
.AddSingleton<BackupService>()
|
.AddSingleton<BackupService>()
|
||||||
.AddSingleton<CommunicatorService>()
|
.AddSingleton<CommunicatorService>()
|
||||||
.AddSingleton<ChatService>()
|
.AddSingleton<ChatService>()
|
||||||
.AddSingleton<SaveService>();
|
.AddSingleton<SaveService>()
|
||||||
|
.AddSingleton<FileCompactor>();
|
||||||
|
|
||||||
|
|
||||||
private static IServiceCollection AddGameData(this IServiceCollection services)
|
private static IServiceCollection AddGameData(this IServiceCollection services)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using Dalamud.Plugin.Services;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
using OtterGui.Classes;
|
using OtterGui.Classes;
|
||||||
|
using OtterGui.Compression;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
using Penumbra.GameData.Files;
|
using Penumbra.GameData.Files;
|
||||||
|
|
@ -23,9 +24,10 @@ public class FileEditor<T> : IDisposable where T : class, IWritable
|
||||||
private readonly FileDialogService _fileDialog;
|
private readonly FileDialogService _fileDialog;
|
||||||
private readonly IDataManager _gameData;
|
private readonly IDataManager _gameData;
|
||||||
private readonly ModEditWindow _owner;
|
private readonly ModEditWindow _owner;
|
||||||
|
private readonly FileCompactor _compactor;
|
||||||
|
|
||||||
public FileEditor(ModEditWindow owner, IDataManager gameData, Configuration config, FileDialogService fileDialog, string tabName,
|
public FileEditor(ModEditWindow owner, IDataManager gameData, Configuration config, FileCompactor compactor, FileDialogService fileDialog,
|
||||||
string fileType, Func<IReadOnlyList<FileRegistry>> getFiles, Func<T, bool, bool> drawEdit, Func<string> getInitialPath,
|
string tabName, string fileType, Func<IReadOnlyList<FileRegistry>> getFiles, Func<T, bool, bool> drawEdit, Func<string> getInitialPath,
|
||||||
Func<byte[], string, bool, T?> parseFile)
|
Func<byte[], string, bool, T?> parseFile)
|
||||||
{
|
{
|
||||||
_owner = owner;
|
_owner = owner;
|
||||||
|
|
@ -36,6 +38,7 @@ public class FileEditor<T> : IDisposable where T : class, IWritable
|
||||||
_drawEdit = drawEdit;
|
_drawEdit = drawEdit;
|
||||||
_getInitialPath = getInitialPath;
|
_getInitialPath = getInitialPath;
|
||||||
_parseFile = parseFile;
|
_parseFile = parseFile;
|
||||||
|
_compactor = compactor;
|
||||||
_combo = new Combo(config, getFiles);
|
_combo = new Combo(config, getFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,7 +138,7 @@ public class FileEditor<T> : IDisposable where T : class, IWritable
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(name, _defaultFile?.Write() ?? throw new Exception("File invalid."));
|
_compactor.WriteAllBytes(name, _defaultFile?.Write() ?? throw new Exception("File invalid."));
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -209,7 +212,7 @@ public class FileEditor<T> : IDisposable where T : class, IWritable
|
||||||
if (ImGuiUtil.DrawDisabledButton("Save to File", Vector2.Zero,
|
if (ImGuiUtil.DrawDisabledButton("Save to File", Vector2.Zero,
|
||||||
$"Save the selected {_fileType} file with all changes applied. This is not revertible.", !_changed))
|
$"Save the selected {_fileType} file with all changes applied. This is not revertible.", !_changed))
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(_currentPath!.File.FullName, _currentFile!.Write());
|
_compactor.WriteAllBytes(_currentPath!.File.FullName, _currentFile!.Write());
|
||||||
_changed = false;
|
_changed = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,7 @@ public partial class ModEditWindow
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Save.ToIconString(), iconSize,
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Save.ToIconString(), iconSize,
|
||||||
"Save the changed mdl file.\nUse at own risk!", !info.Changed, true))
|
"Save the changed mdl file.\nUse at own risk!", !info.Changed, true))
|
||||||
info.Save();
|
info.Save(_editor.Compactor);
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Recycle.ToIconString(), iconSize,
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Recycle.ToIconString(), iconSize,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ using Penumbra.Meta;
|
||||||
using Penumbra.Meta.Files;
|
using Penumbra.Meta.Files;
|
||||||
using Penumbra.Meta.Manipulations;
|
using Penumbra.Meta.Manipulations;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.UI.Classes;
|
using Penumbra.UI.Classes;
|
||||||
|
|
||||||
namespace Penumbra.UI.AdvancedWindow;
|
namespace Penumbra.UI.AdvancedWindow;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ using OtterGui.Raii;
|
||||||
using Penumbra.GameData.Files;
|
using Penumbra.GameData.Files;
|
||||||
using Penumbra.Interop.ResourceTree;
|
using Penumbra.Interop.ResourceTree;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.String.Classes;
|
using Penumbra.String.Classes;
|
||||||
|
|
||||||
namespace Penumbra.UI.AdvancedWindow;
|
namespace Penumbra.UI.AdvancedWindow;
|
||||||
|
|
@ -72,7 +73,7 @@ public partial class ModEditWindow
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
File.WriteAllBytes(name, writable!.Write());
|
_editor.Compactor.WriteAllBytes(name, writable!.Write());
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
@ -194,7 +195,7 @@ public partial class ModEditWindow
|
||||||
var directory = Path.GetDirectoryName(_targetPath);
|
var directory = Path.GetDirectoryName(_targetPath);
|
||||||
if (directory != null)
|
if (directory != null)
|
||||||
Directory.CreateDirectory(directory);
|
Directory.CreateDirectory(directory);
|
||||||
File.WriteAllBytes(_targetPath!, _file!.Write());
|
_editor.Compactor.WriteAllBytes(_targetPath!, _file!.Write());
|
||||||
_editor.FileEditor.Revert(_editor.Mod!, _editor.Option!);
|
_editor.FileEditor.Revert(_editor.Mod!, _editor.Option!);
|
||||||
var fileRegistry = _editor.Files.Available.First(file => file.File.FullName == _targetPath);
|
var fileRegistry = _editor.Files.Available.First(file => file.File.FullName == _targetPath);
|
||||||
_editor.FileEditor.AddPathsToSelected(_editor.Option!, new[]
|
_editor.FileEditor.AddPathsToSelected(_editor.Option!, new[]
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ using Dalamud.Interface.Windowing;
|
||||||
using Dalamud.Plugin.Services;
|
using Dalamud.Plugin.Services;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Compression;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using Penumbra.Collections.Manager;
|
using Penumbra.Collections.Manager;
|
||||||
using Penumbra.Communication;
|
using Penumbra.Communication;
|
||||||
|
|
@ -22,6 +23,7 @@ using Penumbra.Interop.ResourceTree;
|
||||||
using Penumbra.Interop.Services;
|
using Penumbra.Interop.Services;
|
||||||
using Penumbra.Meta;
|
using Penumbra.Meta;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
using Penumbra.Mods.Editor;
|
||||||
using Penumbra.Mods.Manager;
|
using Penumbra.Mods.Manager;
|
||||||
using Penumbra.Services;
|
using Penumbra.Services;
|
||||||
using Penumbra.String;
|
using Penumbra.String;
|
||||||
|
|
@ -236,7 +238,7 @@ public partial class ModEditWindow : Window, IDisposable
|
||||||
var anyChanges = editor.MdlMaterialEditor.ModelFiles.Any(m => m.Changed);
|
var anyChanges = editor.MdlMaterialEditor.ModelFiles.Any(m => m.Changed);
|
||||||
if (ImGuiUtil.DrawDisabledButton("Save All Changes", buttonSize,
|
if (ImGuiUtil.DrawDisabledButton("Save All Changes", buttonSize,
|
||||||
anyChanges ? "Irreversibly rewrites all currently applied changes to model files." : "No changes made yet.", !anyChanges))
|
anyChanges ? "Irreversibly rewrites all currently applied changes to model files." : "No changes made yet.", !anyChanges))
|
||||||
editor.MdlMaterialEditor.SaveAllModels();
|
editor.MdlMaterialEditor.SaveAllModels(editor.Compactor);
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
if (ImGuiUtil.DrawDisabledButton("Revert All Changes", buttonSize,
|
if (ImGuiUtil.DrawDisabledButton("Revert All Changes", buttonSize,
|
||||||
|
|
@ -572,17 +574,18 @@ public partial class ModEditWindow : Window, IDisposable
|
||||||
_textures = textures;
|
_textures = textures;
|
||||||
_fileDialog = fileDialog;
|
_fileDialog = fileDialog;
|
||||||
_gameEvents = gameEvents;
|
_gameEvents = gameEvents;
|
||||||
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _fileDialog, "Materials", ".mtrl",
|
_materialTab = new FileEditor<MtrlTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Materials", ".mtrl",
|
||||||
() => _editor.Files.Mtrl, DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
|
() => _editor.Files.Mtrl, DrawMaterialPanel, () => _mod?.ModPath.FullName ?? string.Empty,
|
||||||
(bytes, path, writable) => new MtrlTab(this, new MtrlFile(bytes), path, writable));
|
(bytes, path, writable) => new MtrlTab(this, new MtrlFile(bytes), path, writable));
|
||||||
_modelTab = new FileEditor<MdlFile>(this, gameData, config, _fileDialog, "Models", ".mdl",
|
_modelTab = new FileEditor<MdlFile>(this, gameData, config, _editor.Compactor, _fileDialog, "Models", ".mdl",
|
||||||
() => _editor.Files.Mdl, DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty, (bytes, _, _) => new MdlFile(bytes));
|
() => _editor.Files.Mdl, DrawModelPanel, () => _mod?.ModPath.FullName ?? string.Empty, (bytes, _, _) => new MdlFile(bytes));
|
||||||
_shaderPackageTab = new FileEditor<ShpkTab>(this, gameData, config, _fileDialog, "Shaders", ".shpk",
|
_shaderPackageTab = new FileEditor<ShpkTab>(this, gameData, config, _editor.Compactor, _fileDialog, "Shaders", ".shpk",
|
||||||
() => _editor.Files.Shpk, DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty,
|
() => _editor.Files.Shpk, DrawShaderPackagePanel, () => _mod?.ModPath.FullName ?? string.Empty,
|
||||||
(bytes, _, _) => new ShpkTab(_fileDialog, bytes));
|
(bytes, _, _) => new ShpkTab(_fileDialog, bytes));
|
||||||
_center = new CombinedTexture(_left, _right);
|
_center = new CombinedTexture(_left, _right);
|
||||||
_textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor);
|
_textureSelectCombo = new TextureDrawer.PathSelectCombo(textures, editor);
|
||||||
_quickImportViewer = new ResourceTreeViewer(_config, resourceTreeFactory, changedItemDrawer, 2, OnQuickImportRefresh, DrawQuickImportActions);
|
_quickImportViewer =
|
||||||
|
new ResourceTreeViewer(_config, resourceTreeFactory, changedItemDrawer, 2, OnQuickImportRefresh, DrawQuickImportActions);
|
||||||
_communicator.ModPathChanged.Subscribe(OnModPathChanged, ModPathChanged.Priority.ModEditWindow);
|
_communicator.ModPathChanged.Subscribe(OnModPathChanged, ModPathChanged.Priority.ModEditWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ public class ModPanelEditTab : ITab
|
||||||
_editor.LoadMod(_mod);
|
_editor.LoadMod(_mod);
|
||||||
_editor.MdlMaterialEditor.ReplaceAllMaterials("bibo", "b");
|
_editor.MdlMaterialEditor.ReplaceAllMaterials("bibo", "b");
|
||||||
_editor.MdlMaterialEditor.ReplaceAllMaterials("bibopube", "c");
|
_editor.MdlMaterialEditor.ReplaceAllMaterials("bibopube", "c");
|
||||||
_editor.MdlMaterialEditor.SaveAllModels();
|
_editor.MdlMaterialEditor.SaveAllModels(_editor.Compactor);
|
||||||
_editWindow.UpdateModels();
|
_editWindow.UpdateModels();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Dalamud.Interface.Components;
|
||||||
using Dalamud.Utility;
|
using Dalamud.Utility;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using OtterGui;
|
using OtterGui;
|
||||||
|
using OtterGui.Compression;
|
||||||
using OtterGui.Custom;
|
using OtterGui.Custom;
|
||||||
using OtterGui.Raii;
|
using OtterGui.Raii;
|
||||||
using OtterGui.Widgets;
|
using OtterGui.Widgets;
|
||||||
|
|
@ -39,6 +40,7 @@ public class SettingsTab : ITab
|
||||||
private readonly DalamudServices _dalamud;
|
private readonly DalamudServices _dalamud;
|
||||||
private readonly HttpApi _httpApi;
|
private readonly HttpApi _httpApi;
|
||||||
private readonly DalamudSubstitutionProvider _dalamudSubstitutionProvider;
|
private readonly DalamudSubstitutionProvider _dalamudSubstitutionProvider;
|
||||||
|
private readonly FileCompactor _compactor;
|
||||||
|
|
||||||
private int _minimumX = int.MaxValue;
|
private int _minimumX = int.MaxValue;
|
||||||
private int _minimumY = int.MaxValue;
|
private int _minimumY = int.MaxValue;
|
||||||
|
|
@ -46,7 +48,7 @@ public class SettingsTab : ITab
|
||||||
public SettingsTab(Configuration config, FontReloader fontReloader, TutorialService tutorial, Penumbra penumbra,
|
public SettingsTab(Configuration config, FontReloader fontReloader, TutorialService tutorial, Penumbra penumbra,
|
||||||
FileDialogService fileDialog, ModManager modManager, ModFileSystemSelector selector, CharacterUtility characterUtility,
|
FileDialogService fileDialog, ModManager modManager, ModFileSystemSelector selector, CharacterUtility characterUtility,
|
||||||
ResidentResourceManager residentResources, DalamudServices dalamud, ModExportManager modExportManager, HttpApi httpApi,
|
ResidentResourceManager residentResources, DalamudServices dalamud, ModExportManager modExportManager, HttpApi httpApi,
|
||||||
DalamudSubstitutionProvider dalamudSubstitutionProvider)
|
DalamudSubstitutionProvider dalamudSubstitutionProvider, FileCompactor compactor)
|
||||||
{
|
{
|
||||||
_config = config;
|
_config = config;
|
||||||
_fontReloader = fontReloader;
|
_fontReloader = fontReloader;
|
||||||
|
|
@ -61,6 +63,9 @@ public class SettingsTab : ITab
|
||||||
_modExportManager = modExportManager;
|
_modExportManager = modExportManager;
|
||||||
_httpApi = httpApi;
|
_httpApi = httpApi;
|
||||||
_dalamudSubstitutionProvider = dalamudSubstitutionProvider;
|
_dalamudSubstitutionProvider = dalamudSubstitutionProvider;
|
||||||
|
_compactor = compactor;
|
||||||
|
if (_compactor.CanCompact)
|
||||||
|
_compactor.Enabled = _config.UseFileSystemCompression;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawHeader()
|
public void DrawHeader()
|
||||||
|
|
@ -661,6 +666,7 @@ public class SettingsTab : ITab
|
||||||
Checkbox("Auto Deduplicate on Import",
|
Checkbox("Auto Deduplicate on Import",
|
||||||
"Automatically deduplicate mod files on import. This will make mod file sizes smaller, but deletes (binary identical) files.",
|
"Automatically deduplicate mod files on import. This will make mod file sizes smaller, but deletes (binary identical) files.",
|
||||||
_config.AutoDeduplicateOnImport, v => _config.AutoDeduplicateOnImport = v);
|
_config.AutoDeduplicateOnImport, v => _config.AutoDeduplicateOnImport = v);
|
||||||
|
DrawCompressionBox();
|
||||||
Checkbox("Keep Default Metadata Changes on Import",
|
Checkbox("Keep Default Metadata Changes on Import",
|
||||||
"Normally, metadata changes that equal their default values, which are sometimes exported by TexTools, are discarded. "
|
"Normally, metadata changes that equal their default values, which are sometimes exported by TexTools, are discarded. "
|
||||||
+ "Toggle this to keep them, for example if an option in a mod is supposed to disable a metadata change from a prior option.",
|
+ "Toggle this to keep them, for example if an option in a mod is supposed to disable a metadata change from a prior option.",
|
||||||
|
|
@ -673,6 +679,47 @@ public class SettingsTab : ITab
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DrawCompressionBox()
|
||||||
|
{
|
||||||
|
if (!_compactor.CanCompact)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Checkbox("Use Filesystem Compression",
|
||||||
|
"Use Windows functionality to transparently reduce storage size of mod files on your computer. This might cost performance, but seems to generally be beneficial to performance by shifting more responsibility to the underused CPU and away from the overused hard drives.",
|
||||||
|
_config.UseFileSystemCompression,
|
||||||
|
v =>
|
||||||
|
{
|
||||||
|
_config.UseFileSystemCompression = v;
|
||||||
|
_compactor.Enabled = v;
|
||||||
|
});
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGuiUtil.DrawDisabledButton("Compress Existing Files", Vector2.Zero,
|
||||||
|
"Try to compress all files in your root directory. This will take a while.",
|
||||||
|
_compactor.MassCompactRunning || !_modManager.Valid))
|
||||||
|
_compactor.StartMassCompact(_modManager.BasePath.EnumerateFiles("*.*", SearchOption.AllDirectories), CompressionAlgorithm.Xpress8K);
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGuiUtil.DrawDisabledButton("Decompress Existing Files", Vector2.Zero,
|
||||||
|
"Try to decompress all files in your root directory. This will take a while.",
|
||||||
|
_compactor.MassCompactRunning || !_modManager.Valid))
|
||||||
|
_compactor.StartMassCompact(_modManager.BasePath.EnumerateFiles("*.*", SearchOption.AllDirectories), CompressionAlgorithm.None);
|
||||||
|
|
||||||
|
if (_compactor.MassCompactRunning)
|
||||||
|
{
|
||||||
|
ImGui.ProgressBar((float)_compactor.CurrentIndex / _compactor.TotalFiles,
|
||||||
|
new Vector2(ImGui.GetContentRegionAvail().X - ImGui.GetStyle().ItemSpacing.X - UiHelpers.IconButtonSize.X, ImGui.GetFrameHeight()),
|
||||||
|
_compactor.CurrentFile?.FullName[(_modManager.BasePath.FullName.Length + 1)..] ?? "Gathering Files...");
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGuiUtil.DrawDisabledButton(FontAwesomeIcon.Ban.ToIconString(), UiHelpers.IconButtonSize, "Cancel the mass action.",
|
||||||
|
!_compactor.MassCompactRunning, true))
|
||||||
|
_compactor.CancelMassCompact();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ImGui.Dummy(UiHelpers.IconButtonSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary> Draw two integral inputs for minimum dimensions of this window. </summary>
|
/// <summary> Draw two integral inputs for minimum dimensions of this window. </summary>
|
||||||
private void DrawMinimumDimensionConfig()
|
private void DrawMinimumDimensionConfig()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue