mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-30 12:23:41 +01:00
Add Byte String stuff, remove Services, cleanup and refactor interop stuff, disable path resolver for the moment
This commit is contained in:
parent
0e8f839471
commit
c3454f1d16
65 changed files with 4707 additions and 3371 deletions
|
|
@ -4,231 +4,231 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Dalamud.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Importer;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Structs;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Meta
|
||||
namespace Penumbra.Meta;
|
||||
|
||||
// Corresponds meta manipulations of any kind with the settings for a mod.
|
||||
// DefaultData contains all manipulations that are active regardless of option groups.
|
||||
// GroupData contains a mapping of Group -> { Options -> {Manipulations} }.
|
||||
public class MetaCollection
|
||||
{
|
||||
// Corresponds meta manipulations of any kind with the settings for a mod.
|
||||
// DefaultData contains all manipulations that are active regardless of option groups.
|
||||
// GroupData contains a mapping of Group -> { Options -> {Manipulations} }.
|
||||
public class MetaCollection
|
||||
public List< MetaManipulation > DefaultData = new();
|
||||
public Dictionary< string, Dictionary< string, List< MetaManipulation > > > GroupData = new();
|
||||
|
||||
|
||||
// Store total number of manipulations for some ease of access.
|
||||
[JsonIgnore]
|
||||
internal int Count;
|
||||
|
||||
|
||||
// Return an enumeration of all active meta manipulations for a given mod with given settings.
|
||||
public IEnumerable< MetaManipulation > GetManipulationsForConfig( ModSettings settings, ModMeta modMeta )
|
||||
{
|
||||
public List< MetaManipulation > DefaultData = new();
|
||||
public Dictionary< string, Dictionary< string, List< MetaManipulation > > > GroupData = new();
|
||||
|
||||
|
||||
// Store total number of manipulations for some ease of access.
|
||||
[JsonIgnore]
|
||||
internal int Count;
|
||||
|
||||
|
||||
// Return an enumeration of all active meta manipulations for a given mod with given settings.
|
||||
public IEnumerable< MetaManipulation > GetManipulationsForConfig( ModSettings settings, ModMeta modMeta )
|
||||
if( Count == DefaultData.Count )
|
||||
{
|
||||
if( Count == DefaultData.Count )
|
||||
return DefaultData;
|
||||
}
|
||||
|
||||
IEnumerable< MetaManipulation > ret = DefaultData;
|
||||
|
||||
foreach( var group in modMeta.Groups )
|
||||
{
|
||||
if( !GroupData.TryGetValue( group.Key, out var metas ) || !settings.Settings.TryGetValue( group.Key, out var setting ) )
|
||||
{
|
||||
return DefaultData;
|
||||
continue;
|
||||
}
|
||||
|
||||
IEnumerable< MetaManipulation > ret = DefaultData;
|
||||
|
||||
foreach( var group in modMeta.Groups )
|
||||
if( group.Value.SelectionType == SelectType.Single )
|
||||
{
|
||||
if( !GroupData.TryGetValue( group.Key, out var metas ) || !settings.Settings.TryGetValue( group.Key, out var setting ) )
|
||||
var settingName = group.Value.Options[ setting ].OptionName;
|
||||
if( metas.TryGetValue( settingName, out var meta ) )
|
||||
{
|
||||
continue;
|
||||
ret = ret.Concat( meta );
|
||||
}
|
||||
|
||||
if( group.Value.SelectionType == SelectType.Single )
|
||||
}
|
||||
else
|
||||
{
|
||||
for( var i = 0; i < group.Value.Options.Count; ++i )
|
||||
{
|
||||
var settingName = group.Value.Options[ setting ].OptionName;
|
||||
var flag = 1 << i;
|
||||
if( ( setting & flag ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var settingName = group.Value.Options[ i ].OptionName;
|
||||
if( metas.TryGetValue( settingName, out var meta ) )
|
||||
{
|
||||
ret = ret.Concat( meta );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( var i = 0; i < group.Value.Options.Count; ++i )
|
||||
{
|
||||
var flag = 1 << i;
|
||||
if( ( setting & flag ) == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var settingName = group.Value.Options[ i ].OptionName;
|
||||
if( metas.TryGetValue( settingName, out var meta ) )
|
||||
{
|
||||
ret = ret.Concat( meta );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check that the collection is still basically valid,
|
||||
// i.e. keep it sorted, and verify that the options stored by name are all still part of the mod,
|
||||
// and that the contained manipulations are still valid and non-default manipulations.
|
||||
public bool Validate( ModMeta modMeta )
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check that the collection is still basically valid,
|
||||
// i.e. keep it sorted, and verify that the options stored by name are all still part of the mod,
|
||||
// and that the contained manipulations are still valid and non-default manipulations.
|
||||
public bool Validate( ModMeta modMeta )
|
||||
{
|
||||
var defaultFiles = Penumbra.MetaDefaults;
|
||||
SortLists();
|
||||
foreach( var group in GroupData )
|
||||
{
|
||||
var defaultFiles = Service< MetaDefaults >.Get();
|
||||
SortLists();
|
||||
foreach( var group in GroupData )
|
||||
if( !modMeta.Groups.TryGetValue( group.Key, out var options ) )
|
||||
{
|
||||
if( !modMeta.Groups.TryGetValue( group.Key, out var options ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach( var option in group.Value )
|
||||
{
|
||||
if( options.Options.All( o => o.OptionName != option.Key ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach( var option in group.Value )
|
||||
if( option.Value.Any( manip => defaultFiles.CheckAgainstDefault( manip ) ) )
|
||||
{
|
||||
if( options.Options.All( o => o.OptionName != option.Key ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( option.Value.Any( manip => defaultFiles.CheckAgainstDefault( manip ) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return DefaultData.All( manip => !defaultFiles.CheckAgainstDefault( manip ) );
|
||||
}
|
||||
|
||||
// Re-sort all manipulations.
|
||||
private void SortLists()
|
||||
{
|
||||
DefaultData.Sort();
|
||||
foreach( var list in GroupData.Values.SelectMany( g => g.Values ) )
|
||||
{
|
||||
list.Sort();
|
||||
}
|
||||
}
|
||||
|
||||
// Add a parsed TexTools .meta file to a given option group and option. If group is the empty string, add it to default.
|
||||
// Creates the option group and the option if necessary.
|
||||
private void AddMeta( string group, string option, TexToolsMeta meta )
|
||||
return DefaultData.All( manip => !defaultFiles.CheckAgainstDefault( manip ) );
|
||||
}
|
||||
|
||||
// Re-sort all manipulations.
|
||||
private void SortLists()
|
||||
{
|
||||
DefaultData.Sort();
|
||||
foreach( var list in GroupData.Values.SelectMany( g => g.Values ) )
|
||||
{
|
||||
if( meta.Manipulations.Count == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
list.Sort();
|
||||
}
|
||||
}
|
||||
|
||||
if( group.Length == 0 )
|
||||
{
|
||||
DefaultData.AddRange( meta.Manipulations );
|
||||
}
|
||||
else if( option.Length == 0 )
|
||||
{ }
|
||||
else if( !GroupData.TryGetValue( group, out var options ) )
|
||||
{
|
||||
GroupData.Add( group, new Dictionary< string, List< MetaManipulation > >() { { option, meta.Manipulations.ToList() } } );
|
||||
}
|
||||
else if( !options.TryGetValue( option, out var list ) )
|
||||
{
|
||||
options.Add( option, meta.Manipulations.ToList() );
|
||||
}
|
||||
else
|
||||
{
|
||||
list.AddRange( meta.Manipulations );
|
||||
}
|
||||
|
||||
Count += meta.Manipulations.Count;
|
||||
// Add a parsed TexTools .meta file to a given option group and option. If group is the empty string, add it to default.
|
||||
// Creates the option group and the option if necessary.
|
||||
private void AddMeta( string group, string option, TexToolsMeta meta )
|
||||
{
|
||||
if( meta.Manipulations.Count == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the whole meta collection by reading all TexTools .meta files in a mod directory anew,
|
||||
// combining them with the given ModMeta.
|
||||
public void Update( IEnumerable< FullPath > files, DirectoryInfo basePath, ModMeta modMeta )
|
||||
if( group.Length == 0 )
|
||||
{
|
||||
DefaultData.Clear();
|
||||
GroupData.Clear();
|
||||
Count = 0;
|
||||
foreach( var file in files )
|
||||
{
|
||||
TexToolsMeta metaData = file.Extension.ToLowerInvariant() switch
|
||||
{
|
||||
".meta" => new TexToolsMeta( File.ReadAllBytes( file.FullName ) ),
|
||||
".rgsp" => TexToolsMeta.FromRgspFile( file.FullName, File.ReadAllBytes( file.FullName ) ),
|
||||
_ => TexToolsMeta.Invalid,
|
||||
};
|
||||
|
||||
if( metaData.FilePath == string.Empty || metaData.Manipulations.Count == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var path = new RelPath( file, basePath );
|
||||
var foundAny = false;
|
||||
foreach( var group in modMeta.Groups )
|
||||
{
|
||||
foreach( var option in group.Value.Options.Where( o => o.OptionFiles.ContainsKey( path ) ) )
|
||||
{
|
||||
foundAny = true;
|
||||
AddMeta( group.Key, option.OptionName, metaData );
|
||||
}
|
||||
}
|
||||
|
||||
if( !foundAny )
|
||||
{
|
||||
AddMeta( string.Empty, string.Empty, metaData );
|
||||
}
|
||||
}
|
||||
|
||||
SortLists();
|
||||
DefaultData.AddRange( meta.Manipulations );
|
||||
}
|
||||
else if( option.Length == 0 )
|
||||
{ }
|
||||
else if( !GroupData.TryGetValue( group, out var options ) )
|
||||
{
|
||||
GroupData.Add( group, new Dictionary< string, List< MetaManipulation > >() { { option, meta.Manipulations.ToList() } } );
|
||||
}
|
||||
else if( !options.TryGetValue( option, out var list ) )
|
||||
{
|
||||
options.Add( option, meta.Manipulations.ToList() );
|
||||
}
|
||||
else
|
||||
{
|
||||
list.AddRange( meta.Manipulations );
|
||||
}
|
||||
|
||||
public static FileInfo FileName( DirectoryInfo basePath )
|
||||
=> new( Path.Combine( basePath.FullName, "metadata_manipulations.json" ) );
|
||||
Count += meta.Manipulations.Count;
|
||||
}
|
||||
|
||||
public void SaveToFile( FileInfo file )
|
||||
// Update the whole meta collection by reading all TexTools .meta files in a mod directory anew,
|
||||
// combining them with the given ModMeta.
|
||||
public void Update( IEnumerable< FullPath > files, DirectoryInfo basePath, ModMeta modMeta )
|
||||
{
|
||||
DefaultData.Clear();
|
||||
GroupData.Clear();
|
||||
Count = 0;
|
||||
foreach( var file in files )
|
||||
{
|
||||
try
|
||||
var metaData = file.Extension.ToLowerInvariant() switch
|
||||
{
|
||||
var text = JsonConvert.SerializeObject( this, Formatting.Indented );
|
||||
File.WriteAllText( file.FullName, text );
|
||||
".meta" => new TexToolsMeta( File.ReadAllBytes( file.FullName ) ),
|
||||
".rgsp" => TexToolsMeta.FromRgspFile( file.FullName, File.ReadAllBytes( file.FullName ) ),
|
||||
_ => TexToolsMeta.Invalid,
|
||||
};
|
||||
|
||||
if( metaData.FilePath == string.Empty || metaData.Manipulations.Count == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
catch( Exception e )
|
||||
|
||||
var path = new RelPath( file, basePath );
|
||||
var foundAny = false;
|
||||
foreach( var group in modMeta.Groups )
|
||||
{
|
||||
PluginLog.Error( $"Could not write metadata manipulations file to {file.FullName}:\n{e}" );
|
||||
foreach( var option in group.Value.Options.Where( o => o.OptionFiles.ContainsKey( path ) ) )
|
||||
{
|
||||
foundAny = true;
|
||||
AddMeta( group.Key, option.OptionName, metaData );
|
||||
}
|
||||
}
|
||||
|
||||
if( !foundAny )
|
||||
{
|
||||
AddMeta( string.Empty, string.Empty, metaData );
|
||||
}
|
||||
}
|
||||
|
||||
public static MetaCollection? LoadFromFile( FileInfo file )
|
||||
SortLists();
|
||||
}
|
||||
|
||||
public static FileInfo FileName( DirectoryInfo basePath )
|
||||
=> new(Path.Combine( basePath.FullName, "metadata_manipulations.json" ));
|
||||
|
||||
public void SaveToFile( FileInfo file )
|
||||
{
|
||||
try
|
||||
{
|
||||
if( !file.Exists )
|
||||
var text = JsonConvert.SerializeObject( this, Formatting.Indented );
|
||||
File.WriteAllText( file.FullName, text );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not write metadata manipulations file to {file.FullName}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
public static MetaCollection? LoadFromFile( FileInfo file )
|
||||
{
|
||||
if( !file.Exists )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText( file.FullName );
|
||||
|
||||
var collection = JsonConvert.DeserializeObject< MetaCollection >( text,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore } );
|
||||
|
||||
if( collection != null )
|
||||
{
|
||||
return null;
|
||||
collection.Count = collection.DefaultData.Count
|
||||
+ collection.GroupData.Values.SelectMany( kvp => kvp.Values ).Sum( l => l.Count );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var text = File.ReadAllText( file.FullName );
|
||||
|
||||
var collection = JsonConvert.DeserializeObject< MetaCollection >( text,
|
||||
new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore } );
|
||||
|
||||
if( collection != null )
|
||||
{
|
||||
collection.Count = collection.DefaultData.Count
|
||||
+ collection.GroupData.Values.SelectMany( kvp => kvp.Values ).Sum( l => l.Count );
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not load mod metadata manipulations from {file.FullName}:\n{e}" );
|
||||
return null;
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not load mod metadata manipulations from {file.FullName}:\n{e}" );
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,182 +4,185 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using Dalamud.Logging;
|
||||
using Lumina.Data.Files;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Interop;
|
||||
using Penumbra.Meta.Files;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Meta
|
||||
namespace Penumbra.Meta;
|
||||
|
||||
public class MetaManager : IDisposable
|
||||
{
|
||||
public class MetaManager : IDisposable
|
||||
internal class FileInformation
|
||||
{
|
||||
internal class FileInformation
|
||||
public readonly object Data;
|
||||
public bool Changed;
|
||||
public FullPath? CurrentFile;
|
||||
public byte[] ByteData = Array.Empty< byte >();
|
||||
|
||||
public FileInformation( object data )
|
||||
=> Data = data;
|
||||
|
||||
public void Write( DirectoryInfo dir, GamePath originalPath )
|
||||
{
|
||||
public readonly object Data;
|
||||
public bool Changed;
|
||||
public FullPath? CurrentFile;
|
||||
|
||||
public FileInformation( object data )
|
||||
=> Data = data;
|
||||
|
||||
public void Write( DirectoryInfo dir, GamePath originalPath )
|
||||
ByteData = Data switch
|
||||
{
|
||||
var data = Data switch
|
||||
{
|
||||
EqdpFile eqdp => eqdp.WriteBytes(),
|
||||
EqpFile eqp => eqp.WriteBytes(),
|
||||
GmpFile gmp => gmp.WriteBytes(),
|
||||
EstFile est => est.WriteBytes(),
|
||||
ImcFile imc => imc.WriteBytes(),
|
||||
CmpFile cmp => cmp.WriteBytes(),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
DisposeFile( CurrentFile );
|
||||
CurrentFile = new FullPath(TempFile.WriteNew( dir, data, $"_{originalPath.Filename()}" ));
|
||||
Changed = false;
|
||||
}
|
||||
EqdpFile eqdp => eqdp.WriteBytes(),
|
||||
EqpFile eqp => eqp.WriteBytes(),
|
||||
GmpFile gmp => gmp.WriteBytes(),
|
||||
EstFile est => est.WriteBytes(),
|
||||
ImcFile imc => imc.WriteBytes(),
|
||||
CmpFile cmp => cmp.WriteBytes(),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
DisposeFile( CurrentFile );
|
||||
CurrentFile = new FullPath( TempFile.WriteNew( dir, ByteData, $"_{originalPath.Filename()}" ) );
|
||||
Changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
public const string TmpDirectory = "penumbrametatmp";
|
||||
|
||||
private readonly DirectoryInfo _dir;
|
||||
private readonly Dictionary< GamePath, FullPath > _resolvedFiles;
|
||||
|
||||
private readonly Dictionary< MetaManipulation, Mod.Mod > _currentManipulations = new();
|
||||
private readonly Dictionary< GamePath, FileInformation > _currentFiles = new();
|
||||
|
||||
public IEnumerable< (MetaManipulation, Mod.Mod) > Manipulations
|
||||
=> _currentManipulations.Select( kvp => ( kvp.Key, kvp.Value ) );
|
||||
|
||||
public IEnumerable< (GamePath, FullPath) > Files
|
||||
=> _currentFiles.Where( kvp => kvp.Value.CurrentFile != null )
|
||||
.Select( kvp => ( kvp.Key, kvp.Value.CurrentFile!.Value ) );
|
||||
|
||||
public int Count
|
||||
=> _currentManipulations.Count;
|
||||
|
||||
public bool TryGetValue( MetaManipulation manip, out Mod.Mod mod )
|
||||
=> _currentManipulations.TryGetValue( manip, out mod! );
|
||||
|
||||
public byte[] EqpData = Array.Empty< byte >();
|
||||
|
||||
private static void DisposeFile( FullPath? file )
|
||||
{
|
||||
if( !( file?.Exists ?? false ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public const string TmpDirectory = "penumbrametatmp";
|
||||
|
||||
private readonly MetaDefaults _default;
|
||||
private readonly DirectoryInfo _dir;
|
||||
private readonly ResidentResources _resourceManagement;
|
||||
private readonly Dictionary< GamePath, FullPath > _resolvedFiles;
|
||||
|
||||
private readonly Dictionary< MetaManipulation, Mod.Mod > _currentManipulations = new();
|
||||
private readonly Dictionary< GamePath, FileInformation > _currentFiles = new();
|
||||
|
||||
public IEnumerable< (MetaManipulation, Mod.Mod) > Manipulations
|
||||
=> _currentManipulations.Select( kvp => ( kvp.Key, kvp.Value ) );
|
||||
|
||||
public IEnumerable< (GamePath, FullPath) > Files
|
||||
=> _currentFiles.Where( kvp => kvp.Value.CurrentFile != null )
|
||||
.Select( kvp => ( kvp.Key, kvp.Value.CurrentFile!.Value ) );
|
||||
|
||||
public int Count
|
||||
=> _currentManipulations.Count;
|
||||
|
||||
public bool TryGetValue( MetaManipulation manip, out Mod.Mod mod )
|
||||
=> _currentManipulations.TryGetValue( manip, out mod! );
|
||||
|
||||
private static void DisposeFile( FullPath? file )
|
||||
try
|
||||
{
|
||||
if( !( file?.Exists ?? false ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
File.Delete( file.Value.FullName );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not delete temporary file \"{file.Value.FullName}\":\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset( bool reload = true )
|
||||
{
|
||||
foreach( var file in _currentFiles )
|
||||
{
|
||||
_resolvedFiles.Remove( file.Key );
|
||||
DisposeFile( file.Value.CurrentFile );
|
||||
}
|
||||
|
||||
_currentManipulations.Clear();
|
||||
_currentFiles.Clear();
|
||||
ClearDirectory();
|
||||
if( reload )
|
||||
{
|
||||
Penumbra.ResidentResources.Reload();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Reset();
|
||||
|
||||
private static void ClearDirectory( DirectoryInfo modDir )
|
||||
{
|
||||
modDir.Refresh();
|
||||
if( modDir.Exists )
|
||||
{
|
||||
try
|
||||
{
|
||||
File.Delete( file.Value.FullName );
|
||||
Directory.Delete( modDir.FullName, true );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not delete temporary file \"{file.Value.FullName}\":\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset( bool reload = true )
|
||||
{
|
||||
foreach( var file in _currentFiles )
|
||||
{
|
||||
_resolvedFiles.Remove( file.Key );
|
||||
DisposeFile( file.Value.CurrentFile );
|
||||
}
|
||||
|
||||
_currentManipulations.Clear();
|
||||
_currentFiles.Clear();
|
||||
ClearDirectory();
|
||||
if( reload )
|
||||
{
|
||||
_resourceManagement.ReloadResidentResources();
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
=> Reset();
|
||||
|
||||
private static void ClearDirectory( DirectoryInfo modDir )
|
||||
{
|
||||
modDir.Refresh();
|
||||
if( modDir.Exists )
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete( modDir.FullName, true );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not clear temporary metafile directory \"{modDir.FullName}\":\n{e}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearDirectory()
|
||||
=> ClearDirectory( _dir );
|
||||
|
||||
public MetaManager( string name, Dictionary< GamePath, FullPath > resolvedFiles, DirectoryInfo tempDir )
|
||||
{
|
||||
_resolvedFiles = resolvedFiles;
|
||||
_default = Service< MetaDefaults >.Get();
|
||||
_resourceManagement = Service< ResidentResources >.Get();
|
||||
_dir = new DirectoryInfo( Path.Combine( tempDir.FullName, name.ReplaceBadXivSymbols() ) );
|
||||
ClearDirectory();
|
||||
}
|
||||
|
||||
public void WriteNewFiles()
|
||||
{
|
||||
if( _currentFiles.Any() )
|
||||
{
|
||||
Directory.CreateDirectory( _dir.FullName );
|
||||
}
|
||||
|
||||
foreach( var kvp in _currentFiles.Where( kvp => kvp.Value.Changed ) )
|
||||
{
|
||||
kvp.Value.Write( _dir, kvp.Key );
|
||||
_resolvedFiles[ kvp.Key ] = kvp.Value.CurrentFile!.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ApplyMod( MetaManipulation m, Mod.Mod mod )
|
||||
{
|
||||
if( _currentManipulations.ContainsKey( m ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_currentManipulations.Add( m, mod );
|
||||
var gamePath = m.CorrespondingFilename();
|
||||
try
|
||||
{
|
||||
if( !_currentFiles.TryGetValue( gamePath, out var file ) )
|
||||
{
|
||||
file = new FileInformation( _default.CreateNewFile( m ) ?? throw new IOException() )
|
||||
{
|
||||
Changed = true,
|
||||
CurrentFile = null,
|
||||
};
|
||||
_currentFiles[ gamePath ] = file;
|
||||
}
|
||||
|
||||
file.Changed |= m.Type switch
|
||||
{
|
||||
MetaType.Eqp => m.Apply( ( EqpFile )file.Data ),
|
||||
MetaType.Eqdp => m.Apply( ( EqdpFile )file.Data ),
|
||||
MetaType.Gmp => m.Apply( ( GmpFile )file.Data ),
|
||||
MetaType.Est => m.Apply( ( EstFile )file.Data ),
|
||||
MetaType.Imc => m.Apply( ( ImcFile )file.Data ),
|
||||
MetaType.Rsp => m.Apply( ( CmpFile )file.Data ),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
return true;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not obtain default file for manipulation {m.CorrespondingFilename()}:\n{e}" );
|
||||
return false;
|
||||
PluginLog.Error( $"Could not clear temporary metafile directory \"{modDir.FullName}\":\n{e}" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearDirectory()
|
||||
=> ClearDirectory( _dir );
|
||||
|
||||
public MetaManager( string name, Dictionary< GamePath, FullPath > resolvedFiles, DirectoryInfo tempDir )
|
||||
{
|
||||
_resolvedFiles = resolvedFiles;
|
||||
_dir = new DirectoryInfo( Path.Combine( tempDir.FullName, name.ReplaceBadXivSymbols() ) );
|
||||
ClearDirectory();
|
||||
}
|
||||
|
||||
public void WriteNewFiles()
|
||||
{
|
||||
if( _currentFiles.Any() )
|
||||
{
|
||||
Directory.CreateDirectory( _dir.FullName );
|
||||
}
|
||||
|
||||
foreach( var kvp in _currentFiles.Where( kvp => kvp.Value.Changed ) )
|
||||
{
|
||||
kvp.Value.Write( _dir, kvp.Key );
|
||||
_resolvedFiles[ kvp.Key ] = kvp.Value.CurrentFile!.Value;
|
||||
if( kvp.Value.Data is EqpFile )
|
||||
{
|
||||
EqpData = kvp.Value.ByteData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ApplyMod( MetaManipulation m, Mod.Mod mod )
|
||||
{
|
||||
if( _currentManipulations.ContainsKey( m ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_currentManipulations.Add( m, mod );
|
||||
var gamePath = m.CorrespondingFilename();
|
||||
try
|
||||
{
|
||||
if( !_currentFiles.TryGetValue( gamePath, out var file ) )
|
||||
{
|
||||
file = new FileInformation( Penumbra.MetaDefaults.CreateNewFile( m ) ?? throw new IOException() )
|
||||
{
|
||||
Changed = true,
|
||||
CurrentFile = null,
|
||||
};
|
||||
_currentFiles[ gamePath ] = file;
|
||||
}
|
||||
|
||||
file.Changed |= m.Type switch
|
||||
{
|
||||
MetaType.Eqp => m.Apply( ( EqpFile )file.Data ),
|
||||
MetaType.Eqdp => m.Apply( ( EqdpFile )file.Data ),
|
||||
MetaType.Gmp => m.Apply( ( GmpFile )file.Data ),
|
||||
MetaType.Est => m.Apply( ( EstFile )file.Data ),
|
||||
MetaType.Imc => m.Apply( ( ImcFile )file.Data ),
|
||||
MetaType.Rsp => m.Apply( ( CmpFile )file.Data ),
|
||||
_ => throw new NotImplementedException(),
|
||||
};
|
||||
return true;
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
PluginLog.Error( $"Could not obtain default file for manipulation {m.CorrespondingFilename()}:\n{e}" );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue