mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-14 20:54:16 +01:00
Change moddata to list.
This commit is contained in:
parent
2cece9c422
commit
4a4d93baf3
4 changed files with 96 additions and 93 deletions
|
|
@ -7,10 +7,8 @@ using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using Penumbra.GameData.ByteString;
|
using Penumbra.GameData.ByteString;
|
||||||
using Penumbra.GameData.Util;
|
|
||||||
using Penumbra.Importer;
|
using Penumbra.Importer;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Util;
|
|
||||||
|
|
||||||
namespace Penumbra.Mod;
|
namespace Penumbra.Mod;
|
||||||
|
|
||||||
|
|
@ -62,8 +60,8 @@ public class ModCleanup
|
||||||
|
|
||||||
private static ModData CreateNewMod( DirectoryInfo newDir, string newSortOrder )
|
private static ModData CreateNewMod( DirectoryInfo newDir, string newSortOrder )
|
||||||
{
|
{
|
||||||
Penumbra.ModManager.AddMod( newDir );
|
var idx = Penumbra.ModManager.AddMod( newDir );
|
||||||
var newMod = Penumbra.ModManager.Mods[ newDir.Name ];
|
var newMod = Penumbra.ModManager.Mods[idx];
|
||||||
newMod.Move( newSortOrder );
|
newMod.Move( newSortOrder );
|
||||||
newMod.ComputeChangedItems();
|
newMod.ComputeChangedItems();
|
||||||
ModFileSystem.InvokeChange();
|
ModFileSystem.InvokeChange();
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,36 @@ using Dalamud.Logging;
|
||||||
using Penumbra.GameData.ByteString;
|
using Penumbra.GameData.ByteString;
|
||||||
using Penumbra.Meta;
|
using Penumbra.Meta;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mods;
|
namespace Penumbra.Mods;
|
||||||
|
|
||||||
|
public enum ModChangeType
|
||||||
|
{
|
||||||
|
Added,
|
||||||
|
Removed,
|
||||||
|
Changed,
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void ModChangeDelegate( ModChangeType type, int modIndex, ModData modData );
|
||||||
|
|
||||||
// The ModManager handles the basic mods installed to the mod directory.
|
// The ModManager handles the basic mods installed to the mod directory.
|
||||||
// It also contains the CollectionManager that handles all collections.
|
// It also contains the CollectionManager that handles all collections.
|
||||||
public class ModManager
|
public class ModManager
|
||||||
{
|
{
|
||||||
public DirectoryInfo BasePath { get; private set; } = null!;
|
public DirectoryInfo BasePath { get; private set; } = null!;
|
||||||
|
|
||||||
public Dictionary< string, ModData > Mods { get; } = new();
|
private List< ModData > ModsInternal { get; init; } = new();
|
||||||
|
|
||||||
|
public IReadOnlyList< ModData > Mods
|
||||||
|
=> ModsInternal;
|
||||||
|
|
||||||
public ModFolder StructuredMods { get; } = ModFileSystem.Root;
|
public ModFolder StructuredMods { get; } = ModFileSystem.Root;
|
||||||
|
|
||||||
public CollectionManager Collections { get; }
|
public CollectionManager Collections { get; }
|
||||||
|
|
||||||
|
public event ModChangeDelegate? ModChange;
|
||||||
|
|
||||||
public bool Valid { get; private set; }
|
public bool Valid { get; private set; }
|
||||||
|
|
||||||
public Configuration Config
|
public Configuration Config
|
||||||
|
|
@ -38,7 +54,7 @@ public class ModManager
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !newPath.Any() )
|
if( newPath.Length == 0 )
|
||||||
{
|
{
|
||||||
Valid = false;
|
Valid = false;
|
||||||
BasePath = new DirectoryInfo( "." );
|
BasePath = new DirectoryInfo( "." );
|
||||||
|
|
@ -84,7 +100,7 @@ public class ModManager
|
||||||
{
|
{
|
||||||
mod.Move( path );
|
mod.Move( path );
|
||||||
var fixedPath = mod.SortOrder.FullPath;
|
var fixedPath = mod.SortOrder.FullPath;
|
||||||
if( !fixedPath.Any() || string.Equals( fixedPath, mod.Meta.Name, StringComparison.InvariantCultureIgnoreCase ) )
|
if( fixedPath.Length == 0 || string.Equals( fixedPath, mod.Meta.Name, StringComparison.InvariantCultureIgnoreCase ) )
|
||||||
{
|
{
|
||||||
Config.ModSortOrder.Remove( mod.BasePath.Name );
|
Config.ModSortOrder.Remove( mod.BasePath.Name );
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -103,16 +119,16 @@ public class ModManager
|
||||||
{
|
{
|
||||||
var changes = false;
|
var changes = false;
|
||||||
|
|
||||||
foreach( var kvp in Config.ModSortOrder.ToArray() )
|
foreach( var (folder, path) in Config.ModSortOrder.ToArray() )
|
||||||
{
|
{
|
||||||
if( kvp.Value.Any() && Mods.TryGetValue( kvp.Key, out var mod ) )
|
if( path.Length > 0 && ModsInternal.FindFirst( m => m.BasePath.Name == folder, out var mod ) )
|
||||||
{
|
{
|
||||||
changes |= SetSortOrderPath( mod, kvp.Value );
|
changes |= SetSortOrderPath( mod, path );
|
||||||
}
|
}
|
||||||
else if( removeOldPaths )
|
else if( removeOldPaths )
|
||||||
{
|
{
|
||||||
changes = true;
|
changes = true;
|
||||||
Config.ModSortOrder.Remove( kvp.Key );
|
Config.ModSortOrder.Remove( folder );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,7 +140,7 @@ public class ModManager
|
||||||
|
|
||||||
public void DiscoverMods()
|
public void DiscoverMods()
|
||||||
{
|
{
|
||||||
Mods.Clear();
|
ModsInternal.Clear();
|
||||||
BasePath.Refresh();
|
BasePath.Refresh();
|
||||||
|
|
||||||
StructuredMods.SubFolders.Clear();
|
StructuredMods.SubFolders.Clear();
|
||||||
|
|
@ -139,7 +155,7 @@ public class ModManager
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mods.Add( modFolder.Name, mod );
|
ModsInternal.Add( mod );
|
||||||
}
|
}
|
||||||
|
|
||||||
SetModStructure();
|
SetModStructure();
|
||||||
|
|
@ -151,8 +167,7 @@ public class ModManager
|
||||||
|
|
||||||
public void DeleteMod( DirectoryInfo modFolder )
|
public void DeleteMod( DirectoryInfo modFolder )
|
||||||
{
|
{
|
||||||
modFolder.Refresh();
|
if( Directory.Exists( modFolder.FullName ) )
|
||||||
if( modFolder.Exists )
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -162,22 +177,25 @@ public class ModManager
|
||||||
{
|
{
|
||||||
PluginLog.Error( $"Could not delete the mod {modFolder.Name}:\n{e}" );
|
PluginLog.Error( $"Could not delete the mod {modFolder.Name}:\n{e}" );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( Mods.TryGetValue( modFolder.Name, out var mod ) )
|
var idx = ModsInternal.FindIndex( m => m.BasePath.Name == modFolder.Name );
|
||||||
{
|
if( idx >= 0 )
|
||||||
mod.SortOrder.ParentFolder.RemoveMod( mod );
|
{
|
||||||
Mods.Remove( modFolder.Name );
|
var mod = ModsInternal[ idx ];
|
||||||
Collections.RemoveModFromCaches( modFolder );
|
mod.SortOrder.ParentFolder.RemoveMod( mod );
|
||||||
}
|
ModsInternal.RemoveAt( idx );
|
||||||
|
Collections.RemoveModFromCaches( modFolder );
|
||||||
|
ModChange?.Invoke( ModChangeType.Removed, idx, mod );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AddMod( DirectoryInfo modFolder )
|
public int AddMod( DirectoryInfo modFolder )
|
||||||
{
|
{
|
||||||
var mod = ModData.LoadMod( StructuredMods, modFolder );
|
var mod = ModData.LoadMod( StructuredMods, modFolder );
|
||||||
if( mod == null )
|
if( mod == null )
|
||||||
{
|
{
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Config.ModSortOrder.TryGetValue( mod.BasePath.Name, out var sortOrder ) )
|
if( Config.ModSortOrder.TryGetValue( mod.BasePath.Name, out var sortOrder ) )
|
||||||
|
|
@ -188,22 +206,24 @@ public class ModManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Mods.ContainsKey( modFolder.Name ) )
|
if( ModsInternal.Any( m => m.BasePath.Name == modFolder.Name ) )
|
||||||
{
|
{
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mods.Add( modFolder.Name, mod );
|
ModsInternal.Add( mod );
|
||||||
|
ModChange?.Invoke( ModChangeType.Added, ModsInternal.Count - 1, mod );
|
||||||
foreach( var collection in Collections.Collections.Values )
|
foreach( var collection in Collections.Collections.Values )
|
||||||
{
|
{
|
||||||
collection.AddMod( mod );
|
collection.AddMod( mod );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ModsInternal.Count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool UpdateMod( ModData mod, bool reloadMeta = false, bool recomputeMeta = false, bool force = false )
|
public bool UpdateMod( int idx, bool reloadMeta = false, bool recomputeMeta = false, bool force = false )
|
||||||
{
|
{
|
||||||
|
var mod = Mods[ idx ];
|
||||||
var oldName = mod.Meta.Name;
|
var oldName = mod.Meta.Name;
|
||||||
var metaChanges = mod.Meta.RefreshFromFile( mod.MetaFile ) || force;
|
var metaChanges = mod.Meta.RefreshFromFile( mod.MetaFile ) || force;
|
||||||
var fileChanges = mod.Resources.RefreshModFiles( mod.BasePath );
|
var fileChanges = mod.Resources.RefreshModFiles( mod.BasePath );
|
||||||
|
|
@ -242,60 +262,17 @@ public class ModManager
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.UpdateCollections( mod, metaChanges, fileChanges, nameChange, reloadMeta );
|
Collections.UpdateCollections( mod, metaChanges, fileChanges, nameChange, reloadMeta );
|
||||||
|
ModChange?.Invoke( ModChangeType.Changed, idx, mod );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool UpdateMod( ModData mod, bool reloadMeta = false, bool recomputeMeta = false, bool force = false )
|
||||||
|
=> UpdateMod( Mods.IndexOf( mod ), reloadMeta, recomputeMeta, force );
|
||||||
|
|
||||||
public FullPath? ResolveSwappedOrReplacementPath( Utf8GamePath gameResourcePath )
|
public FullPath? ResolveSwappedOrReplacementPath( Utf8GamePath gameResourcePath )
|
||||||
{
|
{
|
||||||
var ret = Collections.DefaultCollection.ResolveSwappedOrReplacementPath( gameResourcePath );
|
var ret = Collections.DefaultCollection.ResolveSwappedOrReplacementPath( gameResourcePath );
|
||||||
ret ??= Collections.ForcedCollection.ResolveSwappedOrReplacementPath( gameResourcePath );
|
ret ??= Collections.ForcedCollection.ResolveSwappedOrReplacementPath( gameResourcePath );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private void FileSystemWatcherOnChanged( object sender, FileSystemEventArgs e )
|
|
||||||
// {
|
|
||||||
// #if DEBUG
|
|
||||||
// PluginLog.Verbose( "file changed: {FullPath}", e.FullPath );
|
|
||||||
// #endif
|
|
||||||
//
|
|
||||||
// if( _plugin.ImportInProgress )
|
|
||||||
// {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if( _plugin.Configuration.DisableFileSystemNotifications )
|
|
||||||
// {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// var file = e.FullPath;
|
|
||||||
//
|
|
||||||
// if( !ResolvedFiles.Any( x => x.Value.FullName == file ) )
|
|
||||||
// {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// PluginLog.Log( "a loaded file has been modified - file: {FullPath}", file );
|
|
||||||
// _plugin.GameUtils.ReloadPlayerResources();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// private void FileSystemPasta()
|
|
||||||
// {
|
|
||||||
// haha spaghet
|
|
||||||
// _fileSystemWatcher?.Dispose();
|
|
||||||
// _fileSystemWatcher = new FileSystemWatcher( _basePath.FullName )
|
|
||||||
// {
|
|
||||||
// NotifyFilter = NotifyFilters.LastWrite |
|
|
||||||
// NotifyFilters.FileName |
|
|
||||||
// NotifyFilters.DirectoryName,
|
|
||||||
// IncludeSubdirectories = true,
|
|
||||||
// EnableRaisingEvents = true
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// _fileSystemWatcher.Changed += FileSystemWatcherOnChanged;
|
|
||||||
// _fileSystemWatcher.Created += FileSystemWatcherOnChanged;
|
|
||||||
// _fileSystemWatcher.Deleted += FileSystemWatcherOnChanged;
|
|
||||||
// _fileSystemWatcher.Renamed += FileSystemWatcherOnChanged;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
@ -70,9 +70,6 @@ public static class ModManagerEditExtensions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.Mods.Remove( mod.BasePath.Name );
|
|
||||||
manager.Mods[ newDir.Name ] = mod;
|
|
||||||
|
|
||||||
var oldBasePath = mod.BasePath;
|
var oldBasePath = mod.BasePath;
|
||||||
mod.BasePath = newDir;
|
mod.BasePath = newDir;
|
||||||
mod.MetaFile = ModData.MetaFileInfo( newDir );
|
mod.MetaFile = ModData.MetaFileInfo( newDir );
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,16 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
namespace Penumbra.Util;
|
namespace Penumbra.Util;
|
||||||
|
|
||||||
public static class ArrayExtensions
|
public static class ArrayExtensions
|
||||||
{
|
{
|
||||||
public static int IndexOf< T >( this T[] array, Predicate< T > match )
|
public static int IndexOf< T >( this IReadOnlyList< T > array, Predicate< T > predicate )
|
||||||
{
|
|
||||||
for( var i = 0; i < array.Length; ++i )
|
|
||||||
{
|
|
||||||
if( match( array[ i ] ) )
|
|
||||||
{
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int IndexOf< T >( this IList< T > array, Func< T, bool > predicate )
|
|
||||||
{
|
{
|
||||||
for( var i = 0; i < array.Count; ++i )
|
for( var i = 0; i < array.Count; ++i )
|
||||||
{
|
{
|
||||||
if( predicate.Invoke( array[ i ] ) )
|
if( predicate( array[ i ] ) )
|
||||||
{
|
{
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
@ -30,4 +18,47 @@ public static class ArrayExtensions
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int IndexOf< T >( this IReadOnlyList< T > array, T needle )
|
||||||
|
{
|
||||||
|
for( var i = 0; i < array.Count; ++i )
|
||||||
|
{
|
||||||
|
if( needle!.Equals( array[i] ) )
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FindFirst< T >( this IReadOnlyList< T > array, Predicate< T > predicate, [NotNullWhen( true )] out T? result )
|
||||||
|
{
|
||||||
|
foreach( var obj in array )
|
||||||
|
{
|
||||||
|
if( predicate( obj ) )
|
||||||
|
{
|
||||||
|
result = obj!;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool FindFirst< T >( this IReadOnlyList< T > array, T needle, [NotNullWhen( true )] out T? result ) where T : IEquatable< T >
|
||||||
|
{
|
||||||
|
foreach( var obj in array )
|
||||||
|
{
|
||||||
|
if( obj.Equals( needle ) )
|
||||||
|
{
|
||||||
|
result = obj!;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result = default;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue