From 00af098d6641d09e6eeb80e22006c4f8cab65464 Mon Sep 17 00:00:00 2001 From: Adam <893184+NotAdam@users.noreply.github.com> Date: Mon, 15 Feb 2021 21:43:41 +1100 Subject: [PATCH] cleanup some garbage, make loading less brittle --- Penumbra/Importer/TexToolsImport.cs | 14 +- Penumbra/Mods/ModCollection.cs | 5 + Penumbra/Mods/ModManager.cs | 217 +++++++++++++++------------- README.md | 6 +- 4 files changed, 129 insertions(+), 113 deletions(-) diff --git a/Penumbra/Importer/TexToolsImport.cs b/Penumbra/Importer/TexToolsImport.cs index ee6b1fec..7d587314 100644 --- a/Penumbra/Importer/TexToolsImport.cs +++ b/Penumbra/Importer/TexToolsImport.cs @@ -54,13 +54,13 @@ namespace Penumbra.Importer { case ".ttmp": ImportV1ModPack( modPackFile ); - return; + break; case ".ttmp2": ImportV2ModPack( modPackFile ); - return; - - default: + break; + + default: throw new ArgumentException( $"Unrecognized modpack format: {modPackFile.Extension}", nameof(modPackFile) ); } @@ -249,13 +249,13 @@ namespace Penumbra.Importer OptionFiles = new Dictionary>() }; var optDir = new DirectoryInfo(Path.Combine( groupFolder.FullName, opt.Name)); - if (optDir.Exists) + if (optDir.Exists) { foreach ( var file in optDir.EnumerateFiles("*.*", SearchOption.AllDirectories) ) { optio.AddFile(file.FullName.Substring(baseFolder.FullName.Length).TrimStart('\\'), file.FullName.Substring(optDir.FullName.Length).TrimStart('\\').Replace('\\','/')); - } - } + } + } Inf.Options.Add( optio ); } meta.Groups.Add( group.GroupName, Inf ); diff --git a/Penumbra/Mods/ModCollection.cs b/Penumbra/Mods/ModCollection.cs index 81d1ae77..b3af86da 100644 --- a/Penumbra/Mods/ModCollection.cs +++ b/Penumbra/Mods/ModCollection.cs @@ -65,6 +65,11 @@ namespace Penumbra.Mods } var meta = ModMeta.LoadFromFile( metaFile.FullName ); + if( meta == null ) + { + PluginLog.LogError( "mod meta is invalid for resource mod: {ResourceModFile}", metaFile.FullName ); + continue; + } var mod = new ResourceMod { diff --git a/Penumbra/Mods/ModManager.cs b/Penumbra/Mods/ModManager.cs index c1e4c354..17be24d8 100644 --- a/Penumbra/Mods/ModManager.cs +++ b/Penumbra/Mods/ModManager.cs @@ -99,9 +99,6 @@ namespace Penumbra.Mods Mods.Save(); CalculateEffectiveFileList(); - - // Needed to reload body textures with mods - //_plugin.GameUtils.ReloadPlayerResources(); } public void CalculateEffectiveFileList() @@ -114,115 +111,133 @@ namespace Penumbra.Mods foreach( var (mod, settings) in Mods.GetOrderedAndEnabledModListWithSettings( _plugin.Configuration.InvertModListOrder ) ) { mod.FileConflicts?.Clear(); - - // fixup path - var baseDir = mod.ModBasePath.FullName; - if( settings.Conf == null ) { settings.Conf = new(); _plugin.ModManager.Mods.Save(); } - foreach( var file in mod.ModFiles ) - { - var relativeFilePath = file.FullName.Substring( baseDir.Length ).TrimStart( '\\' ); - - bool doNotAdd = false; - - void AddFiles( HashSet< string > gamePaths ) - { - doNotAdd = true; - foreach( var gamePath in gamePaths ) - { - if( !ResolvedFiles.ContainsKey( gamePath ) ) - { - ResolvedFiles[ gamePath.ToLowerInvariant() ] = file; - registeredFiles[ gamePath ] = mod.Meta.Name; - } - else if( registeredFiles.TryGetValue( gamePath, out var modName ) ) - { - mod.AddConflict( modName, gamePath ); - } - } - } - - HashSet< string > paths; - foreach( var group in mod.Meta.Groups.Select( G => G.Value ) ) - { - if( !settings.Conf.TryGetValue( group.GroupName, out var setting ) - || ( group.SelectionType == SelectType.Single && settings.Conf[ group.GroupName ] >= group.Options.Count ) ) - { - settings.Conf[ group.GroupName ] = 0; - _plugin.ModManager.Mods.Save(); - setting = 0; - } - - if( group.Options.Count == 0 ) - continue; - - if( group.SelectionType == SelectType.Multi ) - settings.Conf[ group.GroupName ] &= ( ( 1 << group.Options.Count ) - 1 ); - - switch( group.SelectionType ) - { - case SelectType.Single: - if( group.Options[ setting ].OptionFiles.TryGetValue( relativeFilePath, out paths ) ) - AddFiles( paths ); - else - { - for( var i = 0; i < group.Options.Count; ++i ) - { - if( i == setting ) - continue; - if( group.Options[ i ].OptionFiles.ContainsKey( relativeFilePath ) ) - { - doNotAdd = true; - break; - } - } - } - - break; - case SelectType.Multi: - for( var i = 0; i < group.Options.Count; ++i ) - { - if( ( setting & ( 1 << i ) ) != 0 ) - { - if( group.Options[ i ].OptionFiles.TryGetValue( relativeFilePath, out paths ) ) - AddFiles( paths ); - } - else if( group.Options[ i ].OptionFiles.ContainsKey( relativeFilePath ) ) - doNotAdd = true; - } - - break; - } - } - - if( !doNotAdd ) - AddFiles( new() { relativeFilePath.Replace( '\\', '/' ) } ); - } - - - foreach( var swap in mod.Meta?.FileSwaps ) - { - // just assume people put not fucked paths in here lol - if( !SwappedFiles.ContainsKey( swap.Value ) ) - { - SwappedFiles[ swap.Key.ToLowerInvariant() ] = swap.Value; - registeredFiles[ swap.Key ] = mod.Meta.Name; - } - else if( registeredFiles.TryGetValue( swap.Key, out var modName ) ) - { - mod.AddConflict( modName, swap.Key ); - } - } + ProcessModFiles( registeredFiles, mod, settings ); + ProcessSwappedFiles( registeredFiles, mod, settings ); } _plugin.GameUtils.ReloadPlayerResources(); } + private void ProcessSwappedFiles( Dictionary< string, string > registeredFiles, ResourceMod mod, ModInfo settings ) + { + if( mod?.Meta?.FileSwaps == null ) + { + return; + } + + foreach( var swap in mod.Meta.FileSwaps ) + { + // just assume people put not fucked paths in here lol + if( !SwappedFiles.ContainsKey( swap.Value ) ) + { + SwappedFiles[ swap.Key.ToLowerInvariant() ] = swap.Value; + registeredFiles[ swap.Key ] = mod.Meta.Name; + } + else if( registeredFiles.TryGetValue( swap.Key, out var modName ) ) + { + mod.AddConflict( modName, swap.Key ); + } + } + } + + private void ProcessModFiles( Dictionary< string, string > registeredFiles, ResourceMod mod, ModInfo settings ) + { + var baseDir = mod.ModBasePath.FullName; + + foreach( var file in mod.ModFiles ) + { + var relativeFilePath = file.FullName.Substring( baseDir.Length ).TrimStart( '\\' ); + + bool doNotAdd = false; + + HashSet< string > paths; + foreach( var group in mod.Meta.Groups.Select( G => G.Value ) ) + { + if( !settings.Conf.TryGetValue( group.GroupName, out var setting ) + || ( group.SelectionType == SelectType.Single && settings.Conf[ group.GroupName ] >= group.Options.Count ) ) + { + settings.Conf[ group.GroupName ] = 0; + _plugin.ModManager.Mods.Save(); + setting = 0; + } + + if( group.Options.Count == 0 ) + continue; + + if( group.SelectionType == SelectType.Multi ) + settings.Conf[ group.GroupName ] &= ( ( 1 << group.Options.Count ) - 1 ); + + switch( group.SelectionType ) + { + case SelectType.Single: + if( group.Options[ setting ].OptionFiles.TryGetValue( relativeFilePath, out paths ) ) + { + AddFiles( paths, out doNotAdd, file, registeredFiles, mod ); + } + else + { + for( var i = 0; i < group.Options.Count; ++i ) + { + if( i == setting ) + continue; + if( group.Options[ i ].OptionFiles.ContainsKey( relativeFilePath ) ) + { + doNotAdd = true; + break; + } + } + } + + break; + case SelectType.Multi: + for( var i = 0; i < group.Options.Count; ++i ) + { + if( ( setting & ( 1 << i ) ) != 0 ) + { + if( group.Options[ i ].OptionFiles.TryGetValue( relativeFilePath, out paths ) ) + { + AddFiles( paths, out doNotAdd, file, registeredFiles, mod ); + } + } + else if( group.Options[ i ].OptionFiles.ContainsKey( relativeFilePath ) ) + doNotAdd = true; + } + + break; + } + } + + if( !doNotAdd ) + { + AddFiles( new() { relativeFilePath.Replace( '\\', '/' ) }, out doNotAdd, file, registeredFiles, mod ); + } + } + } + + private void AddFiles( HashSet< string > gamePaths, out bool doNotAdd, FileInfo file, Dictionary< string, string > registeredFiles, + ResourceMod mod ) + { + doNotAdd = true; + foreach( var gamePath in gamePaths ) + { + if( !ResolvedFiles.ContainsKey( gamePath ) ) + { + ResolvedFiles[ gamePath.ToLowerInvariant() ] = file; + registeredFiles[ gamePath ] = mod.Meta.Name; + } + else if( registeredFiles.TryGetValue( gamePath, out var modName ) ) + { + mod.AddConflict( modName, gamePath ); + } + } + } + public void ChangeModPriority( ModInfo info, bool up = false ) { Mods.ReorderMod( info, up ); diff --git a/README.md b/README.md index 9c406157..28045605 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,4 @@ We're working towards a 1.0 release, and you can follow it's progress [here](htt Contributions are welcome, but please make an issue first before writing any code. It's possible what you want to implement is out of scope for this project, or could be reworked so that it would provide greater benefit. ## TexTools Mods -Penumbra has support for some types of TexTools modpacks, however no support will be given. This is aimed as an interim measure while better tooling is developed, but note that there is no ETA for this. - -### Why not support TexTools? - -Because it sucks. It's slow to use, the workflow is awful and the codebase is so far gone any notable improvements or support for new features would mean throwing out significant portions of the existing codebase. +Penumbra has support for most TexTools modpacks however this is provided on a best-effort basis and support is not guaranteed. Built in tooling will be added to Penumbra over time to avoid many common TexTools use cases as