From 3db035312641b629aaa5517569d0d30cf71bac29 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 7 May 2022 23:12:33 -0400 Subject: simplify and rewrite case-insensitive file path feature --- .../Framework/ContentManagers/ModContentManager.cs | 39 ++++++++++------------ 1 file changed, 18 insertions(+), 21 deletions(-) (limited to 'src/SMAPI/Framework/ContentManagers') diff --git a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs index 65dffd8b..7cac8f36 100644 --- a/src/SMAPI/Framework/ContentManagers/ModContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/ModContentManager.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; @@ -33,11 +34,11 @@ namespace StardewModdingAPI.Framework.ContentManagers /// The game content manager used for map tilesheets not provided by the mod. private readonly IContentManager GameContentManager; - /// A lookup for relative paths within the . - private readonly IFilePathLookup RelativePathLookup; + /// A lookup for files within the . + private readonly IFileLookup FileLookup; /// If a map tilesheet's image source has no file extensions, the file extensions to check for in the local mod folder. - private readonly string[] LocalTilesheetExtensions = { ".png", ".xnb" }; + private static readonly HashSet LocalTilesheetExtensions = new(StringComparer.OrdinalIgnoreCase) { ".png", ".xnb" }; /********* @@ -55,12 +56,12 @@ namespace StardewModdingAPI.Framework.ContentManagers /// Simplifies access to private code. /// Encapsulates SMAPI's JSON file parsing. /// A callback to invoke when the content manager is being disposed. - /// A lookup for relative paths within the . - public ModContentManager(string name, IContentManager gameContentManager, IServiceProvider serviceProvider, string modName, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onDisposing, IFilePathLookup relativePathLookup) + /// A lookup for files within the . + public ModContentManager(string name, IContentManager gameContentManager, IServiceProvider serviceProvider, string modName, string rootDirectory, CultureInfo currentCulture, ContentCoordinator coordinator, IMonitor monitor, Reflector reflection, JsonHelper jsonHelper, Action onDisposing, IFileLookup fileLookup) : base(name, serviceProvider, rootDirectory, currentCulture, coordinator, monitor, reflection, onDisposing, isNamespaced: true) { this.GameContentManager = gameContentManager; - this.RelativePathLookup = relativePathLookup; + this.FileLookup = fileLookup; this.JsonHelper = jsonHelper; this.ModName = modName; @@ -73,7 +74,7 @@ namespace StardewModdingAPI.Framework.ContentManagers if (base.DoesAssetExist(assetName)) return true; - FileInfo file = this.GetModFile(assetName.Name); + FileInfo file = this.GetModFile(assetName.Name); return file.Exists; } @@ -103,7 +104,7 @@ namespace StardewModdingAPI.Framework.ContentManagers try { // get file - FileInfo file = this.GetModFile(assetName.Name); + FileInfo file = this.GetModFile(assetName.Name); if (!file.Exists) throw this.GetLoadError(assetName, "the specified path doesn't exist."); @@ -139,9 +140,7 @@ namespace StardewModdingAPI.Framework.ContentManagers /// The is empty or contains invalid characters. public IAssetName GetInternalAssetKey(string key) { - FileInfo file = this.GetModFile(key); - string relativePath = Path.GetRelativePath(this.RootDirectory, file.FullName); - string internalKey = Path.Combine(this.Name, relativePath); + string internalKey = Path.Combine(this.Name, PathUtilities.NormalizeAssetName(key)); return this.Coordinator.ParseAssetName(internalKey, allowLocales: false); } @@ -253,19 +252,17 @@ namespace StardewModdingAPI.Framework.ContentManagers } /// Get a file from the mod folder. + /// The expected asset type. /// The asset path relative to the content folder. - private FileInfo GetModFile(string path) + private FileInfo GetModFile(string path) { - // map to case-insensitive path if needed - path = this.RelativePathLookup.GetFilePath(path); + // get exact file + FileInfo file = this.FileLookup.GetFile(path); - // try exact match - FileInfo file = new(Path.Combine(this.FullRootDirectory, path)); - - // try with default extension - if (!file.Exists) + // try with default image extensions + if (!file.Exists && typeof(Texture2D).IsAssignableFrom(typeof(T)) && !ModContentManager.LocalTilesheetExtensions.Contains(file.Extension)) { - foreach (string extension in this.LocalTilesheetExtensions) + foreach (string extension in ModContentManager.LocalTilesheetExtensions) { FileInfo result = new(file.FullName + extension); if (result.Exists) @@ -385,7 +382,7 @@ namespace StardewModdingAPI.Framework.ContentManagers // get relative to map file { string localKey = Path.Combine(modRelativeMapFolder, relativePath); - if (this.GetModFile(localKey).Exists) + if (this.GetModFile(localKey).Exists) { assetName = this.GetInternalAssetKey(localKey); return true; -- cgit