Skip to content

Commit ab91432

Browse files
[pre-commit.ci] Auto fixes from pre-commit.com hooks.
1 parent d78cf05 commit ab91432

6 files changed

Lines changed: 79 additions & 60 deletions

File tree

games/game_stalker2heartofchornobyl.py

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
1-
from typing import List
1+
import os
22
from enum import IntEnum, auto
3-
from pathlib import Path
4-
from PyQt6.QtCore import QDir, QFileInfo
3+
from typing import List
4+
5+
from PyQt6.QtCore import QDir
56
from PyQt6.QtWidgets import QMainWindow, QTabWidget, QWidget
7+
68
import mobase
7-
import os
9+
10+
from ..basic_features import BasicLocalSavegames, BasicModDataChecker, GlobPatterns
811
from ..basic_game import BasicGame
9-
from ..basic_features import BasicModDataChecker, GlobPatterns, BasicLocalSavegames
1012

1113

1214
class Problems(IntEnum):
1315
"""
1416
Enums for IPluginDiagnose.
1517
"""
18+
1619
# PAK files placed in incorrect locations
1720
MISPLACED_PAK_FILES = auto()
1821
# Missing mod directory structure
@@ -39,7 +42,7 @@ class S2HoCGame(BasicGame, mobase.IPluginFileMapper, mobase.IPluginDiagnose):
3942
GameIniFiles = [
4043
"%GAME_DOCUMENTS%/Saved/Config/Windows/Game.ini",
4144
"%GAME_DOCUMENTS%/Saved/Config/Windows/GameUserSettings.ini",
42-
"%GAME_DOCUMENTS%/Saved/Config/Windows/Engine.ini"
45+
"%GAME_DOCUMENTS%/Saved/Config/Windows/Engine.ini",
4346
]
4447

