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.PathLookups; namespace StardewModdingAPI.Framework.ModHelpers { /// internal class ModContentHelper : BaseHelper, IModContentHelper { /********* ** Fields *********/ /// SMAPI's core content logic. private readonly ContentCoordinator ContentCore; /// A content manager for this mod which manages files from the mod's folder. private readonly ModContentManager ModContentManager; /// The friendly mod name for use in errors. private readonly string ModName; /// A lookup for relative paths within the . private readonly IFilePathLookup RelativePathLookup; /// Simplifies access to private code. private readonly Reflector Reflection; /********* ** Public methods *********/ /// Construct an instance. /// SMAPI's core content logic. /// The absolute path to the mod folder. /// The mod using this instance. /// The friendly mod name for use in errors. /// The game content manager used for map tilesheets not provided by the mod. /// A lookup for relative paths within the . /// Simplifies access to private code. public ModContentHelper(ContentCoordinator contentCore, string modFolderPath, IModMetadata mod, string modName, IContentManager gameContentManager, IFilePathLookup relativePathLookup, 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.RelativePathLookup = relativePathLookup; this.Reflection = reflection; } /// public T Load(string relativePath) where T : notnull { relativePath = this.RelativePathLookup.GetAssetName(relativePath); IAssetName assetName = this.ContentCore.ParseAssetName(relativePath, allowLocales: false); try { return this.ModContentManager.LoadExact(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); } } /// public IAssetName GetInternalAssetName(string relativePath) { relativePath = this.RelativePathLookup.GetAssetName(relativePath); return this.ModContentManager.GetInternalAssetKey(relativePath); } /// public IAssetData GetPatchHelper(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.RelativePathLookup.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 ); } } }