about summary refs log tree commit diff
path: root/pkgs/games/itch
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2018-07-16 07:09:38 +0200
committeraszlig <aszlig@nix.build>2018-07-19 06:35:06 +0200
commitc9dfe485e9b922b35c9412e6c4fdbe119f17f4b5 (patch)
tree96180ef3647607a6eb764bfe2aa4c48d0fe0999e /pkgs/games/itch
parentbc0be07dd9920c8dfc16be8f5bdb269bc9e3f986 (diff)
towerfall-ascension: Move patcher into own pkg
The patcher using Cecil is now in its own derivation and can thus be
easily added via nativeBuildInputs. Patching FileStream types is so
common that it comes in handy for other games using Mono.

I also improved the patcher a little bit so it accepts command line
arguments and it's easier to add the types that needed to be patched
directly via command line arguments.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/games/itch')
-rw-r--r--pkgs/games/itch/towerfall-ascension.nix100
1 files changed, 6 insertions, 94 deletions
diff --git a/pkgs/games/itch/towerfall-ascension.nix b/pkgs/games/itch/towerfall-ascension.nix
index a4ba5abf..21704211 100644
--- a/pkgs/games/itch/towerfall-ascension.nix
+++ b/pkgs/games/itch/towerfall-ascension.nix
@@ -1,94 +1,11 @@
 { stdenv, lib, buildGame, fetchItch, makeWrapper, p7zip, unzip, mono50
-, SDL2, SDL2_image, libGL, libvorbis, openal
-
-, writeScriptBin, coreutils
-, fetchNuGet, writeText
+, SDL2, SDL2_image, libGL, libvorbis, openal, monogamePatcher, writeScriptBin
+, coreutils
 
 , darkWorldExpansion ? true
 }:
 
-let
-  cecil = fetchNuGet {
-    baseName = "Mono.Cecil";
-    version = "0.10-beta7";
-    sha256 = "03bina3llcnylrfrvp5psnwrfn757j7zch5r360rpdn7gmcjjcpl";
-    outputFiles = [ "lib/net40/*" ];
-  };
-
-  # We need to patch a few occurences of System.IO.FileStream which are used
-  # with the default arguments for FileAccess. The defaults open the file in
-  # read-write mode and given that all the game data files are in the read-only
-  # Nix store, we'd get an UnauthorizedAccessException.
-  patcher = writeText "patcher.cs" ''
-    using System.Linq;
-    using System.Collections.Generic;
-    using Mono.Cecil;
-    using Mono.Cecil.Cil;
-    using Mono.Cecil.Rocks;
-
-    public class patcher {
-      private ModuleDefinition module;
-
-      private patcher(List<string> typesToPatch) {
-        this.module = ModuleDefinition.ReadModule("TowerFall.exe");
-
-        var filtered = this.module.Types
-          .Where(p => typesToPatch.Contains(p.Name));
-
-        foreach (var toPatch in filtered) {
-          patch_class(toPatch);
-        }
-
-        this.module.Write("TowerFallPatched.exe");
-      }
-
-      private void patch_method(MethodDefinition md) {
-        var il = md.Body.GetILProcessor();
-
-        var fileStreams = md.Body.Instructions
-          .Where(i => i.OpCode == OpCodes.Newobj)
-          .Where(i => (i.Operand as MethodReference).DeclaringType
-                      .FullName == "System.IO.FileStream");
-
-        foreach (Instruction i in fileStreams.ToList()) {
-          var fileAccessRead = il.Create(OpCodes.Ldc_I4_1);
-          il.InsertBefore(i, fileAccessRead);
-
-          var ctorType = this.module.AssemblyReferences.Select(
-            x => new {
-              type = this.module.AssemblyResolver.Resolve(x)
-                .MainModule.GetType("System.IO.FileStream")
-            }
-          ).Where(x => x.type != null).Select(x => x.type).First();
-
-          string wantedCtor = "System.Void System.IO.FileStream"
-                            + "::.ctor(System.String,"
-                            + "System.IO.FileMode,"
-                            + "System.IO.FileAccess)";
-
-          var newCtor = ctorType.GetConstructors()
-            .Single(x => x.ToString() == wantedCtor);
-
-          var refCtor = this.module.ImportReference(newCtor);
-          il.Replace(i, il.Create(OpCodes.Newobj, refCtor));
-        }
-      }
-
-      private void patch_class(TypeDefinition td) {
-        foreach (var nested in td.NestedTypes) patch_class(nested);
-        foreach (MethodDefinition md in td.Methods) patch_method(md);
-      }
-
-      public static void Main() {
-        var typesToPatch = new List<string>() {
-          "Texture", "IntroScene", "SFX", "SFXVaried"
-        };
-        new patcher(typesToPatch);
-      }
-    }
-  '';
-
-in buildGame rec {
+buildGame rec {
   name = "towerfall-ascension-${version}";
   version = "20160723";
 
@@ -113,16 +30,11 @@ in buildGame rec {
   '';
 
   patchPhase = ''
-    { export MONO_PATH=${cecil}/lib/dotnet/Mono.Cecil
-      mcs ${lib.escapeShellArg patcher} -out:patcher \
-        -lib:${cecil}/lib/dotnet/Mono.Cecil \
-        -r:Mono.Cecil -r:Mono.Cecil.Rocks
-      mono patcher
-      mv TowerFallPatched.exe TowerFall.exe
-    }
+    monogame-patcher fix-filestreams -i TowerFall.exe \
+      Texture IntroScene SFX SFXVaried
   '';
 
-  nativeBuildInputs = [ makeWrapper mono50 ];
+  nativeBuildInputs = [ makeWrapper mono50 monogamePatcher ];
 
   libdir = if stdenv.system == "x86_64-linux" then "lib64" else "lib";