mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +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 Dalamud.Logging;
|
||||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.GameData.Util;
|
||||
using Penumbra.Importer;
|
||||
using Penumbra.Mods;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra.Mod;
|
||||
|
||||
|
|
@ -62,8 +60,8 @@ public class ModCleanup
|
|||
|
||||
private static ModData CreateNewMod( DirectoryInfo newDir, string newSortOrder )
|
||||
{
|
||||
Penumbra.ModManager.AddMod( newDir );
|
||||
var newMod = Penumbra.ModManager.Mods[ newDir.Name ];
|
||||
var idx = Penumbra.ModManager.AddMod( newDir );
|
||||
var newMod = Penumbra.ModManager.Mods[idx];
|
||||
newMod.Move( newSortOrder );
|
||||
newMod.ComputeChangedItems();
|
||||
ModFileSystem.InvokeChange();
|
||||
|
|
|
|||
|
|
@ -6,20 +6,36 @@ using Dalamud.Logging;
|
|||
using Penumbra.GameData.ByteString;
|
||||
using Penumbra.Meta;
|
||||
using Penumbra.Mod;
|
||||
using Penumbra.Util;
|
||||
|
||||
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.
|
||||
// It also contains the CollectionManager that handles all collections.
|
||||
public class ModManager
|
||||
{
|
||||
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 CollectionManager Collections { get; }
|
||||
|
||||
public event ModChangeDelegate? ModChange;
|
||||
|
||||
public bool Valid { get; private set; }
|
||||
|
||||
public Configuration Config
|
||||
|
|
@ -38,7 +54,7 @@ public class ModManager
|
|||
return;
|
||||
}
|
||||
|
||||
if( !newPath.Any() )
|
||||
if( newPath.Length == 0 )
|
||||
{
|
||||
Valid = false;
|
||||
BasePath = new DirectoryInfo( "." );
|
||||
|
|
@ -84,7 +100,7 @@ public class ModManager
|
|||
{
|
||||
mod.Move( path );
|
||||
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 );
|
||||
return true;
|
||||
|
|
@ -103,16 +119,16 @@ public class ModManager
|
|||
{
|
||||
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 )
|
||||
{
|
||||
changes = true;
|
||||
Config.ModSortOrder.Remove( kvp.Key );
|
||||
Config.ModSortOrder.Remove( folder );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,7 +140,7 @@ public class ModManager
|
|||
|
||||
public void DiscoverMods()
|
||||
{
|
||||
Mods.Clear();
|
||||
ModsInternal.Clear();
|
||||
BasePath.Refresh();
|
||||
|
||||
StructuredMods.SubFolders.Clear();
|
||||
|
|
@ -139,7 +155,7 @@ public class ModManager
|
|||
continue;
|
||||
}
|
||||
|
||||
Mods.Add( modFolder.Name, mod );
|
||||
ModsInternal.Add( mod );
|
||||
}
|
||||
|
||||
SetModStructure();
|
||||
|
|
@ -151,8 +167,7 @@ public class ModManager
|
|||
|
||||
public void DeleteMod( DirectoryInfo modFolder )
|
||||
{
|
||||
modFolder.Refresh();
|
||||
if( modFolder.Exists )
|
||||
if( Directory.Exists( modFolder.FullName ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -162,22 +177,25 @@ public class ModManager
|
|||
{
|
||||
PluginLog.Error( $"Could not delete the mod {modFolder.Name}:\n{e}" );
|
||||
}
|
||||
}
|
||||
|
||||
if( Mods.TryGetValue( modFolder.Name, out var mod ) )
|
||||
{
|
||||
mod.SortOrder.ParentFolder.RemoveMod( mod );
|
||||
Mods.Remove( modFolder.Name );
|
||||
Collections.RemoveModFromCaches( modFolder );
|
||||
}
|
||||
var idx = ModsInternal.FindIndex( m => m.BasePath.Name == modFolder.Name );
|
||||
if( idx >= 0 )
|
||||
{
|
||||
var mod = ModsInternal[ idx ];
|
||||
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 );
|
||||
if( mod == null )
|
||||
{
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
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 metaChanges = mod.Meta.RefreshFromFile( mod.MetaFile ) || force;
|
||||
var fileChanges = mod.Resources.RefreshModFiles( mod.BasePath );
|
||||
|
|
@ -242,60 +262,17 @@ public class ModManager
|
|||
}
|
||||
|
||||
Collections.UpdateCollections( mod, metaChanges, fileChanges, nameChange, reloadMeta );
|
||||
|
||||
ModChange?.Invoke( ModChangeType.Changed, idx, mod );
|
||||
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 )
|
||||
{
|
||||
var ret = Collections.DefaultCollection.ResolveSwappedOrReplacementPath( gameResourcePath );
|
||||
ret ??= Collections.ForcedCollection.ResolveSwappedOrReplacementPath( gameResourcePath );
|
||||
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;
|
||||
mod.BasePath = newDir;
|
||||
mod.MetaFile = ModData.MetaFileInfo( newDir );
|
||||
|
|
|
|||
|
|
@ -1,28 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Penumbra.Util;
|
||||
|
||||
public static class ArrayExtensions
|
||||
{
|
||||
public static int IndexOf< T >( this T[] array, Predicate< T > match )
|
||||
{
|
||||
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 )
|
||||
public static int IndexOf< T >( this IReadOnlyList< T > array, Predicate< T > predicate )
|
||||
{
|
||||
for( var i = 0; i < array.Count; ++i )
|
||||
{
|
||||
if( predicate.Invoke( array[ i ] ) )
|
||||
if( predicate( array[ i ] ) )
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
|
@ -30,4 +18,47 @@ public static class ArrayExtensions
|
|||
|
||||
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