diff options
-rw-r--r-- | pkgs/games/build-support/build-game.nix | 6 | ||||
-rw-r--r-- | pkgs/games/build-support/default.nix | 4 | ||||
-rw-r--r-- | pkgs/games/build-support/setup-hooks/default.nix | 7 | ||||
-rw-r--r-- | pkgs/games/build-support/setup-hooks/gog-unpack.sh | 71 | ||||
-rw-r--r-- | pkgs/games/default.nix | 1 |
5 files changed, 86 insertions, 3 deletions
diff --git a/pkgs/games/build-support/build-game.nix b/pkgs/games/build-support/build-game.nix index 5c1f1ef4..459fca75 100644 --- a/pkgs/games/build-support/build-game.nix +++ b/pkgs/games/build-support/build-game.nix @@ -1,4 +1,4 @@ -{ stdenv, lib, file, unzip, buildSandbox, autoPatchelfHook +{ stdenv, lib, file, unzip, buildSandbox, autoPatchelfHook, gogUnpackHook , withPulseAudio ? true, libpulseaudio ? null , alsaLib @@ -18,7 +18,9 @@ assert withPulseAudio -> libpulseaudio != null; buildSandbox (stdenv.mkDerivation ({ buildInputs = [ stdenv.cc.cc ] ++ buildInputs; - nativeBuildInputs = [ unzip autoPatchelfHook ] ++ nativeBuildInputs; + nativeBuildInputs = [ + unzip autoPatchelfHook gogUnpackHook + ] ++ nativeBuildInputs; preUnpack = preUnpack + '' mkdir "$name" diff --git a/pkgs/games/build-support/default.nix b/pkgs/games/build-support/default.nix index 1832f987..0e7574ec 100644 --- a/pkgs/games/build-support/default.nix +++ b/pkgs/games/build-support/default.nix @@ -1,4 +1,4 @@ -{ config, callPackage, ... }: +{ config, callPackage, callPackages, ... }: { buildGame = callPackage ./build-game.nix { @@ -6,4 +6,6 @@ }; buildUnity = callPackage ./build-unity.nix {}; monogamePatcher = callPackage ./monogame-patcher {}; + + inherit (callPackages ./setup-hooks {}) gogUnpackHook; } diff --git a/pkgs/games/build-support/setup-hooks/default.nix b/pkgs/games/build-support/setup-hooks/default.nix new file mode 100644 index 00000000..9f35dad7 --- /dev/null +++ b/pkgs/games/build-support/setup-hooks/default.nix @@ -0,0 +1,7 @@ +{ makeSetupHook, libarchive, innoextract }: + +{ + gogUnpackHook = makeSetupHook { + deps = [ libarchive innoextract ]; + } ./gog-unpack.sh; +} diff --git a/pkgs/games/build-support/setup-hooks/gog-unpack.sh b/pkgs/games/build-support/setup-hooks/gog-unpack.sh new file mode 100644 index 00000000..8b70803c --- /dev/null +++ b/pkgs/games/build-support/setup-hooks/gog-unpack.sh @@ -0,0 +1,71 @@ +unpackCmdHooks+=(_tryUnpackGogMakeSelf _tryUnpackGogInnoSetup) + +_tryUnpackGogMakeSelf() { + # Make sure it's really a Makeself installer with GOG.com modifications. + sed -n -e '1,/^\([^#]\| *\)$/ { + /This script.*Makeself/ { + n; /GOG\.com/q + } + 200q1 # This is getting too long, so quit immediately. + b + } + q1' "$curSrc" || return 1 + + # The file consists of a shell script at the top, followed by a tarball with + # the installer and after that tarball, the actual ZIP file with the game + # data follows. So we need to calculate the offsets accordingly, which + # luckily are dumped using --dumpconf (we only get the sizes, but we can + # infer the starting offset for the ZIP file using those). + local zipfileOffset="$( + eval "$($SHELL "$curSrc" --dumpconf)" + declare -i offset=1 + offset+="$(head -n $(($OLDSKIP - 1)) "$curSrc" | wc -c)" + for fs in $filesizes; do + offset+="$fs" + done + echo "$offset" + )" + + # Unfortunately bsdtar exits with failure if one of the patterns specified + # using the --include flag doesn't match. However, if the desktop icon is + # missing it's not the end of the world, so we need to find another way to + # make it happen without bsdtar returning a failure. + # + # Let's introduce -s, which is used to substitute the paths. While it may + # sound eligible to be used in conjunction --include, it's only really useful + # for our case if the inclusion patterns would be matched _after_ the + # substitiotions. Unfortunately, they're matched before the substitions. + # + # So what we do instead is rewrite *everything* that we want to include into + # a special path "/_/game" and rewrite everything that doesn't begin with / + # into "skip". We're (ab)using the fact here that files coming from the + # archive never start with "/", but during the substitutions the leading + # slash isn't stripped. + # + # In the end the resulting paths are normalized, so "/..." will be turned + # into "./...", so all we need to do in the end is to strip 2 components from + # the resulting path. This discards every path that has been renamed to + # "skip". + tail -c"+$zipfileOffset" "$curSrc" | bsdtar -xf - \ + -s '!^data/noarch/game/\(.*\)$!/_/game/\1!' \ + -s '!^data/noarch/support/icon\.png$!/_/game/xdg-icon.png!' \ + -s '!^[^/].*!skip!' --strip-components=2 +} + +_tryUnpackGogInnoSetup() { + innoextract -i "$curSrc" &> /dev/null || return 1 + + local -a unpackArgs=() + if [ -n "$innoExtractOnly" ]; then + local i + for i in $innoExtractOnly; do + unpackArgs+=("--include" "$i") + done + fi + + if [ -z "$innoExtractKeepCase" ]; then + unpackArgs+=("-L") + fi + + innoextract -s "${unpackArgs[@]}" -m "$curSrc" +} diff --git a/pkgs/games/default.nix b/pkgs/games/default.nix index bead9271..71ccdf5e 100644 --- a/pkgs/games/default.nix +++ b/pkgs/games/default.nix @@ -23,6 +23,7 @@ let self = import ./build-support { inherit (super) config; callPackage = pkgs.lib.callPackageWith (super // self); + callPackages = pkgs.lib.callPackagesWith (super // self); }; in self; |