about summary refs log tree commit diff
path: root/pkgs/games
diff options
context:
space:
mode:
authoraszlig <aszlig@nix.build>2018-07-19 06:23:58 +0200
committeraszlig <aszlig@nix.build>2018-07-19 06:35:48 +0200
commit54e484fa385b16858bad77041da19c52238ae1c9 (patch)
treefcf4a03cacbab9c21cd4361ce34f8c91fc2bb97e /pkgs/games
parent3106b5dc491a75c8aa7a3696728aea9cd48d4cb7 (diff)
games/gog: Add War for the Overworld
This was the whole reason why I implemented the monogame-patcher even
though it is very useful for other games as well.

So the main issue why patching was needed is that the game writes its
savegames into the same directories as other assets, so we need to be
very careful about which method we patch and how in order to avoid
failures to load other assets rather than savegames.

However while in principle the game runs fine there is a Heisenbug
hidden, so it segfaults whenever strace is not used. Here is the
backtrace:

  #0  0x0000000000f973be in ?? ()
  #1  0x0000000000f8f444 in ?? ()
  #2  0x0000000000f2379b in ?? ()
  #3  0x0000000000f2940b in ?? ()
  #4  0x0000000000f1fa87 in ?? ()
  #5  0x00000000008e8cc8 in ?? ()
  #6  0x00007ffff79bc5a7 in start_thread () from libpthread.so.0
  #7  0x00007ffff61cf22f in clone () from libc.so.6

Disassembly around 0xf973be:

  f973a2:       45 0f b6 4f 02          movzbl 0x2(%r15),%r9d
  f973a7:       ba 04 00 00 00          mov    $0x4,%edx
  f973ac:       41 80 f9 02             cmp    $0x2,%r9b
  f973b0:       74 05                   je     f973b7
  f973b2:       41 0f b6 57 03          movzbl 0x3(%r15),%edx
  f973b7:       48 8b 40 30             mov    0x30(%rax),%rax
  f973bb:       83 f9 1b                cmp    $0x1b,%ecx
 >f973be:       8b 40 08                mov    0x8(%rax),%eax
  f973c1:       89 44 24 58             mov    %eax,0x58(%rsp)
  f973c5:       0f 86 6d 01 00 00       jbe    f97538
  f973cb:       c6 44 24 5f 00          movb   $0x0,0x5f(%rsp)
  f973d0:       45 31 ff                xor    %r15d,%r15d
  f973d3:       89 54 24 28             mov    %edx,0x28(%rsp)
  f973d7:       89 74 24 20             mov    %esi,0x20(%rsp)
  f973db:       44 88 44 24 18          mov    %r8b,0x18(%rsp)
  f973e0:       44 88 4c 24 30          mov    %r9b,0x30(%rsp)
  f973e5:       e8 16 fa 92 ff          callq  8c6e00

The last callq is for <operator new(unsigned long)@@Base+0x27c9d0>, so
I'd suppose this might be a bug in the patched Mono version of Unity but
could also be a chain reaction (who knows).

Probably the reason why it works with strace might be a race condition,
but I haven't thoroughly debugged this. Especially if there are no
symbols available it's very hard to debug, so I'll leave that to some
day in the future.

Signed-off-by: aszlig <aszlig@nix.build>
Diffstat (limited to 'pkgs/games')
-rw-r--r--pkgs/games/gog/default.nix1
-rw-r--r--pkgs/games/gog/war-for-the-overworld.nix88
2 files changed, 89 insertions, 0 deletions
diff --git a/pkgs/games/gog/default.nix b/pkgs/games/gog/default.nix
index eaf7e28a..d63c5901 100644
--- a/pkgs/games/gog/default.nix
+++ b/pkgs/games/gog/default.nix
@@ -22,6 +22,7 @@ let
       beta = true;
     });
     thimbleweed-park = callPackage ./thimbleweed-park.nix {};
+    war-for-the-overworld = callPackage ./war-for-the-overworld.nix {};
     wizard-of-legend = callPackage ./wizard-of-legend.nix {};
     xeen = callPackage ./xeen.nix {};
   };
