track mod metadata reference in APIs for upcoming deprecation changes

This commit is contained in:
Jesse Plamondon-Willard 2022-04-14 23:00:30 -04:00
parent 43c875c4c2
commit 1a3befa93e
No known key found for this signature in database
GPG Key ID: CF8B1456B3E29F49
15 changed files with 94 additions and 65 deletions

View File

@ -1,10 +1,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using NUnit.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.ModHelpers;
using StardewModdingAPI.Framework.ModLoading;
using StardewModdingAPI.Toolkit.Serialization.Models;
using StardewValley;
namespace SMAPI.Tests.Core
@ -33,7 +37,7 @@ namespace SMAPI.Tests.Core
var data = new Dictionary<string, IDictionary<string, string>>();
// act
ITranslationHelper helper = new TranslationHelper("ModID", "en", LocalizedContentManager.LanguageCode.en).SetTranslations(data);
ITranslationHelper helper = new TranslationHelper(this.CreateModMetadata(), "en", LocalizedContentManager.LanguageCode.en).SetTranslations(data);
Translation translation = helper.Get("key");
Translation[]? translationList = helper.GetTranslations()?.ToArray();
@ -56,7 +60,7 @@ namespace SMAPI.Tests.Core
// act
var actual = new Dictionary<string, Translation[]?>();
TranslationHelper helper = new TranslationHelper("ModID", "en", LocalizedContentManager.LanguageCode.en).SetTranslations(data);
TranslationHelper helper = new TranslationHelper(this.CreateModMetadata(), "en", LocalizedContentManager.LanguageCode.en).SetTranslations(data);
foreach (string locale in expected.Keys)
{
this.AssertSetLocale(helper, locale, LocalizedContentManager.LanguageCode.en);
@ -80,7 +84,7 @@ namespace SMAPI.Tests.Core
// act
var actual = new Dictionary<string, Translation[]>();
TranslationHelper helper = new TranslationHelper("ModID", "en", LocalizedContentManager.LanguageCode.en).SetTranslations(data);
TranslationHelper helper = new TranslationHelper(this.CreateModMetadata(), "en", LocalizedContentManager.LanguageCode.en).SetTranslations(data);
foreach (string locale in expected.Keys)
{
this.AssertSetLocale(helper, locale, LocalizedContentManager.LanguageCode.en);
@ -325,6 +329,28 @@ namespace SMAPI.Tests.Core
return string.Format(Translation.PlaceholderText, key);
}
/// <summary>Create a fake mod manifest.</summary>
private IModMetadata CreateModMetadata()
{
string id = $"smapi.unit-tests.fake-mod-{Guid.NewGuid():N}";
string tempPath = Path.Combine(Path.GetTempPath(), id);
return new ModMetadata(
displayName: "Mod Display Name",
directoryPath: tempPath,
rootPath: tempPath,
manifest: new Manifest(
uniqueID: id,
name: "Mod Name",
author: "Mod Author",
description: "Mod Description",
version: new SemanticVersion(1, 0, 0)
),
dataRecord: null,
isIgnored: false
);
}
/*********
** Test models

View File

@ -3,21 +3,28 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>The common base class for mod helpers.</summary>
internal abstract class BaseHelper : IModLinked
{
/*********
** Fields
*********/
/// <summary>The mod using this instance.</summary>
protected readonly IModMetadata Mod;
/*********
** Accessors
*********/
/// <inheritdoc />
public string ModID { get; }
public string ModID => this.Mod.Manifest.UniqueID;
/*********
** Protected methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
protected BaseHelper(string modID)
/// <param name="mod">The mod using this instance.</param>
protected BaseHelper(IModMetadata mod)
{
this.ModID = modID;
this.Mod = mod;
}
}
}

View File

@ -8,9 +8,6 @@ namespace StardewModdingAPI.Framework.ModHelpers
/*********
** Fields
*********/
/// <summary>The mod using this instance.</summary>
private readonly IModMetadata Mod;
/// <summary>Manages console commands.</summary>
private readonly CommandManager CommandManager;
@ -22,9 +19,8 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="mod">The mod using this instance.</param>
/// <param name="commandManager">Manages console commands.</param>
public CommandHelper(IModMetadata mod, CommandManager commandManager)
: base(mod.Manifest.UniqueID)
: base(mod)
{
this.Mod = mod;
this.CommandManager = commandManager;
}

View File

@ -93,14 +93,14 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <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="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="modName">The friendly mod name for use in errors.</param>
/// <param name="monitor">Encapsulates monitoring and logging.</param>
/// <param name="reflection">Simplifies access to private code.</param>
public ContentHelper(ContentCoordinator contentCore, string modFolderPath, string modID, string modName, IMonitor monitor, Reflector reflection)
: base(modID)
public ContentHelper(ContentCoordinator contentCore, string modFolderPath, IModMetadata mod, string modName, IMonitor monitor, Reflector reflection)
: base(mod)
{
string managedAssetPrefix = contentCore.GetManagedAssetPrefix(modID);
string managedAssetPrefix = contentCore.GetManagedAssetPrefix(mod.Manifest.UniqueID);
this.ContentCore = contentCore;
this.GameContentManager = contentCore.CreateGameContentManager(managedAssetPrefix + ".content");

View File

@ -22,11 +22,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="contentPacks">The content packs loaded for this mod.</param>
/// <param name="createContentPack">Create a temporary content pack.</param>
public ContentPackHelper(string modID, Lazy<IContentPack[]> contentPacks, Func<string, IManifest, IContentPack> createContentPack)
: base(modID)
public ContentPackHelper(IModMetadata mod, Lazy<IContentPack[]> contentPacks, Func<string, IManifest, IContentPack> createContentPack)
: base(mod)
{
this.ContentPacks = contentPacks;
this.CreateContentPack = createContentPack;

View File

@ -26,11 +26,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="modFolderPath">The absolute path to the mod folder.</param>
/// <param name="jsonHelper">The absolute path to the mod folder.</param>
public DataHelper(string modID, string modFolderPath, JsonHelper jsonHelper)
: base(modID)
public DataHelper(IModMetadata mod, string modFolderPath, JsonHelper jsonHelper)
: base(mod)
{
this.ModFolderPath = modFolderPath;
this.JsonHelper = jsonHelper;

View File

@ -45,14 +45,14 @@ namespace StardewModdingAPI.Framework.ModHelpers
*********/
/// <summary>Construct an instance.</summary>
/// <param name="contentCore">SMAPI's core content logic.</param>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="modName">The friendly mod name for use in errors.</param>
/// <param name="monitor">Encapsulates monitoring and logging.</param>
/// <param name="reflection">Simplifies access to private code.</param>
public GameContentHelper(ContentCoordinator contentCore, string modID, string modName, IMonitor monitor, Reflector reflection)
: base(modID)
public GameContentHelper(ContentCoordinator contentCore, IModMetadata mod, string modName, IMonitor monitor, Reflector reflection)
: base(mod)
{
string managedAssetPrefix = contentCore.GetManagedAssetPrefix(modID);
string managedAssetPrefix = contentCore.GetManagedAssetPrefix(mod.Manifest.UniqueID);
this.ContentCore = contentCore;
this.GameContentManager = contentCore.CreateGameContentManager(managedAssetPrefix + ".content");

View File

@ -18,10 +18,10 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="currentInputState">Manages the game's input state for the current player instance. That may not be the main player in split-screen mode.</param>
public InputHelper(string modID, Func<SInputState> currentInputState)
: base(modID)
public InputHelper(IModMetadata mod, Func<SInputState> currentInputState)
: base(mod)
{
this.CurrentInputState = currentInputState;
}

View File

@ -36,15 +36,15 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <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="modID">The unique ID of the relevant mod.</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, string modID, string modName, IContentManager gameContentManager, CaseInsensitivePathCache relativePathCache, Reflector reflection)
: base(modID)
public ModContentHelper(ContentCoordinator contentCore, string modFolderPath, IModMetadata mod, string modName, IContentManager gameContentManager, CaseInsensitivePathCache relativePathCache, Reflector reflection)
: base(mod)
{
string managedAssetPrefix = contentCore.GetManagedAssetPrefix(modID);
string managedAssetPrefix = contentCore.GetManagedAssetPrefix(mod.Manifest.UniqueID);
this.ContentCore = contentCore;
this.ModContentManager = contentCore.CreateModContentManager(managedAssetPrefix, modName, modFolderPath, gameContentManager);

View File

@ -77,7 +77,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The mod's unique ID.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="modDirectory">The full path to the mod's folder.</param>
/// <param name="currentInputState">Manages the game's input state for the current player instance. That may not be the main player in split-screen mode.</param>
/// <param name="events">Manages access to events raised by SMAPI.</param>
@ -94,13 +94,13 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <exception cref="ArgumentNullException">An argument is null or empty.</exception>
/// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception>
public ModHelper(
string modID, string modDirectory, Func<SInputState> currentInputState, IModEvents events,
IModMetadata mod, string modDirectory, Func<SInputState> currentInputState, IModEvents events,
#pragma warning disable CS0612 // deprecated code
ContentHelper contentHelper,
#pragma warning restore CS0612
IGameContentHelper gameContentHelper, IModContentHelper modContentHelper, IContentPackHelper contentPackHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper
)
: base(modID)
: base(mod)
{
// validate directory
if (string.IsNullOrWhiteSpace(modDirectory))
@ -117,7 +117,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
this.ModContent = modContentHelper ?? throw new ArgumentNullException(nameof(modContentHelper));
this.ContentPacks = contentPackHelper ?? throw new ArgumentNullException(nameof(contentPackHelper));
this.Data = dataHelper ?? throw new ArgumentNullException(nameof(dataHelper));
this.Input = new InputHelper(modID, currentInputState);
this.Input = new InputHelper(mod, currentInputState);
this.ModRegistry = modRegistry ?? throw new ArgumentNullException(nameof(modRegistry));
this.ConsoleCommands = commandHelper ?? throw new ArgumentNullException(nameof(commandHelper));
this.Reflection = reflectionHelper ?? throw new ArgumentNullException(nameof(reflectionHelper));

View File

@ -26,12 +26,12 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="registry">The underlying mod registry.</param>
/// <param name="proxyFactory">Generates proxy classes to access mod APIs through an arbitrary interface.</param>
/// <param name="monitor">Encapsulates monitoring and logging for the mod.</param>
public ModRegistryHelper(string modID, ModRegistry registry, InterfaceProxyFactory proxyFactory, IMonitor monitor)
: base(modID)
public ModRegistryHelper(IModMetadata mod, ModRegistry registry, InterfaceProxyFactory proxyFactory, IMonitor monitor)
: base(mod)
{
this.Registry = registry;
this.ProxyFactory = proxyFactory;

View File

@ -18,10 +18,10 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="multiplayer">SMAPI's core multiplayer utility.</param>
public MultiplayerHelper(string modID, SMultiplayer multiplayer)
: base(modID)
public MultiplayerHelper(IModMetadata mod, SMultiplayer multiplayer)
: base(mod)
{
this.Multiplayer = multiplayer;
}

View File

@ -22,11 +22,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="modName">The mod name for error messages.</param>
/// <param name="reflector">The underlying reflection helper.</param>
public ReflectionHelper(string modID, string modName, Reflector reflector)
: base(modID)
public ReflectionHelper(IModMetadata mod, string modName, Reflector reflector)
: base(mod)
{
this.ModName = modName;
this.Reflector = reflector;

View File

@ -27,11 +27,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="mod">The mod using this instance.</param>
/// <param name="locale">The initial locale.</param>
/// <param name="languageCode">The game's current language code.</param>
public TranslationHelper(string modID, string locale, LocalizedContentManager.LanguageCode languageCode)
: base(modID)
public TranslationHelper(IModMetadata mod, string locale, LocalizedContentManager.LanguageCode languageCode)
: base(mod)
{
this.Translator = new Translator();
this.Translator.SetLocale(locale, languageCode);

View File

@ -1749,9 +1749,9 @@ namespace StardewModdingAPI.Framework
{
IMonitor monitor = this.LogManager.GetMonitor(mod.DisplayName);
CaseInsensitivePathCache relativePathCache = this.ContentCore.GetCaseInsensitivePathCache(mod.DirectoryPath);
GameContentHelper gameContentHelper = new(this.ContentCore, manifest.UniqueID, mod.DisplayName, monitor, this.Reflection);
IModContentHelper modContentHelper = new ModContentHelper(this.ContentCore, mod.DirectoryPath, manifest.UniqueID, mod.DisplayName, gameContentHelper.GetUnderlyingContentManager(), relativePathCache, this.Reflection);
TranslationHelper translationHelper = new(manifest.UniqueID, contentCore.GetLocale(), contentCore.Language);
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);
IContentPack contentPack = new ContentPack(mod.DirectoryPath, manifest, modContentHelper, translationHelper, jsonHelper, relativePathCache);
mod.SetMod(contentPack, monitor, translationHelper);
this.ModRegistry.Add(mod);
@ -1823,7 +1823,7 @@ namespace StardewModdingAPI.Framework
// init mod helpers
IMonitor monitor = this.LogManager.GetMonitor(mod.DisplayName);
TranslationHelper translationHelper = new(manifest.UniqueID, contentCore.GetLocale(), contentCore.Language);
TranslationHelper translationHelper = new(mod, contentCore.GetLocale(), contentCore.Language);
IModHelper modHelper;
{
IContentPack CreateFakeContentPack(string packDirPath, IManifest packManifest)
@ -1832,9 +1832,9 @@ namespace StardewModdingAPI.Framework
CaseInsensitivePathCache relativePathCache = this.ContentCore.GetCaseInsensitivePathCache(packDirPath);
GameContentHelper gameContentHelper = new(contentCore, packManifest.UniqueID, packManifest.Name, packMonitor, this.Reflection);
IModContentHelper packContentHelper = new ModContentHelper(contentCore, packDirPath, packManifest.UniqueID, packManifest.Name, gameContentHelper.GetUnderlyingContentManager(), relativePathCache, this.Reflection);
TranslationHelper packTranslationHelper = new(packManifest.UniqueID, contentCore.GetLocale(), contentCore.Language);
GameContentHelper gameContentHelper = new(contentCore, mod, packManifest.Name, packMonitor, this.Reflection);
IModContentHelper packContentHelper = new ModContentHelper(contentCore, packDirPath, mod, packManifest.Name, gameContentHelper.GetUnderlyingContentManager(), relativePathCache, this.Reflection);
TranslationHelper packTranslationHelper = new(mod, contentCore.GetLocale(), contentCore.Language);
ContentPack contentPack = new(packDirPath, packManifest, packContentHelper, packTranslationHelper, this.Toolkit.JsonHelper, relativePathCache);
this.ReloadTranslationsForTemporaryContentPack(mod, contentPack);
@ -1846,17 +1846,17 @@ namespace StardewModdingAPI.Framework
ICommandHelper commandHelper = new CommandHelper(mod, this.CommandManager);
CaseInsensitivePathCache relativePathCache = this.ContentCore.GetCaseInsensitivePathCache(mod.DirectoryPath);
#pragma warning disable CS0612 // deprecated code
ContentHelper contentHelper = new(contentCore, mod.DirectoryPath, manifest.UniqueID, mod.DisplayName, monitor, this.Reflection);
ContentHelper contentHelper = new(contentCore, mod.DirectoryPath, mod, mod.DisplayName, monitor, this.Reflection);
#pragma warning restore CS0612
GameContentHelper gameContentHelper = new(contentCore, manifest.UniqueID, mod.DisplayName, monitor, this.Reflection);
IModContentHelper modContentHelper = new ModContentHelper(contentCore, mod.DirectoryPath, manifest.UniqueID, mod.DisplayName, gameContentHelper.GetUnderlyingContentManager(), relativePathCache, this.Reflection);
IContentPackHelper contentPackHelper = new ContentPackHelper(manifest.UniqueID, new Lazy<IContentPack[]>(GetContentPacks), CreateFakeContentPack);
IDataHelper dataHelper = new DataHelper(manifest.UniqueID, mod.DirectoryPath, jsonHelper);
IReflectionHelper reflectionHelper = new ReflectionHelper(manifest.UniqueID, mod.DisplayName, this.Reflection);
IModRegistry modRegistryHelper = new ModRegistryHelper(manifest.UniqueID, this.ModRegistry, proxyFactory, monitor);
IMultiplayerHelper multiplayerHelper = new MultiplayerHelper(manifest.UniqueID, this.Multiplayer);
GameContentHelper gameContentHelper = new(contentCore, mod, mod.DisplayName, monitor, this.Reflection);
IModContentHelper modContentHelper = new ModContentHelper(contentCore, mod.DirectoryPath, mod, mod.DisplayName, gameContentHelper.GetUnderlyingContentManager(), relativePathCache, this.Reflection);
IContentPackHelper contentPackHelper = new ContentPackHelper(mod, new Lazy<IContentPack[]>(GetContentPacks), CreateFakeContentPack);
IDataHelper dataHelper = new DataHelper(mod, mod.DirectoryPath, jsonHelper);
IReflectionHelper reflectionHelper = new ReflectionHelper(mod, mod.DisplayName, this.Reflection);
IModRegistry modRegistryHelper = new ModRegistryHelper(mod, this.ModRegistry, proxyFactory, monitor);
IMultiplayerHelper multiplayerHelper = new MultiplayerHelper(mod, this.Multiplayer);
modHelper = new ModHelper(manifest.UniqueID, mod.DirectoryPath, () => this.GetCurrentGameInstance().Input, events, contentHelper, gameContentHelper, modContentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper);
modHelper = new ModHelper(mod, mod.DirectoryPath, () => this.GetCurrentGameInstance().Input, events, contentHelper, gameContentHelper, modContentHelper, contentPackHelper, commandHelper, dataHelper, modRegistryHelper, reflectionHelper, multiplayerHelper, translationHelper);
}
// init mod