1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
from __future__ import annotations
import shutil
from pathlib import Path
from PyQt6.QtCore import QDir, QFileInfo, qInfo, qWarning
import mobase
from ..basic_game import BasicGame
class RedDeadRedemption2Game(BasicGame):
Name = "Red Dead Redemption 2 Support Plugin"
Author = "KrebKrebou, Fluorine"
Version = "1.1.0"
GameName = "Red Dead Redemption 2"
GameShortName = "reddeadredemption2"
GameNexusName = "reddeadredemption2"
GameNexusId = 3024
GameSteamId = 1174180
GameBinary = "RDR2.exe"
GameLauncher = "PlayRDR2.exe"
GameDataPath = ""
_binary_candidates = ("RDR2.exe", "PlayRDR2.exe")
def init(self, organizer: mobase.IOrganizer) -> bool:
if not super().init(organizer):
return False
return organizer.onAboutToRun(self._on_about_to_run)
def settings(self) -> list[mobase.PluginSetting]:
settings = super().settings()
settings.append(
mobase.PluginSetting(
"cleanup_overwrite_scripts",
(
"Delete overwrite/scripts before launching RDR2. This works around "
"ScriptHookRDR2 launch failures caused by a stale generated scripts "
"folder in overwrite."
),
True,
)
)
return settings
def binaryName(self) -> str:
game_dir = self.gameDirectory()
for candidate in self._binary_candidates:
if game_dir.exists(candidate):
return candidate
return super().binaryName()
def looksValid(self, directory: QDir) -> bool:
return any(directory.exists(candidate) for candidate in self._binary_candidates)
def executables(self) -> list[mobase.ExecutableInfo]:
game_dir = self.gameDirectory()
executables: list[mobase.ExecutableInfo] = []
for candidate in self._binary_candidates:
if game_dir.exists(candidate) or not executables:
label = self.gameName()
if candidate != self.binaryName():
label = f"{self.gameName()} ({candidate})"
executables.append(
mobase.ExecutableInfo(label, QFileInfo(game_dir, candidate))
)
return executables
def _on_about_to_run(self, app_path: str, *args: object) -> bool:
if not self._is_rdr2_executable(app_path):
return True
cleanup_scripts = self._organizer.pluginSetting(
self.name(), "cleanup_overwrite_scripts"
)
if cleanup_scripts is False:
return True
overwrite_scripts = Path(self._organizer.overwritePath()) / "scripts"
try:
if overwrite_scripts.is_dir():
shutil.rmtree(overwrite_scripts)
qInfo(f"Removed stale RDR2 ScriptHook folder: {overwrite_scripts}")
elif overwrite_scripts.exists():
overwrite_scripts.unlink()
qInfo(f"Removed stale RDR2 ScriptHook path: {overwrite_scripts}")
except OSError as err:
qWarning(f"Failed to remove '{overwrite_scripts}': {err}")
return True
def _is_rdr2_executable(self, app_path: str) -> bool:
executable_name = Path(app_path.replace("\\", "/")).name.lower()
return executable_name in {name.lower() for name in self._binary_candidates}
|