about summary refs log tree commit diff
path: root/pkgs/games/steam
diff options
context:
space:
mode:
Diffstat (limited to 'pkgs/games/steam')
-rw-r--r--pkgs/games/steam/default.nix38
-rw-r--r--pkgs/games/steam/fetchsteam/default.nix91
-rw-r--r--pkgs/games/steam/fetchsteam/downloader.patch34
-rw-r--r--pkgs/games/steam/starbound.nix132
4 files changed, 295 insertions, 0 deletions
diff --git a/pkgs/games/steam/default.nix b/pkgs/games/steam/default.nix
new file mode 100644
index 00000000..03e6b180
--- /dev/null
+++ b/pkgs/games/steam/default.nix
@@ -0,0 +1,38 @@
+{ config, lib, pkgs, ... }:
+
+let
+  cfg = config.steam;
+
+  self = rec {
+    callPackage = pkgs.lib.callPackageWith (pkgs // self);
+
+    fetchSteam = callPackage ./fetchsteam {
+      inherit (config.steam) username password;
+    };
+
+    starbound = callPackage ./starbound.nix { flavor = "stable"; };
+    starbound-unstable = callPackage ./starbound.nix { flavor = "unstable"; };
+  };
+in with lib; {
+  options.steam = {
+    username = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        User name for your Steam account.
+      '';
+    };
+
+    password = mkOption {
+      type = types.nullOr types.str;
+      default = null;
+      description = ''
+        Password for your Steam account.
+      '';
+    };
+  };
+
+  config.packages = {
+    steam = mkIf (cfg.username != null && cfg.password != null) self;
+  };
+}
diff --git a/pkgs/games/steam/fetchsteam/default.nix b/pkgs/games/steam/fetchsteam/default.nix
new file mode 100644
index 00000000..cccddb51
--- /dev/null
+++ b/pkgs/games/steam/fetchsteam/default.nix
@@ -0,0 +1,91 @@
+{ stdenv, runCommand, writeText, fetchFromGitHub, buildDotnetPackage
+, username, password
+}:
+
+{ name, appId, depotId, manifestId, sha256, fileList ? [] }:
+
+let
+  protobuf-net = buildDotnetPackage rec {
+    baseName = "protobuf-net";
+    version = "2.0.0.668";
+
+    src = fetchFromGitHub {
+      owner = "mgravell";
+      repo = "protobuf-net";
+      rev = "r668";
+      sha256 = "1060pihqkbr9pd2z6m01d6fsbc9nj56m6y5a0pch9mqdmviv4896";
+    };
+
+    sourceRoot = "${src.name}/${baseName}";
+  };
+
+  SteamKit2 = buildDotnetPackage rec {
+    baseName = "SteamKit2";
+    version = "1.6.4";
+
+    src = fetchFromGitHub {
+      owner = "SteamRE";
+      repo = "SteamKit";
+      rev = "SteamKit_${version}";
+      sha256 = "17d7wi2f396qhp4w9sf37lazvsaqws8x071hfis9gv5llv6s7q46";
+    };
+
+    buildInputs = [ protobuf-net ];
+
+    xBuildFiles = [ "SteamKit2/SteamKit2.sln" ];
+    outputFiles = [ "SteamKit2/SteamKit2/bin/Release/*" ];
+  };
+
+  DepotDownloader = buildDotnetPackage rec {
+    baseName = "DepotDownloader";
+    version = "2.1.1git20160207";
+
+    src = fetchFromGitHub {
+      owner = "SteamRE";
+      repo = baseName;
+      rev = "5fa6621d9f9448fcd20c974b427a8bd2cb044cb4";
+      sha256 = "0vb566d7x1scd96c8ybq6gdbc2cv5jjq453ld458qcvfy587amfn";
+    };
+
+    patches = [ ./downloader.patch ];
+
+    postPatch = ''
+      sed -i \
+        -e 's/\(<[Rr]eference *[Ii]nclude="[^", ]\+\)[^"]*/\1/g' \
+        -e 's,<[Ss]pecific[Vv]ersion>[Tt]rue</[Ss]pecific[Vv]ersion>,,g' \
+        DepotDownloader/DepotDownloader.csproj
+      sed -i -e 's/ version="[^"]*"//g' DepotDownloader/packages.config
+    '';
+
+    buildInputs = [ SteamKit2 protobuf-net ];
+
+    outputFiles = [ "${baseName}/bin/Release/*" ];
+
+    # UUUGLY, but I don't want to spend a week trying to get this working
+    # without that nasty wrapper.
+    makeWrapperArgs = let
+      mkMono = name: path: "${path}/lib/dotnet/${name}";
+      paths = stdenv.lib.mapAttrsToList mkMono {
+        inherit SteamKit2 protobuf-net;
+      };
+      monoPath = stdenv.lib.concatStringsSep ":" paths;
+    in [ "--prefix MONO_PATH : \"${monoPath}\"" ];
+  };
+
+  fileListFile = let
+    content = stdenv.lib.concatStringsSep "\n" fileList;
+  in writeText "steam-file-list-${name}.txt" content;
+
+in with stdenv.lib; runCommand "${name}-src" {
+  buildInputs = [ DepotDownloader ];
+  inherit username password appId depotId manifestId;
+  outputHashAlgo = "sha256";
+  outputHash = sha256;
+  outputHashMode = "recursive";
+} ''
+  depotdownloader -app "$appId" -depot "$depotId" -manifest "$manifestId" \
+    ${optionalString (fileList != []) "-filelist \"${fileListFile}\""} \
+    -username "$username" -password "$password" -dir "$out"
+  rm -r "$out/.DepotDownloader"
+  rm "$out/_steam_depot_manifest_$depotId.csv"
+''
diff --git a/pkgs/games/steam/fetchsteam/downloader.patch b/pkgs/games/steam/fetchsteam/downloader.patch
new file mode 100644
index 00000000..72e5c473
--- /dev/null
+++ b/pkgs/games/steam/fetchsteam/downloader.patch
@@ -0,0 +1,34 @@
+diff --git a/DepotDownloader/ContentDownloader.cs b/DepotDownloader/ContentDownloader.cs
+index 21c317e..81f2a93 100644
+--- a/DepotDownloader/ContentDownloader.cs
++++ b/DepotDownloader/ContentDownloader.cs
+@@ -34,7 +34,7 @@ namespace DepotDownloader
+             public string installDir { get; private set; }
+             public string contentName { get; private set; }
+ 
+-            public ulong manifestId { get; private set; }
++            public ulong manifestId { get; set; }
+             public byte[] depotKey;
+ 
+             public DepotDownloadInfo(uint depotid, ulong manifestId, string installDir, string contentName)
+@@ -198,9 +198,6 @@ namespace DepotDownloader
+ 
+         static ulong GetSteam3DepotManifest(uint depotId, uint appId, string branch)
+         {
+-            if (Config.ManifestId != INVALID_MANIFEST_ID)
+-                return Config.ManifestId;
+-
+             KeyValue depots = GetSteam3AppSection(appId, EAppInfoSection.Depots);
+             KeyValue depotChild = depots[depotId.ToString()];
+ 
+@@ -583,6 +580,10 @@ namespace DepotDownloader
+                 ConfigStore.TheConfig.LastManifests[depot.id] = INVALID_MANIFEST_ID;
+                 ConfigStore.Save();
+ 
++                Console.WriteLine("Latest manifest ID is {0}.", depot.manifestId);
++                if (Config.ManifestId != INVALID_MANIFEST_ID)
++                    depot.manifestId = Config.ManifestId;
++
+                 if (lastManifestId != INVALID_MANIFEST_ID)
+                 {
+                     var oldManifestFileName = Path.Combine(configDir, string.Format("{0}.bin", lastManifestId));
diff --git a/pkgs/games/steam/starbound.nix b/pkgs/games/steam/starbound.nix
new file mode 100644
index 00000000..ba63fcfa
--- /dev/null
+++ b/pkgs/games/steam/starbound.nix
@@ -0,0 +1,132 @@
+{ stdenv, fetchSteam, makeWrapper, SDL, mesa, flavor ? "stable" }:
+
+let
+  renameAttrs = f: let
+    rename = name: value: {
+      name = f name;
+      inherit value;
+    };
+  in stdenv.lib.mapAttrs' rename;
+
+  darwinize = renameAttrs (bin: "Starbound.app/Contents/MacOS/${bin}");
+  winize = renameAttrs (bin: "${bin}.exe");
+
+  mkOsBinaryDeps = with stdenv.lib;
+    if stdenv.system == "x86_64-darwin" then darwinize
+    else if elem stdenv.system [ "i686-cygwin" "x86_64-cygwin" ] then winize
+    else id;
+
+  binaryDeps = mkOsBinaryDeps {
+    starbound.deps = [ SDL mesa ];
+    starbound_server.name = "starbound-server";
+    asset_packer.name = "starbound-asset-packer";
+    asset_unpacker.name = "starbound-asset-unpacker";
+    dump_versioned_json.name = "starbound-dump-versioned-json";
+    make_versioned_json.name = "starbound-make-versioned-json";
+    planet_mapgen.name = "starbound-planet-mapgen";
+  };
+
+  binpath = if stdenv.system == "x86_64-linux" then "linux64"
+            else if stdenv.system == "i686-linux" then "linux32"
+            else if stdenv.system == "x86_64-darwin" then "osx"
+            else if stdenv.system == "i686-cygwin" then "win32"
+            else if stdenv.system == "x86_64-cygwin" then "win64"
+            else throw "Unsupported system ${stdenv.system} for Starbound";
+
+  upstream = let
+    attrs = if flavor == "stable" then {
+      name = "starbound";
+      appId = 211820;
+      depotId = 211821;
+      manifestId = 1842730272313189605;
+      sha256 = "0qppfn56c778wsg38hi6sxgi3rl9nv72h9rmmxybi1vzpf3p49py";
+    } else if flavor == "unstable" then {
+      name = "starbound-unstable";
+      appId = 367540;
+      depotId = 367541;
+      manifestId = 6970641909803280413;
+      sha256 = "0qppfn56c778wsg38hi6sxgi3rl9nv72h9rmmxybi1vzpf3p49py";
+    } else throw "Unsupported flavor, use either `stable' or `unstable'.";
+  in fetchSteam (attrs // {
+    fileList = [
+      "^(?:assets|tiled)/"
+      ( "^${binpath}(?:/Starbound\\.app/Contents/MacOS)?"
+      + "/(?:[a-zA-Z0-9_-]+(?:\\.exe)?|sbboot\\.config)$")
+    ];
+  });
+
+in stdenv.mkDerivation {
+  name = "${upstream.name}-20160208";
+
+  unpackPhase = ":";
+
+  configurePhase = ''
+    libexec="$out/libexec/starbound"
+    data="$out/share/starbound"
+  '';
+
+  inherit binpath upstream;
+
+  buildInputs = [ makeWrapper ];
+
+  buildPhase = with stdenv.lib; ''
+    mkdir -p patched
+    sed -e 's,\.\./assets,'"$data/assets"',g' \
+        -e 's,\.\./giraffe_storage,.,g' \
+        "$upstream/$binpath/sbboot.config" > "patched/sbboot.config"
+  '' + concatStrings (mapAttrsToList (bin: attrs: ''
+    mkdir -p "patched/$(dirname "${bin}")"
+    cp -t "patched/$(dirname "${bin}")" "$upstream/$binpath/${bin}"
+    chmod +x "patched/$(basename "${bin}")"
+    patchelf \
+      --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \
+      --set-rpath "${stdenv.lib.makeLibraryPath (attrs.deps or [])}" \
+      "patched/$(basename "${bin}")"
+    if ldd "patched/$(basename "${bin}")" | grep -F 'not found'; then
+      exit 1;
+    fi
+  '') binaryDeps);
+
+  doCheck = true;
+
+  checkPhase = ''
+    checkFailed=
+    for i in "$upstream/$binpath"/*; do
+      [ -f "$i" ] || continue
+      [ "$(basename "$i")" != launcher ] || continue
+      [ ! -e "patched/$(basename "$i")" ] || continue
+
+      echo "Found missing binary $i from the upstream tree."
+      checkFailed=1
+    done
+    [ -z "$checkFailed" ]
+  '';
+
+  installPhase = ''
+    mkdir -p "$out/bin"
+    ${stdenv.lib.concatStrings (stdenv.lib.mapAttrsToList (bin: attrs: ''
+      prog="$(basename "${bin}")"
+      install -vD "patched/$prog" "$libexec/$prog"
+      cat > "$out/bin/${attrs.name or "$prog"}" <<EOF
+      #!${stdenv.shell} -e
+      [ -n "\$XDG_DATA_HOME" ] || XDG_DATA_HOME="\$HOME/.local/share"
+      mkdir -p "\$XDG_DATA_HOME/starbound/mods"
+      ln -sf "$out/etc/sbboot.config" "\$XDG_DATA_HOME/starbound/sbboot.config"
+      cd "\$XDG_DATA_HOME/starbound"
+      exec "$libexec/$prog" "\$@"
+      EOF
+      chmod +x "$out/bin/${attrs.name or "$prog"}"
+    '') binaryDeps)}
+
+    install -vD -m 644 patched/sbboot.config "$out/etc/sbboot.config"
+
+    mkdir -p "$data"
+    for i in assets tiled; do
+      echo -n "Installing $i..."
+      cp -rt "$data" "$upstream/$i"
+      echo " done."
+    done
+  '';
+
+  dontStrip = true;
+}