Files
netris-nestri/.scripts/proton
Wanjohi 674124e819 🐛 fix(server): Final touches (#66)
## Description

**What issue are you solving (or what feature are you adding) and how
are you doing it?**

This is a catch all PR that tries to smooth out the creases found while
playing using Netris.
What i have found so far:
1. Change `NAME` environment to `SESSION_ID` for warp server.
2. Run `entrypoint.sh` and `warp-input` as user `netris`
3. Netris-proton is broken, it quits prematurely. I think it has to be a
problem with a missing wine installation
2024-05-30 01:53:07 +03:00

610 lines
22 KiB
Bash

#!/bin/bash
# Version 1.1
#Copied from https://github.com/noabody/unibuild/blob/master/data/wstart
# WINEARCH win32/win64 not as good as binary wine/wine64"
# WINEDEBUG="-all" not as good as dev/null
# complex command line builder to simplify command objects
# vars bin, pfx set to wine binary, prefix dirs initially
# menus will dynamically set bin pfx to specific targets
# menu shows gui based 32/64-bit pe header exe via pev
# var 'x' for unified cross-functionality
# ${@:2} skips 'wstart' and 1st arg
# manjaro 21.2.1
#sudo pacman -S bash binutils findutils gendesk grep icoutils pcre2 perl yay winetricks; yay -S pev
# wnbin needs wine dir with: bin lib lib64 share
# manjaro default path is /usr
# can symlink various wnbin="$HOME/.local/opt"
#mkdir "$HOME"/.local/opt
#ln -sf /usr "$HOME"/.local/opt/wine
#ln -sf /usr/share/steam/compatibilitytools.d/proton-ge-custom/files "$HOME"/.local/opt/proton
wnbin="/usr"
# top level wine dir, symlink into "$HOME/.local/opt" to flatten paths
wnpfx="$HOME"
# top level wine prefix dir
pntop="$HOME/.steam"
# top level linux steam dir
pnapp="$pntop/steam/steamapps"
# steamapps subdir
pnbin="$pnapp/common"
# proton subdir normally under top/app
pnpfx="$pnapp/compatdata"
# proton prefix subdir normally under top/app
pnpge="$pntop/root/compatibilitytools.d"
# proton ge
progs="drive_c/Program Files"
# Program Files standard subdir
stcmn="Steam/steamapps/common"
# windows steam client subdir under progs
desk="$HOME/Desktop"
# desktop entry folder
icon="applications-other"
# default icon
temp="$HOME/Downloads"
# temp folder
clprm=("${@:2}")
# store cmdline args minus first option
x="$(echo "$1" | grep -Pio '(?<=-)[wp]')"
# 1st letter of 1st cmd line arg determines wine/proton
if [[ -n "$x" ]]; then
xarg="$(echo "$1" | perl -pe 's/-[wp]/-x/gi')"
else
xarg="$(echo "$1" | perl -pe 's/-x+/-/gi')"
fi
# drop 1st letter x or change to it
xcmd=()
i_mnus=()
myprnt=()
i_syms=()
pmenu=("Command Prompt/wineconsole.exe" "Control Panel/control.exe" "Registry Editor/regedit.exe" "Task Manager/taskmgr.exe" "Windows Explorer/explorer.exe" "Wine Configuration/winecfg.exe")
# scalable built-in programs menu
unset WINEARCH WINEDLLPATH WINEPREFIX STEAM_COMPAT_CLIENT_INSTALL_PATH STEAM_COMPAT_DATA_PATH
# prevent shell inheritance of env vars we use
w_menu () {
PS3="Please enter your choice: "
select answer in "${i_mnus[@]}"; do
for item in "${i_mnus[@]}"; do
if [[ $item == "$answer" ]]; then
break 2
fi
done
done
# repeating menu requires valid selection from array
if [[ "$answer" = "quit" ]]; then
# pop quit from end of array for menu option
exit
else
xmrtn="$answer"
fi
unset i_mnus
clear
}
# Path ordering: wine64 x64/x32 or wine32 x32 then standard
# Order critical to proper operation
xn64 () {
xstrt="wine64"
xnldl="$xnbin/lib64:$xnbin/lib"
xndll="$xnbin/lib64/wine:$xnbin/lib/wine"
}
xn32 () {
xstrt="wine"
xnldl="$xnbin/lib"
xndll="$xnbin/lib/wine"
}
xnint () {
if [[ "$x" = "p" ]]; then
xnbin="$pnbin"
xnpfx="$pnpfx"
dpth=(4 3)
else
xnbin="$wnbin"
xnpfx="$wnpfx"
dpth=(3 2)
fi
}
xnexe () {
# menu installed wine/proton or exit
readarray -t i_mnus < <(find -L "$xnbin" -maxdepth "${dpth[0]}" -type f -iname 'wine' ! \( -ipath '*/sbin*' \) 2>/dev/null | perl -pe "s|\Q$xnbin\E/(.*)[/]*bin/wine|\1| ; s|/$||" | sort ; echo "quit")
if [[ ${#i_mnus[@]} -gt 2 ]]; then
clear
w_menu
xnbin="$(realpath "$xnbin/$xmrtn")"
unset xmrtn
elif [[ ${#i_mnus[@]} -eq 2 ]]; then
xnbin="$(realpath "$xnbin/${i_mnus[0]}")"
else
echo "No installed Wine/Proton found."
exit 1
fi
}
xndef () {
# create default prefix cross-function
if [[ "$x" = "p" ]]; then
if [[ ! -d "$xnpfx/0" ]]; then
# always create default 0 prefix
xnpfx="$xnpfx/0"
echo "Creating default prefix: $xnpfx"
mkdir -p "$xnpfx"
STEAM_COMPAT_DATA_PATH="$xnpfx" "${xnbin%/*}/proton" run > /dev/null 2>&1 &
xnpfx="$xnpfx/pfx"
fi
else
if [[ ! -d "$xnpfx/.wine" ]]; then
# always create default wine prefix
xnpfx="$xnpfx/.wine"
echo "Creating default prefix: $xnpfx"
WINEPREFIX="$xnpfx" "$xnbin"/bin/winecfg > /dev/null 2>&1 &
if [[ -d "$HOME/.wine" && "$HOME/.wine" != "$xnpfx" ]]; then
rm -rf "$HOME"/.wine
ln -sf "$xnpfx" "$HOME"/.wine
fi
fi
fi
}
xnpre () {
# menu wine/proton prefix
readarray -t i_mnus < <(find "$xnpfx" -maxdepth "${dpth[1]}" -type f -iname 'system.reg' 2>/dev/null | perl -pe "s|\Q$xnpfx\E/(.*)/system.reg|\1|" | sort ; echo "quit")
# use perl escaped Q/E to preserve special characters in path variable
if [[ ${#i_mnus[@]} -gt 2 ]]; then
# display menu with min two options plus quit
# guard proton cross-function
if [[ "$x" = "p" ]]; then
# shellcheck disable=SC2044
for value in $(find "$xnpfx" -maxdepth 1 -type d -ipath '*/[0-9]*' -printf "${xnpfx///compatdata}/appmanifest_%P.acf\n" 2>/dev/null); do
test -f "$value" && myprnt+=("$(grep -Pio '^\s+\"(appid|name)\"\s+\"(.*)\"' "$value" | perl -pe 's/.*appid.+?\"(.*)\"\v|.*name.+?\"(.*)\"/\1 \2/')")
done
if [[ ${#myprnt[@]} -gt 0 ]]; then
printf '%s\n' "${myprnt[@]}" | sort
fi
# correlate appmanifest to proton prefix and list before menu
unset myprnt
fi
w_menu
xnpfx="$xnpfx/$xmrtn"
unset xmrtn
elif [[ ${#i_mnus[@]} -eq 2 ]]; then
# don't menu if only one option plus quit
xnpfx="$xnpfx/${i_mnus[0]}"
fi
if [[ -d "$xnpfx/$progs (x86)" ]]; then
xn64
else
xn32
fi
}
xnenv () {
# core env vars allow proper targetting of wine/proton
xpath="$xnbin/bin:$PATH"
xcmd=(env PATH="$xpath" WINEDLLPATH="$xndll" LD_LIBRARY_PATH="$xnldl" WINEPREFIX="$xnpfx")
# guard proton cross-function which adds on to core env vars
if [[ "$x" = "p" ]]; then
xcmd+=(STEAM_COMPAT_DATA_PATH="${xnpfx///pfx}" STEAM_COMPAT_CLIENT_INSTALL_PATH="$pntop")
fi
}
xnldr () {
# loader default to proton as applicable, otherwise wine
if [[ "$x" = "p" ]]; then
read -r -p 'wine loader? [y/N] ' chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
xcmd+=("$xstrt")
else
xcmd+=("${xnbin%/*}/proton" "run")
fi
else
xcmd+=("$xstrt")
fi
}
xnset () {
# set cross-fuction
xnint
# wine/proton menu
xnexe
# create default prefix as required
xndef
# wine/proton prefix
xnpre
# wine/proton env vars
xnenv
}
xlnch () {
# cross-function command line launcher
if [[ -z "$dbg" ]]; then
("${xcmd[@]}" > /dev/null 2>&1 &)
else
echo "${xcmd[@]}"
if [[ "$dbg" = "1" ]]; then
("${xcmd[@]}" &)
elif [[ "$dbg" = "2" ]]; then
(WINEDEBUG="warn+all" "${xcmd[@]}" &)
fi
fi
# prepend cmd with dbg=1 to see command and default debug output
# dbg=2 to see command and all debug output, dbg=? for command only
}
allexe () {
# unfiltered list of exe in specified path
if [[ -n "$(stat --file-system --format=%T "$(stat --format=%m "$pedir" 2>/dev/null)" 2>/dev/null | grep -Pio 'fuse')" ]]; then
readarray -t i_mnus < <(find "$pedir" -maxdepth 7 -type f -regextype posix-extended -iname '*.exe' 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|" | sort ; echo "quit")
# skip exe validity tests if file is on network drive
else
readarray -t i_mnus < <(env pedir="$pedir" find "$pedir" -maxdepth 7 -type f -regextype posix-extended -iname '*.exe' -exec sh -c '(readpe -h optional "$1" 2>/dev/null | grep -Piq '0x2.*gui') && (wrestool "$1" 2>/dev/null | grep -Piq 'type=icon') && echo "$1" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|"' -- {} \; 2>/dev/null | sort ; echo "quit")
# perform exe validity tests if file is on local drive
fi
}
fewexe () {
# filtered list of exe in standard paths
readarray -t i_mnus < <(env pedir="$pedir" find "$pedir" -maxdepth 7 -type f -regextype posix-extended ! \( -ipath '*cache*' -o -ipath '*/microsoft*' -o -ipath '*/windows*' -o -ipath '*/temp*' \) ! \( -iregex '.*(capture|clokspl|helper|iexplore|install|internal|kernel|[^ ]launcher|legacypm|overlay|proxy|redist|renderer|(crash|error)reporter|serv(er|ice)|setup|streaming|tutorial|unins|update).*' \) -iname '*.exe' -exec sh -c '(readpe -h optional "$1" 2>/dev/null | grep -Piq '0x2.*gui') && (wrestool "$1" 2>/dev/null | grep -Piq 'type=icon') && echo "$1" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|"' -- {} \; 2>/dev/null | sort ; echo "quit")
# valid exe will have gui and icon
}
alloth () {
# unfiltered list of variable type in specified path
readarray -t i_mnus < <(find "$pedir" -maxdepth 7 -type f -regextype posix-extended -iname "$xflt" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|" | sort ; echo "quit")
}
fewoth () {
# filtered list of variable type in standard paths
readarray -t i_mnus < <(env pedir="$pedir" find "$pedir" -maxdepth 7 -type f -regextype posix-extended ! \( -ipath '*cache*' -o -ipath '*/microsoft*' -o -ipath '*/windows*' -o -ipath '*/temp*' \) ! \( -iregex '.*(capture|clokspl|helper|iexplore|install|internal|kernel|[^ ]launcher|legacypm|overlay|proxy|redist|renderer|(crash|error)reporter|serv(er|ice)|setup|streaming|tutorial|unins|update).*' \) -iname "$xflt" 2>/dev/null | perl -pe "s|\Q$pedir\E/(.*)|\1|" | sort ; echo "quit")
}
xbld () {
# cross-function custom prefix builder
pnpfx="$pnpfx/${clprm[0]}"
wnpfx="$wnpfx/${clprm[0]}"
xnint
if [[ -z "${clprm[0]}" ]]; then
echo "Wine/Proton prefix name required: (e.g. .wine, 0 )"
elif [[ -d "$xnpfx" ]]; then
echo "Wine/Proton Prefix exists: $xnpfx"
else
xnexe
echo "Creating Wine/Proton Prefix: ${clprm[0]}"
if [[ "$x" = "p" ]]; then
xnenv
mkdir -p "$xnpfx"
xcmd+=(STEAM_COMPAT_DATA_PATH="$xnpfx" "${xnbin%/*}/proton" "run")
else
read -r -p '32-bit only? [y/N] ' chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
xn32
xnenv
xcmd+=(WINEARCH="win32" "$xstrt" "winecfg.exe")
else
xn64
xnenv
xcmd+=(WINEARCH="win64" "$xstrt" "winecfg.exe")
fi
fi
xlnch
fi
}
xpmn () {
# use specified exe, menu specified folder, or menu system
if [[ -f "${clprm[0]}" ]]; then
# parse 1st cmdline arg, queue if valid file
pedir="$(realpath "${clprm[0]}")"
xmrtn="$(basename "$pedir")"
pedir="$(dirname "$pedir")"
else
if [[ -d "${clprm[0]}" ]]; then
# parse 1st cmdline arg, use as path if valid
pedir="$(realpath "${clprm[0]}")"
test -z "$xflt" && allexe || alloth
else
# if no cmdline path, use prefix drive_c
pedir="$xnpfx/drive_c"
test -z "$xflt" && fewexe || fewoth
fi
# create menu, from path, of file
test ${#i_mnus[@]} -gt 1 && w_menu
fi
}
xlyt() {
# pe layout for launch
# 64-bit prefix, 32-bit pe header, reset env to 32
if [[ -n "$(readpe -h optional "$pedir/$xmrtn" 2>/dev/null | grep -Pi 'magic number.*0x10b')" && -d "$xnpfx/$progs (x86)" ]]; then
xn32
xnenv
fi
xnldr
# if 1st arg is file/folder, skip it and run selection + remaining args
if [[ -e "${clprm[0]}" ]];then
xcmd+=("$pedir/$xmrtn" "${clprm[@]:1}")
else
xcmd+=("$pedir/$xmrtn" "${clprm[@]}")
fi
}
xstm() {
if [[ "$x" = "p" ]]; then
sstrt="$(realpath "$(which steam)" 2>/dev/null)"
else
xnset
sstrt="$(find "$xnpfx/drive_c" -maxdepth 3 -iname 'steam.exe' 2>/dev/null)"
if [[ -f "$sstrt" ]]; then
pnapp="$(dirname "$sstrt")/steamapps"
xcmd+=("$xstrt")
fi
fi
# find wine/proton steam binary path, normally subdir of program files
if [[ -f "$sstrt" ]]; then
test -d "$pnapp" && readarray -t i_mnus < <(find "$pnapp" -maxdepth 1 -type f -iname 'appmanifest_*.acf' -exec grep -Pio '^\s+\"(appid|name)\"\s+\"(.*)\"' "{}" \; 2>/dev/null | perl -pe 's/.*appid.+?\"(.*)\"\v|.*name.+?\"(.*)\"/\1 \2/' | sort ; echo -e "steam\nquit")
# read appmanifests to create menu entries
test ${#i_mnus[@]} -gt 2 && w_menu && xmrtn="$(expr "$xmrtn" : '\([0-9]*\)')"
if [[ -n "$xmrtn" ]]; then
# lauch selection with steam
xcmd+=("$sstrt" "-no-browser" "-applaunch" "$xmrtn")
xlnch
else
# launch steam was selected
# minigamelist (short game list) for no-browser (disabled chrome) to save memory
xcmd+=("$sstrt" "-no-browser" "steam://open/minigameslist")
xlnch
fi
else
echo -e "Steam not found."
fi
}
xpge () {
test -d "$pnpge" || mkdir -p "$pnpge"
test -d "$pnbin" || mkdir -p "$pnbin"
if [[ ! -d "$(dirname "$pnpge")" ]]; then
echo -e "Could not create folder 'compatibilitytools.d/protonge' in:\n $(dirname "$pnpge")\n because that path does not exist.\nVerify script variable 'pnpge'"
elif [[ ! -d "$pnbin" ]]; then
echo -e "Could not create sym-link 'protonge' in:\n $pnbin\n because that path does not exist.\nVerify script variable 'pnbin'"
else
gedl="$(curl -sL https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest | jq -r ".tag_name")"
# gedl="$(gh release list -R GloriousEggroll/proton-ge-custom -L 1 | grep -Pio '^ge[^ ]+')"
gever="$(echo "$gedl" | grep -Pio '(?<=ge-proton).*')"
if [[ -f "$pnpge/protonge/version" ]]; then
if [[ -z "$(grep -Pio "$gever" "$pnpge/protonge/version")" ]]; then
echo -e "Available Proton GE $gever differs from installed, updating...\n"
chse=y
else
echo -e "Available Proton GE $gever matches installed, nothing to do.\n"
fi
else
echo -e "Proton GE not found, installing...\n"
chse=y
fi
fi
if [[ -n "$chse" ]]; then
wget --progress=dot:giga "$(curl -s https://api.github.com/repos/GloriousEggroll/proton-ge-custom/releases/latest | grep browser_download_url | cut -d\" -f4 | grep .tar.gz)" -P "$temp"/
rm -rf "$pnpge/protonge"
tar -xf "$temp/$gedl".tar.gz -C "$pnpge/"
mv "$pnpge"/*roton* "$pnpge/protonge"
rm -f "$temp/$gedl".tar.gz
grep -Piq "$gever" "$pnpge/protonge/version" || perl -pi -e "s|(?<=ge-proton).*|$gever|gi" "$pnpge/protonge/version"
test -h "$pnbin/protonge" || ln -sf "$pnpge/protonge" "$pnbin"
fi
}
xwn () {
export WINE_BRANCH=staging
sudo mkdir -pm755 /etc/apt/keyrings && sudo curl -fsSL -o /etc/apt/keyrings/winehq-archive.key "https://dl.winehq.org/wine-builds/winehq.key" \
&& sudo curl -fsSL -o "/etc/apt/sources.list.d/winehq-$(grep UBUNTU_CODENAME= /etc/os-release | cut -d= -f2 | tr -d '\"').sources" "https://dl.winehq.org/wine-builds/ubuntu/dists/$(grep UBUNTU_CODENAME= /etc/os-release | cut -d= -f2 | tr -d '\"')/winehq-$(grep UBUNTU_CODENAME= /etc/os-release | cut -d= -f2 | tr -d '\"').sources" \
&& sudo apt-get update && sudo apt-get install --install-recommends -y winehq-${WINE_BRANCH} \
&& sudo curl -fsSL -o /usr/bin/winetricks "https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks" \
&& sudo chmod 755 /usr/bin/winetricks \
&& sudo curl -fsSL -o /usr/share/bash-completion/completions/winetricks "https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks.bash-completion"
}
usage() {
echo -e "\n$(basename $0): ERROR - $*" 1>&2
echo -e "\nusage: $(basename $0)\n [-?a,--?add] [-?b,--?bld] [-?c,--?cmd] [-?d,--?dsk]\n [-?i,--?inf] [-?k,--?kil] [-?o,--?ovr] [-?p,--?prg]\n [-?s,--?stm] [-?t,--?trk] [-?u,--?cut] [-?v,--?ver]\n\n[?] = (p)roton, (w)ine\n (add) exe path to reg, (bld) build prefix,\n (cmd) prog menu, (dsk) desktop, (inf) exe info,\n (kil) kill wine, (ovr) overrides, (prg) exe list,\n (stm) steam, (trk) winetricks, (cut) shortcut,\n (ver) wine version\n" 1>&2
}
if [[ $# -lt 1 ]]; then
usage "one option required!"
else
case $xarg in
-xa|--xadd)
# cross-fuction path add to registry based on exe
xnint
xnpre
xpmn
if [[ -n "$xmrtn" ]]; then
ptadd="$(dirname "$pedir/$xmrtn")"
ptadd="z:${ptadd////\\\\}"
read -r -p 'prepend to system path? [y/N] ' chse
clear
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
xnreg='System\\CurrentControlSet\\Control\\Session Manager\\Environment'
xmrtn='system.reg'
else
xnreg='Environment'
xmrtn='user.reg'
fi
if [[ -z "$(pcre2grep -Mio "\[\Q${xnreg,,}\E\](?s).+?\"PATH\"=str\(2\):\".+?(?=\[.+?\])(?-s)" "$xnpfx/$xmrtn")" ]]; then
perl -0777 -pi -e "s|(\[\Q${xnreg,,}\E\](?s).+?#time=(?-s).*)(?s)(.+?)(?=\[.+?\])(?-s)|\\1\n\"PATH\"=str\(2\):\"${ptadd//\\/\\\\}\"\\2|gi" "$xnpfx/$xmrtn"
echo -e "$( (echo "$xnreg" | grep -Pioq '\\Environment') && echo 'HKLM\\' || echo 'HKCU\\')$xnreg:\n\n $ptadd\n\nPATH created successfully\n"
elif [[ -z "$(pcre2grep -Mio "\[\Q${xnreg,,}\E\](?s).+?\"PATH\"=str\(2\):\"(?-s).*\Q${ptadd,,}\E[\;\"](?s).+?(?=\[.+?\])(?-s)" "$xnpfx/$xmrtn")" ]]; then
perl -0777 -pi -e "s|(\[\Q${xnreg,,}\E\](?s).+?\"PATH\"=str\(2\):\")(?-s)(.*)(?s)(.+?)(?=\[.+?\])(?-s)|\\1${ptadd//\\/\\\\}\;\\2\\3|gi" "$xnpfx/$xmrtn"
echo -e "$( (echo "$xnreg" | grep -Pioq '\\Environment') && echo 'HKLM\\' || echo 'HKCU\\')$xnreg:\n\n $ptadd\n\nPATH added successfully\n"
else
echo -e "$( (echo "$xnreg" | grep -Pioq '\\Environment') && echo 'HKLM\\' || echo 'HKCU\\')$xnreg:\n\n $ptadd\n\nalready in PATH\n"
fi
# \Q \E adds \ to non alphanums but variable with \E ends \Q
# lowercase ${var,,} to avoid since path/reg not case sensitive
# linux path is case sensitive so user must not create duplicates
fi
;;
-xb|--xbld)
# cross-function prefix builder
xbld
;;
-xc|--xcmd)
# cross-function standard tools menu
xnset
readarray -t i_mnus < <(printf '%s\n' "${pmenu[@]}" | perl -pe 's|/.*||gi' ; echo "quit")
w_menu
xmrtn="$(printf '%s\n' "${pmenu[@]}" | grep -Pio "(?<=$xmrtn/).*")"
xnldr
if [[ -f "${clprm[0]}" ]];then
pedir="$(realpath "${clprm[0]}")"
cd "$(dirname "$pedir")" || exit
xcmd+=("$xmrtn" "$pedir" "${clprm[@]:1}")
else
xcmd+=("$xmrtn" "${clprm[@]}")
fi
xlnch
;;
-xd|--xdsk)
# cross-function wine desktop
xnset
xnldr
xcmd+=("explorer.exe" "/desktop=shell,1024x768" "explorer.exe")
xlnch
;;
-i|--install)
# proton ge
xpge
xwn
;;
-xi|--xinf)
# cross-fuction program info
if [[ ! -f "${clprm[0]}" && ! -d "${clprm[0]}" ]]; then
# don't menu prefix on supplied file or folder
xnint
xnpre
fi
if [[ ! -f "${clprm[0]}" ]]; then
# offer to menu dll if no file given
read -r -p 'query dll? [y/N] ' chse
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
xflt="*.dll"
fi
fi
xpmn
IFS=$'\n'
if [[ -n "$xmrtn" ]]; then
if [[ $(readpe "$pedir/$xmrtn" 2>/dev/null) ]]; then
# if file is PE print 32/64-bit and dll references
myprnt+=("$(readpe -h optional "$pedir/$xmrtn" 2>/dev/null | grep -Piq 'PE32\+' && echo -e "FILE:\n$xmrtn\n \nPE HEADER:\n64-bit" || echo -e "FILE:\n$xmrtn\n \nPE HEADER:\n32-bit")")
myprnt+=("$(echo -e ' \nVersion:' ; peres -v "$pedir/$xmrtn" 2>/dev/null | grep -Pio '(?<=Product Version:).*' | tr -d ' ')")
# find dll references, filenames without spaces
myprnt+=("$(echo -e ' \nREFERENCES:' ; strings "$pedir/$xmrtn" | grep -Pio '[^<>:"/\\|?*\s]+\.dll' | perl -pe 's|([^/]*\Z)|lc($1)|e' | sort -u ; echo ' ')")
else
myprnt+=("$(echo -e ' \nNot a 32/64-bit program, no information to provide\n ')")
fi
else
myprnt+=("$(echo -e ' \nNo file found\n ')")
fi
printf '%s\n' "${myprnt[@]}"
unset IFS myprnt
;;
-xk|--xkil)
# cross-function wine kill, must select same as running
xnset
xcmd+=("wineserver" "-k")
xlnch
;;
-xo|--xovr)
# cross-function prefix override list
xnint
xnpre
read -r -p 'per application? [y/N] ' chse
clear
IFS=$'\n'
myprnt+=("$(echo -e "Prefix:\n$xnpfx\n ")")
if [[ "$chse" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
# show existing per-application overrides
myprnt+=("$(echo -e 'Per-application overrides:' ; pcre2grep -Mio '\[\Qsoftware\\wine\\appdefaults\\\E[^\\]+\Q\\dlloverrides\E\](?s).+?(?=\[.+?\])(?-s)' "$xnpfx/user.reg" | grep -Pio '(?<=appdefaults..).*(?=..dlloverrides)|\".*\"' && echo ' ' || echo -e 'None found\n ')")
else
# show existing prefix overrides
myprnt+=("$(echo -e 'Global overrides:' ; pcre2grep -Mio '\[\Qsoftware\\wine\\dlloverrides\E\](?s).+?(?=\[.+?\])(?-s)' "$xnpfx/user.reg" | grep -Pio '\".*\"' && echo ' ' || echo -e 'None found\n ')")
fi
printf '%s\n' "${myprnt[@]}"
unset IFS myprnt
# A command like:
# perl -pi -e 's/(\".*msvc.*\"=\")(.*),(.*)(")/\1\3,\2\4/g' user.reg
# Swaps msvc entries (native,builtin) to (builtin,native)
;;
-xr|--xrun)
# cross-fuction run program - 1st arg valid file to run, folder to menu,
# neither (sys menu), 2nd arg... passed to exe
xnset
xpmn
if [[ -n "$xmrtn" ]]; then
xlyt
# change to exe dir before run
cd "$(dirname "$pedir/$xmrtn")" || exit
xlnch
fi
;;
-xs|--xstm)
# cross-function steam launcher
xstm
;;
-xt|--xtrk)
# cross-function winetricks
xnset
# winetricks for selected wine/proton prefix
if [[ ${#clprm[@]} -gt 0 ]]; then
xcmd+=("winetricks" "${clprm[@]}")
dbg="1"
# use args if supplied, otherwise gui
else
xcmd+=("winetricks" "--gui")
# protontricks may work better
fi
xlnch
;;
-xu|--xcut)
# cross-function desktop shortcut
if [[ -d "$desk" ]]; then
xnset
xpmn
if [[ -n "$xmrtn" ]]; then
xlyt
# change to desktop dir before create icon
cd "$desk" || exit
read -r -e -p $'Shortcut Name?\x0a' -i "$(basename "${xmrtn/.*}")" chse
# create desktop entry
gendesk -f -n --name="$chse" --comment='created by wstart' --custom='Keywords=wine;proton;launcher;' --exec="bash -c 'cd \"$(dirname "$pedir/$xmrtn")\" ; $(printf '"%s" ' "${xcmd[@]}")'" --icon="$icon" --terminal=false --categories='Emulator;Game' --startupnotify=false --pkgname="$chse"
chmod 755 "$chse".desktop
fi
else
echo -e "Invalid desktop location: $desk\nPlease edit the script"
fi
;;
-xv|--xver)
# cross-function wine version
xnint
xnexe
xnenv
xcmd+=("wine" "--version")
("${xcmd[@]}" &)
;;
-h|--help)
echo -e "\n General usage: netris-proton -w? args\n -w? options for wine and -p? for proton.\n Type wstart by itself for command list.\n\n Edit script path variables as needed.\n bash, find, gendesk, grep, readpe,\n strings, winetricks, wrestool,\n pcre2grep, peres, perl needed by\n certain items.\n"
;;
-*|\*|*)
# do_usage
usage "invalid option $1"
exit 1
;;
esac
fi