diff --git a/pkgs/games/gog/war-for-the-overworld.nix b/pkgs/games/gog/war-for-the-overworld.nix
new file mode 100644
index 00000000..8309fa12
--- /dev/null
+++ b/pkgs/games/gog/war-for-the-overworld.nix
@@ -0,0 +1,88 @@
+{ buildUnity, fetchGog, unzip, mono, monogamePatcher }:
+
+buildUnity {
+  name = "war-for-the-overworld";
+  fullName = "WFTOGame";
+  saveDir = "Subterranean Games/War For The Overworld";
+  version = "2.0.3f1";
+
+  src = fetchGog {
+    productId = 1964276929;
+    downloadName = "en3installer0";
+    sha256 = "07yj9clf3hmy7z67ck9sqf3gnrazx5rzifg91jas77z774vwdg8k";
+  };
+
+  unpackCmd = "${unzip}/bin/unzip -qq \"$curSrc\" 'data/noarch/game/*' || :";
+
+  nativeBuildInputs = [ mono monogamePatcher ];
+
+  # The game tries to write stuff to its dataPath and it's even more
+  # complicated than for most other games that try to write stuff into their
+  # dataPath because the paths overlap with the assets.
+  #
+  # I've reported this upstream at:
+  #
+  # https://brightrockgames.userecho.com/communities/1/topics/4720-xdg
+  #
+  # So let's patch a few stuff so that at least starting the game and
+  # loading/saving games will work.
+  buildPhase = ''
+    cat > nix-support.cs <<EOF
+    using UnityEngine;
+    using System.IO;
+
+    public class NixSupport {
+      public static string GetDataDir() {
+        var path = Path.Combine(Application.persistentDataPath, "GameData");
+        if (!Directory.Exists(path))
+          Directory.CreateDirectory(path);
+        return path;
+      }
+
+      public static string GetDataDir(string subpath) {
+        var path = Path.Combine(NixSupport.GetDataDir(), subpath);
+        if (!Directory.Exists(path))
+          Directory.CreateDirectory(path);
+        return path;
+      }
+
+      public static string GetFullPathMkParent(string path) {
+        var fullpath = Path.GetFullPath(path);
+        var dirname = Path.GetDirectoryName(fullpath);
+        if (!Directory.Exists(dirname))
+          Directory.CreateDirectory(dirname);
+        return fullpath;
+      }
+    }
+    EOF
+
+    mcs nix-support.cs -target:library -r:WFTOGame_Data/Managed/UnityEngine \
+      -out:WFTOGame_Data/Managed/NixSupport.dll
+
+    monogame-patcher replace-call \
+      -i WFTOGame_Data/Managed/Assembly-CSharp.dll \
+      'System.String UnityEngine.Application::get_dataPath()' \
+      'System.String UnityEngine.Application::get_persistentDataPath()' \
+      IniParser SaveMeta::UpdateMetaDataAndMinimap SaveMeta::GetMinimapPath \
+      SaveMeta::GetMinimapPath SaveMeta::GetMinimapAbsolutePath
+
+    monogame-patcher replace-call \
+      -i WFTOGame_Data/Managed/Assembly-CSharp.dll \
+      -a WFTOGame_Data/Managed/NixSupport.dll \
+      'System.String GameDataFolder::Get(System.String)' \
+      'System.String NixSupport::GetDataDir(System.String)' \
+      Serializer::MapSave DRMFree::FullPath DRMFree::OnEnable \
+      SaveStatAchievementLAN::FullPath SaveStatAchievementLAN::GetFolders
+
+    monogame-patcher replace-call \
+      -i WFTOGame_Data/Managed/Assembly-CSharp.dll \
+      -a WFTOGame_Data/Managed/NixSupport.dll \
+      'System.String System.IO.Path::GetFullPath(System.String)' \
+      'System.String NixSupport::GetFullPathMkParent(System.String)' \
+      SaveMeta::GetMinimapAbsolutePath
+
+    monogame-patcher fix-filestreams \
+      -i WFTOGame_Data/Managed/Assembly-CSharp-firstpass.dll \
+      UnityGTResourceHandler
+  '';
+}