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) --- .../Framework/BaseTypeFinder.cs | 52 ++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/StardewModdingAPI.AssemblyRewriters/Framework/BaseTypeFinder.cs (limited to 'src/StardewModdingAPI.AssemblyRewriters/Framework') 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; + } + } +} -- cgit