mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-31 21:03:48 +01:00
More sophisticated fix against E4S crashes with working mods in E4S.
This commit is contained in:
parent
a1f02975cb
commit
f601812666
13 changed files with 273 additions and 210 deletions
|
|
@ -3,86 +3,87 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Mod
|
||||
namespace Penumbra.Mod;
|
||||
|
||||
[Flags]
|
||||
public enum ResourceChange
|
||||
{
|
||||
[Flags]
|
||||
public enum ResourceChange
|
||||
None = 0,
|
||||
Files = 1,
|
||||
Meta = 2,
|
||||
}
|
||||
|
||||
// Contains static mod data that should only change on filesystem changes.
|
||||
public class ModResources
|
||||
{
|
||||
public List< FullPath > ModFiles { get; private set; } = new();
|
||||
public List< FullPath > MetaFiles { get; private set; } = new();
|
||||
|
||||
public MetaCollection MetaManipulations { get; private set; } = new();
|
||||
|
||||
|
||||
private void ForceManipulationsUpdate( ModMeta meta, DirectoryInfo basePath )
|
||||
{
|
||||
None = 0,
|
||||
Files = 1,
|
||||
Meta = 2,
|
||||
MetaManipulations.Update( MetaFiles, basePath, meta );
|
||||
MetaManipulations.SaveToFile( MetaCollection.FileName( basePath ) );
|
||||
}
|
||||
|
||||
// Contains static mod data that should only change on filesystem changes.
|
||||
public class ModResources
|
||||
public void SetManipulations( ModMeta meta, DirectoryInfo basePath, bool validate = true )
|
||||
{
|
||||
public List< FileInfo > ModFiles { get; private set; } = new();
|
||||
public List< FileInfo > MetaFiles { get; private set; } = new();
|
||||
|
||||
public MetaCollection MetaManipulations { get; private set; } = new();
|
||||
|
||||
|
||||
private void ForceManipulationsUpdate( ModMeta meta, DirectoryInfo basePath )
|
||||
var newManipulations = MetaCollection.LoadFromFile( MetaCollection.FileName( basePath ) );
|
||||
if( newManipulations == null )
|
||||
{
|
||||
MetaManipulations.Update( MetaFiles, basePath, meta );
|
||||
MetaManipulations.SaveToFile( MetaCollection.FileName( basePath ) );
|
||||
ForceManipulationsUpdate( meta, basePath );
|
||||
}
|
||||
|
||||
public void SetManipulations( ModMeta meta, DirectoryInfo basePath, bool validate = true )
|
||||
else
|
||||
{
|
||||
var newManipulations = MetaCollection.LoadFromFile( MetaCollection.FileName( basePath ) );
|
||||
if( newManipulations == null )
|
||||
MetaManipulations = newManipulations;
|
||||
if( validate && !MetaManipulations.Validate( meta ) )
|
||||
{
|
||||
ForceManipulationsUpdate( meta, basePath );
|
||||
}
|
||||
else
|
||||
{
|
||||
MetaManipulations = newManipulations;
|
||||
if( validate && !MetaManipulations.Validate( meta ) )
|
||||
{
|
||||
ForceManipulationsUpdate( meta, basePath );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current set of files used by the mod,
|
||||
// returns true if anything changed.
|
||||
public ResourceChange RefreshModFiles( DirectoryInfo basePath )
|
||||
{
|
||||
List< FileInfo > tmpFiles = new( ModFiles.Count );
|
||||
List< FileInfo > tmpMetas = new( MetaFiles.Count );
|
||||
// we don't care about any _files_ in the root dir, but any folders should be a game folder/file combo
|
||||
foreach( var file in basePath.EnumerateDirectories()
|
||||
.SelectMany( dir => dir.EnumerateFiles( "*.*", SearchOption.AllDirectories ) )
|
||||
.OrderBy( f => f.FullName ) )
|
||||
{
|
||||
switch( file.Extension.ToLowerInvariant() )
|
||||
{
|
||||
case ".meta":
|
||||
case ".rgsp":
|
||||
tmpMetas.Add( file );
|
||||
break;
|
||||
default:
|
||||
tmpFiles.Add( file );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ResourceChange changes = 0;
|
||||
if( !tmpFiles.Select( f => f.FullName ).SequenceEqual( ModFiles.Select( f => f.FullName ) ) )
|
||||
{
|
||||
ModFiles = tmpFiles;
|
||||
changes |= ResourceChange.Files;
|
||||
}
|
||||
|
||||
if( !tmpMetas.Select( f => f.FullName ).SequenceEqual( MetaFiles.Select( f => f.FullName ) ) )
|
||||
{
|
||||
MetaFiles = tmpMetas;
|
||||
changes |= ResourceChange.Meta;
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current set of files used by the mod,
|
||||
// returns true if anything changed.
|
||||
public ResourceChange RefreshModFiles( DirectoryInfo basePath )
|
||||
{
|
||||
List< FullPath > tmpFiles = new(ModFiles.Count);
|
||||
List< FullPath > tmpMetas = new(MetaFiles.Count);
|
||||
// we don't care about any _files_ in the root dir, but any folders should be a game folder/file combo
|
||||
foreach( var file in basePath.EnumerateDirectories()
|
||||
.SelectMany( dir => dir.EnumerateFiles( "*.*", SearchOption.AllDirectories ) )
|
||||
.Select( f => new FullPath( f ) )
|
||||
.OrderBy( f => f.FullName ) )
|
||||
{
|
||||
switch( file.Extension.ToLowerInvariant() )
|
||||
{
|
||||
case ".meta":
|
||||
case ".rgsp":
|
||||
tmpMetas.Add( file );
|
||||
break;
|
||||
default:
|
||||
tmpFiles.Add( file );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ResourceChange changes = 0;
|
||||
if( !tmpFiles.Select( f => f.FullName ).SequenceEqual( ModFiles.Select( f => f.FullName ) ) )
|
||||
{
|
||||
ModFiles = tmpFiles;
|
||||
changes |= ResourceChange.Files;
|
||||
}
|
||||
|
||||
if( !tmpMetas.Select( f => f.FullName ).SequenceEqual( MetaFiles.Select( f => f.FullName ) ) )
|
||||
{
|
||||
MetaFiles = tmpMetas;
|
||||
changes |= ResourceChange.Meta;
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue