diff --git a/Penumbra/Mods/ModManager.cs b/Penumbra/Mods/ModManager.cs index 4890100f..1cd55bdb 100644 --- a/Penumbra/Mods/ModManager.cs +++ b/Penumbra/Mods/ModManager.cs @@ -190,7 +190,7 @@ namespace Penumbra.Mods => SwappedFiles.TryGetValue( gameResourcePath, out var swappedPath ) ? swappedPath : null; public string? ResolveSwappedOrReplacementFilePath( GamePath gameResourcePath ) - => GetCandidateForGameFile( gameResourcePath )?.FullName ?? GetSwappedFilePath( gameResourcePath ) ?? null; + => GetCandidateForGameFile( gameResourcePath )?.FullName.Replace( '\\', '/' ) ?? GetSwappedFilePath( gameResourcePath ) ?? null; public void Dispose() diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs index bc9341bb..18aec077 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs @@ -373,6 +373,30 @@ namespace Penumbra.UI ImGui.EndTabItem(); } + private int HandleDefaultString( GamePath[] gamePaths, out int removeFolders ) + { + removeFolders = 0; + var defaultIndex = gamePaths.IndexOf( p => ( ( string )p ).StartsWith( TextDefaultGamePath ) ); + if( defaultIndex < 0 ) + { + return defaultIndex; + } + + string path = gamePaths[ defaultIndex ]; + if( path.Length == TextDefaultGamePath.Length ) + { + return defaultIndex; + } + + if( path[ TextDefaultGamePath.Length ] != '-' + || !int.TryParse( path.Substring( TextDefaultGamePath.Length + 1 ), out removeFolders ) ) + { + return -1; + } + + return defaultIndex; + } + private void HandleSelectedFilesButton( bool remove ) { if( _selectedOption == null ) @@ -388,7 +412,7 @@ namespace Penumbra.UI return; } - var defaultIndex = gamePaths.IndexOf( p => p == TextDefaultGamePath ); + var defaultIndex = HandleDefaultString( gamePaths, out var removeFolders ); var changed = false; for( var i = 0; i < Mod.Mod.ModFiles.Count; ++i ) { @@ -400,7 +424,7 @@ namespace Penumbra.UI var relName = _fullFilenameList[ i ].relName; if( defaultIndex >= 0 ) { - gamePaths[ defaultIndex ] = new GamePath( relName ); + gamePaths[ defaultIndex ] = new GamePath( relName, removeFolders ); } if( remove && option.OptionFiles.TryGetValue( relName, out var setPaths ) ) diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsEdit.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsEdit.cs index 5cf73119..7be378d8 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsEdit.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetailsEdit.cs @@ -30,7 +30,8 @@ namespace Penumbra.UI private static readonly string TooltipGamePathsEdit = $"Enter all game paths to add or remove, separated by '{GamePathsSeparator}'.\n" + - $"Use '{TextDefaultGamePath}' to add the original file path."; + $"Use '{TextDefaultGamePath}' to add the original file path." + + $"Use '{TextDefaultGamePath}-#' to skip the first # relative directories."; private const float MultiEditBoxWidth = 300f; diff --git a/Penumbra/Util/PenumbraPath.cs b/Penumbra/Util/PenumbraPath.cs index a8e81cbc..55174bf6 100644 --- a/Penumbra/Util/PenumbraPath.cs +++ b/Penumbra/Util/PenumbraPath.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; namespace Penumbra.Util { @@ -89,8 +90,16 @@ namespace Penumbra.Util public GamePath( FileInfo file, DirectoryInfo baseDir ) => _path = CheckPre( file, baseDir ) ? Lower( Trim( ReplaceSlash( Substring( file, baseDir ) ) ) ) : ""; - public GamePath( RelPath relPath ) - => _path = relPath ? Lower( ReplaceSlash( relPath ) ) : ""; + public GamePath( RelPath relPath, int skipFolders ) + { + string p = relPath; + if( skipFolders > 0 ) + { + p = string.Join( "/", p.Split( '\\' ).Skip( skipFolders ) ); + } + + _path = Lower( ReplaceSlash( p ) ); + } private static bool CheckPre( FileInfo file, DirectoryInfo baseDir ) => file.FullName.StartsWith( baseDir.FullName ) && file.FullName.Length < MaxGamePathLength; @@ -122,6 +131,11 @@ namespace Penumbra.Util public static explicit operator GamePath( string gamePath ) => new( gamePath ); + public string Filename() + { + var idx = _path.LastIndexOf( "/", StringComparison.Ordinal ); + return idx == -1 ? _path : idx == _path.Length - 1 ? "" : _path.Substring( idx + 1 ); + } public int CompareTo( object rhs ) {