mirror of
https://github.com/ModOrganizer2/modorganizer-basic_games.git
synced 2026-07-27 14:07:29 -07:00
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>
This commit is contained in:
co-authored by
Jeremy Rimpo
parent
7ce47ddc83
commit
f35a6b087a
@@ -0,0 +1,44 @@
|
||||
name: Build Basic Games Plugin
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [master]
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Set environmental variables
|
||||
shell: bash
|
||||
run: |
|
||||
echo "VCPKG_ROOT=$VCPKG_INSTALLATION_ROOT" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: build
|
||||
|
||||
- name: Configure Basic Games Plugin build
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
shell: pwsh
|
||||
run: |
|
||||
cmake --preset vs2022-windows "-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/install" "-DVCPKG_MANIFEST_FEATURES=standalone"
|
||||
|
||||
- name: Build Basic Games Plugin
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
run: cmake --build vsbuild --config RelWithDebInfo
|
||||
|
||||
- name: Install Basic Games Plugin
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
run: cmake --install vsbuild --config RelWithDebInfo
|
||||
|
||||
- name: Upload Basic Games Plugin artifact
|
||||
uses: actions/upload-artifact@master
|
||||
with:
|
||||
name: basic_games
|
||||
path: ${{ github.workspace }}/install/bin/plugins
|
||||
+4
-9
@@ -1,13 +1,8 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
if(DEFINED DEPENDENCIES_DIR)
|
||||
include(${DEPENDENCIES_DIR}/modorganizer_super/cmake_common/mo2.cmake)
|
||||
else()
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../cmake_common/mo2.cmake)
|
||||
endif()
|
||||
|
||||
project(basic_games LANGUAGES NONE)
|
||||
|
||||
find_package(mo2-cmake CONFIG REQUIRED)
|
||||
|
||||
add_custom_target(basic_games ALL)
|
||||
mo2_configure_python(basic_games
|
||||
MODULE
|
||||
TRANSLATIONS OFF)
|
||||
mo2_configure_python(basic_games MODULE TRANSLATIONS OFF)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"configurePresets": [
|
||||
{
|
||||
"binaryDir": "${sourceDir}/vsbuild",
|
||||
"toolchainFile": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"generator": "Visual Studio 17 2022",
|
||||
"name": "vs2022-windows"
|
||||
}
|
||||
],
|
||||
"buildPresets": [
|
||||
{
|
||||
"name": "vs2022-windows",
|
||||
"configurePreset": "vs2022-windows"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
@@ -13,11 +13,9 @@ import mobase
|
||||
|
||||
from ..basic_features import BasicGameSaveGameInfo
|
||||
from ..basic_game import BasicGame
|
||||
from .oblivion_remaster.constants import PLUGIN_NAME
|
||||
from .oblivion_remaster.constants import DEFAULT_UE4SS_MODS, PLUGIN_NAME, UE4SSModInfo
|
||||
from .oblivion_remaster.paks.widget import PaksTabWidget
|
||||
from .oblivion_remaster.ue4ss.widget import UE4SSModInfo, UE4SSTabWidget
|
||||
|
||||
DEFAULT_UE4SS_MODS = ["BPML_GenericFunctions", "BPModLoaderMod"]
|
||||
from .oblivion_remaster.ue4ss.widget import UE4SSTabWidget
|
||||
|
||||
|
||||
def getLootPath() -> Path | None:
|
||||
@@ -286,11 +284,11 @@ class OblivionRemasteredGame(
|
||||
if not ue4ss_mods_txt.exists():
|
||||
with open(ue4ss_mods_txt.absoluteFilePath(), "w") as mods_txt:
|
||||
for mod in DEFAULT_UE4SS_MODS:
|
||||
mods_txt.write(f"{mod} : 1\n")
|
||||
mods_txt.write(f"{mod['mod_name']} : 1\n")
|
||||
if not ue4ss_mods_json.exists():
|
||||
mods_data: list[UE4SSModInfo] = []
|
||||
for mod in DEFAULT_UE4SS_MODS:
|
||||
mods_data.append({"mod_name": mod, "mod_enabled": True})
|
||||
mods_data.append({"mod_name": mod["mod_name"], "mod_enabled": True})
|
||||
with open(ue4ss_mods_json.absoluteFilePath(), "w") as mods_json:
|
||||
mods_json.write(json.dumps(mods_data, indent=4))
|
||||
|
||||
|
||||
@@ -1 +1,14 @@
|
||||
from typing import TypedDict
|
||||
|
||||
PLUGIN_NAME = "Oblivion Remastered Support Plugin"
|
||||
|
||||
|
||||
class UE4SSModInfo(TypedDict):
|
||||
mod_name: str
|
||||
mod_enabled: bool
|
||||
|
||||
|
||||
DEFAULT_UE4SS_MODS: list[UE4SSModInfo] = [
|
||||
{"mod_name": "BPML_GenericFunctions", "mod_enabled": True},
|
||||
{"mod_name": "BPModLoaderMod", "mod_enabled": True},
|
||||
]
|
||||
|
||||
@@ -82,8 +82,14 @@ class OblivionRemasteredDataContent(mobase.ModDataContent):
|
||||
for paks_entry in entry:
|
||||
if isinstance(paks_entry, mobase.IFileTree):
|
||||
if paks_entry.name().casefold() == "~mods":
|
||||
if paks_entry.find("MagicLoader"):
|
||||
contents.add(Content.MAGIC_LOADER)
|
||||
for mods_entry in paks_entry:
|
||||
if isinstance(mods_entry, mobase.IFileTree):
|
||||
if (
|
||||
"magicloader"
|
||||
in mods_entry.name().casefold()
|
||||
):
|
||||
contents.add(Content.MAGIC_LOADER)
|
||||
break
|
||||
if paks_entry.name().casefold() == "logicmods":
|
||||
contents.add(Content.UE4SS)
|
||||
case "movies":
|
||||
|
||||
@@ -235,7 +235,7 @@ class PaksModel(QAbstractItemModel):
|
||||
)
|
||||
)
|
||||
|
||||
index = 9999
|
||||
index = 8999
|
||||
for row, pak in new_paks.items():
|
||||
current_dir = QDir(pak[2])
|
||||
parent_dir = QDir(pak[2])
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import re
|
||||
from functools import cmp_to_key
|
||||
from pathlib import Path
|
||||
from typing import cast
|
||||
@@ -69,7 +68,7 @@ class PaksTabWidget(QWidget):
|
||||
|
||||
def write_pak_files(self):
|
||||
for index, pak in sorted(self._model.paks.items()):
|
||||
name, _, current_path, target_path = pak
|
||||
_, _, current_path, target_path = pak
|
||||
if current_path and current_path != target_path:
|
||||
path_dir = Path(current_path)
|
||||
target_dir = Path(target_path)
|
||||
@@ -77,30 +76,23 @@ class PaksTabWidget(QWidget):
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
if path_dir.exists():
|
||||
for pak_file in path_dir.glob("*.pak"):
|
||||
match = re.match(r"^(\d{4}_)?(.*)", pak_file.stem)
|
||||
if not match:
|
||||
continue
|
||||
match_name = (
|
||||
match.group(2) if match.group(2) else match.group(1)
|
||||
ucas_file = pak_file.with_suffix(".ucas")
|
||||
utoc_file = pak_file.with_suffix(".utoc")
|
||||
for file in (pak_file, ucas_file, utoc_file):
|
||||
if not file.exists():
|
||||
continue
|
||||
try:
|
||||
file.rename(target_dir.joinpath(file.name))
|
||||
except FileExistsError:
|
||||
pass
|
||||
data = self._model.paks[index]
|
||||
self._model.paks[index] = (
|
||||
data[0],
|
||||
data[1],
|
||||
data[3],
|
||||
data[3],
|
||||
)
|
||||
if match_name == name:
|
||||
ucas_file = pak_file.with_suffix(".ucas")
|
||||
utoc_file = pak_file.with_suffix(".utoc")
|
||||
for file in (pak_file, ucas_file, utoc_file):
|
||||
if not file.exists():
|
||||
continue
|
||||
try:
|
||||
file.rename(target_dir.joinpath(file.name))
|
||||
except FileExistsError:
|
||||
pass
|
||||
data = self._model.paks[index]
|
||||
self._model.paks[index] = (
|
||||
data[0],
|
||||
data[1],
|
||||
data[3],
|
||||
data[3],
|
||||
)
|
||||
break
|
||||
break
|
||||
if not list(path_dir.iterdir()):
|
||||
path_dir.rmdir()
|
||||
|
||||
@@ -140,7 +132,7 @@ class PaksTabWidget(QWidget):
|
||||
if isinstance(pak_mods, mobase.IFileTree):
|
||||
for entry in pak_mods:
|
||||
if is_directory(entry):
|
||||
if entry.name().casefold() == "magicloader":
|
||||
if "magicloader" in entry.name().casefold():
|
||||
continue
|
||||
for sub_entry in entry:
|
||||
if (
|
||||
@@ -179,7 +171,7 @@ class PaksTabWidget(QWidget):
|
||||
QDir.Filter.Dirs | QDir.Filter.Files | QDir.Filter.NoDotAndDotDot
|
||||
):
|
||||
if entry.isDir():
|
||||
if entry.completeBaseName().casefold() == "magicloader":
|
||||
if "magicloader" in entry.completeBaseName().casefold():
|
||||
continue
|
||||
for sub_entry in QDir(entry.absoluteFilePath()).entryInfoList(
|
||||
QDir.Filter.Files
|
||||
@@ -207,7 +199,7 @@ class PaksTabWidget(QWidget):
|
||||
sorted_paks = dict(sorted(paks.items(), key=cmp_to_key(pak_sort)))
|
||||
shaken_paks: list[str] = self._shake_paks(sorted_paks)
|
||||
final_paks: dict[str, tuple[str, str, str]] = {}
|
||||
pak_index = 9999
|
||||
pak_index = 8999
|
||||
for pak in shaken_paks:
|
||||
target_dir = pak_paths[pak][1] + "/" + str(pak_index).zfill(4)
|
||||
final_paks[pak] = (pak_source[pak], pak_paths[pak][0], target_dir)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import json
|
||||
from json import JSONDecodeError
|
||||
from typing import Any, Iterable
|
||||
|
||||
from PyQt6.QtCore import (
|
||||
@@ -13,6 +14,8 @@ from PyQt6.QtWidgets import QWidget
|
||||
|
||||
import mobase
|
||||
|
||||
from ..constants import DEFAULT_UE4SS_MODS
|
||||
|
||||
|
||||
class UE4SSListModel(QStringListModel):
|
||||
def __init__(self, parent: QWidget | None, organizer: mobase.IOrganizer):
|
||||
@@ -26,7 +29,10 @@ class UE4SSListModel(QStringListModel):
|
||||
mods_json = QFileInfo(profile.absoluteFilePath("mods.json"))
|
||||
if mods_json.exists():
|
||||
with open(mods_json.absoluteFilePath(), "r") as json_file:
|
||||
mod_data = json.load(json_file)
|
||||
try:
|
||||
mod_data = json.load(json_file)
|
||||
except JSONDecodeError:
|
||||
mod_data = DEFAULT_UE4SS_MODS
|
||||
for mod in mod_data:
|
||||
if mod["mod_enabled"]:
|
||||
self._checked_items.add(mod["mod_name"])
|
||||
@@ -37,7 +43,10 @@ class UE4SSListModel(QStringListModel):
|
||||
mod_list: dict[str, bool] = {}
|
||||
if mods_json.exists():
|
||||
with open(mods_json.absoluteFilePath(), "r") as json_file:
|
||||
mod_data = json.load(json_file)
|
||||
try:
|
||||
mod_data = json.load(json_file)
|
||||
except JSONDecodeError:
|
||||
mod_data = DEFAULT_UE4SS_MODS
|
||||
for mod in mod_data:
|
||||
mod_list[mod["mod_name"]] = mod["mod_enabled"]
|
||||
for i in range(self.rowCount()):
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
import json
|
||||
from functools import cmp_to_key
|
||||
from json import JSONDecodeError
|
||||
from pathlib import Path
|
||||
from typing import TypedDict
|
||||
|
||||
from PyQt6.QtCore import QDir, QFileInfo, Qt
|
||||
from PyQt6.QtWidgets import QGridLayout, QWidget
|
||||
|
||||
import mobase
|
||||
|
||||
from ..constants import DEFAULT_UE4SS_MODS, UE4SSModInfo
|
||||
from .model import UE4SSListModel
|
||||
from .view import UE4SSView
|
||||
|
||||
|
||||
class UE4SSModInfo(TypedDict):
|
||||
mod_name: str
|
||||
mod_enabled: bool
|
||||
|
||||
|
||||
class UE4SSTabWidget(QWidget):
|
||||
def __init__(self, parent: QWidget | None, organizer: mobase.IOrganizer):
|
||||
super().__init__(parent)
|
||||
@@ -155,7 +151,10 @@ class UE4SSTabWidget(QWidget):
|
||||
mods_list: list[str] = []
|
||||
if mods_json.exists() and mods_json.isFile():
|
||||
with open(mods_json.absoluteFilePath(), "r") as json_file:
|
||||
mods = json.load(json_file)
|
||||
try:
|
||||
mods = json.load(json_file)
|
||||
except JSONDecodeError:
|
||||
mods = DEFAULT_UE4SS_MODS
|
||||
for mod in mods:
|
||||
if mod["mod_enabled"]:
|
||||
mods_list.append(mod["mod_name"])
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"features": {
|
||||
"standalone": {
|
||||
"description": "Build Standalone.",
|
||||
"dependencies": [
|
||||
"mo2-cmake"
|
||||
]
|
||||
}
|
||||
},
|
||||
"vcpkg-configuration": {
|
||||
"default-registry": {
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/ModOrganizer2/vcpkg-registry",
|
||||
"baseline": "69db61b22147b14ad66fd05cf798d855f6d68c12"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user