mirror of
https://github.com/aclist/dztui.git
synced 2026-08-26 01:37:18 +02:00
feat: preconnect dialog (WIP)
This commit is contained in:
parent
25640751a5
commit
b42aea1e02
@ -81,7 +81,7 @@ def get_mod_size(path: Path) -> float:
|
||||
s = 0
|
||||
for f in path.rglob("*"):
|
||||
s += f.stat().st_size
|
||||
size = round(s / (1024 * 1024), 3)
|
||||
size = round(s / (1024**2), 3)
|
||||
return size
|
||||
|
||||
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import json
|
||||
import logging
|
||||
import requests
|
||||
import subprocess
|
||||
|
||||
from shlex import shlex
|
||||
from pathlib import Path
|
||||
|
||||
from dzgui.const.constants import APP_NAME
|
||||
from dzgui.const.endpoints import STEAM_PUBLISHED_FILES
|
||||
from dzgui.util.bash import concat_bash_args
|
||||
|
||||
|
||||
@ -49,15 +51,65 @@ def query_defunct() -> None:
|
||||
# query_defunct "3576065083"
|
||||
|
||||
|
||||
def concat_mods(mods: list[str]) -> str:
|
||||
def concat_mods(mods: list[int]) -> str:
|
||||
for mod in mods:
|
||||
mods[mod] = f"@{mod}"
|
||||
return ";".join(mods)
|
||||
|
||||
|
||||
def get_local_signatures(version_file: Path) -> dict[str, int]:
|
||||
hashes: dict[str, int] = {}
|
||||
lines = version_file.read_text().splitlines()
|
||||
for line in lines:
|
||||
line = line.split(",")
|
||||
_id = line[0]
|
||||
_hash = line[1]
|
||||
hashes[_id] = _hash
|
||||
return hashes
|
||||
|
||||
|
||||
def get_needs_update(
|
||||
version_file: Path, remote_hashes: list[tuple[str, int, str]]
|
||||
) -> list[tuple[str, int, str]]:
|
||||
local_hashes = get_local_signatures(version_file)
|
||||
needs_update: list[tuple[str, str]] = []
|
||||
for _id, _hash, size in remote_hashes:
|
||||
if _id not in local_hashes:
|
||||
needs_update.append((_id, _hash, size))
|
||||
elif _hash != local_hashes[_id]:
|
||||
needs_update.append((_id, _hash, size))
|
||||
else:
|
||||
continue
|
||||
return needs_update
|
||||
|
||||
|
||||
def get_remote_signatures(mods: list[str]) -> list[tuple[str, int]]:
|
||||
payload: dict[str, str] = {}
|
||||
payload["itemcount"] = len(mods)
|
||||
for i, mod in enumerate(mods):
|
||||
payload[f"publishedfileids[{i}]"] = mod
|
||||
try:
|
||||
r = requests.post(STEAM_PUBLISHED_FILES, payload)
|
||||
except Exception as e:
|
||||
logger.critical(e)
|
||||
return []
|
||||
if r.status_code != 200:
|
||||
return []
|
||||
|
||||
hashes: list[tuple[str, int, str]] = []
|
||||
j = r.json()
|
||||
rows = j["response"]["publishedfiledetails"]
|
||||
for row in rows:
|
||||
_id = row["publishedfileid"]
|
||||
time = row["time_updated"]
|
||||
size = row["file_size"]
|
||||
hashes.append((_id, time, size))
|
||||
return hashes
|
||||
|
||||
|
||||
# TEST: set config to name=user, use official server and no mods,
|
||||
# ensure that formatted string is identical to fixture
|
||||
def connect(addr: str, appid: int, name: str, mods: list) -> None:
|
||||
def connect(addr: str, appid: int, name: str, mods: list[int]) -> None:
|
||||
# TODO: get name from configs
|
||||
# TODO: concat_mods(mods):
|
||||
# @<mod>;@<mod>;
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
# internal
|
||||
STEAM_PUBLISHED_FILES = "https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/?format=json"
|
||||
STEAM_SERVERS = "https://api.steampowered.com/IGameServersService/GetServerList/v1/?"
|
||||
BM_SERVERS = "https://api.battlemetrics.com/servers?"
|
||||
GITHUB = "https://github.com/aclist"
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import logging
|
||||
import shutil
|
||||
|
||||
from pathlib import Path
|
||||
@ -5,8 +6,10 @@ from typing import Union, TYPE_CHECKING
|
||||
|
||||
import dzgui.api.pefile as PeFile
|
||||
import dzgui.api.servers as Servers
|
||||
from dzgui.api.steam import get_remote_signatures, get_needs_update
|
||||
|
||||
from dzgui.api.mods import get_local_mod_ids
|
||||
from dzgui.const.constants import APP_NAME
|
||||
from dzgui.const.enum import Preferences
|
||||
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
||||
from dzgui.util.strings import dialog, server_timeout, checkmark
|
||||
@ -22,6 +25,8 @@ if TYPE_CHECKING:
|
||||
from dzgui.api.servers import PreReqs
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
logger = logging.getLogger(APP_NAME)
|
||||
|
||||
|
||||
class ConnectionManager:
|
||||
def __init__(self, controller: "Controller") -> None:
|
||||
@ -46,35 +51,55 @@ class ConnectionManager:
|
||||
|
||||
def _prepare_connection(self, res: Union["PreReqs", None]) -> None:
|
||||
failure_func = StoredFunc(self._server_timeout)
|
||||
|
||||
if res is None:
|
||||
self.thread_man.set_cleanup_func(failure_func, destroy_first=True)
|
||||
return
|
||||
|
||||
record = res.record
|
||||
info = res.source
|
||||
|
||||
try:
|
||||
mods = self._query_modlist(record)
|
||||
except Exception:
|
||||
remote_mods = self._query_modlist(record)
|
||||
remote_mod_ids = [mod[1] for mod in remote_mods]
|
||||
except Exception as e:
|
||||
print(e)
|
||||
self.thread_man.set_cleanup_func(failure_func, destroy_first=True)
|
||||
return
|
||||
|
||||
# TODO: get missing mod diff
|
||||
# TODO: get missing mod sizes
|
||||
steam_path = Path(self.controller.query_config(Preferences.DEFAULT))
|
||||
|
||||
hashes = get_remote_signatures(remote_mod_ids)
|
||||
version_file = self.controller.get_prefs().paths.version
|
||||
needs_update = get_needs_update(version_file, hashes)
|
||||
|
||||
# TODO: populate version file at boot if nonexistent (after symlinking)
|
||||
# missing mods should be the totality of all mods with no signature
|
||||
# missing = get_missing_mods(local_mod_ids, remote_mod_ids)
|
||||
# print(missing)
|
||||
|
||||
# TODO: when updating, create symlinks of everything
|
||||
# contains id and signature
|
||||
|
||||
# TODO: get missing mod sizes, warn if not enough space
|
||||
info = res.source
|
||||
try:
|
||||
path = Path(self.controller.query_config(Preferences.DEFAULT))
|
||||
dayz_path = PeFile.get_pefile_path(path, info.game_id)
|
||||
dayz_path = PeFile.get_pefile_path(steam_path, info.game_id)
|
||||
total, used, free = shutil.disk_usage(dayz_path)
|
||||
free_mib = free / (1024**2)
|
||||
print(free_mib)
|
||||
if len(needs_update) > 0:
|
||||
# TODO: generic mib function
|
||||
required_size = sum(int(row[2]) for row in needs_update)
|
||||
required_mib = round(required_size / (1024**2), 3)
|
||||
free_mib = round(free / (1024**2), 3)
|
||||
print(required_mib)
|
||||
print(free_mib)
|
||||
except Exception:
|
||||
# TODO: if this fails, need to show missing build warning
|
||||
# TODO: if this fails, need to show missing build warning, not failure func
|
||||
# build up list of warnings/errors
|
||||
# logger.warning(e)
|
||||
self.thread_man.set_cleanup_func(failure_func, destroy_first=True)
|
||||
|
||||
func = StoredFunc(self.controller.open_connection_assistant, res, mods)
|
||||
# TODO: number separator func
|
||||
# TODO: pack a final PreReq struct with pre-process values
|
||||
|
||||
func = StoredFunc(self.controller.open_connection_assistant, res, remote_mods)
|
||||
self.thread_man.set_cleanup_func(func, destroy_first=True)
|
||||
|
||||
@call_on_thread(dialog.querying)
|
||||
|
||||
@ -27,15 +27,15 @@ from dzgui.views.pages.preconnect import PreConnectionAssistant
|
||||
from dzgui.views.pages.servers import ServerNotebook
|
||||
from dzgui.views.pages.thanks import Thanks
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.config.userprefs import UserPrefs
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version("GLibUnix", "2.0")
|
||||
from gi.repository import Gtk, GLib, GLibUnix, Gdk # type: ignore # noqa E402
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.config.userprefs import UserPrefs
|
||||
|
||||
logger = logging.getLogger(APP_NAME)
|
||||
|
||||
# TODO: drop
|
||||
|
||||
@ -43,7 +43,6 @@ class ValidatedEntry(Gtk.Entry):
|
||||
placeholder_text: str = "",
|
||||
tooltip_text: str = "",
|
||||
) -> None:
|
||||
# TODO: tooltip text should not be hardcoded
|
||||
super().__init__(
|
||||
hexpand=True, placeholder_text=placeholder_text, tooltip_text=tooltip_text
|
||||
)
|
||||
|
||||
@ -12,13 +12,6 @@ from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
# TODO: reimplement as standalone dialogs
|
||||
# NOTE: steam deck prints <2> if dialog title is same as window title
|
||||
# case Popup.MODLIST:
|
||||
# dialog_type = Gtk.MessageType.INFO
|
||||
# button_type = Gtk.ButtonsType.OK
|
||||
# header_text = strings.modlist
|
||||
|
||||
|
||||
class GenericDialog(Gtk.MessageDialog):
|
||||
def __init__(
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
from typing import Literal
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
|
||||
@ -52,9 +52,6 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
||||
spacing=10,
|
||||
)
|
||||
|
||||
# self.rules: dict[Any]
|
||||
# self.mods: list["DayzMod"]
|
||||
|
||||
self.controller.register_widget("preconnect", self)
|
||||
|
||||
# TODO: strings
|
||||
@ -154,24 +151,17 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
||||
prefix = preconnect.total_mods
|
||||
self.mod_count.set_text(f"{prefix}{str(total)}")
|
||||
|
||||
# TODO: check which mods need updating
|
||||
# steam_path = self.controller.get_config_man().lookup(Preferences.DEFAULT)
|
||||
# dayz_version = PeFile.get_pretty_version(steam_path, APPID_DAYZ)
|
||||
# dayz_exp_version = PeFile.get_pretty_version(steam_path, APPID_DAYZ_EXP)
|
||||
# TODO: reset warning and error dialogs
|
||||
|
||||
def download_mods(self) -> None:
|
||||
pass
|
||||
|
||||
def connect_server(self) -> None:
|
||||
# TODO: add to history file and list store
|
||||
# TODO: concat mods
|
||||
"""
|
||||
spawn dialog in thread
|
||||
watch for subprocess
|
||||
return to prior page when finished
|
||||
"""
|
||||
self.back.emit("clicked")
|
||||
pass
|
||||
|
||||
# TODO: icon for mod signature issue
|
||||
# or "Update mods and connect"
|
||||
# also handle servers with no mods; do not show tree
|
||||
|
||||
Loading…
Reference in New Issue
Block a user