add DoesAssetExist to support the upcoming Stardew Valley 1.6 (#766)
This commit is contained in:
parent
b0d8b23c2c
commit
b68b301b71
|
@ -296,6 +296,22 @@ namespace StardewModdingAPI.Framework
|
|||
return Path.Combine(this.ManagedPrefix, modID.ToLower());
|
||||
}
|
||||
|
||||
/// <summary>Get whether an asset from a mod folder exists.</summary>
|
||||
/// <param name="contentManagerID">The unique name for the content manager which should load this asset.</param>
|
||||
/// <param name="assetName">The asset name within the mod folder.</param>
|
||||
public bool DoesManagedAssetExist(string contentManagerID, IAssetName assetName)
|
||||
{
|
||||
// get content manager
|
||||
IContentManager contentManager = this.ContentManagerLock.InReadLock(() =>
|
||||
this.ContentManagers.FirstOrDefault(p => p.IsNamespaced && p.Name == contentManagerID)
|
||||
);
|
||||
if (contentManager == null)
|
||||
throw new InvalidOperationException($"The '{contentManagerID}' prefix isn't handled by any mod.");
|
||||
|
||||
// get whether the asset exists
|
||||
return contentManager.DoesAssetExist(assetName);
|
||||
}
|
||||
|
||||
/// <summary>Get a copy of an asset from a mod folder.</summary>
|
||||
/// <typeparam name="T">The asset type.</typeparam>
|
||||
/// <param name="contentManagerID">The unique name for the content manager which should load this asset.</param>
|
||||
|
|
|
@ -92,6 +92,12 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
this.BaseDisposableReferences = reflection.GetField<List<IDisposable>>(this, "disposableAssets").GetValue();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool DoesAssetExist(IAssetName assetName)
|
||||
{
|
||||
return this.Cache.ContainsKey(assetName.Name);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
[Obsolete("This method is implemented for the base game and should not be used directly. To load an asset from the underlying content manager directly, use " + nameof(BaseContentManager.RawLoad) + " instead.")]
|
||||
public override T LoadBase<T>(string assetName)
|
||||
|
|
|
@ -62,6 +62,29 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
this.OnLoadingFirstAsset = onLoadingFirstAsset;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool DoesAssetExist(IAssetName assetName)
|
||||
{
|
||||
if (base.DoesAssetExist(assetName))
|
||||
return true;
|
||||
|
||||
// managed asset
|
||||
if (this.Coordinator.TryParseManagedAssetKey(assetName.Name, out string contentManagerID, out IAssetName relativePath))
|
||||
return this.Coordinator.DoesManagedAssetExist(contentManagerID, relativePath);
|
||||
|
||||
// else check for loaders
|
||||
string locale = this.GetLocale();
|
||||
IAssetInfo info = new AssetInfo(locale, assetName, typeof(object), this.AssertAndNormalizeAssetName);
|
||||
ModLinked<IAssetLoader>[] loaders = this.GetLoaders<object>(info).ToArray();
|
||||
if (loaders.Length > 1)
|
||||
{
|
||||
string[] loaderNames = loaders.Select(p => p.Mod.DisplayName).ToArray();
|
||||
this.Monitor.Log($"Multiple mods want to provide the '{info.Name}' asset ({string.Join(", ", loaderNames)}), but an asset can't be loaded multiple times. SMAPI will use the default asset instead; uninstall one of the mods to fix this. (Message for modders: you should usually use {typeof(IAssetEditor)} instead to avoid conflicts.)", LogLevel.Warn);
|
||||
}
|
||||
|
||||
return loaders.Length == 1;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T Load<T>(IAssetName assetName, LanguageCode language, bool useCache)
|
||||
{
|
||||
|
@ -246,20 +269,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
private IAssetData ApplyLoader<T>(IAssetInfo info)
|
||||
{
|
||||
// find matching loaders
|
||||
var loaders = this.Loaders
|
||||
.Where(entry =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return entry.Data.CanLoad<T>(info);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
entry.Mod.LogAsMod($"Mod failed when checking whether it could load asset '{info.Name}', and will be ignored. Error details:\n{ex.GetLogSummary()}", LogLevel.Error);
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.ToArray();
|
||||
var loaders = this.GetLoaders<T>(info).ToArray();
|
||||
|
||||
// validate loaders
|
||||
if (!loaders.Any())
|
||||
|
@ -360,6 +370,26 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
return asset;
|
||||
}
|
||||
|
||||
/// <summary>Get the asset loaders which handle the asset.</summary>
|
||||
/// <typeparam name="T">The asset type.</typeparam>
|
||||
/// <param name="info">The basic asset metadata.</param>
|
||||
private IEnumerable<ModLinked<IAssetLoader>> GetLoaders<T>(IAssetInfo info)
|
||||
{
|
||||
return this.Loaders
|
||||
.Where(entry =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return entry.Data.CanLoad<T>(info);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
entry.Mod.LogAsMod($"Mod failed when checking whether it could load asset '{info.Name}', and will be ignored. Error details:\n{ex.GetLogSummary()}", LogLevel.Error);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>Validate that an asset loaded by a mod is valid and won't cause issues, and fix issues if possible.</summary>
|
||||
/// <typeparam name="T">The asset type.</typeparam>
|
||||
/// <param name="info">The basic asset metadata.</param>
|
||||
|
|
|
@ -28,6 +28,10 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
/*********
|
||||
** Methods
|
||||
*********/
|
||||
/// <summary>Get whether an asset exists and can be loaded.</summary>
|
||||
/// <param name="assetName">The normalized asset name.</param>
|
||||
bool DoesAssetExist(IAssetName assetName);
|
||||
|
||||
/// <summary>Load an asset that has been processed by the content pipeline.</summary>
|
||||
/// <typeparam name="T">The type of asset to load.</typeparam>
|
||||
/// <param name="assetName">The asset name relative to the loader root directory.</param>
|
||||
|
|
|
@ -63,6 +63,16 @@ namespace StardewModdingAPI.Framework.ContentManagers
|
|||
this.ModName = modName;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool DoesAssetExist(IAssetName assetName)
|
||||
{
|
||||
if (base.DoesAssetExist(assetName))
|
||||
return true;
|
||||
|
||||
FileInfo file = this.GetModFile(assetName.Name);
|
||||
return file.Exists;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override T Load<T>(string assetName)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue