Skip to content

Commit f35a6b0

Browse files
Holt59Silarn
andauthored
Move to VCPKG for mo2-cmake. (#151)
* Oblivion Remastered updates - Handle invalid JSON - Remove outdated pak sorting code - Start from 8999 for pak directories - Leaves space for early loaders - Update MagicLoader handling for more dir names --------- Co-authored-by: Jeremy Rimpo <jeremy.rimpo@servermonkey.com>
1 parent 7ce47dd commit f35a6b0

11 files changed

Lines changed: 145 additions & 55 deletions

File tree

.github/workflows/build.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Build Basic Games Plugin
2+
3+
on:
4+
push:
5+
branches: [master]
6+
pull_request:
7+
types: [opened, synchronize, reopened]
8+
9+
jobs:
10+
build:
11+
runs-on: windows-2022
12+
steps:
13+
- uses: actions/setup-python@v5
14+
with:
15+
python-version: "3.12"
16+
17+
- name: Set environmental variables
18+
shell: bash
19+
run: |
20+
echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> $GITHUB_ENV
21+
22+
- uses: actions/checkout@v4
23+
with:
24+
path: build
25+
26+
- name: Configure Basic Games Plugin build
27+
working-directory: ${{ github.workspace }}/build
28+
shell: pwsh
29+
run: |
30+
cmake --preset vs2022-windows "-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install" "-DVCPKG_MANIFEST_FEATURES=standalone"
31+
32+
- name: Build Basic Games Plugin
33+
working-directory: ${{ github.workspace }}/build
34+
run: cmake --build vsbuild --config RelWithDebInfo
35+
36+
- name: Install Basic Games Plugin
37+
working-directory: ${{ github.workspace }}/build
38+
run: cmake --install vsbuild --config RelWithDebInfo
39+
40+
- name: Upload Basic Games Plugin artifact
41+
uses: actions/upload-artifact@master
42+
with:
43+
name: basic_games
44+
path: ${{ github.workspace }}/install/bin/plugins

CMakeLists.txt

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
11
cmake_minimum_required(VERSION 3.16)
22

3-
if(DEFINED DEPENDENCIES_DIR)
4-
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/mo2.cmake)
5-
else()
6-
include(${CMAKE_CURRENT_LIST_DIR}/../cmake_common/mo2.cmake)
7-
endif()
8-
93
project(basic_games LANGUAGES NONE)
4+
5+
find_package(mo2-cmake CONFIG REQUIRED)
6+
107
add_custom_target(basic_games ALL)
11-
mo2_configure_python(basic_games
12-
MODULE
13-
TRANSLATIONS OFF)
8+
mo2_configure_python(basic_games MODULE TRANSLATIONS OFF)

CMakePresets.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"configurePresets": [
3+
{
4+
"binaryDir": "${sourceDir}/vsbuild",
5+
"toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
6+
"generator": "Visual Studio 17 2022",
7+
"name": "vs2022-windows"
8+
}
9+
],
10+
"buildPresets": [
11+
{
12+
"name": "vs2022-windows",
13+
"configurePreset": "vs2022-windows"
14+
}
15+
],
16+
"version": 4
17+
}

games/game_oblivion_remaster.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,9 @@
1313

1414
from ..basic_features import BasicGameSaveGameInfo
1515
from ..basic_game import BasicGame
16-
from .oblivion_remaster.constants import PLUGIN_NAME
16+
from .oblivion_remaster.constants import DEFAULT_UE4SS_MODS, PLUGIN_NAME, UE4SSModInfo
1717
from .oblivion_remaster.paks.widget import PaksTabWidget
18-
from .oblivion_remaster.ue4ss.widget import UE4SSModInfo, UE4SSTabWidget
19-
20-
DEFAULT_UE4SS_MODS = ["BPML_GenericFunctions", "BPModLoaderMod"]
18+
from .oblivion_remaster.ue4ss.widget import UE4SSTabWidget
2119

2220

2321
def getLootPath() -> Path | None:
@@ -286,11 +284,11 @@ def write_default_mods(self, profile: QDir):
286284
if not ue4ss_mods_txt.exists():
287285
with open(ue4ss_mods_txt.absoluteFilePath(), "w") as mods_txt:
288286
for mod in DEFAULT_UE4SS_MODS:
289-
mods_txt.write(f"{mod} : 1\n")
287+
mods_txt.write(f"{mod['mod_name']} : 1\n")
290288
if not ue4ss_mods_json.exists():
291289
mods_data: list[UE4SSModInfo] = []
292290
for mod in DEFAULT_UE4SS_MODS:
293-
mods_data.append({"mod_name": mod, "mod_enabled": True})
291+
mods_data.append({"mod_name": mod["mod_name"], "mod_enabled": True})
294292
with open(ue4ss_mods_json.absoluteFilePath(), "w") as mods_json:
295293
mods_json.write(json.dumps(mods_data, indent=4))
296294

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,14 @@
1+
from typing import TypedDict
2+
13
PLUGIN_NAME = "Oblivion Remastered Support Plugin"
4+
5+
6+
class UE4SSModInfo(TypedDict):
7+
mod_name: str
8+
mod_enabled: bool
9+
10+
11+
DEFAULT_UE4SS_MODS: list[UE4SSModInfo] = [
12+
{"mod_name": "BPML_GenericFunctions", "mod_enabled": True},
13+
{"mod_name": "BPModLoaderMod", "mod_enabled": True},
14+
]

games/oblivion_remaster/mod_data_content.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,14 @@ def getContentsFor(self, filetree: mobase.IFileTree) -> list[int]:
8282
for paks_entry in entry:
8383
if isinstance(paks_entry, mobase.IFileTree):
8484
if paks_entry.name().casefold() == "~mods":
85-
if paks_entry.find("MagicLoader"):
86-
contents.add(Content.MAGIC_LOADER)
85+
for mods_entry in paks_entry:
86+
if isinstance(mods_entry, mobase.IFileTree):
87+
if (
88+
"magicloader"
89+
in mods_entry.name().casefold()
90+
):
91+
contents.add(Content.MAGIC_LOADER)
92+
break
8793
if paks_entry.name().casefold() == "logicmods":
8894
contents.add(Content.UE4SS)
8995
case "movies":

games/oblivion_remaster/paks/model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ def dropMimeData(
235235
)
236236
)
237237

238-
index = 9999
238+
index = 8999
239239
for row, pak in new_paks.items():
240240
current_dir = QDir(pak[2])
241241
parent_dir = QDir(pak[2])

games/oblivion_remaster/paks/widget.py

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import re
21
from functools import cmp_to_key
32
from pathlib import Path
43
from typing import cast
@@ -69,38 +68,31 @@ def write_paks_list(self):
6968

