summaryrefslogtreecommitdiff
path: root/src/SMAPI
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI')
-rw-r--r--src/SMAPI/Constants.cs2
-rw-r--r--src/SMAPI/Events/EventArgsInput.cs8
-rw-r--r--src/SMAPI/Events/GameEvents.cs10
-rw-r--r--src/SMAPI/Framework/Content/ContentCache.cs4
-rw-r--r--src/SMAPI/Framework/DeprecationManager.cs6
-rw-r--r--src/SMAPI/Framework/IModMetadata.cs7
-rw-r--r--src/SMAPI/Framework/InternalExtensions.cs11
-rw-r--r--src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs67
-rw-r--r--src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs167
-rw-r--r--src/SMAPI/Framework/ModLoading/ModMetadata.cs11
-rw-r--r--src/SMAPI/Framework/ModRegistry.cs62
-rw-r--r--src/SMAPI/Framework/Reflection/InterfaceProxyBuilder.cs138
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedField.cs (renamed from src/SMAPI/Framework/Reflection/PrivateField.cs)16
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedMethod.cs (renamed from src/SMAPI/Framework/Reflection/PrivateMethod.cs)16
-rw-r--r--src/SMAPI/Framework/Reflection/ReflectedProperty.cs (renamed from src/SMAPI/Framework/Reflection/PrivateProperty.cs)42
-rw-r--r--src/SMAPI/Framework/Reflection/Reflector.cs106
-rw-r--r--src/SMAPI/Framework/SContentManager.cs10
-rw-r--r--src/SMAPI/Framework/SGame.cs103
-rw-r--r--src/SMAPI/IMod.cs7
-rw-r--r--src/SMAPI/IModRegistry.cs13
-rw-r--r--src/SMAPI/IPrivateField.cs6
-rw-r--r--src/SMAPI/IPrivateMethod.cs6
-rw-r--r--src/SMAPI/IPrivateProperty.cs6
-rw-r--r--src/SMAPI/IReflectedField.cs26
-rw-r--r--src/SMAPI/IReflectedMethod.cs27
-rw-r--r--src/SMAPI/IReflectedProperty.cs26
-rw-r--r--src/SMAPI/IReflectionHelper.cs55
-rw-r--r--src/SMAPI/Metadata/InstructionMetadata.cs1
-rw-r--r--src/SMAPI/Mod.cs3
-rw-r--r--src/SMAPI/Program.cs272
-rw-r--r--src/SMAPI/StardewModdingAPI.config.json10
-rw-r--r--src/SMAPI/StardewModdingAPI.csproj14
32 files changed, 873 insertions, 385 deletions
diff --git a/src/SMAPI/Constants.cs b/src/SMAPI/Constants.cs
index 41b79272..786ae32b 100644
--- a/src/SMAPI/Constants.cs
+++ b/src/SMAPI/Constants.cs
@@ -29,7 +29,7 @@ namespace StardewModdingAPI
** Public
****/
/// <summary>SMAPI's current semantic version.</summary>
- public static ISemanticVersion ApiVersion { get; } = new SemanticVersion("2.2");
+ public static ISemanticVersion ApiVersion { get; } = new SemanticVersion("2.3");
/// <summary>The minimum supported version of Stardew Valley.</summary>
public static ISemanticVersion MinimumGameVersion { get; } = new SemanticVersion("1.2.30");
diff --git a/src/SMAPI/Events/EventArgsInput.cs b/src/SMAPI/Events/EventArgsInput.cs
index 54ce9b53..a5325b76 100644
--- a/src/SMAPI/Events/EventArgsInput.cs
+++ b/src/SMAPI/Events/EventArgsInput.cs
@@ -16,7 +16,7 @@ namespace StardewModdingAPI.Events
public SButton Button { get; }
/// <summary>The current cursor position.</summary>
- public ICursorPosition Cursor { get; set; }
+ public ICursorPosition Cursor { get; }
/// <summary>Whether the input is considered a 'click' by the game for enabling action.</summary>
[Obsolete("Use " + nameof(EventArgsInput.IsActionButton) + " or " + nameof(EventArgsInput.IsUseToolButton) + " instead")] // deprecated in SMAPI 2.1
@@ -28,6 +28,9 @@ namespace StardewModdingAPI.Events
/// <summary>Whether the input should use tools on the affected tile.</summary>
public bool IsUseToolButton { get; }
+ /// <summary>Whether a mod has indicated the key was already handled.</summary>
+ public bool IsSuppressed { get; private set; }
+
/*********
** Public methods
@@ -55,6 +58,9 @@ namespace StardewModdingAPI.Events
/// <param name="button">The button to suppress.</param>
public void SuppressButton(SButton button)
{
+ if (button == this.Button)
+ this.IsSuppressed = true;
+
// keyboard
if (button.TryGetKeyboard(out Keys key))
Game1.oldKBState = new KeyboardState(Game1.oldKBState.GetPressedKeys().Union(new[] { key }).ToArray());
diff --git a/src/SMAPI/Events/GameEvents.cs b/src/SMAPI/Events/GameEvents.cs
index b477376e..3466470d 100644
--- a/src/SMAPI/Events/GameEvents.cs
+++ b/src/SMAPI/Events/GameEvents.cs
@@ -33,6 +33,9 @@ namespace StardewModdingAPI.Events
/// <summary>Raised every 60th tick (≈once per second).</summary>
public static event EventHandler OneSecondTick;
+ /// <summary>Raised once after the game initialises and all <see cref="IMod.Entry"/> methods have been called.</summary>
+ public static event EventHandler FirstUpdateTick;
+
/*********
** Internal methods
@@ -92,5 +95,12 @@ namespace StardewModdingAPI.Events
{
monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.OneSecondTick)}", GameEvents.OneSecondTick?.GetInvocationList());
}
+
+ /// <summary>Raise a <see cref="FirstUpdateTick"/> event.</summary>
+ /// <param name="monitor">Encapsulates monitoring and logging.</param>
+ internal static void InvokeFirstUpdateTick(IMonitor monitor)
+ {
+ monitor.SafelyRaisePlainEvent($"{nameof(GameEvents)}.{nameof(GameEvents.FirstUpdateTick)}", GameEvents.FirstUpdateTick?.GetInvocationList());
+ }
}
}
diff --git a/src/SMAPI/Framework/Content/ContentCache.cs b/src/SMAPI/Framework/Content/ContentCache.cs
index 10c41d08..4508e641 100644
--- a/src/SMAPI/Framework/Content/ContentCache.cs
+++ b/src/SMAPI/Framework/Content/ContentCache.cs
@@ -57,14 +57,14 @@ namespace StardewModdingAPI.Framework.Content
public ContentCache(LocalizedContentManager contentManager, Reflector reflection, char[] possiblePathSeparators, string preferredPathSeparator)
{
// init
- this.Cache = reflection.GetPrivateField<Dictionary<string, object>>(contentManager, "loadedAssets").GetValue();
+ this.Cache = reflection.GetField<Dictionary<string, object>>(contentManager, "loadedAssets").GetValue();
this.PossiblePathSeparators = possiblePathSeparators;
this.PreferredPathSeparator = preferredPathSeparator;
// get key normalisation logic
if (Constants.TargetPlatform == Platform.Windows)
{
- IPrivateMethod method = reflection.GetPrivateMethod(typeof(TitleContainer), "GetCleanPath");
+ IReflectedMethod method = reflection.GetMethod(typeof(TitleContainer), "GetCleanPath");
this.NormaliseAssetNameForPlatform = path => method.Invoke<string>(path);
}
else
diff --git a/src/SMAPI/Framework/DeprecationManager.cs b/src/SMAPI/Framework/DeprecationManager.cs
index b07c6c7d..7a824a05 100644
--- a/src/SMAPI/Framework/DeprecationManager.cs
+++ b/src/SMAPI/Framework/DeprecationManager.cs
@@ -37,7 +37,7 @@ namespace StardewModdingAPI.Framework
/// <param name="severity">How deprecated the code is.</param>
public void Warn(string nounPhrase, string version, DeprecationLevel severity)
{
- this.Warn(this.ModRegistry.GetModFromStack(), nounPhrase, version, severity);
+ this.Warn(this.ModRegistry.GetFromStack()?.DisplayName, nounPhrase, version, severity);
}
/// <summary>Log a deprecation warning.</summary>
@@ -52,7 +52,7 @@ namespace StardewModdingAPI.Framework
return;
// build message
- string message = $"{source ?? "An unknown mod"} uses deprecated code ({nounPhrase}).";
+ string message = $"{source ?? "An unknown mod"} uses deprecated code ({nounPhrase} is deprecated since SMAPI {version}).";
if (source == null)
message += $"{Environment.NewLine}{Environment.StackTrace}";
@@ -82,7 +82,7 @@ namespace StardewModdingAPI.Framework
/// <returns>Returns whether the deprecation was successfully marked as warned. Returns <c>false</c> if it was already marked.</returns>
public bool MarkWarned(string nounPhrase, string version)
{
- return this.MarkWarned(this.ModRegistry.GetModFromStack(), nounPhrase, version);
+ return this.MarkWarned(this.ModRegistry.GetFromStack()?.DisplayName, nounPhrase, version);
}
/// <summary>Mark a deprecation warning as already logged.</summary>
diff --git a/src/SMAPI/Framework/IModMetadata.cs b/src/SMAPI/Framework/IModMetadata.cs
index c21734a7..a36994fd 100644
--- a/src/SMAPI/Framework/IModMetadata.cs
+++ b/src/SMAPI/Framework/IModMetadata.cs
@@ -30,6 +30,9 @@ namespace StardewModdingAPI.Framework
/// <summary>The mod instance (if it was loaded).</summary>
IMod Mod { get; }
+ /// <summary>The mod-provided API (if any).</summary>
+ object Api { get; }
+
/*********
** Public methods
@@ -43,5 +46,9 @@ namespace StardewModdingAPI.Framework
/// <summary>Set the mod instance.</summary>
/// <param name="mod">The mod instance to set.</param>
IModMetadata SetMod(IMod mod);
+
+ /// <summary>Set the mod-provided API instance.</summary>
+ /// <param name="api">The mod-provided API.</param>
+ IModMetadata SetApi(object api);
}
}
diff --git a/src/SMAPI/Framework/InternalExtensions.cs b/src/SMAPI/Framework/InternalExtensions.cs
index 3709e05d..bec6c183 100644
--- a/src/SMAPI/Framework/InternalExtensions.cs
+++ b/src/SMAPI/Framework/InternalExtensions.cs
@@ -108,6 +108,15 @@ namespace StardewModdingAPI.Framework
}
}
+ /// <summary>Get the lowest exception in an exception stack.</summary>
+ /// <param name="exception">The exception from which to search.</param>
+ public static Exception GetInnermostException(this Exception exception)
+ {
+ while (exception.InnerException != null)
+ exception = exception.InnerException;
+ return exception;
+ }
+
/****
** Sprite batch
****/
@@ -125,7 +134,7 @@ namespace StardewModdingAPI.Framework
#endif
// get result
- return reflection.GetPrivateField<bool>(Game1.spriteBatch, fieldName).GetValue();
+ return reflection.GetField<bool>(Game1.spriteBatch, fieldName).GetValue();
}
}
}
diff --git a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs
index 9e824694..ea0dbb38 100644
--- a/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ModRegistryHelper.cs
@@ -1,4 +1,6 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
+using System.Linq;
+using StardewModdingAPI.Framework.Reflection;
namespace StardewModdingAPI.Framework.ModHelpers
{
@@ -11,6 +13,15 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>The underlying mod registry.</summary>
private readonly ModRegistry Registry;
+ /// <summary>Encapsulates monitoring and logging for the mod.</summary>
+ private readonly IMonitor Monitor;
+
+ /// <summary>The mod IDs for APIs accessed by this instanced.</summary>
+ private readonly HashSet<string> AccessedModApis = new HashSet<string>();
+
+ /// <summary>Generates proxy classes to access mod APIs through an arbitrary interface.</summary>
+ private readonly InterfaceProxyBuilder ProxyBuilder;
+
/*********
** Public methods
@@ -18,16 +29,20 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>Construct an instance.</summary>
/// <param name="modID">The unique ID of the relevant mod.</param>
/// <param name="registry">The underlying mod registry.</param>
- public ModRegistryHelper(string modID, ModRegistry registry)
+ /// <param name="proxyBuilder">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, InterfaceProxyBuilder proxyBuilder, IMonitor monitor)
: base(modID)
{
this.Registry = registry;
+ this.ProxyBuilder = proxyBuilder;
+ this.Monitor = monitor;
}
/// <summary>Get metadata for all loaded mods.</summary>
public IEnumerable<IManifest> GetAll()
{
- return this.Registry.GetAll();
+ return this.Registry.GetAll().Select(p => p.Manifest);
}
/// <summary>Get metadata for a loaded mod.</summary>
@@ -35,14 +50,56 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <returns>Returns the matching mod's metadata, or <c>null</c> if not found.</returns>
public IManifest Get(string uniqueID)
{
- return this.Registry.Get(uniqueID);
+ return this.Registry.Get(uniqueID)?.Manifest;
}
/// <summary>Get whether a mod has been loaded.</summary>
/// <param name="uniqueID">The mod's unique ID.</param>
public bool IsLoaded(string uniqueID)
{
- return this.Registry.IsLoaded(uniqueID);
+ return this.Registry.Get(uniqueID) != null;
+ }
+
+ /// <summary>Get the API provided by a mod, or <c>null</c> if it has none. This signature requires using the <see cref="IModHelper.Reflection"/> API to access the API's properties and methods.</summary>
+ public object GetApi(string uniqueID)
+ {
+ IModMetadata mod = this.Registry.Get(uniqueID);
+ if (mod?.Api != null && this.AccessedModApis.Add(mod.Manifest.UniqueID))
+ this.Monitor.Log($"Accessed mod-provided API for {mod.DisplayName}.", LogLevel.Trace);
+ return mod?.Api;
+ }
+
+ /// <summary>Get the API provided by a mod, mapped to a given interface which specifies the expected properties and methods. If the mod has no API or it's not compatible with the given interface, get <c>null</c>.</summary>
+ /// <typeparam name="TInterface">The interface which matches the properties and methods you intend to access.</typeparam>
+ /// <param name="uniqueID">The mod's unique ID.</param>
+ public TInterface GetApi<TInterface>(string uniqueID) where TInterface : class
+ {
+ // validate
+ if (!this.Registry.AreAllModsInitialised)
+ {
+ this.Monitor.Log("Tried to access a mod-provided API before all mods were initialised.", LogLevel.Error);
+ return null;
+ }
+ if (!typeof(TInterface).IsInterface)
+ {
+ this.Monitor.Log("Tried to map a mod-provided API to a class; must be a public interface.", LogLevel.Error);
+ return null;
+ }
+ if (!typeof(TInterface).IsPublic)
+ {
+ this.Monitor.Log("Tried to map a mod-provided API to a non-public interface; must be a public interface.", LogLevel.Error);
+ return null;
+ }
+
+ // get raw API
+ object api = this.GetApi(uniqueID);
+ if (api == null)
+ return null;
+
+ // get API of type
+ if (api is TInterface castApi)
+ return castApi;
+ return this.ProxyBuilder.CreateProxy<TInterface>(api, this.ModID, uniqueID);
}
}
}
diff --git a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
index 8788b142..81453003 100644
--- a/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
+++ b/src/SMAPI/Framework/ModHelpers/ReflectionHelper.cs
@@ -17,6 +17,9 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>The mod name for error messages.</summary>
private readonly string ModName;
+ /// <summary>Manages deprecation warnings.</summary>
+ private readonly DeprecationManager DeprecationManager;
+
/*********
** Public methods
@@ -25,15 +28,88 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="modID">The unique ID of the relevant mod.</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)
+ /// <param name="deprecationManager">Manages deprecation warnings.</param>
+ public ReflectionHelper(string modID, string modName, Reflector reflector, DeprecationManager deprecationManager)
: base(modID)
{
this.ModName = modName;
this.Reflector = reflector;
+ this.DeprecationManager = deprecationManager;
+ }
+
+ /// <summary>Get an instance field.</summary>
+ /// <typeparam name="TValue">The field type.</typeparam>
+ /// <param name="obj">The object which has the field.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedField<TValue> GetField<TValue>(object obj, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetField<TValue>(obj, name, required)
+ );
+ }
+
+ /// <summary>Get a static field.</summary>
+ /// <typeparam name="TValue">The field type.</typeparam>
+ /// <param name="type">The type which has the field.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedField<TValue> GetField<TValue>(Type type, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetField<TValue>(type, name, required)
+ );
+ }
+
+ /// <summary>Get an instance property.</summary>
+ /// <typeparam name="TValue">The property type.</typeparam>
+ /// <param name="obj">The object which has the property.</param>
+ /// <param name="name">The property name.</param>
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ public IReflectedProperty<TValue> GetProperty<TValue>(object obj, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetProperty<TValue>(obj, name, required)
+ );
+ }
+
+ /// <summary>Get a static property.</summary>
+ /// <typeparam name="TValue">The property type.</typeparam>
+ /// <param name="type">The type which has the property.</param>
+ /// <param name="name">The property name.</param>
+ /// <param name="required">Whether to throw an exception if the property is not found.</param>
+ public IReflectedProperty<TValue> GetProperty<TValue>(Type type, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetProperty<TValue>(type, name, required)
+ );
+ }
+
+ /// <summary>Get an instance method.</summary>
+ /// <param name="obj">The object which has the method.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(object obj, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetMethod(obj, name, required)
+ );
+ }
+
+ /// <summary>Get a static method.</summary>
+ /// <param name="type">The type which has the method.</param>
+ /// <param name="name">The field name.</param>
+ /// <param name="required">Whether to throw an exception if the field is not found.</param>
+ public IReflectedMethod GetMethod(Type type, string name, bool required = true)
+ {
+ return this.AssertAccessAllowed(
+ this.Reflector.GetMethod(type, name, required)
+ );
}
+
/****
- ** Fields
+ ** Obsolete
****/
/// <summary>Get a private instance field.</summary>
/// <typeparam name="TValue">The field type.</typeparam>
@@ -41,11 +117,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
/// <returns>Returns the field wrapper, or <c>null</c> if the field doesn't exist and <paramref name="required"/> is <c>false</c>.</returns>
+ [Obsolete]
public IPrivateField<TValue> GetPrivateField<TValue>(object obj, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateField<TValue>(obj, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateField<TValue>)this.GetField<TValue>(obj, name, required);
}
/// <summary>Get a private static field.</summary>
@@ -53,26 +129,23 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="type">The type which has the field.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete]
public IPrivateField<TValue> GetPrivateField<TValue>(Type type, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateField<TValue>(type, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateField<TValue>)this.GetField<TValue>(type, name, required);
}
- /****
- ** Properties
- ****/
/// <summary>Get a private instance property.</summary>
/// <typeparam name="TValue">The property type.</typeparam>
/// <param name="obj">The object which has the property.</param>
/// <param name="name">The property name.</param>
/// <param name="required">Whether to throw an exception if the private property is not found.</param>
+ [Obsolete]
public IPrivateProperty<TValue> GetPrivateProperty<TValue>(object obj, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateProperty<TValue>(obj, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateProperty<TValue>)this.GetProperty<TValue>(obj, name, required);
}
/// <summary>Get a private static property.</summary>
@@ -80,17 +153,13 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <param name="type">The type which has the property.</param>
/// <param name="name">The property name.</param>
/// <param name="required">Whether to throw an exception if the private property is not found.</param>
+ [Obsolete]
public IPrivateProperty<TValue> GetPrivateProperty<TValue>(Type type, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateProperty<TValue>(type, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateProperty<TValue>)this.GetProperty<TValue>(type, name, required);
}
- /****
- ** Field values
- ** (shorthand since this is the most common case)
- ****/
/// <summary>Get the value of a private instance field.</summary>
/// <typeparam name="TValue">The field type.</typeparam>
/// <param name="obj">The object which has the field.</param>
@@ -101,9 +170,11 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// This is a shortcut for <see cref="GetPrivateField{TValue}(object,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
/// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(object,string,bool)" /> instead.
/// </remarks>
+ [Obsolete]
public TValue GetPrivateValue<TValue>(object obj, string name, bool required = true)
{
- IPrivateField<TValue> field = this.GetPrivateField<TValue>(obj, name, required);
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ IPrivateField<TValue> field = (IPrivateField<TValue>)this.GetField<TValue>(obj, name, required);
return field != null
? field.GetValue()
: default(TValue);
@@ -119,64 +190,36 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// This is a shortcut for <see cref="GetPrivateField{TValue}(Type,string,bool)"/> followed by <see cref="IPrivateField{TValue}.GetValue"/>.
/// When <paramref name="required" /> is false, this will return the default value if reflection fails. If you need to check whether the field exists, use <see cref="GetPrivateField{TValue}(Type,string,bool)" /> instead.
/// </remarks>
+ [Obsolete]
public TValue GetPrivateValue<TValue>(Type type, string name, bool required = true)
{
- IPrivateField<TValue> field = this.GetPrivateField<TValue>(type, name, required);
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ IPrivateField<TValue> field = (IPrivateField<TValue>)this.GetField<TValue>(type, name, required);
return field != null
? field.GetValue()
: default(TValue);
}
- /****
- ** Methods
- ****/
/// <summary>Get a private instance method.</summary>
/// <param name="obj">The object which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete]
public IPrivateMethod GetPrivateMethod(object obj, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(obj, name, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateMethod)this.GetMethod(obj, name, required);
}
/// <summary>Get a private static method.</summary>
/// <param name="type">The type which has the method.</param>
/// <param name="name">The field name.</param>
/// <param name="required">Whether to throw an exception if the private field is not found.</param>
+ [Obsolete]
public IPrivateMethod GetPrivateMethod(Type type, string name, bool required = true)
{
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(type, name, required)
- );
- }
-
- /****
- ** Methods by signature
- ****/
- /// <summary>Get a private instance method.</summary>
- /// <param name="obj">The object which has the method.</param>
- /// <param name="name">The field name.</param>
- /// <param name="argumentTypes">The argument types of the method signature to find.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(object obj, string name, Type[] argumentTypes, bool required = true)
- {
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(obj, name, argumentTypes, required)
- );
- }
-
- /// <summary>Get a private static method.</summary>
- /// <param name="type">The type which has the method.</param>
- /// <param name="name">The field name.</param>
- /// <param name="argumentTypes">The argument types of the method signature to find.</param>
- /// <param name="required">Whether to throw an exception if the private field is not found.</param>
- public IPrivateMethod GetPrivateMethod(Type type, string name, Type[] argumentTypes, bool required = true)
- {
- return this.AssertAccessAllowed(
- this.Reflector.GetPrivateMethod(type, name, argumentTypes, required)
- );
+ this.DeprecationManager.Warn($"{nameof(IReflectionHelper)}.GetPrivate*", "2.3", DeprecationLevel.Notice);
+ return (IPrivateMethod)this.GetMethod(type, name, required);
}
@@ -187,7 +230,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <typeparam name="T">The field value type.</typeparam>
/// <param name="field">The field being accessed.</param>
/// <returns>Returns the same field instance for convenience.</returns>
- private IPrivateField<T> AssertAccessAllowed<T>(IPrivateField<T> field)
+ private IReflectedField<T> AssertAccessAllowed<T>(IReflectedField<T> field)
{
this.AssertAccessAllowed(field?.FieldInfo);
return field;
@@ -197,7 +240,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <typeparam name="T">The property value type.</typeparam>
/// <param name="property">The property being accessed.</param>
/// <returns>Returns the same property instance for convenience.</returns>
- private IPrivateProperty<T> AssertAccessAllowed<T>(IPrivateProperty<T> property)
+ private IReflectedProperty<T> AssertAccessAllowed<T>(IReflectedProperty<T> property)
{
this.AssertAccessAllowed(property?.PropertyInfo);
return property;
@@ -206,7 +249,7 @@ namespace StardewModdingAPI.Framework.ModHelpers
/// <summary>Assert that mods can use the reflection helper to access the given member.</summary>
/// <param name="method">The method being accessed.</param>
/// <returns>Returns the same method instance for convenience.</returns>
- private IPrivateMethod AssertAccessAllowed(IPrivateMethod method)
+ private IReflectedMethod AssertAccessAllowed(IReflectedMethod method)
{
this.AssertAccessAllowed(method?.MethodInfo);
return method;
diff --git a/src/SMAPI/Framework/ModLoading/ModMetadata.cs b/src/SMAPI/Framework/ModLoading/ModMetadata.cs
index 5055da75..30fe211b 100644
--- a/src/SMAPI/Framework/ModLoading/ModMetadata.cs
+++ b/src/SMAPI/Framework/ModLoading/ModMetadata.cs
@@ -29,6 +29,9 @@ namespace StardewModdingAPI.Framework.ModLoading
/// <summary>The mod instance (if it was loaded).</summary>
public IMod Mod { get; private set; }