From fd10cf958cb68a41e1aa7ac4d7d2371205be0c75 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 19 Sep 2017 23:02:00 -0400 Subject: move rewriters into metadata class (#347) --- src/StardewModdingAPI/Constants.cs | 79 ------------------- .../Framework/ModLoading/AssemblyLoader.cs | 3 +- .../Metadata/InstructionMetadata.cs | 91 ++++++++++++++++++++++ src/StardewModdingAPI/StardewModdingAPI.csproj | 1 + 4 files changed, 94 insertions(+), 80 deletions(-) create mode 100644 src/StardewModdingAPI/Metadata/InstructionMetadata.cs diff --git a/src/StardewModdingAPI/Constants.cs b/src/StardewModdingAPI/Constants.cs index 4bbd7328..07647d2d 100644 --- a/src/StardewModdingAPI/Constants.cs +++ b/src/StardewModdingAPI/Constants.cs @@ -1,15 +1,9 @@ using System; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; -using Microsoft.Xna.Framework.Graphics; -using StardewModdingAPI.Events; using StardewModdingAPI.Framework; using StardewModdingAPI.Framework.ModLoading; -using StardewModdingAPI.Framework.ModLoading.Finders; -using StardewModdingAPI.Framework.ModLoading.Rewriters; -using StardewModdingAPI.Framework.ModLoading.Rewriters.Wrappers; using StardewValley; namespace StardewModdingAPI @@ -147,79 +141,6 @@ namespace StardewModdingAPI return new PlatformAssemblyMap(targetPlatform, removeAssemblyReferences, targetAssemblies); } - /// Get rewriters which detect or fix incompatible CIL instructions in mod assemblies. - internal static IEnumerable GetRewriters() - { - return new IInstructionRewriter[] - { - /**** - ** Finders throw an exception when incompatible code is found. - ****/ - // changes in Stardew Valley 1.2 (with no rewriters) - new FieldFinder("StardewValley.Item", "set_Name"), - - // APIs removed in SMAPI 1.9 - new TypeFinder("StardewModdingAPI.Advanced.ConfigFile"), - new TypeFinder("StardewModdingAPI.Advanced.IConfigFile"), - new TypeFinder("StardewModdingAPI.Entities.SPlayer"), - new TypeFinder("StardewModdingAPI.Extensions"), - new TypeFinder("StardewModdingAPI.Inheritance.SGame"), - new TypeFinder("StardewModdingAPI.Inheritance.SObject"), - new TypeFinder("StardewModdingAPI.LogWriter"), - new TypeFinder("StardewModdingAPI.Manifest"), - new TypeFinder("StardewModdingAPI.Version"), - new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "DrawDebug"), - new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "DrawTick"), - new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPostRenderHudEventNoCheck"), - new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPostRenderGuiEventNoCheck"), - new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPreRenderHudEventNoCheck"), - new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPreRenderGuiEventNoCheck"), - - // APIs removed in SMAPI 2.0 -#if !SMAPI_1_x - new TypeFinder("StardewModdingAPI.Command"), - new TypeFinder("StardewModdingAPI.Config"), - new TypeFinder("StardewModdingAPI.Log"), - new EventFinder("StardewModdingAPI.Events.GameEvents", "Initialize"), - new EventFinder("StardewModdingAPI.Events.GameEvents", "LoadContent"), - new EventFinder("StardewModdingAPI.Events.GameEvents", "GameLoaded"), - new EventFinder("StardewModdingAPI.Events.GameEvents", "FirstUpdateTick"), - new EventFinder("StardewModdingAPI.Events.PlayerEvents", "LoadedGame"), - new EventFinder("StardewModdingAPI.Events.PlayerEvents", "FarmerChanged"), - new EventFinder("StardewModdingAPI.Events.TimeEvents", "DayOfMonthChanged"), - new EventFinder("StardewModdingAPI.Events.TimeEvents", "YearOfGameChanged"), - new EventFinder("StardewModdingAPI.Events.TimeEvents", "SeasonOfYearChanged"), - new EventFinder("StardewModdingAPI.Events.TimeEvents", "OnNewDay"), - new TypeFinder("StardewModdingAPI.Events.EventArgsCommand"), - new TypeFinder("StardewModdingAPI.Events.EventArgsFarmerChanged"), - new TypeFinder("StardewModdingAPI.Events.EventArgsLoadedGameChanged"), - new TypeFinder("StardewModdingAPI.Events.EventArgsNewDay"), - new TypeFinder("StardewModdingAPI.Events.EventArgsStringChanged"), - new PropertyFinder("StardewModdingAPI.Mod", "PathOnDisk"), - new PropertyFinder("StardewModdingAPI.Mod", "BaseConfigPath"), - new PropertyFinder("StardewModdingAPI.Mod", "PerSaveConfigFolder"), - new PropertyFinder("StardewModdingAPI.Mod", "PerSaveConfigPath"), -#endif - - /**** - ** Rewriters change CIL as needed to fix incompatible code - ****/ - // crossplatform - new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchWrapper), onlyIfPlatformChanged: true), - - // Stardew Valley 1.2 - new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.activeClickableMenu)), - new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.currentMinigame)), - new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.gameMode)), - new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.player)), - new FieldReplaceRewriter(typeof(Game1), "borderFont", nameof(Game1.smallFont)), - new FieldReplaceRewriter(typeof(Game1), "smoothFont", nameof(Game1.smallFont)), - - // SMAPI 1.9 - new TypeReferenceRewriter("StardewModdingAPI.Inheritance.ItemStackChange", typeof(ItemStackChange)) - }; - } - /********* ** Private methods diff --git a/src/StardewModdingAPI/Framework/ModLoading/AssemblyLoader.cs b/src/StardewModdingAPI/Framework/ModLoading/AssemblyLoader.cs index f9c43f1f..871a081f 100644 --- a/src/StardewModdingAPI/Framework/ModLoading/AssemblyLoader.cs +++ b/src/StardewModdingAPI/Framework/ModLoading/AssemblyLoader.cs @@ -6,6 +6,7 @@ using System.Reflection; using Mono.Cecil; using Mono.Cecil.Cil; using StardewModdingAPI.Framework.Exceptions; +using StardewModdingAPI.Metadata; namespace StardewModdingAPI.Framework.ModLoading { @@ -213,7 +214,7 @@ namespace StardewModdingAPI.Framework.ModLoading // find (and optionally rewrite) incompatible instructions bool anyRewritten = false; - IInstructionRewriter[] rewriters = Constants.GetRewriters(this.Monitor).ToArray(); + IInstructionRewriter[] rewriters = new InstructionMetadata().GetRewriters().ToArray(); foreach (MethodDefinition method in this.GetMethods(module)) { // check method definition diff --git a/src/StardewModdingAPI/Metadata/InstructionMetadata.cs b/src/StardewModdingAPI/Metadata/InstructionMetadata.cs new file mode 100644 index 00000000..67fdc041 --- /dev/null +++ b/src/StardewModdingAPI/Metadata/InstructionMetadata.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI.Events; +using StardewModdingAPI.Framework.ModLoading; +using StardewModdingAPI.Framework.ModLoading.Finders; +using StardewModdingAPI.Framework.ModLoading.Rewriters; +using StardewModdingAPI.Framework.ModLoading.Rewriters.Wrappers; +using StardewValley; + +namespace StardewModdingAPI.Metadata +{ + /// Provides CIL instruction handlers which rewrite mods for compatibility and throw exceptions for incompatible code. + internal class InstructionMetadata + { + /********* + ** Public methods + *********/ + /// Get rewriters which detect or fix incompatible CIL instructions in mod assemblies. + public IEnumerable GetRewriters() + { + return new IInstructionRewriter[] + { + /**** + ** Finders throw an exception when incompatible code is found. + ****/ + // changes in Stardew Valley 1.2 (with no rewriters) + new FieldFinder("StardewValley.Item", "set_Name"), + + // APIs removed in SMAPI 1.9 + new TypeFinder("StardewModdingAPI.Advanced.ConfigFile"), + new TypeFinder("StardewModdingAPI.Advanced.IConfigFile"), + new TypeFinder("StardewModdingAPI.Entities.SPlayer"), + new TypeFinder("StardewModdingAPI.Extensions"), + new TypeFinder("StardewModdingAPI.Inheritance.SGame"), + new TypeFinder("StardewModdingAPI.Inheritance.SObject"), + new TypeFinder("StardewModdingAPI.LogWriter"), + new TypeFinder("StardewModdingAPI.Manifest"), + new TypeFinder("StardewModdingAPI.Version"), + new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "DrawDebug"), + new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "DrawTick"), + new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPostRenderHudEventNoCheck"), + new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPostRenderGuiEventNoCheck"), + new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPreRenderHudEventNoCheck"), + new EventFinder("StardewModdingAPI.Events.GraphicsEvents", "OnPreRenderGuiEventNoCheck"), + + // APIs removed in SMAPI 2.0 +#if !SMAPI_1_x + new TypeFinder("StardewModdingAPI.Command"), + new TypeFinder("StardewModdingAPI.Config"), + new TypeFinder("StardewModdingAPI.Log"), + new EventFinder("StardewModdingAPI.Events.GameEvents", "Initialize"), + new EventFinder("StardewModdingAPI.Events.GameEvents", "LoadContent"), + new EventFinder("StardewModdingAPI.Events.GameEvents", "GameLoaded"), + new EventFinder("StardewModdingAPI.Events.GameEvents", "FirstUpdateTick"), + new EventFinder("StardewModdingAPI.Events.PlayerEvents", "LoadedGame"), + new EventFinder("StardewModdingAPI.Events.PlayerEvents", "FarmerChanged"), + new EventFinder("StardewModdingAPI.Events.TimeEvents", "DayOfMonthChanged"), + new EventFinder("StardewModdingAPI.Events.TimeEvents", "YearOfGameChanged"), + new EventFinder("StardewModdingAPI.Events.TimeEvents", "SeasonOfYearChanged"), + new EventFinder("StardewModdingAPI.Events.TimeEvents", "OnNewDay"), + new TypeFinder("StardewModdingAPI.Events.EventArgsCommand"), + new TypeFinder("StardewModdingAPI.Events.EventArgsFarmerChanged"), + new TypeFinder("StardewModdingAPI.Events.EventArgsLoadedGameChanged"), + new TypeFinder("StardewModdingAPI.Events.EventArgsNewDay"), + new TypeFinder("StardewModdingAPI.Events.EventArgsStringChanged"), + new PropertyFinder("StardewModdingAPI.Mod", "PathOnDisk"), + new PropertyFinder("StardewModdingAPI.Mod", "BaseConfigPath"), + new PropertyFinder("StardewModdingAPI.Mod", "PerSaveConfigFolder"), + new PropertyFinder("StardewModdingAPI.Mod", "PerSaveConfigPath"), +#endif + + /**** + ** Rewriters change CIL as needed to fix incompatible code + ****/ + // crossplatform + new MethodParentRewriter(typeof(SpriteBatch), typeof(SpriteBatchWrapper), onlyIfPlatformChanged: true), + + // Stardew Valley 1.2 + new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.activeClickableMenu)), + new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.currentMinigame)), + new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.gameMode)), + new FieldToPropertyRewriter(typeof(Game1), nameof(Game1.player)), + new FieldReplaceRewriter(typeof(Game1), "borderFont", nameof(Game1.smallFont)), + new FieldReplaceRewriter(typeof(Game1), "smoothFont", nameof(Game1.smallFont)), + + // SMAPI 1.9 + new TypeReferenceRewriter("StardewModdingAPI.Inheritance.ItemStackChange", typeof(ItemStackChange)) + }; + } + } +} diff --git a/src/StardewModdingAPI/StardewModdingAPI.csproj b/src/StardewModdingAPI/StardewModdingAPI.csproj index 5f59d125..d4b1cb69 100644 --- a/src/StardewModdingAPI/StardewModdingAPI.csproj +++ b/src/StardewModdingAPI/StardewModdingAPI.csproj @@ -226,6 +226,7 @@ + -- cgit