mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-10-18 05:07:22 -04:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
67bf8f1568 |
No files matched your search
@@ -32,6 +32,7 @@ object GameEnvironmentOptions {
|
||||
Option("MESA_EXTENSION_MAX_YEAR", "", 0, Type.TEXT),
|
||||
Option("MESA_GL_VERSION_OVERRIDE", "", 0, Type.TEXT),
|
||||
Option("PULSE_LATENCY_MSEC", "", 0, Type.NUMBER),
|
||||
Option("DROIDDECK_ANTICHEAT_OFFLINE", "1", R.string.game_env_anticheat_offline, Type.TOGGLE, listOf("0", "1")),
|
||||
Option("WINE_LARGE_ADDRESS_AWARE", "0", 0, Type.TOGGLE, listOf("0", "1")),
|
||||
Option("WINEDLLOVERRIDES", "", 0, Type.TEXT),
|
||||
Option("GALLIUM_HUD", "simple", 0, Type.MULTIPLE, listOf("simple", "fps", "frametime")),
|
||||
|
||||
@@ -86,6 +86,7 @@
|
||||
<string name="game_env_no_fsync">Set to 1 to keep this game off droiddeck-fsync; it uses droiddeck-esync where a pack exists, otherwise droiddeck-ntsync.</string>
|
||||
<string name="game_env_fsync_first">Set to 1 to run this game on droiddeck-fsync, or 0 to put droiddeck-esync first where a pack fits its Proton.</string>
|
||||
<string name="game_env_xalia">Set to 0 to disable Proton’s gamepad-navigation helper for this game.</string>
|
||||
<string name="game_env_anticheat_offline">Set to 1 to start an Easy Anti-Cheat game without its anti-cheat. The game must support offline play; online modes that require Easy Anti-Cheat remain unavailable.</string>
|
||||
<string name="game_env_hud">DXVK overlay for D3D9–11. fps displays frame rate; unset hides it.</string>
|
||||
<string name="game_env_dxvk_config">DXVK settings separated by semicolons. Recent builds use dxvk.maxFrameRate for frame limiting; prefer the session frame limiter for ordinary play.</string>
|
||||
<string name="game_env_vkd3d_limit">D3D12 frame-rate limit. 0 disables the limit.</string>
|
||||
|
||||
@@ -119,6 +119,28 @@ def skip_red_launcher(command):
|
||||
return command
|
||||
|
||||
|
||||
def offline_without_anticheat(command, env):
|
||||
"""Start the configured game executable when the player opts into launching without EAC."""
|
||||
if env.get("DROIDDECK_ANTICHEAT_OFFLINE") != "1" or len(command) <= 2:
|
||||
return command
|
||||
folder = os.path.dirname(command[2])
|
||||
try:
|
||||
with open(os.path.join(folder, "EasyAntiCheat", "settings.json"), encoding="utf-8-sig") as source:
|
||||
executable = json.load(source).get("executable")
|
||||
except (OSError, ValueError, AttributeError):
|
||||
return command
|
||||
if not isinstance(executable, str) or not executable:
|
||||
return command
|
||||
relative = os.path.normpath(executable.replace("\\", "/"))
|
||||
game = os.path.join(folder, relative)
|
||||
if os.path.isabs(relative) or relative.startswith("..") or not os.path.isfile(game):
|
||||
return command
|
||||
if os.path.normcase(os.path.abspath(game)) == os.path.normcase(os.path.abspath(command[2])):
|
||||
return command
|
||||
print("droiddeck-game-env: started without Easy Anti-Cheat (offline only)", file=sys.stderr)
|
||||
return command[:2] + [game] + command[3:]
|
||||
|
||||
|
||||
def engine_fixes(exe, args):
|
||||
"""Environment and extra arguments a game needs because of what it is built with."""
|
||||
game = Game(exe, args)
|
||||
@@ -307,6 +329,8 @@ def main():
|
||||
env = apply_config(env, {"version": 1}, app_id, fixes)
|
||||
except (OSError, ValueError, TypeError, AttributeError):
|
||||
print("droiddeck-game-env: invalid configuration; using inherited environment", file=sys.stderr)
|
||||
if app_id and len(command) > 1 and command[1] == "waitforexitandrun":
|
||||
command = offline_without_anticheat(command, env)
|
||||
if mic_enabled == "0":
|
||||
env["BANNER_AUDIO_DIRECT_MIC"] = "0"
|
||||
env = force_ssbs(command, env)
|
||||
|
||||
@@ -179,6 +179,27 @@ class GameEnvironmentTest(unittest.TestCase):
|
||||
(other / "Other.exe").touch()
|
||||
self.assertEqual(MODULE["engine_fixes"](str(other / "Other.exe"), []), ({}, [], []))
|
||||
|
||||
def test_easy_anti_cheat_games_start_offline_only_when_opted_in(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
game = Path(tmp) / "ELDEN RING/Game"
|
||||
(game / "EasyAntiCheat").mkdir(parents=True)
|
||||
for name in ("start_protected_game.exe", "eldenring.exe"):
|
||||
(game / name).touch()
|
||||
(game / "EasyAntiCheat/settings.json").write_text('\ufeff{ "executable" : "eldenring.exe" }', encoding="utf-8")
|
||||
command = ["proton", "waitforexitandrun", str(game / "start_protected_game.exe"), "-arg"]
|
||||
offline = MODULE["offline_without_anticheat"]
|
||||
self.assertEqual(offline(command, {}), command)
|
||||
self.assertEqual(offline(command, {"DROIDDECK_ANTICHEAT_OFFLINE": "0"}), command)
|
||||
self.assertEqual(offline(command, {"DROIDDECK_ANTICHEAT_OFFLINE": "1"}),
|
||||
["proton", "waitforexitandrun", str(game / "eldenring.exe"), "-arg"])
|
||||
(game / "EasyAntiCheat/settings.json").write_text('{ "executable" : "../../escape.exe" }')
|
||||
(Path(tmp) / "escape.exe").touch()
|
||||
self.assertEqual(offline(command, {"DROIDDECK_ANTICHEAT_OFFLINE": "1"}), command)
|
||||
(game / "EasyAntiCheat/settings.json").write_text('{ "executable" : "missing.exe" }')
|
||||
self.assertEqual(offline(command, {"DROIDDECK_ANTICHEAT_OFFLINE": "1"}), command)
|
||||
plain = ["proton", "waitforexitandrun", str(Path(tmp) / "Other.exe")]
|
||||
self.assertEqual(offline(plain, {"DROIDDECK_ANTICHEAT_OFFLINE": "1"}), plain)
|
||||
|
||||
def test_arkham_city_gets_full_x87_precision_over_the_preset(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
city = Path(tmp) / "Batman Arkham City GOTY/Binaries/Win32"
|
||||
|
||||
Reference in new issue
Block a user