From a12bcf3b7845b7c4541ca7539a4810a81b87e3ce Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 12 Mar 2017 17:48:53 -0400 Subject: reject mods which reference obsolete SGame class (#247) --- .../Finders/GenericTypeFinder.cs | 30 +++++++++++++ .../Framework/BaseTypeFinder.cs | 52 ++++++++++++++++++++++ .../StardewModdingAPI.AssemblyRewriters.csproj | 2 + src/StardewModdingAPI/Constants.cs | 3 +- 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/StardewModdingAPI.AssemblyRewriters/Finders/GenericTypeFinder.cs create mode 100644 src/StardewModdingAPI.AssemblyRewriters/Framework/BaseTypeFinder.cs (limited to 'src') diff --git a/src/StardewModdingAPI.AssemblyRewriters/Finders/GenericTypeFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Finders/GenericTypeFinder.cs new file mode 100644 index 00000000..11ffa734 --- /dev/null +++ b/src/StardewModdingAPI.AssemblyRewriters/Finders/GenericTypeFinder.cs @@ -0,0 +1,30 @@ +using StardewModdingAPI.AssemblyRewriters.Framework; + +namespace StardewModdingAPI.AssemblyRewriters.Finders +{ + /// Base class for a type reference finder. + public class GenericTypeFinder : BaseTypeFinder + { + /********* + ** Accessors + *********/ + /// A brief noun phrase indicating what the instruction finder matches. + public override string NounPhrase { get; } + + /// The full type name to match. + public override string FullTypeName { get; } + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The full type name to match. + /// A brief noun phrase indicating what the instruction finder matches. + public GenericTypeFinder(string fullTypeName, string nounPhrase) + { + this.FullTypeName = fullTypeName; + this.NounPhrase = nounPhrase; + } + } +} diff --git a/src/StardewModdingAPI.AssemblyRewriters/Framework/BaseTypeFinder.cs b/src/StardewModdingAPI.AssemblyRewriters/Framework/BaseTypeFinder.cs new file mode 100644 index 00000000..5a768794 --- /dev/null +++ b/src/StardewModdingAPI.AssemblyRewriters/Framework/BaseTypeFinder.cs @@ -0,0 +1,52 @@ +using System.Linq; +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace StardewModdingAPI.AssemblyRewriters.Framework +{ + /// Base class for a type reference finder. + public abstract class BaseTypeFinder : IInstructionFinder + { + /********* + ** Accessors + *********/ + /// A brief noun phrase indicating what the instruction finder matches. + public abstract string NounPhrase { get; } + + /// The full type name to match. + public abstract string FullTypeName { get; } + + + /********* + ** Public methods + *********/ + /// Get whether a CIL instruction matches. + /// The IL instruction. + /// Whether the mod was compiled on a different platform. + public virtual bool IsMatch(Instruction instruction, bool platformChanged) + { + string fullName = this.FullTypeName; + + // field reference + if (instruction.OpCode == OpCodes.Ldfld || instruction.OpCode == OpCodes.Ldsfld || instruction.OpCode == OpCodes.Stfld || instruction.OpCode == OpCodes.Stsfld) + { + FieldReference field = (FieldReference)instruction.Operand; + return + field.DeclaringType.FullName == fullName // field on target class + || field.FieldType.FullName == fullName; // field value is target class + } + + // method reference + if (instruction.OpCode == OpCodes.Call || instruction.OpCode == OpCodes.Callvirt) + { + MethodReference method = (MethodReference)instruction.Operand; + return + method.DeclaringType.FullName == fullName // method on target class + || method.ReturnType.FullName == fullName // method returns target class + || method.Parameters.Any(p => p.ParameterType.FullName == fullName); // method parameters + } + + return false; + } + } +} diff --git a/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj b/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj index 3f437ca0..d489eb34 100644 --- a/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj +++ b/src/StardewModdingAPI.AssemblyRewriters/StardewModdingAPI.AssemblyRewriters.csproj @@ -69,8 +69,10 @@ + + diff --git a/src/StardewModdingAPI/Constants.cs b/src/StardewModdingAPI/Constants.cs index 563cdd52..1e1ca325 100644 --- a/src/StardewModdingAPI/Constants.cs +++ b/src/StardewModdingAPI/Constants.cs @@ -146,7 +146,8 @@ namespace StardewModdingAPI new Game1_smoothFont_FieldFinder(), // APIs removed in SMAPI 1.9 - new SMAPI_Extensions_MethodFinder() + new SMAPI_Extensions_MethodFinder(), + new GenericTypeFinder("StardewModdingAPI.Inheritance.SGame", "obsolete StardewModdingAPI.SGame class") }; } -- cgit