7069
def write_pak_files(self):
7170
for index, pak in sorted(self._model.paks.items()):
72-
name, _, current_path, target_path = pak
71+
_, _, current_path, target_path = pak
7372
if current_path and current_path != target_path:
7473
path_dir = Path(current_path)
7574
target_dir = Path(target_path)
7675
if not target_dir.exists():
7776
target_dir.mkdir(parents=True, exist_ok=True)
7877
if path_dir.exists():
7978
for pak_file in path_dir.glob("*.pak"):
80-
match = re.match(r"^(\d{4}_)?(.*)", pak_file.stem)
81-
if not match:
82-
continue
83-
match_name = (
84-
match.group(2) if match.group(2) else match.group(1)
79+
ucas_file = pak_file.with_suffix(".ucas")
80+
utoc_file = pak_file.with_suffix(".utoc")
81+
for file in (pak_file, ucas_file, utoc_file):
82+
if not file.exists():
83+
continue
84+
try:
85+
file.rename(target_dir.joinpath(file.name))
86+
except FileExistsError:
87+
pass
88+
data = self._model.paks[index]
89+
self._model.paks[index] = (
90+
data[0],
91+
data[1],
92+
data[3],
93+
data[3],
8594
)
86-
if match_name == name:
87-
ucas_file = pak_file.with_suffix(".ucas")
88-
utoc_file = pak_file.with_suffix(".utoc")
89-
for file in (pak_file, ucas_file, utoc_file):
90-
if not file.exists():
91-
continue
92-
try:
93-
file.rename(target_dir.joinpath(file.name))
94-
except FileExistsError:
95-
pass
96-
data = self._model.paks[index]
97-
self._model.paks[index] = (
98-
data[0],
99-
data[1],
100-
data[3],
101-
data[3],
102-
)
103-
break
95+
break
10496
if not list(path_dir.iterdir()):
10597
path_dir.rmdir()
10698

@@ -140,7 +132,7 @@ def _parse_pak_files(self):
140132
if isinstance(pak_mods, mobase.IFileTree):
141133
for entry in pak_mods:
142134
if is_directory(entry):
143-
if entry.name().casefold() == "magicloader":
135+
if "magicloader" in entry.name().casefold():
144136
continue
145137
for sub_entry in entry:
146138
if (
@@ -179,7 +171,7 @@ def _parse_pak_files(self):
179171
QDir.Filter.Dirs | QDir.Filter.Files | QDir.Filter.NoDotAndDotDot
180172
):
181173
if entry.isDir():
182-
if entry.completeBaseName().casefold() == "magicloader":
174+
if "magicloader" in entry.completeBaseName().casefold():
183175
continue
184176
for sub_entry in QDir(entry.absoluteFilePath()).entryInfoList(
185177
QDir.Filter.Files
@@ -207,7 +199,7 @@ def _parse_pak_files(self):
207199
sorted_paks = dict(sorted(paks.items(), key=cmp_to_key(pak_sort)))
208200
shaken_paks: list[str] = self._shake_paks(sorted_paks)
209201
final_paks: dict[str, tuple[str, str, str]] = {}
210-
pak_index = 9999
202+
pak_index = 8999
211203
for pak in shaken_paks:
212204
target_dir = pak_paths[pak][1] + "/" + str(pak_index).zfill(4)
213205
final_paks[pak] = (pak_source[pak], pak_paths[pak][0], target_dir)

games/oblivion_remaster/ue4ss/model.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
from json import JSONDecodeError
23
from typing import Any, Iterable
34

45
from PyQt6.QtCore import (
@@ -13,6 +14,8 @@
1314

1415
import mobase
1516

17+
from ..constants import DEFAULT_UE4SS_MODS
18+
1619

1720
class UE4SSListModel(QStringListModel):
1821
def __init__(self, parent: QWidget | None, organizer: mobase.IOrganizer):
@@ -26,7 +29,10 @@ def _init_mod_states(self):
2629
mods_json = QFileInfo(profile.absoluteFilePath("mods.json"))
2730
if mods_json.exists():
2831
with open(mods_json.absoluteFilePath(), "r") as json_file:
29-
mod_data = json.load(json_file)
32+
try:
33+
mod_data = json.load(json_file)
34+
except JSONDecodeError:
35+
mod_data = DEFAULT_UE4SS_MODS
3036
for mod in mod_data:
3137
if mod["mod_enabled"]:
3238
self._checked_items.add(mod["mod_name"])
@@ -37,7 +43,10 @@ def _set_mod_states(self):
3743
mod_list: dict[str, bool] = {}
3844
if mods_json.exists():
3945
with open(mods_json.absoluteFilePath(), "r") as json_file:
40-
mod_data = json.load(json_file)
46+
try:
47+
mod_data = json.load(json_file)
48+
except JSONDecodeError:
49+
mod_data = DEFAULT_UE4SS_MODS
4150
for mod in mod_data:
4251
mod_list[mod["mod_name"]] = mod["mod_enabled"]
4352
for i in range(self.rowCount()):

games/oblivion_remaster/ue4ss/widget.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
11
import json
22
from functools import cmp_to_key
3+
from json import JSONDecodeError
34
from pathlib import Path
4-
from typing import TypedDict
55

66
from PyQt6.QtCore import QDir, QFileInfo, Qt
77
from PyQt6.QtWidgets import QGridLayout, QWidget
88

99
import mobase
1010

11+
from ..constants import DEFAULT_UE4SS_MODS, UE4SSModInfo
1112
from .model import UE4SSListModel
1213
from .view import UE4SSView
1314

1415

15-
class UE4SSModInfo(TypedDict):
16-
mod_name: str
17-
mod_enabled: bool
18-
19-
2016
class UE4SSTabWidget(QWidget):
2117
def __init__(self, parent: QWidget | None, organizer: mobase.IOrganizer):
2218
super().__init__(parent)
@@ -155,7 +151,10 @@ def sort_mods(self, mod_a: str, mod_b: str) -> int:
155151
mods_list: list[str] = []
156152
if mods_json.exists() and mods_json.isFile():
157153
with open(mods_json.absoluteFilePath(), "r") as json_file:
158-
mods = json.load(json_file)
154+
try:
155+
mods = json.load(json_file)
156+
except JSONDecodeError:
157+
mods = DEFAULT_UE4SS_MODS
159158
for mod in mods:
160159
if mod["mod_enabled"]:
161160
mods_list.append(mod["mod_name"])

0 commit comments

Comments
 (0)