make EntryDll manifest field case-insensitive
This commit is contained in:
parent
e7fd95aafd
commit
1974324c43
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue