add simple Harmony wrapper for validation, error-handling, etc (#541)

This commit is contained in:
Jesse Plamondon-Willard 2018-06-06 21:45:03 -04:00
parent 9e525533e1
commit cd62dcc8cf
5 changed files with 71 additions and 8 deletions

View File

@ -103,6 +103,9 @@ namespace StardewModdingAPI
/// <summary>The target game platform.</summary> /// <summary>The target game platform.</summary>
internal static Platform Platform { get; } = EnvironmentUtility.DetectPlatform(); internal static Platform Platform { get; } = EnvironmentUtility.DetectPlatform();
/// <summary>The game's assembly name.</summary>
internal static string GameAssemblyName => Constants.Platform == Platform.Windows ? "Stardew Valley" : "StardewValley";
/********* /*********
** Internal methods ** Internal methods

View File

@ -0,0 +1,45 @@
using System;
using Harmony;
namespace StardewModdingAPI.Framework.Patching
{
/// <summary>Encapsulates applying Harmony patches to the game.</summary>
internal class GamePatcher
{
/*********
** Properties
*********/
/// <summary>Encapsulates monitoring and logging.</summary>
private readonly IMonitor Monitor;
/*********
** Public methods
*********/
/// <summary>Construct an instance.</summary>
/// <param name="monitor">Encapsulates monitoring and logging.</param>
public GamePatcher(IMonitor monitor)
{
this.Monitor = monitor;
}
/// <summary>Apply all loaded patches to the game.</summary>
/// <param name="patches">The patches to apply.</param>
public void Apply(params IHarmonyPatch[] patches)
{
HarmonyInstance harmony = HarmonyInstance.Create("io.smapi");
foreach (IHarmonyPatch patch in patches)
{
try
{
patch.Apply(harmony);
}
catch (Exception ex)
{
this.Monitor.Log($"Couldn't apply runtime patch '{patch.Name}' to the game. Some SMAPI features may not work correctly. See log file for details.", LogLevel.Error);
this.Monitor.Log(ex.GetLogSummary(), LogLevel.Trace);
}
}
}
}
}

View File

@ -0,0 +1,15 @@
using Harmony;
namespace StardewModdingAPI.Framework.Patching
{
/// <summary>A Harmony patch to apply.</summary>
internal interface IHarmonyPatch
{
/// <summary>A unique name for this patch.</summary>
string Name { get; }
/// <summary>Apply the Harmony patch.</summary>
/// <param name="harmony">The Harmony instance.</param>
void Apply(HarmonyInstance harmony);
}
}

View File

@ -24,6 +24,7 @@ using StardewModdingAPI.Framework.ModData;
using StardewModdingAPI.Framework.Models; using StardewModdingAPI.Framework.Models;
using StardewModdingAPI.Framework.ModHelpers; using StardewModdingAPI.Framework.ModHelpers;
using StardewModdingAPI.Framework.ModLoading; using StardewModdingAPI.Framework.ModLoading;
using StardewModdingAPI.Framework.Patching;
using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Framework.Serialisation; using StardewModdingAPI.Framework.Serialisation;
using StardewModdingAPI.Internal; using StardewModdingAPI.Internal;
@ -152,6 +153,10 @@ namespace StardewModdingAPI
}; };
this.EventManager = new EventManager(this.Monitor, this.ModRegistry); this.EventManager = new EventManager(this.Monitor, this.ModRegistry);
// apply game patches
new GamePatcher(this.Monitor).Apply(
);
// init JSON parser // init JSON parser
JsonConverter[] converters = { JsonConverter[] converters = {
new StringEnumConverter<Buttons>(), new StringEnumConverter<Buttons>(),
@ -359,14 +364,7 @@ namespace StardewModdingAPI
Console.ResetColor(); Console.ResetColor();
Program.PressAnyKeyToExit(showMessage: true); Program.PressAnyKeyToExit(showMessage: true);
} }
string gameAssemblyName = Constants.GameAssemblyName;
// get game assembly name
const string gameAssemblyName =
#if SMAPI_FOR_WINDOWS
"Stardew Valley";
#else
"StardewValley";
#endif
// game not present // game not present
if (Type.GetType($"StardewValley.Game1, {gameAssemblyName}", throwOnError: false) == null) if (Type.GetType($"StardewValley.Game1, {gameAssemblyName}", throwOnError: false) == null)

View File

@ -107,6 +107,8 @@
<Compile Include="Framework\ContentManagers\GameContentManager.cs" /> <Compile Include="Framework\ContentManagers\GameContentManager.cs" />
<Compile Include="Framework\ContentManagers\IContentManager.cs" /> <Compile Include="Framework\ContentManagers\IContentManager.cs" />
<Compile Include="Framework\ContentManagers\ModContentManager.cs" /> <Compile Include="Framework\ContentManagers\ModContentManager.cs" />
<Compile Include="Framework\Patching\GamePatcher.cs" />
<Compile Include="Framework\Patching\IHarmonyPatch.cs" />
<Compile Include="Framework\Serialisation\ColorConverter.cs" /> <Compile Include="Framework\Serialisation\ColorConverter.cs" />
<Compile Include="Framework\Serialisation\PointConverter.cs" /> <Compile Include="Framework\Serialisation\PointConverter.cs" />
<Compile Include="Framework\Serialisation\RectangleConverter.cs" /> <Compile Include="Framework\Serialisation\RectangleConverter.cs" />