Skip to content

Commit 10dc0a5

Browse files
committed
Fix CrashReporter error with CET installed in VFS by disabling it.
1 parent bd5af50 commit 10dc0a5

1 file changed

Lines changed: 79 additions & 1 deletion

File tree

games/game_cyberpunk2077.py

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from collections.abc import Iterable
77
from dataclasses import dataclass
88
from pathlib import Path
9-
from typing import Literal, TypeVar
9+
from typing import Any, Literal, TypeVar
1010

1111
import mobase
1212
from PyQt6.QtCore import QDateTime, QDir, qCritical, qInfo, qWarning
@@ -199,6 +199,7 @@ class Cyberpunk2077Game(BasicGame):
199199

200200
# CET and RED4ext, relative to Cyberpunk2077.exe
201201
_forced_libraries = ["version.dll", "winmm.dll"]
202+
_crashreporter_path = "bin/x64/CrashReporter/CrashReporter.exe"
202203

203204
_redmod_binary = Path("tools/redmod/bin/redMod.exe")
204205
_redmod_log = Path("tools/redmod/bin/REDmodLog.txt")
@@ -232,6 +233,8 @@ def init(self, organizer: mobase.IOrganizer) -> bool:
232233
)
233234
organizer.onAboutToRun(self._onAboutToRun)
234235
organizer.onPluginSettingChanged(self._on_settings_changed)
236+
organizer.modList().onModInstalled(self._check_disable_crashreporter)
237+
organizer.onUserInterfaceInitialized(self._check_disable_crashreporter)
235238
return True
236239

237240
def _on_settings_changed(
@@ -247,6 +250,73 @@ def _on_settings_changed(
247250
elif setting == "reverse_remod_load_order":
248251
self._modlist_files["redmod"].reversed_priority = bool(new)
249252

253+
def _check_disable_crashreporter(
254+
self, mod: mobase.IModInterface | None | Any = None
255+
):
256+
"""
257+
Disable Crashreporter with CET installed in VFS, since it crashes
258+
when trying to resolve `version.dll`.
259+
"""
260+
if not self._get_setting("disable_crashreporter"):
261+
return
262+
cet_mod_name = self._find_cet_mod_name(
263+
mod if isinstance(mod, mobase.IModInterface) else None
264+
)
265+
if (
266+
cet_mod_name
267+
and (cr_origin := self._organizer.getFileOrigins(self._crashreporter_path))
268+
and cr_origin[0] == "data"
269+
):
270+
self._create_dummy_crashreporter_mod(
271+
self._organizer.modList().priority(cet_mod_name) + 1
272+
)
273+
274+
def _find_cet_mod_name(self, mod: mobase.IModInterface | None = None) -> str:
275+
"""
276+
Find the mod containing `version.dll`.
277+
278+
Args:
279+
mod (optional): check the mods filetree instead. Defaults to None.
280+
281+
Returns:
282+
The mods name if `version.dll` is found, else ''.
283+
"""
284+
cet_mod_name = ""
285+
if mod:
286+
if mod.fileTree().find("bin/x64/version.dll"):
287+
cet_mod_name = mod.name()
288+
elif dll_origins := self._organizer.getFileOrigins("bin/x64/version.dll"):
289+
cet_mod_name = dll_origins[0]
290+
return cet_mod_name if cet_mod_name != "data" else ""
291+
292+
def _create_dummy_crashreporter_mod(self, priority: int = 0):
293+
"""
294+
Disables CrashReporter by creating an empty dummy file to replace
295+
`CrashReporter.exe`.
296+
"""
297+
mod_name = "disable CrashReporter (MO CET fix)"
298+
modlist = self._organizer.modList()
299+
if modlist.getMod(mod_name):
300+
return
301+
qInfo(f"CET VFS fix: creating mod {mod_name}")
302+
new_mod = self._organizer.createMod(mobase.GuessedString(mod_name))
303+
if not new_mod:
304+
return
305+
mod_name = new_mod.name()
306+
new_mod.setGameName(self.gameShortName())
307+
new_mod.setUrl(f"{self.getSupportURL()}#crashreporter")
308+
crashReporter = Path(new_mod.absolutePath(), self._crashreporter_path)
309+
crashReporter.parent.mkdir(parents=True)
310+
crashReporter.touch()
311+
312+
def callback():
313+
modlist.setActive(mod_name, True)
314+
modlist.setPriority(mod_name, priority)
315+
316+
self._organizer.onNextRefresh(callback, False)
317+
self._organizer.refresh()
318+
self._set_setting("disable_crashreporter", False)
319+
250320
def iniFiles(self):
251321
return ["UserSettings.json"]
252322

@@ -310,6 +380,14 @@ def settings(self) -> list[mobase.PluginSetting]:
310380
),
311381
True,
312382
),
383+
mobase.PluginSetting(
384+
"disable_crashreporter",
385+
(
386+
"Creates a dummy mod/file to disable CrashReporter.exe, "
387+
"which is not compatible with VFS version.dll, see wiki"
388+
),
389+
True,
390+
),
313391
]
314392

315393
def _get_setting(self, key: str) -> mobase.MoVariant:

0 commit comments

Comments
 (0)