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

1628 lines
51 KiB
Bash
Raw Normal View History

2022-05-09 13:42:24 +02:00
#!/bin/bash
2022-06-04 22:29:30 +02:00
set -o pipefail
2022-10-08 14:12:22 +02:00
version=2.8.0-rc.21
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"
2022-09-22 11:37:43 +02:00
tmp=/tmp/dzgui.tmp
2022-09-25 22:24:08 +02:00
fifo=/tmp/table.tmp
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"
news_url="$testing_url/news"
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"
sums_url="$testing_url/helpers/sums.md5"
2022-10-07 06:30:09 +02:00
scmd_url="$testing_url/helpers/scmd.sh"
2022-10-08 05:09:08 +02:00
notify_url="$testing_url/helpers/d.html"
notify_img_url="$testing_url/helpers/d.webp"
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
printf "[DZGUI] Updated last seen news item to '$sum'\n"
source $config_file
}
check_news(){
result=$(curl -Ls "$news_url")
sum=$(echo -n "$result" | md5sum | awk '{print $1}')
}
print_news(){
check_news
if [[ $sum == $seen_news || -z $result ]]; then
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
}
#TODO: prevent connecting to offline servers
2022-08-14 11:10:00 +02:00
#TODO: abstract zenity title params and dimensions
2022-05-09 13:42:24 +02:00
declare -A deps
2022-10-08 13:17:31 +02:00
deps=([awk]="5.1.1" [curl]="7.80.0" [jq]="1.6" [tr]="9.0" [zenity]="3.42.1" [steam]="1.0.0")
2022-06-12 06:44:30 +02:00
changelog(){
2022-07-24 15:20:06 +02:00
if [[ $branch == "stable" ]]; then
md="https://raw.githubusercontent.com/aclist/dztui/dzgui/changelog.md"
else
md="https://raw.githubusercontent.com/aclist/dztui/testing/changelog.md"
fi
2022-06-12 06:44:30 +02:00
prefix="This window can be scrolled."
echo $prefix
echo ""
curl -Ls "$md" | awk '/Unreleased/ {flag=1}flag'
2022-06-12 06:44:30 +02:00
}
2022-05-09 13:42:24 +02:00
depcheck(){
for dep in "${!deps[@]}"; do
2022-07-24 15:20:06 +02: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-06-22 15:33:52 +02:00
init_items(){
#array order determines menu selector; this is destructive
2022-05-22 21:20:34 +02:00
items=(
2022-10-03 17:04:13 +02:00
"[Connect]"
" NEW: Server browser"
" My servers"
" Quick connect to favorite server"
"[Manage servers]"
" Connect by IP"
" Add server by ID"
" Add favorite server"
" Delete server"
"[Options]"
" List installed mods"
" Report bug (opens in browser)"
" Help file (opens in browser)"
" View changelog"
2022-10-07 06:30:09 +02:00
" Advanced options"
2022-05-22 21:20:34 +02:00
)
2022-06-22 15:33:52 +02:00
}
2022-06-04 22:29:30 +02:00
warn_and_exit(){
2022-10-08 07:01:59 +02:00
zenity --info --title="DZGUI" --text="$1" --width=500 --icon-name="dialog-warning" 2>/dev/null
2022-06-15 12:32:10 +02:00
printf "[DZGUI] %s\n" "$check_config_msg"
2022-06-04 22:29:30 +02:00
exit
}
2022-05-22 21:20:34 +02:00
warn(){
2022-10-08 07:01:59 +02:00
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-10-08 07:01:59 +02:00
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(){
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-09 13:42:24 +02:00
query_api(){
2022-06-15 12:32:10 +02:00
#TODO: prevent drawing list if null values returned without API error
if [[ $one_shot_launch -eq 1 ]]; then
list_of_ids="$fav"
else
if [[ -n $fav ]]; then
list_of_ids="$whitelist,$fav"
else
list_of_ids="$whitelist"
fi
fi
2022-08-11 00:59:29 +02:00
set_api_params
2022-05-09 13:42:24 +02:00
if [[ "$(jq -r 'keys[]' <<< "$response")" == "errors" ]]; then
code=$(jq -r '.errors[] .status' <<< $response)
#TODO: fix granular api codes
2022-06-15 12:32:10 +02:00
if [[ $code -eq 401 ]]; then
2022-09-26 21:04:06 +02:00
warn "Error $code: malformed API key"
return
2022-06-15 12:32:10 +02:00
elif [[ $code -eq 500 ]]; then
2022-09-26 21:04:06 +02:00
warn "Error $code: malformed server list"
return
2022-06-15 12:32:10 +02:00
fi
fi
if [[ -z $(echo $response | jq '.data[]') ]]; then
2022-09-26 21:04:06 +02:00
warn "95: API returned empty response. Check config file."
return
2022-05-09 13:42:24 +02:00
fi
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
#Comma-separated list of server IDs
2022-06-15 12:32:10 +02:00
whitelist="$whitelist"
2022-05-22 21:20:34 +02:00
#Favorite server to fast-connect to (limit one)
2022-06-15 12:32:10 +02:00
fav="$fav"
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
#Terminal emulator
term="$term"
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-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"
#TODO: update url
2022-08-06 00:42:35 +02:00
curl -s "$version_url" > "$sd_install_path/dzgui.sh"
chmod +x "$sd_install_path/dzgui.sh"
2022-08-05 21:58:59 +02:00
img_url="https://raw.githubusercontent.com/aclist/dztui/testing/images"
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-08-14 11:10:00 +02:00
file_picker(){
while true; do
local path=$(zenity --file-selection --directory 2>/dev/null)
2022-10-07 12:19:09 +02:00
if [[ -z "$path" ]]; then
return
2022-08-14 11:10:00 +02:00
else
2022-10-07 12:19:09 +02:00
echo "[DZGUI]" Set mod staging path to "$path"
staging_dir="$path"
write_config > $config_file
2022-08-14 11:10:00 +02:00
return
fi
done
}
2022-08-05 21:58:59 +02:00
guess_path(){
echo "# Checking for default DayZ path"
2022-08-14 11:10:00 +02:00
path=$(find $HOME -type d -regex ".*/steamapps/common/DayZ$" -print -quit)
2022-08-31 10:22:07 +02:00
if [[ -n "$path" ]]; then
clean_path=$(echo -e "$path" | awk -F"/steamapps" '{print $1}')
steam_path="$clean_path"
2022-06-15 12:32:10 +02:00
else
2022-08-14 11:10:00 +02:00
echo "# Searching for alternate DayZ path. This may take some time."
path=$(find / -type d \( -path "/proc" -o -path "*/timeshift" -o -path "/tmp" -o -path "/usr" -o -path "/boot" -o -path "/proc" -o -path "/root" -o -path "/run" -o -path "/sys" -o -path "/etc" -o -path "/var" -o -path "/run" -o -path "/lost+found" \) -prune -o -regex ".*/steamapps/common/DayZ$" -print -quit 2>/dev/null)
2022-08-05 21:58:59 +02:00
clean_path=$(echo -e "$path" | awk -F"/steamapps" '{print $1}')
steam_path="$clean_path"
2022-06-15 12:32:10 +02:00
fi
}
2022-05-22 21:20:34 +02:00
create_config(){
2022-08-04 21:14:56 +02:00
while true; do
2022-10-03 17:04:13 +02:00
player_input="$(zenity --forms --add-entry="Player name (required for some servers)" --add-entry="API key" --add-entry="Server 1 (you can add more later)" --title="DZGUI" --text="DZGUI" --add-entry="Server 2" --add-entry="Server 3" --add-entry="Server 4" $sd_res --separator="│" 2>/dev/null)"
2022-08-04 21:14:56 +02:00
#explicitly setting IFS crashes zenity in loop
#and mapfile does not support high ascii delimiters
#so split fields with newline
readarray -t args < <(echo "$player_input" | sed 's/│/\n/g')
name="${args[0]}"
api_key="${args[1]}"
server_1="${args[2]}"
server_2="${args[3]}"
server_3="${args[4]}"
server_4="${args[5]}"
[[ -z $player_input ]] && exit
if [[ -z $api_key ]]; then
warn "API key: invalid value"
elif [[ -z $server_1 ]]; then
warn "Server 1: cannot be empty"
2022-08-04 21:14:56 +02:00
elif [[ ! $server_1 =~ ^[0-9]+$ ]]; then
warn "Server 1: only numeric IDs"
2022-08-04 21:14:56 +02:00
elif [[ -n $server_2 ]] && [[ ! $server_2 =~ ^[0-9]+$ ]]; then
warn "Server 2: only numeric IDs"
2022-08-04 21:14:56 +02:00
elif [[ -n $server_3 ]] && [[ ! $server_3 =~ ^[0-9]+$ ]]; then
warn "Server 3: only numeric IDs"
2022-08-04 21:14:56 +02:00
elif [[ -n $server_4 ]] && [[ ! $server_3 =~ ^[0-9]+$ ]]; then
warn "Server 4: only numeric IDs"
2022-08-04 21:14:56 +02:00
else
whitelist=$(echo "$player_input" | awk -F"│" '{OFS=","}{print $3,$4,$5,$6}' | sed 's/,*$//g' | sed 's/^,*//g')
2022-08-14 11:10:00 +02:00
guess_path > >(zenity --width 500 --progress --auto-close --pulsate 2>/dev/null) &&
echo "[DZGUI] Set path to $steam_path"
#FIXME: tech debt: gracefully exit if user cancels search process
2022-05-22 21:20:34 +02:00
mkdir -p $config_path; write_config > $config_file
2022-06-15 12:32:10 +02:00
info "Config file created at $config_file."
2022-08-04 21:14:56 +02:00
return
fi
done
2022-05-22 21:20:34 +02:00
}
err(){
printf "[ERROR] %s\n" "$1"
}
varcheck(){
[[ -z $api_key ]] && (err "Error in key: 'api_key'")
[[ -z $whitelist ]] && (err "Error in key: 'whitelist'")
2022-08-31 10:22:07 +02:00
[[ ! -d "$game_dir" ]] && (err "Malformed game path")
2022-05-22 21:20:34 +02:00
[[ $whitelist =~ [[:space:]] ]] && (err "Separate whitelist values with commas")
}
2022-09-22 11:37:43 +02:00
run_depcheck(){
2022-05-22 21:20:34 +02:00
if [[ -z $(depcheck) ]]; then
:
else
2022-10-08 13:09:33 +02:00
echo "100"
2022-07-24 15:20:06 +02:00
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
}
run_varcheck(){
source $config_file
workshop_dir="$steam_path/steamapps/workshop/content/$aid"
game_dir="$steam_path/steamapps/common/DayZ"
2022-10-08 13:09:33 +02:00
if [[ -z $(varcheck) ]]; then
2022-05-22 21:20:34 +02:00
:
else
zenity --warning --width 500 --text="$(varcheck)" 2>/dev/null
2022-06-15 12:32:10 +02:00
printf "[DZGUI] %s\n" "$check_config_msg"
zenity --question --cancel-label="Exit" --text="Malformed config file. This is probably user error.\nStart first-time setup process again?" 2>/dev/null
code=$?
if [[ $code -eq 1 ]]; then
exit
else
2022-10-02 02:26:21 +02:00
echo "100"
create_config
fi
2022-05-22 21:20:34 +02:00
fi
}
config(){
if [[ ! -f $config_file ]]; then
2022-08-05 22:26:00 +02:00
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=$?
2022-08-05 21:58:59 +02:00
#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-06-15 12:32:10 +02:00
}
open_mod_links(){
link_file=$(mktemp)
echo "<html>" > $link_file
echo "<title>DZGUI</title>" >> $link_file
echo "<h1>DZGUI</h1>" >> $link_file
echo "<p>Open these links and subscribe to them on the Steam Workshop, then continue with the application prompts.<br><b>Note:</b> it may take some time for mods to synchronize before DZGUI can see them.<br>It can help to have Steam in an adjacent window so that you can see the downloads completing.</p>" >> $link_file
2022-07-18 10:58:38 +02:00
n=1
for i in $diff; do
echo "$n. <a href=\"${workshop}$i\">${workshop}$i</a><br>"
let n++
2022-06-15 12:32:10 +02:00
done >> $link_file
echo "</html>" >> $link_file
2022-09-14 06:56:13 +02:00
browser "$link_file" 2>/dev/null &
2022-06-15 12:32:10 +02:00
2022-05-22 21:20:34 +02:00
}
2022-10-08 14:12:22 +02:00
steam_deck_mods(){
until [[ -z $diff ]]; do
next=$(echo -e "$diff" | head -n1)
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
rc=$?
if [[ $rc -eq 0 ]]; then
echo "[DZGUI] Opening ${workshop}$next"
steam steam://url/CommunityFilePage/$next 2>/dev/null &
zenity --info --title="DZGUI" --ok-label="Next" --text="Click [Next] to continue mod check." --width=500 2>/dev/null
else
return 1
fi
compare
done
}
2022-10-05 10:08:47 +02:00
set_term(){
local term="$1"
local tterm="term=\"$term\""
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/term=/ {print NR}' ${config_path}dztuirc.old)
awk -v "var=$tterm" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > $config_file
printf "[DZGUI] Set term to '$term'\n"
source $config_file
}
sel_term(){
2022-10-06 14:50:37 +02:00
#only terminals known to support -e flag
2022-10-08 06:46:56 +02:00
for i in "$TERMINAL" urxvt alacritty konsole gnome-terminal terminator xfce4-terminal xterm tilix; do
2022-10-05 10:08:47 +02:00
[[ $(command -v $i) ]] && terms+=($i)
done
#FIXME: if no terms, error
local terms=$(printf "%s\n" "${terms[@]}" | sort -u)
2022-10-07 09:26:39 +02:00
term=$(echo "$terms" | zenity --list --column=Terminal --height=800 --width=1200 --text="Select your preferred terminal emulator to run steamcmd (setting will be saved)" --title=DZGUI 2>/dev/null)
2022-10-05 10:08:47 +02:00
}
2022-10-08 04:50:47 +02:00
calc_mod_sizes(){
for i in "$diff"; do
2022-10-08 05:09:08 +02:00
local mods+=$(grep -w "$i" /tmp/modsizes | awk '{print $1}')
2022-10-08 04:50:47 +02:00
done
totalmodsize=$(echo -e "${mods[@]}" | awk '{s+=$1}END{print s}')
}
2022-10-08 06:46:56 +02:00
term_params(){
case $term in
konsole) $term --hold -e "bash $helpers_path/scmd.sh $totalmodsize $1";;
urxvt) $term -e bash -c "/$helpers_path/scmd.sh $totalmodsize $1";;
alacritty) $term -e bash -c "/$helpers_path/scmd.sh $totalmodsize $1";;
terminator|xterm|tilix|xfce4-terminal) $term -e "bash $helpers_path/scmd.sh $totalmodsize $1";;
esac
}
2022-10-05 10:08:47 +02:00
auto_mod_install(){
cmd=$(printf "%q " "$@")
if [[ -z "$term" ]]; then
2022-10-08 06:14:27 +02:00
if [[ $is_steam_deck -eq 1 ]]; then
set_term konsole
return 0
else
sel_term && set_term "$term"
fi
2022-10-05 10:08:47 +02:00
fi
2022-10-07 09:26:39 +02:00
[[ -z "$term" ]] && return 1
2022-10-05 10:08:47 +02:00
echo "[DZGUI] Kicking off auto mod script"
2022-10-08 04:50:47 +02:00
calc_mod_sizes
2022-10-08 06:46:56 +02:00
term_params "$cmd"
2022-10-05 10:08:47 +02:00
compare
if [[ -z $diff ]]; then
passed_mod_check > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
2022-10-07 09:26:39 +02:00
launch
2022-10-05 10:08:47 +02:00
else
warn "Auto mod installation failed or some mods missing.\nReverting to manual mode."
return 1
fi
}
2022-10-08 14:12:22 +02:00
test_display_mode(){
pgrep -a gamescope | grep -q "generate-drm-mode"
[[ $? -eq 0 ]] && gamemode=1
}
2022-06-04 22:29:30 +02:00
manual_mod_install(){
2022-10-08 14:12:22 +02:00
[[ $is_steam_deck -eq 1 ]] && test_display_mode
if [[ $gamemode -eq 1 ]]; then
steam_deck_mods
else
local ex="/tmp/dzc.tmp"
[[ -f $ex ]] && rm $ex
watcher(){
readarray -t stage_mods <<< "$diff"
for((i=0;i<${#stage_mods[@]};i++)); do
2022-10-08 13:04:49 +02:00
[[ -f $ex ]] && return 1
2022-10-08 14:12:22 +02:00
local downloads_dir="$steam_path/steamapps/workshop/downloads/$aid"
local workshop_dir="$steam_path/steamapps/workshop/content/$aid"
steam "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
wmctrl -a "DZG Watcher"
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
2022-10-08 13:04:49 +02:00
done
2022-10-08 14:12:22 +02:00
wmctrl -a "DZG Watcher"
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
wmctrl -a "DZG Watcher"
echo "# ${stage_mods[$i]} moved to mods dir"
done
echo "100"
}
watcher > >(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 > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
launch
else
return 1
fi
2022-10-08 09:30:47 +02:00
fi
2022-06-04 22:29:30 +02:00
}
2022-10-08 13:04:49 +02:00
# if [[ $is_steam_deck -eq 0 ]]; then
# open_mod_links
# until [[ -z $diff ]]; do
# zenity --question --title="DZGUI" --ok-label="Next" --cancel-label="Cancel" --text="Opened mod links in browser.\nClick [Next] when all mods have been subscribed to.\nThis dialog may reappear if clicking [Next] too soon\nbefore mods are synchronized in the background." --width=500 2>/dev/null
# rc=$?
# if [[ $rc -eq 0 ]]; then
# compare
# open_mod_links
# else
# return
# fi
# done
# else
# steam_deck_mods
# rc=$?
# [[ $rc -eq 1 ]] && return 1
# fi
# passed_mod_check > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
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(){
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(){
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")
2022-06-04 22:29:30 +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
printf "[DZGUI] Creating symlink for $mod\n"
2022-06-04 22:29:30 +02:00
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(){
echo "[DZGUI] Passed mod check"
2022-09-26 21:04:06 +02:00
echo "# Preparing symlinks"
2022-07-24 15:20:06 +02:00
stale_symlinks
legacy_symlinks
2022-06-04 22:29:30 +02:00
symlinks
2022-09-26 21:04:06 +02:00
echo "100"
2022-05-22 21:20:34 +02:00
}
2022-06-04 22:29:30 +02:00
connect(){
#TODO: sanitize/validate input
2022-07-18 10:58:38 +02:00
readarray -t qport_arr <<< "$qport_list"
if [[ -z ${qport_arr[@]} ]]; then
2022-09-24 17:42:13 +02:00
err "98: Failed to obtain query ports"
2022-07-18 10:58:38 +02:00
return
fi
2022-06-04 22:29:30 +02:00
ip=$(echo "$1" | awk -F"$separator" '{print $1}')
bid=$(echo "$1" | awk -F"$separator" '{print $2}')
2022-09-03 21:40:21 +02:00
if [[ $2 == "ip" ]]; then
2022-10-03 08:42:18 +02:00
fetch_mods_sa "$ip" > >(zenity --pulsate --progress --auto-close --no-cancel --width=500 2>/dev/null)
2022-09-03 21:40:21 +02:00
else
fetch_mods "$bid"
fi
2022-09-14 06:56:13 +02:00
if [[ $ret -eq 96 ]]; then
unset ret
return
fi
2022-06-04 22:29:30 +02:00
validate_mods
rc=$?
[[ $rc -eq 1 ]] && return
compare
if [[ -n $diff ]]; then
2022-10-07 06:30:09 +02:00
if [[ $auto_install -eq 1 ]]; then
auto_mod_install "$diff"
rc=$?
[[ $rc -eq 1 ]] && manual_mod_install
else
manual_mod_install
fi
2022-06-04 22:29:30 +02:00
else
2022-09-26 21:04:06 +02:00
passed_mod_check > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
2022-10-06 14:58:35 +02:00
launch
2022-06-04 22:29:30 +02:00
fi
}
2022-09-03 06:46:21 +02:00
fetch_mods(){
remote_mods=$(curl -s "$api" -H "Authorization: Bearer "$api_key"" -G -d filter[ids][whitelist]="$1" -d "sort=-players" \
| jq -r '.data[] .attributes .details .modIds[]')
}
fetch_mods_sa(){
2022-08-16 17:49:51 +02:00
sa_ip=$(echo "$1" | awk -F: '{print $1}')
for i in ${qport_arr[@]}; do
2022-07-18 10:58:38 +02:00
if [[ -n $(echo "$i" | awk -v ip=$ip '$0 ~ ip') ]]; then
sa_port=$(echo $i | awk -v ip=$ip -F$separator '$0 ~ ip {print $2}')
fi
done
echo "[DZGUI] Querying modlist on ${sa_ip}:${sa_port}"
2022-09-26 21:04:06 +02:00
echo "# Querying modlist on ${sa_ip}:${sa_port}"
2022-09-14 06:56:13 +02:00
local response=$(curl -Ls "https://dayzsalauncher.com/api/v1/query/$sa_ip/$sa_port")
local status=$(echo "$response" | jq '.status')
if [[ $status -eq 1 ]]; then
2022-09-26 21:04:06 +02:00
echo "100"
2022-09-24 17:42:13 +02:00
err "97: Failed to fetch modlist"
2022-10-03 17:04:13 +02:00
zenity --error --title="DZGUI" --width=500 --text="[ERROR] 97: Failed to fetch modlist" 2>/dev/null &&
2022-09-14 06:56:13 +02:00
ret=96
2022-07-18 10:58:38 +02:00
return
fi
2022-09-14 06:56:13 +02:00
remote_mods=$(echo "$response" | jq -r '.result.mods[].steamWorkshopId')
2022-08-16 17:49:51 +02:00
qport_arr=()
}
prepare_ip_list(){
ct=$(< "$1" jq '[.response.servers[]]|length')
for((i=0;i<$ct;i++));do
name=$(< $json jq --arg i $i -r '[.servers[]][($i|tonumber)].name')
addr=$(< $json jq --arg i $i -r '[.servers[]][($i|tonumber)].addr')
ip=$(echo "$addr" | awk -F: '{print $1}')
players=$(< $json jq --arg i $i -r '[.servers[]][($i|tonumber)].players')
max_players=$(< $json jq --arg i $i -r '[.servers[]][($i|tonumber)].max_players')
gameport=$(< $json jq --arg i $i -r '[.servers[]][($i|tonumber)].gameport')
ip_port=$(echo "$ip:$gameport")
time=$(< $json jq --arg i $i -r '[.servers[]][($i|tonumber)].gametype' | grep -oP '(?<!\d)\d{2}:\d{2}(?!\d)')
echo "$name"
echo "$ip_port"
echo "$players/$max_players"
echo "$time"
done
}
ip_table(){
while true; do
sel=$(prepare_ip_list "$meta_file" | zenity --width 1200 --height 800 --list --column=Name --column=IP --column=Players --column=Gametime --print-column=2 --separator=%% 2>/dev/null)
if [[ $? -eq 1 ]]; then
return_from_table=1
return
fi
if [[ -z $sel ]]; then
echo "No selection"
else
local gameport="$(echo "$sel" | awk -F: '{print $2}')"
2022-09-03 21:55:22 +02:00
local ip="$(echo "$sel" | awk -F: '{print $1}')"
2022-08-16 17:49:51 +02:00
local addr=$(< $json jq -r --arg gameport $gameport '.servers[]|select(.gameport == ($gameport|tonumber)).addr')
local qport=$(echo "$addr" | awk -F: '{print $2}')
local sa_ip=$(echo "$ip:$gameport%%$qport")
qport_list="$sa_ip"
2022-09-03 21:40:21 +02:00
connect "$sel" "ip"
2022-08-16 17:49:51 +02:00
fi
done
}
fetch_ip_metadata(){
local meta_file=$(mktemp)
source $config_file
url="https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100\gameaddr\\$ip&key=$steam_api"
curl -Ls "$url" > $meta_file
json=$(mktemp)
< $meta_file jq '.response' > $json
res=$(< $meta_file jq -er '.response.servers[]' 2>/dev/null)
if [[ ! $? -eq 0 ]]; then
2022-09-24 17:42:13 +02:00
warn "[ERROR] 96: Failed to retrieve IP metadata. Check IP or API key and try again."
echo "[DZGUI] 96: Failed to retrieve IP metadata"
2022-08-16 17:49:51 +02:00
else
ip_table
fi
}
#TODO: local servers
#local_ip(){
#(^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)
#}
2022-10-03 08:42:18 +02:00
test_steam_api(){
local code=$(curl -ILs "https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100&limit=10&key=$steam_api" \
| grep -E "^HTTP")
[[ $code =~ 403 ]] && return 1
2022-10-03 08:42:18 +02:00
}
2022-08-16 17:49:51 +02:00
add_steam_api(){
2022-10-03 08:42:18 +02:00
[[ ! $(test_steam_api) ]] && 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"
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" 2>/dev/null
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
steam_api=$(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-03 08:42:18 +02:00
elif [[ ${#steam_api} -lt 32 ]] || [[ ! $(test_steam_api) ]]; then
2022-09-13 06:41:26 +02:00
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}$'
}
connect_by_ip(){
source $config_file
check_steam_api
2022-10-03 08:42:18 +02:00
[[ $? -eq 1 ]] && return
2022-08-16 17:49:51 +02:00
while true; do
2022-08-31 10:22:07 +02:00
if [[ $return_from_table -eq 1 ]]; then
return_from_table=0
return
fi
2022-10-02 02:26:21 +02:00
ip=$(zenity --entry --text="Enter server IP (omit port)" --title="DZGUI" 2>/dev/null)
2022-08-31 10:22:07 +02:00
[[ $? -eq 1 ]] && return
if validate_ip "$ip"; then
fetch_ip_metadata
else
continue
fi
2022-08-16 17:49:51 +02:00
done
}
2022-05-22 21:20:34 +02:00
fetch_mods(){
remote_mods=$(curl -s "$api" -H "Authorization: Bearer "$api_key"" -G -d filter[ids][whitelist]="$1" -d "sort=-players" \
| jq -r '.data[] .attributes .details .modIds[]')
2022-05-09 13:42:24 +02:00
}
2022-06-12 06:44:30 +02:00
query_defunct(){
max=${#modlist[@]}
concat(){
for ((i=0;i<$max;i++)); do
echo "publishedfileids[$i]=${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'
}
2022-10-06 14:50:37 +02:00
result=$(post | jq -r '.[].publishedfiledetails[] | select(.result==1) | "\(.file_size) \(.publishedfileid)"')
2022-10-08 04:50:47 +02:00
echo "$result" > /tmp/modsizes
2022-10-06 14:50:37 +02:00
readarray -t newlist <<< $(echo -e "$result" | awk '{print $2}')
2022-06-12 06:44:30 +02:00
}
2022-06-04 22:29:30 +02:00
validate_mods(){
url="https://steamcommunity.com/sharedfiles/filedetails/?id="
newlist=()
readarray -t modlist <<< $remote_mods
2022-06-12 06:44:30 +02:00
query_defunct
2022-06-04 22:29:30 +02:00
}
server_modlist(){
for i in "${newlist[@]}"; do
printf "$i\n"
done
}
compare(){
diff=$(comm -23 <(server_modlist | sort) <(installed_mods | sort))
}
installed_mods(){
ls -1 "$workshop_dir"
}
2022-05-09 13:42:24 +02:00
concat_mods(){
if [[ -z ${remote_mods[@]} ]]; then
return 1
else
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}')
2022-07-24 15:20:06 +02:00
encoded_id=$(encode $id)
link="@$encoded_id;"
echo -e "$link"
done | tr -d '\n' | perl -ple 'chop'
fi
2022-05-09 13:42:24 +02:00
}
launch(){
mods=$(concat_mods)
if [[ $debug -eq 1 ]]; then
2022-10-07 12:19:09 +02:00
launch_options="steam -applaunch $aid -connect=$ip -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-07-24 15:20:06 +02:00
zenity --question --title="DZGUI" --ok-label="Write to file" --cancel-label="Back"\
--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"
2022-08-14 04:20:35 +02:00
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
2022-06-13 03:16:03 +02:00
echo "[DZGUI] All OK. Launching DayZ"
2022-08-14 11:10:00 +02:00
zenity --width 500 --title="DZGUI" --info --text="Launch conditions satisfied.\nDayZ will now launch after clicking [OK]." 2>/dev/null
2022-05-09 13:42:24 +02:00
steam -applaunch $aid -connect=$ip -nolauncher -nosplash -skipintro -name=$name \"-mod=$mods\"
exit
fi
2022-06-15 12:32:10 +02:00
one_shot_launch=0
}
browser(){
if [[ -n "$BROWSER" ]]; then
"$BROWSER" "$1" 2>/dev/null
else
xdg-open "$1" 2>/dev/null
fi
2022-05-09 13:42:24 +02:00
}
2022-06-04 22:29:30 +02:00
report_bug(){
2022-06-15 12:32:10 +02:00
echo "[DZGUI] Opening issues page in browser"
if [[ $is_steam_deck -eq 1 ]]; then
2022-09-14 06:56:13 +02:00
steam steam://openurl/"$issues_url" 2>/dev/null
2022-06-15 12:32:10 +02:00
elif [[ $is_steam_deck -eq 0 ]]; then
2022-09-14 06:56:13 +02:00
browser "$issues_url" 2>/dev/null &
2022-06-15 12:32:10 +02:00
fi
}
help_file(){
echo "[DZGUI] Opening help file in browser"
if [[ $is_steam_deck -eq 1 ]]; then
steam steam://openurl/"$help_url" 2>/dev/null
elif [[ $is_steam_deck -eq 0 ]]; then
2022-07-24 15:20:06 +02:00
browser "$help_url" 2>/dev/null &
2022-06-15 12:32:10 +02:00
fi
2022-05-22 21:20:34 +02:00
}
set_mode(){
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
}
2022-07-24 15:20:06 +02:00
delete_by_id(){
new_whitelist="whitelist=\"$(echo "$whitelist" | sed "s/,$server_id$//;s/^$server_id,//;s/,$server_id,/,/")\""
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/whitelist=/ {print NR}' ${config_path}dztuirc.old)
awk -v "var=$new_whitelist" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > ${config_path}dztuirc
echo "[DZGUI] Removed $server_id from key 'whitelist'"
zenity --info --title="DZGUI" --text="Removed "$server_id" from:\n${config_path}dztuirc\nIf errors occur, you can restore the file:\n${config_path}dztuirc.old" 2>/dev/null
source $config_file
}
delete_or_connect(){
if [[ $delete -eq 1 ]]; then
server_name=$(echo "$sel" | awk -F"%%" '{print $1}')
server_id=$(echo "$sel" | awk -F"%%" '{print $2}')
zenity --question --text="Delete this server? \n$server_name"
if [[ $? -eq 0 ]]; then
delete_by_id $server_id
fi
else
2022-10-03 00:24:27 +02:00
#hotfix for bug #36
local lookup_ip=$(echo "$sel" | awk -F%% '{print $1}')
local lookup_id="$(echo "$sel" | awk -F%% '{print $2}')"
local qport=$(echo "$response" | jq --arg id $lookup_id '.data[]|select(.id==$id).attributes.portQuery')
qport_list="$lookup_ip%%$qport"
connect "$sel" "ip"
2022-07-24 15:20:06 +02:00
fi
}
2022-06-04 22:29:30 +02:00
populate(){
2022-05-22 21:20:34 +02:00
while true; do
2022-07-24 15:20:06 +02:00
if [[ $delete -eq 1 ]]; then
cols="--column="Server" --column="ID""
set_header "delete"
else
cols="--column="Server" --column="IP" --column="Players" --column="Gametime" --column="Status" --column="ID" --column="Ping""
set_header ${FUNCNAME[0]}
fi
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
2022-07-24 15:20:06 +02:00
delete_or_connect
return
2022-06-04 22:29:30 +02:00
fi
else
2022-07-24 15:20:06 +02:00
delete=0
2022-06-04 22:29:30 +02:00
return
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-09-24 17:42:13 +02:00
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)
awk -v d=$dir -F\" '/name/ {printf "%s\t%s\n", $2,d}' "$gamedir"/$d/meta.cpp
2022-10-07 06:30:09 +02:00
done | sort
2022-06-15 12:32:10 +02:00
fi
2022-06-04 22:29:30 +02:00
}
2022-07-24 15:20:06 +02:00
fetch_query_ports(){
qport_list=$(echo "$response" | jq -r '.data[] .attributes | "\(.ip):\(.port)%%\(.portQuery)"')
}
2022-06-04 22:29:30 +02:00
connect_to_fav(){
2022-06-15 12:32:10 +02:00
if [[ -n $fav ]]; then
one_shot_launch=1
query_api
2022-07-24 15:20:06 +02:00
fetch_query_ports
2022-06-15 12:32:10 +02:00
echo "[DZGUI] Attempting connection to $fav_label"
2022-10-03 00:24:27 +02:00
connect "$qport_list" "ip"
one_shot_launch=0
2022-06-15 12:32:10 +02:00
else
2022-09-24 17:42:13 +02:00
warn "93: No fav server configured"
2022-06-15 12:32:10 +02:00
fi
2022-06-04 22:29:30 +02:00
}
2022-07-18 10:58:38 +02:00
set_header(){
2022-10-07 06:30:09 +02:00
[[ $auto_install -eq 1 ]] && install_mode=auto
[[ $auto_install -eq 0 ]] && install_mode=manual
2022-07-24 15:20:06 +02:00
if [[ $1 == "delete" ]]; then
2022-10-07 06:30:09 +02:00
sel=$(cat $tmp | zenity $sd_res --list $cols --title="DZGUI" --text="DZGUI $version | Mode: $mode | Branch: $branch | Mods: $install_mode | Fav: $fav_label" \
2022-07-24 15:20:06 +02:00
--separator="$separator" --print-column=1,2 --ok-label="Delete" 2>/dev/null)
elif [[ $1 == "populate" ]]; then
2022-10-07 06:30:09 +02:00
sel=$(cat $tmp | zenity $sd_res --list $cols --title="DZGUI" --text="DZGUI $version | Mode: $mode | Branch: $branch | Mods: $install_mode | Fav: $fav_label" \
2022-07-18 10:58:38 +02:00
--separator="$separator" --print-column=2,6 2>/dev/null)
elif [[ $1 == "main_menu" ]]; then
2022-10-07 06:30:09 +02:00
sel=$(zenity $sd_res --list --title="DZGUI" --text="${news}DZGUI $version | Mode: $mode | Branch: $branch | Mods: $install_mode | Fav: $fav_label" \
2022-07-24 15:20:06 +02:00
--cancel-label="Exit" --ok-label="Select" --column="Select launch option" --hide-header "${items[@]}" 2>/dev/null)
2022-07-18 10:58:38 +02:00
fi
}
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
printf "[DZGUI] Toggled branch to '$branch'\n"
source $config_file
}
2022-08-04 21:14:56 +02:00
generate_log(){
cat <<-DOC
Version: $version
Branch: $branch
Whitelist: $whitelist
Path: $steam_path
Linux: $(uname -mrs)
Mods:
$(list_mods)
DOC
}
2022-10-07 09:26:39 +02:00
automods_prompt(){
cat <<- HERE
Auto-mod installation set to ON.
READ THIS FIRST:
With this setting on, DZGUI will attempt to download and prepare mods using Valve's steamcmd tool.
The first time this process is run, DZGUI will ask you to select a terminal emulator of your preference to spawn the installation routine. If you don't have a preference or don't know, you can pick any.
Installation will kick off in a separate window and may ask you for input such as your sudo password in order to install system packages and create the steamcmd user.
steamcmd itself will ask for your Steam credentials. This information is used directly by Valve's steamcmd tool to authenticate your account and let you download mods headlessly. steamcmd is an official program created by Valve and communicates only with their servers.
2022-10-07 12:19:09 +02:00
NOTE: it can take some time for large mods to download, and steamcmd will not inform you of activity until each one is finished downloading.
2022-10-07 09:26:39 +02:00
If your distribution is unsupported, you don't have enough disk space to stage all of the mods, or there are other problems, DZGUI will warn you and write a report to $HOME/.local/share/dzgui/helpers/SCMD.log. You can attach this file to a bug report.
HERE
}
2022-10-06 14:50:37 +02:00
toggle_automods(){
2022-10-07 09:26:39 +02:00
mv $config_file ${config_path}dztuirc.old
local nr=$(awk '/auto_install=/ {print NR}' ${config_path}dztuirc.old)
if [[ $auto_install == "1" ]]; then
auto_install="0"
else
auto_install="1"
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
printf "[DZGUI] Toggled auto-mod install to '$auto_install'\n"
source $config_file
2022-10-08 07:07:30 +02:00
local big_prompt
[[ $is_steam_deck -eq 1 ]] && big_prompt="--width=800"
[[ $auto_install == "1" ]] && zenity --info --text="$(automods_prompt)" $big_prompt
2022-10-06 14:50:37 +02:00
}
2022-10-07 06:30:09 +02:00
options_menu(){
2022-07-18 10:58:38 +02:00
debug_list=(
"Toggle branch"
2022-10-07 12:19:09 +02:00
"Toggle debug mode"
2022-08-04 21:14:56 +02:00
"Generate debug log"
2022-10-07 06:30:09 +02:00
"Toggle auto-mod install (experimental)"
2022-10-08 05:25:46 +02:00
"Set auto-mod staging directory [$staging_dir]"
2022-07-18 10:58:38 +02:00
)
2022-07-24 15:20:06 +02:00
debug_sel=$(zenity --list --width=1280 --height=800 --column="Options" --title="DZGUI" --hide-header "${debug_list[@]}" 2>/dev/null)
2022-07-18 10:58:38 +02:00
if [[ $debug_sel == "${debug_list[0]}" ]]; then
enforce_dl=1
2022-07-31 20:01:58 +02:00
toggle_branch &&
2022-07-18 10:58:38 +02:00
check_version
2022-08-04 21:14:56 +02:00
elif [[ $debug_sel == "${debug_list[1]}" ]]; then
2022-10-07 12:19:09 +02:00
toggle_debug
elif [[ $debug_sel == "${debug_list[2]}" ]]; then
2022-08-04 21:14:56 +02:00
source_script=$(realpath "$0")
source_dir=$(dirname "$source_script")
2022-08-05 21:32:29 +02:00
generate_log > "$source_dir/log"
2022-08-06 02:42:41 +02:00
printf "[DZGUI] Wrote log file to %s/log\n" "$source_dir"
zenity --info --width 500 --title="DZGUI" --text="Wrote log file to \n$source_dir/log" 2>/dev/null
2022-10-07 12:19:09 +02:00
elif [[ $debug_sel == "${debug_list[3]}" ]]; then
2022-10-06 14:50:37 +02:00
toggle_automods
2022-10-07 12:19:09 +02:00
elif [[ $debug_sel == "${debug_list[4]}" ]]; then
file_picker
2022-07-18 10:58:38 +02:00
fi
}
2022-07-24 15:20:06 +02:00
query_and_connect(){
query_api
parse_json
2022-07-24 15:20:06 +02:00
#TODO: create logger function
2022-10-03 08:42:18 +02:00
if [[ ! $delete -eq 1 ]]; then
echo "[DZGUI] Checking response time of servers"
create_array | zenity --width 500 --progress --pulsate --title="DZGUI" --auto-close 2>/dev/null
else
create_array
fi
2022-07-24 15:20:06 +02:00
rc=$?
if [[ $rc -eq 1 ]]; then
:
else
populate
fi
}
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-10-03 17:04:13 +02:00
local map_sel=$(echo "$maps" | 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
local local_ip=$(dig +short myip.opendns.com @resolver1.opendns.com)
fi
2022-09-12 16:55:30 +02:00
local url="http://ip-api.com/json/$local_ip"
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"
2022-09-13 06:41:26 +02:00
printf "Players online: %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
2022-09-14 06:22:14 +02:00
if [[ $res -eq 1 ]]; then
2022-09-12 16:55:30 +02:00
run(){
mkdir -p "$helpers_path"
2022-09-14 06:22:14 +02:00
echo "# Fetching new geolocation DB"
2022-09-12 16:55:30 +02:00
curl -Ls "$db_file" > "$gzip"
echo "# Extracting coordinates"
2022-09-14 06:56:13 +02:00
#force overwrite
gunzip -f "$gzip"
2022-09-12 16:55:30 +02:00
echo "# Preparing helper file"
curl -Ls "$km_helper_url" > "$km_helper"
2022-09-14 06:22:14 +02:00
chmod +x $km_helper
2022-09-12 16:55:30 +02:00
echo "100"
}
run > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
fi
}
choose_filters(){
2022-09-25 22:35:58 +02:00
if [[ $is_steam_deck -eq 0 ]]; then
sd_res="--width=1920 --height=1080"
fi
2022-10-03 17:04:13 +02:00
sels=$(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" False "Empty" False "Full" False "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
2022-10-03 17:04:13 +02:00
search=$(zenity --entry --text="Search (case insensitive)" --width=500 --title="DZGUI" 2>/dev/null | awk '{print tolower($0)}')
2022-09-12 16:55:30 +02:00
[[ -z $search ]] && { ret=97; return; }
fi
[[ -z $sels ]] && return
2022-09-27 03:40:05 +02:00
filters=$(echo "$sels" | sed 's/|/, /g;s/ (untick to select from map list)//')
2022-09-12 16:55:30 +02:00
echo "[DZGUI] Filters: $filters"
}
get_dist(){
local given_ip="$1"
2022-09-13 15:35:13 +02:00
local network="$(echo "$given_ip" | awk -F. '{OFS="."}{print $1"."$2}')"
local binary=$(grep -E "^$network\." $geo_file)
local three=$(echo $given_ip | awk -F. '{print $3}')
local host=$(echo $given_ip | awk -F. '{print $4}')
local res=$(echo "$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=$(echo "$res" | awk '{print $1}')
local remote_lon=$(echo "$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")
printf "%05.0f %s" "$dist" "km"
2022-09-12 16:55:30 +02:00
fi
}
prepare_filters(){
2022-09-14 06:22:14 +02:00
echo "# Filtering list"
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") ; }
[[ -n "$search" ]] && keyword_filter
strip_null
echo "100"
}
2022-09-23 12:52:22 +02:00
write_fifo(){
2022-09-25 22:24:08 +02:00
[[ -p $fifo ]] && rm $fifo
mkfifo $fifo
2022-09-23 12:52:22 +02:00
for((i=0;i<${#qport[@]};i++)); do
printf "%s\n%s\n%s\n%03d\n%03d\n%s\n%s:%s\n%s\n" "${map[$i]}" "${name[$i]}" "${gametime[$i]}" \
2022-09-25 22:24:08 +02:00
"${players[$i]}" "${max[$i]}" "$(get_dist ${addr[$i]})" "${addr[$i]}" "${gameport[$i]}" "${qport[$i]}" >> $fifo
2022-09-23 12:52:22 +02:00
done
}
2022-09-12 16:55:30 +02:00
munge_servers(){
if [[ ! "$sels" =~ "All maps" ]]; then
filter_maps > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
disabled+=("All maps")
fi
[[ $ret -eq 97 ]] && return
prepare_filters > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
if [[ $(echo "$response" | jq 'length') -eq 0 ]]; then
zenity --error --text="No matching servers" 2>/dev/null
return
fi
local addr=$(echo "$response" | jq -r '.[].addr' | awk -F: '{print $1}')
local gameport=$(echo "$response" | jq -r '.[].gameport')
local qport=$(echo "$response" | jq -r '.[].addr' | awk -F: '{print $2}')
2022-09-13 15:35:13 +02:00
#jq bug #1788, raw output cannot be used with ASCII
2022-09-14 15:10:27 +02:00
local name=$(echo "$response" | jq -a '.[].name' | sed 's/\\u[0-9a-z]\{4\}//g;s/^"//;s/"$//')
2022-09-12 16:55:30 +02:00
local players=$(echo "$response" | jq -r '.[].players')
local max=$(echo "$response" | jq -r '.[].max_players')
local map=$(echo "$response" | jq -r '.[].map|ascii_downcase')
local gametime=$(echo "$response" | jq -r '.[].gametype' | grep -oE '[0-9]{2}:[0-9]{2}$')
readarray -t qport <<< $qport
readarray -t gameport <<< $gameport
readarray -t addr <<< $addr
readarray -t name <<< $name
readarray -t players <<< $players
readarray -t map <<< $map
readarray -t max <<< $max
readarray -t gametime <<< $gametime
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=$!
2022-10-03 17:04:13 +02:00
local sel=$(zenity --text="$(pagination)" --title="DZGUI" --list --column=Map --column=Name --column=Gametime --column=Players --column=Max --column=Distance --column=IP --column=Qport $sd_res --print-column=7,8 --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
2022-09-23 12:52:22 +02:00
kill -9 $pid
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(){
[[ -f $debug_log ]] && rm $debug_log
if [[ -n $steam_api ]]; then
exists=true
else
exists=false
fi
key_len=${#steam_api}
first_char=${steam_api:0:1}
last_char=${steam_api:0-1}
debug_res=$(curl -Ls "https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100&limit=10&key=$steam_api")
debug_len=$(echo "$debug_res" | jq '[.response.servers[]]|length')
[[ -z $debug_len ]] && debug_len=0
cat <<-DOC > $debug_log
======START DEBUG======
Key exists: $exists
First char: $first_char
Last char: $last_char
Key length: $key_len
======Short query======
Expected: 10
Found: $debug_len
Response follows---->
$debug_res
======END DEBUG=======
DOC
}
2022-09-12 16:55:30 +02:00
server_browser(){
2022-09-13 06:41:26 +02:00
check_steam_api
2022-10-03 08:42:18 +02:00
[[ $? -eq 1 ]] && return
2022-09-12 16:55:30 +02:00
unset ret
file=$(mktemp)
local limit=20000
local url="https://api.steampowered.com/IGameServersService/GetServerList/v1/?filter=\appid\221100&limit=$limit&key=$steam_api"
2022-10-03 00:24:27 +02:00
check_geo_file
2022-09-12 16:55:30 +02:00
local_latlon
choose_filters
[[ -z $sels ]] && return
[[ $ret -eq 97 ]] && return
#TODO: some error handling here
2022-09-14 06:22:14 +02:00
fetch(){
echo "# Getting server list"
curl -Ls "$url" > $file
}
fetch > >(zenity --pulsate --progress --auto-close --width=500 2>/dev/null)
2022-09-12 16:55:30 +02:00
response=$(< $file jq -r '.response.servers')
2022-09-27 02:42:46 +02:00
total_servers=$(echo "$response" | jq 'length')
players_online=$(echo "$response" | jq '.[].players' | awk '{s+=$1}END{print s}')
2022-09-24 11:49:01 +02:00
debug_log="$HOME/.local/share/dzgui/DEBUG.log"
2022-10-03 00:24:27 +02:00
debug_servers
local sel=$(munge_servers)
if [[ -z $sel ]]; then
unset filters
unset search
ret=98
return
fi
local sel_ip=$(echo "$sel" | awk -F%% '{print $1}')
local sel_port=$(echo "$sel" | awk -F%% '{print $2}')
qport_list="$sel_ip%%$sel_port"
if [[ -n "$sel_ip" ]]; then
connect "$sel_ip" "ip"
2022-09-25 19:29:19 +02:00
else
2022-10-03 00:24:27 +02:00
return
2022-09-25 19:29:19 +02:00
fi
2022-09-12 16:55:30 +02:00
}
2022-07-24 15:20:06 +02:00
2022-09-29 19:54:39 +02:00
mods_disk_size(){
2022-10-07 06:30:09 +02:00
printf "Total size on disk: %s |" $(du -sh "$game_dir" | awk '{print $1}')
printf "Mods location: $steam_path/steamapps/workshop/content/221100"
2022-09-29 19:54:39 +02:00
}
2022-06-04 22:29:30 +02:00
main_menu(){
2022-07-24 15:20:06 +02:00
print_news
set_mode
2022-06-15 12:32:10 +02:00
if [[ -n $fav ]]; then
2022-10-03 17:04:13 +02:00
items[7]=" Change favorite server"
2022-06-15 12:32:10 +02:00
fi
2022-06-04 22:29:30 +02:00
while true; do
2022-07-18 10:58:38 +02:00
set_header ${FUNCNAME[0]}
2022-06-04 22:29:30 +02:00
rc=$?
if [[ $rc -eq 0 ]]; then
if [[ -z $sel ]]; then
warn "No item was selected."
2022-06-15 12:32:10 +02:00
elif [[ $sel == "${items[0]}" ]]; then
2022-10-03 17:04:13 +02:00
:
2022-06-15 12:32:10 +02:00
elif [[ $sel == "${items[1]}" ]]; then
2022-10-03 17:04:13 +02:00
server_browser
2022-06-15 12:32:10 +02:00
elif [[ $sel == "${items[2]}" ]]; then
2022-10-03 17:04:13 +02:00
query_and_connect
2022-06-15 12:32:10 +02:00
elif [[ $sel == "${items[3]}" ]]; then
2022-10-03 17:04:13 +02:00
connect_to_fav
2022-06-15 12:32:10 +02:00
elif [[ $sel == "${items[4]}" ]]; then
2022-10-03 17:04:13 +02:00
:
2022-08-16 17:49:51 +02:00
elif [[ $sel == "${items[5]}" ]]; then
2022-10-03 17:04:13 +02:00
connect_by_ip
2022-10-03 08:42:18 +02:00
elif [[ $sel == "${items[6]}" ]]; then
2022-10-03 17:04:13 +02:00
add_by_id
elif [[ $sel == "${items[7]}" ]]; then
add_by_fav
elif [[ $sel == "${items[8]}" ]]; then
2022-07-24 15:20:06 +02:00
delete=1
query_and_connect
2022-10-03 17:04:13 +02:00
elif [[ $sel == "${items[9]}" ]]; then
:
elif [[ $sel == "${items[10]}" ]]; then
2022-09-29 19:54:39 +02:00
list_mods | sed 's/\t/\n/g' | zenity --list --column="Mod" --column="Symlink" \
--title="DZGUI" $sd_res --text="$(mods_disk_size)" \
--print-column="" 2>/dev/null
2022-10-03 17:04:13 +02:00
elif [[ $sel == "${items[11]}" ]]; then
2022-09-12 16:55:30 +02:00
report_bug
2022-10-07 06:30:09 +02:00
elif [[ $sel == "${items[12]}" ]]; then
2022-09-12 16:55:30 +02:00
help_file
2022-10-07 06:30:09 +02:00
elif [[ $sel == "${items[13]}" ]]; then
2022-09-12 16:55:30 +02:00
changelog | zenity --text-info $sd_res --title="DZGUI" 2>/dev/null
2022-10-07 06:30:09 +02:00
elif [[ $sel == "${items[14]}" ]]; then
options_menu
2022-10-07 12:19:09 +02:00
main_menu
return
2022-06-04 22:29:30 +02:00
else
warn "This feature is not yet implemented."
fi
2022-05-22 21:20:34 +02:00
else
2022-06-04 22:29:30 +02:00
return
2022-05-22 21:20:34 +02:00
fi
done
}
2022-08-11 00:59:29 +02:00
page_through(){
2022-08-12 02:52:07 +02:00
list_response=$(curl -s "$page")
list=$(echo "$list_response" | jq -r '.data[] .attributes | "\(.name)\t\(.ip):\(.port)\t\(.players)/\(.maxPlayers)\t\(.details.time)\t\(.status)\t\(.id)"')
2022-08-11 00:59:29 +02:00
idarr+=("$list")
parse_json
}
2022-05-22 21:20:34 +02:00
parse_json(){
2022-08-12 02:52:07 +02:00
page=$(echo "$list_response" | jq -r '.links.next?')
2022-08-14 18:22:21 +02:00
if [[ $first_entry -eq 1 ]]; then
local list=$(echo "$list_response" | jq -r '.data[] .attributes | "\(.name)\t\(.ip):\(.port)\t\(.players)/\(.maxPlayers)\t\(.details.time)\t\(.status)\t\(.id)"')
2022-08-14 18:22:21 +02:00
idarr+=("$list")
first_entry=0
fi
2022-08-11 00:59:29 +02:00
if [[ "$page" != "null" ]]; then
local list=$(echo "$list_response" | jq -r '.data[] .attributes | "\(.name)\t\(.ip):\(.port)\t\(.players)/\(.maxPlayers)\t\(.details.time)\t\(.status)\t\(.id)"')
2022-08-11 00:59:29 +02:00
idarr+=("$list")
page_through
else
printf "%s\n" "${idarr[@]}" > $tmp
idarr=()
fetch_query_ports
fi
2022-05-09 13:42:24 +02:00
}
check_ping(){
2022-07-24 15:20:06 +02:00
ping_ip=$(echo "$1" | awk -F'\t' '{print $2}' | awk -F: '{print $1}')
ms=$(ping -c 1 -W 1 "$ping_ip" | awk -Ftime= '/time=/ {print $2}')
if [[ -z $ms ]]; then
echo "Timeout"
else
echo "$ms"
fi
2022-05-22 21:20:34 +02:00
}
2022-05-09 13:42:24 +02:00
create_array(){
rows=()
2022-05-09 13:42:24 +02:00
list=$(cat $tmp)
#TODO: improve error handling for null values
2022-05-29 08:33:14 +02:00
lc=1
2022-05-09 13:42:24 +02:00
while read line; do
name=$(echo "$line" | awk -F'\t' '{print $1}')
2022-05-22 21:20:34 +02:00
#truncate names
2022-06-15 12:32:10 +02:00
if [[ $(echo "$name" | wc -m) -gt 50 ]]; then
2022-08-10 03:08:27 +02:00
name="$(echo "$name" | awk '{print substr($0,1,50) "..."}')"
2022-05-09 13:42:24 +02:00
else
:
fi
ip=$(echo "$line" | awk -F'\t' '{print $2}')
players=$(echo "$line" | awk -F'\t' '{print $3}')
2022-06-15 12:32:10 +02:00
time=$(echo "$line" | awk -F'\t' '{print $4}')
stat=$(echo "$line" | awk -F'\t' '{print $5}')
2022-06-04 22:29:30 +02:00
2022-05-22 21:20:34 +02:00
#yad only
#[[ $stat == "online" ]] && stat="<span color='#77ff33'>online</span>" || :
2022-06-04 22:29:30 +02:00
2022-05-09 13:42:24 +02:00
#TODO: probe offline return codes
2022-06-15 12:32:10 +02:00
id=$(echo "$line" | awk -F'\t' '{print $6}')
2022-05-29 08:33:14 +02:00
tc=$(awk 'END{print NR}' $tmp)
2022-07-24 15:20:06 +02:00
if [[ $delete -eq 1 ]]; then
declare -g -a rows=("${rows[@]}" "$name" "$id")
else
echo "# Checking ping: $lc/$tc"
ping=$(check_ping "$line")
declare -g -a rows=("${rows[@]}" "$name" "$ip" "$players" "$time" "$stat" "$id" "$ping")
fi
2022-05-29 08:33:14 +02:00
let lc++
done <<< "$list"
2022-05-29 08:33:14 +02:00
for i in "${rows[@]}"; do echo -e "$i"; done > $tmp
2022-05-09 13:42:24 +02:00
}
2022-06-04 22:29:30 +02:00
set_fav(){
#TODO: test API key here and return errors
2022-08-12 02:52:07 +02:00
echo "[DZGUI] Querying favorite server"
2022-06-12 06:44:30 +02:00
query_api
2022-06-04 22:29:30 +02:00
fav_label=$(curl -s "$api" -H "Authorization: Bearer "$api_key"" -G -d "filter[game]=$game" -d "filter[ids][whitelist]=$fav" \
| jq -r '.data[] .attributes .name')
2022-06-15 12:32:10 +02:00
if [[ -z $fav_label ]]; then
fav_label=null
2022-06-12 06:44:30 +02:00
fi
echo "[DZGUI] Setting favorite server to '$fav_label'"
2022-06-04 22:29:30 +02:00
}
2022-06-15 12:32:10 +02:00
check_unmerged(){
if [[ -f ${config_path}.unmerged ]]; then
printf "[DZGUI] Found new config format, merging changes\n"
merge_config
rm ${config_path}.unmerged
fi
}
merge_config(){
source $config_file
mv $config_file ${config_path}dztuirc.old
2022-10-07 09:26:39 +02:00
[[ -z $staging_dir ]] && staging_dir="/tmp"
2022-06-15 12:32:10 +02:00
write_config > $config_file
printf "[DZGUI] Wrote new config file to %sdztuirc\n" $config_path
2022-08-05 22:26:00 +02:00
zenity --info --width 500 --title="DZGUI" --text="Wrote new config format to \n${config_path}dztuirc\nIf errors occur, you can restore the file:\n${config_path}dztuirc.old" 2>/dev/null
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
2022-10-03 17:04:13 +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"
2022-08-05 22:26:00 +02:00
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
changelog | zenity --text-info $sd_res --title="DZGUI" 2>/dev/null
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-09-24 17:42:13 +02:00
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(){
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
upstream=$(curl -Ls "$version_url" | awk -F= '/^version=/ {print $2}')
}
enforce_dl(){
2022-10-03 17:04:13 +02:00
download_new_version > >(zenity --progress --pulsate --auto-close --no-cancel --width=500)
}
2022-10-03 17:04:13 +02:00
prompt_dl(){
2022-10-06 15:00:13 +02:00
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"
download_new_version > >(zenity --progress --pulsate --auto-close --no-cancel --width=500)
fi
}
2022-06-04 22:29:30 +02:00
check_version(){
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-03 17:15:09 +02:00
[[ ! -d "$freedesktop_path" ]] && freedesktop_dirs
2022-06-04 22:29:30 +02:00
if [[ $version == $upstream ]]; then
2022-06-15 12:32:10 +02:00
check_unmerged
2022-06-04 22:29:30 +02:00
else
2022-10-08 13:09:33 +02:00
echo "100"
echo "[DZGUI] Upstream ($upstream) != local ($version)"
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(){
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
echo "[DZGUI] Setting architecture to 'Steam Deck'"
else
is_steam_deck=0
echo "[DZGUI] Setting architecture to 'desktop'"
fi
}
2022-06-04 22:29:30 +02:00
add_by_id(){
2022-08-04 21:14:56 +02:00
#FIXME: prevent redundant creation of existent IDs (for neatness)
2022-06-15 12:32:10 +02:00
while true; do
id=$(zenity --entry --text="Enter server ID" --title="DZGUI" 2>/dev/null)
rc=$?
if [[ $rc -eq 1 ]]; then
return
else
if [[ ! $id =~ ^[0-9]+$ ]]; then
zenity --warning --title="DZGUI" --text="Invalid ID" 2>/dev/null
else
new_whitelist="whitelist=\"$whitelist,$id\""
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/whitelist=/ {print NR}' ${config_path}dztuirc.old)
awk -v "var=$new_whitelist" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > ${config_path}dztuirc
echo "[DZGUI] Added $id to key 'whitelist'"
zenity --info --title="DZGUI" --text="Added "$id" to:\n${config_path}dztuirc\nIf errors occur, you can restore the file:\n${config_path}dztuirc.old" 2>/dev/null
source $config_file
return
fi
fi
done
}
2022-06-22 15:33:52 +02:00
toggle_debug(){
mv $config_file ${config_path}dztuirc.old
nr=$(awk '/debug=/ {print NR}' ${config_path}dztuirc.old)
if [[ $debug -eq 1 ]]; then
debug=0
else
debug=1
fi
flip_debug="debug=\"$debug\""
awk -v "var=$flip_debug" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > $config_file
printf "[DZGUI] Toggled debug flag to '$debug'\n"
source $config_file
}
setup(){
if [[ -n $fav ]]; then
set_fav
2022-10-03 17:04:13 +02:00
items[7]=" Change favorite server"
2022-06-22 15:33:52 +02:00
fi
}
2022-07-24 15:20:06 +02:00
check_map_count(){
count=1048576
2022-08-16 17:49:51 +02:00
echo "[DZGUI] Checking system map count"
2022-08-06 03:22:12 +02:00
if [[ $(sysctl -q vm.max_map_count | awk -F"= " '{print $2}') -lt $count ]]; then
2022-10-08 13:09:33 +02:00
echo "100"
2022-08-05 21:58:59 +02:00
map_warning=$(zenity --question --width 500 --title="DZGUI" --text "System map count must be $count or higher to run DayZ with Wine. Increase map count and make this change permanent? (will prompt for sudo password)" 2>/dev/null)
2022-07-24 15:20:06 +02:00
if [[ $? -eq 0 ]]; then
pass=$(zenity --password)
sudo -S <<< "$pass" sh -c "echo 'vm.max_map_count=1048576' > /etc/sysctl.d/dayz.conf"
echo ""
fi
fi
}
2022-06-15 12:32:10 +02:00
add_by_fav(){
2022-06-04 22:29:30 +02:00
while true; do
2022-06-15 12:32:10 +02:00
fav_id=$(zenity --entry --text="Enter server ID" --title="DZGUI" 2>/dev/null)
2022-06-04 22:29:30 +02:00
rc=$?
if [[ $rc -eq 1 ]]; then
return
else
2022-06-15 12:32:10 +02:00
if [[ ! $fav_id =~ ^[0-9]+$ ]]; then
2022-06-04 22:29:30 +02:00
zenity --warning --title="DZGUI" --text="Invalid ID"
else
2022-06-15 12:32:10 +02:00
new_fav="fav=\"$fav_id\""
2022-06-04 22:29:30 +02:00
mv $config_file ${config_path}dztuirc.old
2022-06-15 12:32:10 +02:00
nr=$(awk '/fav=/ {print NR}' ${config_path}dztuirc.old)
awk -v "var=$new_fav" -v "nr=$nr" 'NR==nr {$0=var}{print}' ${config_path}dztuirc.old > ${config_path}dztuirc
echo "[DZGUI] Added $fav_id to key 'fav'"
zenity --info --title="DZGUI" --text="Added "$fav_id" to:\n${config_path}dztuirc\nIf errors occurred, you can restore the file:\n${config_path}dztuirc.old" 2>/dev/null
2022-06-04 22:29:30 +02:00
source $config_file
2022-06-15 12:32:10 +02:00
set_fav
2022-10-03 17:04:13 +02:00
items[7]=" Change favorite server"
2022-06-04 22:29:30 +02:00
return
fi
fi
done
}
2022-08-13 15:00:35 +02:00
#cleanup(){
# rm $config_path/.lockfile
#}
lock(){
if [[ ! -f $config_path/.lockfile ]]; then
touch $config_path/.lockfile
fi
pid=$(cat $config_path/.lockfile)
ps -p $pid -o pid= >/dev/null 2>&1
res=$?
if [[ $res -eq 0 ]]; then
echo "[DZGUI] Already running ($pid)"
2022-10-03 17:04:13 +02:00
zenity --info --text="DZGUI already running (pid $pid)" --width=500 --title="DZGUI" 2>/dev/null
2022-08-13 15:00:35 +02:00
exit
elif [[ $pid == $$ ]]; then
:
else
echo $$ > $config_path/.lockfile
fi
}
2022-10-07 06:30:09 +02:00
fetch_scmd_helper(){
2022-10-08 05:25:46 +02:00
mkdir -p "$helpers_path"
2022-10-07 09:32:26 +02:00
curl -Ls "$scmd_url" > "$helpers_path/scmd.sh"
2022-10-07 09:46:26 +02:00
chmod +x "$helpers_path/scmd.sh"
2022-10-08 05:09:08 +02:00
[[ ! -f "$helpers_path/d.html" ]] && curl -Ls "$notify_url" > "$helpers_path/d.html"
[[ ! -f "$helpers_path/d.webp" ]] && curl -Ls "$notify_img_url" > "$helpers_path/d.webp"
2022-10-07 06:30:09 +02:00
}
2022-09-24 11:49:01 +02:00
initial_setup(){
echo "# Initial setup"
2022-06-15 12:32:10 +02:00
run_depcheck
check_architecture
2022-08-05 22:28:52 +02:00
check_version
2022-07-24 15:20:06 +02:00
check_map_count
2022-05-22 21:20:34 +02:00
config
2022-10-07 09:26:39 +02:00
fetch_scmd_helper
2022-06-15 12:32:10 +02:00
run_varcheck
2022-06-22 15:33:52 +02:00
init_items
setup
2022-09-24 11:49:01 +02:00
echo "100"
}
main(){
2022-09-27 02:42:46 +02:00
lock
2022-10-03 17:04:13 +02:00
initial_setup > >(zenity --pulsate --progress --auto-close --title="DZGUI" --width=500 2>/dev/null)
2022-05-22 21:20:34 +02:00
main_menu
2022-09-23 12:52:22 +02:00
#cruddy handling for steam forking
[[ $? -eq 1 ]] && pkill -f dzgui.sh
2022-05-09 13:42:24 +02:00
}
main
2022-08-12 02:52:07 +02:00
#trap cleanup EXIT