Compare commits

...
10 Commits
Author SHA1 Message Date
aclist 1a065123bb Merge branch 'feat/shortcuts' of github.com:aclist/dztui into feat/shortcuts
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2026-07-12 10:25:06 +09:00
aclist 2586306323 chore: drop comment 2026-07-12 10:24:45 +09:00
aclist 1ccb99d935 Merge branch 'dzgui7' into feat/shortcuts 2026-07-12 10:24:04 +09:00
aclist 054fe968d1 Merge pull request #399 from aclist/feat/reaper-proc
feat: config parsers and reaper process monitor
2026-07-12 10:22:45 +09:00
aclist 1760e6e928 chore: cleanup
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
2026-07-12 10:21:06 +09:00
aclist a2a39e9927 fix: backport fixes from feat/shortcuts 2026-07-12 10:15:58 +09:00
aclist e664f68624 fix: restore prior proc monitor logic (avoids conflicts) 2026-07-12 10:14:55 +09:00
aclist 2e41856348 chore: backport changelog fixes 2026-07-12 10:14:15 +09:00
aclist e92df8c062 Merge pull request #398 from u-alexandru/fix/history-file-not-found
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
fix: prevent stuck launch dialog when history file is missing
2026-07-08 10:41:36 +09:00
u-alexandru 494311e8df fix: prevent stuck launch dialog when history file is missing
update_history_file() opened dzg.history in read mode without handling a
missing file. dzg.history is only created the first time it is written, so
on a fresh install the very first server connection raised FileNotFoundError
inside the post-launch cleanup callback:

  _destroy_on_idle -> _add_to_history_and_return -> update_history_file

The exception propagated out of the GLib idle callback before destroy_dialog()
ran, orphaning the "Waiting for DayZ to launch" modal so it could never be
closed from the UI and its Cancel button was unresponsive.

Treat a missing history file as an empty history so the first connection
records history normally instead of crashing the cleanup callback.
2026-07-07 18:45:22 +03:00
4 changed files with 66 additions and 51 deletions

No files matched your search

