This commit is contained in:
aclist 2026-06-20 14:28:57 +00:00 committed by GitHub
commit 83e4b0c455
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 49 additions and 17 deletions

View File

@ -170,8 +170,10 @@ def launch_offline(
"-skipintro",
f"-name={name}",
f"-mod={symlinks}",
f"-mission={mission}",
]
if len(mission) > 0:
arg = f"-mission={mission}"
params.append(arg)
proc = subprocess.run([*client_args, *params])
return proc.returncode

View File

@ -4,7 +4,8 @@ UDP_PORT = 27016
VM_FILE = "/proc/sys/vm/max_map_count"
MIN_COUNT = 1048576
RATE_LIMIT_THRESHOLD = 3
API_RATE_LIMIT = 1
CLIENT_RATE_LIMIT = 3
REQUEST_TIMEOUT = 10
APPNAME_DAYZ = "DayZ"

View File

@ -172,3 +172,7 @@ class Emitter(GObject.GObject):
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
def invalid_custom_mods(self) -> None:
pass
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
def all_mods_synched(self) -> None:
pass

View File

@ -23,7 +23,7 @@ from dzgui.managers.contextmenu import ContextMenuManager
from dzgui.managers.notes import NoteManager
from dzgui.model.servers import ServerModelManager
from dzgui.util.diag import write_diagnostic
from dzgui.util.format import format_player_count
from dzgui.util.format import format_exception, format_player_count
from dzgui.util.open_links import open_user_workshop, open_workshop_page
from dzgui.views.dialogs.filepicker import FilePicker
from dzgui.views.dialogs.generic import ExceptionDialog
@ -203,7 +203,10 @@ class Controller(GObject.GObject):
try:
# TODO: where to put config file check
self.mediator.grid.notebook.settings.populate_settings()
except Exception:
except Exception as e:
msg = format_exception(e)
print(msg)
logger.critical(msg)
return
case ButtonType.MODS:
self.load_mods()

View File

@ -25,17 +25,17 @@ from dzgui.api.mods import (
update_signatures,
)
from dzgui.const.constants import (
API_RATE_LIMIT,
APP_NAME,
APPID_DAYZ,
APPID_DAYZ_EXP,
APPNAME_DAYZ,
APPNAME_DAYZ_EXP_HUMAN,
RATE_LIMIT_THRESHOLD,
)
from dzgui.const.enum import NotebookPage, Preferences
from dzgui.init.proc import is_dayz_running, is_steam_running
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
from dzgui.strings.dialogs import waiting_for_launch, waiting_for_mods
from dzgui.strings.dialogs import waiting_for_launch, waiting_for_mods, waiting_for_directories
from dzgui.strings.server_mods import checkmark, resync
from dzgui.util.format import format_mib
from dzgui.util.strings import dialog, server_timeout
@ -276,7 +276,6 @@ class ConnectionManager:
self.thread_man.set_cleanup_func(func)
return
self.thread_man.show_cancel(False)
self.thread_man.update_dialog(waiting_for_launch)
while True:
# FIXME: cancel should not be visible here per setting above
@ -303,8 +302,9 @@ class ConnectionManager:
if self.controller.is_cancel_pending():
return
subscribe(key, int(mod))
time.sleep(RATE_LIMIT_THRESHOLD)
time.sleep(API_RATE_LIMIT)
self.thread_man.update_dialog(waiting_for_directories)
for title, mod, stamp, size in self.missing_mods:
mod_path = self.workshop / mod
@ -322,8 +322,12 @@ class ConnectionManager:
time.sleep(1)
update_signatures(self.missing_mods, prefs.paths.version)
# TODO: just push steam path directly
rebuild_symlinks(prefs.paths.config)
# NOTE: update table status in main loop
self.thread_man.update_emitter("all_mods_synched")
# TODO: just push steam path directly
self._connect_steam(menu_only)
@call_on_thread(waiting_for_mods, show_cancel=True)

View File

