Skip to content

Commit da12f31

Browse files
committed
Remove Cyberpunk RootBuilder option, forced load libraries works now with CET and RED4ext
1 parent a8613c4 commit da12f31

1 file changed

Lines changed: 14 additions & 148 deletions

File tree

games/game_cyberpunk2077.py

Lines changed: 14 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
import re
44
import shutil
55
from collections import Counter
6-
from collections.abc import Iterable, Mapping
6+
from collections.abc import Iterable
77
from dataclasses import dataclass
88
from pathlib import Path
9-
from typing import Any, Literal, TypeVar
9+
from typing import Literal, TypeVar
1010

1111
import mobase
1212
from PyQt6.QtCore import QDateTime, QDir, qCritical, qInfo, qWarning
@@ -17,7 +17,6 @@
1717
BasicGameSaveGameInfo,
1818
format_date,
1919
)
20-
from ..basic_features.utils import is_directory
2120
from ..basic_game import BasicGame
2221

2322

@@ -36,103 +35,12 @@ def __init__(self):
3635
"engine",
3736
"r6",
3837
"mods", # RedMod
39-
"red4ext", # red4ext/RED4ext.dll is moved to root in .fix()
38+
"red4ext",
4039
"bin", # CET etc. gets handled below
41-
"root", # RootBuilder: hardlink / copy to game root
4240
],
4341
)
4442
)
4543

46-
_extra_files_to_move = {
47-
# Red4ext: only .dll files
48-
"red4ext/RED4ext.dll": "root/red4ext/",
49-
"bin/x64/winmm.dll": "root/bin/x64/",
50-
# CET: all files, folder gets handled in .fix()
51-
"bin/x64/version.dll": "root/bin/x64/",
52-
"bin/x64/global.ini": "root/bin/x64/",
53-
"bin/x64/plugins/cyber_engine_tweaks.asi": "root/bin/x64/plugins/",
54-
}
55-
_cet_path = "bin/x64/plugins/cyber_engine_tweaks/"
56-
57-
def dataLooksValid(
58-
self, filetree: mobase.IFileTree
59-
) -> mobase.ModDataChecker.CheckReturn:
60-
# fix: single root folders get traversed by Simple Installer
61-
parent = filetree.parent()
62-
if parent is not None and self.dataLooksValid(parent) is self.FIXABLE:
63-
return self.FIXABLE
64-
status = mobase.ModDataChecker.INVALID
65-
# Check extra fixes
66-
if any(filetree.exists(p) for p in self._extra_files_to_move):
67-
return mobase.ModDataChecker.FIXABLE
68-
rp = self._regex_patterns
69-
for entry in filetree:
70-
name = entry.name().casefold()
71-
if rp.move_match(name) is not None:
72-
status = mobase.ModDataChecker.FIXABLE
73-
elif rp.valid.match(name):
74-
if status is mobase.ModDataChecker.INVALID:
75-
status = mobase.ModDataChecker.VALID
76-
elif self._valid_redmod(entry):
77-
# Archive with REDmod folders, not in mods/
78-
status = mobase.ModDataChecker.FIXABLE
79-
# Accept any other entry
80-
return status
81-
82-
def _valid_redmod(self, filetree: mobase.IFileTree | mobase.FileTreeEntry) -> bool:
83-
return isinstance(filetree, mobase.IFileTree) and bool(
84-
filetree and filetree.find("info.json")
85-
)
86-
87-
def fix(self, filetree: mobase.IFileTree) -> mobase.IFileTree:
88-
for source, target in self._extra_files_to_move.items():
89-
if file := filetree.find(source):
90-
parent = file.parent()
91-
filetree.move(file, target)
92-
clear_empty_folder(parent)
93-
if filetree := super().fix(filetree):
94-
filetree = self._fix_cet_framework(filetree)
95-
# REDmod
96-
for entry in list(filetree):
97-
if not self._regex_patterns.valid.match(
98-
entry.name().casefold()
99-
) and self._valid_redmod(entry):
100-
filetree.move(entry, "mods/")
101-
return filetree
102-
103-
def _fix_cet_framework(self, filetree: mobase.IFileTree) -> mobase.IFileTree:
104-
"""Move CET framework to `root/`, except for `mods`.
105-
Only CET >= v1.27.0 (Patch 2.01) works with USVFS.
106-
107-
See: https://github.com/maximegmd/CyberEngineTweaks/pull/877
108-
"""
109-
if cet_folder := filetree.find(
110-
self._cet_path, mobase.FileTreeEntry.FileTypes.DIRECTORY
111-
):
112-
assert is_directory(cet_folder)
113-
root_cet_path = f"root/{self._cet_path}"
114-
if not cet_folder.exists("mods"):
115-
parent = cet_folder.parent()
116-
filetree.move(cet_folder, root_cet_path.rstrip("/\\"))
117-
else:
118-
parent = cet_folder
119-
for entry in list(cet_folder):
120-
if entry.name() != "mods":
121-
filetree.move(entry, root_cet_path)
122-
clear_empty_folder(parent)
123-
return filetree
124-
125-
126-
def clear_empty_folder(filetree: mobase.IFileTree | None):
127-
if filetree is None:
128-
return
129-
while not filetree:
130-
parent = filetree.parent()
131-
filetree.detach()
132-
if parent is None:
133-
break
134-
filetree = parent
135-
13644

