From 7f57160aae455c75fbfe89cb848d5217631b1211 Mon Sep 17 00:00:00 2001 From: maj00r Date: Fri, 13 Nov 2026 16:09:52 +0100 Subject: [PATCH] fix: open a livery's folder whatever the case of its name "Open texture folder" finds the folder under dynamic, or from the game folder, through CaseInsensitivePaths, so on Linux it opens the folder when textures.txt names it in other letter case. --- StarterNG.Tests/TextureFolderTests.cs | 22 +++++++++++++++++ .../Infrastructure/Vehicles/TextureFolder.cs | 24 +++++++++++++++++++ StarterNG/Views/Depot/TextureMenuItems.cs | 12 ++++------ 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 StarterNG.Tests/TextureFolderTests.cs create mode 100644 StarterNG/Infrastructure/Vehicles/TextureFolder.cs diff --git a/StarterNG.Tests/TextureFolderTests.cs b/StarterNG.Tests/TextureFolderTests.cs new file mode 100644 index 0000000..2384c37 --- /dev/null +++ b/StarterNG.Tests/TextureFolderTests.cs @@ -0,0 +1,22 @@ +using StarterNG.Domain.Vehicles; +using StarterNG.Infrastructure.Vehicles; +using StarterNG.Tests.Fakes; + +namespace StarterNG.Tests; + +public class TextureFolderTests +{ + private static readonly TestInstallation Installation = new(new InMemoryFileSystem(caseSensitive: true) + .WithFile("game/dynamic/PKP/EP09_v1/textures.txt", "") + .WithDirectory("game/Other/Folder")); + + [Theory] + [InlineData("pkp/ep09_v1/", "dynamic/PKP/EP09_v1")] + [InlineData(@"PKP\EP09_V1", "dynamic/PKP/EP09_v1")] + [InlineData("other/folder/", "Other/Folder")] + [InlineData("pkp/brak/", "pkp/brak")] + public void A_liverys_folder_is_found_as_it_is_named_on_disk(string named, string onDisk) => + Assert.Equal(Path.GetFullPath(Path.Combine("game", onDisk)), + Path.GetFullPath(TextureFolder.Of(Installation.Files, Installation.Paths, + new VehicleTexture { Directory = named }))); +} diff --git a/StarterNG/Infrastructure/Vehicles/TextureFolder.cs b/StarterNG/Infrastructure/Vehicles/TextureFolder.cs new file mode 100644 index 0000000..530d5bb --- /dev/null +++ b/StarterNG/Infrastructure/Vehicles/TextureFolder.cs @@ -0,0 +1,24 @@ +using System.IO; +using StarterNG.Application.Abstractions; +using StarterNG.Domain.Vehicles; + +namespace StarterNG.Infrastructure.Vehicles; + +public static class TextureFolder +{ + /// + /// A livery's folder as it is named on disk: under dynamic, or from the game's folder + /// when its name starts there, in any letter case. Where it would be when it is not there. + /// + public static string Of(IFileSystem files, IGamePaths paths, VehicleTexture texture) + { + string directory = texture.Directory.Replace('\\', '/').TrimEnd('/'); + if (directory.Length == 0) + return paths.Dynamic; + + var names = new CaseInsensitivePaths(files); + return names.Find(paths.Dynamic, directory, directory: true) ?? + names.Find(paths.Root, directory, directory: true) ?? + Path.Combine(paths.Root, directory.Replace('/', Path.DirectorySeparatorChar)); + } +} diff --git a/StarterNG/Views/Depot/TextureMenuItems.cs b/StarterNG/Views/Depot/TextureMenuItems.cs index b54810e..0461a99 100644 --- a/StarterNG/Views/Depot/TextureMenuItems.cs +++ b/StarterNG/Views/Depot/TextureMenuItems.cs @@ -1,8 +1,10 @@ using System.IO; using Avalonia.Controls; using Avalonia.Input.Platform; +using StarterNG.Application; using StarterNG.Domain; using StarterNG.Domain.Vehicles; +using StarterNG.Infrastructure.Vehicles; namespace StarterNG.Views; @@ -17,13 +19,7 @@ internal static class TextureMenuItems if (TopLevel.GetTopLevel(owner)?.Clipboard is { } clipboard) await clipboard.SetTextAsync(Consist.Base(texture.Skinfile)); }); - menu.AddItem(App.Loc["OpenTextureFolder"], () => Infrastructure.Diagnostics.OpenOrReport(FolderOf(texture))); - } - - private static string FolderOf(VehicleTexture texture) - { - string dir = Path.Combine(Directory.GetCurrentDirectory(), "dynamic", - texture.Directory.Replace('/', Path.DirectorySeparatorChar).TrimEnd('\\', '/')); - return Directory.Exists(dir) ? dir : Path.Combine(Directory.GetCurrentDirectory(), texture.Directory); + menu.AddItem(App.Loc["OpenTextureFolder"], () => Infrastructure.Diagnostics.OpenOrReport( + Path.GetFullPath(TextureFolder.Of(AppServices.Current.Files, AppServices.Current.Paths, texture)))); } }