From f3817f7c8214b4ff74d86a207c770ababcc91099 Mon Sep 17 00:00:00 2001 From: magges Date: Sat, 27 Jun 2026 10:26:21 +0200 Subject: [PATCH] feat: initial Elsword-GE builder --- .gitea/workflows/build.yml | 101 +++++++ .gitignore | 2 + README.md | 95 +++++++ build.sh | 570 +++++++++++++++++++++++++++++++++++++ flake.lock | 27 ++ flake.nix | 27 ++ 6 files changed, 822 insertions(+) create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100755 build.sh create mode 100644 flake.lock create mode 100644 flake.nix diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..47496c7 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,101 @@ +name: build-elsword-ge + +on: + schedule: + - cron: "0 4 * * *" + workflow_dispatch: + +permissions: + contents: write + +jobs: + build-release: + runs-on: self-hosted + steps: + - name: Checkout repository + run: | + git init . + git config --global --add safe.directory "$PWD" + git remote add origin "${{ gitea.server_url }}/${{ gitea.repository }}.git" + git -c http.extraHeader="Authorization: token ${{ secrets.GITEA_TOKEN }}" fetch --depth 1 origin "${{ gitea.sha }}" + git checkout --detach FETCH_HEAD + + - name: Build Elsword Proton-GE 10-34 tool + run: | + nix develop -c ./build.sh --no-install + + - name: Create or update Gitea release + env: + GITEA_SERVER_URL: ${{ gitea.server_url }} + GITEA_REPOSITORY: ${{ gitea.repository }} + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + GITEA_SHA: ${{ gitea.sha }} + run: | + nix develop -c bash -lc ' + set -euo pipefail + set -a + . dist/package-info.env + set +a + + RELEASE_API="${GITEA_SERVER_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases" + RELEASE_TAG_URL="$(python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=\"\"))" "$RELEASE_TAG")" + ARCHIVE_URL_NAME="$(python3 -c "import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=\"\"))" "$ARCHIVE_FILE")" + + HTTP_CODE="$(curl -s -o /tmp/release.json -w "%{http_code}" \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${RELEASE_API}/tags/${RELEASE_TAG_URL}")" + + if [ "$HTTP_CODE" = "200" ]; then + RELEASE_ID="$(python3 -c "import json; print(json.load(open(\"/tmp/release.json\"))[\"id\"])" )" + elif [ "$HTTP_CODE" = "404" ]; then + python3 -c "import json, pathlib, os; pathlib.Path(\"/tmp/release-create.json\").write_text(json.dumps({ + \"tag_name\": os.environ[\"RELEASE_TAG\"], + \"target_commitish\": os.environ[\"GITEA_SHA\"], + \"name\": os.environ[\"RELEASE_TAG\"], + \"body\": pathlib.Path(\"dist/release-notes.md\").read_text(), + \"draft\": False, + \"prerelease\": False, + }))" + curl --fail-with-body \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + --data-binary @/tmp/release-create.json \ + "${RELEASE_API}" > /tmp/release.json + RELEASE_ID="$(python3 -c "import json; print(json.load(open(\"/tmp/release.json\"))[\"id\"])" )" + else + cat /tmp/release.json + exit 1 + fi + + python3 -c "import json, pathlib, os; pathlib.Path(\"/tmp/release-update.json\").write_text(json.dumps({ + \"tag_name\": os.environ[\"RELEASE_TAG\"], + \"target_commitish\": os.environ[\"GITEA_SHA\"], + \"name\": os.environ[\"RELEASE_TAG\"], + \"body\": pathlib.Path(\"dist/release-notes.md\").read_text(), + \"draft\": False, + \"prerelease\": False, + }))" + curl --fail-with-body \ + -X PATCH \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + --data-binary @/tmp/release-update.json \ + "${RELEASE_API}/${RELEASE_ID}" > /tmp/release.json + + curl --fail-with-body \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${RELEASE_API}/${RELEASE_ID}/assets" > /tmp/assets.json + + EXISTING_ASSET_ID="$(python3 -c "import json, os; data=json.load(open(\"/tmp/assets.json\")); target=os.environ[\"ARCHIVE_FILE\"]; print(next((str(item[\"id\"]) for item in data if item.get(\"name\") == target), \"\"))")" + if [ -n "$EXISTING_ASSET_ID" ]; then + curl --fail-with-body \ + -X DELETE \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${RELEASE_API}/${RELEASE_ID}/assets/${EXISTING_ASSET_ID}" + fi + + curl --fail-with-body \ + -H "Authorization: token ${GITEA_TOKEN}" \ + --data-binary @"dist/${ARCHIVE_FILE}" \ + "${RELEASE_API}/${RELEASE_ID}/assets?name=${ARCHIVE_URL_NAME}" + ' diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c98b99c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.cache/ +dist/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..3b5a5f8 --- /dev/null +++ b/README.md @@ -0,0 +1,95 @@ +# Elsword Proton-GE Builder + +Dieses Repo baut per Gitea Actions versionierte Proton-GE-Kompatibilitätstools +für Elsword mit `dxvk-git` und Steam Linux Runtime 3.0 (`sniper`). + +## Was gebaut wird + +- Tool-Name: `Elsword-GE-(Version)` +- Beispiel: `Elsword-GE-11-1` +- Runtime: `1628350` (`Steam Linux Runtime 3.0`) +- DXVK: standardmäßig `dxvk-git` +- Ausgabe: versionierte `.tar.xz`-Archive in `dist/` + +Ältere lokal installierte Versionen wie `Elsword-GE-10-30` bleiben bestehen, +weil jede Build ihren eigenen Tool-Namen bekommt. + +## Ablauf + +1. Das Repo nutzt standardmäßig `GE-Proton10-34`. +2. DXVK wird aus Upstream gebaut, standardmäßig als `dxvk-git`. +3. Die GE-Basis wird auf `sniper` umgestellt. +4. Die DXVK-DLLs in Proton-GE werden ersetzt. +5. Das Ergebnis wird als eigenes Steam-Compatibility-Tool paketiert. +6. Die Gitea Action erstellt oder aktualisiert ein Release und lädt das Archiv hoch. + +## Standardverhalten + +Ohne Parameter baut `build.sh`: + +- `GE-Proton10-34` +- mit `dxvk-git` +- als Tool `Elsword-GE-(Version)` +- mit `sniper` + +## Lokaler Build + +```bash +nix develop -c ./build.sh +``` + +Nur Archiv bauen, nicht lokal installieren: + +```bash +nix develop -c ./build.sh --no-install +``` + +Einen bestimmten GE-Tag bauen: + +```bash +nix develop -c ./build.sh --proton-tag GE-Proton11-1 +``` + +Eigenen Tool-Namen setzen: + +```bash +nix develop -c ./build.sh --tool-name Elsword-GE-test +``` + +## Wichtige Optionen + +- `--proton-tag TAG` +- `--proton-asset x86_64|aarch64` +- `--dxvk-channel git|stable` +- `--dxvk-tag TAG` +- `--tool-prefix PREFIX` +- `--tool-name NAME` +- `--runtime-appid APPID` +- `--no-install` + +## Gitea Actions + +Der Workflow liegt unter: + +- `.gitea/workflows/build.yml` + +Er läuft bei: + +- manuellem Start per `workflow_dispatch` +- automatischem Zeitplan täglich + +Für Release-Uploads braucht der Workflow ein Secret: + +- `GITEA_TOKEN` + +Dieses Token muss Release-Schreibrechte auf das Repo haben. + +## Release-Ausgabe + +Nach einem Build schreibt das Skript nach `dist/`: + +- das fertige `.tar.xz`-Archiv +- `package-info.env` +- `release-notes.md` + +Die Gitea Action nutzt diese Dateien direkt für das Release. diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..0d78d49 --- /dev/null +++ b/build.sh @@ -0,0 +1,570 @@ +#!/usr/bin/env bash + +set -euo pipefail + +REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +CACHE_DIR="$REPO_ROOT/.cache" +DIST_DIR="$REPO_ROOT/dist" +WORK_BASE="$CACHE_DIR/work" +DXVK_CACHE_DIR="$CACHE_DIR/dxvk" +STEAM_COMPAT_DIR="${HOME}/.local/share/Steam/compatibilitytools.d" +UPSTREAM_REPO="GloriousEggroll/proton-ge-custom" +PROTON_TAG="GE-Proton10-34" +PROTON_ASSET="x86_64" +DXVK_CHANNEL="git" +DXVK_TAG="latest" +RUNTIME_APPID="1628350" +TOOL_PREFIX="Elsword-GE" +TOOL_NAME="" +KEEP_WORK=0 +DXVK_SRC_OVERRIDE="" +MINGW_PTHREAD_ROOT="${MINGW_PTHREAD_ROOT:-}" +INSTALL_TOOL=1 +DXVK_DESCRIBE="" +DXVK_FULL_SHA="" +DXVK_SHORT_SHA="" + +usage() { + cat <<'EOF' +Usage: ./build.sh [options] + +Build a custom Proton-GE compatibility tool for Elsword and replace its bundled +DXVK with a chosen DXVK build, defaulting to GE-Proton10-34 plus dxvk-git on +Steam Linux Runtime 3.0 (sniper). + +Options: + --proton-tag TAG Build a specific Proton-GE release tag, default: GE-Proton10-34 + --proton-asset x86_64|aarch64 Choose which Proton-GE asset to use + --dxvk-channel git|stable Choose DXVK source channel, default: git + --dxvk-tag TAG Stable DXVK tag to use when --dxvk-channel stable + --tool-prefix PREFIX Tool name prefix, default: Elsword-GE + --tool-name NAME Override final tool name completely + --runtime-appid APPID Steam Runtime appid, default: 1628350 (sniper) + --steam-compat-dir PATH Override compatibilitytools.d path + --dxvk-src PATH Use an existing dxvk checkout instead of cache + --mingw-pthread-root PATH Path with x32/libpthread.a and x64/libpthread.a + --dist-dir PATH Output directory for sendable archives + --no-install Build/package only, do not install into Steam + --keep-work Keep temporary work directory + -h, --help Show this help +EOF +} + +while [[ $# -gt 0 ]]; do + case "$1" in + --proton-tag) + PROTON_TAG="${2:?missing value for --proton-tag}" + shift 2 + ;; + --proton-asset) + PROTON_ASSET="${2:?missing value for --proton-asset}" + shift 2 + ;; + --dxvk-channel) + DXVK_CHANNEL="${2:?missing value for --dxvk-channel}" + shift 2 + ;; + --dxvk-tag) + DXVK_TAG="${2:?missing value for --dxvk-tag}" + shift 2 + ;; + --tool-prefix) + TOOL_PREFIX="${2:?missing value for --tool-prefix}" + shift 2 + ;; + --tool-name) + TOOL_NAME="${2:?missing value for --tool-name}" + shift 2 + ;; + --runtime-appid) + RUNTIME_APPID="${2:?missing value for --runtime-appid}" + shift 2 + ;; + --steam-compat-dir) + STEAM_COMPAT_DIR="${2:?missing value for --steam-compat-dir}" + shift 2 + ;; + --dxvk-src) + DXVK_SRC_OVERRIDE="${2:?missing value for --dxvk-src}" + shift 2 + ;; + --mingw-pthread-root) + MINGW_PTHREAD_ROOT="${2:?missing value for --mingw-pthread-root}" + shift 2 + ;; + --dist-dir) + DIST_DIR="${2:?missing value for --dist-dir}" + shift 2 + ;; + --no-install) + INSTALL_TOOL=0 + shift + ;; + --keep-work) + KEEP_WORK=1 + shift + ;; + -h|--help) + usage + exit 0 + ;; + *) + echo "Unknown option: $1" >&2 + usage >&2 + exit 1 + ;; + esac +done + +case "$PROTON_ASSET" in + x86_64|aarch64) ;; + *) + echo "Unsupported --proton-asset: $PROTON_ASSET" >&2 + exit 1 + ;; +esac + +case "$DXVK_CHANNEL" in + git|stable) ;; + *) + echo "Unsupported --dxvk-channel: $DXVK_CHANNEL" >&2 + exit 1 + ;; +esac + +require_cmd() { + command -v "$1" >/dev/null 2>&1 || { + echo "Missing required command: $1" >&2 + exit 1 + } +} + +for cmd in \ + curl \ + git \ + nix \ + tar \ + meson \ + ninja \ + python3 \ + realpath \ + glslangValidator \ + x86_64-w64-mingw32-gcc \ + x86_64-w64-mingw32-g++ \ + i686-w64-mingw32-gcc \ + i686-w64-mingw32-g++ \ + wine; do + require_cmd "$cmd" +done + +mkdir -p "$CACHE_DIR" "$WORK_BASE" "$DIST_DIR" +if [[ "$INSTALL_TOOL" -eq 1 ]]; then + mkdir -p "$STEAM_COMPAT_DIR" +fi +WORK_DIR="$(mktemp -d "$WORK_BASE/build.XXXXXX")" + +cleanup() { + if [[ "$KEEP_WORK" -ne 1 ]]; then + rm -rf "$WORK_DIR" + fi +} +trap cleanup EXIT + +say() { + printf '\n==> %s\n' "$1" >&2 +} + +tool_version_from_tag() { + local tag="$1" + local version="${tag#GE-Proton}" + if [[ "$version" == "$tag" ]]; then + printf '%s\n' "$tag" + else + printf '%s\n' "$version" + fi +} + +get_latest_proton_tag() { + curl -fsSL "https://api.github.com/repos/${UPSTREAM_REPO}/releases/latest" \ + | grep -oP '"tag_name":\s*"\K[^"]+' \ + | head -n1 +} + +get_latest_dxvk_tag() { + curl -fsSL https://api.github.com/repos/doitsujin/dxvk/releases/latest \ + | grep -oP '"tag_name":\s*"\K[^"]+' \ + | head -n1 +} + +prepare_dxvk_cache() { + if [[ ! -d "$DXVK_CACHE_DIR/.git" ]]; then + say "Clone dxvk" + git clone --recursive https://github.com/doitsujin/dxvk.git "$DXVK_CACHE_DIR" >&2 + else + say "Update dxvk cache" + git -C "$DXVK_CACHE_DIR" fetch --tags origin >&2 + git -C "$DXVK_CACHE_DIR" checkout master >&2 + git -C "$DXVK_CACHE_DIR" reset --hard origin/master >&2 + git -C "$DXVK_CACHE_DIR" submodule update --init --recursive >&2 + git -C "$DXVK_CACHE_DIR" clean -fdx >&2 + fi +} + +prepare_dxvk_repo() { + local source_repo ref_name checkout_dir + checkout_dir="$WORK_DIR/dxvk-src" + + if [[ -n "$DXVK_SRC_OVERRIDE" ]]; then + source_repo="$DXVK_SRC_OVERRIDE" + else + prepare_dxvk_cache + source_repo="$DXVK_CACHE_DIR" + fi + + if [[ "$DXVK_CHANNEL" == "stable" ]]; then + ref_name="$DXVK_TAG" + if [[ -z "$ref_name" || "$ref_name" == "latest" ]]; then + ref_name="$(get_latest_dxvk_tag)" + fi + if [[ -z "$ref_name" ]]; then + echo "Failed to resolve DXVK stable tag" >&2 + exit 1 + fi + else + ref_name="HEAD" + fi + + say "Prepare DXVK source ($DXVK_CHANNEL)" + git clone --recursive "$source_repo" "$checkout_dir" >&2 + + if [[ "$DXVK_CHANNEL" == "stable" ]]; then + git -C "$checkout_dir" fetch --tags https://github.com/doitsujin/dxvk.git >&2 + git -C "$checkout_dir" checkout "refs/tags/$ref_name" >&2 + git -C "$checkout_dir" submodule update --init --recursive >&2 + fi + + echo "$checkout_dir" +} + +build_dxvk() { + local dxvk_src="$1" + local dxvk_build_dir="$WORK_DIR/dxvk-out/dxvk-${DXVK_CHANNEL}" + local toolchain_dir="$WORK_DIR/toolchain" + local pthread_dir="$WORK_DIR/mingw-pthread" + + DXVK_SHORT_SHA="$(git -C "$dxvk_src" rev-parse --short HEAD)" + DXVK_FULL_SHA="$(git -C "$dxvk_src" rev-parse HEAD)" + DXVK_DESCRIBE="$(git -C "$dxvk_src" describe --always --tags --dirty)" + + say "Build DXVK ($DXVK_DESCRIBE)" + rm -rf "$WORK_DIR/dxvk-out" "$toolchain_dir" "$pthread_dir" + mkdir -p "$dxvk_build_dir" "$toolchain_dir" "$pthread_dir/x32" "$pthread_dir/x64" + + if [[ -n "$MINGW_PTHREAD_ROOT" \ + && -f "$MINGW_PTHREAD_ROOT/x32/libpthread.a" \ + && -f "$MINGW_PTHREAD_ROOT/x64/libpthread.a" ]]; then + ln -sf "$MINGW_PTHREAD_ROOT/x32/libpthread.a" "$pthread_dir/x32/libpthread.a" + ln -sf "$MINGW_PTHREAD_ROOT/x64/libpthread.a" "$pthread_dir/x64/libpthread.a" + else + local mcfg32 mcfg64 + mcfg32="$(NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1 nix path-info --impure nixpkgs#pkgsCross.mingw32.windows.mcfgthreads)" + mcfg64="$(NIXPKGS_ALLOW_UNSUPPORTED_SYSTEM=1 nix path-info --impure nixpkgs#pkgsCross.mingwW64.windows.mcfgthreads)" + ln -sf "$mcfg32/lib/libmcfgthread.a" "$pthread_dir/x32/libpthread.a" + ln -sf "$mcfg64/lib/libmcfgthread.a" "$pthread_dir/x64/libpthread.a" + fi + + cat > "$toolchain_dir/x86_64-w64-mingw32-gcc" < "$toolchain_dir/x86_64-w64-mingw32-g++" < "$toolchain_dir/i686-w64-mingw32-gcc" < "$toolchain_dir/i686-w64-mingw32-g++" < "$toolchain_dir/build-win64-mcfg.txt" < "$toolchain_dir/build-win32-mcfg.txt" <&2 + ninja -C "$dxvk_build_dir/build.64" install >&2 + + meson setup --cross-file "$toolchain_dir/build-win32-mcfg.txt" \ + --buildtype release \ + --prefix "$dxvk_build_dir" \ + --strip \ + --bindir x32 \ + --libdir x32 \ + -Db_ndebug=if-release \ + "$dxvk_build_dir/build.32" >&2 + ninja -C "$dxvk_build_dir/build.32" install >&2 + ) + + rm -f "$dxvk_build_dir/x64/"*.a "$dxvk_build_dir/x32/"*.a + rm -rf "$dxvk_build_dir/build.64" "$dxvk_build_dir/build.32" + + echo "$DXVK_SHORT_SHA" +} + +download_proton() { + local proton_tag="$1" + local asset_file + local proton_tarball + local proton_url + + if [[ "$PROTON_ASSET" == "aarch64" ]]; then + asset_file="${proton_tag}-aarch64.tar.gz" + else + asset_file="${proton_tag}.tar.gz" + fi + + proton_tarball="$CACHE_DIR/${asset_file}" + proton_url="https://github.com/${UPSTREAM_REPO}/releases/download/${proton_tag}/${asset_file}" + + if [[ ! -f "$proton_tarball" ]]; then + say "Download Proton-GE ${proton_tag} (${PROTON_ASSET})" + curl -fL "$proton_url" -o "$proton_tarball" + else + say "Reuse cached Proton tarball" + fi + + echo "$proton_tarball" +} + +replace_tree() { + local source_dir="$1" + local target_dir="$2" + mkdir -p "$target_dir" + for dll in d3d8.dll d3d9.dll d3d10core.dll d3d11.dll dxgi.dll openvr_api_dxvk.dll; do + if [[ -f "$source_dir/$dll" ]]; then + cp -f "$source_dir/$dll" "$target_dir/$dll" + fi + done +} + +replace_base_dlls() { + local source_dir="$1" + local target_dir="$2" + mkdir -p "$target_dir" + for dll in d3d8.dll d3d9.dll d3d10core.dll d3d11.dll ddraw.dll dxgi.dll; do + if [[ -f "$source_dir/$dll" ]]; then + cp -f "$source_dir/$dll" "$target_dir/$dll" + fi + done +} + +patch_tool() { + local tool_root="$1" + local tool_name="$2" + local proton_tag="$3" + local dxvk_src="$4" + local dxvk_short_dir="$WORK_DIR/dxvk-out/dxvk-${DXVK_CHANNEL}" + local timestamp + + timestamp="$(date -u +%Y-%m-%dT%H:%M:%SZ)" + + say "Replace DXVK payload" + replace_tree "$dxvk_short_dir/x64" "$tool_root/files/lib/wine/dxvk/x86_64-windows" + replace_tree "$dxvk_short_dir/x32" "$tool_root/files/lib/wine/dxvk/i386-windows" + replace_base_dlls "$dxvk_short_dir/x64" "$tool_root/files/lib/wine/x86_64-windows" + replace_base_dlls "$dxvk_short_dir/x32" "$tool_root/files/lib/wine/i386-windows" + replace_base_dlls "$dxvk_short_dir/x64" "$tool_root/files/share/default_pfx/drive_c/windows/system32" + replace_base_dlls "$dxvk_short_dir/x32" "$tool_root/files/share/default_pfx/drive_c/windows/syswow64" + + chmod u+w \ + "$tool_root/files/lib/wine/dxvk/version" \ + "$tool_root/version" \ + "$tool_root/toolmanifest.vdf" 2>/dev/null || true + + printf '%s dxvk (%s)\n' "$DXVK_FULL_SHA" "$DXVK_DESCRIBE" > "$tool_root/files/lib/wine/dxvk/version" + printf '%s %s\n' "$(date +%s)" "$tool_name" > "$tool_root/version" + + cat > "$tool_root/compatibilitytool.vdf" < "$tool_root/toolmanifest.vdf" < "$tool_root/BUILD-INFO.txt" < "$DIST_DIR/package-info.env" < "$DIST_DIR/release-notes.md" </dev/null +PROTON_TARBALL="$(download_proton "$PROTON_TAG")" + +say "Extract Proton-GE" +mkdir -p "$WORK_DIR/proton" +tar -xf "$PROTON_TARBALL" -C "$WORK_DIR/proton" +TOOL_ROOT="$(find "$WORK_DIR/proton" -mindepth 1 -maxdepth 1 -type d | head -n1)" +if [[ -z "$TOOL_ROOT" ]]; then + echo "Could not find extracted Proton tool root" >&2 + exit 1 +fi + +patch_tool "$TOOL_ROOT" "$TOOL_NAME" "$PROTON_TAG" "$DXVK_SRC" +ARCHIVE_PATH="$(package_tool "$TOOL_ROOT" "$TOOL_NAME")" +write_dist_metadata "$ARCHIVE_PATH" "$TOOL_NAME" "$PROTON_TAG" + +if [[ "$INSTALL_TOOL" -eq 1 ]]; then + INSTALLED_PATH="$(install_tool "$TOOL_ROOT" "$TOOL_NAME")" +fi + +say "Done" +printf 'Archive: %s\n' "$ARCHIVE_PATH" +if [[ "$INSTALL_TOOL" -eq 1 ]]; then + printf 'Installed: %s\n' "$INSTALLED_PATH" +fi +printf 'Proton-GE: %s (%s)\n' "$PROTON_TAG" "$PROTON_ASSET" +printf 'DXVK: %s\n' "$DXVK_DESCRIBE" +printf 'Runtime: %s\n' "$RUNTIME_APPID" +if [[ "$INSTALL_TOOL" -eq 1 ]]; then + printf '\nRestart Steam and choose "%s" as compatibility tool.\n' "$TOOL_NAME" +else + printf '\nShare the archive or unpack it into compatibilitytools.d on another system.\n' +fi diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..a94690d --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1782467914, + "narHash": "sha256-pGvFkM8N0xEkIIXDe5YYfbEAvHrk4IxBrjB/x8OomhE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "e73de5be04e0eff4190a1432b946d469c794e7b4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..eb1f389 --- /dev/null +++ b/flake.nix @@ -0,0 +1,27 @@ +{ + description = "Build versioned Elsword Proton-GE tools with DXVK and sniper runtime"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = { self, nixpkgs }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { inherit system; }; + in + { + devShells.${system}.default = pkgs.mkShell { + packages = with pkgs; [ + curl + git + glslang + meson + ninja + pkg-config + python3 + wineWow64Packages.stable + pkgsCross.mingw32.stdenv.cc + pkgsCross.mingwW64.stdenv.cc + ]; + }; + }; +}