Compare commits

..

40 commits

Author SHA1 Message Date
gurrgur
98aa86767c
Add Linux HDR example 2024-07-18 15:04:36 +02:00
gurrgur
3ca1d96c9b
Merge pull request #78 from metinc/main
Avoid deleting eldenring.exe while it is running
2024-07-18 14:37:50 +02:00
Metin Çelik
adf3fe57aa Retry deleting eldenring.exe if it is still running 2024-07-14 11:56:59 +02:00
Metin Çelik
e9f39e6ae3 Avoid deleting eldenring.exe while it is locked 2024-07-08 00:46:14 +02:00
Metin Çelik
ebc316f9e3 Use new executable name for Seamless Co-op example 2024-07-07 16:56:18 +02:00
gurrgur
808bf71966
Merge pull request #71 from polsrepo/patch-3
Fix for crash on death with --disable-rune-loss + potential fix for 60Hz fullscreen lock
2024-06-21 16:34:00 +02:00
polsrepo
9c22a9cd1b
Potential fix for crash on death with --disable-rune-loss and 60Hz lock on full screen
Updated the hex pattern in patch.disable_rune_loss to potentially fix the crash on death. Updated the patch.remove_60hz_fullscreen function and hex pattern to potentially fix the 60hz lock in full screen
2024-06-21 12:13:11 +02:00
gurrgur
f2c55ad352
Merge pull request #67 from polsrepo/patch-2
Update README.md for Windows users
2024-06-20 20:08:39 +02:00
polsrepo
05a5425654
Update README.md for Windows users
Added Note 2
2024-06-20 14:01:48 +02:00
gurrgur
2fb795c305
Merge pull request #65 from polsrepo/patch-1
Update er-patcher for v1.12
2024-06-20 13:48:57 +02:00
polsrepo
a388b09bee
Update er-patcher for v1.12
Updated hex pattern for patch.rate, fixed the offset value for patch.remove_60hz_fullscreen
2024-06-20 13:25:04 +02:00
gurrgur
e8be93b2e2
Merge pull request #59 from gurrgur/python-3-9-regression-fix
fix regression on python 3.9
2024-01-12 02:44:23 +01:00
Marcus Gursch
98cf4aeaa8 use old link_to api when running on python 3.9 or older 2024-01-12 02:40:36 +01:00
gurrgur
a82a9d6e01
Merge pull request #56 from gurrgur/python-3-12-compat
Adapt to python 3.12 changes
2023-12-23 14:32:43 +01:00
Marcus Gursch
569917cb4b adapt to python 3.12 changes
Co-authored-by: mtnorthcott <matthew@northcott.nz>
2023-11-20 11:37:46 +01:00
gurrgur
1a3e191ee9
Merge pull request #47 from arminveres/fix/spelling
Fixed vignette spelling
2022-12-27 14:47:44 +01:00
Armin Veres
7faf4c4f25 Fixed vignette spelling 2022-12-27 12:30:36 +01:00
gurrgur
1c4d60e8f7
Merge pull request #44 from IvarWithoutBones/exec-flag
feature: add --executable flag
2022-10-04 20:57:33 +02:00
Ivar Scholten
124fe3c082
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.
2022-09-30 20:30:08 +02:00
Marcus Gursch
56558f8481 remove --fix-camera option 2022-09-11 14:49:16 +02:00
Marcus Gursch
1d9d2deafc remove --fix-camera option
It is not longer needed since the game now provides a setting for this.
2022-09-11 14:45:38 +02:00
gurrgur
32586d3264
Merge pull request #41 from IvarWithoutBones/disable-rune-loss
Disable rune loss upon death
2022-09-11 14:39:54 +02:00
Ivar Scholten
0f39247ab7
feature: disable rune loss upon death 2022-09-03 18:12:08 +02:00
gurrgur
fd1a1a4f99
Merge pull request #34 from jjgmckenzie/main
Fixes ultrawide for 1.05 with new pattern.
2022-06-16 12:26:02 +02:00
James McKenzie
c3ee974b54 Fixes ultrawide for 1.05 with new pattern. 2022-06-15 12:15:15 -07:00
gurrgur
54f5c17ca5
Merge pull request #28 from joao-pedro-braz/fix-grammar-readme
Fix: Grammar in the README
2022-04-22 18:05:55 +02:00
João Pedro Braz
f6cebbf832
Fix: Grammar in the README
Fixed "Use at own your risk" to "Use it at your own risk"
2022-04-22 11:49:28 -03:00
gurrgur
b87fa70015
Merge pull request #25 from joao-pedro-braz/dev-with-eac
Flag to allow the game to run with EAC
2022-04-22 10:55:03 +02:00
João Pedro Rodrigues Prates Braz
6c4be1ae92 Revert "Fix: Major bug where the flag 'with-eac' defaults to true"
This reverts commit ebcf78c9bb.
2022-04-21 18:38:38 -03:00
João Pedro Rodrigues Prates Braz
b1b2af55af Feat: Improved README 2022-04-21 18:34:44 -03:00
João Pedro Rodrigues Prates Braz
ebcf78c9bb Fix: Major bug where the flag 'with-eac' defaults to true 2022-04-21 18:34:05 -03:00
João Pedro Rodrigues Prates Braz
33b88872f8 Feat: Updated the README to include the 'with-eac' arg 2022-04-21 17:21:54 -03:00
gurrgur
d07b112f06
Merge pull request #26 from joao-pedro-braz/dev-ultrawide-fix
Update Ultrawide fix to version 1.04
2022-04-21 21:56:35 +02:00
João Pedro Rodrigues Prates Braz
0afbe0c4f1 Feat: Include 'start_protected_game.exe' in the tmp folder 2022-04-21 01:02:55 -03:00
João Pedro Rodrigues Prates Braz
e2f0ab53cf Feat: Updated Ultrawide fix to version 1.04 2022-04-21 00:56:17 -03:00
João Pedro Rodrigues Prates Braz
771663eabf Feat: Added option to run game with EAC enabled 2022-04-21 00:54:22 -03:00
Marcus Gursch
0ec730fe89 readme: update recommended launch option line to prevent file permission errors 2022-03-29 21:17:43 +02:00
Marcus Gursch
100c4561b7 fix whitespace 2022-03-29 10:26:33 +02:00
Marcus Gursch
f49096c2c6 feature: gracefully fail pattern scanning and print helpful error messages
refactor: use regex pattern scanning everywhere
2022-03-28 21:26:32 +02:00
Marcus Gursch
7ae9c59fcc update animation fix with proper pattern scanning 2022-03-28 21:10:14 +02:00
2 changed files with 147 additions and 72 deletions

