mirror of
https://github.com/aclist/dztui.git
synced 2026-10-25 12:12:31 +01:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
343630d2da | ||
|
|
d63c7ce3ec | ||
|
|
f7ad357e6f | ||
|
|
035a01fe34 | ||
|
|
7dd14804aa | ||
|
|
1cc1ba2864 | ||
|
|
8c4d0aecdc |
No files matched your search
+20
-8
@@ -255,16 +255,28 @@ class PeFileError(Exception):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def parse_version_number(data: BinaryIO) -> FileVersion:
|
||||
# https://learn.microsoft.com/en-us/windows/win32/api/verrsrc/ns-verrsrc-vs_fixedfileinfo
|
||||
minor = struct.unpack("<L", data.read(4))[0] >> 16 & 0xFFFF
|
||||
major = struct.unpack("<L", data.read(4))[0] >> 0 & 0xFFFF
|
||||
build = struct.unpack("<L", data.read(4))[0] >> 0 & 0xFFFF
|
||||
# NOTE: 0-pad revision number
|
||||
revision = str(struct.unpack("<L", data.read(4))[0] >> 16 & 0xFFFF)
|
||||
offset = 3 - len(revision)
|
||||
padded = "0" * offset + revision
|
||||
return FileVersion(major, minor, build, padded)
|
||||
"""
|
||||
Note: structure differs from standard VS_FIXEDFILEINFO
|
||||
Major: lower 16 bits of first DWORD
|
||||
Minor: upper 16 bits of first DWORD
|
||||
Build: lower 16 bits of third DWORD
|
||||
Revision: upper 16 bits of second DWORD, zero-padded
|
||||
Lower 16 bits of revision DWORD appear unused.
|
||||
"""
|
||||
major_minor = struct.unpack("<I", data.read(4))[0]
|
||||
revision_pair = struct.unpack("<I", data.read(4))[0]
|
||||
build_dword = struct.unpack("<I", data.read(4))[0]
|
||||
|
||||
major = major_minor & 0xFFFF
|
||||
minor = (major_minor >> 16) & 0xFFFF
|
||||
build = build_dword & 0xFFFF
|
||||
revision = (revision_pair >> 16) & 0xFFFF
|
||||
revision = f"{revision:03d}"
|
||||
|
||||
return FileVersion(major, minor, build, revision)
|
||||
|
||||
|
||||
def seek_to_hex(address: str, data: BinaryIO) -> None:
|
||||
|
||||
+19
-1
@@ -1,13 +1,14 @@
|
||||
import logging
|
||||
import os
|
||||
import psutil
|
||||
import re
|
||||
import requests
|
||||
import subprocess
|
||||
import vdf # type: ignore
|
||||
|
||||
from pathlib import Path
|
||||
from requests.exceptions import HTTPError
|
||||
from typing import Any, Union
|
||||
from typing import Any, Generator, Union
|
||||
from warnings import deprecated
|
||||
|
||||
from dzgui.api.acf import ACF
|
||||
@@ -20,6 +21,7 @@ from dzgui.const.constants import (
|
||||
DAYZ_LAUNCHER,
|
||||
DEBIAN_STEAM_PATH,
|
||||
DEFAULT_STEAM_PATH,
|
||||
DOWNLOADS_PATH,
|
||||
FLATPAK_STEAM_PATH,
|
||||
LIBRARYFOLDERS_PATH,
|
||||
UBUNTU_STEAM_PATH,
|
||||
@@ -439,6 +441,22 @@ def is_dayz_running() -> bool:
|
||||
return any(s in item for sublist in procs for item in sublist for s in substring)
|
||||
|
||||
|
||||
def get_pending_downloads(steam_path: Path, appid: int) -> Generator[Path, None, None]:
|
||||
root_path = get_app_path(steam_path, appid)
|
||||
downloads_dir = root_path / DOWNLOADS_PATH
|
||||
files = downloads_dir.iterdir()
|
||||
return files
|
||||
|
||||
|
||||
def is_dayz_downloading(steam_path: Path, appid: int) -> bool:
|
||||
files = get_pending_downloads(steam_path, appid)
|
||||
reg = re.compile(rf"^state_(?:{APPID_DAYZ_EXP}|{APPID_DAYZ})_.*\.patch$")
|
||||
pending = [f for f in files if reg.match(f.name)]
|
||||
if len(pending) > 0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_app_path(folders_path: Path, appid: int) -> Path:
|
||||
app_path = None
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ DAYZ_BINARY = "DayZ_x64.exe"
|
||||
DAYZ_LAUNCHER = "DayZLauncher.exe"
|
||||
|
||||
LIBRARYFOLDERS_PATH = "steamapps/libraryfolders.vdf"
|
||||
DOWNLOADS_PATH = "steamapps/downloading"
|
||||
WORKSHOP_PATH = "steamapps/workshop/content/" + str(APPID_DAYZ)
|
||||
|
||||
STEAM_CMD = "steam"
|
||||
|
||||
@@ -14,6 +14,7 @@ from dzgui.api.shortcuts import Shortcuts
|
||||
from dzgui.api.steam import (
|
||||
connect,
|
||||
connect_debug,
|
||||
is_dayz_downloading,
|
||||
get_app_allows_downloads,
|
||||
get_app_name,
|
||||
get_needs_update,
|
||||
@@ -84,6 +85,7 @@ class Prerequisites:
|
||||
available_space: float
|
||||
passworded: bool
|
||||
dayz_running: bool
|
||||
download_paused: bool
|
||||
steam_proc: SteamProcess
|
||||
mods: list[list[str]]
|
||||
game_mode: bool
|
||||
@@ -169,6 +171,7 @@ class ConnectionManager:
|
||||
free_mib = format_mib(free)
|
||||
|
||||
dayz_running = is_dayz_running()
|
||||
download_paused = is_dayz_downloading(steam_path, self.appid)
|
||||
|
||||
running_app = get_running_app()
|
||||
if running_app is not None:
|
||||
@@ -210,6 +213,7 @@ class ConnectionManager:
|
||||
available_space=free_mib,
|
||||
passworded=info.password_protected,
|
||||
dayz_running=dayz_running,
|
||||
download_paused=download_paused,
|
||||
steam_proc=steam_proc,
|
||||
mods=remote_mods,
|
||||
game_mode=game_mode,
|
||||
|
||||
@@ -47,3 +47,7 @@ running_app = (
|
||||
"Either stop the game first, or update your global Steam settings or the game's local settings.\n"
|
||||
"Otherwise, mods may be queued for download but never update."
|
||||
)
|
||||
downloads_paused = (
|
||||
"It looks like DayZ may have a pending update on Steam that was paused.\n"
|
||||
"To enqueue mods for download, unpause any pending DayZ update and allow it to complete."
|
||||
)
|
||||
@@ -279,6 +279,8 @@ class PreConnectionAssistant(Gtk.Box):
|
||||
warnings.append(preconnect.protected_server)
|
||||
if prereqs.dayz_running is True:
|
||||
warnings.append(preconnect.dayz_running)
|
||||
if len(prereqs.mods) > 0 and prereqs.download_paused:
|
||||
warnings.append(preconnect.downloads_paused)
|
||||
|
||||
allows_dl, running_app = prereqs.allows_downloads
|
||||
if len(prereqs.mods) > 0 and allows_dl is False:
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ description = "DayZ server browser and mod manager for Linux"
|
||||
authors = [
|
||||
{name = "aclist"}
|
||||
]
|
||||
version = "7.0.0b27"
|
||||
version = "7.0.0b28"
|
||||
license = "GPL-3.0-or-later"
|
||||
license-files = ["LICENSE"]
|
||||
readme = "README.md"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import pytest
|
||||
from pathlib import Path
|
||||
|
||||
from dzgui.api.steam import is_dayz_downloading
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"file_list, expect",
|
||||
[
|
||||
(["state_221100_1111.patch"], True),
|
||||
(["state_730_1111.patch"], False),
|
||||
(["state_1024020_1111.patch"], True),
|
||||
(["221100"], False),
|
||||
(["221100", "state_221100_1111.patch"], True),
|
||||
(["state_221100_1111.patch", "state_1024020_1111.patch"], True),
|
||||
(["state_221100_1111"], False),
|
||||
],
|
||||
)
|
||||
def test_dayz_patch_pending(monkeypatch, file_list, expect) -> None:
|
||||
def mock_get_pending_downloads(steam_path: Path, appid: int) -> None:
|
||||
files = [Path(file) for file in file_list]
|
||||
return files
|
||||
|
||||
monkeypatch.setattr(
|
||||
"dzgui.api.steam.get_pending_downloads", mock_get_pending_downloads
|
||||
)
|
||||
assert is_dayz_downloading(Path("/tmp"), Path("/tmp")) == expect
|
||||
Reference in new issue
Block a user