@ -12,10 +12,10 @@ from dzgui.api.mods import (
remove_stale_signatures,
)
from dzgui.const.constants import (
API_RATE_LIMIT,
APP_NAME,
APPID_DAYZ,
APPID_DAYZ_EXP,
RATE_LIMIT_THRESHOLD,
)
from dzgui.const.enum import Preferences
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
@ -109,6 +109,7 @@ class ModManager:
def unsub_all_mods(self, mods: list[tuple[str, Gtk.TreeIter]]) -> None:
for mod, _iter in mods:
self.unsub_atomic_mod(mod)
time.sleep(API_RATE_LIMIT)
iters = [_iter for mod, _iter in mods]
func = StoredFunc(self._on_mods_unsubbed, iters)
@ -136,7 +137,7 @@ class ModManager:
symlink.unlink()
except PeFile.AppNotInstalledError:
pass
time.sleep(RATE_LIMIT_THRESHOLD)
time.sleep(API_RATE_LIMIT)
def _on_mods_unsubbed(self, iters: list[Gtk.TreeIter]) -> None:
if self.store is None:

View File

@ -81,6 +81,11 @@ class ThreadingManager:
def set_job_count(self, jobs: int) -> None:
self.jobs = jobs
def update_emitter(self, signal: str) -> None:
if self.controller:
emitter = self.controller.get_emitter()
GLib.idle_add(lambda: emitter.emit(signal))
def update_dialog(self, msg: str) -> None:
GLib.idle_add(lambda: self.wait_dialog.update_text(msg))

View File

@ -1,5 +1,6 @@
waiting_for_launch = "Waiting for DayZ to launch"
waiting_for_mods = "Waiting for Steam to update mods"
waiting_for_mods = "Queueing up mods (step 1/2)"
waiting_for_directories = "Steam is staging mods (step 2/2)"
fetching_update = "Fetching update"
failed_to_update = "Failed to update DZGUI executable"

View File

@ -10,6 +10,7 @@ warnings = "Warnings"
errors = "Errors"
mods = "Mods"
total_mods = "Total mods: "
up_to_date = "All mods are up to date."
all_updated = "All mods updated."
"If you recently installed {build} or moved it to a different drive, "
"restart Steam to allow these changes to synchronize, then try again."

View File

@ -392,7 +392,7 @@ class Options(Gtk.Box):
if prefs.paths.config.is_file() is False:
dialog = ExceptionDialog(self.controller, strings.config_not_found)
dialog.run()
raise Exception
raise OSError(f"Config file '{prefs.paths.config}' not found")
config = query.get_config(prefs.paths.config)

View File

@ -23,6 +23,7 @@ from gi.repository import Gdk, Gtk # noqa E402
if TYPE_CHECKING:
from dzgui.managers.connection import Prerequisites
from dzgui.controllers.mc import Controller
from dzgui.controllers.emitter import Emitter
@dataclass
@ -191,9 +192,14 @@ class PreConnectionAssistant(Gtk.Box):
self.add(self.scrolled_box)
self.add(self.button_box)
emitter = self.controller.get_emitter()
emitter.connect("all_mods_synched", self._on_mods_synched)
self.connect("key-press-event", self._on_keypress)
self.connect("map", self._on_map)
def _on_mods_synched(self, emitter: "Emitter") -> None:
self.tree.mark_mods_synched()
def _on_map(self, widget: Self) -> None:
widgets = (
self.tree_frame,
@ -297,16 +303,16 @@ class PreConnectionAssistant(Gtk.Box):
self._hide_mod_area()
else:
self._show_mod_area()
msg = "All mods are up to date."
msg = preconnect.up_to_date
self.mod_count.set_text(msg)
if prereqs.required_space == 0:
self.ok.set_label(preconnect.connect)
if prereqs.required_space != 0:
pretty = number(prereqs.required_space)
suffix = f" Need to download {pretty} MiB of mod updates."
prefix = preconnect.total_mods
self.mod_count.set_text(f"{prefix}{str(total_mods)}.{suffix}")
else:
self.ok.set_label(preconnect.connect)
if prereqs.is_last_server:
self.connect_last.show()

View File

@ -48,6 +48,10 @@ class ServerModTreeView(ContextMixin, TreeView): # type: ignore
case _:
pass
def mark_mods_synched(self) -> None:
for row in self.mod_store:
row[2] = server_mods.checkmark
# TODO: could be problematic if user downloads mods out of band
def _on_row_activated(
self,