From 3106b5dc491a75c8aa7a3696728aea9cd48d4cb7 Mon Sep 17 00:00:00 2001 From: aszlig Date: Wed, 18 Jul 2018 16:51:44 +0200 Subject: monogame-patcher: Allow to define specific methods So far we only matched a substring of a type, which isn't very exact of course. We also weren't able to specify the method to patch. Now the methods that are being patched can be specified by using Type::Method. If it's just Type without a method all the methods of the type and its subtypes are patched. I also added a small check to make sure that all of these methods were found, and if not an error is thrown. Signed-off-by: aszlig --- .../build-support/monogame-patcher/src/patcher.cs | 61 +++++++++++++++------- .../build-support/monogame-patcher/src/test.sh | 11 ++-- 2 files changed, 49 insertions(+), 23 deletions(-) (limited to 'pkgs/games') diff --git a/pkgs/games/build-support/monogame-patcher/src/patcher.cs b/pkgs/games/build-support/monogame-patcher/src/patcher.cs index bf572d9c..90ed640f 100644 --- a/pkgs/games/build-support/monogame-patcher/src/patcher.cs +++ b/pkgs/games/build-support/monogame-patcher/src/patcher.cs @@ -25,6 +25,42 @@ class Command { this.module = this.read_module(this.infile, readOnly); } + private IEnumerable get_methods(TypeDefinition td) { + return td.NestedTypes + .SelectMany(n => this.get_methods(n)) + .Union(td.Methods); + } + + protected IEnumerable getm(IEnumerable types) { + var needles = types + .Select(t => t.Split(new[] { "::" }, 2, StringSplitOptions.None)); + + foreach (var n in needles) { + var filtered = this.module.Types.Where(p => p.Name == n[0]); + var methods = filtered.SelectMany(t => this.get_methods(t)); + + var found = false; + + if (n.Length == 1) { + foreach (var m in methods) + yield return m; + found = true; + } else { + foreach (var m in methods) { + if (m.Name == n[1]) { + found = true; + yield return m; + } + } + } + + if (!found) { + var thetype = string.Join("::", n); + throw new Exception("Type {thetype} not found."); + } + } + } + protected ModuleDefinition read_module(string path, bool readOnly) { var resolver = new DefaultAssemblyResolver(); resolver.AddSearchDirectory(Path.GetDirectoryName(path)); @@ -69,16 +105,13 @@ class FixFileStreams : Command { private MethodReference betterFileStream; public FixFileStreams(FixFileStreamsCmd options) : base(options) { - var filtered = this.module.Types - .Where(p => options.typesToPatch.Contains(p.Name)); - this.betterFileStream = this.find_method_ref( "System.Void System.IO.FileStream::.ctor" + "(System.String,System.IO.FileMode,System.IO.FileAccess)" ); - foreach (var toPatch in filtered) - patch_type(toPatch); + foreach (var toPatch in this.getm(options.typesToPatch)) + patch_method(toPatch); this.save(); } @@ -97,11 +130,6 @@ class FixFileStreams : Command { il.Replace(i, il.Create(OpCodes.Newobj, this.betterFileStream)); } } - - private void patch_type(TypeDefinition td) { - foreach (var nested in td.NestedTypes) patch_type(nested); - foreach (MethodDefinition md in td.Methods) patch_method(md); - } } class ReplaceCall : Command { @@ -117,12 +145,10 @@ class ReplaceCall : Command { this.search = options.replaceMethod; this.replace = this.find_method_ref(options.replacementMethod); - var filtered = this.module.Types - .Where(p => options.typesToPatch.Contains(p.Name)); - this.patch_done = false; - foreach (var toPatch in filtered) - patch_type(toPatch); + + foreach (var toPatch in this.getm(options.typesToPatch)) + patch_method(toPatch); if (!this.patch_done) { var types = string.Join(", ", options.typesToPatch); @@ -151,11 +177,6 @@ class ReplaceCall : Command { this.patch_done = true; } } - - private void patch_type(TypeDefinition td) { - foreach (var nested in td.NestedTypes) patch_type(nested); - foreach (MethodDefinition md in td.Methods) patch_method(md); - } } public class patcher { diff --git a/pkgs/games/build-support/monogame-patcher/src/test.sh b/pkgs/games/build-support/monogame-patcher/src/test.sh index b7380f27..b03fa6cb 100644 --- a/pkgs/games/build-support/monogame-patcher/src/test.sh +++ b/pkgs/games/build-support/monogame-patcher/src/test.sh @@ -18,7 +18,7 @@ using System.IO; public class b { public static string replacement(string bar) { - if (bar == "nope") + if (bar == "nope" || bar == "yikes") return "nope"; Console.WriteLine("bar called: " + bar); return "bar"; @@ -49,15 +49,20 @@ EOF cat > "test1.cs" < "test2.cs" <