-1
View File
@@ -162,7 +162,6 @@ def add_steam_shortcut(steam_path: Path, exe_path: Path) -> None:
images = Path(str(traversable))
icon = images.joinpath("icon.png")
# TEST: assert that record (start dir and exe combo) is in shortcuts after creation
shortcuts = Shortcuts(Path(steam_path))
shortcuts.add_shortcut(APP_NAME, start_dir, exe_path, icon)
shortcuts.save_shortcuts()
+32 -20
View File
@@ -15,6 +15,7 @@ from dzgui.const.constants import (
APPID_DAYZ,
APPID_DAYZ_EXP,
APP_NAME,
DAYZ_BINARY,
DEBIAN_STEAM_PATH,
DEFAULT_STEAM_PATH,
FLATPAK_STEAM_PATH,
@@ -38,19 +39,16 @@ logger = logging.getLogger(APP_NAME)
class AppNotInstalledError(Exception):
"""App not present in user's libraryfolders"""
pass
class AppMovedError(Exception):
"""VDF points to a nonexistent location on disk"""
pass
class VDFLoadError(Exception):
"""Malformed VDF or JSON conversion"""
pass
@@ -219,6 +217,7 @@ def find_user_id(path: Path) -> str | None:
logger.warn(e)
return None
def find_user_id_32(path: Path) -> int:
uid = find_user_id(path)
if uid is None:
@@ -301,21 +300,24 @@ def get_running_app() -> int | None:
PROC_NAME = "steam"
SUBPROC_NAME = "reaper"
FLAG = "AppId"
for proc in psutil.process_iter():
if proc.name() == PROC_NAME:
subprocs = proc.children()
filtered = (proc for proc in subprocs if proc.name() == SUBPROC_NAME)
try:
proc = next(filtered)
except StopIteration:
return None
args = proc.cmdline()
appid = (row for row in args if FLAG in row)
try:
return int(next(appid).split("=")[1])
except StopIteration:
return None
# NOTE: may cause conflicts if multiple apps are running
try:
for proc in psutil.process_iter():
if proc.name() == PROC_NAME:
subprocs = proc.children()
filtered = (proc for proc in subprocs if proc.name() == SUBPROC_NAME)
try:
proc = next(filtered)
except StopIteration:
return None
args = proc.cmdline()
appid = (row for row in args if FLAG in row)
try:
return int(next(appid).split("=")[1])
except StopIteration:
return None
except Exception as e:
logger.debug(e)
return None
@@ -337,9 +339,11 @@ def get_app_allows_downloads(path: Path, appid: int) -> bool:
case _:
return True
def get_config(path: Path) -> Path:
return path.joinpath("config/config.vdf")
def get_client_allows_downloads(path: Path) -> bool:
config = get_config(path)
try:
@@ -360,8 +364,16 @@ def get_client_allows_downloads(path: Path) -> bool:
def is_dayz_running() -> bool:
appid = get_running_app()
return appid in (APPID_DAYZ, APPID_DAYZ_EXP)
"""Subprocesses spawned from Steam will not show up in regular process tree"""
procs = []
substring = DAYZ_BINARY
for proc in psutil.process_iter():
try:
procs.append(proc.cmdline())
except Exception as e:
logger.warning(e)
continue
return any(substring in item for sublist in procs for item in sublist)
def get_app_path(folders_path: Path, appid: int) -> Path:
+29 -28
View File
@@ -1,6 +1,7 @@
# Changelog
## Added
## [7.0.0] Unreleased
### Added
- Setup wizard
- Changelog text wrapping and formatting
- Changelog ships with source
@@ -44,7 +45,7 @@
- Generate Steam shortcuts and cover art
- Warn user if background downloads are disabled
## Changed
### Changed
- Conform to PEP 440 versioning for beta versions
- Reduce padding on keys button
- Boldface breadcrumbs
@@ -61,58 +62,58 @@
- Enable LAN page Empty/Full filters on first run of app
- Propagate subscribed mods to Steam client
## Dropped
### Dropped
- Debug mode
- Branch switching
- Manual mod install mode (describe rationale)
- Force update mods
## Fixed
### Fixed
- Longstanding issue with left clicks not registering as tree selection changes after spamming keyboard input
- Center server title text on server dialogs
- Rare segfaults when changing maps (threading)
- Moved dialogs out of threads
## Unreleased
### Unreleased
- Load offline mods
- Local documentation
- Raw debug command in context menu
## Developer-facing
### Developer-facing
- Add pyproject.toml file
- Show deprecation warnings
- Options -> Dev page
## [6.0.5] 2026-05-17
## Changed
### Changed
- Update symlink hash logic to align with DZGUI 7 beta
- Update A2S helper to latest commit
## [6.0.4] 2026-04-13
## Fixed
### Fixed
- Update A2S module checksums to support servers with missing description field
## [6.0.3] 2026-04-12
## Fixed
### Fixed
- Use GLibUnix namespace where available when setting up SIGINT callback
## [6.0.2] 2026-01-26
## Fixed
### Fixed
- Explicitly use Python 3.13 when calling subprocesses
- Raise error correctly from module
- Do not spawn dialogs from inside of thread when fetching prereqs
## Changed
### Changed
- Optimize time complexity of startup checks
- Optimize coordinate calculation by using local records first
- Rename some internal functions
- Wrap entire startup process in dialog
## [6.0.1] 2026-01-16
## Fixed
### Fixed
- Explicitly use Python 3.13 when calling subprocesses
## [6.0.0] 2026-01-14
## Added
### Added
- Support DayZ Experimental
- Ping display on server tables
- Save descriptive text notes on a per-server basis
@@ -138,7 +139,7 @@
- Commandline usage help text (GaryBlackbourne)
- More descriptive help dialogs when initial dependencies are missing
## Fixed
### Fixed
- Script failing to start when remote endpoints are unavailable (GaryBlackbourne)
- Key stickiness when quickly navigating through entries in tables
- Servers returning malformed A2S_INFO blocking server browser from loading
@@ -177,7 +178,7 @@
- Path discovery during first-time setup when parsing filepaths with whitespaces
- First-time setup dialog continuously triggering when DayZ install path had whitespaces in it
## Changed
### Changed
- Require Python 3.13
- Reduced global API cooldown from 60s to 30s
- Clarify dialog messages when DayZ path could not be found
@@ -189,50 +190,50 @@
- Rewrote distance calculation module (GaryBlackbourne)
- Changed preferred client setting from radio toggle to combobox
## Dropped
### Dropped
- Ping readout in statusbar
- Extraneous information from right statusbar
## [5.8.3] 2026-01-04
## Fixed
### Fixed
- Normalize checksum numbers and dates
## [5.8.2] 2026-01-04
## Fixed
### Fixed
- Fix regression in symlink routine introduced by previous hotfix
## [5.8.1] 2025-12-27
## Fixed
### Fixed
- Path discovery during first-time setup when parsing filepaths with whitespaces
- First-time setup dialog continuously triggering when DayZ install path had whitespaces in it
## [5.8.0] 2025-07-06
## Added
### Added
- Filter servers by official/unofficial status
- Automatically fetch geolocation records
## Changed
### Changed
- Updated internal versioning of helper files
## Fixed
### Fixed
- Corrected erroneous 2024 date in prior changelog entries
## [5.7.0] 2025-04-17
## Added
### Added
- Save application dimensions when quitting and restore on subsequent boot
## Fixed
### Fixed
- Issues with the window exceeding the bounds of the screen when displaying some table contexts
## Changed
### Changed
- More direct server ping query method that should return marginally more accurate times
## [5.6.7] 2025-04-04
## Dropped
### Dropped
- Removed extraneous pre-boot API checks that could cause error messages to be printed if the user had not set up an API key yet
## [5.6.6] 2025-03-16
## Changed
### Changed
- Update IP database records for 2025-03
## [5.6.5] 2025-03-04
## Fixed
### Fixed
- Livonia server results being dropped from batch queries
## [5.6.4] 2025-02-10
+5 -2
View File
@@ -55,8 +55,11 @@ class ConfigManager:
self.update_config(Preferences.IP_LIST, ips)
def update_history_file(self, fqip: str) -> None:
with open(self.prefs.paths.history, "r") as f:
ips = [line.rstrip() for line in f.readlines()]
try:
with open(self.prefs.paths.history, "r") as f:
ips = [line.rstrip() for line in f.readlines()]
except FileNotFoundError:
ips = []
seen = set()
ips.append(fqip)