summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/SMAPI.Installer/InteractiveInstaller.cs3
-rw-r--r--src/SMAPI.Internal.Patching/BasePatcher.cs54
-rw-r--r--src/SMAPI.Internal.Patching/HarmonyPatcher.cs36
-rw-r--r--src/SMAPI.Internal.Patching/IPatcher.cs16
-rw-r--r--src/SMAPI.Internal.Patching/PatchHelper.cs77
-rw-r--r--src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.projitems17
-rw-r--r--src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.shproj13
-rw-r--r--src/SMAPI.Internal/ExceptionExtensions.cs41
-rw-r--r--src/SMAPI.Internal/SMAPI.Internal.projitems1
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs10
-rw-r--r--src/SMAPI.Mods.ConsoleCommands/manifest.json4
-rw-r--r--src/SMAPI.Mods.ErrorHandler/ModEntry.cs40
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/DialogueErrorPatch.cs184
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/DialoguePatcher.cs75
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/DictionaryPatcher.cs75
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/EventPatcher.cs (renamed from src/SMAPI.Mods.ErrorHandler/Patches/EventPatches.cs)26
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatcher.cs79
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs158
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/IClickableMenuPatcher.cs44
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/LoadErrorPatch.cs150
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/NpcPatcher.cs85
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/ObjectErrorPatch.cs136
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/ObjectPatcher.cs71
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs145
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/ScheduleErrorPatch.cs108
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs (renamed from src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchValidationPatches.cs)30
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/UtilityErrorPatches.cs89
-rw-r--r--src/SMAPI.Mods.ErrorHandler/Patches/UtilityPatcher.cs43
-rw-r--r--src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj2
-rw-r--r--src/SMAPI.Mods.ErrorHandler/manifest.json4
-rw-r--r--src/SMAPI.Mods.SaveBackup/manifest.json4
-rw-r--r--src/SMAPI.Toolkit/Framework/LowLevelEnvironmentUtility.cs9
-rw-r--r--src/SMAPI.Toolkit/SMAPI.Toolkit.csproj2
-rw-r--r--src/SMAPI.sln6
-rw-r--r--src/SMAPI.sln.DotSettings2
-rw-r--r--src/SMAPI/Constants.cs15
-rw-r--r--src/SMAPI/Framework/Commands/HarmonySummaryCommand.cs26
-rw-r--r--src/SMAPI/Framework/Content/AssetInterceptorChange.cs1
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs1
-rw-r--r--src/SMAPI/Framework/ContentManagers/ModContentManager.cs5
-rw-r--r--src/SMAPI/Framework/Events/ManagedEvent.cs1
-rw-r--r--src/SMAPI/Framework/InternalExtensions.cs35
-rw-r--r--src/SMAPI/Framework/Logging/LogManager.cs8
-rw-r--r--src/SMAPI/Framework/ModLoading/RewriteFacades/AccessToolsFacade.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyInstanceFacade.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/RewriteFacades/HarmonyMethodFacade.cs2
-rw-r--r--src/SMAPI/Framework/ModLoading/Rewriters/Harmony1AssemblyRewriter.cs65
-rw-r--r--src/SMAPI/Framework/Patching/GamePatcher.cs53
-rw-r--r--src/SMAPI/Framework/Patching/IHarmonyPatch.cs23
-rw-r--r--src/SMAPI/Framework/Patching/PatchHelper.cs36
-rw-r--r--src/SMAPI/Framework/Reflection/InterfaceProxyFactory.cs33
-rw-r--r--src/SMAPI/Framework/SCore.cs19
-rw-r--r--src/SMAPI/Framework/SGame.cs1
-rw-r--r--src/SMAPI/Framework/TemporaryHacks/MiniMonoModHotfix.cs239
-rw-r--r--src/SMAPI/Metadata/CoreAssetPropagator.cs17
-rw-r--r--src/SMAPI/Metadata/InstructionMetadata.cs8
-rw-r--r--src/SMAPI/Patches/Game1Patcher.cs (renamed from src/SMAPI/Patches/LoadContextPatch.cs)83
-rw-r--r--src/SMAPI/Patches/TitleMenuPatcher.cs55
-rw-r--r--src/SMAPI/Program.cs32
-rw-r--r--src/SMAPI/Properties/AssemblyInfo.cs1
-rw-r--r--src/SMAPI/SMAPI.csproj4
61 files changed, 1415 insertions, 1191 deletions
diff --git a/src/SMAPI.Installer/InteractiveInstaller.cs b/src/SMAPI.Installer/InteractiveInstaller.cs
index 55e9c064..ab07c864 100644
--- a/src/SMAPI.Installer/InteractiveInstaller.cs
+++ b/src/SMAPI.Installer/InteractiveInstaller.cs
@@ -9,6 +9,7 @@ using StardewModdingApi.Installer.Enums;
using StardewModdingAPI.Installer.Framework;
using StardewModdingAPI.Internal.ConsoleWriting;
using StardewModdingAPI.Toolkit;
+using StardewModdingAPI.Toolkit.Framework;
using StardewModdingAPI.Toolkit.Framework.ModScanning;
using StardewModdingAPI.Toolkit.Utilities;
@@ -571,7 +572,7 @@ namespace StardewModdingApi.Installer
/// <param name="executablePath">The absolute path to the executable file.</param>
private bool Is64Bit(string executablePath)
{
- return AssemblyName.GetAssemblyName(executablePath).ProcessorArchitecture != ProcessorArchitecture.X86;
+ return LowLevelEnvironmentUtility.Is64BitAssembly(executablePath);
}
/// <summary>Get the display text for a color scheme.</summary>
diff --git a/src/SMAPI.Internal.Patching/BasePatcher.cs b/src/SMAPI.Internal.Patching/BasePatcher.cs
new file mode 100644
index 00000000..87155d7f
--- /dev/null
+++ b/src/SMAPI.Internal.Patching/BasePatcher.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Reflection;
+using HarmonyLib;
+
+namespace StardewModdingAPI.Internal.Patching
+{
+ /// <summary>Provides base implementation logic for <see cref="IPatcher"/> instances.</summary>
+ internal abstract class BasePatcher : IPatcher
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <inheritdoc />
+ public abstract void Apply(Harmony harmony, IMonitor monitor);
+
+
+ /*********
+ ** Protected methods
+ *********/
+ /// <summary>Get a method and assert that it was found.</summary>
+ /// <typeparam name="TTarget">The type containing the method.</typeparam>
+ /// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
+ protected ConstructorInfo RequireConstructor<TTarget>(params Type[] parameters)
+ {
+ return PatchHelper.RequireConstructor<TTarget>(parameters);
+ }
+
+ /// <summary>Get a method and assert that it was found.</summary>
+ /// <typeparam name="TTarget">The type containing the method.</typeparam>
+ /// <param name="name">The method name.</param>
+ /// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
+ /// <param name="generics">The method generic types, or <c>null</c> if it's not generic.</param>
+ protected MethodInfo RequireMethod<TTarget>(string name, Type[] parameters = null, Type[] generics = null)
+ {
+ return PatchHelper.RequireMethod<TTarget>(name, parameters, generics);
+ }
+
+ /// <summary>Get a Harmony patch method on the current patcher instance.</summary>
+ /// <param name="name">The method name.</param>
+ /// <param name="priority">The patch priority to apply, usually specified using Harmony's <see cref="Priority"/> enum, or <c>null</c> to keep the default value.</param>
+ protected HarmonyMethod GetHarmonyMethod(string name, int? priority = null)
+ {
+ var method = new HarmonyMethod(
+ AccessTools.Method(this.GetType(), name)
+ ?? throw new InvalidOperationException($"Can't find patcher method {PatchHelper.GetMethodString(this.GetType(), name)}.")
+ );
+
+ if (priority.HasValue)
+ method.priority = priority.Value;
+
+ return method;
+ }
+ }
+}
diff --git a/src/SMAPI.Internal.Patching/HarmonyPatcher.cs b/src/SMAPI.Internal.Patching/HarmonyPatcher.cs
new file mode 100644
index 00000000..c07e3b41
--- /dev/null
+++ b/src/SMAPI.Internal.Patching/HarmonyPatcher.cs
@@ -0,0 +1,36 @@
+using System;
+using HarmonyLib;
+
+namespace StardewModdingAPI.Internal.Patching
+{
+ /// <summary>Simplifies applying <see cref="IPatcher"/> instances to the game.</summary>
+ internal static class HarmonyPatcher
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Apply the given Harmony patchers.</summary>
+ /// <param name="id">The mod ID applying the patchers.</param>
+ /// <param name="monitor">The monitor with which to log any errors.</param>
+ /// <param name="patchers">The patchers to apply.</param>
+ public static Harmony Apply(string id, IMonitor monitor, params IPatcher[] patchers)
+ {
+ Harmony harmony = new Harmony(id);
+
+ foreach (IPatcher patcher in patchers)
+ {
+ try
+ {
+ patcher.Apply(harmony, monitor);
+ }
+ catch (Exception ex)
+ {
+ monitor.Log($"Couldn't apply runtime patch '{patcher.GetType().Name}' to the game. Some SMAPI features may not work correctly. See log file for details.", LogLevel.Error);
+ monitor.Log($"Technical details:\n{ex.GetLogSummary()}");
+ }
+ }
+
+ return harmony;
+ }
+ }
+}
diff --git a/src/SMAPI.Internal.Patching/IPatcher.cs b/src/SMAPI.Internal.Patching/IPatcher.cs
new file mode 100644
index 00000000..a732d64f
--- /dev/null
+++ b/src/SMAPI.Internal.Patching/IPatcher.cs
@@ -0,0 +1,16 @@
+using HarmonyLib;
+
+namespace StardewModdingAPI.Internal.Patching
+{
+ /// <summary>A set of Harmony patches to apply.</summary>
+ internal interface IPatcher
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Apply the Harmony patches for this instance.</summary>
+ /// <param name="harmony">The Harmony instance.</param>
+ /// <param name="monitor">The monitor with which to log any errors.</param>
+ public void Apply(Harmony harmony, IMonitor monitor);
+ }
+}
diff --git a/src/SMAPI.Internal.Patching/PatchHelper.cs b/src/SMAPI.Internal.Patching/PatchHelper.cs
new file mode 100644
index 00000000..fc79ddf2
--- /dev/null
+++ b/src/SMAPI.Internal.Patching/PatchHelper.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using HarmonyLib;
+
+namespace StardewModdingAPI.Internal.Patching
+{
+ /// <summary>Provides utility methods for patching game code with Harmony.</summary>
+ internal static class PatchHelper
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Get a constructor and assert that it was found.</summary>
+ /// <typeparam name="TTarget">The type containing the method.</typeparam>
+ /// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
+ /// <exception cref="InvalidOperationException">The type has no matching constructor.</exception>
+ public static ConstructorInfo RequireConstructor<TTarget>(Type[] parameters = null)
+ {
+ return
+ AccessTools.Constructor(typeof(TTarget), parameters)
+ ?? throw new InvalidOperationException($"Can't find constructor {PatchHelper.GetMethodString(typeof(TTarget), null, parameters)} to patch.");
+ }
+
+ /// <summary>Get a method and assert that it was found.</summary>
+ /// <typeparam name="TTarget">The type containing the method.</typeparam>
+ /// <param name="name">The method name.</param>
+ /// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
+ /// <param name="generics">The method generic types, or <c>null</c> if it's not generic.</param>
+ /// <exception cref="InvalidOperationException">The type has no matching method.</exception>
+ public static MethodInfo RequireMethod<TTarget>(string name, Type[] parameters = null, Type[] generics = null)
+ {
+ return
+ AccessTools.Method(typeof(TTarget), name, parameters, generics)
+ ?? throw new InvalidOperationException($"Can't find method {PatchHelper.GetMethodString(typeof(TTarget), name, parameters, generics)} to patch.");
+ }
+
+ /// <summary>Get a human-readable representation of a method target.</summary>
+ /// <param name="type">The type containing the method.</param>
+ /// <param name="name">The method name, or <c>null</c> for a constructor.</param>
+ /// <param name="parameters">The method parameter types, or <c>null</c> if it's not overloaded.</param>
+ /// <param name="generics">The method generic types, or <c>null</c> if it's not generic.</param>
+ public static string GetMethodString(Type type, string name, Type[] parameters = null, Type[] generics = null)
+ {
+ StringBuilder str = new StringBuilder();
+
+ // type
+ str.Append(type.FullName);
+
+ // method name (if not constructor)
+ if (name != null)
+ {
+ str.Append('.');
+ str.Append(name);
+ }
+
+ // generics
+ if (generics?.Any() == true)
+ {
+ str.Append('<');
+ str.Append(string.Join(", ", generics.Select(p => p.FullName)));
+ str.Append('>');
+ }
+
+ // parameters
+ if (parameters?.Any() == true)
+ {
+ str.Append('(');
+ str.Append(string.Join(", ", parameters.Select(p => p.FullName)));
+ str.Append(')');
+ }
+
+ return str.ToString();
+ }
+ }
+}
diff --git a/src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.projitems b/src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.projitems
new file mode 100644
index 00000000..4fa2a062
--- /dev/null
+++ b/src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.projitems
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <SharedGUID>6c16e948-3e5c-47a7-bf4b-07a7469a87a5</SharedGUID>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <Import_RootNamespace>SMAPI.Internal.Patching</Import_RootNamespace>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildThisFileDirectory)BasePatcher.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)HarmonyPatcher.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)IPatcher.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)PatchHelper.cs" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.shproj b/src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.shproj
new file mode 100644
index 00000000..1a102c82
--- /dev/null
+++ b/src/SMAPI.Internal.Patching/SMAPI.Internal.Patching.shproj
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>6c16e948-3e5c-47a7-bf4b-07a7469a87a5</ProjectGuid>
+ <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
+ <PropertyGroup />
+ <Import Project="SMAPI.Internal.Patching.projitems" Label="Shared" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
+</Project>
diff --git a/src/SMAPI.Internal/ExceptionExtensions.cs b/src/SMAPI.Internal/ExceptionExtensions.cs
new file mode 100644
index 00000000..d7a2252b
--- /dev/null
+++ b/src/SMAPI.Internal/ExceptionExtensions.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Reflection;
+
+namespace StardewModdingAPI.Internal
+{
+ /// <summary>Provides extension methods for handling exceptions.</summary>
+ internal static class ExceptionExtensions
+ {
+ /*********
+ ** Public methods
+ *********/
+ /// <summary>Get a string representation of an exception suitable for writing to the error log.</summary>
+ /// <param name="exception">The error to summarize.</param>
+ public static string GetLogSummary(this Exception exception)
+ {
+ switch (exception)
+ {
+ case TypeLoadException ex:
+ return $"Failed loading type '{ex.TypeName}': {exception}";
+
+ case ReflectionTypeLoadException ex:
+ string summary = exception.ToString();
+ foreach (Exception childEx in ex.LoaderExceptions)
+ summary += $"\n\n{childEx.GetLogSummary()}";
+ return summary;
+
+ default:
+ return exception.ToString();
+ }
+ }
+
+ /// <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;
+ }
+ }
+}
diff --git a/src/SMAPI.Internal/SMAPI.Internal.projitems b/src/SMAPI.Internal/SMAPI.Internal.projitems
index 0d583a6d..0ee94a5b 100644
--- a/src/SMAPI.Internal/SMAPI.Internal.projitems
+++ b/src/SMAPI.Internal/SMAPI.Internal.projitems
@@ -14,5 +14,6 @@
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\ConsoleLogLevel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\IConsoleWriter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConsoleWriting\MonitorColorScheme.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)ExceptionExtensions.cs" />
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs
index 4cfaf242..ceaeb278 100644
--- a/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs
+++ b/src/SMAPI.Mods.ConsoleCommands/Framework/Commands/World/ClearCommand.cs
@@ -15,7 +15,7 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
** Fields
*********/
/// <summary>The valid types that can be cleared.</summary>
- private readonly string[] ValidTypes = { "crops", "debris", "fruit-trees", "furniture", "grass", "trees", "everything" };
+ private readonly string[] ValidTypes = { "crops", "debris", "fruit-trees", "furniture", "grass", "trees", "removable", "everything" };
/// <summary>The resource clump IDs to consider debris.</summary>
private readonly int[] DebrisClumps = { ResourceClump.stumpIndex, ResourceClump.hollowLogIndex, ResourceClump.meteoriteIndex, ResourceClump.boulderIndex };
@@ -30,8 +30,8 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
name: "world_clear",
description: "Clears in-game entities in a given location.\n\n"
+ "Usage: world_clear <location> <object type>\n"
- + "- location: the location name for which to clear objects (like Farm), or 'current' for the current location.\n"
- + " - object type: the type of object clear. You can specify 'crops', 'debris' (stones/twigs/weeds and dead crops), 'furniture', 'grass', and 'trees' / 'fruit-trees'. You can also specify 'everything', which includes things not removed by the other types (like resource clumps)."
+ + " - location: the location name for which to clear objects (like Farm), or 'current' for the current location.\n"
+ + " - object type: the type of object clear. You can specify 'crops', 'debris' (stones/twigs/weeds and dead crops), 'furniture', 'grass', and 'trees' / 'fruit-trees'. You can also specify 'removable' (remove everything that can be removed or destroyed during normal gameplay) or 'everything' (remove everything including permanent bushes)."
)
{ }
@@ -133,13 +133,15 @@ namespace StardewModdingAPI.Mods.ConsoleCommands.Framework.Commands.World
break;
}
+ case "removable":
case "everything":
{
+ bool everything = type == "everything";
int removed =
this.RemoveFurniture(location, p => true)
+ this.RemoveObjects(location, p => true)
+ this.RemoveTerrainFeatures(location, p => true)
- + this.RemoveLargeTerrainFeatures(location, p => true)
+ + this.RemoveLargeTerrainFeatures(location, p => everything || !(p is Bush bush) || bush.isDestroyable(location, p.currentTileLocation))
+ this.RemoveResourceClumps(location, p => true);
monitor.Log($"Done! Removed {removed} entities from {location.Name}.", LogLevel.Info);
break;
diff --git a/src/SMAPI.Mods.ConsoleCommands/manifest.json b/src/SMAPI.Mods.ConsoleCommands/manifest.json
index 1781c40d..09684f32 100644
--- a/src/SMAPI.Mods.ConsoleCommands/manifest.json
+++ b/src/SMAPI.Mods.ConsoleCommands/manifest.json
@@ -1,9 +1,9 @@
{
"Name": "Console Commands",
"Author": "SMAPI",
- "Version": "3.11.0",
+ "Version": "3.12.0",
"Description": "Adds SMAPI console commands that let you manipulate the game.",
"UniqueID": "SMAPI.ConsoleCommands",
"EntryDll": "ConsoleCommands.dll",
- "MinimumApiVersion": "3.11.0"
+ "MinimumApiVersion": "3.12.0"
}
diff --git a/src/SMAPI.Mods.ErrorHandler/ModEntry.cs b/src/SMAPI.Mods.ErrorHandler/ModEntry.cs
index d9426d75..067f6a8d 100644
--- a/src/SMAPI.Mods.ErrorHandler/ModEntry.cs
+++ b/src/SMAPI.Mods.ErrorHandler/ModEntry.cs
@@ -1,8 +1,7 @@
+using System;
using System.Reflection;
using StardewModdingAPI.Events;
-using StardewModdingAPI.Framework;
-using StardewModdingAPI.Framework.Logging;
-using StardewModdingAPI.Framework.Patching;
+using StardewModdingAPI.Internal.Patching;
using StardewModdingAPI.Mods.ErrorHandler.Patches;
using StardewValley;
@@ -29,15 +28,17 @@ namespace StardewModdingAPI.Mods.ErrorHandler
IMonitor monitorForGame = this.GetMonitorForGame();
// apply patches
- new GamePatcher(this.Monitor).Apply(
- new DialogueErrorPatch(monitorForGame, this.Helper.Reflection),
- new EventPatches(monitorForGame),
- new GameLocationPatches(monitorForGame),
- new ObjectErrorPatch(),
- new LoadErrorPatch(this.Monitor, this.OnSaveContentRemoved),
- new ScheduleErrorPatch(monitorForGame),
- new SpriteBatchValidationPatches(),
- new UtilityErrorPatches()
+ HarmonyPatcher.Apply(this.ModManifest.UniqueID, this.Monitor,
+ new DialoguePatcher(monitorForGame, this.Helper.Reflection),
+ new DictionaryPatcher(this.Helper.Reflection),
+ new EventPatcher(monitorForGame),
+ new GameLocationPatcher(monitorForGame),
+ new IClickableMenuPatcher(),
+ new NpcPatcher(monitorForGame),
+ new ObjectPatcher(),
+ new SaveGamePatcher(this.Monitor, this.OnSaveContentRemoved),
+ new SpriteBatchPatcher(),
+ new UtilityPatcher()
);
// hook events
@@ -70,12 +71,17 @@ namespace StardewModdingAPI.Mods.ErrorHandler
/// <summary>Get the monitor with which to log game errors.</summary>
pr