using System;
using System.IO;
using StardewModdingAPI.Toolkit.Serialization;
using StardewModdingAPI.Toolkit.Utilities;
namespace StardewModdingAPI.Framework
{
/// Manages access to a content pack's metadata and files.
internal class ContentPack : IContentPack
{
/*********
** Fields
*********/
/// Provides an API for loading content assets.
private readonly IContentHelper Content;
/// Encapsulates SMAPI's JSON file parsing.
private readonly JsonHelper JsonHelper;
/*********
** Accessors
*********/
///
public string DirectoryPath { get; }
///
public IManifest Manifest { get; }
///
public ITranslationHelper Translation { get; }
/*********
** Public methods
*********/
/// Construct an instance.
/// The full path to the content pack's folder.
/// The content pack's manifest.
/// Provides an API for loading content assets.
/// Provides translations stored in the content pack's i18n folder.
/// Encapsulates SMAPI's JSON file parsing.
public ContentPack(string directoryPath, IManifest manifest, IContentHelper content, ITranslationHelper translation, JsonHelper jsonHelper)
{
this.DirectoryPath = directoryPath;
this.Manifest = manifest;
this.Content = content;
this.Translation = translation;
this.JsonHelper = jsonHelper;
}
///
public bool HasFile(string path)
{
this.AssertRelativePath(path, nameof(this.HasFile));
return File.Exists(Path.Combine(this.DirectoryPath, path));
}
///
public TModel ReadJsonFile(string path) where TModel : class
{
this.AssertRelativePath(path, nameof(this.ReadJsonFile));
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalizePath(path));
return this.JsonHelper.ReadJsonFileIfExists(path, out TModel model)
? model
: null;
}
///
public void WriteJsonFile(string path, TModel data) where TModel : class
{
this.AssertRelativePath(path, nameof(this.WriteJsonFile));
path = Path.Combine(this.DirectoryPath, PathUtilities.NormalizePath(path));
this.JsonHelper.WriteJsonFile(path, data);
}
///
public T LoadAsset(string key)
{
return this.Content.Load(key, ContentSource.ModFolder);
}
///
public string GetActualAssetKey(string key)
{
return this.Content.GetActualAssetKey(key, ContentSource.ModFolder);
}
/*********
** Private methods
*********/
/// Assert that a relative path was passed it to a content pack method.
/// The path to check.
/// The name of the method which was invoked.
private void AssertRelativePath(string path, string methodName)
{
if (!PathUtilities.IsSafeRelativePath(path))
throw new InvalidOperationException($"You must call {nameof(IContentPack)}.{methodName} with a relative path.");
}
}
}