mirror of
https://github.com/aclist/dztui.git
synced 2026-08-25 17:32:36 +02:00
Merge pull request #270 from aclist/prerelease/6.0.2
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
Some checks failed
Mirror to Codeberg / mirror-to-codeberg (push) Has been cancelled
fix: dialogs in thread
This commit is contained in:
commit
c14fb10d23
3
.gitignore
vendored
3
.gitignore
vendored
@ -1 +1,4 @@
|
||||
tags
|
||||
__pycache__
|
||||
pre-commit
|
||||
tests/
|
||||
|
||||
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,5 +1,16 @@
|
||||
# Changelog
|
||||
|
||||
## [6.0.2] 2026-01-26
|
||||
## 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
|
||||
- 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
|
||||
- Explicitly use Python 3.13 when calling subprocesses
|
||||
|
||||
178
dzgui.sh
178
dzgui.sh
@ -2,7 +2,7 @@
|
||||
set -o pipefail
|
||||
|
||||
src_path="$(readlink -e "$0")"
|
||||
version=6.0.1
|
||||
version=6.0.2
|
||||
|
||||
#CONSTANTS
|
||||
aid=221100
|
||||
@ -142,7 +142,7 @@ test_gobject(){
|
||||
python3.13 -c "import gi"
|
||||
if [[ ! $? -eq 0 ]]; then
|
||||
logger CRITICAL "Missing PyGObject"
|
||||
quit_with_pdialog "Requires PyGObject (python-gobject)"
|
||||
quit_with_help_dialog "Requires PyGObject (python-gobject)"
|
||||
exit 1
|
||||
fi
|
||||
logger INFO "Found PyGObject in Python env"
|
||||
@ -247,7 +247,7 @@ open_url(){
|
||||
xdg-open "$url"
|
||||
fi
|
||||
}
|
||||
quit_with_pdialog(){
|
||||
quit_with_help_dialog(){
|
||||
local sel
|
||||
msg="$1"
|
||||
help_button="Open help page"
|
||||
@ -260,7 +260,7 @@ quit_with_pdialog(){
|
||||
check_pyver(){
|
||||
if [[ ! $(python3.13 --version) ]]; then
|
||||
local msg="Requires Python 3.13"
|
||||
quit_with_pdialog "$msg"
|
||||
quit_with_help_dialog "$msg"
|
||||
fi
|
||||
}
|
||||
watcher_deps(){
|
||||
@ -335,6 +335,7 @@ check_unmerged(){
|
||||
fi
|
||||
}
|
||||
check_version(){
|
||||
echo "# Checking version"
|
||||
[[ -n $reference_branch ]] && return
|
||||
local version_url=$(format_version_url)
|
||||
local upstream=$(curl -Ls "$version_url" | awk -F= '/^version=/ {print $2}')
|
||||
@ -414,6 +415,7 @@ test_display_mode(){
|
||||
fi
|
||||
}
|
||||
check_architecture(){
|
||||
echo "# Checking system architecture"
|
||||
local cpu=$(< /proc/cpuinfo awk -F": " '/AMD Custom APU [0-9]{4}$/ {print $2; exit}')
|
||||
read -a APU_MODEL <<< "$cpu"
|
||||
if [[ ${APU_MODEL[3]} != "0932" ]] && [[ ${APU_MODEL[3]} != "0405" ]]; then
|
||||
@ -430,6 +432,7 @@ check_architecture(){
|
||||
logger INFO "Setting architecture to 'Steam Deck'"
|
||||
}
|
||||
check_map_count(){
|
||||
echo "# Checking map count"
|
||||
[[ $is_steam_deck -gt 0 ]] && return 0
|
||||
local map_count_file="/proc/sys/vm/max_map_count"
|
||||
local min_count=1048576
|
||||
@ -479,6 +482,7 @@ tdialog(){
|
||||
$steamsafe_zenity --info --text="$1" "${zenity_flags[@]}"
|
||||
}
|
||||
steam_deps(){
|
||||
echo "# Checking Steam"
|
||||
local flatpak
|
||||
local steam
|
||||
[[ $(command -v flatpak) ]] && flatpak=$(flatpak list | grep valvesoftware.Steam)
|
||||
@ -489,16 +493,8 @@ steam_deps(){
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
migrate_files(){
|
||||
if [[ ! -f $config_path/dztuirc.oldapi ]]; then
|
||||
cp $config_file $config_path/dztuirc.oldapi
|
||||
logger INFO "Migrated old API file"
|
||||
fi
|
||||
[[ ! -f $hist_file ]] && return
|
||||
rm $hist_file
|
||||
logger INFO "Wiped old history file"
|
||||
}
|
||||
stale_symlinks(){
|
||||
echo "# Cleaning stale symlinks"
|
||||
local game_dir="$steam_path/steamapps/common/DayZ"
|
||||
readarray -t links < <(find "$game_dir" -xtype l)
|
||||
for link in "${links[@]}"; do
|
||||
@ -512,7 +508,7 @@ check_availability() {
|
||||
return 1
|
||||
fi
|
||||
local url=$1
|
||||
local timeout_sec="3"
|
||||
local timeout_sec="2"
|
||||
if [[ $2 ]]; then
|
||||
timeout_sec=$2
|
||||
fi
|
||||
@ -523,6 +519,7 @@ check_availability() {
|
||||
}
|
||||
|
||||
local_latlon(){
|
||||
echo "# Checking coordinates"
|
||||
if [[ -z $(command -v dig) ]]; then
|
||||
local url_ipecho="https://ipecho.net/plain"
|
||||
if ! check_availability "ipecho.net"; then
|
||||
@ -534,6 +531,9 @@ local_latlon(){
|
||||
# TODO : implement checking remote
|
||||
local local_ip=$(dig -4 +short myip.opendns.com @resolver1.opendns.com)
|
||||
fi
|
||||
if calc_local_coords "$local_ip"; then
|
||||
return 0
|
||||
fi
|
||||
local url_ip_api="http://ip-api.com/json/$local_ip"
|
||||
if ! check_availability "ip-api.com"; then
|
||||
logger WARN "Failed to get local coordinates, ip-api.com service may be down."
|
||||
@ -548,6 +548,7 @@ local_latlon(){
|
||||
}
|
||||
|
||||
lock(){
|
||||
echo "# Setting up lock file"
|
||||
[[ ! -f $lock_file ]] && touch $lock_file
|
||||
local pid=$(cat $lock_file)
|
||||
ps -p $pid -o pid= >/dev/null 2>&1
|
||||
@ -625,12 +626,12 @@ fetch_helpers_by_sum(){
|
||||
[[ -f "$config_file" ]] && source "$config_file"
|
||||
declare -A sums
|
||||
sums=(
|
||||
["funcs"]="5e35a9812c03fc64d75843a23d024f0d"
|
||||
["funcs"]="5523d933e9f0668fc14b3faf0d4aafd8"
|
||||
["query_v2.py"]="55d339ba02512ac69de288eb3be41067"
|
||||
["servers.py"]="ed442c3aecf33f777d59dcf53650d263"
|
||||
["ui.py"]="3d67e5e8e85a23dde1fd0e85a9be62a9"
|
||||
["ui.py"]="d09b9d8bed3854efd51377289786c5ac"
|
||||
["vdf2json.py"]="2f49f6f5d3af919bebaab2e9c220f397"
|
||||
["pefile.py"]="21531f2c0d9dfa5f110cf6779f9d22c0"
|
||||
["pefile.py"]="b452974a84bff1d821872fcebf59e380"
|
||||
)
|
||||
local author="aclist"
|
||||
local repo="dztui"
|
||||
@ -690,12 +691,12 @@ fetch_km_helper(){
|
||||
}
|
||||
get_response_code(){
|
||||
local url="$1"
|
||||
curl -Ls -I -o /dev/null -w "%{http_code}" "$url"
|
||||
curl --connect-timeout 3 -Ls -I -o /dev/null -w "%{http_code}" "$url"
|
||||
}
|
||||
|
||||
fetch_ip_db(){
|
||||
parse_dl_url(){
|
||||
curl -Ls "$url" \
|
||||
curl --connect-timeout 3 -Ls "$url" \
|
||||
| grep "csv.gz" \
|
||||
| awk -F"['']" '{print $2}'
|
||||
}
|
||||
@ -711,6 +712,9 @@ fetch_ip_db(){
|
||||
fetch(){
|
||||
logger INFO "Triggering fetch routine"
|
||||
local url="$1"
|
||||
local ip_file="${state_path}/ips.csv"
|
||||
local base_file="${state_path}/${this_month}.csv.gz"
|
||||
local extracted_file="${state_path}/${this_month}.csv"
|
||||
|
||||
curl -Ls "$url" > "$base_file"
|
||||
if [[ $? -ne 0 ]]; then
|
||||
@ -730,7 +734,7 @@ fetch_ip_db(){
|
||||
logger WARN "Abnormal exit while parsing IPs"
|
||||
return
|
||||
fi
|
||||
rm "${state_path}/${month}.csv"
|
||||
rm "${state_path}/${this_month}.csv"
|
||||
|
||||
readarray -t records < <(cat $ip_file | awk -F, 'NR==1 {print $1} END {print $1}')
|
||||
if [[ ${records[0]} != "0.0.0.0" ]] && [[ ${records[1]} != "224.0.0.0" ]]; then
|
||||
@ -745,55 +749,57 @@ fetch_ip_db(){
|
||||
rm "$ip_file"
|
||||
fi
|
||||
|
||||
echo "$month" > "$month_file"
|
||||
logger INFO "Wrote '$month' to stub '$month_file'"
|
||||
echo "$this_month" > "$month_file"
|
||||
logger INFO "Wrote '$this_month' to stub '$month_file'"
|
||||
logger INFO "Updated '$ip_file'"
|
||||
}
|
||||
|
||||
check_remote(){
|
||||
local url="$1"
|
||||
local res=$(get_response_code "$url")
|
||||
if [[ $res -ne 200 ]]; then
|
||||
logger WARN "Failed to retrieve remote resource: '$url' ($res)"
|
||||
return
|
||||
fi
|
||||
logger INFO "Resolved remote URL: '$url'"
|
||||
|
||||
# test dl url
|
||||
local dl_url="$(parse_dl_url)"
|
||||
local res=$(get_response_code "$dl_url")
|
||||
if [[ $res -ne 200 ]]; then
|
||||
logger WARN "Remote resource unavailable: '$dl_url' ($res)"
|
||||
return
|
||||
fi
|
||||
logger INFO "Resolved download URL: '$dl_url'"
|
||||
fetch "$dl_url"
|
||||
}
|
||||
|
||||
local url="https://db-ip.com/db/download/ip-to-city-lite"
|
||||
local month_file="${state_path}/.month"
|
||||
local ip_file="${state_path}/ips.csv"
|
||||
|
||||
# test main url
|
||||
local res=$(get_response_code "$url")
|
||||
if [[ $res -ne 200 ]]; then
|
||||
logger WARN "Failed to retrieve remote resource: '$url' ($res)"
|
||||
return
|
||||
fi
|
||||
logger INFO "Resolved remote URL: '$url'"
|
||||
|
||||
# test dl url
|
||||
local dl_url="$(parse_dl_url)"
|
||||
local res=$(get_response_code "$dl_url")
|
||||
if [[ $res -ne 200 ]]; then
|
||||
logger WARN "Remote resource unavailable: '$dl_url' ($res)"
|
||||
return
|
||||
fi
|
||||
logger INFO "Resolved download URL: '$dl_url'"
|
||||
|
||||
local month=$(parse_dl_url_date "$dl_url")
|
||||
local base_file="${state_path}/${month}.csv.gz"
|
||||
local extracted_file="${state_path}/${month}.csv"
|
||||
month_file="${state_path}/.month"
|
||||
this_month=$(date +%Y-%m)
|
||||
|
||||
# no stub file
|
||||
if [[ ! -f $month_file ]]; then
|
||||
logger WARN "No stub file '$month_file' present"
|
||||
fetch "$dl_url"
|
||||
return
|
||||
fi
|
||||
|
||||
# local needs update
|
||||
local last_month=$(< "$month_file")
|
||||
if [[ $last_month != "$month" ]]; then
|
||||
logger WARN "Local stub '$last_month' does not match remote stub '$month'"
|
||||
fetch "$dl_url"
|
||||
check_remote "$url"
|
||||
return
|
||||
fi
|
||||
|
||||
# if stub is same date, abort
|
||||
logger INFO "Local stub '$last_month' is identical to remote, skipping"
|
||||
local last_month=$(< "$month_file")
|
||||
if [[ $last_month == "$this_month" ]]; then
|
||||
logger INFO "Local stub '$last_month' is identical to remote, skipping"
|
||||
return
|
||||
fi
|
||||
|
||||
# local needs update
|
||||
logger WARN "Local stub '$last_month' does not match '$this_month'"
|
||||
check_remote "$url"
|
||||
return
|
||||
|
||||
}
|
||||
fetch_helpers(){
|
||||
echo "# Checking helper files"
|
||||
fetch_a2s
|
||||
fetch_dzq
|
||||
fetch_km_helper
|
||||
@ -981,6 +987,7 @@ create_config(){
|
||||
done
|
||||
}
|
||||
varcheck(){
|
||||
echo "# Checking config file"
|
||||
local msg="Config file '$config_file' missing. Start first-time setup now?"
|
||||
local msg2="The Steam paths set in your config file appear to be invalid (DayZ was moved or uninstalled). Restart first-time setup now?"
|
||||
if [[ ! -f $config_file ]]; then
|
||||
@ -1007,12 +1014,14 @@ varcheck(){
|
||||
fi
|
||||
}
|
||||
is_dzg_downloading(){
|
||||
echo "# Checking DayZ"
|
||||
if [[ -d $steam_path ]] && [[ -d $steam_path/downloading/$aid ]]; then
|
||||
logger WARN "DayZ may be scheduling updates"
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
is_steam_running(){
|
||||
echo "# Checking Steam"
|
||||
local res=$(ps aux | grep "steamwebhelper" | grep -v grep)
|
||||
if [[ -z $res ]]; then
|
||||
logger WARN "Steam may not be running"
|
||||
@ -1025,6 +1034,7 @@ get_response_code(){
|
||||
curl -Ls -I -o /dev/null -w "%{http_code}" "$url"
|
||||
}
|
||||
test_connection(){
|
||||
echo "# Testing connection"
|
||||
declare -A hr
|
||||
local res1
|
||||
local res2
|
||||
@ -1058,6 +1068,7 @@ legacy_cols(){
|
||||
mv $cols_file.new $cols_file
|
||||
}
|
||||
stale_mod_signatures(){
|
||||
echo "# Checking stale mods"
|
||||
[[ ! -f "$versions_file" ]] && return
|
||||
local workshop_dir="$steam_path/steamapps/workshop/content/$aid"
|
||||
if [[ -d $workshop_dir ]]; then
|
||||
@ -1071,18 +1082,48 @@ stale_mod_signatures(){
|
||||
|
||||
}
|
||||
create_new_links(){
|
||||
echo "# Setting up symlinks"
|
||||
"$func_helper" "update_symlinks"
|
||||
}
|
||||
calc_local_coords(){
|
||||
local ip="$1"
|
||||
[[ ! -f "$geo_helper" ]] && return 1
|
||||
|
||||
IFS="." read -ra split <<< "$ip"
|
||||
[[ ${#split[@]} -ne 4 ]] && return 1
|
||||
|
||||
prefix="^${split[0]}.${split[1]}."
|
||||
readarray -t res < <(grep "$prefix" "$geo_helper")
|
||||
|
||||
for address in "${res[@]}"; do
|
||||
IFS="," read -ra fields <<< "$address"
|
||||
upper="${fields[1]}"
|
||||
IFS="." read -ra upper_digits <<< "$upper"
|
||||
if [[ ${split[2]} -gt ${upper_digits[2]} ]]; then
|
||||
continue
|
||||
fi
|
||||
if [[ ${split[2]} -eq ${upper_digits[2]} ]]; then
|
||||
if [[ ${split[3]} -gt ${upper_digits[3]} ]]; then
|
||||
continue
|
||||
fi
|
||||
if [[ ${split[3]} -eq ${upper_digits[3]} ]]; then
|
||||
echo "${fields[-2]}" >> "$coords_file"
|
||||
echo "${fields[-1]}" >> "$coords_file"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
if [[ ${split[2]} -lt ${upper_digits[2]} ]]; then
|
||||
echo "${fields[-2]}" >> "$coords_file"
|
||||
echo "${fields[-1]}" >> "$coords_file"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
initial_setup(){
|
||||
setup_dirs
|
||||
setup_state_files
|
||||
depcheck
|
||||
check_pyver
|
||||
test_gobject
|
||||
watcher_deps
|
||||
check_architecture
|
||||
test_connection
|
||||
fetch_helpers > >(pdialog "Checking helper files")
|
||||
fetch_helpers
|
||||
varcheck
|
||||
source "$config_file"
|
||||
lock
|
||||
@ -1091,14 +1132,12 @@ initial_setup(){
|
||||
check_version
|
||||
check_map_count
|
||||
steam_deps
|
||||
migrate_files
|
||||
stale_symlinks
|
||||
stale_mod_signatures
|
||||
create_new_links
|
||||
local_latlon
|
||||
is_steam_running
|
||||
is_dzg_downloading
|
||||
print_config_vals
|
||||
}
|
||||
uninstall(){
|
||||
_full(){
|
||||
@ -1200,8 +1239,15 @@ main(){
|
||||
|
||||
set_im_module
|
||||
|
||||
printf "Initializing setup...\n"
|
||||
initial_setup
|
||||
printf "Checking dependencies...\n"
|
||||
setup_dirs
|
||||
setup_state_files
|
||||
depcheck
|
||||
check_pyver
|
||||
test_gobject
|
||||
watcher_deps
|
||||
|
||||
initial_setup > >(pdialog "Initializing setup")
|
||||
|
||||
printf "All OK. Kicking off UI...\n"
|
||||
python3.13 "$ui_helper" "--init-ui" "$version" "$is_steam_deck"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
set -o pipefail
|
||||
version="6.0.1"
|
||||
version="6.0.2"
|
||||
|
||||
#CONSTANTS
|
||||
aid=221100
|
||||
|
||||
@ -295,7 +295,7 @@ def get_dayz_version(file: Path) -> DayZVersion | Exception:
|
||||
try:
|
||||
version = get_version(file)
|
||||
except Exception as e:
|
||||
return e
|
||||
raise e
|
||||
patch = str(version.build) + str(version.revision)
|
||||
dz_vers = DayZVersion(version.major, version.minor, int(patch))
|
||||
return dz_vers
|
||||
|
||||
173
helpers/ui.py
173
helpers/ui.py
@ -19,7 +19,7 @@ from collections.abc import Callable
|
||||
from concurrent.futures import wait
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
from pathlib import Path
|
||||
from typing import Literal, Self, Any
|
||||
from typing import Literal, Self, Any, TYPE_CHECKING
|
||||
|
||||
import servers as Servers # noqa E402
|
||||
import pefile as PeFile # noqa E402
|
||||
@ -32,10 +32,12 @@ from pefile import (
|
||||
)
|
||||
from pefile import VersionMatch
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from servers import Prereqs
|
||||
|
||||
locale.setlocale(locale.LC_ALL, "")
|
||||
|
||||
import gi # noqa E402
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
|
||||
|
||||
@ -1027,13 +1029,7 @@ def process_tree_option(choice: RowType) -> None:
|
||||
return
|
||||
|
||||
record = str_to_record(record)
|
||||
thread_new_with_dialog(
|
||||
App.treeview.prepare_connection,
|
||||
parse_shell_output,
|
||||
"Querying server",
|
||||
command,
|
||||
[record],
|
||||
)
|
||||
prepare_connection(command, record)
|
||||
return
|
||||
|
||||
match command.dict["type"]:
|
||||
@ -1061,48 +1057,54 @@ def parse_shell_output(proc: subprocess.CompletedProcess, row: RowType):
|
||||
process_shell_return_code(msg, proc.returncode, row)
|
||||
|
||||
|
||||
def thread_new_with_dialog(
|
||||
func: Callable,
|
||||
callback: Callable | None,
|
||||
msg: str,
|
||||
row: RowType | None,
|
||||
args: list,
|
||||
def prepare_connection(rowtype: RowType, record: Record) -> None:
|
||||
def background(rowtype: RowType, record: Record) -> None:
|
||||
def cleanup() -> None:
|
||||
App.treeview.wait_dialog.destroy()
|
||||
# NOTE: When using RowType.CONN_BY_IP, the gameport needs to be interpolated
|
||||
record.gameport = prereqs.gameport
|
||||
addr = record_to_str(record)
|
||||
|
||||
if proceed is False:
|
||||
spawn_dialog(msg, Popup.NOTIFY)
|
||||
return
|
||||
if msg != "":
|
||||
res = spawn_dialog(msg, Popup.CONFIRM)
|
||||
if res is False:
|
||||
try_connect(addr, str(prereqs.appid), str(pefile_path), rowtype)
|
||||
else:
|
||||
try_connect(addr, str(prereqs.appid), str(pefile_path), rowtype)
|
||||
|
||||
proceed, msg, pefile_path, prereqs = App.treeview.get_prereqs(record)
|
||||
GLib.idle_add(cleanup)
|
||||
|
||||
msg = "Checking prerequisites"
|
||||
App.treeview.dialog_show(msg)
|
||||
thread = threading.Thread(target=background, args=(rowtype, record))
|
||||
thread.start()
|
||||
|
||||
def try_connect(
|
||||
addr: str,
|
||||
appid: str,
|
||||
path: str,
|
||||
row: RowType
|
||||
) -> None:
|
||||
"""
|
||||
Pop a GenericDialog transient to App.treeview and
|
||||
call a function on a thread, with optional callback.
|
||||
Chiefly used for connection-related subprocesses.
|
||||
|
||||
After completion, the dialog is destroyed in the main event loop
|
||||
and additional exception handling occurs.
|
||||
|
||||
This is intended as a bridge between legacy shell methods and the UI.
|
||||
A more abstracted version of call_on_thread() for when extra threaded
|
||||
processing occurs before calls to shell subprocesses.
|
||||
"""
|
||||
|
||||
def background(*args):
|
||||
def background(addr, appid, path):
|
||||
def cleanup():
|
||||
App.treeview.dialog_hide()
|
||||
if exception is not None:
|
||||
spawn_dialog(str(exception), Popup.NOTIFY)
|
||||
process_user_input(row)
|
||||
return
|
||||
if callback is not None and proc is not None:
|
||||
callback(proc, row)
|
||||
parse_shell_output(proc, row)
|
||||
|
||||
exception = None
|
||||
proc = None
|
||||
try:
|
||||
proc = func(*args)
|
||||
proc = call_out("try_connect", addr, appid, path)
|
||||
except Exception as e:
|
||||
exception = e
|
||||
logger.critical(e)
|
||||
GLib.idle_add(cleanup)
|
||||
return
|
||||
GLib.idle_add(cleanup)
|
||||
|
||||
msg = "Querying server"
|
||||
App.treeview.dialog_show(msg)
|
||||
thread = threading.Thread(target=background, args=(args))
|
||||
thread = threading.Thread(target=background, args=(addr, appid, path))
|
||||
thread.start()
|
||||
|
||||
|
||||
@ -1142,27 +1144,31 @@ def record_to_str(record: Record) -> str:
|
||||
|
||||
|
||||
def connect_by_ip(enum: RowType, response: str) -> None:
|
||||
def _prep(response: str) -> None:
|
||||
try:
|
||||
record = Servers.validate_ip(response)
|
||||
proc = App.treeview.prepare_connection(record)
|
||||
return proc
|
||||
|
||||
thread_new_with_dialog(
|
||||
_prep, parse_shell_output, "Querying IP", enum, [response]
|
||||
)
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
spawn_dialog(str(e), Popup.NOTIFY)
|
||||
return
|
||||
prepare_connection(enum, record)
|
||||
|
||||
def connect_by_id(enum: RowType, response: str, key: str) -> None:
|
||||
def _prep(key: str, response: str) -> None:
|
||||
record = Servers.query_bm_api(key, response)
|
||||
proc = App.treeview.prepare_connection(record)
|
||||
return proc
|
||||
def cleanup() -> None:
|
||||
App.treeview.dialog_hide()
|
||||
prepare_connection(enum, record)
|
||||
|
||||
thread_new_with_dialog(
|
||||
_prep, parse_shell_output, "Querying API", enum, [key, response]
|
||||
)
|
||||
return
|
||||
try:
|
||||
record = Servers.query_bm_api(key, response)
|
||||
except Exception as e:
|
||||
spawn_dialog(str(e), Popup.NOTIFY)
|
||||
App.treeview.dialog_hide()
|
||||
return
|
||||
GLib.idle_add(cleanup)
|
||||
|
||||
msg = "Validating ID"
|
||||
App.treeview.dialog_show(msg)
|
||||
thread = threading.Thread(target=_prep, args=(key, response))
|
||||
thread.start()
|
||||
|
||||
|
||||
def process_user_input(enum: RowType) -> None:
|
||||
@ -2493,6 +2499,8 @@ class TreeView(Gtk.TreeView):
|
||||
def _dump_servers(self, ips: list) -> list | None:
|
||||
if len(ips) == 0:
|
||||
return []
|
||||
# NOTE: block malformed records
|
||||
ips = [ip for ip in ips if len(ip.split(":")) == 3 and ip.split(":")[2] != "" ]
|
||||
with ThreadPoolExecutor() as executor:
|
||||
futures = [
|
||||
executor.submit(
|
||||
@ -2943,9 +2951,9 @@ class TreeView(Gtk.TreeView):
|
||||
def get_view(self):
|
||||
return self.view
|
||||
|
||||
def prepare_connection(
|
||||
def get_prereqs(
|
||||
self, record: Record
|
||||
) -> subprocess.CompletedProcess | None:
|
||||
) -> tuple[bool, str, str|None, "Prereqs"]:
|
||||
"""
|
||||
Always called on a thread with a dialog on the transient parent window
|
||||
"""
|
||||
@ -2953,8 +2961,7 @@ class TreeView(Gtk.TreeView):
|
||||
if prereqs.appid is None:
|
||||
logger.warning(f"Query to '{record.ip}:{record.qport}' timed out")
|
||||
msg = "Timed out when querying server, check IP or try again later"
|
||||
spawn_dialog(msg, Popup.NOTIFY)
|
||||
return None
|
||||
return (False, msg, None, prereqs)
|
||||
|
||||
build = "DayZ" if prereqs.appid == APPID_DAYZ else "DayZ Experimental"
|
||||
steam_path = query_config("default_steam_path")[0]
|
||||
@ -2964,8 +2971,7 @@ class TreeView(Gtk.TreeView):
|
||||
"Config file has no value set for 'default_steam_path'"
|
||||
)
|
||||
msg = "Local Steam installation is not set, possibly malformed config file."
|
||||
spawn_dialog(msg, Popup.NOTIFY)
|
||||
return None
|
||||
return (False, msg, None, prereqs)
|
||||
|
||||
try:
|
||||
pefile_path = PeFile.get_pefile_path(steam_path, prereqs.appid)
|
||||
@ -2979,8 +2985,7 @@ class TreeView(Gtk.TreeView):
|
||||
f"If you recently installed {build} or moved it to a different drive, "
|
||||
"restart Steam to allow these changes to synchronize, then try again."
|
||||
)
|
||||
spawn_dialog(msg, Popup.NOTIFY)
|
||||
return None
|
||||
return (False, msg, None, prereqs)
|
||||
except AppMovedError:
|
||||
logger.critical(
|
||||
f"Library folder synch error for '{prereqs.appid}'"
|
||||
@ -2990,13 +2995,11 @@ class TreeView(Gtk.TreeView):
|
||||
f"If you recently installed {build} or moved it to a different drive, "
|
||||
"restart Steam to allow these changes to synchronize, then try again."
|
||||
)
|
||||
spawn_dialog(msg, Popup.NOTIFY)
|
||||
return None
|
||||
return (False, msg, None, prereqs)
|
||||
except (VDFLoadError, PeFileError, Exception) as e:
|
||||
logger.critical(e)
|
||||
msg = "Steam settings or DayZ installation may be corrupted. Try restarting Steam."
|
||||
spawn_dialog(msg, Popup.NOTIFY)
|
||||
return None
|
||||
return (False, msg, None, prereqs)
|
||||
|
||||
try:
|
||||
local_vers = PeFile.get_dayz_version(pefile_path)
|
||||
@ -3008,7 +3011,7 @@ class TreeView(Gtk.TreeView):
|
||||
local_vers = None
|
||||
|
||||
try:
|
||||
remote_vers = PeFile.dayz_version_from_str(prereqs.version)
|
||||
remote_vers = PeFile.dayz_version_from_str(prereqs)
|
||||
except Exception:
|
||||
remote_vers = None
|
||||
|
||||
@ -3021,18 +3024,15 @@ class TreeView(Gtk.TreeView):
|
||||
f"This server is running a newer build ({prereqs.version}) of {build} than "
|
||||
f"your local version. You may be unable to connect. Proceed anyway?"
|
||||
)
|
||||
res = spawn_dialog(msg, Popup.CONFIRM)
|
||||
if res is True:
|
||||
return None
|
||||
return (True, msg, pefile_path, prereqs)
|
||||
case VersionMatch.LOCAL_NEWER:
|
||||
msg = (
|
||||
f"This server is running an out-of-date build ({prereqs.version}) of {build}. "
|
||||
"You may be unable to connect. Proceed anyway?"
|
||||
)
|
||||
res = spawn_dialog(msg, Popup.CONFIRM)
|
||||
if res is True:
|
||||
return None
|
||||
return (True, msg, pefile_path, prereqs)
|
||||
case VersionMatch.SAME_VERSION:
|
||||
return (True, "", pefile_path, prereqs)
|
||||
pass
|
||||
|
||||
if prereqs.password is True:
|
||||
@ -3040,19 +3040,10 @@ class TreeView(Gtk.TreeView):
|
||||
"This server is password-protected and you will be "
|
||||
"prompted when connecting. Do you want to proceed?"
|
||||
)
|
||||
res = spawn_dialog(msg, Popup.CONFIRM)
|
||||
if res is True:
|
||||
return None
|
||||
return (True, msg, pefile_path, prereqs)
|
||||
|
||||
return (True, "", pefile_path, prereqs)
|
||||
|
||||
"""
|
||||
When using RowType.CONN_BY_IP, the gameport needs to be interpolated
|
||||
"""
|
||||
record.gameport = prereqs.gameport
|
||||
addr = record_to_str(record)
|
||||
proc = call_out(
|
||||
"try_connect", addr, str(prereqs.appid), str(pefile_path)
|
||||
)
|
||||
return proc
|
||||
|
||||
@signal_emission
|
||||
@update_window_labels
|
||||
@ -3122,13 +3113,7 @@ class TreeView(Gtk.TreeView):
|
||||
record = self.get_record()
|
||||
if record is None:
|
||||
return
|
||||
thread_new_with_dialog(
|
||||
self.prepare_connection,
|
||||
parse_shell_output,
|
||||
"Querying server",
|
||||
None,
|
||||
[record],
|
||||
)
|
||||
prepare_connection(None, record)
|
||||
case _: # any other non-server option from the main menu
|
||||
process_tree_option(output)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user