13745
def time_from_seconds(s: int | float) -> str:
13846
m, s = divmod(int(s), 60)
@@ -269,27 +177,10 @@ def active_mod_paths(self, reverse: bool = False) -> Iterable[Path]:
269177
yield mods_path / mod
270178

271179

272-
@dataclass
273-
class PluginDefaultSettings:
274-
organizer: mobase.IOrganizer
275-
plugin_name: str
276-
settings: Mapping[str, mobase.MoVariant]
277-
278-
def is_plugin_enabled(self) -> bool:
279-
return self.organizer.isPluginEnabled(self.plugin_name)
280-
281-
def apply(self) -> bool:
282-
if not self.is_plugin_enabled():
283-
return False
284-
for setting, value in self.settings.items():
285-
self.organizer.setPluginSetting(self.plugin_name, setting, value)
286-
return True
287-
288-
289180
class Cyberpunk2077Game(BasicGame):
290181
Name = "Cyberpunk 2077 Support Plugin"
291182
Author = "6788, Zash"
292-
Version = "2.3.1"
183+
Version = "3.0.0"
293184

294185
GameName = "Cyberpunk 2077"
295186
GameShortName = "cyberpunk2077"
@@ -306,6 +197,9 @@ class Cyberpunk2077Game(BasicGame):
306197
"Game:-Cyberpunk-2077"
307198
)
308199

200+
# CET and RED4ext, relative to Cyberpunk2077.exe
201+
_forced_libraries = ["version.dll", "winmm.dll"]
202+
309203
_redmod_binary = Path("tools/redmod/bin/redMod.exe")
310204
_redmod_log = Path("tools/redmod/bin/REDmodLog.txt")
311205
_redmod_deploy_path = Path("r6/cache/modded/")
@@ -336,37 +230,7 @@ def init(self, organizer: mobase.IOrganizer) -> bool:
336230
reversed_priority=bool(self._get_setting("reverse_redmod_load_order")),
337231
),
338232
)
339-
self._rootbuilder_settings = PluginDefaultSettings(
340-
organizer,
341-
"RootBuilder",
342-
{
343-
"usvfsmode": False,
344-
"linkmode": False,
345-
# Available with RootBuilder v4.5+
346-
# Currently bugged / incompatible with MO 2.5.2 (Python 3.12)
347-
# https://github.com/Kezyma/ModOrganizer-Plugins/issues/36
348-
"linkonlymode": False,
349-
"backup": True,
350-
"cache": True,
351-
"autobuild": True,
352-
"redirect": False,
353-
"installer": False,
354-
"exclusions": "archive,setup_redlauncher.exe,tools",
355-
"linkextensions": "dll,exe",
356-
},
357-
)
358-
359-
def apply_rootbuilder_settings_once(*args: Any):
360-
if not self.isActive() or not self._get_setting("configure_RootBuilder"):
361-
return
362-
if self._rootbuilder_settings.apply():
363-
qInfo(f"RootBuilder configured for {self.gameName()}")
364-
self._set_setting("configure_RootBuilder", False)
365-
366-
organizer.onUserInterfaceInitialized(apply_rootbuilder_settings_once)
367-
organizer.onPluginEnabled("RootBuilder", apply_rootbuilder_settings_once)
368233
organizer.onAboutToRun(self._onAboutToRun)
369-
370234
organizer.onPluginSettingChanged(self._on_settings_changed)
371235
return True
372236

@@ -446,11 +310,6 @@ def settings(self) -> list[mobase.PluginSetting]:
446310
),
447311
True,
448312
),
449-
mobase.PluginSetting(
450-
"configure_RootBuilder",
451-
"Configures RootBuilder for Cyberpunk if installed and enabled",
452-
True,
453-
),
454313
]
455314

456315
def _get_setting(self, key: str) -> mobase.MoVariant:
@@ -489,6 +348,13 @@ def executables(self) -> list[mobase.ExecutableInfo]:
489348
).withArgument(f"{skip_start_screen}"),
490349
]
491350

351+
def executableForcedLoads(self) -> list[mobase.ExecutableForcedLoadSetting]:
352+
exe = Path(self.binaryName()).name
353+
return [
354+
mobase.ExecutableForcedLoadSetting(exe, lib).withEnabled(True)
355+
for lib in self._forced_libraries
356+
]
357+
492358
def _get_redmod_binary(self) -> Path:
493359
"""Absolute path to redmod binary"""
494360
return Path(self.gameDirectory().absolutePath(), self._redmod_binary)

0 commit comments

Comments
 (0)