diff --git a/CHANGELOG.md b/CHANGELOG.md index d4d9713..db81c5d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,29 @@ # Changelog -## [4.0.4] 2023-11-23 -## Fixed -- Fetch correct checksums for query helper +## [4.1.0] 2023-12-03 + +This update adds support for DayZ servers running on a local area network. To connect or add to your server list, supply the server IP and query port in the format IP:PORT. + +Support for Steam Deck Game Mode has also been restored, with a new dialog format that allows for virtual keyboard input. This should allow you to enter text in form fields by activating the Steam button + X. In addition, you can unlock the mouse and keyboard input when launching DZGUI through Steam by using an internal binding provided by Steam Deck: long-press the three dots button on the right of the device for three seconds to toggle the input state. This allows you to use mouse and keyboard-style bindings on Game Mode and vice versa. + +### Added +- Virtual keyboard support for text entry fields on Steam Deck Game Mode +- Validate and connect to LAN server IPs + +## [4.0.4] 2023-12-23 +### Fixed +- Enforce version check for Python versions before 3.10 ## [4.0.3] 2023-11-22 -## Fixed +### Fixed - Query helper: backwards compatibility for pre-2021 versions of Python 3 ## [4.0.2] 2023-11-22 -## Fixed +### Fixed - Query helper not loading: fixed a remote link pointing to the wrong destination and added a checksum verification to ensure file is present ## [4.0.1] 2023-11-22 -## Fixed +### Fixed - Emergency hotfix to remove build artifacts leaking into main script: if you updated DZGUI from 3.3.18 to 4.0.0 between 2023-11-22 15:00:02 and 2023-11-22 15:03:37 GMT, there is a small chance it will be unable to launch correctly. If so, please follow the instructions on the manual to reinstall. ## [4.0.0] 2023-11-22 @@ -29,7 +39,7 @@ If you encounter any problems with this new release or with the migration of con Attention Fedora 38 users: problems with upstream GNOME packages causing crashes have been reported to GNOME development and a fix has been issued. You have the choice of compiling the zenity package from source or waiting until the latest version is merged into Fedora's package manager. -## Added +### Added - Change in game name: dynamically change your profile name via the Advanced Options menu - Connect by ID: supply a Battlemetrics ID to connect to a server; this can be used in lieu of the IP - Add by IP: supply a standard IP to add a server to your list; this can be used as a more direct way of saving servers @@ -37,7 +47,7 @@ from source or waiting until the latest version is merged into Fedora's package - Save connected server to favorites: prior to connecting, asks the user if they want to save this server for future use - Generate additional output when generating system logs -## Fixed +### Fixed - Rare cases where the keyword filter would not filter server results correctly - Handling of dialog exit signals: made it much more difficult to crash the application in rare cases when spamming input or returning from menus - Update menus in place: when toggling options in the Advanced Options menu, displays the current state/mode of the option for better readability into what option is currently enabled @@ -46,7 +56,7 @@ from source or waiting until the latest version is merged into Fedora's package - Fixed a rare case where dialogs would spawn twice during first-time setup - Properly remain inside of menus when looping where it would make sense to do so : e.g., Delete Servers list, Advanced Options -## Changed +### Changed - Query servers directly to reduce API hops: initial bootup and subsequent server queries should be considerably faster - Store complete IP:Port instead of server IDs - Make Battlemetrics API key optional: this is only used for the 'Connect by ID' and 'Add server by ID' methods and is not required. If you prefer, you can simply connect/add by IP. diff --git a/dzgui.sh b/dzgui.sh index 2f66201..7673eca 100755 --- a/dzgui.sh +++ b/dzgui.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash set -o pipefail -version=4.0.4 +version=4.1.0 aid=221100 game="dayz" @@ -132,6 +132,7 @@ items=( ) } warn(){ + logger WARN "$1" $steamsafe_zenity --info --title="DZGUI" --text="$1" --width=500 --icon-name="dialog-warning" 2>/dev/null } info(){ @@ -375,7 +376,11 @@ steam_deck_mods(){ } test_display_mode(){ pgrep -a gamescope | grep -q "generate-drm-mode" - [[ $? -eq 0 ]] && gamemode=1 + if [[ $? -eq 0 ]]; then + echo gm + else + echo dm + fi } foreground(){ if [[ $(command -v wmctrl) ]]; then @@ -389,11 +394,6 @@ manual_mod_install(){ local ip="$1" local gameport="$2" - [[ $is_steam_deck -eq 1 ]] && test_display_mode - if [[ $gamemode -eq 1 ]]; then - popup 1400 - return - fi local ex="/tmp/dzc.tmp" [[ -f $ex ]] && rm $ex watcher(){ @@ -605,6 +605,10 @@ connect(){ compare [[ $auto_install -eq 2 ]] && merge_modlists > >(pdialog) if [[ -n $diff ]]; then + if [[ $is_steam_deck -eq 1 ]] && [[ $(test_display_mode) == "gm" ]]; then + popup 1400 + return 1 + fi case $auto_install in 1|2) auto_mod_install "$ip" "$gameport" ;; *) manual_mod_install "$ip" "$gameport" ;; @@ -662,10 +666,9 @@ fetch_ip_metadata(){ curl -Ls "$url" } -#TODO: local servers -#local_ip(){ -#(^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.) -#} +validate_local_ip(){ + <<< "$1" grep -qP '(^127.\d+.\d+.\d+:\d+$)|(^10\.\d+.\d+.\d+:\d+$)|(^172\.1[6-9]\.\d+.\d+:\d+$)|(^172\.2[0-9]\.\d+.\d+:\d+$)|(^172\.3[0-1]\.\d+.\d+:\d+$)|(^192\.168\.\d+.\d+:\d+$)' +} test_steam_api(){ local url="https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100&limit=10&key=$steam_api" local code=$(curl -ILs "$url" | grep -E "^HTTP") @@ -731,35 +734,59 @@ connect_by_ip(){ connect "$ip" "$gameport" "$qport" } parse_ips(){ + local res source $config_file check_steam_api [[ $? -eq 1 ]] && return while true; do local ip - ip=$($steamsafe_zenity --entry --text="Enter server IP (omit port)" --title="DZGUI" 2>/dev/null) + ip=$(edialog "Enter server IP (for LAN servers, include query port in IP:PORT format)") [[ $? -eq 1 ]] && return 1 - [[ $ip =~ ':' ]] && continue - if validate_ip "$ip"; then - local res - res=$(fetch_ip_metadata "$ip") - if [[ ! $? -eq 0 ]] || [[ $(<<< $res jq '.response|length') -eq 0 ]]; then - warn "Failed to retrieve IP metadata. Check IP or API key and try again." + if [[ $ip =~ ':' ]]; then + if ! validate_local_ip "$ip"; then + warn "Invalid local IP. Check IP:PORT combination and try again." + continue + fi + local lan_ip=$(<<< $ip awk -F: '{print $1}') + local lan_qport=$(<<< $ip awk -F: '{print $2}') + logger INFO "Given LAN IP was $lan_ip" + logger INFO "Given LAN port was $lan_qport" + res=$(a2s $lan_ip $lan_qport info) + if [[ ! $? -eq 0 ]] || [[ $(<<< $res jq 'length') -eq 0 ]]; then + warn "Failed to retrieve server metadata. Check IP:PORT combination and try again." return 1 fi - local ct=$(<<< "$res" jq '.response.servers|length') - if [[ $ct -eq 1 ]]; then - local name=$(<<< $res jq -r '.response.servers[].name') - local address=$(<<< $res jq -r '.response.servers[].addr') - local ip=$(<<< "$address" awk -F: '{print $1}') - local qport=$(<<< "$address" awk -F: '{print $2}') - local gameport=$(<<< $res jq -r '.response.servers[].gameport') - echo "${name}%%${ip}:${gameport}%%${qport}" - return 0 - fi - ip_table "$res" + logger INFO "$res" + local name=$(<<< $res jq -r '.name') + local address=$(<<< $res jq -r '.address') + local ip=$(<<< $address awk -F: '{print $1}') + local gameport=$(<<< $address awk -F: '{print $2}') + local qport=$(<<< $res jq -r '.qport') + logger INFO "Found '${name}' at ${ip}:${gameport}:${qport}" + echo "${name}%%${ip}:${gameport}%%${qport}" return 0 else - warn "Invalid IP" + if validate_ip "$ip"; then + res=$(fetch_ip_metadata "$ip") + if [[ ! $? -eq 0 ]] || [[ $(<<< $res jq '.response|length') -eq 0 ]]; then + warn "Failed to retrieve server metadata. Check IP or API key and try again." + return 1 + fi + local ct=$(<<< "$res" jq '.response.servers|length') + if [[ $ct -eq 1 ]]; then + local name=$(<<< $res jq -r '.response.servers[].name') + local address=$(<<< $res jq -r '.response.servers[].addr') + local ip=$(<<< "$address" awk -F: '{print $1}') + local qport=$(<<< "$address" awk -F: '{print $2}') + local gameport=$(<<< $res jq -r '.response.servers[].gameport') + echo "${name}%%${ip}:${gameport}%%${qport}" + return 0 + fi + ip_table "$res" + return 0 + else + warn "Invalid IP" + fi fi done } @@ -953,8 +980,6 @@ list_mods(){ fi } connect_to_fav(){ - #TODO: test with broken/bogus fav - #TODO: test backing out of connection dialogs logger INFO "${FUNCNAME[0]}" local fav="$1" @@ -1126,7 +1151,7 @@ popup(){ 1100) pop "No results found." ;; 1200) pop "Timed out. Server may be temporarily offline or not responding to queries." ;; 1300) pop "No favorite server configured." ;; - 1400) pop "DZGUI must be run in Desktop Mode on Steam Deck, preferably via the desktop shortcut." ;; + 1400) pop "To install missing mods, run DZGUI via Desktop Mode on Steam Deck, preferably via the desktop shortcut." ;; esac } toggle_console_dl(){ @@ -1232,6 +1257,7 @@ a2s(){ local ip="$1" local qport="$2" local mode="$3" + logger A2S "Querying '$ip:$qport' with mode '$mode'" python3 $helpers_path/query.py "$ip" "$qport" "$mode" } format_config_address(){ @@ -1431,7 +1457,7 @@ choose_filters(){ if [[ $sels =~ Keyword ]]; then local search while true; do - search=$($steamsafe_zenity --entry --text="Search (case insensitive)" --width=500 --title="DZGUI" 2>/dev/null | awk '{print tolower($0)}') + search=$(edialog "Search (case insensitive)" | awk '{print tolower($0)}') [[ $? -eq 1 ]] && return 1 [[ -z $search ]] && warn "Cannot submit an empty keyword" [[ -n $search ]] && break @@ -1749,11 +1775,6 @@ check_architecture(){ if [[ -n "$cpu" ]]; then is_steam_deck=1 logger INFO "Setting architecture to 'Steam Deck'" - [[ $is_steam_deck -eq 1 ]] && test_display_mode - if [[ $gamemode -eq 1 ]]; then - popup 1400 && - exit 1 - fi else is_steam_deck=0 logger INFO "Setting architecture to 'desktop'" @@ -1839,7 +1860,11 @@ pdialog(){ $steamsafe_zenity --progress --pulsate --auto-close --title="DZGUI" --width=500 2>/dev/null } edialog(){ - $steamsafe_zenity --entry --text="$1" --width=500 --title="DZGUI" 2>/dev/null + if [[ $is_steam_deck -eq 1 ]] && [[ $(test_display_mode) == "gm" ]]; then + kdialog --inputbox "$1" --title "DZGUI" --geometry 500 2>/dev/null + else + $steamsafe_zenity --entry --text="$1" --width=500 --title="DZGUI" 2>/dev/null + fi } tdialog(){ $steamsafe_zenity --info --text="$1" --width=500 --title="DZGUI" 2>/dev/null diff --git a/news b/news index 1108072..386f0c1 100644 --- a/news +++ b/news @@ -1 +1 @@ -NEWS: Major 4.0.0 update. Full details via the View Changelog menu option. +NEWS: Added support for LAN servers and restored Steam Deck Game Mode support. See changelog.