mirror of
https://github.com/aclist/dztui.git
synced 2026-10-25 12:12:31 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dac02d75f6 | ||
|
|
3a5c061dbf | ||
|
|
3851b76ca0 | ||
|
|
387930b147 | ||
|
|
c0c3ee8c64 | ||
|
|
1212c09110 | ||
|
|
86e2249a23 | ||
|
|
302a43e65e | ||
|
|
3dc58c1a69 | ||
|
|
9af2145ee8 | ||
|
|
7b4382b178 | ||
|
|
ea3631072b | ||
|
|
67bae3c3e0 | ||
|
|
1ea30270ce | ||
|
|
2c9b36ba84 | ||
|
|
fd9eb33714 | ||
|
|
15d928026a | ||
|
|
24d3bc8209 | ||
|
|
881847cee9 | ||
|
|
d3a06cf970 | ||
|
|
741344e75e | ||
|
|
a8a7aba338 | ||
|
|
fafd4c6000 | ||
|
|
7e5e326ebe | ||
|
|
e7644b49f5 |
No files matched your search
@@ -8,7 +8,7 @@ jobs:
|
||||
mirror-to-codeberg:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: pixta-dev/repository-mirroring-action@v1
|
||||
|
||||
+2
-1
@@ -36,6 +36,7 @@
|
||||
- Preconnect warnings/failsafes like filesize
|
||||
- Save filters per server context between sessions
|
||||
- Preboot progress dialog
|
||||
- Choose to jump into splash screen instead of server
|
||||
|
||||
|
||||
## Changed
|
||||
@@ -52,6 +53,7 @@
|
||||
- Embed Workshop link in Options menu
|
||||
- Disable overlay scrollbars on server tables
|
||||
- Reduce size of geolocation DB on disk (~100MB)
|
||||
- Enable LAN page Empty/Full filters on first run of app
|
||||
|
||||
## Dropped
|
||||
- Debug mode
|
||||
@@ -67,7 +69,6 @@
|
||||
|
||||
## Unreleased
|
||||
- Load offline mods
|
||||
- Choose to jump into splash screen instead of server
|
||||
- Local documentation
|
||||
- Raw debug command in context menu
|
||||
|
||||
|
||||
+11
-6
@@ -3,16 +3,21 @@ Knowledge Base
|
||||
|
||||
.. _DZG-001:
|
||||
|
||||
DZG-001: Periodically getting dropped from servers, or servers appear unreachable
|
||||
DZG-001: Periodically getting dropped from servers, or servers time out in DZGUI
|
||||
------------------------------------------------------------------------------------
|
||||
It is a longstanding issue in DayZ that the game opens a large number of connections when querying servers and/or while connected to servers.
|
||||
This can result in excess traffic on the user's PC which, depending on how much headroom your network has, can lead to getting dropped, unresponsiveness, or a timeout.
|
||||
DayZ opens a large number of connections while querying/connected to servers.
|
||||
|
||||
If you are on Wi-Fi, try switching to a wired connection and see if the problem resolves itself. If it does, your wireless router settings do not have enough headroom for max simultaneous connections. Use a wired connection, or update your network settings to a more permissive setup.
|
||||
In addition, packets sent from server responses are expected to be a standard size (see warning below).
|
||||
|
||||
Bohemia has acknowledged this issue going back 10+ years and stated that DayZ has a heavy impact on the network, but there is as yet no proposed solution on the DayZ side.
|
||||
If your network does not have enough headroom or has settings departing from defaults, this may lead to getting dropped from servers,
|
||||
unresponsiveness, or a timeout.
|
||||
|
||||
This issue is frequently seen on Steam Deck, due to the tendency for users to use it in an untethered Wi-Fi setup.
|
||||
If you are on Wi-Fi, try switching to a wired connection and see if the problem resolves itself. Consumer Wi-Fi routers
|
||||
tend to have less headroom than their wired counterparts.
|
||||
|
||||
.. important::
|
||||
Ensure that MTU (maximum tranmission unit) on your network is set to the standard size of 1,500 bytes.
|
||||
If your network preferences or router have "jumbo" frames enabled, packets may be dropped, causing server queries to time out.
|
||||
|
||||
.. _DZG-002:
|
||||
|
||||
|
||||
+1
-2
@@ -456,6 +456,5 @@ def get_pretty_version(steam_path: Path, appid: int) -> str | None:
|
||||
vers = get_dayz_version(pe_file_path)
|
||||
dayz_version = dayz_version_to_str(vers)
|
||||
return dayz_version
|
||||
except Exception as e:
|
||||
print(e)
|
||||
except Exception:
|
||||
return None
|
||||
@@ -61,6 +61,8 @@ class Details:
|
||||
|
||||
@dataclass(slots=True)
|
||||
class Record:
|
||||
# TODO: investigate whether this enum is still being used;
|
||||
# can this be frozen?
|
||||
"""
|
||||
The gameport field is manipulated by the RowType.CONN_BY_IP method
|
||||
"""
|
||||
@@ -509,6 +511,10 @@ def fqip_to_record(addr: str) -> Optional[Record]:
|
||||
return Record(r[0], int(r[1]), int(r[2]))
|
||||
|
||||
|
||||
def record_to_fqip(record: Record) -> str:
|
||||
return f"{record.ip}:{record.gameport}:{record.qport}"
|
||||
|
||||
|
||||
def response_to_fqip(res: dict) -> str:
|
||||
ip = res["addr"].split(":")[0]
|
||||
gameport = res["gameport"]
|
||||
|
||||
@@ -146,6 +146,23 @@ def connect(client: str, addr: str, appid: int, name: str, mods: list[str]) -> i
|
||||
return proc.returncode
|
||||
|
||||
|
||||
def load_to_menu(client: str, addr: str, appid: int, name: str, mods: list[str]) -> int:
|
||||
"""Loads to the menu screen with the selected mods; used for AFK/pre-joining"""
|
||||
concat = concat_mods(mods)
|
||||
client_args = concat_bash_args(client)
|
||||
params = [
|
||||
"-applaunch",
|
||||
str(appid),
|
||||
"-nolauncher",
|
||||
"-nosplash",
|
||||
"-skipintro",
|
||||
f"-name={name}",
|
||||
f"-mod={concat}",
|
||||
]
|
||||
proc = subprocess.run([*client_args, *params])
|
||||
return proc.returncode
|
||||
|
||||
|
||||
def find_user_id(path: Path) -> str | None:
|
||||
resolved_path = path / "config" / "loginusers.vdf"
|
||||
try:
|
||||
|
||||
@@ -409,9 +409,12 @@ class Controller(GObject.GObject):
|
||||
saved_tree = self.get_servers().get_saved()
|
||||
ServerModelManager(self, saved_tree).remove_by_record(record)
|
||||
|
||||
def add_to_history(self, record: dict[str, Any]) -> None:
|
||||
def add_to_history(self, row: dict[str, Any], record: "Record") -> None:
|
||||
tv = self.get_servers().get_recent()
|
||||
ServerModelManager(self, tv).add_to_history(record)
|
||||
ServerModelManager(self, tv).add_to_history((row, record))
|
||||
|
||||
# def append_to_history(self, record: "Record") -> None:
|
||||
# self.config_man.append_to_history_file(record)
|
||||
|
||||
def remove_from_history(self, record: "Record") -> None:
|
||||
# NOTE: remove action is only possible from history tree context menu,
|
||||
@@ -508,6 +511,9 @@ class Controller(GObject.GObject):
|
||||
ind = self.config_man.get_start_tab()
|
||||
self.get_servers().notebook.set_current_page(ind)
|
||||
|
||||
def update_and_load_to_menu(self, raise_window: bool) -> None:
|
||||
self.connection_man.update_and_connect(raise_window, menu_only=True)
|
||||
|
||||
def update_and_connect(self, raise_window: bool) -> None:
|
||||
self.connection_man.update_and_connect(raise_window)
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
- Preconnect warnings/failsafes like filesize
|
||||
- Save filters per server context between sessions
|
||||
- Preboot progress dialog
|
||||
- Choose to jump into splash screen instead of server
|
||||
|
||||
|
||||
## Changed
|
||||
@@ -51,6 +52,8 @@
|
||||
- Suppress log messages from imported modules
|
||||
- Embed Workshop link in Options menu
|
||||
- Disable overlay scrollbars on server tables
|
||||
- Reduce size of geolocation DB on disk (~100MB)
|
||||
- Enable LAN page Empty/Full filters on first run of app
|
||||
|
||||
## Dropped
|
||||
- Debug mode
|
||||
@@ -66,7 +69,6 @@
|
||||
|
||||
## Unreleased
|
||||
- Load offline mods
|
||||
- Choose to jump into splash screen instead of server
|
||||
- Local documentation
|
||||
- Raw debug command in context menu
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
import traceback
|
||||
|
||||
from collections import deque
|
||||
from typing import Any, TYPE_CHECKING
|
||||
|
||||
from dzgui.const.constants import (
|
||||
@@ -52,11 +53,25 @@ class ConfigManager:
|
||||
ips.append(record)
|
||||
self.update_config(Preferences.IP_LIST, ips)
|
||||
|
||||
def update_history_file(self, records: list[Any]) -> None:
|
||||
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()]
|
||||
|
||||
seen = set()
|
||||
ips.append(fqip)
|
||||
# NOTE: Preserve linear order of records while deduplicating
|
||||
unique = deque(maxlen=10) # type: ignore
|
||||
for i in range(len(ips) - 1, -1, -1):
|
||||
if ips[i] not in seen:
|
||||
seen.add(ips[i])
|
||||
unique.appendleft(ips[i])
|
||||
# NOTE: appendleft will push 11th item off right edge
|
||||
if len(unique) == 10:
|
||||
break
|
||||
|
||||
with open(self.prefs.paths.history, "w") as f:
|
||||
for record in records:
|
||||
addr = f"{record[7]}:{record[8]}"
|
||||
f.write(f"{addr}\n")
|
||||
for record in unique:
|
||||
f.write(f"{record}\n")
|
||||
|
||||
def remove_saved_server(self, record: str) -> None:
|
||||
ips = self.lookup(Preferences.IP_LIST)
|
||||
|
||||
@@ -15,6 +15,7 @@ from dzgui.api.steam import (
|
||||
enqueue_mod,
|
||||
get_remote_signatures,
|
||||
get_needs_update,
|
||||
load_to_menu,
|
||||
)
|
||||
|
||||
from dzgui.api.mods import (
|
||||
@@ -74,6 +75,7 @@ class Prerequisites:
|
||||
steam_proc: SteamProcess
|
||||
mods: list[list[str]]
|
||||
game_mode: bool
|
||||
is_last_server: bool
|
||||
|
||||
|
||||
class ConnectionManager:
|
||||
@@ -172,6 +174,8 @@ class ConnectionManager:
|
||||
|
||||
game_mode = prefs.is_game_mode
|
||||
|
||||
is_last = self.is_last_server()
|
||||
|
||||
prereqs = Prerequisites(
|
||||
name=info.server_name,
|
||||
appid=info.game_id,
|
||||
@@ -186,11 +190,23 @@ class ConnectionManager:
|
||||
steam_proc=steam_proc,
|
||||
mods=remote_mods,
|
||||
game_mode=game_mode,
|
||||
is_last_server=is_last,
|
||||
)
|
||||
|
||||
func = StoredFunc(self.controller.open_connection_assistant, prereqs)
|
||||
self.thread_man.set_cleanup_func(func, destroy_first=True)
|
||||
|
||||
def is_last_server(self) -> bool:
|
||||
prefs = self.controller.get_prefs()
|
||||
history = prefs.paths.history
|
||||
try:
|
||||
lines = history.read_text().splitlines()
|
||||
last = lines[-1]
|
||||
current = Servers.record_to_fqip(self.record)
|
||||
return last == current
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@call_on_thread(dialog.querying)
|
||||
def query_details(self, record: Servers.Record) -> None:
|
||||
details = Servers.get_details(record)
|
||||
@@ -245,11 +261,14 @@ class ConnectionManager:
|
||||
dialog = ExceptionDialog(self.controller, server_timeout)
|
||||
dialog.run()
|
||||
|
||||
def _connect_steam(self) -> None:
|
||||
def _connect_steam(self, menu_only: bool) -> None:
|
||||
addr = f"{self.record.ip}:{self.record.gameport}"
|
||||
playername = self.controller.query_config(Preferences.NAME)
|
||||
client = self.controller.query_config(Preferences.CLIENT)
|
||||
rc = connect(client, addr, self.appid, playername, self.remote_mod_ids)
|
||||
if menu_only:
|
||||
rc = load_to_menu(client, addr, self.appid, playername, self.remote_mod_ids)
|
||||
else:
|
||||
rc = connect(client, addr, self.appid, playername, self.remote_mod_ids)
|
||||
if rc != 0:
|
||||
# TODO: log/pop the error
|
||||
func = StoredFunc(self.controller.update_status)
|
||||
@@ -271,10 +290,10 @@ class ConnectionManager:
|
||||
self.thread_man.set_cleanup_func(func)
|
||||
|
||||
def _add_to_history_and_return(self) -> None:
|
||||
self.controller.add_to_history(self.history)
|
||||
self.controller.add_to_history(self.history, self.record)
|
||||
self.controller.open_page(NotebookPage.SERVERS)
|
||||
|
||||
def _update_mods(self, raise_window: bool) -> None:
|
||||
def _update_mods(self, raise_window: bool, menu_only: bool = False) -> None:
|
||||
# NOTE: fast enqueue all mods in auto mode
|
||||
prefs = self.controller.get_prefs()
|
||||
|
||||
@@ -312,11 +331,11 @@ class ConnectionManager:
|
||||
update_signatures(self.missing_mods, prefs.paths.version)
|
||||
# TODO: just push steam path directly
|
||||
rebuild_symlinks(prefs.paths.config)
|
||||
self._connect_steam()
|
||||
self._connect_steam(menu_only)
|
||||
|
||||
@call_on_thread(waiting_for_mods, show_cancel=True)
|
||||
def update_and_connect(self, raise_window: bool) -> None:
|
||||
def update_and_connect(self, raise_window: bool, menu_only: bool = False) -> None:
|
||||
if len(self.missing_mods) > 0:
|
||||
self._update_mods(raise_window)
|
||||
self._update_mods(raise_window, menu_only)
|
||||
else:
|
||||
self._connect_steam()
|
||||
self._connect_steam(menu_only)
|
||||
@@ -9,7 +9,7 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class FilterManager:
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, show_empty: bool = False, show_full: bool = False) -> None:
|
||||
|
||||
self.map_store = ModelFactory().make_map_store()
|
||||
|
||||
@@ -17,10 +17,10 @@ class FilterManager:
|
||||
self.default_filters = {
|
||||
strings.filter_1pp: True,
|
||||
strings.filter_day: True,
|
||||
strings.filter_empty: False,
|
||||
strings.filter_empty: show_empty,
|
||||
strings.filter_3pp: True,
|
||||
strings.filter_night: True,
|
||||
strings.filter_full: False,
|
||||
strings.filter_full: show_full,
|
||||
strings.filter_lowpop: True,
|
||||
strings.filter_nonascii: False,
|
||||
strings.filter_duplicate: False,
|
||||
|
||||
@@ -85,8 +85,9 @@ class ProxyModelManager:
|
||||
|
||||
if found is False:
|
||||
self.control_model.append(history)
|
||||
if len(self.control_model) == 11:
|
||||
del self.control_model[0]
|
||||
|
||||
# if len(self.control_model) == 11:
|
||||
# del self.control_model[0]
|
||||
|
||||
self.filter(FilterMode.INITIAL, skip_cache=True)
|
||||
|
||||
|
||||
+22
-9
@@ -14,6 +14,7 @@ from dzgui.const.constants import (
|
||||
)
|
||||
from dzgui.const.enum import FilterMode, Preferences, ServerTab
|
||||
from dzgui.managers.threading import call_on_thread, StoredFunc, ThreadingManager
|
||||
from dzgui.strings import dialogs
|
||||
from dzgui.util.strings import api_warn_msg, dialog
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog
|
||||
|
||||
@@ -23,7 +24,7 @@ gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa E402
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.api.servers import A2SInfo
|
||||
from dzgui.api.servers import A2SInfo, Record
|
||||
from dzgui.controllers.mc import Controller
|
||||
from dzgui.model.proxy_model import ProxyModelManager
|
||||
from dzgui.views.trees.tree_servers import ServerTreeView
|
||||
@@ -130,7 +131,7 @@ class ServerModelManager:
|
||||
|
||||
servers = []
|
||||
ports = range(1, 256)
|
||||
failure_func = StoredFunc(self._cleanup_on_failure)
|
||||
failure_func = StoredFunc(self._cleanup_on_lan_failure)
|
||||
|
||||
event = threading.Event()
|
||||
with ThreadPoolExecutor() as executor:
|
||||
@@ -225,15 +226,12 @@ class ServerModelManager:
|
||||
) = None,
|
||||
) -> None:
|
||||
proxy_man = self._get_proxy_man()
|
||||
config_man = self.controller.get_config_man()
|
||||
if rows is not None:
|
||||
records = rows
|
||||
else:
|
||||
control_model = proxy_man.get_control()
|
||||
records = control_model
|
||||
|
||||
config_man.update_history_file(records)
|
||||
config_man.update_history_file(records)
|
||||
self._sort_unique_maps(records)
|
||||
proxy = proxy_man.get_proxy_model()
|
||||
self.tv.set_model(proxy)
|
||||
@@ -249,15 +247,20 @@ class ServerModelManager:
|
||||
self.emitter.emit("load_maps", store)
|
||||
# self.emitter.emit("servers_loaded_init")
|
||||
|
||||
def add_to_history(self, record: dict[str, Any]) -> None:
|
||||
# TODO: dataclass for record rows; check for other dict annotations
|
||||
def add_to_history(self, data: tuple[dict[str, Any], "Record"]) -> None:
|
||||
row, record = data
|
||||
proxy_man = self._get_proxy_man()
|
||||
rows = Servers.parse_json([record])
|
||||
rows = Servers.parse_json([row])
|
||||
try:
|
||||
proxy_man.append_row_to_history(rows[0])
|
||||
self.update_history()
|
||||
except Exception:
|
||||
self.update_history(rows)
|
||||
return
|
||||
self.update_history()
|
||||
|
||||
fqip = Servers.record_to_fqip(record)
|
||||
config_man = self.controller.get_config_man()
|
||||
config_man.update_history_file(fqip)
|
||||
|
||||
def remove_from_history(self, record: Servers.Record) -> None:
|
||||
proxy_man = self._get_proxy_man()
|
||||
@@ -403,6 +406,16 @@ class ServerModelManager:
|
||||
if self.first_iteration:
|
||||
self._update_maps()
|
||||
|
||||
def _cleanup_on_lan_failure(self, show_dialog: bool = True) -> None:
|
||||
if self.preserve_on_fail is False:
|
||||
self.tv.set_model(None)
|
||||
filter_man = self.tv.get_filter_man()
|
||||
filter_man.set_unique_maps([])
|
||||
|
||||
if show_dialog:
|
||||
dialog = ExceptionDialog(self.controller, dialogs.load_error_lan)
|
||||
dialog.run()
|
||||
|
||||
def _cleanup_on_failure(self, show_dialog: bool = True) -> None:
|
||||
# TODO: disable map, keyword, and filter widgets if model is None
|
||||
# signal driven (servers_empty, servers_failed_to_load)
|
||||
|
||||
@@ -4,3 +4,5 @@ waiting_for_mods = "Waiting for Steam to update mods"
|
||||
fetching_update = "Fetching update"
|
||||
failed_to_update = "Failed to update DZGUI executable"
|
||||
update_success = "Updated successfully. Please exit and relaunch."
|
||||
|
||||
load_error_lan = "Failed to find any servers on your network.\nCheck the server query port or your firewall settings."
|
||||
@@ -1,5 +1,9 @@
|
||||
update_mods = "Update mods and connect"
|
||||
connect = "Connect"
|
||||
connect_last = "Load to menu screen"
|
||||
connect_last_tooltip = (
|
||||
"Launch DayZ with these mods (if any) and\ngo to the menu screen without connecting."
|
||||
)
|
||||
back = "Back"
|
||||
cancel = "Cancel"
|
||||
warnings = "Warnings"
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def is_writeable(path: "Path") -> bool:
|
||||
now = int(datetime.now().timestamp())
|
||||
suffix = ".dzgtmp"
|
||||
file = str(now) + suffix
|
||||
filepath = Path(str(path) + "_" + file)
|
||||
try:
|
||||
filepath.touch()
|
||||
filepath.unlink()
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
@@ -611,6 +611,7 @@ atomic_buttons = AtomicButton(
|
||||
keys_tooltip="Toggles the keybindings dialog",
|
||||
)
|
||||
|
||||
gtk_theme_missing = "No GTK theme provided"
|
||||
steam_icon_missing = "Steam icon not found in IconTheme"
|
||||
|
||||
missing_changelog = "Error: failed to read changelog"
|
||||
|
||||
+9
-5
@@ -323,8 +323,12 @@ class App(Gtk.Application):
|
||||
|
||||
MainController = Controller()
|
||||
|
||||
theme = Gtk.IconTheme.get_default()
|
||||
icons = theme.list_icons(None)
|
||||
if STEAM_ICON not in icons:
|
||||
logger.warn(strings.steam_icon_missing)
|
||||
warnings.warn(strings.steam_icon_missing, stacklevel=2)
|
||||
try:
|
||||
theme = Gtk.IconTheme.get_default()
|
||||
icons = theme.list_icons(None)
|
||||
if STEAM_ICON not in icons:
|
||||
logger.warn(strings.steam_icon_missing)
|
||||
warnings.warn(strings.steam_icon_missing, stacklevel=2)
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
warnings.warn(strings.gtk_theme_missing, stacklevel=2)
|
||||
@@ -1,6 +1,7 @@
|
||||
import logging
|
||||
import os
|
||||
|
||||
from pathlib import Path
|
||||
from typing import Literal, TYPE_CHECKING
|
||||
|
||||
from dzgui.const.constants import (
|
||||
@@ -13,6 +14,7 @@ from dzgui.const.constants import (
|
||||
from dzgui.const.enum import ServerTab
|
||||
from dzgui.managers.update import UpdateManager
|
||||
from dzgui.util.clip import copy_clipboard
|
||||
from dzgui.util.file import is_writeable
|
||||
from dzgui.views.components.buttonbox import ButtonBox
|
||||
from dzgui.views.components.filter_panel import FilterPanel
|
||||
from dzgui.views.components.mod_panel import ModSelectionPanel
|
||||
@@ -87,11 +89,12 @@ class RightPanel(Gtk.Box):
|
||||
)
|
||||
exe_path = os.getenv("PYAPP")
|
||||
if exe_path and update is not None:
|
||||
self.update_button.set_halign(Gtk.Align.END)
|
||||
self.gutter_box.add(self.update_button)
|
||||
self.update_button.connect(
|
||||
"clicked", self._on_update_button_clicked, exe_path, update
|
||||
)
|
||||
if is_writeable(Path(exe_path)) is True:
|
||||
self.update_button.set_halign(Gtk.Align.END)
|
||||
self.gutter_box.add(self.update_button)
|
||||
self.update_button.connect(
|
||||
"clicked", self._on_update_button_clicked, exe_path, update
|
||||
)
|
||||
self.gutter_box.add(eb)
|
||||
self.pack_start(self.gutter_box, NO_EXPAND, FILL, NO_PADDING)
|
||||
|
||||
@@ -108,7 +111,7 @@ class RightPanel(Gtk.Box):
|
||||
return
|
||||
self.filters_vbox.set_sensitive(False)
|
||||
# TODO: unless it is lan page
|
||||
#self.refresh_button.set_sensitive(False)
|
||||
# self.refresh_button.set_sensitive(False)
|
||||
|
||||
def _on_lan_page_init(self, emitter: "Emitter") -> None:
|
||||
self.filters_vbox.set_sensitive(False)
|
||||
|
||||
@@ -106,6 +106,9 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
||||
label=preconnect.back, halign=Gtk.Align.END, hexpand=True
|
||||
)
|
||||
self.ok = Gtk.Button(label=preconnect.update_mods, halign=Gtk.Align.END)
|
||||
self.connect_last = Gtk.Button(
|
||||
label=preconnect.connect_last, halign=Gtk.Align.END, tooltip_text=preconnect.connect_last_tooltip
|
||||
)
|
||||
|
||||
# TODO: abstract
|
||||
self.raise_window = Gtk.CheckButton(
|
||||
@@ -126,13 +129,14 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
||||
spacing=5,
|
||||
)
|
||||
box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=5)
|
||||
for button in self.back, self.ok:
|
||||
for button in self.back, self.ok, self.connect_last:
|
||||
box.add(button)
|
||||
for el in self.raise_window, box:
|
||||
self.button_box.add(el)
|
||||
|
||||
self.back.connect("clicked", self._on_back_clicked)
|
||||
self.ok.connect("clicked", self._on_ok_clicked)
|
||||
self.connect_last.connect("clicked", self._on_connect_last_clicked)
|
||||
|
||||
self.title = Gtk.Label(label="")
|
||||
add_class(self.title, "preconnect-heading")
|
||||
@@ -213,6 +217,9 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
||||
if event.keyval == Gdk.KEY_u:
|
||||
self.ok.emit("clicked")
|
||||
|
||||
def _on_connect_last_clicked(self, button: Gtk.Button) -> None:
|
||||
self.controller.update_and_load_to_menu(self.raise_window.get_active())
|
||||
|
||||
def _on_ok_clicked(self, button: Gtk.Button) -> None:
|
||||
self.controller.update_and_connect(self.raise_window.get_active())
|
||||
|
||||
@@ -308,6 +315,11 @@ class PreConnectionAssistant(Gtk.ScrolledWindow):
|
||||
prefix = preconnect.total_mods
|
||||
self.mod_count.set_text(f"{prefix}{str(total_mods)}.{suffix}")
|
||||
|
||||
if prereqs.is_last_server:
|
||||
self.connect_last.show()
|
||||
else:
|
||||
self.connect_last.hide()
|
||||
|
||||
self._process_warnings(prereqs)
|
||||
if self.tree.is_visible():
|
||||
self.tree.grab_focus()
|
||||
|
||||
@@ -47,7 +47,13 @@ class ServerNotebook(Gtk.ScrolledWindow):
|
||||
self.recent = ServerTreeView(
|
||||
controller, ServerTab.RECENT, ContextMenuGroup.RECENT
|
||||
)
|
||||
self.lan = ServerTreeView(controller, ServerTab.LAN, ContextMenuGroup.SCAN_LAN)
|
||||
self.lan = ServerTreeView(
|
||||
controller,
|
||||
ServerTab.LAN,
|
||||
ContextMenuGroup.SCAN_LAN,
|
||||
show_empty=True,
|
||||
show_full=True,
|
||||
)
|
||||
|
||||
tabs = [
|
||||
(self.browser, server_labels.browser),
|
||||
|
||||
@@ -38,7 +38,12 @@ QUEUE_CHECK_DELAY = 200
|
||||
|
||||
class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
def __init__(
|
||||
self, controller: "Controller", enum: ServerTab, menu: ContextMenuGroup
|
||||
self,
|
||||
controller: "Controller",
|
||||
enum: ServerTab,
|
||||
menu: ContextMenuGroup,
|
||||
show_empty: bool = False,
|
||||
show_full: bool = False,
|
||||
) -> None:
|
||||
super().__init__(controller, menu=menu)
|
||||
|
||||
@@ -48,7 +53,7 @@ class ServerTreeView(ContextMixin, TreeView): # type: ignore
|
||||
|
||||
self.loaded = False
|
||||
|
||||
self.filter_man = FilterManager()
|
||||
self.filter_man = FilterManager(show_empty, show_full)
|
||||
self.proxy_man = ProxyModelManager(self.filter_man)
|
||||
model = self.proxy_man.get_proxy_model()
|
||||
self.set_model(model)
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ description = "DayZ server browser and mod manager for Linux"
|
||||
authors = [
|
||||
{name = "aclist"}
|
||||
]
|
||||
version = "7.0.0b7"
|
||||
version = "7.0.0b8"
|
||||
license = "GPL-3.0-or-later"
|
||||
license-files = ["LICENSE"]
|
||||
readme = "README.md"
|
||||
|
||||
+5
-2
@@ -53,7 +53,8 @@ def untar(file: str, glob: str, renamed: str) -> None:
|
||||
|
||||
def install_deps() -> None:
|
||||
pip = build_dir.joinpath(f"{CPYTHON_BUILD}/bin/pip")
|
||||
subprocess.run([pip, "install", root])
|
||||
proc = subprocess.run([pip, "install", root])
|
||||
return proc.returncode
|
||||
|
||||
|
||||
def repackage() -> None:
|
||||
@@ -66,7 +67,9 @@ def repackage() -> None:
|
||||
def rebuild_cpython() -> None:
|
||||
if cpython_dir.is_dir() is False:
|
||||
get_cpython()
|
||||
install_deps()
|
||||
code = install_deps()
|
||||
if code != 0:
|
||||
return
|
||||
repackage()
|
||||
return get_packaged_version()
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
from dzgui.config.ipdb import get_ipdb
|
||||
from pathlib import Path
|
||||
import os
|
||||
import pytest
|
||||
import tempfile
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_stripping():
|
||||
d = tempfile.TemporaryDirectory()
|
||||
path = Path(d.name).joinpath("ips.csv")
|
||||
get_ipdb(path)
|
||||
with open(path, "rb") as f:
|
||||
first = f.readline().decode().rstrip()
|
||||
try:
|
||||
f.seek(-2, os.SEEK_END)
|
||||
while f.read(1) != b"\n":
|
||||
f.seek(-2, os.SEEK_CUR)
|
||||
except OSError:
|
||||
f.seek(0)
|
||||
last = f.read().decode().rstrip()
|
||||
|
||||
first_els = first.split(",")
|
||||
last_els = last.split(",")
|
||||
|
||||
assert first_els[0] == "0.0.0.0"
|
||||
assert last_els[0] == "224.0.0.0"
|
||||
Reference in new issue
Block a user