From a4ae44f3105271c7dda321baf7e773ed23efeafe Mon Sep 17 00:00:00 2001 From: Ottermandias Date: Sun, 25 Jul 2021 01:05:01 +0200 Subject: [PATCH] Split GamePath and RelPath file, made GamePath independent of RelPath. --- Penumbra.GameData/Util/GamePath.cs | 105 ++++++++++++++++++ Penumbra/Mod/ModCleanup.cs | 6 +- Penumbra/Mod/ModFunctions.cs | 2 +- .../TabInstalled/TabInstalledDetails.cs | 4 +- .../Util/{PenumbraPath.cs => GamePath.cs} | 74 ------------ Penumbra/Util/RelPath.cs | 80 +++++++++++++ 6 files changed, 191 insertions(+), 80 deletions(-) create mode 100644 Penumbra.GameData/Util/GamePath.cs rename Penumbra/Util/{PenumbraPath.cs => GamePath.cs} (59%) create mode 100644 Penumbra/Util/RelPath.cs diff --git a/Penumbra.GameData/Util/GamePath.cs b/Penumbra.GameData/Util/GamePath.cs new file mode 100644 index 00000000..598dafe5 --- /dev/null +++ b/Penumbra.GameData/Util/GamePath.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace Penumbra.GameData.Util +{ + public readonly struct GamePath : IComparable + { + public const int MaxGamePathLength = 256; + + private readonly string _path; + + private GamePath( string path, bool _ ) + => _path = path; + + public GamePath( string? path ) + { + if( path != null && path.Length < MaxGamePathLength ) + { + _path = Lower( Trim( ReplaceSlash( path ) ) ); + } + else + { + _path = ""; + } + } + + public GamePath( FileInfo file, DirectoryInfo baseDir ) + => _path = CheckPre( file, baseDir ) ? Lower( Trim( ReplaceSlash( Substring( file, baseDir ) ) ) ) : ""; + + private static bool CheckPre( FileInfo file, DirectoryInfo baseDir ) + => file.FullName.StartsWith( baseDir.FullName ) && file.FullName.Length < MaxGamePathLength; + + private static string Substring( FileInfo file, DirectoryInfo baseDir ) + => file.FullName.Substring( baseDir.FullName.Length ); + + private static string ReplaceSlash( string path ) + => path.Replace( '\\', '/' ); + + private static string Trim( string path ) + => path.TrimStart( '/' ); + + private static string Lower( string path ) + => path.ToLowerInvariant(); + + public static GamePath GenerateUnchecked( string path ) + => new( path, true ); + + public static GamePath GenerateUncheckedLower( string path ) + => new( Lower( path ), true ); + + public static implicit operator string( GamePath gamePath ) + => gamePath._path; + + public static explicit operator GamePath( string gamePath ) + => new( gamePath ); + + public bool Empty + => _path.Length == 0; + + 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 ) + { + return rhs switch + { + string path => string.Compare( _path, path, StringComparison.InvariantCulture ), + GamePath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ), + _ => -1, + }; + } + + public override string ToString() + => _path; + } + + public class GamePathConverter : JsonConverter + { + public override bool CanConvert( Type objectType ) + => objectType == typeof( GamePath ); + + public override object ReadJson( JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer ) + { + var token = JToken.Load( reader ); + return token.ToObject< GamePath >(); + } + + public override bool CanWrite + => true; + + public override void WriteJson( JsonWriter writer, object? value, JsonSerializer serializer ) + { + if( value != null ) + { + var v = ( GamePath )value; + serializer.Serialize( writer, v.ToString() ); + } + } + } +} \ No newline at end of file diff --git a/Penumbra/Mod/ModCleanup.cs b/Penumbra/Mod/ModCleanup.cs index 3be18f13..02b80546 100644 --- a/Penumbra/Mod/ModCleanup.cs +++ b/Penumbra/Mod/ModCleanup.cs @@ -160,12 +160,12 @@ namespace Penumbra.Mod var duplicates = FindOrCreateDuplicates( _mod ); if( !inOption1 ) { - duplicates.AddFile( relName1, new GamePath( relName2, 0 ) ); + duplicates.AddFile( relName2, relName2.ToGamePath() ); } if( !inOption2 ) { - duplicates.AddFile( relName1, new GamePath( relName1, 0 ) ); + duplicates.AddFile( relName1, relName1.ToGamePath() ); } } @@ -227,7 +227,7 @@ namespace Penumbra.Mod continue; } - if( kvp.Value.Count == 0 || kvp.Value.First().CompareTo( new GamePath( kvp.Key, 0 ) ) == 0 ) + if( kvp.Value.Count == 0 || kvp.Value.First().CompareTo( kvp.Key.ToGamePath() ) == 0 ) { required.OptionFiles.Remove( kvp.Key ); } diff --git a/Penumbra/Mod/ModFunctions.cs b/Penumbra/Mod/ModFunctions.cs index 675f1dfc..3cedcd06 100644 --- a/Penumbra/Mod/ModFunctions.cs +++ b/Penumbra/Mod/ModFunctions.cs @@ -52,7 +52,7 @@ namespace Penumbra.Mod if( ret.Count == 0 ) { - ret.Add( new GamePath( relPath, 0 ) ); + ret.Add( relPath.ToGamePath( ) ); } return ret; diff --git a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs index 1da5be02..cb83ff1a 100644 --- a/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs +++ b/Penumbra/UI/MenuTabs/TabInstalled/TabInstalledDetails.cs @@ -206,7 +206,7 @@ namespace Penumbra.UI { ChatUtil.LinkItem( it ); } - + if( ImGui.IsItemHovered() ) { ImGui.SetTooltip( "Left click to create link in chat." ); @@ -425,7 +425,7 @@ namespace Penumbra.UI var relName = _fullFilenameList[ i ].relName; if( defaultIndex >= 0 ) { - gamePaths[ defaultIndex ] = new GamePath( relName, removeFolders ); + gamePaths[ defaultIndex ] = relName.ToGamePath( removeFolders ); } if( remove && option.OptionFiles.TryGetValue( relName, out var setPaths ) ) diff --git a/Penumbra/Util/PenumbraPath.cs b/Penumbra/Util/GamePath.cs similarity index 59% rename from Penumbra/Util/PenumbraPath.cs rename to Penumbra/Util/GamePath.cs index 72f66119..fdf57183 100644 --- a/Penumbra/Util/PenumbraPath.cs +++ b/Penumbra/Util/GamePath.cs @@ -1,73 +1,10 @@ using System; using System.IO; -using System.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Penumbra.Util { - public readonly struct RelPath : IComparable - { - public const int MaxRelPathLength = 256; - - private readonly string _path; - - private RelPath( string path, bool _ ) - => _path = path; - - private RelPath( string? path ) - { - if( path != null && path.Length < MaxRelPathLength ) - { - _path = Trim( ReplaceSlash( path ) ); - } - else - { - _path = ""; - } - } - - public RelPath( FileInfo file, DirectoryInfo baseDir ) - => _path = CheckPre( file, baseDir ) ? Trim( Substring( file, baseDir ) ) : ""; - - public RelPath( GamePath gamePath ) - => _path = ReplaceSlash( gamePath ); - - private static bool CheckPre( FileInfo file, DirectoryInfo baseDir ) - => file.FullName.StartsWith( baseDir.FullName ) && file.FullName.Length < MaxRelPathLength; - - private static string Substring( FileInfo file, DirectoryInfo baseDir ) - => file.FullName.Substring( baseDir.FullName.Length ); - - private static string ReplaceSlash( string path ) - => path.Replace( '/', '\\' ); - - private static string Trim( string path ) - => path.TrimStart( '\\' ); - - public static implicit operator string( RelPath relPath ) - => relPath._path; - - public static explicit operator RelPath( string relPath ) - => new( relPath ); - - public bool Empty - => _path.Length == 0; - - public int CompareTo( object rhs ) - { - return rhs switch - { - string path => string.Compare( _path, path, StringComparison.InvariantCulture ), - RelPath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ), - _ => -1, - }; - } - - public override string ToString() - => _path; - } - public readonly struct GamePath : IComparable { public const int MaxGamePathLength = 256; @@ -92,17 +29,6 @@ namespace Penumbra.Util public GamePath( FileInfo file, DirectoryInfo baseDir ) => _path = CheckPre( file, baseDir ) ? Lower( Trim( ReplaceSlash( Substring( file, baseDir ) ) ) ) : ""; - 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; diff --git a/Penumbra/Util/RelPath.cs b/Penumbra/Util/RelPath.cs new file mode 100644 index 00000000..e0913aae --- /dev/null +++ b/Penumbra/Util/RelPath.cs @@ -0,0 +1,80 @@ +using System; +using System.IO; +using System.Linq; + +namespace Penumbra.Util +{ + public readonly struct RelPath : IComparable + { + public const int MaxRelPathLength = 256; + + private readonly string _path; + + private RelPath( string path, bool _ ) + => _path = path; + + private RelPath( string? path ) + { + if( path != null && path.Length < MaxRelPathLength ) + { + _path = Trim( ReplaceSlash( path ) ); + } + else + { + _path = ""; + } + } + + public RelPath( FileInfo file, DirectoryInfo baseDir ) + => _path = CheckPre( file, baseDir ) ? Trim( Substring( file, baseDir ) ) : ""; + + public RelPath( GamePath gamePath ) + => _path = ReplaceSlash( gamePath ); + + public GamePath ToGamePath( int skipFolders = 0 ) + { + string p = this; + if( skipFolders > 0 ) + { + p = string.Join( "/", p.Split( '\\' ).Skip( skipFolders ) ); + return GamePath.GenerateUncheckedLower( p ); + } + + return GamePath.GenerateUncheckedLower( p.Replace( '\\', '/' ) ); + } + + private static bool CheckPre( FileInfo file, DirectoryInfo baseDir ) + => file.FullName.StartsWith( baseDir.FullName ) && file.FullName.Length < MaxRelPathLength; + + private static string Substring( FileInfo file, DirectoryInfo baseDir ) + => file.FullName.Substring( baseDir.FullName.Length ); + + private static string ReplaceSlash( string path ) + => path.Replace( '/', '\\' ); + + private static string Trim( string path ) + => path.TrimStart( '\\' ); + + public static implicit operator string( RelPath relPath ) + => relPath._path; + + public static explicit operator RelPath( string relPath ) + => new( relPath ); + + public bool Empty + => _path.Length == 0; + + public int CompareTo( object rhs ) + { + return rhs switch + { + string path => string.Compare( _path, path, StringComparison.InvariantCulture ), + RelPath path => string.Compare( _path, path._path, StringComparison.InvariantCulture ), + _ => -1, + }; + } + + public override string ToString() + => _path; + } +} \ No newline at end of file