This PR creates the PathHelper and PathValidator classes which have all the necessary methods to read a case-insensitive path and somewhat determine a case-sensitive path based on it. Methods are available to find case-insensitive duplicates, find the closest case-sensitive match, and validate a directory/file path. There are discrepancies in some NET versions that are accounted for here to provide some better unified support across most Unix/windows platforms. We also have a method that will find a case-sensitive path on case-insensitive systems.
The problem:
KOTOR assumes a case-insensitive filesystem, but on case-sensitive filesystems there's the potential for files/directories to duplicate which KOTOR either randomly picks one or picks a specific duplicate that matches the file/directory exactly.
The solution:
This PR provides the following methods in the PathHelper and PathValidator classes:
List<FileSystemInfo> FindCaseInsensitiveDuplicates(DirectoryInfo directory): If you want to initially scan the KOTOR directory to find case-insensitive duplicates on case-sensitive systems, this method will return a List on all duplicates found (e.g. nwScripT.NSS and nwscript.nss found in the same directory).
string FixPathFormatting( string path ): fixes common problems in path strings (backslash vs forwardslash, multiple slashes, and trailing slashes are resolved)
(FileSystemInfo?, List<string>) GetClosestMatchingEntry( string path ): Takes the argument of a case-insensitive path to a file/directory on disk, and will find out if that file is duplicated on disk in the same folder. If it is, it will return a tuple containing the closest matching entry (the closest valid case-sensitive path to the file/directory if one is found), and all other case-sensitive files/directories that duplicate in a case insensitive environment. This method matches more or less what KOTOR does internally.
List<string> EnumerateFilesWithWildcards(IEnumerable<string> filesAndFolders, bool topLevelOnly = false): Will handle common wildcards such as * (anything here) and ? (any character here) in path strings. Takes a collection of path strings as an argument, and an optional bool for whether to recurse into subfolders.
string? GetCaseSensitivePath(string path): Takes a case-insensitive path and returns a case-sensitive path. Even works on Windows somewhat, but some refactoring must be done to have it work correctly everytime on windows as windows was never meant to support something like that.
bool IsValidPath( string path?): Some versions of NET will exception if the path string sent to the DirectoryInfo or FileInfo constructors are too malformed, this method will safely determine whether the file/directory path string will always be valid in both unix/windows filesystems. It enforces windows restrictions in unix and vice versa.
This PR creates the
PathHelper
andPathValidator
classes which have all the necessary methods to read a case-insensitive path and somewhat determine a case-sensitive path based on it. Methods are available to find case-insensitive duplicates, find the closest case-sensitive match, and validate a directory/file path. There are discrepancies in some NET versions that are accounted for here to provide some better unified support across most Unix/windows platforms. We also have a method that will find a case-sensitive path on case-insensitive systems.The problem: KOTOR assumes a case-insensitive filesystem, but on case-sensitive filesystems there's the potential for files/directories to duplicate which KOTOR either randomly picks one or picks a specific duplicate that matches the file/directory exactly.
The solution: This PR provides the following methods in the
PathHelper
andPathValidator
classes:List<FileSystemInfo> FindCaseInsensitiveDuplicates(DirectoryInfo directory)
: If you want to initially scan the KOTOR directory to find case-insensitive duplicates on case-sensitive systems, this method will return a Liststring FixPathFormatting( string path )
: fixes common problems in path strings (backslash vs forwardslash, multiple slashes, and trailing slashes are resolved)(FileSystemInfo?, List<string>) GetClosestMatchingEntry( string path )
: Takes the argument of a case-insensitive path to a file/directory on disk, and will find out if that file is duplicated on disk in the same folder. If it is, it will return a tuple containing the closest matching entry (the closest valid case-sensitive path to the file/directory if one is found), and all other case-sensitive files/directories that duplicate in a case insensitive environment. This method matches more or less what KOTOR does internally.List<string> EnumerateFilesWithWildcards(IEnumerable<string> filesAndFolders, bool topLevelOnly = false)
: Will handle common wildcards such as * (anything here) and ? (any character here) in path strings. Takes a collection of path strings as an argument, and an optional bool for whether to recurse into subfolders.string? GetCaseSensitivePath(string path)
: Takes a case-insensitive path and returns a case-sensitive path. Even works on Windows somewhat, but some refactoring must be done to have it work correctly everytime on windows as windows was never meant to support something like that.bool IsValidPath( string path?)
: Some versions of NET will exception if the path string sent to the DirectoryInfo or FileInfo constructors are too malformed, this method will safely determine whether the file/directory path string will always be valid in both unix/windows filesystems. It enforces windows restrictions in unix and vice versa.