1
0
Fork 0
mirror of https://github.com/aclist/dztui.git synced 2024-12-29 13:52:03 +01:00
dztui/dzgui.sh

2135 lines
67 KiB
Bash
Raw Normal View History

2023-05-16 00:14:56 +02:00
#!/usr/bin/env bash
2022-05-09 13:42:24 +02:00
2022-06-04 22:29:30 +02:00
set -o pipefail
2023-12-17 03:23:45 +01:00
version=4.2.0.rc-1
2022-08-14 04:03:27 +02:00
2022-05-09 13:42:24 +02:00
aid=221100
game="dayz"
workshop="steam://url/CommunityFilePage/"
2022-05-09 13:42:24 +02:00
api="https://api.battlemetrics.com/servers"
2022-05-22 21:20:34 +02:00
sd_res="--width=1280 --height=800"
config_path="$HOME/.config/dztui/"
config_file="${config_path}dztuirc"
2023-11-15 11:53:11 +01:00
hist_file="${config_path}history"
2022-09-22 11:37:43 +02:00
tmp=/tmp/dzgui.tmp
2022-09-25 22:24:08 +02:00
fifo=/tmp/table.tmp
2023-07-25 03:10:07 +02:00
debug_log="$PWD/DZGUI_DEBUG.log"
2022-05-29 07:41:56 +02:00
separator="%%"
2022-06-15 12:32:10 +02:00
check_config_msg="Check config values and restart."
2022-09-14 06:56:13 +02:00
issues_url="https://github.com/aclist/dztui/issues"
url_prefix="https://raw.githubusercontent.com/aclist/dztui"
stable_url="$url_prefix/dzgui"
2022-10-08 05:58:02 +02:00
testing_url="$url_prefix/testing"
2022-09-14 06:56:13 +02:00
releases_url="https://github.com/aclist/dztui/releases/download/browser"
help_url="https://aclist.github.io/dzgui/dzgui"
2023-05-20 12:53:51 +02:00
sponsor_url="https://github.com/sponsors/aclist"
2022-08-05 20:35:17 +02:00
freedesktop_path="$HOME/.local/share/applications"
2022-08-06 00:42:35 +02:00
sd_install_path="$HOME/.local/share/dzgui"
2022-09-12 16:55:30 +02:00
helpers_path="$sd_install_path/helpers"
2022-09-14 06:56:13 +02:00
geo_file="$helpers_path/ips.csv"
km_helper="$helpers_path/latlon"
sums_path="$helpers_path/sums.md5"
2022-10-07 06:30:09 +02:00
scmd_file="$helpers_path/scmd.sh"
2022-09-14 06:56:13 +02:00
km_helper_url="$releases_url/latlon"
db_file="$releases_url/ips.csv.gz"
2023-12-03 09:22:52 +01:00
sums_url="$testing_url/helpers/sums.md5"
scmd_url="$testing_url/helpers/scmd.sh"
vdf2json_url="$testing_url/helpers/vdf2json.py"
2023-05-27 08:09:31 +02:00
forum_url="https://github.com/aclist/dztui/discussions"
2022-10-26 02:22:19 +02:00
version_file="$config_path/versions"
2022-12-02 08:25:08 +01:00
steamsafe_zenity="/usr/bin/zenity"
2022-05-09 13:42:24 +02:00
2022-07-24 15:20:06 +02:00
update_last_seen(){
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/seen_news=/ {print NR}' ${config_path}dztuirc.old)
seen_news="seen_news=\"$sum\""
awk -v "var=$seen_news" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > $config_file
source $config_file
}
check_news(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2023-05-16 00:14:56 +02:00
echo "# Checking news"
2022-10-11 09:24:37 +02:00
[[ $branch == "stable" ]] && news_url="$stable_url/news"
[[ $branch == "testing" ]] && news_url="$testing_url/news"
2023-11-15 11:53:11 +01:00
local result=$(curl -Ls "$news_url")
2022-07-24 15:20:06 +02:00
sum=$(echo -n "$result" | md5sum | awk '{print $1}')
2023-07-25 03:10:07 +02:00
logger INFO "News: $result"
2022-07-24 15:20:06 +02:00
}
print_news(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-11-24 21:53:35 +01:00
if [[ $sum == $seen_news || -z $result ]]; then
2022-07-24 15:20:06 +02:00
hchar=""
news=""
else
hchar="─"
news="$result\n$(awk -v var="$hchar" 'BEGIN{for(c=0;c<90;c++) printf var;}')\n"
update_last_seen
fi
}
2022-05-09 13:42:24 +02:00
declare -A deps
2023-11-15 11:53:11 +01:00
deps=([awk]="5.1.1" [curl]="7.80.0" [jq]="1.6" [tr]="9.0" [$steamsafe_zenity]="3.42.1" [fold]="9.0")
2022-06-12 06:44:30 +02:00
changelog(){
2023-11-15 11:53:11 +01:00
build(){
local mdbranch
case "$branch" in
"stable")
mdbranch="dzgui"
;;
*)
mdbranch="testing"
;;
esac
2023-11-18 06:40:21 +01:00
local md="https://raw.githubusercontent.com/aclist/dztui/${mdbranch}/CHANGELOG.md"
2023-11-15 11:53:11 +01:00
prefix="This window can be scrolled."
echo $prefix
echo ""
curl -Ls "$md"
}
build | $steamsafe_zenity --text-info $sd_res --title="DZGUI" 2>/dev/null
2022-06-12 06:44:30 +02:00
}
2022-05-09 13:42:24 +02:00
depcheck(){
for dep in "${!deps[@]}"; do
2023-01-19 12:20:30 +01:00
command -v "$dep" 2>&1>/dev/null || (printf "Requires %s >=%s\n" "$dep" ${deps[$dep]}; exit 1)
2022-05-09 13:42:24 +02:00
done
}
2022-10-09 04:07:07 +02:00
watcher_deps(){
2023-10-21 15:39:23 +02:00
logger INFO "${FUNCNAME[0]}"
2023-05-20 04:01:00 +02:00
if [[ ! $(command -v wmctrl) ]] && [[ ! $(command -v xdotool) ]]; then
2022-10-09 04:07:07 +02:00
echo "100"
2023-10-21 15:39:23 +02:00
warn "Missing dependency: requires 'wmctrl' or 'xdotool'.\nInstall from your system's package manager."
logger ERROR "Missing watcher dependencies"
2022-10-09 04:07:07 +02:00
exit 1
fi
}
2022-06-22 15:33:52 +02:00
init_items(){
#array order determines menu selector; this is destructive
2023-11-15 11:53:11 +01:00
#change favorite index affects setup() and add_by_fav()
2022-05-22 21:20:34 +02:00
items=(
2022-10-03 17:04:13 +02:00
"[Connect]"
2022-10-11 13:58:00 +02:00
" Server browser"
2022-10-03 17:04:13 +02:00
" My servers"
" Quick connect to favorite server"
2023-11-15 11:53:11 +01:00
" Connect by ID"
2022-10-03 17:04:13 +02:00
" Connect by IP"
2022-11-23 18:15:11 +01:00
" Recent servers (last 10)"
2022-11-21 20:54:23 +01:00
"[Manage servers]"
2022-10-03 17:04:13 +02:00
" Add server by ID"
2023-11-15 11:53:11 +01:00
" Add server by IP"
2022-10-03 17:04:13 +02:00
" Add favorite server"
" Delete server"
"[Options]"
" List installed mods"
" View changelog"
2022-10-07 06:30:09 +02:00
" Advanced options"
2022-10-11 14:43:52 +02:00
"[Help]"
" Help file ⧉"
" Report bug ⧉"
2022-11-24 21:53:35 +01:00
" Forum ⧉"
2023-10-21 15:39:23 +02:00
" Sponsor ⧉"
" Hall of fame ⧉"
2022-05-22 21:20:34 +02:00
)
2022-06-22 15:33:52 +02:00
}
2022-05-22 21:20:34 +02:00
warn(){
2023-12-03 09:22:52 +01:00
logger WARN "$1"
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --info --title="DZGUI" --text="$1" --width=500 --icon-name="dialog-warning" 2>/dev/null
2022-05-09 13:42:24 +02:00
}
2022-05-22 21:20:34 +02:00
info(){
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --info --title="DZGUI" --text="$1" --width=500 2>/dev/null
2022-05-22 21:20:34 +02:00
}
2022-08-11 00:59:29 +02:00
set_api_params(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-08-11 00:59:29 +02:00
response=$(curl -s "$api" -H "Authorization: Bearer "$api_key"" -G -d "sort=-players" \
-d "filter[game]=$game" -d "filter[ids][whitelist]=$list_of_ids")
2022-08-12 02:52:07 +02:00
list_response=$response
2022-08-14 18:22:21 +02:00
first_entry=1
2022-08-11 00:59:29 +02:00
}
2022-05-22 21:20:34 +02:00
write_config(){
2022-06-15 12:32:10 +02:00
cat <<-END
#Path to DayZ installation
steam_path="$steam_path"
2022-05-22 21:20:34 +02:00
#Your unique API key
2022-06-15 12:32:10 +02:00
api_key="$api_key"
2022-05-22 21:20:34 +02:00
2023-11-15 11:53:11 +01:00
#Favorited server IP:PORT array
ip_list=(
$(print_ip_list)
)
2022-05-22 21:20:34 +02:00
#Favorite server to fast-connect to (limit one)
2023-11-15 11:53:11 +01:00
fav_server="$fav_server"
#Favorite server label (human readable)
fav_label="$fav_label"
2022-05-22 21:20:34 +02:00
#Custom player name (optional, required by some servers)
2022-06-15 12:32:10 +02:00
name="$name"
2022-05-22 21:20:34 +02:00
#Set to 1 to perform dry-run and print launch options
2022-07-31 20:01:58 +02:00
debug="$debug"
2022-07-18 10:58:38 +02:00
#Toggle stable/testing branch
2022-07-31 19:52:59 +02:00
branch="$branch"
2022-07-24 15:20:06 +02:00
#Last seen news item
2022-07-31 20:01:58 +02:00
seen_news="$seen_news"
2022-08-16 17:49:51 +02:00
#Steam API key
2022-08-31 10:22:07 +02:00
steam_api="$steam_api"
2022-10-05 10:08:47 +02:00
2022-10-06 14:50:37 +02:00
#Auto-install mods
auto_install="$auto_install"
#Automod staging directory
2022-10-07 09:26:39 +02:00
staging_dir="$staging_dir"
2022-10-23 20:09:35 +02:00
#Path to default Steam client
default_steam_path="$default_steam_path"
#Preferred Steam launch command (for Flatpak support)
2023-01-19 17:55:41 +01:00
preferred_client="$preferred_client"
2022-05-22 21:20:34 +02:00
END
}
2022-08-04 21:14:56 +02:00
write_desktop_file(){
cat <<-END
[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
2022-08-06 00:42:35 +02:00
Exec=$sd_install_path/dzgui.sh
2022-08-04 21:14:56 +02:00
Name=DZGUI
Comment=dzgui
2022-08-06 00:42:35 +02:00
Icon=$sd_install_path/dzgui
2022-08-05 20:03:24 +02:00
Categories=Game
2022-08-04 21:14:56 +02:00
END
}
2022-08-05 21:58:59 +02:00
freedesktop_dirs(){
2022-08-06 00:42:35 +02:00
mkdir -p "$sd_install_path"
2022-08-05 21:58:59 +02:00
mkdir -p "$freedesktop_path"
2022-08-06 00:42:35 +02:00
curl -s "$version_url" > "$sd_install_path/dzgui.sh"
chmod +x "$sd_install_path/dzgui.sh"
2023-12-03 09:22:52 +01:00
img_url="$testing_url/images"
2022-08-05 21:58:59 +02:00
for i in dzgui grid.png hero.png logo.png; do
2022-08-06 00:42:35 +02:00
curl -s "$img_url/$i" > "$sd_install_path/$i"
2022-08-05 21:58:59 +02:00
done
write_desktop_file > "$freedesktop_path/dzgui.desktop"
2022-08-06 02:42:41 +02:00
if [[ $is_steam_deck -eq 1 ]]; then
write_desktop_file > "$HOME/Desktop/dzgui.desktop"
fi
2022-08-05 21:58:59 +02:00
}
2022-11-24 21:53:35 +01:00
find_library_folder(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
logger INFO "User picked directory: '$1'"
2023-05-16 00:14:56 +02:00
steam_path="$(python3 "$helpers_path/vdf2json.py" -i "$1/steamapps/libraryfolders.vdf" | jq -r '.libraryfolders[]|select(.apps|has("221100")).path')"
2023-07-25 03:10:07 +02:00
logger INFO "Steam path resolved to: $steam_path"
2022-11-24 21:53:35 +01:00
}
2022-08-14 11:10:00 +02:00
file_picker(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-12-02 08:25:08 +01:00
local path=$($steamsafe_zenity --file-selection --directory 2>/dev/null)
2023-07-25 03:10:07 +02:00
logger INFO "File picker path resolve to: $path"
2023-05-16 00:14:56 +02:00
if [[ -z "$path" ]]; then
2023-07-25 03:10:07 +02:00
logger INFO "Path was empty"
2023-05-16 00:14:56 +02:00
return
else
default_steam_path="$path"
find_library_folder "$default_steam_path"
fi
2022-08-14 11:10:00 +02:00
}
2022-05-22 21:20:34 +02:00
create_config(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-11-28 20:52:25 +01:00
check_pyver
2023-05-16 00:14:56 +02:00
write_to_config(){
mkdir -p $config_path
write_config > $config_file
info "Config file created at $config_file."
source $config_file
}
2022-08-04 21:14:56 +02:00
while true; do
2023-11-15 11:53:11 +01:00
player_input="$($steamsafe_zenity --forms --add-entry="Player name (required for some servers)" --add-entry="Steam API key" --add-entry="BattleMetrics API key (optional)" --title="DZGUI" --text="DZGUI" $sd_res --separator="@" 2>/dev/null)"
2022-12-02 08:25:08 +01:00
#explicitly setting IFS crashes $steamsafe_zenity in loop
2022-11-24 21:53:35 +01:00
#and mapfile does not support high ascii delimiters
#so split fields with newline
2023-05-16 00:14:56 +02:00
readarray -t args < <(echo "$player_input" | sed 's/@/\n/g')
2022-11-24 21:53:35 +01:00
name="${args[0]}"
2023-11-15 11:53:11 +01:00
steam_api="${args[1]}"
api_key="${args[2]}"
2022-08-04 21:14:56 +02:00
2022-11-24 21:53:35 +01:00
[[ -z $player_input ]] && exit
2023-11-15 11:53:11 +01:00
if [[ -z $steam_api ]]; then
warn "Steam API key cannot be empty"
continue
2022-11-24 21:53:35 +01:00
elif [[ $(test_steam_api) -eq 1 ]]; then
warn "Invalid Steam API key"
2023-11-15 11:53:11 +01:00
continue
fi
if [[ -n $api_key ]] && [[ $(test_bm_api $api_key) -eq 1 ]]; then
2023-01-02 02:22:58 +01:00
warn "Invalid BM API key"
2023-11-15 11:53:11 +01:00
continue
fi
while true; do
logger INFO "steamsafe_zenity is $steamsafe_zenity"
if [[ -n $steam_path ]]; then
write_to_config
return
fi
find_default_path
find_library_folder "$default_steam_path"
if [[ -z $steam_path ]]; then
logger WARN "Steam path was empty"
zenity --question --text="DayZ not found or not installed at the chosen path." --ok-label="Choose path manually" --cancel-label="Exit"
if [[ $? -eq 0 ]]; then
logger INFO "User selected file picker"
file_picker
else
exit
fi
else
write_to_config
return
fi
done
2022-08-04 21:14:56 +02:00
done
2022-05-22 21:20:34 +02:00
}
err(){
printf "[ERROR] %s\n" "$1"
}
varcheck(){
2023-11-15 11:53:11 +01:00
if [[ ! -d $steam_path ]] || [[ ! -d $game_dir ]]; then
2022-12-03 07:57:33 +01:00
echo 1
fi
2022-05-22 21:20:34 +02:00
}
2022-09-22 11:37:43 +02:00
run_depcheck(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-12-01 10:34:40 +01:00
if [[ -n $(depcheck) ]]; then
2022-10-08 13:09:33 +02:00
echo "100"
2023-07-25 03:10:07 +02:00
logger ERROR "Missing dependencies, quitting"
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --warning --ok-label="Exit" --title="DZGUI" --text="$(depcheck)"
2022-06-04 22:29:30 +02:00
exit
2022-05-22 21:20:34 +02:00
fi
2022-06-15 12:32:10 +02:00
}
2023-07-25 03:10:07 +02:00
logger(){
local date="$(date "+%F %T")"
local tag="$1"
local string="$2"
printf "[%s] [%s] %s\n" "$date" "$tag" "$string" >> "$debug_log"
2023-05-16 00:14:56 +02:00
}
2022-11-28 20:52:25 +01:00
check_pyver(){
2023-11-23 05:55:15 +01:00
local pyver=$(python3 --version | awk '{print $2}')
local minor=$(<<< $pyver awk -F. '{print $2}')
if [[ -z $pyver ]] || [[ ${pyver:0:1} -lt 3 ]] || [[ $minor -lt 10 ]]; then
warn "Requires python >=3.10" &&
2022-11-28 20:52:25 +01:00
exit
fi
}
2022-06-15 12:32:10 +02:00
run_varcheck(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-06-15 12:32:10 +02:00
source $config_file
workshop_dir="$steam_path/steamapps/workshop/content/$aid"
game_dir="$steam_path/steamapps/common/DayZ"
2022-12-03 07:57:33 +01:00
if [[ $(varcheck) -eq 1 ]]; then
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --question --cancel-label="Exit" --text="Malformed config file. This is probably user error.\nStart first-time setup process again?" --width=500 2>/dev/null
code=$?
if [[ $code -eq 1 ]]; then
2023-07-25 03:10:07 +02:00
logger ERROR "Malformed config vars"
exit
else
create_config
fi
2022-05-22 21:20:34 +02:00
fi
}
config(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-05-22 21:20:34 +02:00
if [[ ! -f $config_file ]]; then
2023-07-25 03:10:07 +02:00
logger WARN "Config file missing"
logger INFO "steamsafe_zenity is $steamsafe_zenity"
$steamsafe_zenity --width=500 --info --text="Config file not found. Click OK to proceed to first-time setup." 2>/dev/null
2022-05-22 21:20:34 +02:00
code=$?
2023-07-25 03:10:07 +02:00
logger INFO "Return code $code"
2022-12-01 10:34:40 +01:00
#TODO: prevent progress if user hits ESC
2022-05-22 21:20:34 +02:00
if [[ $code -eq 1 ]]; then
exit
else
create_config
fi
else
source $config_file
fi
}
2022-10-08 14:12:22 +02:00
steam_deck_mods(){
until [[ -z $diff ]]; do
next=$(echo -e "$diff" | head -n1)
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --question --ok-label="Open" --cancel-label="Cancel" --title="DZGUI" --text="Missing mods. Click [Open] to open mod $next in Steam Workshop and subscribe to it by clicking the green Subscribe button. After the mod is downloaded, return to this menu to continue validation." --width=500 2>/dev/null
2022-10-08 14:12:22 +02:00
rc=$?
if [[ $rc -eq 0 ]]; then
echo "[DZGUI] Opening ${workshop}$next"
2023-01-19 18:21:59 +01:00
$steam_cmd steam://url/CommunityFilePage/$next 2>/dev/null &
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --info --title="DZGUI" --ok-label="Next" --text="Click [Next] to continue mod check." --width=500 2>/dev/null
2022-10-08 14:12:22 +02:00
else
return 1
fi
compare
done
}
test_display_mode(){
pgrep -a gamescope | grep -q "generate-drm-mode"
2023-12-02 14:37:37 +01:00
if [[ $? -eq 0 ]]; then
echo gm
else
echo dm
fi
2022-10-08 14:12:22 +02:00
}
2022-10-09 04:07:07 +02:00
foreground(){
if [[ $(command -v wmctrl) ]]; then
2023-11-15 11:53:11 +01:00
wmctrl -a "DZG Watcher"
2022-10-09 04:07:07 +02:00
else
local window_id=$(xdotool search --name "DZG Watcher")
xdotool windowactivate $window_id
fi
}
2022-06-04 22:29:30 +02:00
manual_mod_install(){
2023-11-15 11:53:11 +01:00
local ip="$1"
local gameport="$2"
local ex="/tmp/dzc.tmp"
[[ -f $ex ]] && rm $ex
watcher(){
readarray -t stage_mods <<< "$diff"
for((i=0;i<${#stage_mods[@]};i++)); do
[[ -f $ex ]] && return 1
local downloads_dir="$steam_path/steamapps/workshop/downloads/$aid"
local workshop_dir="$steam_path/steamapps/workshop/content/$aid"
$steam_cmd "steam://url/CommunityFilePage/${stage_mods[$i]}"
echo "# Opening workshop page for ${stage_mods[$i]}. If you see no progress after subscribing, try unsubscribing and resubscribing again until the download commences."
sleep 1s
foreground
until [[ -d $downloads_dir/${stage_mods[$i]} ]]; do
[[ -f $ex ]] && return 1
sleep 0.1s
if [[ -d $workshop_dir/${stage_mods[$i]} ]]; then
break
fi
done
foreground
echo "# Steam is downloading ${stage_mods[$i]} (mod $((i+1)) of ${#stage_mods[@]})"
until [[ -d $workshop_dir/${stage_mods[$i]} ]]; do
[[ -f $ex ]] && return 1
sleep 0.1s
done
foreground
echo "# ${stage_mods[$i]} moved to mods dir"
done
echo "100"
}
watcher > >($steamsafe_zenity --pulsate --progress --auto-close --title="DZG Watcher" --width=500 2>/dev/null; rc=$?; [[ $rc -eq 1 ]] && touch $ex)
compare
if [[ -z $diff ]]; then
passed_mod_check > >($steamsafe_zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
launch "$ip" "$gameport"
else
return 1
fi
2022-06-04 22:29:30 +02:00
}
2022-07-24 15:20:06 +02:00
encode(){
2022-08-13 15:00:35 +02:00
echo "$1" | md5sum | cut -c -8
2022-07-24 15:20:06 +02:00
}
stale_symlinks(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-07-24 15:20:06 +02:00
for l in $(find "$game_dir" -xtype l); do
unlink $l
done
}
legacy_symlinks(){
for d in "$game_dir"/*; do
if [[ $d =~ @[0-9]+-.+ ]]; then
unlink "$d"
fi
done
2022-08-14 02:38:08 +02:00
for d in "$workshop_dir"/*; do
local id=$(awk -F"= " '/publishedid/ {print $2}' "$d"/meta.cpp | awk -F\; '{print $1}')
local encoded_id=$(echo "$id" | awk '{printf("%c",$1)}' | base64 | sed 's/\//_/g; s/=//g; s/+/]/g')
if [[ -h "$game_dir/@$encoded_id" ]]; then
unlink "$game_dir/@$encoded_id"
fi
done
2022-07-24 15:20:06 +02:00
}
2022-06-04 22:29:30 +02:00
symlinks(){
2023-07-25 03:10:07 +02:00
for d in "$workshop_dir"/*; do
id=$(awk -F"= " '/publishedid/ {print $2}' "$d"/meta.cpp | awk -F\; '{print $1}')
2022-07-24 15:20:06 +02:00
encoded_id=$(encode "$id")
2023-07-25 03:10:07 +02:00
mod=$(awk -F\" '/name/ {print $2}' "$d"/meta.cpp | sed -E 's/[^[:alpha:]0-9]+/_/g; s/^_|_$//g')
2022-07-24 15:20:06 +02:00
link="@$encoded_id"
2022-06-04 22:29:30 +02:00
if [[ -h "$game_dir/$link" ]]; then
2022-07-24 15:20:06 +02:00
:
else
2023-07-25 03:10:07 +02:00
printf "[DZGUI] Creating symlink for $mod\n"
ln -fs "$d" "$game_dir/$link"
2022-07-24 15:20:06 +02:00
fi
done
2022-06-04 22:29:30 +02:00
}
passed_mod_check(){
2023-07-25 03:10:07 +02:00
echo "[DZGUI] Passed mod check"
echo "# Preparing symlinks"
legacy_symlinks
2022-06-04 22:29:30 +02:00
symlinks
2022-09-26 21:04:06 +02:00
echo "100"
2023-07-25 03:10:07 +02:00
2022-05-22 21:20:34 +02:00
}
2022-10-23 20:09:35 +02:00
auto_mod_install(){
2023-11-15 11:53:11 +01:00
local ip="$1"
local gameport="$2"
2022-10-23 20:09:35 +02:00
popup 300
rc=$?
2023-11-15 11:53:11 +01:00
if [[ $rc -eq 1 ]]; then
manual_mod_install "$ip" "$gameport"
return
fi
log="$default_steam_path/logs/content_log.txt"
[[ -f "/tmp/dz.status" ]] && rm "/tmp/dz.status"
touch "/tmp/dz.status"
console_dl "$diff" &&
$steam_cmd steam://open/downloads && 2>/dev/null 1>&2
foreground
until [[ -z $(comm -23 <(printf "%s\n" "${modids[@]}" | sort) <(ls -1 $workshop_dir | sort)) ]]; do
local missing=$(comm -23 <(printf "%s\n" "${modids[@]}" | sort) <(ls -1 $workshop_dir | sort) | wc -l)
echo "# Downloaded $((${#modids[@]}-missing)) of ${#modids[@]} mods. ESC cancels"
done | $steamsafe_zenity --pulsate --progress --title="DZG Watcher" --auto-close --no-cancel --width=500 2>/dev/null
compare
[[ $force_update -eq 1 ]] && { unset force_update; return; }
if [[ -z $diff ]]; then
check_timestamps
passed_mod_check > >($steamsafe_zenity --pulsate --progress --title="DZGUI" --auto-close --width=500 2>/dev/null)
launch "$ip" "$gameport"
else
manual_mod_install "$ip" "$gameport"
fi
2022-10-23 20:09:35 +02:00
}
2022-10-26 02:22:19 +02:00
get_local_stamps(){
concat(){
for ((i=0;i<$max;i++)); do
echo "publishedfileids[$i]=${local_modlist[$i]}&"
done | awk '{print}' ORS=''
}
payload(){
echo -e "itemcount=${max}&$(concat)"
}
post(){
curl -s -X POST -H "Content-Type:application/x-www-form-urlencoded" \
-d "$(payload)" 'https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/?format=json'
}
post
}
update_stamps(){
for((i=0;i<${#local_modlist[@]};i++)); do
mod=${local_modlist[$i]}
stamp=${stamps[$i]}
printf "%s\t%s\n" "$mod" "$stamp" >> $version_file
done
}
check_timestamps(){
readarray -t local_modlist < <(ls -1 $workshop_dir)
max=${#local_modlist[@]}
2023-01-19 12:20:30 +01:00
[[ $max -eq 0 ]] && return
2022-10-26 02:22:19 +02:00
readarray -t stamps < <(get_local_stamps | jq -r '.response.publishedfiledetails[].time_updated')
if [[ ! -f $version_file ]]; then
update_stamps
return
else
needs_update=()
for((i=0;i<${#local_modlist[@]};i++)); do
mod=${local_modlist[$i]}
stamp=${stamps[$i]}
if [[ ! $(awk -v var=$mod '$1 == var' $version_file) ]]; then
echo -e "$mod\t$stamp" >> $version_file
elif [[ $(awk -v var=$mod -v var2=$stamp '$1 == var && $2 == var2' $version_file) ]]; then
:
else
awk -v var=$mod -v var2=$stamp '$1 == var {$2=var2;print $1"\t"$2; next;};{print}' $version_file > $version_file.new
mv $version_file.new $version_file
needs_update+=($mod)
fi
done
fi
}
merge_modlists(){
2023-11-15 11:53:11 +01:00
echo "# Aligning modlists"
2022-11-21 20:54:23 +01:00
[[ $force_update -eq 1 ]] && echo "# Checking mod versions"
2022-10-26 02:22:19 +02:00
check_timestamps
if [[ -z "$diff" ]] && [[ ${#needs_update[@]} -gt 0 ]]; then
diff=$(printf "%s\n" "${needs_update[@]}")
elif [[ -z "$diff" ]] && [[ ${#needs_update[@]} -eq 0 ]]; then
diff=
elif [[ -n "$diff" ]] && [[ ${#needs_update[@]} -eq 0 ]]; then
:
else
2023-01-19 12:20:30 +01:00
diff="$(printf "%s\n%s\n" "$diff" "${needs_update[@]}")"
2022-10-26 02:22:19 +02:00
fi
2022-11-21 20:54:23 +01:00
[[ $force_update -eq 1 ]] && echo "100"
}
update_history(){
2023-11-15 11:53:11 +01:00
local ip="$1"
local gameport="$2"
local qport="$3"
[[ -n $(grep "$ip:$gameport:$qport" $hist_file) ]] && return
2022-11-21 20:54:23 +01:00
if [[ -f $hist_file ]]; then
old=$(tail -n9 "$hist_file")
old="$old\n"
fi
2023-11-15 11:53:11 +01:00
echo -e "${old}${ip}:${gameport}:${qport}" > "$hist_file"
2022-11-23 17:50:34 +01:00
}
2022-06-04 22:29:30 +02:00
connect(){
2023-11-15 11:53:11 +01:00
local ip=$1
local gameport=$2
local qport=$3
logger INFO "Querying $ip:$gameport:$qport"
connect_dialog(){
echo "# Querying modlist"
local remote
remote=$(a2s "$ip" "$qport" rules)
if [[ $? -eq 1 ]]; then
echo "100"
popup 1200
return 1
fi
logger INFO "Server returned modlist: $(<<< $remote tr '\n' ' ')"
echo "# Checking for defunct mods"
query_defunct "$remote"
}
(connect_dialog "$ip" "$qport") | pdialog
2022-06-04 22:29:30 +02:00
rc=$?
[[ $rc -eq 1 ]] && return
2023-11-15 11:53:11 +01:00
readarray -t newlist < /tmp/dz.modlist
compare
[[ $auto_install -eq 2 ]] && merge_modlists > >(pdialog)
2022-06-04 22:29:30 +02:00
if [[ -n $diff ]]; then
2023-12-02 14:37:37 +01:00
if [[ $is_steam_deck -eq 1 ]] && [[ $(test_display_mode) == "gm" ]]; then
popup 1400
return 1
fi
2022-12-03 13:20:36 +01:00
case $auto_install in
2023-11-15 11:53:11 +01:00
1|2) auto_mod_install "$ip" "$gameport" ;;
*) manual_mod_install "$ip" "$gameport" ;;
2022-12-03 13:20:36 +01:00
esac
2022-06-04 22:29:30 +02:00
else
2023-11-15 11:53:11 +01:00
passed_mod_check > >(pdialog)
update_history "$ip" "$gameport" "$qport"
launch "$ip" "$gameport" "$qport"
2022-06-04 22:29:30 +02:00
fi
}
2023-11-15 11:53:11 +01:00
update_config(){
mv $config_file ${config_file}.old
write_config > $config_file
source $config_file
2022-08-16 17:49:51 +02:00
}
prepare_ip_list(){
2023-11-15 11:53:11 +01:00
local res="$1"
local ct=$(<<< "$res" jq '[.response.servers[]]|length' 2>/dev/null)
2023-01-02 02:22:58 +01:00
if [[ -n $ct ]]; then
for((i=0;i<$ct;i++));do
2023-11-15 11:53:11 +01:00
readarray -t json_arr < <(<<< $res jq --arg i $i -r '[.response.servers[]][($i|tonumber)]|"\(.name)\n\(.addr)\n\(.players)\n\(.max_players)\n\(.gameport)\n\(.gametype)"')
local name=${json_arr[0]}
local addr=${json_arr[1]}
local ip=$(<<< $addr awk -F: '{print $1}')
local qport=$(<<< $addr awk -F: '{print $2}')
local current=${json_arr[2]}
local max=${json_arr[3]}
local players="${current}/${max}"
local gameport="${json_arr[4]}"
local gametime="${json_arr[5]}"
gametime=$(<<< "$gametime" grep -o '[0-9][0-9]:[0-9][0-9]')
2023-01-02 02:22:58 +01:00
echo "$name"
2023-11-15 11:53:11 +01:00
echo "${ip}:${gameport}"
echo "$players"
echo "$gametime"
2023-01-02 02:22:58 +01:00
echo "$qport"
done
fi
2022-08-16 17:49:51 +02:00
}
ip_table(){
2023-11-15 11:53:11 +01:00
local sel
local res="$1"
2022-08-16 17:49:51 +02:00
while true; do
2023-11-15 11:53:11 +01:00
sel=$(prepare_ip_list "$res" | $steamsafe_zenity --width 1200 --height 800 --text="Multiple maps found at this server. Select map from the list below" --title="DZGUI" --list --column=Name --column=IP --column=Players --column=Gametime --column=Qport --print-column=1,2,5 --separator=%% 2>/dev/null)
[[ $? -eq 1 ]] && return 1
echo "$sel"
return 0
2022-08-16 17:49:51 +02:00
done
}
fetch_ip_metadata(){
2023-11-15 11:53:11 +01:00
local ip="$1"
2022-08-16 17:49:51 +02:00
source $config_file
2023-11-15 11:53:11 +01:00
local url="https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100\gameaddr\\$ip&key=$steam_api"
curl -Ls "$url"
2022-08-16 17:49:51 +02:00
}
2023-12-02 14:37:37 +01:00
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+$)'
}
2022-10-03 08:42:18 +02:00
test_steam_api(){
2023-11-02 16:06:59 +01:00
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")
2022-10-11 13:58:00 +02:00
[[ $code =~ 403 ]] && echo 1
[[ $code =~ 200 ]] && echo 0
2022-10-03 08:42:18 +02:00
}
2023-01-02 02:22:58 +01:00
test_bm_api(){
2023-11-15 11:53:11 +01:00
local api_key="$1"
[[ -z $api_key ]] && return 1
2023-01-02 02:22:58 +01:00
local code=$(curl -ILs "$api" -H "Authorization: Bearer "$api_key"" -G \
-d "filter[game]=$game" | grep -E "^HTTP")
[[ $code =~ 401 ]] && echo 1
[[ $code =~ 200 ]] && echo 0
}
2022-08-16 17:49:51 +02:00
add_steam_api(){
2022-10-11 13:58:00 +02:00
[[ $(test_steam_api) -eq 1 ]] && return 1
2022-08-16 17:49:51 +02:00
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/steam_api=/ {print NR}' ${config_path}dztuirc.old)
steam_api="steam_api=\"$steam_api\""
awk -v "var=$steam_api" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > ${config_path}dztuirc
echo "[DZGUI] Added Steam API key"
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --info --title="DZGUI" --text="Added Steam API key to:\n\n${config_path}dztuirc\nIf errors occur, you can restore the file:\n${config_path}dztuirc.old" --width=500 2>/dev/null
2022-08-16 17:49:51 +02:00
source $config_file
}
2022-09-13 06:41:26 +02:00
check_steam_api(){
2022-08-16 17:49:51 +02:00
if [[ -z $steam_api ]]; then
2022-12-02 08:25:08 +01:00
steam_api=$($steamsafe_zenity --entry --text="Key 'steam_api' not present in config file. Enter Steam API key:" --title="DZGUI" 2>/dev/null)
2022-08-31 10:22:07 +02:00
if [[ $? -eq 1 ]] ; then
return
2022-10-11 13:58:00 +02:00
elif [[ ${#steam_api} -lt 32 ]] || [[ $(test_steam_api) -eq 1 ]]; then
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --warning --title="DZGUI" --text="Check API key and try again." 2>/dev/null
2022-10-03 08:42:18 +02:00
return 1
2022-08-16 17:49:51 +02:00
else
add_steam_api
fi
fi
2022-09-13 06:41:26 +02:00
}
validate_ip(){
echo "$1" | grep -qP '^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$'
}
2023-11-15 11:53:11 +01:00
connect_by_id(){
local ip
ip=$(add_by_id "connect")
[[ $? -eq 1 ]] && return
readarray -t address < <(format_config_address "$ip")
local ip="${address[0]}"
local gameport="${address[1]}"
local qport="${address[2]}"
unset address
connect "$ip" "$gameport" "$qport"
}
2022-09-13 06:41:26 +02:00
connect_by_ip(){
2023-11-15 11:53:11 +01:00
local sel
sel=$(parse_ips)
[[ -z $sel ]] && return
readarray -t address < <(format_table_results "$sel")
local ip="${address[1]}"
local gameport="${address[2]}"
local qport="${address[3]}"
connect "$ip" "$gameport" "$qport"
}
parse_ips(){
2023-12-02 14:37:37 +01:00
local res
2022-09-13 06:41:26 +02:00
source $config_file
check_steam_api
2022-10-03 08:42:18 +02:00
[[ $? -eq 1 ]] && return
2023-11-15 11:53:11 +01:00
while true; do
local ip
2023-12-02 14:37:37 +01:00
ip=$(edialog "Enter server IP (for LAN servers, include query port in IP:PORT format)")
2023-11-15 11:53:11 +01:00
[[ $? -eq 1 ]] && return 1
2023-12-02 14:37:37 +01:00
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}')
2023-12-07 18:59:50 +01:00
logger INFO "Given LAN IP was $lan_ip"
logger INFO "Given LAN port was $lan_qport"
2023-12-02 14:37:37 +01:00
res=$(a2s $lan_ip $lan_qport info)
2023-12-08 13:53:59 +01:00
if [[ ! $? -eq 0 ]] || [[ $(<<< $res jq 'length') -eq 0 ]]; then
2023-12-02 14:37:37 +01:00
warn "Failed to retrieve server metadata. Check IP:PORT combination and try again."
2023-11-15 11:53:11 +01:00
return 1
fi
2023-12-07 18:59:50 +01:00
logger INFO "$res"
2023-12-08 14:04:21 +01:00
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}')
2023-12-09 08:41:42 +01:00
local qport=$(<<< $res jq -r '.qport')
logger INFO "Found '${name}' at ${ip}:${gameport}:${qport}"
echo "${name}%%${ip}:${gameport}%%${qport}"
2023-11-15 11:53:11 +01:00
return 0
else
2023-12-02 14:37:37 +01:00
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
2023-11-15 11:53:11 +01:00
fi
done
2022-05-09 13:42:24 +02:00
}
2022-06-12 06:44:30 +02:00
query_defunct(){
2023-11-15 11:53:11 +01:00
readarray -t modlist <<< "$@"
local max=${#modlist[@]}
2022-06-12 06:44:30 +02:00
concat(){
2023-11-15 11:53:11 +01:00
for ((i=0;i<$max;i++)); do
echo "publishedfileids[$i]=${modlist[$i]}&"
done | awk '{print}' ORS=''
2022-06-12 06:44:30 +02:00
}
payload(){
echo -e "itemcount=${max}&$(concat)"
}
post(){
2023-11-15 11:53:11 +01:00
curl -s \
-X POST \
-H "Content-Type:application/x-www-form-urlencoded"\
-d "$(payload)" 'https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/?format=json'
2022-06-12 06:44:30 +02:00
}
2023-11-15 11:53:11 +01:00
local result=$(post | jq -r '.[].publishedfiledetails[] | select(.result==1) | "\(.file_size) \(.publishedfileid)"')
<<< "$result" awk '{print $2}' > /tmp/dz.modlist
2022-06-04 22:29:30 +02:00
}
server_modlist(){
for i in "${newlist[@]}"; do
printf "$i\n"
done
}
compare(){
2022-11-25 06:34:16 +01:00
diff=$(comm -23 <(server_modlist | sort -u) <(installed_mods | sort))
2022-06-04 22:29:30 +02:00
}
installed_mods(){
ls -1 "$workshop_dir"
}
2022-05-09 13:42:24 +02:00
concat_mods(){
2023-11-15 11:53:11 +01:00
readarray -t serv <<< "$(server_modlist)"
for i in "${serv[@]}"; do
id=$(awk -F"= " '/publishedid/ {print $2}' "$workshop_dir"/$i/meta.cpp | awk -F\; '{print $1}')
encoded_id=$(encode $id)
link="@$encoded_id;"
echo -e "$link"
done | tr -d '\n' | perl -ple 'chop'
2022-05-09 13:42:24 +02:00
}
launch(){
2023-11-15 11:53:11 +01:00
local ip="$1"
local gameport="$2"
local qport="$3"
source $config_file
2022-05-09 13:42:24 +02:00
mods=$(concat_mods)
2023-11-22 10:33:50 +01:00
if [[ ! ${ip_list[@]} =~ "$ip:$gameport:$qport" ]]; then
2023-11-18 06:37:15 +01:00
qdialog "Before connecting, add this server to My Servers?"
2023-11-15 11:53:11 +01:00
if [[ $? -eq 0 ]]; then
ip_list+=("$ip:$gameport:$qport")
update_config
fi
fi
2022-05-09 13:42:24 +02:00
if [[ $debug -eq 1 ]]; then
2023-11-15 11:53:11 +01:00
launch_options="$steam_cmd -applaunch $aid -connect=$ip:$gameport -nolauncher -nosplash -name=$name -skipintro \"-mod=$mods\""
2022-09-26 21:04:06 +02:00
print_launch_options="$(printf "This is a dry run.\nThese options would have been used to launch the game:\n\n$launch_options\n" | fold -w 60)"
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --question --title="DZGUI" --ok-label="Write to file" --cancel-label="Back"\
2022-07-24 15:20:06 +02:00
--text="$print_launch_options" 2>/dev/null
if [[ $? -eq 0 ]]; then
source_script=$(realpath "$0")
source_dir=$(dirname "$source_script")
echo "$launch_options" > "$source_dir"/options.log
2022-08-15 12:39:05 +02:00
echo "[DZGUI] Wrote launch options to $source_dir/options.log"
2023-07-25 03:10:07 +02:00
$steamsafe_zenity --info --width=500 --title="DZGUI" --text="Wrote launch options to \n$source_dir/options.log" 2>/dev/null
2022-07-24 15:20:06 +02:00
fi
2022-05-09 13:42:24 +02:00
else
2023-07-25 03:10:07 +02:00
$steamsafe_zenity --width=500 --title="DZGUI" --info --text="Launch conditions satisfied.\nDayZ will now launch after clicking [OK]." 2>/dev/null
2023-11-15 11:53:11 +01:00
$steam_cmd -applaunch $aid -connect=$ip:$gameport -nolauncher -nosplash -skipintro -name=$name \"-mod=$mods\"
2022-05-09 13:42:24 +02:00
fi
2022-06-15 12:32:10 +02:00
}
browser(){
if [[ $is_steam_deck -eq 1 ]]; then
2023-05-19 16:29:21 +02:00
steam steam://openurl/"$1" 2>/dev/null
2022-06-15 12:32:10 +02:00
elif [[ $is_steam_deck -eq 0 ]]; then
2023-05-19 16:29:21 +02:00
if [[ -n "$BROWSER" ]]; then
"$BROWSER" "$1" 2>/dev/null
else
xdg-open "$1" 2>/dev/null
fi
2022-06-15 12:32:10 +02:00
fi
}
2023-05-19 16:29:21 +02:00
report_bug(){
browser "$issues_url"
}
2022-10-11 09:07:34 +02:00
forum(){
2023-05-19 16:29:21 +02:00
browser "$forum_url"
2022-10-11 09:07:34 +02:00
}
2022-06-15 12:32:10 +02:00
help_file(){
2023-05-19 16:29:21 +02:00
browser "$help_url"
}
sponsor(){
browser "$sponsor_url"
}
hof(){
browser "${help_url}#_hall_of_fame"
2022-05-22 21:20:34 +02:00
}
set_mode(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-05-22 21:20:34 +02:00
if [[ $debug -eq 1 ]]; then
2022-06-04 22:29:30 +02:00
mode=debug
2022-05-22 21:20:34 +02:00
else
mode=normal
fi
2023-07-25 03:10:07 +02:00
logger INFO "Mode is $mode"
2022-05-22 21:20:34 +02:00
}
2023-11-15 11:53:11 +01:00
delete_by_ip(){
local to_delete="$1"
for (( i=0; i<${#ip_list[@]}; ++i )); do
if [[ ${ip_list[$i]} == "$to_delete" ]]; then
unset ip_list[$i]
fi
done
2023-11-22 10:33:50 +01:00
if [[ ${#ip_list} -gt 0 ]]; then
readarray -t ip_list < <(printf "%s\n" "${ip_list[@]}")
fi
2023-11-15 11:53:11 +01:00
update_config
info "Removed $to_delete from:\n${config_path}dztuirc\nIf errors occur, you can restore the file:\n${config_path}dztuirc.old"
}
format_table_results(){
local sel="$1"
local name=$(<<< "$sel" awk -F"%%" '{print $1}')
local address=$(<<< "$sel" awk -F"%%" '{print $2}')
local ip=$(<<< "$address" awk -F":" '{print $1}')
local gameport=$(<<< "$address" awk -F":" '{print $2}')
local qport=$(<<< "$sel" awk -F"%%" '{print $3}')
printf "%s\n%s\n%s\n%s\n" "$name" "$ip" "$gameport" "$qport"
2022-07-24 15:20:06 +02:00
}
delete_or_connect(){
2023-11-15 11:53:11 +01:00
local sel="$1"
local mode="$2"
readarray -t address < <(format_table_results "$sel")
local server_name="${address[0]}"
local ip="${address[1]}"
local gameport="${address[2]}"
local qport="${address[3]}"
unset address
case "$mode" in
"delete")
qdialog "Delete this server?\n$server_name"
[[ $? -eq 1 ]] && return
delete_by_ip "$ip:$gameport:$qport"
source $config_file
local str="^$ip:$gameport$"
local nr=$(awk -v v="$str" '$1 ~ v {print NR}' $tmp)
local st=$((nr-1))
2023-11-22 10:33:50 +01:00
local en=$((st+5))
2023-11-15 11:53:11 +01:00
sed -i "${st},${en}d" $tmp
2023-11-22 10:33:50 +01:00
# if [[ ${#ip_list[@]} -eq 0 ]]; then
# return 1
# fi
2023-11-15 11:53:11 +01:00
;;
"connect"|"history")
connect "$ip" "$gameport" "$qport"
return
esac
2022-07-24 15:20:06 +02:00
}
2022-06-04 22:29:30 +02:00
populate(){
2023-11-15 11:53:11 +01:00
local switch="$1"
2022-05-22 21:20:34 +02:00
while true; do
2023-11-15 11:53:11 +01:00
cols="--column="Server" --column="IP" --column="Players" --column="Gametime" --column="Distance" --column="Qport""
set_header "$switch"
2022-06-04 22:29:30 +02:00
rc=$?
if [[ $rc -eq 0 ]]; then
2022-07-18 10:58:38 +02:00
if [[ -z $sel ]]; then
2022-06-04 22:29:30 +02:00
warn "No item was selected."
else
2023-11-15 11:53:11 +01:00
delete_or_connect "$sel" "$switch"
2022-06-04 22:29:30 +02:00
fi
else
2023-11-15 11:53:11 +01:00
return 1
2022-06-04 22:29:30 +02:00
fi
done
}
list_mods(){
2022-09-29 19:54:39 +02:00
if [[ -z $(installed_mods) ]] || [[ -z $(find $workshop_dir -maxdepth 2 -name "*.cpp" | grep .cpp) ]]; then
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --info --text="94: No mods currently installed or incorrect path given" $sd_res 2>/dev/null
2022-06-15 12:32:10 +02:00
else
2022-07-24 15:20:06 +02:00
for d in $(find $game_dir/* -maxdepth 1 -type l); do
dir=$(basename $d)
2023-05-10 20:08:18 +02:00
awk -v d=$dir -F\" '/name/ {printf "%s\t%s\t", $2,d}' "$gamedir"/$d/meta.cpp
printf "%s\n" "$(basename $(readlink -f $game_dir/$dir))"
done | sort -k1
2022-06-15 12:32:10 +02:00
fi
2022-06-04 22:29:30 +02:00
}
connect_to_fav(){
2023-11-15 11:53:11 +01:00
logger INFO "${FUNCNAME[0]}"
local fav="$1"
[[ -z $fav ]] && { popup 1300; return; }
2022-06-04 22:29:30 +02:00
2023-11-15 11:53:11 +01:00
readarray -t address < <(format_config_address "$fav")
local ip="${address[0]}"
local gameport="${address[1]}"
local qport="${address[2]}"
unset address
connect "$ip" "$gameport" "$qport"
[[ $? -eq 1 ]] && return 1
2022-06-04 22:29:30 +02:00
}
2022-07-18 10:58:38 +02:00
set_header(){
2023-11-15 11:53:11 +01:00
local switch="$1"
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
logger INFO "Header mode is $1"
2023-05-19 16:29:21 +02:00
print_news
2022-10-23 20:09:35 +02:00
[[ $auto_install -eq 2 ]] && install_mode="auto"
[[ $auto_install -eq 1 ]] && install_mode="headless"
2022-10-07 06:30:09 +02:00
[[ $auto_install -eq 0 ]] && install_mode=manual
2023-11-15 11:53:11 +01:00
case "$switch" in
"delete")
2023-11-22 10:33:50 +01:00
[[ -z $(< $tmp) ]] && return 1
2023-11-15 11:53:11 +01:00
sel=$(< $tmp $steamsafe_zenity $sd_res --list $cols --title="DZGUI" \
--text="DZGUI $version | Mode: $mode | Branch: $branch | Mods: $install_mode | Fav: $fav_label" \
--separator="$separator" --print-column=1,2,6 --ok-label="Delete" 2>/dev/null)
;;
"connect"|"history")
sel=$(< $tmp $steamsafe_zenity $sd_res --list $cols --title="DZGUI" \
--text="DZGUI $version | Mode: $mode | Branch: $branch | Mods: $install_mode | Fav: $fav_label" \
--separator="$separator" --print-column=1,2,6 --ok-label="Connect" 2>/dev/null)
;;
"main_menu")
sel=$($steamsafe_zenity $sd_res --list --title="DZGUI" \
--text="${news}DZGUI $version | Mode: $mode | Branch: $branch | Mods: $install_mode | Fav: $fav_label" \
--cancel-label="Exit" --ok-label="Select" --column="Select launch option" --hide-header "${items[@]}" 2>/dev/null)
;;
esac
2022-07-18 10:58:38 +02:00
}
toggle_branch(){
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/branch=/ {print NR}' ${config_path}dztuirc.old)
if [[ $branch == "stable" ]]; then
branch="testing"
else
branch="stable"
fi
flip_branch="branch=\"$branch\""
awk -v "var=$flip_branch" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > $config_file
source $config_file
}
2023-07-25 03:10:07 +02:00
generate_log(){
cat <<-DOC
2023-11-15 11:53:11 +01:00
Distro: $(< /etc/os-release grep -w NAME | awk -F\" '{print $2}')
Kernel: $(uname -mrs)
2023-07-25 03:10:07 +02:00
Version: $version
Branch: $branch
2023-11-15 11:53:11 +01:00
Mode: $mode
Auto: $auto_hr
2023-11-23 05:33:34 +01:00
Servers:
$(print_ip_list)
2023-07-25 03:10:07 +02:00
Steam path: $steam_path
Workshop path: $workshop_dir
Game path: $game_dir
Mods:
$(list_mods)
DOC
2023-05-11 05:10:27 +02:00
}
focus_beta_client(){
steam steam://open/library 2>/dev/null 1>&2 &&
2023-07-25 03:10:07 +02:00
steam steam://open/console 2>/dev/null 1>&2 &&
sleep 1s
2023-05-11 05:10:27 +02:00
wid(){
2023-10-21 15:39:23 +02:00
wmctrl -ilx |\
awk 'tolower($3) == "steamwebhelper.steam"' |\
awk '$5 ~ /^Steam|Steam Games List/' |\
2023-10-21 15:39:23 +02:00
awk '{print $1}'
2023-05-11 05:10:27 +02:00
}
until [[ -n $(wid) ]]; do
:
done
wmctrl -ia $(wid)
sleep 0.1s
wid=$(xdotool getactivewindow)
local geo=$(xdotool getwindowgeometry $wid)
local pos=$(<<< "$geo" awk 'NR==2 {print $2}' | sed 's/,/ /')
local dim=$(<<< "$geo" awk 'NR==3 {print $2}' | sed 's/x/ /')
local pos1=$(<<< "$pos" awk '{print $1}')
local pos2=$(<<< "$pos" awk '{print $2}')
local dim1=$(<<< "$dim" awk '{print $1}')
local dim2=$(<<< "$dim" awk '{print $2}')
local dim1=$(((dim1/2)+pos1))
local dim2=$(((dim2/2)+pos2))
xdotool mousemove $dim1 $dim2
xdotool click 1
sleep 0.5s
xdotool key Tab
}
2022-10-23 20:09:35 +02:00
console_dl(){
readarray -t modids <<< "$@"
2023-07-25 03:10:07 +02:00
focus_beta_client
2023-05-11 05:08:15 +02:00
sleep 1.5s
2022-10-23 20:09:35 +02:00
for i in "${modids[@]}"; do
2023-07-25 03:10:07 +02:00
xdotool type --delay 0 "workshop_download_item $aid $i"
sleep 0.5s
xdotool key Return
sleep 0.5s
2022-10-23 20:09:35 +02:00
done
}
find_default_path(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-11-24 21:53:35 +01:00
discover(){
echo "# Searching for Steam"
2023-05-16 13:05:36 +02:00
default_steam_path=$(find / -type d \( -path "/proc" -o -path "*/timeshift" -o -path \
2022-12-03 05:05:12 +01:00
"/tmp" -o -path "/usr" -o -path "/boot" -o -path "/proc" -o -path "/root" \
2022-11-24 21:53:35 +01:00
-o -path "/sys" -o -path "/etc" -o -path "/var" -o -path "/lost+found" \) -prune \
-o -regex ".*/Steam/ubuntu12_32$" -print -quit 2>/dev/null | sed 's@/ubuntu12_32@@')
}
2022-10-26 02:22:19 +02:00
if [[ $is_steam_deck -eq 1 ]]; then
default_steam_path="$HOME/.local/share/Steam"
else
2023-05-16 13:05:36 +02:00
local def_path
local ub_path
local flat_path
def_path="$HOME/.local/share/Steam"
ub_path="$HOME/.steam/steam"
flat_path="$HOME/.var/app/com.valvesoftware.Steam/data/Steam"
if [[ -d "$def_path" ]]; then
default_steam_path="$def_path"
elif [[ -d "$ub_path" ]]; then
default_steam_path="$ub_path"
elif [[ -d $flat_path ]]; then
default_steam_path="$flat_path"
2022-10-26 02:22:19 +02:00
else
local res=$(echo -e "Let DZGUI auto-discover Steam path (accurate, slower)\nSelect the Steam path manually (less accurate, faster)" | $steamsafe_zenity --list --column="Choice" --title="DZGUI" --hide-header --text="Steam is not installed in a standard location." $sd_res)
2022-11-24 21:53:35 +01:00
case "$res" in
2022-12-03 07:57:33 +01:00
*auto*) discover ;;
*manual*)
2022-12-03 13:20:36 +01:00
zenity --info --text="\nSelect the top-level entry point to the location where Steam (not DayZ)\nis installed and before entering the \"steamapps\" path.\n\nE.g., if Steam is installed at:\n\"/media/mydrive/Steam\"\n\nCorrect:\n- \"/media/mydrive/Steam\"\n\nIncorrect:\n- \"/media/mydrive/Steam/steamapps/common/DayZ\"\n- \"/media/mydrive/\"" --width=500 &&
2022-12-03 07:57:33 +01:00
file_picker ;;
2022-11-24 21:53:35 +01:00
esac
2022-10-26 02:22:19 +02:00
fi
fi
2022-10-23 20:09:35 +02:00
}
2023-11-15 11:53:11 +01:00
fold_message(){
echo "$1" | fold -s -w40
}
2022-10-23 20:09:35 +02:00
popup(){
2022-11-21 20:54:23 +01:00
pop(){
$steamsafe_zenity --info --text="$1" --title="DZGUI" --width=500 2>/dev/null
2022-11-21 20:54:23 +01:00
}
case "$1" in
2023-05-16 13:05:36 +02:00
100) pop "This feature requires xdotool and wmctrl.";;
2022-11-21 20:54:23 +01:00
200) pop "This feature is not supported on Gaming Mode.";;
2023-11-15 11:53:11 +01:00
300) pop "$(fold_message 'The Steam console will now open and briefly issue commands to download the workshop files, then return to the download progress page. Ensure that the Steam console has keyboard and mouse focus (keep hands off keyboard) while the commands are being issued. Depending on the number if mods, it may take some time to queue the downloads. If a popup or notification window steals focus, it could obstruct the process.')" ;;
400) pop "$(fold_message 'Automod install enabled. Auto-downloaded mods will not appear in your Steam Workshop subscriptions, but DZGUI will track the version number of downloaded mods internally and trigger an update if necessary.')" ;;
500) pop "$(fold_message 'Automod install disabled. Switched to manual mode.')" ;;
2022-11-24 21:53:35 +01:00
600) pop "No preferred servers set." ;;
2023-01-19 12:20:30 +01:00
700) pop "Toggled to Flatpak Steam." ;;
800) pop "Toggled to native Steam." ;;
2023-05-20 12:53:51 +02:00
900) pop "This feature is not supported on Steam Deck." ;;
2023-11-02 16:06:59 +01:00
1000) pop "No recent history." ;;
1100) pop "No results found." ;;
2023-11-15 11:53:11 +01:00
1200) pop "Timed out. Server may be temporarily offline or not responding to queries." ;;
1300) pop "No favorite server configured." ;;
2023-12-02 14:37:37 +01:00
1400) pop "To install missing mods, run DZGUI via Desktop Mode on Steam Deck, preferably via the desktop shortcut." ;;
2022-11-21 20:54:23 +01:00
esac
2022-10-23 20:09:35 +02:00
}
toggle_console_dl(){
2023-05-16 13:05:36 +02:00
[[ $is_steam_deck -eq 1 ]] && { popup 900; return; }
2022-10-23 20:09:35 +02:00
[[ ! $(command -v xdotool) ]] && { popup 100; return; }
2023-05-16 13:05:36 +02:00
[[ ! $(command -v wmctrl) ]] && { popup 100; return; }
2022-10-23 20:09:35 +02:00
mv $config_file ${config_path}dztuirc.old
local nr=$(awk '/auto_install=/ {print NR}' ${config_path}dztuirc.old)
if [[ $auto_install == "2" ]]; then
auto_install="0"
2022-11-21 20:54:23 +01:00
popup 500
2022-10-23 20:09:35 +02:00
else
auto_install="2"
2022-11-21 20:54:23 +01:00
popup 400
2022-10-23 20:09:35 +02:00
fi
local flip_state="auto_install=\"$auto_install\""
awk -v "var=$flip_state" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > $config_file
source $config_file
}
2022-11-21 20:54:23 +01:00
force_update_mods(){
if [[ -f $version_file ]]; then
awk '{OFS="\t"}{$2="000"}1' $version_file > /tmp/versions
mv /tmp/versions $version_file
fi
}
2023-01-19 12:20:30 +01:00
toggle_steam_binary(){
2023-01-19 17:55:41 +01:00
case "$steam_cmd" in
2023-01-19 12:20:30 +01:00
steam)
steam_cmd="flatpak run com.valvesoftware.Steam"
2023-01-19 17:55:41 +01:00
update_steam_cmd
2023-01-19 12:20:30 +01:00
popup 700
;;
2023-01-19 17:55:41 +01:00
flatpak*)
steam_cmd="steam"
2023-01-19 17:55:41 +01:00
update_steam_cmd
2023-01-19 12:20:30 +01:00
popup 800;;
esac
}
2022-10-07 06:30:09 +02:00
options_menu(){
2023-11-15 11:53:11 +01:00
init_options_list(){
source $config_file
set_mode
case "$auto_install" in
0|1|"") auto_hr="OFF"; ;;
2) auto_hr="ON"; ;;
esac
[[ -z $name ]] && name="null"
debug_list=(
"Toggle branch [current: $branch]"
"Toggle debug mode [current: $mode]"
"Toggle auto mod install [current: $auto_hr]"
"Change player name [current: $name]"
"Output system info"
)
#TODO: tech debt: drop old flags
[[ $auto_install -eq 2 ]] || [[ $auto_install -eq 1 ]] && debug_list+=("Force update local mods")
case "$steam_cmd" in
steam) steam_hr=Steam ;;
flatpak*) steam_hr=Flatpak ;;
esac
[[ $toggle_steam -eq 1 ]] && debug_list+=("Toggle native Steam or Flatpak [$steam_hr]")
}
while true; do
init_options_list
debug_sel=$($steamsafe_zenity --list --width=1280 --height=800 --column="Options" --title="DZGUI" --hide-header "${debug_list[@]}" 2>/dev/null)
[[ -z $debug_sel ]] && return
case "$debug_sel" in
Toggle[[:space:]]branch*)
enforce_dl=1
toggle_branch &&
check_version
;;
Toggle[[:space:]]debug*) toggle_debug ;;
"Output system info")
source_script=$(realpath "$0")
source_dir=$(dirname "$source_script")
output(){
echo "# Generating log"
generate_log > "$source_dir/DZGUI.log"
}
(output) | pdialog
[[ $? -eq 1 ]] && return
info_dialog "Wrote log file to: $source_dir/DZGUI.log"
;;
Toggle[[:space:]]auto*) toggle_console_dl ;;
"Force update local mods")
force_update=1
force_update_mods
(merge_modlists) | pdialog
auto_mod_install
;;
Toggle[[:space:]]native*) toggle_steam_binary ;;
Change[[:space:]]player[[:space:]]name*) change_name
;;
esac
done
}
info_dialog(){
local title="DZGUI"
$steamsafe_zenity --info --width=500 --title="$title" --text="$1" 2>/dev/null
}
a2s(){
local ip="$1"
local qport="$2"
local mode="$3"
2023-12-07 18:59:50 +01:00
logger A2S "Querying '$ip:$qport' with mode '$mode'"
2023-11-15 11:53:11 +01:00
python3 $helpers_path/query.py "$ip" "$qport" "$mode"
}
format_config_address(){
local address="$1"
parse(){
local ind="$1"
<<< $address awk -F: "{print \$$ind}"
}
local ip=$(parse 1)
local gameport=$(parse 2)
local qport=$(parse 3)
printf "%s\n%s\n%s" "$ip" "$gameport" "$qport"
2022-07-18 10:58:38 +02:00
}
2022-07-24 15:20:06 +02:00
query_and_connect(){
2023-11-15 11:53:11 +01:00
source $config_file
local switch="$1"
local ips="$2"
case "$switch" in
"history")
if [[ -z $2 ]]; then
warn "No recent servers in history"
return 1
fi
readarray -t ip_arr <<< "$ips"
;;
"connect"|"delete")
if [[ ${#ip_list[@]} -eq 0 ]]; then
warn "No servers currently saved"
return 1
fi
ips="$(printf "%s\n" "${ip_list[@]}")"
readarray -t ip_arr <<< "$ips"
;;
esac
[[ ${#ip_arr[@]} -lt 1 ]] && { popup 600; return; }
> $tmp
q(){
for (( i = 0; i < ${#ip_arr[@]}; ++i )); do
local address="${ip_arr[$i]}"
readarray -t address < <(format_config_address "$address")
local ip="${address[0]}"
local gameport="${address[1]}"
local qport="${address[2]}"
unset address
local info
echo "# Querying $ip:$qport"
info=$(a2s "$ip" "$qport" info)
[[ $? -eq 1 ]] && continue
local keywords=$(<<< $info jq -r '.keywords')
local vars=("name" "address" "count" "time" "dist" "qport")
for j in ${vars[@]}; do
local -n var=$j
case "$j" in
"time")
var=$(<<< "$keywords" grep -o '[0-9][0-9]:[0-9][0-9]')
;;
"name")
var=$(<<< "$info" jq -r --arg arg $j '.[$arg]')
if [[ "${#var}" -gt 50 ]]; then
var="$(<<< "$var" awk '{print substr($0,1,50) "..."}')"
fi
;;
"dist")
check_geo_file
local_latlon
var=$(get_dist $(<<< $address awk -F: '{print $1}'))
;;
*)
var=$(<<< "$info" jq -r --arg arg $j '.[$arg]')
;;
esac
printf "%s\n" "$var" >> $tmp
done
unset $j
done
}
(q) | pdialog
[[ $? -eq 1 ]] && return
populate "$switch"
2022-07-24 15:20:06 +02:00
}
2023-11-18 06:37:15 +01:00
exclude_fpp(){
response=$(<<< "$response" jq '[.[]|select(.gametype|split(",")|any(. == "no3rd")|not)]')
}
exclude_tpp(){
response=$(<<< "$response" jq '[.[]|select(.gametype|split(",")|any(. == "no3rd"))]')
}
2022-09-12 16:55:30 +02:00
exclude_full(){
response=$(echo "$response" | jq '[.[]|select(.players!=.max_players)]')
}
exclude_empty(){
response=$(echo "$response" | jq '[.[]|select(.players!=0)]')
}
filter_maps(){
echo "# Filtering maps"
[[ $ret -eq 98 ]] && return
local maps=$(echo "$response" | jq -r '.[].map//empty|ascii_downcase' | sort -u)
2022-09-13 15:45:28 +02:00
local map_ct=$(echo "$maps" | wc -l)
2022-12-02 08:25:08 +01:00
local map_sel=$(echo "$maps" | $steamsafe_zenity --list --column="Check" --width=1200 --height=800 2>/dev/null --title="DZGUI" --text="Found $map_ct map types")
2022-09-12 16:55:30 +02:00
echo "[DZGUI] Selected '$map_sel'"
if [[ -z $map_sel ]]; then
ret=97
return
fi
echo "100"
response=$(echo "$response" | jq --arg map "$map_sel" '[.[]|select(.map)//empty|select(.map|ascii_downcase == $map)]')
}
exclude_daytime(){
response=$(echo "$response" | jq '[.[]|select(.gametype|test(",[0][6-9]:|,[1][0-6]:")|not)]')
}
exclude_nighttime(){
response=$(echo "$response" | jq '[.[]|select(.gametype|test(",[1][7-9]:|,[2][0-4]:|[0][0-5]:")|not)]')
}
keyword_filter(){
response=$(echo "$response" | jq --arg search "$search" '[.[]|select(.name|ascii_downcase | contains($search))]')
}
exclude_lowpop(){
response=$(echo "$response" | jq '[.[]|select(.players > 9)]')
}
exclude_nonascii(){
response=$(echo "$response" | jq -r '[.[]|select(.name|test("^([[:ascii:]])*$"))]')
}
strip_null(){
response=$(echo "$response" | jq -r '[.[]|select(.map//empty)]')
}
local_latlon(){
2022-09-22 11:37:43 +02:00
if [[ -z $(command -v dig) ]]; then
local local_ip=$(curl -Ls "https://ipecho.net/plain")
else
2023-11-02 16:06:59 +01:00
local local_ip=$(dig -4 +short myip.opendns.com @resolver1.opendns.com)
2022-09-22 11:37:43 +02:00
fi
2023-11-02 16:06:59 +01:00
local url="http://ip-api.com/json/$local_ip"
2022-09-12 16:55:30 +02:00
local res=$(curl -Ls "$url" | jq -r '"\(.lat),\(.lon)"')
local_lat=$(echo "$res" | awk -F, '{print $1}')
local_lon=$(echo "$res" | awk -F, '{print $2}')
}
disabled(){
if [[ -z ${disabled[@]} ]]; then
printf "%s" "-"
else
for((i=0;i<${#disabled[@]};i++)); do
if [[ $i < $((${#disabled[@]}-1)) ]]; then
printf "%s, " "${disabled[$i]}"
else
printf "%s" "${disabled[$i]}"
fi
done
fi
}
pagination(){
if [[ ${#qport[@]} -eq 1 ]]; then
entry=server
else
entry=servers
fi
2022-09-25 19:29:19 +02:00
printf "DZGUI %s | " "$version"
printf "Mode: %s |" "$mode"
printf "Fav: %s " "$fav_label"
2022-09-23 12:52:22 +02:00
printf "\nIncluded: %s | " "$filters"
2022-09-13 06:41:26 +02:00
printf "Excluded: %s " "$(disabled)"
2022-09-12 16:55:30 +02:00
if [[ -n $search ]]; then
2022-09-23 12:52:22 +02:00
printf "| Keyword: %s " "$search"
2022-09-12 16:55:30 +02:00
fi
2022-09-23 12:52:22 +02:00
printf "\nReturned: %s %s of %s | " "${#qport[@]}" "$entry" "$total_servers"
2023-05-11 03:23:52 +02:00
printf "Players in-game: %s" "$players_online"
2022-09-12 16:55:30 +02:00
}
check_geo_file(){
local gzip="$helpers_path/ips.csv.gz"
2022-09-14 06:22:14 +02:00
curl -Ls "$sums_url" > "$sums_path"
2022-09-14 06:56:13 +02:00
cd "$helpers_path"
md5sum -c "$sums_path" 2>/dev/null 1>&2
2022-09-14 06:22:14 +02:00
local res=$?
2022-10-07 12:19:09 +02:00
cd $OLDPWD
2023-11-15 11:53:11 +01:00
[[ $res -eq 0 ]] && return
update(){
mkdir -p "$helpers_path"
echo "# Fetching new geolocation DB"
curl -Ls "$db_file" > "$gzip"
echo "# Extracting coordinates"
#force overwrite
gunzip -f "$gzip"
echo "# Preparing helper file"
curl -Ls "$km_helper_url" > "$km_helper"
chmod +x $km_helper
echo "100"
}
update > >(pdialog)
2022-09-12 16:55:30 +02:00
}
choose_filters(){
2022-09-25 22:35:58 +02:00
if [[ $is_steam_deck -eq 0 ]]; then
sd_res="--width=1920 --height=1080"
fi
2023-11-18 06:37:15 +01:00
sels=$($steamsafe_zenity --title="DZGUI" --text="Server search" --list --checklist --column "Check" --column "Option" --hide-header TRUE "All maps (untick to select from map list)" TRUE "Daytime" TRUE "Nighttime" TRUE "1PP" TRUE "3PP" False "Empty" False "Full" TRUE "Low population" FALSE "Non-ASCII titles" FALSE "Keyword search" $sd_res 2>/dev/null)
2022-09-12 16:55:30 +02:00
if [[ $sels =~ Keyword ]]; then
2023-11-15 11:53:11 +01:00
local search
while true; do
2023-12-02 14:37:37 +01:00
search=$(edialog "Search (case insensitive)" | awk '{print tolower($0)}')
2023-11-15 11:53:11 +01:00
[[ $? -eq 1 ]] && return 1
[[ -z $search ]] && warn "Cannot submit an empty keyword"
[[ -n $search ]] && break
done
2023-10-21 15:39:23 +02:00
fi
2022-09-12 16:55:30 +02:00
[[ -z $sels ]] && return
2023-11-02 16:06:59 +01:00
echo "$sels" | sed 's/|/, /g;s/ (untick to select from map list)//'
2023-11-15 11:53:11 +01:00
echo "$search"
2022-09-12 16:55:30 +02:00
}
get_dist(){
local given_ip="$1"
2023-11-18 06:37:15 +01:00
local network="$(<<< "$given_ip" awk -F. '{OFS="."}{print $1"."$2}')"
2022-09-13 15:35:13 +02:00
local binary=$(grep -E "^$network\." $geo_file)
2023-11-18 06:37:15 +01:00
local three=$(<<< $given_ip awk -F. '{print $3}')
local host=$(<<< $given_ip awk -F. '{print $4}')
local res=$(<<< "$binary" awk -F[.,] -v three=$three -v host=$host '$3 <=three && $7 >= three{if($3>three || ($3==three && $4 > host) || $7 < three || ($7==three && $8 < host)){next}{print}}' | awk -F, '{print $7,$8}')
local remote_lat=$(<<< "$res" awk '{print $1}')
local remote_lon=$(<<< "$res" awk '{print $2}')
2022-09-12 16:55:30 +02:00
if [[ -z $remote_lat ]]; then
local dist="Unknown"
echo "$dist"
else
2022-09-14 06:22:14 +02:00
local dist=$($km_helper "$local_lat" "$local_lon" "$remote_lat" "$remote_lon")
2023-10-21 15:39:23 +02:00
LC_NUMERIC=C printf "%05.0f %s" "$dist" "km"
2022-09-12 16:55:30 +02:00
fi
}
prepare_filters(){
2023-11-15 11:53:11 +01:00
local sels="$1"
local search="$2"
2022-09-12 16:55:30 +02:00
[[ ! "$sels" =~ "Full" ]] && { exclude_full; disabled+=("Full") ; }
[[ ! "$sels" =~ "Empty" ]] && { exclude_empty; disabled+=("Empty") ; }
[[ ! "$sels" =~ "Daytime" ]] && { exclude_daytime; disabled+=("Daytime") ; }
[[ ! "$sels" =~ "Nighttime" ]] && { exclude_nighttime; disabled+=("Nighttime") ; }
[[ ! "$sels" =~ "Low population" ]] && { exclude_lowpop; disabled+=("Low-pop") ; }
[[ ! "$sels" =~ "Non-ASCII titles" ]] && { exclude_nonascii; disabled+=("Non-ASCII") ; }
2023-11-18 06:37:15 +01:00
[[ ! "$sels" =~ "1PP" ]] && { exclude_fpp; disabled+=("FPP") ; }
[[ ! "$sels" =~ "3PP" ]] && { exclude_tpp; disabled+=("TPP") ; }
2022-09-12 16:55:30 +02:00
[[ -n "$search" ]] && keyword_filter
strip_null
2022-09-23 12:52:22 +02:00
}
2022-09-12 16:55:30 +02:00
munge_servers(){
2023-11-15 11:53:11 +01:00
local sels="$1"
local search="$2"
write_fifo(){
[[ -p $fifo ]] && rm $fifo
mkfifo $fifo
2023-11-18 06:37:15 +01:00
local dist
2023-11-15 11:53:11 +01:00
for((i=0;i<${#qport[@]};i++)); do
2023-11-18 06:37:15 +01:00
dist=$(get_dist ${addr[$i]})
printf "%s\n%s\n%s\n%s\n%03d\n%03d\n%s\n%s:%s\n%s\n" "${name[$i]}" "${map[$i]}" "${fpp[$i]}" "${gametime[$i]}" \
"${players[$i]}" "${max[$i]}" "$dist" "${addr[$i]}" "${gameport[$i]}" "${qport[$i]}" >> $fifo
2023-11-15 11:53:11 +01:00
done
}
response="$(cat /tmp/dz.servers)"
2022-09-12 16:55:30 +02:00
if [[ ! "$sels" =~ "All maps" ]]; then
2023-11-15 11:53:11 +01:00
filter_maps > >(pdialog)
[[ $? -eq 1 ]] && return
2022-09-12 16:55:30 +02:00
disabled+=("All maps")
fi
[[ $ret -eq 97 ]] && return
2023-11-15 11:53:11 +01:00
prepare_filters "$sels" "$search"
[[ $? -eq 1 ]] && return
2022-09-12 16:55:30 +02:00
if [[ $(echo "$response" | jq 'length') -eq 0 ]]; then
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --error --text="No matching servers" 2>/dev/null
2022-09-12 16:55:30 +02:00
return
fi
2023-11-18 06:37:15 +01:00
#jq bug #1788, raw output (-r) cannot be used with ASCII
local name=$(<<< "$response" jq -a '.[].name' | sed 's/\\u[0-9a-z]\{4\}//g;s/^"//;s/"$//')
local map=$(<<< "$response" jq -r '.[].map|if type == "string" then ascii_downcase else "null" end')
local gametime=$(<<< "$response" jq -r '.[]|(if .gametype == null then "null" else .gametype end)|scan("[0-9]{2}:[0-9]{2}$")')
local fpp=$(<<< "$response" jq -r '.[].gametype|split(",")|if any(. == "no3rd") then "1PP" else "3PP" end')
local players=$(<<< "$response" jq -r '.[].players')
local max=$(<<< "$response" jq -r '.[].max_players')
local addr=$(<<< "$response" jq -r '.[].addr|split(":")[0]')
local gameport=$(<<< "$response" jq -r '.[]|(if .gameport == null then "null" else .gameport end)')
local qport=$(<<< "$response" jq -r '.[].addr|split(":")[1]')
2023-11-15 11:53:11 +01:00
2022-09-12 16:55:30 +02:00
readarray -t qport <<< $qport
readarray -t gameport <<< $gameport
readarray -t addr <<< $addr
readarray -t name <<< $name
2023-11-18 06:37:15 +01:00
readarray -t fpp <<< $fpp
2022-09-12 16:55:30 +02:00
readarray -t players <<< $players
readarray -t map <<< $map
readarray -t max <<< $max
readarray -t gametime <<< $gametime
2023-11-15 11:53:11 +01:00
2022-09-12 16:55:30 +02:00
if [[ $is_steam_deck -eq 0 ]]; then
sd_res="--width=1920 --height=1080"
fi
2022-09-23 12:52:22 +02:00
write_fifo &
pid=$!
2023-11-18 06:37:15 +01:00
local sel=$($steamsafe_zenity --text="$(pagination)" --title="DZGUI" --list --column=Name --column=Map --column=PP --column=Gametime --column=Players --column=Max --column=Distance --column=IP --column=Qport $sd_res --print-column=1,8,9 --separator=%% 2>/dev/null < <(while true; do cat $fifo; done))
2022-09-23 12:52:22 +02:00
if [[ -z $sel ]]; then
2022-09-25 22:24:08 +02:00
rm $fifo
2023-11-15 11:53:11 +01:00
kill -9 $pid 2>/dev/null
return 1
2022-09-25 22:24:08 +02:00
else
rm $fifo
kill -9 $pid
echo $sel
2022-09-23 12:52:22 +02:00
fi
2022-09-12 16:55:30 +02:00
}
2022-10-03 00:24:27 +02:00
debug_servers(){
2023-11-02 16:06:59 +01:00
debug_res=$(curl -Ls "https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100&limit=10&key=$steam_api")
local len=$(<<< "$debug_res" jq '[.response.servers[]]|length')
if [[ $len -eq 0 ]]; then
return 1
2022-10-03 00:24:27 +02:00
else
2023-11-02 16:06:59 +01:00
return 0
2022-10-03 00:24:27 +02:00
fi
2023-11-02 16:06:59 +01:00
}
2022-09-12 16:55:30 +02:00
server_browser(){
2023-11-15 11:53:11 +01:00
unset ret
local filters="$(<<< "$1" awk 'NR==1 {print $0}')"
local keywords="$(<<< "$1" awk 'NR==2 {print $0}')"
echo "# Checking Steam API"
check_steam_api
[[ $? -eq 1 ]] && return
echo "# Checking geolocation file"
check_geo_file
echo "# Calculating server distances"
local_latlon
2022-09-12 16:55:30 +02:00
[[ $ret -eq 97 ]] && return
2023-11-15 11:53:11 +01:00
local limit=20000
local url="https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100&limit=$limit&key=$steam_api"
echo "# Getting server list"
curl -Ls "$url" | jq -r '.response.servers' > /tmp/dz.servers
total_servers=$(< /tmp/dz.servers jq 'length' | numfmt --grouping)
2023-05-16 13:05:36 +02:00
players_online=$(curl -Ls "https://api.steampowered.com/ISteamUserStats/GetNumberOfCurrentPlayers/v1/?appid=$aid" \
2023-05-11 03:23:52 +02:00
| jq '.response.player_count' | numfmt --grouping)
2022-10-03 00:24:27 +02:00
debug_servers
2023-11-02 16:06:59 +01:00
[[ $? -eq 1 ]] && { popup 1100; return 1; }
2023-11-15 11:53:11 +01:00
echo "100"
2023-11-18 06:37:15 +01:00
local sel=$(munge_servers "$filters" "$keywords")
if [[ -z $sel ]]; then
unset filters
unset search
ret=98
sd_res="--width=1280 --height=800"
return 1
fi
2023-11-15 11:53:11 +01:00
readarray -t address < <(format_table_results "$sel")
local ip="${address[1]}"
local gameport="${address[2]}"
local qport="${address[3]}"
unset address
2023-11-18 06:37:15 +01:00
connect "$ip" "$gameport" "$qport"
2023-11-02 16:06:59 +01:00
sd_res="--width=1280 --height=800"
2022-09-12 16:55:30 +02:00
}
2022-09-29 19:54:39 +02:00
mods_disk_size(){
2023-10-21 15:39:23 +02:00
printf "Total size on disk: %s | " $(du -sh "$workshop_dir" | awk '{print $1}')
printf "%s mods | " $(ls -1 "$workshop_dir" | wc -l)
2022-10-11 17:29:50 +02:00
printf "Location: %s/steamapps/workshop/content/221100" "$steam_path"
2022-09-29 19:54:39 +02:00
}
2022-06-04 22:29:30 +02:00
main_menu(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
logger INFO "Setting mode"
2022-07-24 15:20:06 +02:00
set_mode
2022-06-04 22:29:30 +02:00
while true; do
2023-11-15 11:53:11 +01:00
set_header "main_menu"
2023-07-25 03:10:07 +02:00
rc=$?
logger INFO "set_header rc is $rc"
if [[ $rc -eq 0 ]]; then
case "$sel" in
"") warn "No item was selected." ;;
2023-11-15 11:53:11 +01:00
" Server browser")
local filters=$(choose_filters)
[[ -z $filters ]] && continue
(server_browser "$filters") | pdialog ;;
" My servers") query_and_connect "connect" ;;
" Quick connect to favorite server") connect_to_fav "$fav_server" ;;
" Connect by ID") connect_by_id ;;
2023-07-25 03:10:07 +02:00
" Connect by IP") connect_by_ip ;;
2023-11-15 11:53:11 +01:00
" Recent servers (last 10)") query_and_connect "history" "$(cat $hist_file)" ;;
2023-07-25 03:10:07 +02:00
" Add server by ID") add_by_id ;;
2023-11-15 11:53:11 +01:00
" Add server by IP") add_by_ip ;;
2023-07-25 03:10:07 +02:00
" Add favorite server") add_by_fav ;;
" Change favorite server") add_by_fav ;;
2023-11-15 11:53:11 +01:00
" Delete server") query_and_connect "delete" ;;
2023-07-25 03:10:07 +02:00
" List installed mods")
list_mods | sed 's/\t/\n/g' | $steamsafe_zenity --list --column="Mod" --column="Symlink" --column="Dir" \
--title="DZGUI" $sd_res --text="$(mods_disk_size)" \
--print-column="" 2>/dev/null
2023-05-19 16:29:21 +02:00
;;
2023-11-15 11:53:11 +01:00
" View changelog") changelog ;;
2023-07-25 03:10:07 +02:00
" Advanced options")
options_menu
main_menu
return
;;
" Help file ⧉") help_file ;;
" Report bug ⧉") report_bug ;;
" Forum ⧉") forum ;;
2023-11-02 16:06:59 +01:00
" Sponsor ⧉") sponsor ;;
" Hall of fame ⧉") hof ;;
2023-07-25 03:10:07 +02:00
esac
else
logger INFO "Returning from main menu"
return
fi
2022-05-22 21:20:34 +02:00
done
}
2022-06-04 22:29:30 +02:00
set_fav(){
2023-11-15 11:53:11 +01:00
local fav="$1"
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2023-11-15 11:53:11 +01:00
readarray -t address < <(format_config_address "$fav")
local ip="${address[0]}"
local gameport="${address[1]}"
local qport="${address[2]}"
unset address
local info=$(a2s "$ip" "$qport" info)
local name=$(<<< $info jq -r '.name')
echo "'$name'"
2022-06-04 22:29:30 +02:00
}
2022-06-15 12:32:10 +02:00
check_unmerged(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-06-15 12:32:10 +02:00
if [[ -f ${config_path}.unmerged ]]; then
merge_config
rm ${config_path}.unmerged
fi
}
merge_config(){
source $config_file
2023-11-17 15:16:37 +01:00
legacy_fav
legacy_ids
2022-10-07 09:26:39 +02:00
[[ -z $staging_dir ]] && staging_dir="/tmp"
2023-11-15 11:53:11 +01:00
update_config
tdialog "Wrote new config format to \n${config_file}\nIf errors occur, you can restore the file:\n${config_file}.old"
2022-06-15 12:32:10 +02:00
}
2022-06-04 22:29:30 +02:00
download_new_version(){
2022-08-05 22:26:00 +02:00
if [[ $is_steam_deck -eq 1 ]]; then
freedesktop_dirs
fi
source_script=$(realpath "$0")
source_dir=$(dirname "$source_script")
mv $source_script $source_script.old
2023-07-25 03:10:07 +02:00
echo "# Downloading version $upstream"
curl -Ls "$version_url" > $source_script
2022-06-04 22:29:30 +02:00
rc=$?
if [[ $rc -eq 0 ]]; then
echo "[DZGUI] Wrote $upstream to $source_script"
chmod +x $source_script
2022-06-15 12:32:10 +02:00
touch ${config_path}.unmerged
2022-10-03 17:04:13 +02:00
echo "100"
2023-07-25 03:10:07 +02:00
$steamsafe_zenity --question --width=500 --title="DZGUI" --text "DZGUI $upstream successfully downloaded.\nTo view the changelog, select Changelog.\nTo use the new version, select Exit and restart." --ok-label="Changelog" --cancel-label="Exit" 2>/dev/null
2022-06-12 06:44:30 +02:00
code=$?
if [[ $code -eq 0 ]]; then
2023-11-15 11:53:11 +01:00
changelog
2022-06-12 06:44:30 +02:00
exit
elif [[ $code -eq 1 ]]; then
exit
fi
2022-06-04 22:29:30 +02:00
else
2022-10-03 17:04:13 +02:00
echo "100"
mv $source_script.old $source_script
2022-12-02 08:25:08 +01:00
$steamsafe_zenity --info --title="DZGUI" --text "[ERROR] 99: Failed to download new version." 2>/dev/null
2022-06-04 22:29:30 +02:00
return
fi
}
2022-07-18 10:58:38 +02:00
check_branch(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-07-18 10:58:38 +02:00
if [[ $branch == "stable" ]]; then
2022-09-14 06:56:13 +02:00
version_url="$stable_url/dzgui.sh"
2022-07-18 10:58:38 +02:00
elif [[ $branch == "testing" ]]; then
2022-09-14 06:56:13 +02:00
version_url="$testing_url/dzgui.sh"
2022-07-18 10:58:38 +02:00
fi
2023-07-25 03:10:07 +02:00
logger INFO "Branch is $branch"
2022-07-18 10:58:38 +02:00
upstream=$(curl -Ls "$version_url" | awk -F= '/^version=/ {print $2}')
2023-07-25 03:10:07 +02:00
logger INFO "Upstream version is $version"
2022-07-18 10:58:38 +02:00
}
enforce_dl(){
2023-11-15 11:53:11 +01:00
download_new_version > >(pdialog)
}
2022-10-03 17:04:13 +02:00
prompt_dl(){
2023-05-16 00:14:56 +02:00
$steamsafe_zenity --question --title="DZGUI" --text "Version conflict.\n\nYour branch:\t\t\t$branch\nYour version:\t\t\t$version\nUpstream version:\t\t$upstream\n\nVersion updates introduce important bug fixes and are encouraged.\n\nAttempt to download latest version?" --width=500 --ok-label="Yes" --cancel-label="No" 2>/dev/null
rc=$?
if [[ $rc -eq 1 ]]; then
return
else
2022-10-03 17:04:13 +02:00
echo "100"
2023-11-15 11:53:11 +01:00
download_new_version > >(pdialog)
fi
}
2022-06-04 22:29:30 +02:00
check_version(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-10-03 17:04:13 +02:00
[[ -f $config_file ]] && source $config_file
[[ -z $branch ]] && branch="stable"
2022-07-18 10:58:38 +02:00
check_branch
2022-10-27 06:40:42 +02:00
[[ ! -f "$freedesktop_path/dzgui.desktop" ]] && freedesktop_dirs
2022-06-04 22:29:30 +02:00
if [[ $version == $upstream ]]; then
2023-07-25 03:10:07 +02:00
logger INFO "Local version is same as upstream"
2022-06-15 12:32:10 +02:00
check_unmerged
2022-06-04 22:29:30 +02:00
else
2023-07-25 03:10:07 +02:00
logger INFO "Local and remote version mismatch"
if [[ $enforce_dl -eq 1 ]]; then
enforce_dl
2022-06-04 22:29:30 +02:00
else
prompt_dl
2022-06-04 22:29:30 +02:00
fi
fi
}
2022-06-15 12:32:10 +02:00
check_architecture(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-07-24 15:20:06 +02:00
cpu=$(cat /proc/cpuinfo | grep "AMD Custom APU 0405")
2022-08-04 21:41:25 +02:00
if [[ -n "$cpu" ]]; then
2022-06-15 12:32:10 +02:00
is_steam_deck=1
2023-07-25 03:10:07 +02:00
logger INFO "Setting architecture to 'Steam Deck'"
2022-06-15 12:32:10 +02:00
else
is_steam_deck=0
2023-07-25 03:10:07 +02:00
logger INFO "Setting architecture to 'desktop'"
2022-06-15 12:32:10 +02:00
fi
}
2023-11-15 11:53:11 +01:00
print_ip_list(){
2023-11-22 10:33:50 +01:00
[[ ${#ip_list} -eq 0 ]] && return
printf "\t\"%s\"\n" "${ip_list[@]}"
2023-11-15 11:53:11 +01:00
}
migrate_files(){
if [[ ! -f $config_path/dztuirc.oldapi ]]; then
cp $config_file $config_path/dztuirc.oldapi
rm $hist_file
fi
}
legacy_fav(){
source $config_file
[[ -z $fav ]] && return
local res=$(map_fav_to_ip "$fav")
source $config_file
}
legacy_ids(){
source $config_file
[[ -z $whitelist ]] && return
local res=$(map_id_to_ip "$whitelist")
source $config_file
}
map_fav_to_ip(){
local to_add="$1"
fav_server=$(curl -s "$api" -H "Authorization: Bearer "$api_key"" \
-G -d "sort=-players" \
-d "filter[game]=$game" \
-d "filter[ids][whitelist]=$to_add" \
| jq -r '.data[].attributes|"\(.ip):\(.port):\(.portQuery)"')
update_config
fav_label=$(set_fav "$fav_server")
}
map_id_to_ip(){
local to_add="$1"
local mode="$2"
local res=$(curl -s "$api" -H "Authorization: Bearer "$api_key"" \
-G -d "sort=-players" \
-d "filter[game]=$game" \
-d "filter[ids][whitelist]=$to_add")
local len=$(<<< "$res" jq '.data|length')
[[ $len -eq 0 ]] && return 1
local ip=$(<<< "$res" jq -r '.data[].attributes|"\(.ip):\(.port):\(.portQuery)"')
if [[ $mode == "connect" ]]; then
echo "$ip"
return 0
fi
for i in $ip; do
if [[ ${ip_list[@]} =~ $i ]]; then
[[ ! $len -eq 1 ]] && continue
2023-11-22 10:33:50 +01:00
warn "This server is already in your list"
2023-11-15 11:53:11 +01:00
return 2
fi
ip_list+=("$i")
update_config
done
echo $i
}
add_by_ip(){
local sel=$(parse_ips)
[[ -z $sel ]] && return
readarray -t address < <(format_table_results "$sel")
local ip="${address[1]}"
local gameport="${address[2]}"
local qport="${address[3]}"
unset address
if [[ ${ip_list[@]} =~ "$ip:$gameport:$qport" ]]; then
warn "This server is already in your favorites"
return
fi
ip_list+=("$ip:$gameport:$qport")
update_config
info "Added $ip:$gameport:$qport to:\n${config_path}dztuirc\nIf errors occurred, you can restore the file:\n${config_path}dztuirc.old"
}
pdialog(){
$steamsafe_zenity --progress --pulsate --auto-close --title="DZGUI" --width=500 2>/dev/null
}
edialog(){
2023-12-02 14:37:37 +01:00
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
2023-11-15 11:53:11 +01:00
}
tdialog(){
2023-11-15 12:07:18 +01:00
$steamsafe_zenity --info --text="$1" --width=500 --title="DZGUI" 2>/dev/null
2023-11-15 11:53:11 +01:00
}
qdialog(){
2023-11-15 12:07:18 +01:00
$steamsafe_zenity --question --text="$1" --width=500 --title="DZGUI" 2>/dev/null
2023-11-15 11:53:11 +01:00
}
2022-06-04 22:29:30 +02:00
add_by_id(){
2023-11-15 11:53:11 +01:00
local mode="$1"
if [[ -z $api_key ]]; then
qdialog "Requires Battlemetrics API key. Set one now?"
[[ $? -eq 1 ]] && return 1
while true; do
api_key=$(edialog "Battlemetrics API key")
[[ $? -eq 1 ]] && return 1
[[ -z $api_key ]] && { warn "Invalid API key"; continue; }
if [[ $(test_bm_api $api_key) -eq 1 ]]; then
warn "Invalid API key"
unset api_key
continue
fi
update_config
break
done
fi
2022-06-15 12:32:10 +02:00
while true; do
2023-11-15 11:53:11 +01:00
local id
id=$(edialog "Enter server ID")
[[ $? -eq 1 ]] && return 1
if [[ ! $id =~ ^[0-9]+$ ]]; then
warn "Invalid ID"
else
local ip
ip=$(map_id_to_ip "$id" "$mode")
case "$?" in
1)
warn "Invalid ID"
continue
;;
2)
continue
;;
*)
if [[ $mode == "connect" ]]; then
echo "$ip"
return 0
fi
2023-11-22 10:33:50 +01:00
tdialog "Added $ip to:\n${config_path}dztuirc\nIf errors occurred, you can restore the file:\n${config_path}dztuirc.old"
2023-11-15 11:53:11 +01:00
return 0
;;
esac
fi
2022-06-15 12:32:10 +02:00
done
}
2022-06-22 15:33:52 +02:00
toggle_debug(){
if [[ $debug -eq 1 ]]; then
debug=0
else
debug=1
fi
2023-11-15 11:53:11 +01:00
update_config
2022-06-22 15:33:52 +02:00
}
setup(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2023-11-15 11:53:11 +01:00
[[ -z $fav_server ]] && return
items[10]=" Change favorite server"
[[ -n $fav_label ]] && return
fav_label=$(set_fav $fav_server)
update_config
2022-06-22 15:33:52 +02:00
}
2022-07-24 15:20:06 +02:00
check_map_count(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2023-05-19 16:29:21 +02:00
[[ $is_steam_deck -eq 1 ]] && return
2023-05-11 05:08:15 +02:00
local count=1048576
2023-07-25 03:10:07 +02:00
logger INFO "Checking system map count"
2022-08-16 17:49:51 +02:00
echo "[DZGUI] Checking system map count"
2023-05-11 05:08:15 +02:00
if [[ ! -f /etc/sysctl.d/dayz.conf ]]; then
2023-07-25 03:10:07 +02:00
$steamsafe_zenity --question --width=500 --title="DZGUI" --cancel-label="Cancel" --ok-label="OK" --text "sudo password required to check system vm map count."
local rc=$?
logger INFO "Return code is $rc"
if [[ $rc -eq 0 ]]; then
2023-05-16 00:14:56 +02:00
local pass
2023-07-25 03:10:07 +02:00
logger INFO "Prompting user for sudo escalation"
2023-05-16 00:14:56 +02:00
pass=$($steamsafe_zenity --password)
2023-07-25 03:10:07 +02:00
local rc
logger INFO "Return code is $rc"
[[ $rc -eq 1 ]] && exit 1
2023-05-11 05:08:15 +02:00
local ct=$(sudo -S <<< "$pass" sh -c "sysctl -q vm.max_map_count | awk -F'= ' '{print \$2}'")
local new_ct
[[ $ct -lt $count ]] && ct=$count
2023-07-25 03:10:07 +02:00
logger INFO "Updating map count"
2023-05-11 05:08:15 +02:00
sudo -S <<< "$pass" sh -c "echo 'vm.max_map_count=$ct' > /etc/sysctl.d/dayz.conf"
2023-02-17 13:51:21 +01:00
sudo sysctl -p /etc/sysctl.d/dayz.conf
2023-05-11 05:08:15 +02:00
else
2023-07-25 03:10:07 +02:00
logger INFO "Zenity dialog failed or user exit"
2023-05-11 05:08:15 +02:00
exit 1
2022-07-24 15:20:06 +02:00
fi
fi
}
2023-11-15 11:53:11 +01:00
change_name(){
while true; do
local name=$($steamsafe_zenity --entry --text="Enter desired in-game name" --title="DZGUI" 2>/dev/null)
[[ -z "${name//[[:blank:]]/}" ]] && continue
update_config
info "Changed name to: '$name'.\nIf errors occur, you can restore the file '${config_path}dztuirc.old'."
return
done
}
2022-06-15 12:32:10 +02:00
add_by_fav(){
2023-11-15 11:53:11 +01:00
local sel=$(parse_ips)
[[ -z $sel ]] && return
readarray -t address < <(format_table_results "$sel")
local ip="${address[1]}"
local gameport="${address[2]}"
local qport="${address[3]}"
unset address
fav_server="$ip:$gameport:$qport"
fav_label=$(set_fav "$fav_server")
update_config
info "Added $fav_server to:\n${config_path}dztuirc\nIf errors occurred, you can restore the file:\n${config_path}dztuirc.old"
items[10]=" Change favorite server"
2022-06-04 22:29:30 +02:00
}
2022-08-13 15:00:35 +02:00
lock(){
2023-05-11 03:28:19 +02:00
[[ ! -d $config_path ]] && return
2022-12-03 13:38:27 +01:00
if [[ ! -f ${config_path}.lockfile ]]; then
touch ${config_path}.lockfile
2022-08-13 15:00:35 +02:00
fi
2022-12-03 13:38:27 +01:00
pid=$(cat ${config_path}.lockfile)
2022-08-13 15:00:35 +02:00
ps -p $pid -o pid= >/dev/null 2>&1
res=$?
if [[ $res -eq 0 ]]; then
2023-11-15 11:53:11 +01:00
info "DZGUI already running ($pid)"
2022-08-13 15:00:35 +02:00
exit
elif [[ $pid == $$ ]]; then
:
else
2022-12-03 13:38:27 +01:00
echo $$ > ${config_path}.lockfile
2022-08-13 15:00:35 +02:00
fi
}
2023-11-15 11:53:11 +01:00
fetch_a2s(){
[[ -d $helpers_path/a2s ]] && return
local sha=c7590ffa9a6d0c6912e17ceeab15b832a1090640
local author="yepoleb"
local repo="python-a2s"
local url="https://github.com/$author/$repo/tarball/$sha"
local prefix="${author^}-$repo-${sha:0:7}"
local file="$prefix.tar.gz"
curl -Ls "$url" > "$helpers_path/$file"
tar xf "$helpers_path/$file" -C "$helpers_path" "$prefix/a2s" --strip=1
rm "$helpers_path/$file"
}
fetch_dzq(){
[[ -f $helpers_path/dayzquery.py ]] && return
local sha=ccc4f71b48610a1885706c9d92638dbd8ca012a5
local author="yepoleb"
local repo="dayzquery"
local url="https://raw.githubusercontent.com/$author/$repo/$sha/$repo.py"
curl -Ls "$url" > $helpers_path/a2s/$repo.py
}
fetch_query(){
2023-11-23 05:55:15 +01:00
local sum="7cbae12ae68b526e7ff376b638123cc7"
local file="$helpers_path/query.py"
2023-11-23 05:24:16 +01:00
if [[ -f $file ]] && [[ $(md5sum $file | awk '{print $1}') == $sum ]]; then
return
fi
2023-11-15 11:53:11 +01:00
local author="aclist"
2023-11-22 16:31:02 +01:00
local repo="dzgui"
2023-11-15 11:59:07 +01:00
local url="https://raw.githubusercontent.com/$author/dztui/$repo/helpers/query.py"
2023-11-15 11:53:11 +01:00
curl -Ls "$url" > "$helpers_path/query.py"
}
2022-11-24 21:53:35 +01:00
fetch_helpers(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2022-10-08 05:25:46 +02:00
mkdir -p "$helpers_path"
2022-11-24 21:53:35 +01:00
[[ ! -f "$helpers_path/vdf2json.py" ]] && curl -Ls "$vdf2json_url" > "$helpers_path/vdf2json.py"
2023-11-15 11:53:11 +01:00
fetch_a2s
fetch_dzq
fetch_query
2022-10-11 13:58:00 +02:00
}
2023-01-19 17:55:41 +01:00
update_steam_cmd(){
preferred_client="$steam_cmd"
2023-11-15 11:53:11 +01:00
update_config
}
2023-01-19 12:20:30 +01:00
steam_deps(){
2023-07-25 03:10:07 +02:00
logger INFO "${FUNCNAME[0]}"
2023-01-19 18:05:45 +01:00
local flatpak steam
2023-02-17 13:51:21 +01:00
[[ $(command -v flatpak) ]] && flatpak=$(flatpak list | grep valvesoftware.Steam)
2023-01-19 12:20:30 +01:00
steam=$(command -v steam)
if [[ -z "$steam" ]] && [[ -z "$flatpak" ]]; then
warn "Requires Steam or Flatpak Steam"
2023-07-25 03:10:07 +02:00
logger ERROR "Steam was missing"
2023-01-19 12:20:30 +01:00
exit
elif [[ -n "$steam" ]] && [[ -n "$flatpak" ]]; then
toggle_steam=1
steam_cmd="steam"
2023-01-19 17:55:41 +01:00
[[ -n $preferred_client ]] && steam_cmd="$preferred_client"
[[ -z $preferred_client ]] && update_steam_cmd
2023-01-19 12:20:30 +01:00
elif [[ -n "$steam" ]]; then
steam_cmd="steam"
else
steam_cmd="flatpak run com.valvesoftware.Steam"
2023-01-19 12:20:30 +01:00
fi
2023-07-25 03:10:07 +02:00
logger INFO "steam_cmd set to $steam_cmd"
2023-01-19 12:20:30 +01:00
}
2023-01-19 18:05:11 +01:00
update_steam_cmd(){
local new_cmd
preferred_client="$steam_cmd"
new_cmd="preferred_client=\"$preferred_client\""
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/preferred_client=/ {print NR}' ${config_path}dztuirc.old)
awk -v "var=$new_cmd" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > ${config_path}dztuirc
}
2023-01-19 12:11:38 +01:00
steam_deps(){
2023-06-18 14:53:43 +02:00
logger INFO "${FUNCNAME[0]}"
2023-01-19 12:11:38 +01:00
local flatpak steam
2023-02-17 05:35:37 +01:00
[[ $(command -v flatpak) ]] && flatpak=$(flatpak list | grep valvesoftware.Steam)
2023-01-19 12:11:38 +01:00
steam=$(command -v steam)
if [[ -z "$steam" ]] && [[ -z "$flatpak" ]]; then
warn "Requires Steam or Flatpak Steam"
2023-06-18 14:53:43 +02:00
logger ERROR "Steam was missing"
2023-01-19 12:11:38 +01:00
exit
elif [[ -n "$steam" ]] && [[ -n "$flatpak" ]]; then
toggle_steam=1
steam_cmd="steam"
2023-01-19 18:05:11 +01:00
[[ -n $preferred_client ]] && steam_cmd="$preferred_client"
[[ -z $preferred_client ]] && update_steam_cmd
2023-01-19 12:11:38 +01:00
elif [[ -n "$steam" ]]; then
steam_cmd="steam"
else
2023-01-19 15:42:19 +01:00
steam_cmd="flatpak run com.valvesoftware.Steam"
2023-01-19 12:11:38 +01:00
fi
2023-06-18 14:53:43 +02:00
logger INFO "steam_cmd set to $steam_cmd"
2023-01-19 12:11:38 +01:00
}
2022-09-24 11:49:01 +02:00
initial_setup(){
echo "# Initial setup"
2022-06-15 12:32:10 +02:00
run_depcheck
2023-11-23 05:55:15 +01:00
check_pyver
2022-10-09 04:07:07 +02:00
watcher_deps
2022-06-15 12:32:10 +02:00
check_architecture
2022-08-05 22:28:52 +02:00
check_version
2022-07-24 15:20:06 +02:00
check_map_count
2022-11-24 21:53:35 +01:00
fetch_helpers
2022-05-22 21:20:34 +02:00
config
steam_deps
2022-06-15 12:32:10 +02:00
run_varcheck
2023-11-15 11:53:11 +01:00
migrate_files
2022-11-21 20:54:23 +01:00
stale_symlinks
2022-06-22 15:33:52 +02:00
init_items
setup
2023-05-16 00:14:56 +02:00
check_news
2022-09-24 11:49:01 +02:00
echo "100"
}
main(){
2023-11-15 11:53:11 +01:00
local parent=$(cat /proc/$PPID/comm)
[[ -f "$debug_log" ]] && rm "$debug_log"
2022-09-27 02:42:46 +02:00
lock
2023-07-25 03:10:07 +02:00
local zenv=$(zenity --version 2>/dev/null)
2023-11-15 11:53:11 +01:00
[[ -z $zenv ]] && { echo "Failed to find zenity"; logger "Missing zenity"; exit 1; }
2023-11-15 12:11:57 +01:00
initial_setup > >(pdialog)
2022-05-22 21:20:34 +02:00
main_menu
2022-12-03 07:57:33 +01:00
#TODO: tech debt: cruddy handling for steam forking
2022-09-23 12:52:22 +02:00
[[ $? -eq 1 ]] && pkill -f dzgui.sh
2022-05-09 13:42:24 +02:00
}
main