View file

@ -5,29 +5,47 @@ A tool aimed at enhancing the experience when playing the game on linux through
## Warning ## Warning
**This tool is based on patching the game executable through hex-edits. However it is done in a safe and non-destructive way, that ensures the patched executable is never run with EAC enabled. Use at your own risk!** **This tool is based on patching the game executable through hex-edits. However it is done in a safe and non-destructive way, that ensures the patched executable is never run with EAC enabled (unless explicity told to do so). Use at your own risk!**
## Dependencies ## Dependencies
- Python >= 3.8.xx (lowest tested) - Python >= 3.8
## Usage ## Usage
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 `./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: `./er-patcher --all --rate 30 --fix-camera -- %command%` - Example:
- Example using [MangoHud](https://github.com/flightlessmango/MangoHud) and wine fullscreen FSR: `./er-patcher --rate 144 -uvca -- env WINE_FULLSCREEN_FSR=1 MANGOHUD=1 MANGOHUD_CONFIG=histogram %command%`
`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 ersc_launcher.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 for enabling HDR using gamescope on Linux (reported to work on Plasma 6.1):
`ENABLE_GAMESCOPE_WSI=1 DXVK_HDR=1 gamescope -W 3440 -H 1440 -f -r 165 --hdr-enabled -- python er-patcher --all --rate 165 -- %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.
Note: There might be some distros (e.g. older Ubuntu releases) that launch python 2 instead of 3 when running `python`. In that case you'll need to replace `python` with `python3` in the launch option line.
## Features ## Features
| 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). |
| `--fix-camera` | Disable camera auto-rotation. | | `-x EXE` or `--executable EXE` | The executable to launch, relative to the games folder.<br>Mutually exclusive with `--with-eac`. |
| `--all` | Enable all options except `--rate` and<br>gameplay changes like `--fix-camera`. | | `--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. |
| `--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-vignette` | Remove the vignette 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. |
@ -36,15 +54,17 @@ A tool aimed at enhancing the experience when playing the game on linux through
## Windows Support ## Windows Support
The patcher works just as well on windows. The only difference is that you need to explicitly call python to run the script `er-patcher`. The following launch option line works in case you installed Python from Microsoft Store: The patcher works just as well on windows. The following launch option line works in case you e.g. installed Python from Microsoft Store:
> `python er-patcher --rate 165 --all -- %command%` > `python er-patcher --rate 165 --all -- %command%`
Note: This spawns a python console which will close by itself after the game has finished running. If you find this annoying you can try using `pythonw` instead. In any case `python` needs to be in PATH for windows to find it. Note: This spawns a python console which will close by itself after the game has finished running. If you find this annoying you can try using `pythonw` instead. In any case `python` needs to be in PATH for windows to find it.
Note 2: Ensure Vertical Sync is turned off for Elden Ring in Nvidia Control Panel / AMD Radeon Software / Intel Graphics Command Center, otherwise the custom framerate limit feature won't work.
## How it works ## How it works
When the game is launched through steam, the tool creates a patched version of `eldenring.exe` in a temporary subdirectory while leaving the original intact. The tool then modifies the steam launch command to launch the patched executable instead of `start_protected_game.exe`. This ensures that the patched exe is never run with EAC enabled. After the game is closed, the patched executable is removed. When the game is launched through steam, the tool creates a patched version of `eldenring.exe` in a temporary subdirectory while leaving the original intact. As long the flag `--with-eac` is not set, the tool modifies the steam launch command to launch the patched executable instead of `start_protected_game.exe`, thefore ensuring that the patched exe is never run with EAC enabled. After the game is closed, the patched executable is removed.
## Credits ## Credits
@ -52,7 +72,8 @@ When the game is launched through steam, the tool creates a patched version of `
- frame time limit adjustment - frame time limit adjustment
- black bar removal - black bar removal
- [Flawless Widescreen](https://www.flawlesswidescreen.org) - [Flawless Widescreen](https://www.flawlesswidescreen.org)
- vigniette and ca removal - vignette and ca removal
- animation distance increase - animation distance increase
- [DarkSouls3RemoveIntroScreens](https://github.com/bladecoding/DarkSouls3RemoveIntroScreens): intro logo skip - [DarkSouls3RemoveIntroScreens](https://github.com/bladecoding/DarkSouls3RemoveIntroScreens): intro logo skip
- [EldenRingMods](https://github.com/techiew/EldenRingMods) + [EldenRingFpsUnlockAndMore](https://github.com/uberhalit/EldenRingFpsUnlockAndMore): camera fix - [EldenRingMods](https://github.com/techiew/EldenRingMods) + [EldenRingFpsUnlockAndMore](https://github.com/uberhalit/EldenRingFpsUnlockAndMore)
- disable rune loss

View file

@ -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
@ -8,7 +7,23 @@ from pathlib import Path
import struct import struct
import re import re
from shutil import rmtree from shutil import rmtree
import os
import time
def cleanup(game_dir_patched):
if game_dir_patched.exists():
eldenring_path = game_dir_patched / "eldenring.exe"
while eldenring_path.exists():
try:
os.remove(eldenring_path)
break
except PermissionError:
# eldenring.exe is still running, retry in 3 s
time.sleep(3)
except Exception as e:
print(f"er-patcher: could not delete {eldenring_path}: {e}")
break
rmtree(game_dir_patched)
if __name__ == "__main__": if __name__ == "__main__":
@ -17,73 +32,109 @@ if __name__ == "__main__":
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("--fix-camera", action='store_true', help="Disable camera auto-rotation.") 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("--all", action='store_true', help="Enable all options except rate adjustment and gamplay changes like `--fix-camera`.") 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("--all", action='store_true', help="Enable all options except rate adjustment and gamplay changes like `--disable-rune-loss`.")
parser.add_argument("-u", "--ultrawide", action='store_true', help="Removes black bars when using a resolution with an aspect ratio other than 16:9.") parser.add_argument("-u", "--ultrawide", action='store_true', help="Removes black bars when using a resolution with an aspect ratio other than 16:9.")
parser.add_argument("-v", "--disable-vigniette", action='store_true', help="Disables the vigniette overlay.") parser.add_argument("-v", "--disable-vignette", action='store_true', help="Disables the vignette overlay.")
parser.add_argument("-c", "--disable-ca", action='store_true', help="Disables chromatic abberation.") parser.add_argument("-c", "--disable-ca", action='store_true', help="Disables chromatic abberation.")
parser.add_argument("-a", "--increase-animation-distance", action='store_true', help="Increase animation distance.") parser.add_argument("-a", "--increase-animation-distance", action='store_true', help="Increase animation distance.")
parser.add_argument("-s", "--skip-intro", action='store_true', help="Skip intro logos.") parser.add_argument("-s", "--skip-intro", action='store_true', help="Skip intro logos.")
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()
if patch.rate != 60 and patch.rate > 0: if patch.rate != 60 and patch.rate > 0:
exe_hex = exe_hex.replace( r_pattern = "c7 43 1c 89 88 88 3c eb 6d 89 73 18 eb c7 89 73 18".replace(" ", "")
"c743208988883ceb43897318ebca897318", if (res := re.search(r_pattern, exe_hex)) is not None:
"c743208988883ceb43897318ebca897318".replace( r_addr = res.span()[0] + 6
"8988883c", struct.pack('<f', 1 / patch.rate).hex() r_patch = struct.pack('<f', 1 / patch.rate).hex()
) exe_hex = exe_hex[:r_addr] + r_patch + exe_hex[r_addr + len(r_patch):]
) else:
print("er-patcher: rate pattern scan failed")
if patch.fix_camera: if patch.disable_rune_loss:
cf_pattern = '0f 29 a6 .. .. .. .. 41 0f 28 cf'.replace(" ", "") rl_pattern = "41 .. 01 48 .. .. e8 .. .. .. .. 48 .. .. .. .. 32 c0".replace(" ", "")
cf_addr = re.search(cf_pattern, exe_hex).span()[0] if (res := re.search(rl_pattern, exe_hex)) is not None:
cf_offset = 0 rl_addr = res.span()[0] + 12
cf_patch = "90 90 90 90 90 90 90".replace(" ", "") rl_patch = "90 90 90 90 90".replace(" ", "") # NOP
exe_hex = exe_hex[:cf_addr + cf_offset] + cf_patch + exe_hex[cf_addr + cf_offset + len(cf_patch):] exe_hex = exe_hex[:rl_addr] + rl_patch + exe_hex[rl_addr + len(rl_patch):]
else:
print("er-patcher: disable rune loss pattern scan failed")
if patch.ultrawide or patch.all: if patch.ultrawide or patch.all:
exe_hex = exe_hex.replace( uw_pattern = "74 4f 45 8b 94 cc".replace(" ", "")
"8b0185c07442448b5904", if (res := re.search(uw_pattern, exe_hex)) is not None:
"8b0185c0eb42448b5904" uw_addr = res.span()[0]
) uw_patch = "eb"
exe_hex = exe_hex[:uw_addr] + uw_patch + exe_hex[uw_addr + len(uw_patch):]
else:
print("er-patcher: ultrawide pattern scan failed")
if patch.disable_vigniette or patch.all: if patch.disable_vignette or patch.all:
v_pattern = 'f3 0f 10 .. .. f3 0f 59 .. .. .. .. .. e8 .. .. .. .. f3 41 0f .. .. f3 45 0f .. .. 4c 8d .. .. .. .. .. .. 48'.replace(" ", "") v_pattern = 'f3 0f 10 .. .. f3 0f 59 .. .. .. .. .. e8 .. .. .. .. f3 41 0f .. .. f3 45 0f .. .. 4c 8d .. .. .. .. .. .. 48'.replace(" ", "")
v_addr = re.search(v_pattern, exe_hex).span()[0] if (res := re.search(v_pattern, exe_hex)) is not None:
v_offset = 46 v_addr = res.span()[0] + 46
v_patch = "f3 0f 5c c0 90".replace(" ", "") # SUBSS XMM0,XMM0; NOP; all NOP does work too v_patch = "f3 0f 5c c0 90".replace(" ", "") # SUBSS XMM0,XMM0; NOP; all NOP does work too
exe_hex = exe_hex[:v_addr + v_offset] + v_patch + exe_hex[v_addr + v_offset + len(v_patch):] exe_hex = exe_hex[:v_addr] + v_patch + exe_hex[v_addr + len(v_patch):]
else:
print("er-patcher: disable_vignette pattern scan failed")
if patch.disable_ca or patch.all: if patch.disable_ca or patch.all:
ca_addr = 94 + exe_hex.index("0f114360488d8b800000000f1087a00000000f1141f0488d87b00000000f10080f1109") ca_pattern = "0f 11 43 60 48 8d 8b 80 00 00 00 0f 10 87 a0 00 00 00 0f 11 41 f0 48 8d 87 b0 00 00 00 0f 10 08 0f 11 09".replace(" ", "")
if exe_hex[ca_addr:ca_addr + 8] == "0f114920": if (res := re.search(ca_pattern, exe_hex)) is not None:
exe_hex = exe_hex[:ca_addr] + "660fefc9" + exe_hex[ca_addr + 8:] # PXOR XMM1,XMM1 ca_addr = res.span()[0] + 94
ca_orig = "0f 11 49 20".replace(" ", "")
ca_patch = "66 0f ef c9".replace(" ", "") # PXOR XMM1,XMM1
if exe_hex[ca_addr:ca_addr + len(ca_patch)] == ca_orig:
exe_hex = exe_hex[:ca_addr] + ca_patch + exe_hex[ca_addr + len(ca_patch):]
else:
print("er-patcher: disable_ca pattern scan failed")
if patch.increase_animation_distance or patch.all: if patch.increase_animation_distance or patch.all:
# DIVSS XMM1,dword ptr [R12 + 0x54] -> XORPS XMM1,XMM1; PXOR XMM1,XMM1 iad_pattern = "e8 .. .. .. .. 0f 28 .. 0f 28 .. e8 .. .. .. .. f3 0f .. .. 0f 28 .. f3 41 0f 5e 4c 24 54".replace(" ", "")
exe_hex = exe_hex.replace( if (res := re.search(iad_pattern, exe_hex)) is not None:
"e82b309c010f28f80f28c6e820359c01f30f5ef80f28cff3410f5e4c2454", iad_addr = res.span()[0] + 46
"e82b309c010f28f80f28c6e820359c01f30f5ef80f28cf0f57c9660fefc9" iad_patch = "0f 57 c9 66 0f ef c9".replace(" ", "") # DIVSS XMM1,dword ptr [R12 + 0x54] -> XORPS XMM1,XMM1; PXOR XMM1,XMM1
) exe_hex = exe_hex[:iad_addr] + iad_patch + exe_hex[iad_addr + len(iad_patch):]
else:
print("er-patcher: increase_animation_distance pattern scan failed")
if patch.skip_intro or patch.all: if patch.skip_intro or patch.all:
exe_hex = exe_hex.replace( si_pattern = "80 bf b8 00 00 00 00 74 53 48".replace(" ", "")
"80 bf b8 00 00 00 00 74 53 48".replace(" ", ""), if (res := re.search(si_pattern, exe_hex)) is not None:
"80 bf b8 00 00 00 00 90 90 48".replace(" ", "") si_addr = res.span()[0] + 14
) si_patch = "90 90".replace(" ", "")
exe_hex = exe_hex[:si_addr] + si_patch + exe_hex[si_addr + len(si_patch):]
else:
print("er-patcher: skip_intro pattern scan failed")
if patch.remove_60hz_fullscreen or patch.all: if patch.remove_60hz_fullscreen or patch.all:
exe_hex = exe_hex.replace( fs_pattern = "eb .. c7 .. .. 3c 00 00 00 c7 .. .. 01 00 00 00".replace(" ", "")
"c745ef3c000000", if (res := re.search(fs_pattern, exe_hex)) is not None:
"c745ef00000000" fs_addr = res.span()[0] + 10
) fs_patch = "00"
exe_hex = exe_hex[:fs_addr] + fs_patch + exe_hex[fs_addr + len(fs_patch):]
fs_addr_2 = res.span()[0] + 24
fs_patch_2 = "00"
exe_hex = exe_hex[:fs_addr_2] + fs_patch_2 + exe_hex[fs_addr_2 + len(fs_patch_2):]
else:
print("er-patcher: remove_60hz_fullscreen pattern scan failed")
game_dir_patched = Path("er-patcher-tmp") game_dir_patched = Path("er-patcher-tmp")
# make sure a fresh directory is used
cleanup(game_dir_patched)
if not game_dir_patched.is_dir(): if not game_dir_patched.is_dir():
game_dir_patched.mkdir() game_dir_patched.mkdir()
@ -104,15 +155,18 @@ if __name__ == "__main__":
# 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", "start_protected_game.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():
if sys.version_info.minor >= 10:
(game_dir_patched / f).hardlink_to(f)
else:
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 / "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 # try to remove game_dir_patched
rmtree(game_dir_patched) cleanup(game_dir_patched)