diff --git a/pkgs/slippi-launcher/default.nix b/pkgs/slippi-launcher/default.nix new file mode 100644 index 0000000..15c76db --- /dev/null +++ b/pkgs/slippi-launcher/default.nix @@ -0,0 +1,183 @@ +{ lib +, fetchFromGitHub +, electron +, nodejs +, makeWrapper +, git +, stdenv +, yarnConfigHook +, fetchYarnDeps +}: + +# Similar derivations: +# - Logseq: https://github.com/NixOS/nixpkgs/blob/nixos-25.05/pkgs/by-name/lo/logseq/package.nix#L283 +# - Podman: https://github.com/NixOS/nixpkgs/blob/224042e9a3039291f22f4f2ded12af95a616cca0/pkgs/applications/virtualization/podman-desktop/default.nix + +stdenv.mkDerivation (final: { + pname = "slippi-launcher"; + version = "2.11.10"; + + src = fetchFromGitHub { + owner = "project-slippi"; + repo = "slippi-launcher"; + rev = "v${final.version}"; + hash = "sha256-EWKxzGLjyJ15wGioUtfh3biU7Pfa5bYtV1Om2w5IZW8="; + leaveDotGit = true; + }; + + patches = [ + # Dependency with git+https protocol breaks yarnConfigHook. + ./fix-git-deps.patch + ]; + + # Avoid network error during build. + # https://stackoverflow.com/questions/78004799/78004800 + env.ELECTRON_SKIP_BINARY_DOWNLOAD = 1; + + buildInputs = [ + electron + ]; + + nativeBuildInputs = [ + yarnConfigHook + nodejs + electron + git + makeWrapper + ]; + + # Disable the default usage of yarnConfigHook. We instead opt to run the hook + # manually (several times) for reasons made clear in the commentary on this + # package's `postConfigure` script. + dontYarnInstallDeps = true; + + configurePhase = + let + # Constants to be set in the .env file. Slippi contains an example .env + # file here: + # https://github.com/project-slippi/slippi-launcher/blob/main/.env.example + dotenv = { + # N.B. although these values are *not* secrets (yes, even the API key), they + # were extracted from the AppImage release. + FIREBASE_API_KEY = "AIzaSyAuQqc_wgqcUu3FqrICEPZ9Av_hPxMR_i4"; + FIREBASE_AUTH_DOMAIN = "slippi.firebaseapp.com"; + FIREBASE_DATABASE_URL = "https://slippi.firebaseio.com"; + FIREBASE_PROJECT_ID = "slippi"; + FIREBASE_STORAGE_BUCKET = "slippi.appspot.com"; + FIREBASE_MESSAGING_SENDER_ID = "101358986051"; + FIREBASE_APP_ID = "1:101358986051:web:1e361ce2a76dfd1b0f85f6"; + FIREBASE_MEASUREMENT_ID = "G-VNB1EB87Y2"; + + # Ditto. + SLIPPI_WS_SERVER = "ws://broadcast-dot-slippi.uc.r.appspot.com/"; + SLIPPI_GRAPHQL_ENDPOINT = "/graphql"; + }; + in '' + runHook preConfigure + + # For reasons I don't quite understand[1], this package is split across two + # `package.json` files. We call yarnConfigHook once for each package.json + # to install their respective dependencies. Each yarnConfigHook call uses a + # separate offline cache. + # + # [1]: https://www.electron.build/tutorials/two-package-structure.html + yarnOfflineCache="$yarnOfflineCacheRoot" yarnConfigHook + + pushd release/app + yarnOfflineCache="$yarnOfflineCacheRelease" yarnConfigHook + popd + + # Merge the dependencies listed in release/app/package.json into the + # node_modules/ directory corresponding to the top-level package.json. + # This feels very wrong! Surely there's a better way… + for i in release/app/node_modules/*; do + dest="node_modules/$(basename "$i")" + if [[ ! -f "$dest" ]]; then + mv "$i" "$dest" + fi + done + + # Populate the .env file. + tee .env << EOF + ${lib.concatLines + (lib.mapAttrsToList (k: v: "${k}=${v}") dotenv)} + EOF + + runHook postConfigure + ''; + + buildPhase = '' + runHook preBuild + + cp -r ${electron.dist} electron-dist + chmod -R u+w electron-dist + + # Run builds concurrently. Taken from Slippi's `yarn run package` script, + # but we've added the `--ofline` flag. + yarn --offline run build:main & + yarn --offline run build:renderer & + yarn --offline run build:migrations & + wait + + # Build to release/build/linux-unwrapped. The flag `--dir` stops + # electron-builder before creating an AppImage. + ./node_modules/.bin/electron-builder \ + build --dir --publish never \ + -c.electronDist=electron-dist \ + -c.electronVersion=${electron.version} + + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/{bin,opt/slippi-launcher} + cp -r release/build/linux-unpacked/* $out/opt/slippi-launcher + + # Electron programs need to differentiate between production and + # non-production builds, and they do so by testing if argv[0] is 'electron' + # or not. Thus, --inherit-argv0 should be all we need; however, this is not + # the case. God knows why. Just suck it up and set + # ELECTRON_FORCE_IS_PACKAGED=true. + makeWrapper '${lib.getExe electron}' $out/bin/slippi-launcher \ + --add-flags "$out/opt/slippi-launcher/resources/app.asar" \ + --add-flags "\''${NIXOS_OZONE_WL:+\''${WAYLAND_DISPLAY:+--ozone-platform=wayland --enable-features=WaylandWindowDecorations --enable-wayland-ime=true}}" \ + --prefix LD_LIBRARY_PATH : $out/opt/slippi-launcher \ + --inherit-argv0 \ + --set ELECTRON_FORCE_IS_PACKAGED true + + runHook postInstall + ''; + + yarnOfflineCacheRoot = fetchYarnDeps { + name = "slippi-launcher-yarn-deps-root"; + # One of our patches modifies the (top-level) Yarn lockfile and thus must be + # visible to fetchYarnDeps. + inherit (final) src patches; + hash = "sha256-Crq9XywLtEc8IImkldodZJ823YG6dB8D9qGksH/lb3I="; + }; + + yarnOfflineCacheRelease = fetchYarnDeps { + name = "slippi-launcher-yarn-deps-resources"; + # Our patches don't touch the lockfile at release/app/yarn.lock, so there's + # no need to inherit patches }:). + inherit (final) src; + sourceRoot = "${final.src.name}/release/app"; + hash = "sha256-iCFqgy+jRaMCoGC77iXkEh964cZAtXFRfdOOJaRTfLc="; + }; + + meta = { + description = "The way to play Slippi Online and watch replays."; + longDescription = '' + The Slippi Launcher acts as a one stop shop for everything Slippi + related. It handles updating Slippi Dolphin, playing Slippi Online, + launching and analyzing replays, and more. + ''; + license = lib.licenses.gpl3; + homepage = "https://github.com/project-slippi/slippi-launcher"; + changelog = + "https://github.com/project-slippi/slippi-launcher/releases/tag/v${final.version}"; + platforms = lib.platforms.all; + }; +}) diff --git a/pkgs/slippi-launcher/fix-git-deps.patch b/pkgs/slippi-launcher/fix-git-deps.patch new file mode 100644 index 0000000..b9c4f4b --- /dev/null +++ b/pkgs/slippi-launcher/fix-git-deps.patch @@ -0,0 +1,16 @@ +diff --git a/yarn.lock b/yarn.lock +index 6b2fba28..40ed0fc4 100644 +--- a/yarn.lock ++++ b/yarn.lock +@@ -1848,9 +1848,9 @@ + global-agent "^3.0.0" + global-tunnel-ng "^2.7.1" + +-"@electron/node-gyp@git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2": ++"@electron/node-gyp@https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2": + version "10.2.0-electron.1" +- resolved "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2" ++ resolved "https://github.com/electron/node-gyp#06b29aafb7708acef8b3669835c8a7857ebc92d2" + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1"