From 4795751631170ecdae971edc1a41444e0f6bdce3 Mon Sep 17 00:00:00 2001 From: Isuldor Date: Sat, 27 Jun 2026 11:54:34 -0700 Subject: [PATCH] Add EQL installer --- .gitignore | 1 + .vscode/extensions.json | 5 + README.md | 16 +++- docs/eqlegends.md | 98 +++++++++++++++++++ flake.nix | 9 ++ packages/eqlegends/package.nix | 168 +++++++++++++++++++++++++++++++++ 6 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 .vscode/extensions.json create mode 100644 docs/eqlegends.md create mode 100644 packages/eqlegends/package.nix diff --git a/.gitignore b/.gitignore index b2be92b..dc3425e 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ result +EQLegends_setup.exe diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..76d746c --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "jnoortheen.nix-ide" + ] +} diff --git a/README.md b/README.md index 411f478..332967c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ Nix flake packaging EverQuest-related tools for Linux. Packages wrap prebuilt Wi | Flake output | Description | |--------------|-------------| +| `eqlegends` | EverQuest Legends standalone LaunchPad installer via Wine | | `eqlogparser` | [EQLogParser](https://github.com/kauffman12/EQLogParser) via Wine (matches Bottles/Flatpak setup) | More apps will be added over time. @@ -13,12 +14,21 @@ More apps will be added over time. ## Quick start ```bash -nix run .#eqlogparser +nix run .#eqlegends # or +nix run .#eqlogparser +``` + +`eqlegends` expects `EQLegends_setup.exe` in the current directory, or set `EQL_INSTALLER=/path/to/EQLegends_setup.exe`. + +For EQLogParser: + +```bash nix profile install .#eqlogparser eqlogparser ``` +See [docs/eqlegends.md](docs/eqlegends.md) for EverQuest Legends setup and troubleshooting. See [docs/eqlogparser.md](docs/eqlogparser.md) for first-run setup, logs, and troubleshooting ([Wine notes](docs/eqlogparser-wine.md)). ## Custom nixpkgs @@ -26,6 +36,7 @@ See [docs/eqlogparser.md](docs/eqlogparser.md) for first-run setup, logs, and tr The flake pins `github:NixOS/nixpkgs/nixos-unstable`. To use a local checkout, override the input: ```bash +nix run .#eqlegends --override-input nixpkgs path:/path/to/nixpkgs nix run .#eqlogparser --override-input nixpkgs path:/path/to/nixpkgs ``` @@ -36,9 +47,12 @@ Or edit `flake.nix` / `flake.lock` to point `nixpkgs` at your fork. ``` flake.nix packages/ + eqlegends/ + package.nix eqlogparser/ package.nix docs/ + eqlegends.md eqlogparser.md eqlogparser-wine.md ``` diff --git a/docs/eqlegends.md b/docs/eqlegends.md new file mode 100644 index 0000000..3e6e0c7 --- /dev/null +++ b/docs/eqlegends.md @@ -0,0 +1,98 @@ +# EverQuest Legends on NixOS via Wine + +EverQuest Legends is distributed as a standalone Daybreak/LaunchPad installer, not through Steam. The flake provides an `eqlegends` app that creates a mutable Wine prefix and installs the launcher from `EQLegends_setup.exe`. + +The installer in this repository is a Nullsoft/NSIS installer containing `LaunchPad.exe`, CEF libraries, and `LaunchPad.ini` with `appName=EverQuest Legends` and `id=eqns`. The game data itself is expected to be downloaded later by LaunchPad. + +## Quick start + +From the repository directory containing `EQLegends_setup.exe`: + +```bash +nix run .#eqlegends +``` + +Or point the wrapper at the installer explicitly: + +```bash +EQL_INSTALLER=/path/to/EQLegends_setup.exe nix run .#eqlegends +``` + +The Wine prefix lives at: + +```text +~/.local/share/eqlegends/wine +``` + +The wrapper installs LaunchPad to: + +```text +C:\Games\EverQuestLegends +``` + +inside that Wine prefix. + +## Useful environment variables + +| Variable | Use | +|----------|-----| +| `EQL_INSTALLER=/path/to/EQLegends_setup.exe` | Use an installer outside the current working directory. | +| `EQL_WINEPREFIX=/path/to/prefix` | Override the default Wine prefix location. | +| `EQL_RESET_PREFIX=1` | Delete and recreate the prefix before launching. | +| `EQL_DXVK=1` | Install DXVK DLLs into the prefix before launching. | +| `EQL_WINEDEBUG=+seh,+tid` | Override Wine debug logging. Defaults to `-all`. | + +There is also a reset helper: + +```bash +nix run .#eqlegends-reset-prefix +``` + +If the flake app is installed into a profile, the helper is available as: + +```bash +eqlegends-reset-prefix +``` + +## DXVK + +The wrapper defaults to WineD3D. Run with DXVK only if the game client needs it or performs better with Vulkan translation: + +```bash +EQL_DXVK=1 nix run .#eqlegends +``` + +DXVK is copied into the prefix, so switching back to WineD3D requires a prefix reset: + +```bash +EQL_RESET_PREFIX=1 nix run .#eqlegends +``` + +## Troubleshooting + +If the installer cannot be found, run from the repository root or set `EQL_INSTALLER`. + +If LaunchPad installs somewhere unexpected, inspect: + +```bash +find ~/.local/share/eqlegends/wine/drive_c -iname LaunchPad.exe +``` + +The wrapper records the executable it launches in: + +```text +~/.local/share/eqlegends/wine/.eqlegends-launcher-path +``` + +If the launcher opens but renders as a blank CEF window, try a clean prefix first, then try DXVK: + +```bash +EQL_RESET_PREFIX=1 nix run .#eqlegends +EQL_DXVK=1 nix run .#eqlegends +``` + +For verbose Wine logs: + +```bash +EQL_WINEDEBUG=+seh,+tid,+loaddll nix run .#eqlegends +``` diff --git a/flake.nix b/flake.nix index 6665e21..01e21d4 100644 --- a/flake.nix +++ b/flake.nix @@ -27,6 +27,7 @@ in { eqlogparser = pkgs.callPackage ./packages/eqlogparser/package.nix { }; + eqlegends = pkgs.callPackage ./packages/eqlegends/package.nix { }; default = self.packages.${system}.eqlogparser; } ); @@ -38,6 +39,14 @@ type = "app"; program = "${self.packages.${system}.eqlogparser}/bin/eqlogparser"; }; + eqlegends = { + type = "app"; + program = "${self.packages.${system}.eqlegends}/bin/eqlegends"; + }; + eqlegends-reset-prefix = { + type = "app"; + program = "${self.packages.${system}.eqlegends}/bin/eqlegends-reset-prefix"; + }; default = self.apps.${system}.eqlogparser; } ); diff --git a/packages/eqlegends/package.nix b/packages/eqlegends/package.nix new file mode 100644 index 0000000..2946dc3 --- /dev/null +++ b/packages/eqlegends/package.nix @@ -0,0 +1,168 @@ +{ lib +, runCommand +, writeShellScriptBin +, makeDesktopItem +, wineWow64Packages +, dxvk +, symlinkJoin +, +}: + +let + wine = wineWow64Packages.stableFull; + + setupVersion = "nsis-launchpad-v2"; + installDirWin = "C:\\Games\\EverQuestLegends"; + installDirUnix = "drive_c/Games/EverQuestLegends"; + + setupDxvk = writeShellScriptBin "eqlegends-setup-dxvk" '' + set -euo pipefail + + mkdir -p "$WINEPREFIX/drive_c/windows/system32" "$WINEPREFIX/drive_c/windows/syswow64" + cp -Lf ${dxvk.bin}/x64/d3d8.dll ${dxvk.bin}/x64/d3d9.dll ${dxvk.bin}/x64/d3d10core.dll ${dxvk.bin}/x64/d3d11.dll ${dxvk.bin}/x64/dxgi.dll "$WINEPREFIX/drive_c/windows/system32/" + cp -Lf ${dxvk.bin}/x32/d3d8.dll ${dxvk.bin}/x32/d3d9.dll ${dxvk.bin}/x32/d3d10core.dll ${dxvk.bin}/x32/d3d11.dll ${dxvk.bin}/x32/dxgi.dll "$WINEPREFIX/drive_c/windows/syswow64/" + + wine reg add "HKCU\\Software\\Wine\\DllOverrides" /v d3d8 /t REG_SZ /d native /f + wine reg add "HKCU\\Software\\Wine\\DllOverrides" /v d3d9 /t REG_SZ /d native /f + wine reg add "HKCU\\Software\\Wine\\DllOverrides" /v d3d10core /t REG_SZ /d native /f + wine reg add "HKCU\\Software\\Wine\\DllOverrides" /v d3d11 /t REG_SZ /d native /f + wine reg add "HKCU\\Software\\Wine\\DllOverrides" /v dxgi /t REG_SZ /d native /f + ''; + + launcher = writeShellScriptBin "eqlegends" '' + set -euo pipefail + + export WINEARCH=win64 + export WINEDEBUG="''${EQL_WINEDEBUG:--all}" + export PATH="${wine}/bin:$PATH" + + data_home="''${XDG_DATA_HOME:-$HOME/.local/share}" + export WINEPREFIX="''${EQL_WINEPREFIX:-$data_home/eqlegends/wine}" + version_file="$WINEPREFIX/.eqlegends-nix-version" + launcher_path_file="$WINEPREFIX/.eqlegends-launcher-path" + dxvk_marker="$WINEPREFIX/.eqlegends-dxvk-enabled" + launcher_exe="$WINEPREFIX/${installDirUnix}/LaunchPad.exe" + + if [ -f "$launcher_path_file" ]; then + launcher_exe="$(cat "$launcher_path_file")" + fi + + find_installer() { + if [ -n "''${EQL_INSTALLER:-}" ]; then + printf '%s\n' "$EQL_INSTALLER" + return + fi + + if [ -f "$PWD/EQLegends_setup.exe" ]; then + printf '%s\n' "$PWD/EQLegends_setup.exe" + return + fi + + printf '%s\n' "" + } + + if [ "''${EQL_RESET_PREFIX:-0}" = "1" ]; then + echo "eqlegends: removing $WINEPREFIX" + rm -rf "$WINEPREFIX" + fi + + if [ ! -f "$launcher_exe" ] || [ ! -f "$version_file" ] || [ "$(cat "$version_file" 2>/dev/null || true)" != "${setupVersion}" ]; then + installer="$(find_installer)" + if [ -z "$installer" ] || [ ! -f "$installer" ]; then + cat >&2 <<'EOF' +eqlegends: missing EQLegends_setup.exe + +Run from the repository directory containing EQLegends_setup.exe, or set: + + EQL_INSTALLER=/path/to/EQLegends_setup.exe nix run .#eqlegends +EOF + exit 1 + fi + + echo "eqlegends: creating Wine prefix at $WINEPREFIX" + rm -rf "$WINEPREFIX" + mkdir -p "$WINEPREFIX" + + wineboot -u + wineserver -w + + echo "eqlegends: installing EverQuest Legends LaunchPad with NSIS silent mode..." + wine "$installer" /S "/D=${installDirWin}" + # The NSIS installer starts LaunchPad after extraction even in silent mode. + # Stop that first instance so setup can finish and the wrapper can launch + # the recorded executable itself. + wineserver -k || true + + if [ ! -f "$launcher_exe" ]; then + found_launcher="$(find "$WINEPREFIX/drive_c" -type f -iname LaunchPad.exe | head -n 1 || true)" + if [ -n "$found_launcher" ]; then + launcher_exe="$found_launcher" + fi + fi + + if [ ! -f "$launcher_exe" ]; then + echo "eqlegends: LaunchPad.exe was not found after install." >&2 + echo "eqlegends: inspect $WINEPREFIX/drive_c to see where the installer wrote files." >&2 + exit 1 + fi + + printf '%s\n' "$launcher_exe" > "$launcher_path_file" + echo "${setupVersion}" > "$version_file" + echo "eqlegends: setup complete." + fi + + if [ "''${EQL_DXVK:-0}" = "1" ] && [ ! -f "$dxvk_marker" ]; then + echo "eqlegends: installing DXVK into prefix..." + ${setupDxvk}/bin/eqlegends-setup-dxvk + wineserver -w + touch "$dxvk_marker" + fi + + if [ "''${EQL_DXVK:-0}" != "1" ] && [ -f "$dxvk_marker" ]; then + echo "eqlegends: DXVK was previously installed in this prefix." >&2 + echo "eqlegends: run with EQL_DXVK=1 or reset with EQL_RESET_PREFIX=1 to return to WineD3D." >&2 + fi + + cd "$(dirname "$launcher_exe")" + exec wine "$launcher_exe" "$@" + ''; + + reset = writeShellScriptBin "eqlegends-reset-prefix" '' + set -euo pipefail + + data_home="''${XDG_DATA_HOME:-$HOME/.local/share}" + prefix="''${EQL_WINEPREFIX:-$data_home/eqlegends/wine}" + echo "eqlegends: removing $prefix" + rm -rf "$prefix" + ''; + + desktopItem = makeDesktopItem { + name = "eqlegends"; + desktopName = "EverQuest Legends"; + comment = "EverQuest Legends LaunchPad (Wine)"; + exec = "eqlegends"; + categories = [ "Game" ]; + }; + + desktopFiles = runCommand "eqlegends-desktop" { } '' + mkdir -p $out/share/applications + ln -s ${desktopItem}/share/applications/eqlegends.desktop $out/share/applications/ + ''; + +in +symlinkJoin { + name = "eqlegends-launchpad"; + paths = [ + launcher + reset + desktopFiles + ]; + + meta = { + description = "EverQuest Legends LaunchPad wrapper for Wine on NixOS"; + homepage = "https://www.everquest.com/"; + license = lib.licenses.unfree; + platforms = lib.platforms.linux; + mainProgram = "eqlegends"; + }; +}