summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs17
-rw-r--r--src/SMAPI/Framework/ModLoading/ModResolver.cs15
-rw-r--r--src/SMAPI/Framework/SCore.cs11
-rw-r--r--src/SMAPI/Utilities/CaseInsensitivePathCache.cs23
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;
}