diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI/Framework/ContentCoordinator.cs | 17 | ||||
-rw-r--r-- | src/SMAPI/Framework/ModLoading/ModResolver.cs | 15 | ||||
-rw-r--r-- | src/SMAPI/Framework/SCore.cs | 11 | ||||
-rw-r--r-- | src/SMAPI/Utilities/CaseInsensitivePathCache.cs | 23 |
4 files changed, 30 insertions, 36 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index 92452224..f83d4090 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -80,9 +80,6 @@ namespace StardewModdingAPI.Framework /// <summary>The cached asset load/edit operations to apply, indexed by asset name.</summary> private readonly TickCacheDictionary<IAssetName, AssetOperationGroup[]> AssetOperationsByKey = new(); - /// <summary>The previously created case-insensitive path caches by root path.</summary> - private readonly Dictionary<string, CaseInsensitivePathCache> CaseInsensitivePathCaches = new(StringComparer.OrdinalIgnoreCase); - /********* ** Accessors @@ -211,7 +208,7 @@ namespace StardewModdingAPI.Framework jsonHelper: this.JsonHelper, onDisposing: this.OnDisposing, aggressiveMemoryOptimizations: this.AggressiveMemoryOptimizations, - relativePathCache: this.GetCaseInsensitivePathCache(rootDirectory) + relativePathCache: CaseInsensitivePathCache.GetFor(rootDirectory) ); this.ContentManagers.Add(manager); return manager; @@ -486,18 +483,6 @@ namespace StardewModdingAPI.Framework }); } - /// <summary>Get a dictionary of relative paths within a root path, for case-insensitive file lookups.</summary> - /// <param name="rootPath">The root path to scan.</param> - public CaseInsensitivePathCache GetCaseInsensitivePathCache(string rootPath) - { - rootPath = PathUtilities.NormalizePath(rootPath); - - if (!this.CaseInsensitivePathCaches.TryGetValue(rootPath, out CaseInsensitivePathCache? cache)) - this.CaseInsensitivePathCaches[rootPath] = cache = new CaseInsensitivePathCache(rootPath); - - return cache; - } - /// <summary>Get the tilesheet ID order used by the unmodified version of a map asset.</summary> /// <param name="assetName">The asset path relative to the loader root directory, not including the <c>.xnb</c> extension.</param> public TilesheetReference[] GetVanillaTilesheetIds(string assetName) diff --git a/src/SMAPI/Framework/ModLoading/ModResolver.cs b/src/SMAPI/Framework/ModLoading/ModResolver.cs index afb388d0..e3c7873c 100644 --- a/src/SMAPI/Framework/ModLoading/ModResolver.cs +++ b/src/SMAPI/Framework/ModLoading/ModResolver.cs @@ -8,7 +8,7 @@ using StardewModdingAPI.Toolkit.Framework.ModData; using StardewModdingAPI.Toolkit.Framework.ModScanning; using StardewModdingAPI.Toolkit.Framework.UpdateData; using StardewModdingAPI.Toolkit.Serialization.Models; -using StardewModdingAPI.Toolkit.Utilities; +using StardewModdingAPI.Utilities; namespace StardewModdingAPI.Framework.ModLoading { @@ -140,20 +140,13 @@ namespace StardewModdingAPI.Framework.ModLoading continue; } - // invalid path - if (!File.Exists(Path.Combine(mod.DirectoryPath, mod.Manifest.EntryDll!))) + // file doesn't exist + string fileName = CaseInsensitivePathCache.GetFor(mod.DirectoryPath).GetFilePath(mod.Manifest.EntryDll!); + if (!File.Exists(Path.Combine(mod.DirectoryPath, fileName))) { mod.SetStatus(ModMetadataStatus.Failed, ModFailReason.InvalidManifest, $"its DLL '{mod.Manifest.EntryDll}' doesn't exist."); continue; } - - // invalid capitalization - string? actualFilename = new DirectoryInfo(mod.DirectoryPath).GetFiles(mod.Manifest.EntryDll!).FirstOrDefault()?.Name; - if (actualFilename != mod.Manifest.EntryDll) - { - mod.SetStatus(ModMetadataStatus.Failed, ModFailReason.InvalidManifest, $"its {nameof(IManifest.EntryDll)} value '{mod.Manifest.EntryDll}' doesn't match the actual file capitalization '{actualFilename}'. The capitalization must match for crossplatform compatibility."); - continue; - } } // validate content pack diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs index 990fe5ea..d2890c29 100644 --- a/src/SMAPI/Framework/SCore.cs +++ b/src/SMAPI/Framework/SCore.cs @@ -1748,7 +1748,7 @@ namespace StardewModdingAPI.Framework if (mod.IsContentPack) { IMonitor monitor = this.LogManager.GetMonitor(mod.DisplayName); - CaseInsensitivePathCache relativePathCache = this.ContentCore.GetCaseInsensitivePathCache(mod.DirectoryPath); + CaseInsensitivePathCache relativePathCache = CaseInsensitivePathCache.GetFor(mod.DirectoryPath); GameContentHelper gameContentHelper = new(this.ContentCore, mod, mod.DisplayName, monitor, this.Reflection); IModContentHelper modContentHelper = new ModContentHelper(this.ContentCore, mod.DirectoryPath, mod, mod.DisplayName, gameContentHelper.GetUnderlyingContentManager(), relativePathCache, this.Reflection); TranslationHelper translationHelper = new(mod, contentCore.GetLocale(), contentCore.Language); @@ -1765,7 +1765,10 @@ namespace StardewModdingAPI.Framework else { // get mod info - string assemblyPath = Path.Combine(mod.DirectoryPath, manifest.EntryDll!); + string assemblyPath = Path.Combine( + mod.DirectoryPath, + CaseInsensitivePathCache.GetFor(mod.DirectoryPath).GetFilePath(manifest.EntryDll!) + ); // load mod Assembly modAssembly; @@ -1830,7 +1833,7 @@ namespace StardewModdingAPI.Framework { IMonitor packMonitor = this.LogManager.GetMonitor(packManifest.Name); - CaseInsensitivePathCache relativePathCache = this.ContentCore.GetCaseInsensitivePathCache(packDirPath); + CaseInsensitivePathCache relativePathCache = CaseInsensitivePathCache.GetFor(packDirPath); GameContentHelper gameContentHelper = new(contentCore, mod, packManifest.Name, packMonitor, this.Reflection); IModContentHelper packContentHelper = new ModContentHelper(contentCore, packDirPath, mod, packManifest.Name, gameContentHelper.GetUnderlyingContentManager(), relativePathCache, this.Reflection); @@ -1844,7 +1847,7 @@ namespace StardewModdingAPI.Framework IModEvents events = new ModEvents(mod, this.EventManager); ICommandHelper commandHelper = new CommandHelper(mod, this.CommandManager); - CaseInsensitivePathCache relativePathCache = this.ContentCore.GetCaseInsensitivePathCache(mod.DirectoryPath); + CaseInsensitivePathCache relativePathCache = CaseInsensitivePathCache.GetFor(mod.DirectoryPath); #pragma warning disable CS0612 // deprecated code ContentHelper contentHelper = new(contentCore, mod.DirectoryPath, mod, monitor, this.Reflection); #pragma warning restore CS0612 diff --git a/src/SMAPI/Utilities/CaseInsensitivePathCache.cs b/src/SMAPI/Utilities/CaseInsensitivePathCache.cs index 2ac1b9f9..04fdcfae 100644 --- a/src/SMAPI/Utilities/CaseInsensitivePathCache.cs +++ b/src/SMAPI/Utilities/CaseInsensitivePathCache.cs @@ -16,6 +16,9 @@ namespace StardewModdingAPI.Utilities /// <summary>A case-insensitive lookup of file paths within the <see cref="RootPath"/>. Each path is listed in both file path and asset name format, so it's usable in both contexts without needing to re-parse paths.</summary> private readonly Lazy<Dictionary<string, string>> RelativePathCache; + /// <summary>The case-insensitive path caches by root path.</summary> + private static readonly Dictionary<string, CaseInsensitivePathCache> CachesByRootPath = new(StringComparer.OrdinalIgnoreCase); + /********* ** Public methods @@ -65,6 +68,18 @@ namespace StardewModdingAPI.Utilities this.CacheRawPath(this.RelativePathCache.Value, relativePath); } + /// <summary>Get a cached dictionary of relative paths within a root path, for case-insensitive file lookups.</summary> + /// <param name="rootPath">The root path to scan.</param> + public static CaseInsensitivePathCache GetFor(string rootPath) + { + rootPath = PathUtilities.NormalizePath(rootPath); + + if (!CaseInsensitivePathCache.CachesByRootPath.TryGetValue(rootPath, out CaseInsensitivePathCache? cache)) + CaseInsensitivePathCache.CachesByRootPath[rootPath] = cache = new CaseInsensitivePathCache(rootPath); + + return cache; + } + /********* ** Private methods @@ -82,15 +97,13 @@ namespace StardewModdingAPI.Utilities if (this.RelativePathCache.Value.TryGetValue(relativePath, out string? resolved)) return resolved; - // file exists but isn't cached for some reason - // cache it now so any later references to it are case-insensitive + // keep capitalization as-is if (File.Exists(Path.Combine(this.RootPath, relativePath))) { + // file exists but isn't cached for some reason + // cache it now so any later references to it are case-insensitive this.CacheRawPath(this.RelativePathCache.Value, relativePath); - return relativePath; } - - // no such file, keep capitalization as-is return relativePath; } |