mirror of
https://github.com/aclist/dztui.git
synced 2024-12-29 13:52:03 +01:00
Major version bump
This commit is contained in:
parent
3ddf1b2ca5
commit
35122cf723
7 changed files with 485 additions and 709 deletions
27
changelog.md
27
changelog.md
|
@ -4,8 +4,33 @@
|
||||||
- Clean up logging
|
- Clean up logging
|
||||||
- Custom query API
|
- Custom query API
|
||||||
- Standardize dialogs
|
- Standardize dialogs
|
||||||
|
- Validate BM API key
|
||||||
|
|
||||||
## [3.0.7] 2022-11-025
|
## [3.1.0] 2022-12-03
|
||||||
|
### Added
|
||||||
|
- Recent connect history
|
||||||
|
- Simple, OS-agnostic automod installation
|
||||||
|
- Track local mod versions
|
||||||
|
- Force update local mods option
|
||||||
|
- Added python to dependencies
|
||||||
|
- File-picker driven path discovery on initial setup
|
||||||
|
### Dropped
|
||||||
|
- Headless mod installation
|
||||||
|
- Drop server ID field requirement on initial setup
|
||||||
|
### Changed
|
||||||
|
- Clean up main menu options
|
||||||
|
- Enforce Steam API key on initial setup
|
||||||
|
- More accurate path discovery on initial setup
|
||||||
|
- Add thousands separator to player counts in server browser
|
||||||
|
### Fixed
|
||||||
|
- Initial setup dialog causing early crash
|
||||||
|
- Improved error handling on initial setup to avoid malformed config files
|
||||||
|
- Delete server menu not clearing when returning to main menu
|
||||||
|
- Handle whitelist deletion when only one entry present
|
||||||
|
- Include path to drives under /run in path discovery
|
||||||
|
- Use Steam-safe local zenity version
|
||||||
|
|
||||||
|
## [3.0.7] 2022-11-25
|
||||||
### Fixed
|
### Fixed
|
||||||
- Hotfix for server reporting multiple versions of same mod
|
- Hotfix for server reporting multiple versions of same mod
|
||||||
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
<html>
|
|
||||||
<body style="background-color:black">
|
|
||||||
<img style="position:absolute;inset:0;image-orientation:from-image" src="d.webp" width="364" height="384"></img>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
BIN
helpers/d.webp
BIN
helpers/d.webp
Binary file not shown.
Before Width: | Height: | Size: 2.9 MiB |
361
helpers/scmd.sh
361
helpers/scmd.sh
|
@ -1,361 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
conf=$HOME/.config/dztui/dztuirc
|
|
||||||
source $conf
|
|
||||||
[[ -z $staging_dir ]] && staging_dir="/tmp"
|
|
||||||
aid=221100
|
|
||||||
steamcmd_user=steam
|
|
||||||
workshop_dir="$steam_path/steamapps/workshop/content/$aid"
|
|
||||||
helpers_path="$HOME/.local/share/dzgui/helpers"
|
|
||||||
|
|
||||||
log(){
|
|
||||||
printf "$(tput setaf 3)[INFO]$(tput sgr0) %s\n" "$1"
|
|
||||||
}
|
|
||||||
pass(){
|
|
||||||
printf "$(tput setaf 2)[PASS]$(tput sgr0) %s\n" "$1"
|
|
||||||
}
|
|
||||||
fail(){
|
|
||||||
printf "$(tput setaf 1)[FAIL]$(tput sgr0) %s\n" "$1"
|
|
||||||
}
|
|
||||||
steamcmd_modlist(){
|
|
||||||
printf "force_install_dir %s\n" "$staging_dir"
|
|
||||||
printf "login %s\n" "$steam_username"
|
|
||||||
for i in "${ids[@]}"; do
|
|
||||||
printf "workshop_download_item %s %s validate\n" $aid $i
|
|
||||||
done
|
|
||||||
printf "quit"
|
|
||||||
}
|
|
||||||
move_files(){
|
|
||||||
printf "\n"
|
|
||||||
log "Moving mods from $staging_dir to $workshop_dir"
|
|
||||||
if [[ $staging_dir == "/tmp" ]]; then
|
|
||||||
sudo chown -R $USER:$gid "$staging_dir"/steamapps
|
|
||||||
fi
|
|
||||||
cp -R "$staging_dir"/steamapps/workshop/content/$aid/* "$workshop_dir"
|
|
||||||
if [[ $dist == "steamos" ]]; then
|
|
||||||
rm -rf "$staging_dir"/steamapps
|
|
||||||
else
|
|
||||||
sudo rm -rf "$staging_dir"/steamapps
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
#tutorial(){
|
|
||||||
#cat <<- HERE
|
|
||||||
#
|
|
||||||
#INSTRUCTIONS
|
|
||||||
#
|
|
||||||
#Keep this window adjacent to your terminal as a guide.
|
|
||||||
#
|
|
||||||
#1. In the steamcmd prompt, enter "login [id] [pass] [2FA]" (if applicable)
|
|
||||||
#and type Enter. E.g., if the user is Billy, pass is Banana, and 2FA token is 777:
|
|
||||||
#
|
|
||||||
#login Billy Banana 777 [Enter]
|
|
||||||
#
|
|
||||||
#2. Then enter: runscript /tmp/mods.txt and type Enter
|
|
||||||
#
|
|
||||||
#3. The auto-mod process will begin to headlessly download the mods.
|
|
||||||
#
|
|
||||||
#Valve uses a long-lived token to cache credentials,
|
|
||||||
#so you may be able to simply type [id] and "quit"
|
|
||||||
#on subsequent invocations, but it expires after some time.
|
|
||||||
#HERE
|
|
||||||
#}
|
|
||||||
#ctdw(){
|
|
||||||
# for((i=3;i>0;i--)); do
|
|
||||||
# printf "[INFO] Downloading mods in %i\r" "$i"
|
|
||||||
# sleep 1s
|
|
||||||
# done
|
|
||||||
#}
|
|
||||||
test_dir(){
|
|
||||||
if [[ $dist == "steamos" ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
sudo -u steam test -w "$staging_dir"
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 1 ]]; then
|
|
||||||
fail "User '$steamcmd_user' does not have write access to $staging_dir. Reverting to /tmp"
|
|
||||||
staging_dir="/tmp"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
auto_mod_download(){
|
|
||||||
while true; do
|
|
||||||
read -p 'Enter Steam login name: ' steam_username
|
|
||||||
[[ -z $steam_username ]] && { fail "Username can't be empty"; continue; }
|
|
||||||
[[ -n $steam_username ]] && break
|
|
||||||
done
|
|
||||||
test_dir
|
|
||||||
if [[ -d "$staging_dir/steamapps" ]]; then
|
|
||||||
log "Sanitizing $staging_dir"
|
|
||||||
if [[ $staging_dir == "/tmp" ]]; then
|
|
||||||
sudo chown -R $USER:$gid "$staging_dir"/steamapps
|
|
||||||
fi
|
|
||||||
if [[ $dist == "steamos" ]]; then
|
|
||||||
rm -rf "$staging_dir"/steamapps
|
|
||||||
else
|
|
||||||
sudo rm -rf "$staging_dir"/steamapps
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
tput civis
|
|
||||||
[[ ${#ids[@]} -gt 1 ]] && s=s
|
|
||||||
tput cnorm
|
|
||||||
log "Staging dir is $staging_dir"
|
|
||||||
steamcmd_modlist > "/tmp/mods.txt"
|
|
||||||
log "Preparing to download ${#ids[@]} mod$s. This may take some time. Abort with Ctrl+c."
|
|
||||||
if [[ $dist == "steamos" ]]; then
|
|
||||||
$steamcmd_path +runscript /tmp/mods.txt
|
|
||||||
else
|
|
||||||
sudo -iu $steamcmd_user bash -c "$steamcmd_path +runscript /tmp/mods.txt"
|
|
||||||
fi
|
|
||||||
rc=$?
|
|
||||||
rm "/tmp/mods.txt"
|
|
||||||
if [[ $rc -eq 0 ]]; then
|
|
||||||
move_files
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
find_steam_cmd(){
|
|
||||||
for i in "/home/steam" "/usr/bin" "/usr/local/bin" "/usr/games"; do
|
|
||||||
if [[ -f "$i/steamcmd" ]]; then
|
|
||||||
steamcmd_path="$i/steamcmd"
|
|
||||||
pass "Found steamcmd: $steamcmd_path"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fail "Failed to find steamcmd"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
create_user(){
|
|
||||||
log "Creating steamcmd user"
|
|
||||||
sudo useradd -m steam
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 0 ]]; then
|
|
||||||
log "Set a password for the headless steamcmd user"
|
|
||||||
sudo passwd steam
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
check_user(){
|
|
||||||
id $steamcmd_user &>/dev/null
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 1 ]]; then
|
|
||||||
fail "steamcmd user missing"
|
|
||||||
create_user
|
|
||||||
rc=$?
|
|
||||||
[[ $rc -eq 1 ]] && return 1
|
|
||||||
else
|
|
||||||
pass "Found user: $steamcmd_user"
|
|
||||||
fi
|
|
||||||
while true; do
|
|
||||||
local stat=$(sudo passwd $steamcmd_user --status | awk '{print $2}')
|
|
||||||
if
|
|
||||||
[[ $stat == "L" ]] || [[ $stat == "NP" ]]; then
|
|
||||||
fail "steamcmd user has a locked or empty password"
|
|
||||||
sudo passwd $steamcmd_user
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
}
|
|
||||||
generic_install(){
|
|
||||||
fail "Unrecognized distro: $dist."
|
|
||||||
log "Please report this upstream for whitelisting and attach your SCMD.log"
|
|
||||||
log "Location: $helpers_path/SCMD.log"
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
fedora_install(){
|
|
||||||
#TODO
|
|
||||||
:
|
|
||||||
}
|
|
||||||
#ubuntu related
|
|
||||||
# dep: debconf
|
|
||||||
# Debian configuration management system
|
|
||||||
#
|
|
||||||
# dep: debconf (>= 0.5)
|
|
||||||
# Debian configuration management system
|
|
||||||
# or debconf-2.0
|
|
||||||
# virtual package provided by cdebconf, cdebconf-udeb, debconf
|
|
||||||
#
|
|
||||||
# dep: libc6 (>= 2.12)
|
|
||||||
# GNU C Library: Shared libraries
|
|
||||||
# also a virtual package provided by libc6-udeb
|
|
||||||
#
|
|
||||||
# dep: libstdc++6
|
|
||||||
# GNU Standard C++ Library v3
|
|
||||||
#
|
|
||||||
# sug: steam
|
|
||||||
# Valve's Steam digital software delivery system
|
|
||||||
#
|
|
||||||
deb_install(){
|
|
||||||
check_user
|
|
||||||
rc=$?
|
|
||||||
[[ $rc -eq 1 ]] && return 1
|
|
||||||
find_steam_cmd
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 1 ]]; then
|
|
||||||
log "Installing distribution steamcmd packages"
|
|
||||||
sudo add-apt-repository -y multiverse
|
|
||||||
sudo apt install -y software-properties-common
|
|
||||||
sudo dpkg --add-architecture i386
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install -y steamcmd
|
|
||||||
find_steam_cmd
|
|
||||||
fi
|
|
||||||
dpkg -s lib32gcc-s1 1>/dev/null
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 1 ]]; then
|
|
||||||
fail "Missing deps: lib32-gcc-libs"
|
|
||||||
sudo apt install -y lib32gcc-s1
|
|
||||||
else
|
|
||||||
pass "Found deps: lib32-gcc-libs"
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
|
||||||
deck_install(){
|
|
||||||
pacman -Qi lib32-gcc-libs 2>/dev/null 1>&2
|
|
||||||
rc=$?
|
|
||||||
[[ ! $rc -eq 0 ]] && return 1
|
|
||||||
if [[ ! -f $HOME/.local/share/dzgui/helpers/steamcmd/steamcmd.sh ]]; then
|
|
||||||
local tarball="steamcmd_linux.tar.gz"
|
|
||||||
mkdir -p $HOME/.local/share/dzgui/helpers/steamcmd
|
|
||||||
curl -Ls "https://steamcdn-a.akamaihd.net/client/installer/$tarball" > $HOME/.local/share/dzgui/helpers/steamcmd/$tarball
|
|
||||||
$(cd $HOME/.local/share/dzgui/helpers/steamcmd; tar xvf $tarball)
|
|
||||||
fi
|
|
||||||
steamcmd_path="$HOME/.local/share/dzgui/helpers/steamcmd/steamcmd.sh"
|
|
||||||
}
|
|
||||||
arch_install(){
|
|
||||||
check_user
|
|
||||||
rc=$?
|
|
||||||
[[ $rc -eq 1 ]] && return 1
|
|
||||||
find_steam_cmd
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 1 ]]; then
|
|
||||||
log "Checking prerequisites"
|
|
||||||
for i in makepkg git; do
|
|
||||||
if [[ ! $(command -v $i) ]]; then
|
|
||||||
fail "Missing package: $i"
|
|
||||||
info "Script will fetch build tools now. Partial upgrades on Arch Linux are discouraged, so triggering a full update.\n
|
|
||||||
Type any key to proceed."
|
|
||||||
read -n1 key
|
|
||||||
case $key in
|
|
||||||
*) sudo pacman -Syu base-devel git lib32-gcc-libs --noconfirm
|
|
||||||
esac
|
|
||||||
break
|
|
||||||
else
|
|
||||||
pass "Found deps: $i"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
log "Installing steamcmd from distribution"
|
|
||||||
[[ -d /tmp/steamcmd ]] && rm -rf /tmp/steamcmd
|
|
||||||
git clone https://aur.archlinux.org/steamcmd.git /tmp/steamcmd
|
|
||||||
cd /tmp/steamcmd && makepkg -si --noconfirm && cd $OLDPWD
|
|
||||||
#TODO: check symlink
|
|
||||||
log "Symlinking steamcmd"
|
|
||||||
sudo ln -s /usr/bin/steamcmd /home/steam/steamcmd
|
|
||||||
rm -rf /tmp/steamcmd
|
|
||||||
find_steam_cmd
|
|
||||||
fi
|
|
||||||
sudo pacman -Qi lib32-gcc-libs 2>/dev/null 1>&2
|
|
||||||
rc=$?
|
|
||||||
if [[ $rc -eq 1 ]]; then
|
|
||||||
fail "Missing deps: lib32-gcc-libs"
|
|
||||||
info "Script will fetch build tools now. Partial upgrades on Arch Linux are discouraged, so triggering a full update.\n
|
|
||||||
Type any key to proceed."
|
|
||||||
read -n1 key
|
|
||||||
case $key in
|
|
||||||
*) sudo pacman -Syu lib32-gcc-libs --noconfirm
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
pass "Found deps: lib32-gcc-libs"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
check_dist(){
|
|
||||||
os=/etc/os-release
|
|
||||||
dist=$(awk -F= '/^ID=/ {print $2}' $os)
|
|
||||||
pass "Found OS: $dist"
|
|
||||||
case $dist in
|
|
||||||
ubuntu|linuxmint|pop|debian) deb_install ;;
|
|
||||||
arch|antergos|manjaro) arch_install ;;
|
|
||||||
steamos) deck_install ;;
|
|
||||||
fedora) generic_install ;;
|
|
||||||
*) generic_install ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
return_to_dzg(){
|
|
||||||
if [[ $ret -eq 1 ]]; then
|
|
||||||
fail "Errors occurred. Type any key to return to DZGUI and kick off manual install."
|
|
||||||
read -n1 key
|
|
||||||
case $key in
|
|
||||||
*) cleanup ;;
|
|
||||||
esac
|
|
||||||
elif [[ $dist == "steamos" ]]; then
|
|
||||||
pass "All OK. Returning to DZGUI."
|
|
||||||
for((i=3;i>0;i--)); do
|
|
||||||
printf "Returning in %i\r" "$i"
|
|
||||||
sleep 1s
|
|
||||||
done
|
|
||||||
cleanup
|
|
||||||
else
|
|
||||||
$(cd $HOME/.local/share/dzgui/helpers; zenity --text-info --title=DZGUI --html --width=390 --height=452 --filename="d.html" 2>/dev/null)
|
|
||||||
cleanup
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
cleanup(){
|
|
||||||
tput cnorm
|
|
||||||
sed -i "s/Logging in user '.*'/Logging in user XXX/" $helpers_path/SCMD.log
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
abort(){
|
|
||||||
tput cnorm
|
|
||||||
printf "\n"
|
|
||||||
log "Keyboard interrupt"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
check_disks(){
|
|
||||||
if [[ $dist == "steamos" ]]; then
|
|
||||||
staging_dir="$HOME/.local/share/dzgui/mods"
|
|
||||||
mkdir -p $staging_dir
|
|
||||||
fi
|
|
||||||
disksize=$(df $staging_dir --output=avail | tail -n1)
|
|
||||||
disk_bytewise=$((disksize * 1024))
|
|
||||||
hr=$(echo $(numfmt --to=iec --format "%.2f" $totalmodsize $disk_bytewise) | sed 's/ /\//')
|
|
||||||
[[ ${#ids[@]} -gt 1 ]] && s=s
|
|
||||||
if [[ $disk_bytewise -lt $totalmodsize ]]; then
|
|
||||||
fail "Required/actual: $hr. Installation will quit after /tmp reaches capacity."
|
|
||||||
else
|
|
||||||
pass "Required/actual: $hr"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
[[ -f $PWD/SCMD.log ]] && rm SCMD.log
|
|
||||||
if [[ -z $1 ]] || [[ -z $2 ]]; then
|
|
||||||
fail "Missing mod arguments"
|
|
||||||
ret=1
|
|
||||||
return_to_dzg
|
|
||||||
fi
|
|
||||||
totalmodsize="$1"
|
|
||||||
shift
|
|
||||||
for i in $@; do
|
|
||||||
ids+=("$i")
|
|
||||||
done
|
|
||||||
main(){
|
|
||||||
echo ""
|
|
||||||
echo "────────DZGUI automod helper────────"
|
|
||||||
log "Preparing environment"
|
|
||||||
check_disks
|
|
||||||
check_dist
|
|
||||||
if [[ $? -eq 1 ]]; then
|
|
||||||
ret=1
|
|
||||||
return_to_dzg
|
|
||||||
else
|
|
||||||
pass "All OK. Starting mod auto install process"
|
|
||||||
auto_mod_download
|
|
||||||
rc=$?
|
|
||||||
[[ $rc -eq 1 ]] && ret=1
|
|
||||||
return_to_dzg
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
trap cleanup EXIT
|
|
||||||
trap abort SIGINT
|
|
||||||
main | tee -a $helpers_path/SCMD.log
|
|
||||||
cleanup
|
|
63
helpers/vdf2json.py
Normal file
63
helpers/vdf2json.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
from shlex import shlex
|
||||||
|
|
||||||
|
def vdf2json(stream):
|
||||||
|
|
||||||
|
"""
|
||||||
|
Read a Steam vdf file and return a string in json format
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _istr(ident, string):
|
||||||
|
return (ident * ' ') + string
|
||||||
|
|
||||||
|
jbuf = '{\n'
|
||||||
|
lex = shlex(stream)
|
||||||
|
indent = 1
|
||||||
|
|
||||||
|
while True:
|
||||||
|
tok = lex.get_token()
|
||||||
|
if not tok:
|
||||||
|
return jbuf + '}\n'
|
||||||
|
if tok == '}':
|
||||||
|
indent -= 1
|
||||||
|
jbuf += _istr(indent, '}')
|
||||||
|
ntok = lex.get_token()
|
||||||
|
lex.push_token(ntok)
|
||||||
|
if ntok and ntok != '}':
|
||||||
|
jbuf += ','
|
||||||
|
jbuf += '\n'
|
||||||
|
else:
|
||||||
|
ntok = lex.get_token()
|
||||||
|
if ntok == '{':
|
||||||
|
jbuf += _istr(indent, tok + ': {\n')
|
||||||
|
indent += 1
|
||||||
|
else:
|
||||||
|
jbuf += _istr(indent, tok + ': ' + ntok)
|
||||||
|
ntok = lex.get_token()
|
||||||
|
lex.push_token(ntok)
|
||||||
|
if ntok != '}':
|
||||||
|
jbuf += ','
|
||||||
|
jbuf += '\n'
|
||||||
|
def main():
|
||||||
|
"""
|
||||||
|
Read Steam vdf and write json compatible conversion
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(prog='vdf2json', description=main.__doc__)
|
||||||
|
parser.add_argument('-i', '--input',
|
||||||
|
default=sys.stdin,
|
||||||
|
type=argparse.FileType('r'),
|
||||||
|
help='input vdf file (stdin if not specified)')
|
||||||
|
parser.add_argument('-o', '--output',
|
||||||
|
default=sys.stdout,
|
||||||
|
type=argparse.FileType('w'),
|
||||||
|
help='output json file (stdout if not specified)')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
args.output.write(vdf2json(args.input))
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
2
news
2
news
|
@ -1 +1 @@
|
||||||
NEWS: Streamlined manual mod subscription. Automatic mod installation enters testing.
|
NEWS: Simple auto mod installation under Advanced Options.
|
||||||
|
|
Loading…
Reference in a new issue