4548
_main_window: QMainWindow
@@ -64,7 +67,7 @@ def init(self, organizer: mobase.IOrganizer) -> bool:
6467
self._register_feature(
6568
BasicLocalSavegames(QDir(self.resolve_path(self.GameSavesDirectory)))
6669
)
67-
70+
6871
# Create the directory more reliably
6972
if (
7073
self._organizer.managedGame()
@@ -80,10 +83,10 @@ def init(self, organizer: mobase.IOrganizer) -> bool:
8083
print(f"Warning: Failed to create directory: {mod_path}")
8184
except Exception as e:
8285
print(f"Error creating mod directory: {e}")
83-
86+
8487
# Initialize PAK tab when UI is ready
8588
organizer.onUserInterfaceInitialized(self.init_tab)
86-
89+
8790
return True
8891

8992
def init_tab(self, main_window: QMainWindow):
@@ -102,6 +105,7 @@ def init_tab(self, main_window: QMainWindow):
102105

103106
# Import here to avoid circular imports
104107
from .stalker2heartofchornobyl.paks import S2HoCPaksTabWidget
108+
105109
self._paks_tab = S2HoCPaksTabWidget(main_window, self._organizer)
106110

107111
# Insert after the last tab (like Oblivion Remastered)
@@ -110,6 +114,7 @@ def init_tab(self, main_window: QMainWindow):
110114
except Exception as e:
111115
print(f"Error initializing PAK tab: {e}")
112116
import traceback
117+
113118
traceback.print_exc()
114119

115120
def mappings(self) -> List[mobase.Mapping]:
@@ -130,46 +135,48 @@ def mappings(self) -> List[mobase.Mapping]:
130135

131136
def gameDirectory(self) -> QDir:
132137
return QDir(self._gamePath)
133-
138+
134139
def paksDirectory(self) -> QDir:
135140
return QDir(self.gameDirectory().absolutePath() + "/Stalker2/Content/Paks")
136-
141+
137142
def paksModsDirectory(self) -> QDir:
138143
# Use os.path.join for more reliable path construction
139144
path = os.path.join(self.paksDirectory().absolutePath(), "~mods")
140145
return QDir(path)
141-
146+
142147
def logicModsDirectory(self) -> QDir:
143148
# Update path to place LogicMods under Paks
144-
return QDir(self.gameDirectory().absolutePath() + "/Stalker2/Content/Paks/LogicMods")
145-
149+
return QDir(
150+
self.gameDirectory().absolutePath() + "/Stalker2/Content/Paks/LogicMods"
151+
)
152+
146153
def binariesDirectory(self) -> QDir:
147154
return QDir(self.gameDirectory().absolutePath() + "/Stalker2/Binaries/Win64")
148-
155+
149156
def getModMappings(self) -> dict[str, list[str]]:
150157
return {
151158
"Content/Paks/~mods": [self.paksModsDirectory().absolutePath()],
152159
}
153-
160+
154161
def activeProblems(self) -> list[int]:
155162
problems = set()
156163
if self._organizer.managedGame() == self:
157-
158164
# More reliable directory check using os.path
159165
mod_path = self.paksModsDirectory().absolutePath()
160166
if not os.path.isdir(mod_path):
161167
problems.add(Problems.MISSING_MOD_DIRECTORIES)
162168
print(f"Missing mod directory: {mod_path}")
163-
169+
164170
# Check for misplaced PAK files
165171
for mod in self._organizer.modList().allMods():
166172
mod_info = self._organizer.modList().getMod(mod)
167173
filetree = mod_info.fileTree()
168-
174+
169175
# Check for PAK files at the root level (remove LogicMods paths)
170176
for entry in filetree:
171-
if entry.name().endswith(('.pak', '.utoc', '.ucas')) and not any(
172-
entry.path().startswith(p) for p in ['Content/Paks/~mods', 'Paks', '~mods']
177+
if entry.name().endswith((".pak", ".utoc", ".ucas")) and not any(
178+
entry.path().startswith(p)
179+
for p in ["Content/Paks/~mods", "Paks", "~mods"]
173180
):
174181
problems.add(Problems.MISPLACED_PAK_FILES)
175182
break
@@ -228,7 +235,7 @@ def __init__(self, patterns: GlobPatterns = GlobPatterns()):
228235
move_patterns = {
229236
"*.pak": "Content/Paks/~mods/",
230237
"*.utoc": "Content/Paks/~mods/",
231-
"*.ucas": "Content/Paks/~mods/"
238+
"*.ucas": "Content/Paks/~mods/",
232239
}
233240
# Define valid mod roots - remove LogicMods
234241
valid_roots = ["Content", "Paks", "~mods"]
@@ -238,4 +245,4 @@ def __init__(self, patterns: GlobPatterns = GlobPatterns()):
238245

239246

240247
def createPlugin():
241-
return S2HoCGame()
248+
return S2HoCGame()
Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1+
from .paks import S2HoCPaksModel, S2HoCPaksTabWidget, S2HoCPaksView
12

2-
from .paks import S2HoCPaksTabWidget, S2HoCPaksModel, S2HoCPaksView
3-
4-
__all__ = [
5-
"S2HoCPaksTabWidget",
6-
"S2HoCPaksModel",
7-
"S2HoCPaksView"
8-
]
3+
__all__ = ["S2HoCPaksTabWidget", "S2HoCPaksModel", "S2HoCPaksView"]
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from .model import S2HoCPaksModel
2-
from .view import S2HoCPaksView
2+
from .view import S2HoCPaksView
33
from .widget import S2HoCPaksTabWidget
44

5-
__all__ = ["S2HoCPaksTabWidget", "S2HoCPaksModel", "S2HoCPaksView"]
5+
__all__ = ["S2HoCPaksTabWidget", "S2HoCPaksModel", "S2HoCPaksView"]

games/stalker2heartofchornobyl/paks/model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,4 +250,4 @@ def dropMimeData(
250250
index -= 1
251251

252252
self.set_paks(new_paks)
253-
return False
253+
return False

games/stalker2heartofchornobyl/paks/view.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ def dataChanged(
3030
self, topLeft: QModelIndex, bottomRight: QModelIndex, roles: Iterable[int] = ()
3131
):
3232
super().dataChanged(topLeft, bottomRight, roles)
33-
self.repaint()
33+
self.repaint()

games/stalker2heartofchornobyl/paks/widget.py

Lines changed: 43 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import os
21
from functools import cmp_to_key
32
from pathlib import Path
4-
from typing import List, Tuple, cast
3+
from typing import cast
54

65
from PyQt6.QtCore import QDir, QFileInfo
76
from PyQt6.QtWidgets import QGridLayout, QWidget
@@ -124,26 +123,32 @@ def _parse_pak_files(self):
124123
pak_paths: dict[str, tuple[str, str]] = {}
125124
pak_source: dict[str, str] = {}
126125
existing_folders: set[int] = set()
127-
126+
128127
print(f"[PAK Debug] Starting scan of {len(mods)} mods")
129-
print(f"[PAK Debug] ONLY scanning ~mods directories, EXCLUDING LogicMods")
130-
128+
print("[PAK Debug] ONLY scanning ~mods directories, EXCLUDING LogicMods")
129+
131130
# First, scan what numbered folders already exist to avoid double-assignment
132131
game = self._organizer.managedGame()
133132
if isinstance(game, S2HoCGame):
134133
pak_mods_dir = QFileInfo(game.paksModsDirectory().absolutePath())
135134
if pak_mods_dir.exists() and pak_mods_dir.isDir():
136-
print(f"[PAK Debug] Scanning existing folders in: {pak_mods_dir.absoluteFilePath()}")
135+
print(
136+
f"[PAK Debug] Scanning existing folders in: {pak_mods_dir.absoluteFilePath()}"
137+
)
137138
for entry in QDir(pak_mods_dir.absoluteFilePath()).entryInfoList(
138139
QDir.Filter.Dirs | QDir.Filter.NoDotAndDotDot
139140
):
140141
try:
141142
folder_num = int(entry.completeBaseName())
142143
existing_folders.add(folder_num)
143-
print(f"[PAK Debug] Found existing numbered folder: {folder_num}")
144+
print(
145+
f"[PAK Debug] Found existing numbered folder: {folder_num}"
146+
)
144147
except ValueError:
145-
print(f"[PAK Debug] Skipping non-numbered folder: {entry.completeBaseName()}")
146-
148+
print(
149+
f"[PAK Debug] Skipping non-numbered folder: {entry.completeBaseName()}"
150+
)
151+
147152
# Scan mods for PAK files ONLY in Content/Paks/~mods structure (exclude LogicMods)
148153
for mod in mods:
149154
mod_item = self._organizer.modList().getMod(mod)
@@ -152,11 +157,13 @@ def _parse_pak_files(self):
152157
filetree = mod_item.fileTree()
153158

154159
# If this mod contains a LogicMods directory, skip it entirely for the PAK tab
155-
has_logicmods = (
156-
filetree.find("Content/Paks/LogicMods") or filetree.find("Paks/LogicMods")
160+
has_logicmods = filetree.find("Content/Paks/LogicMods") or filetree.find(
161+
"Paks/LogicMods"
157162
)
158163
if isinstance(has_logicmods, mobase.IFileTree):
159-
print(f"[PAK Debug] Skipping mod '{mod_item.name()}' because it contains a LogicMods directory.")
164+
print(
165+
f"[PAK Debug] Skipping mod '{mod_item.name()}' because it contains a LogicMods directory."
166+
)
160167
continue
161168

162169
# ONLY look for ~mods directories
@@ -172,16 +179,22 @@ def _parse_pak_files(self):
172179
sub_entry.isFile()
173180
and sub_entry.suffix().casefold() == "pak"
174181
):
175-
pak_name = sub_entry.name()[: -1 - len(sub_entry.suffix())]
182+
pak_name = sub_entry.name()[
183+
: -1 - len(sub_entry.suffix())
184+
]
176185
paks[pak_name] = entry.name()
177186
pak_paths[pak_name] = (
178187
mod_item.absolutePath()
179188
+ "/"
180-
+ cast(mobase.IFileTree, sub_entry.parent()).path("/"),
181-
mod_item.absolutePath() + "/" + pak_mods.path("/")
189+
+ cast(mobase.IFileTree, sub_entry.parent()).path(
190+
"/"
191+
),
192+
mod_item.absolutePath() + "/" + pak_mods.path("/"),
182193
)
183194
pak_source[pak_name] = mod_item.name()
184-
print(f"[PAK Debug] ✅ Added PAK from ~mods numbered folder: {pak_name} in {entry.name()}")
195+
print(
196+
f"[PAK Debug] ✅ Added PAK from ~mods numbered folder: {pak_name} in {entry.name()}"
197+
)
185198
else:
186199
if entry.suffix().casefold() == "pak":
187200
pak_name = entry.name()[: -1 - len(entry.suffix())]
@@ -190,36 +203,40 @@ def _parse_pak_files(self):
190203
mod_item.absolutePath()
191204
+ "/"
192205
+ cast(mobase.IFileTree, entry.parent()).path("/"),
193-
mod_item.absolutePath() + "/" + pak_mods.path("/")
206+
mod_item.absolutePath() + "/" + pak_mods.path("/"),
194207
)
195208
pak_source[pak_name] = mod_item.name()
196-
print(f"[PAK Debug] ✅ Added loose PAK from ~mods: {pak_name}")
209+
print(
210+
f"[PAK Debug] ✅ Added loose PAK from ~mods: {pak_name}"
211+
)
197212
else:
198213
# Check if this mod has LogicMods (for debugging purposes)
199214
logic_mods = filetree.find("Content/Paks/LogicMods")
200215
if not logic_mods:
201216
logic_mods = filetree.find("Paks/LogicMods")
202217
if isinstance(logic_mods, mobase.IFileTree):
203-
print(f"[PAK Debug] Mod {mod_item.name()} has LogicMods (not included in PAK tab)")
218+
print(
219+
f"[PAK Debug] Mod {mod_item.name()} has LogicMods (not included in PAK tab)"
220+
)
204221

205222
# NOTE: Removed game directory scanning to prevent LogicMods PAKs from appearing
206223
# We only want PAKs from mod files, not from game directory
207-
print(f"[PAK Debug] Skipping game directory scan to prevent LogicMods inclusion")
224+
print("[PAK Debug] Skipping game directory scan to prevent LogicMods inclusion")
208225

209226
# Sort PAKs and shake them (preserve order from paks.txt if it exists)
210227
sorted_paks = dict(sorted(paks.items(), key=cmp_to_key(pak_sort)))
211228
shaken_paks: list[str] = self._shake_paks(sorted_paks)
212-
229+
213230
# Assign target directories with numbered folders (like Oblivion Remastered)
214231
# Skip numbers that already exist, use next available number starting from 8999
215232
final_paks: dict[str, tuple[str, str, str]] = {}
216233
pak_index = 8999
217-
234+
218235
for pak in shaken_paks:
219236
# Find next available number (skip existing folders)
220237
while pak_index in existing_folders:
221238
pak_index -= 1
222-
239+
223240
# If PAK is already in a numbered folder, keep its current assignment
224241
current_folder = paks[pak]
225242
if current_folder.isdigit():
@@ -232,16 +249,16 @@ def _parse_pak_files(self):
232249
existing_folders.add(pak_index)
233250
print(f"[PAK Debug] Assigning {pak} to new folder {pak_index}")
234251
pak_index -= 1
235-
252+
236253
final_paks[pak] = (pak_source[pak], pak_paths[pak][0], target_dir)
237-
254+
238255
# Convert to model format (4-tuple matching Oblivion Remastered)
239256
new_data_paks: dict[int, tuple[str, str, str, str]] = {}
240257
i = 0
241258
for pak, data in final_paks.items():
242259
source, current_path, target_path = data
243260
new_data_paks[i] = (pak, source, current_path, target_path)
244261
i += 1
245-
262+
246263
print(f"[PAK Debug] Final PAK count: {len(new_data_paks)}")
247264
self._model.set_paks(new_data_paks)

0 commit comments

Comments
 (0)