summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/ModHelpers/ModContentHelper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Framework/ModHelpers/ModContentHelper.cs')
-rw-r--r--src/SMAPI/Framework/ModHelpers/ModContentHelper.cs101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/SMAPI/Framework/ModHelpers/ModContentHelper.cs b/src/SMAPI/Framework/ModHelpers/ModContentHelper.cs
new file mode 100644
index 00000000..def0b728
--- /dev/null
+++ b/src/SMAPI/Framework/ModHelpers/ModContentHelper.cs
@@ -0,0 +1,101 @@
+using System;
+using Microsoft.Xna.Framework.Content;
+using StardewModdingAPI.Framework.Content;
+using StardewModdingAPI.Framework.ContentManagers;
+using StardewModdingAPI.Framework.Exceptions;
+using StardewModdingAPI.Framework.Reflection;
+using StardewModdingAPI.Toolkit.Utilities;
+
+namespace StardewModdingAPI.Framework.ModHelpers
+{
+ /// <inheritdoc cref="IModContentHelper"/>
+ internal class ModContentHelper : BaseHelper, IModContentHelper
+ {
+ /*********
+ ** Fields
+ *********/
+ /// <summary>SMAPI's core content logic.</summary>
+ private readonly ContentCoordinator ContentCore;
+
+ /// <summary>A content manager for this mod which manages files from the mod's folder.</summary>
+ private readonly ModContentManager ModContentManager;
+
+ /// <summary>The friendly mod name for use in errors.</summary>
+ private readonly string ModName;
+
+ /// <summary>A case-insensitive lookup of relative paths within the <see cref="ContentManager.RootDirectory"/>.</summary>
+ private readonly CaseInsensitivePathLookup RelativePathCache;
+
+ /// <summary>Simplifies access to private code.</summary>
+ private readonly Reflector Reflection;
+
+
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Construct an instance.</summary>
+ /// <param name="contentCore">SMAPI's core content logic.</param>
+ /// <param name="modFolderPath">The absolute path to the mod folder.</param>
+ /// <param name="mod">The mod using this instance.</param>
+ /// <param name="modName">The friendly mod name for use in errors.</param>
+ /// <param name="gameContentManager">The game content manager used for map tilesheets not provided by the mod.</param>
+ /// <param name="relativePathCache">A case-insensitive lookup of relative paths within the <paramref name="relativePathCache"/>.</param>
+ /// <param name="reflection">Simplifies access to private code.</param>
+ public ModContentHelper(ContentCoordinator contentCore, string modFolderPath, IModMetadata mod, string modName, IContentManager gameContentManager, CaseInsensitivePathLookup relativePathCache, Reflector reflection)
+ : base(mod)
+ {
+ string managedAssetPrefix = contentCore.GetManagedAssetPrefix(mod.Manifest.UniqueID);
+
+ this.ContentCore = contentCore;
+ this.ModContentManager = contentCore.CreateModContentManager(managedAssetPrefix, modName, modFolderPath, gameContentManager);
+ this.ModName = modName;
+ this.RelativePathCache = relativePathCache;
+ this.Reflection = reflection;
+ }
+
+ /// <inheritdoc />
+ public T Load<T>(string relativePath)
+ where T : notnull
+ {
+ relativePath = this.RelativePathCache.GetAssetName(relativePath);
+
+ IAssetName assetName = this.ContentCore.ParseAssetName(relativePath, allowLocales: false);
+
+ try
+ {
+ return this.ModContentManager.LoadExact<T>(assetName, useCache: false);
+ }
+ catch (Exception ex) when (ex is not SContentLoadException)
+ {
+ throw new SContentLoadException($"{this.ModName} failed loading content asset '{relativePath}' from its mod folder.", ex);
+ }
+ }
+
+ /// <inheritdoc />
+ public IAssetName GetInternalAssetName(string relativePath)
+ {
+ relativePath = this.RelativePathCache.GetAssetName(relativePath);
+ return this.ModContentManager.GetInternalAssetKey(relativePath);
+ }
+
+ /// <inheritdoc />
+ public IAssetData GetPatchHelper<T>(T data, string? relativePath = null)
+ where T : notnull
+ {
+ if (data == null)
+ throw new ArgumentNullException(nameof(data), "Can't get a patch helper for a null value.");
+
+ relativePath = relativePath != null
+ ? this.RelativePathCache.GetAssetName(relativePath)
+ : $"temp/{Guid.NewGuid():N}";
+
+ return new AssetDataForObject(
+ locale: this.ContentCore.GetLocale(),
+ assetName: this.ContentCore.ParseAssetName(relativePath, allowLocales: false),
+ data: data,
+ getNormalizedPath: key => this.ContentCore.ParseAssetName(key, allowLocales: false).Name,
+ reflection: this.Reflection
+ );
+ }
+ }
+}