feat: prepare mods in manager (WIP)

This commit is contained in:
aclist committed 2026-06-10 06:15:27 +09:00
1 parent 46fba4eef1
commit d4a99f8229
3 files changed
+54 -17

No files matched your search

+13 -4
View File
@@ -87,15 +87,18 @@ def get_mod_size(path: Path) -> float:
return size return size
def get_delimited_mods(steam_path: Path) -> list[Any]: def get_custom_mods(path: Path) -> list[Any]:
workshop_path = get_local_mod_path(steam_path) mods = get_local_mods(path)
mods = get_local_mods(workshop_path) # TODO: error handling
return parse_mods(mods)
def parse_mods(mods: list[Path]) -> list[Any]:
clean = [] clean = []
for mod in mods: for mod in mods:
mod_dir = mod.name mod_dir = mod.name
symlink = _hash(mod_dir) symlink = _hash(mod_dir)
# FIXME: malformed .cpp files could break this # FIXME: malformed .cpp files could break this
# mention that mods may be downloading
meta = parse_meta(mod) meta = parse_meta(mod)
if meta is None: if meta is None:
continue continue
@@ -106,6 +109,12 @@ def get_delimited_mods(steam_path: Path) -> list[Any]:
return clean return clean
def get_delimited_mods(steam_path: Path) -> list[Any]:
workshop_path = get_local_mod_path(steam_path)
mods = get_local_mods(workshop_path)
return parse_mods(mods)
def get_missing_mods(local: list, remote: list) -> list: def get_missing_mods(local: list, remote: list) -> list:
return [mod for mod in remote if mod not in local] return [mod for mod in remote if mod not in local]
+29 -5
View File
@@ -1,9 +1,11 @@
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Union from typing import TYPE_CHECKING
from dzgui.api.mods import get_custom_mods
from dzgui.api.steam import launch_offline from dzgui.api.steam import launch_offline
from dzgui.const.enum import Preferences from dzgui.const.enum import Preferences
from dzgui.managers.threading import call_on_thread, ThreadingManager from dzgui.managers.threading import call_on_thread, ThreadingManager
from dzgui.model.model_factory import FastInsertListStore, ModelFactory
from dzgui.strings import dialogs from dzgui.strings import dialogs
from dzgui.util.symlink import clone_symlinks from dzgui.util.symlink import clone_symlinks
@@ -15,21 +17,41 @@ class OfflineManager:
def __init__( def __init__(
self, self,
controller: "Controller", controller: "Controller",
appid: int,
mission: str = "",
local_mods: Union[list[str], None] = None,
custom_mods: Union[list[str], None] = None,
) -> None: ) -> None:
super().__init__() super().__init__()
self.controller = controller self.controller = controller
self.thread_man = ThreadingManager(controller) self.thread_man = ThreadingManager(controller)
self.appid: int
self.mission_folder: str
self.local_mods: list[str] | None
self.custom_mods: list[str] | None
# TODO: strings
@call_on_thread("parsing")
def parse_custom_mods(self, folder: str) -> "FastInsertListStore":
mods = get_custom_mods(Path(folder))
store = ModelFactory().make_mod_store()
store.extend(mods)
# TODO: manipulate tree columns to only show name and size
return store
def setup(
self,
appid: int,
mission: str = "",
local_mods: list[str] | None = None,
custom_mods: list[str] | None = None,
) -> None:
self.appid = appid self.appid = appid
self.mission_folder = mission self.mission_folder = mission
self.local_mods = local_mods self.local_mods = local_mods
self.custom_mods = custom_mods self.custom_mods = custom_mods
self.launch()
@call_on_thread(dialogs.waiting_for_launch) @call_on_thread(dialogs.waiting_for_launch)
def launch(self) -> None: def launch(self) -> None:
client = self.controller.query_config(Preferences.CLIENT) client = self.controller.query_config(Preferences.CLIENT)
@@ -43,6 +65,8 @@ class OfflineManager:
combined_mods.extend(self.local_mods) combined_mods.extend(self.local_mods)
if self.custom_mods is not None: if self.custom_mods is not None:
# TODO: new function that creates symlinks in game path
# based on selected mods
clone_symlinks(Path(steam_path)) clone_symlinks(Path(steam_path))
combined_mods.extend(new_symlinks) combined_mods.extend(new_symlinks)
+12 -8
View File
@@ -10,6 +10,7 @@ from dzgui.const.constants import (
APPNAME_DAYZ_EXP_HUMAN, APPNAME_DAYZ_EXP_HUMAN,
) )
from dzgui.const.enum import NotebookPage, Preferences from dzgui.const.enum import NotebookPage, Preferences
from dzgui.managers.offline import OfflineManager
from dzgui.strings import offline from dzgui.strings import offline
from dzgui.views.components.scrollable import NoOverlayScrolledWindow from dzgui.views.components.scrollable import NoOverlayScrolledWindow
from dzgui.views.components.frame import HeadingFrame from dzgui.views.components.frame import HeadingFrame
@@ -145,6 +146,11 @@ class CustomModFrame(ModFrame):
if folder is not None: if folder is not None:
self.custom_hbox.set_label(str(folder)) self.custom_hbox.set_label(str(folder))
def get_mods(self) -> list[str]:
rows = self.tree.get_selection().get_selected_rows()
dirs = [str(col[0]) for col in rows]
return dirs
class RadioFrame(HeadingFrame): class RadioFrame(HeadingFrame):
def __init__(self, controller: "Controller") -> None: def __init__(self, controller: "Controller") -> None:
@@ -197,13 +203,13 @@ class OfflineLoader(Gtk.Box):
# TODO: spacing between inner and outer scrollbars # TODO: spacing between inner and outer scrollbars
self.controller = controller self.controller = controller
self.controller.register_widget("offline_loader", self) self.controller.register_widget("offline_loader", self)
self.offline_man = OfflineManager(controller)
self.add(PageHeading(offline.heading)) self.add(PageHeading(offline.heading))
self.local_frame = ModFrame(controller, offline.local_frame) self.local_frame = ModFrame(controller, offline.local_frame)
self.custom_frame = CustomModFrame(controller, offline.custom_frame) self.custom_frame = CustomModFrame(controller, offline.custom_frame)
# TODO: use ModelFactory
# TODO: suppress symlink column # TODO: suppress symlink column
self.custom_tree = OfflineModTreeView(controller) self.custom_tree = OfflineModTreeView(controller)
@@ -259,10 +265,8 @@ class OfflineLoader(Gtk.Box):
def _on_ok_clicked(self, button: Gtk.Button) -> None: def _on_ok_clicked(self, button: Gtk.Button) -> None:
# appid = self.radio_frame.get_appid() # appid = self.radio_frame.get_appid()
# TODO; delegate to OfflineManager # mission = self.mission_frame.get_mission()
""" # local_mods = self.local_frame.get_mods()
- collect symlinks to selected mods # custom_mods = self.custom_frame.get_mods()
cf. rebuild_symlinks() # self.offline_man.setup(appid, mission, local_mods, custom_mods)
- create symlinks for custom mods pass
- collect mission folder
"""