mirror of
https://github.com/gurrgur/er-patcher.git
synced 2026-06-13 09:47:54 +00:00
feature: add --executable flag
Some mods are launched through a executable different from `eldenring.exe` or `launch_game_protected.exe`. Because of that its useful to be able to explicitly specify the path. Also fixes some linter warnings.
This commit is contained in:
parent
56558f8481
commit
124fe3c082
2 changed files with 18 additions and 12 deletions
|
|
@ -16,6 +16,7 @@ A tool aimed at enhancing the experience when playing the game on linux through
|
||||||
1. Copy the file `er-patcher` to the game directory.
|
1. Copy the file `er-patcher` to the game directory.
|
||||||
2. In steam, set the game launch options to `python er-patcher ARGS -- %command%` See [Features](#features) for available options.
|
2. In steam, set the game launch options to `python er-patcher ARGS -- %command%` See [Features](#features) for available options.
|
||||||
- Example: `python er-patcher --all --rate 30 --disable-rune-loss -- %command%`
|
- Example: `python er-patcher --all --rate 30 --disable-rune-loss -- %command%`
|
||||||
|
- Example using the [seamless co-op](https://www.nexusmods.com/eldenring/mods/510) mod: `python er-patcher --all --executable launch_elden_ring_seamlesscoop.exe -- %command%`
|
||||||
- Example using [MangoHud](https://github.com/flightlessmango/MangoHud) and wine fullscreen FSR: `python er-patcher --rate 144 -uvca -- env WINE_FULLSCREEN_FSR=1 MANGOHUD=1 MANGOHUD_CONFIG=histogram %command%`
|
- Example using [MangoHud](https://github.com/flightlessmango/MangoHud) and wine fullscreen FSR: `python er-patcher --rate 144 -uvca -- env WINE_FULLSCREEN_FSR=1 MANGOHUD=1 MANGOHUD_CONFIG=histogram %command%`
|
||||||
3. Launch the game through steam. `er-patcher` automatically launches a patched version of `eldenring.exe` with EAC disabled.
|
3. Launch the game through steam. `er-patcher` automatically launches a patched version of `eldenring.exe` with EAC disabled.
|
||||||
|
|
||||||
|
|
@ -26,11 +27,12 @@ Note: There might be some distros (e.g. older Ubuntu releases) that launch pytho
|
||||||
| Argument | Description |
|
| Argument | Description |
|
||||||
| --------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
| --------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
||||||
| `-r RATE` or `--rate RATE` | Set a custom framerate limit (default: 60). |
|
| `-r RATE` or `--rate RATE` | Set a custom framerate limit (default: 60). |
|
||||||
| `--with-eac` | Run game with EAC (Use it at your own risk) |
|
| `-x EXE` or `--executable EXE` | The executable to launch, relative to the games folder.<br>Mutually exclusive with `--with-eac`. |
|
||||||
|
| `--with-eac` | Run game with EAC (Use it at your own risk).<br>Mutually exclusive with `--executable`. |
|
||||||
| `--disable-rune-loss` | Disable losing runes upon death. |
|
| `--disable-rune-loss` | Disable losing runes upon death. |
|
||||||
| `--all` | Enable all options except `--rate` and<br>gameplay changes like `--disable-rune-loss`. |
|
| `--all` | Enable all options except `--rate`, `--executable`, and<br>gameplay changes like `--disable-rune-loss`. |
|
||||||
| `-u` or `--ultrawide` | Remove black bars. |
|
| `-u` or `--ultrawide` | Remove black bars. |
|
||||||
| `-v` or `--disable-vigniette` | Remove the vigniette overlay . |
|
| `-v` or `--disable-vigniette` | Remove the vigniette overlay. |
|
||||||
| `-c` or `--disable-ca` | Disable chromatic abberation. |
|
| `-c` or `--disable-ca` | Disable chromatic abberation. |
|
||||||
| `-a` or `--increase-animation-distance` | Fix low frame rate animations at screen<br>edges or for distant entities. |
|
| `-a` or `--increase-animation-distance` | Fix low frame rate animations at screen<br>edges or for distant entities. |
|
||||||
| `-s` or `--skip-intro` | Skip intro logos at game start. |
|
| `-s` or `--skip-intro` | Skip intro logos at game start. |
|
||||||
|
|
|
||||||
22
er-patcher
22
er-patcher
|
|
@ -1,6 +1,5 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
|
|
@ -13,10 +12,11 @@ from shutil import rmtree
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
patcher_args = sys.argv[1:sys.argv.index("--")]
|
patcher_args = sys.argv[1:sys.argv.index("--")]
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(description="Patch Elden Ring executable and launch it without EAC.")
|
parser = argparse.ArgumentParser(description="Patch Elden Ring executable and launch it without EAC.")
|
||||||
|
|
||||||
parser.add_argument("-r", "--rate", type=int, default=60, help="Modify the frame rate limit (e.g. 30, 120, 165 or whatever).")
|
parser.add_argument("-r", "--rate", type=int, default=60, help="Modify the frame rate limit (e.g. 30, 120, 165 or whatever).")
|
||||||
|
parser.add_argument("-x", "--executable", action='store', type=str, default="eldenring.exe", help="The executable to launch, relative to the games folder.")
|
||||||
parser.add_argument("--with-eac", action='store_true', help="Run game with EAC (Use at own your risk)")
|
parser.add_argument("--with-eac", action='store_true', help="Run game with EAC (Use at own your risk)")
|
||||||
parser.add_argument("--disable-rune-loss", action='store_true', help="Disable losing runes upon death.")
|
parser.add_argument("--disable-rune-loss", action='store_true', help="Disable losing runes upon death.")
|
||||||
parser.add_argument("--all", action='store_true', help="Enable all options except rate adjustment and gamplay changes like `--disable-rune-loss`.")
|
parser.add_argument("--all", action='store_true', help="Enable all options except rate adjustment and gamplay changes like `--disable-rune-loss`.")
|
||||||
|
|
@ -28,6 +28,10 @@ if __name__ == "__main__":
|
||||||
parser.add_argument("-f", "--remove-60hz-fullscreen", action='store_true', help="Remove 60hz lock in fullscreen.")
|
parser.add_argument("-f", "--remove-60hz-fullscreen", action='store_true', help="Remove 60hz lock in fullscreen.")
|
||||||
patch = parser.parse_args(patcher_args)
|
patch = parser.parse_args(patcher_args)
|
||||||
|
|
||||||
|
if patch.with_eac and patch.executable != "eldenring.exe":
|
||||||
|
print("er-patcher: --with-eac is mutually exclusive with --executable")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
game_dir = Path(".")
|
game_dir = Path(".")
|
||||||
with open(game_dir / "eldenring.exe", "rb") as f:
|
with open(game_dir / "eldenring.exe", "rb") as f:
|
||||||
exe_hex = f.read().hex()
|
exe_hex = f.read().hex()
|
||||||
|
|
@ -45,7 +49,7 @@ if __name__ == "__main__":
|
||||||
rl_pattern = "b0 01 .. 8b .. e8 .. .. .. .. .. 8b .. .. .. 32 c0 .. 83 .. 28 c3".replace(" ", "")
|
rl_pattern = "b0 01 .. 8b .. e8 .. .. .. .. .. 8b .. .. .. 32 c0 .. 83 .. 28 c3".replace(" ", "")
|
||||||
if (res := re.search(rl_pattern, exe_hex)) is not None:
|
if (res := re.search(rl_pattern, exe_hex)) is not None:
|
||||||
rl_addr = res.span()[0] + 6
|
rl_addr = res.span()[0] + 6
|
||||||
rl_patch = "90 90 90 90 90".replace(" ", "") # NOP
|
rl_patch = "90 90 90 90 90".replace(" ", "") # NOP
|
||||||
exe_hex = exe_hex[:rl_addr] + rl_patch + exe_hex[rl_addr + len(rl_patch):]
|
exe_hex = exe_hex[:rl_addr] + rl_patch + exe_hex[rl_addr + len(rl_patch):]
|
||||||
else:
|
else:
|
||||||
print("er-patcher: disable rune loss pattern scan failed")
|
print("er-patcher: disable rune loss pattern scan failed")
|
||||||
|
|
@ -96,7 +100,7 @@ if __name__ == "__main__":
|
||||||
exe_hex = exe_hex[:si_addr] + si_patch + exe_hex[si_addr + len(si_patch):]
|
exe_hex = exe_hex[:si_addr] + si_patch + exe_hex[si_addr + len(si_patch):]
|
||||||
else:
|
else:
|
||||||
print("er-patcher: skip_intro pattern scan failed")
|
print("er-patcher: skip_intro pattern scan failed")
|
||||||
|
|
||||||
if patch.remove_60hz_fullscreen or patch.all:
|
if patch.remove_60hz_fullscreen or patch.all:
|
||||||
fs_pattern = "c7 45 ef 3c 00 00 00".replace(" ", "")
|
fs_pattern = "c7 45 ef 3c 00 00 00".replace(" ", "")
|
||||||
if (res := re.search(fs_pattern, exe_hex)) is not None:
|
if (res := re.search(fs_pattern, exe_hex)) is not None:
|
||||||
|
|
@ -121,20 +125,20 @@ if __name__ == "__main__":
|
||||||
if d == game_dir_patched:
|
if d == game_dir_patched:
|
||||||
continue
|
continue
|
||||||
if not (game_dir_patched / d).is_dir():
|
if not (game_dir_patched / d).is_dir():
|
||||||
(game_dir_patched / d).mkdir(parents=True)
|
(game_dir_patched / d).mkdir(parents=True)
|
||||||
|
|
||||||
# hard link game files to game_dir_patched; symbolic links would be easier
|
# hard link game files to game_dir_patched; symbolic links would be easier
|
||||||
# to handle but by default windows 10 doesn't allow them
|
# to handle but by default windows 10 doesn't allow them
|
||||||
game_files = [f for f in game_dir.rglob("*") if f.is_file()]
|
game_files = [f for f in game_dir.rglob("*") if f.is_file()]
|
||||||
for f in game_files:
|
for f in game_files:
|
||||||
if f.name in ["eldenring.exe", "er-patcher"]:
|
if f.name in ["eldenring.exe", "er-patcher"]:
|
||||||
continue
|
continue
|
||||||
if not (game_dir_patched / f).is_file():
|
if not (game_dir_patched / f).is_file():
|
||||||
f.link_to(game_dir_patched / f)
|
f.link_to(game_dir_patched / f)
|
||||||
|
|
||||||
# start patched exe directly to avoid EAC
|
# start patched exe directly to avoid EAC
|
||||||
steam_cmd = sys.argv[1 + sys.argv.index("--"):]
|
steam_cmd = sys.argv[1 + sys.argv.index("--"):]
|
||||||
steam_cmd[-1] = Path(steam_cmd[-1]).parent.absolute() / game_dir_patched / ("start_protected_game.exe" if patch.with_eac else "eldenring.exe")
|
steam_cmd[-1] = Path(steam_cmd[-1]).parent.absolute() / game_dir_patched / ("start_protected_game.exe" if patch.with_eac else patch.executable)
|
||||||
subprocess.run(steam_cmd, cwd=steam_cmd[-1].parent.absolute())
|
subprocess.run(steam_cmd, cwd=steam_cmd[-1].parent.absolute())
|
||||||
|
|
||||||
# cleanup
|
# cleanup
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue