added main script: winehelper

This commit is contained in:
Mikhail Tergoev 2025-01-31 15:17:19 +03:00
commit 9ec6dd0f3e

820
winehelper Executable file

@ -0,0 +1,820 @@
#!/usr/bin/env bash
##### CHECK ROOT #####
if [[ $(id -u) -eq 0 ]] ; then
echo "Перезапустите скрипт $0 от обычного пользователя!"
exit 1
fi
##### MESSAGES FUNCTIONS #####
print_error () { printf "\E[31m%s Ошибка: $@ %s\e[0m\n" ;}
print_warning () { printf "\E[33m%s Предупреждение: $@ %s\e[0m\n" ;}
print_info () { printf "\E[36m%s Информация: \"$@\" %s\e[0m\n" ;}
print_ok () { printf "\E[35m%s Успех: $@ %s\e[0m\n" ;}
print_var () { for vp in $@ ; do print_info "${vp}=${!vp}" ; done ;}
fatal () { print_error "$@" ; exit 1 ;}
##### CHECK VARIABLES #####
check_variables () { [[ -z ${!1} ]] && export $1="$2" ;}
##### DEFAULT VARIABLES #####
SCRIPT_NAME="$(basename "$0")"
if [[ "$(realpath "$0")" == "/usr/bin/$SCRIPT_NAME" ]] ; then
USER_WORK_PATH="$HOME/.local/share/$SCRIPT_NAME"
RUN_SCRIPT="/usr/bin/$SCRIPT_NAME"
DATA_PATH="/usr/share/$SCRIPT_NAME"
else
USER_WORK_PATH="$HOME/test-$SCRIPT_NAME"
RUN_SCRIPT="$(realpath "$0")"
DATA_PATH="$(dirname "$RUN_SCRIPT")"
fi
PP_VULKAN_LIBDIR="$USER_WORK_PATH/vulkan"
PP_PREFIXES_DIR="$USER_WORK_PATH/prefixes"
PP_DIST_DIR="$USER_WORK_PATH/dist"
PP_TMP_DIR="$USER_WORK_PATH/tmp"
PP_IMAGE_PATH="$DATA_PATH/image"
PP_DB_DIR="$DATA_PATH/database"
PP_AUTOINSTALL_DIR="$DATA_PATH/autoinstall"
# export WINEDLLOVERRIDES=mshtml,mscoree="
check_variables WINEESYNC "0"
check_variables WINEFSYNC "0"
check_variables WINEARCH "win64" # or "win32"
check_variables PP_WINE_USE "wine_x_tkg_10-0_amd64" # or system
check_variables STAGING_SHARED_MEMORY "1"
check_variables WINE_LARGE_ADDRESS_AWARE "1"
check_variables WINE_FULLSCREEN_FSR "1"
check_variables WINE_DO_NOT_CREATE_DXGI_DEVICE_MANAGER "0"
check_variables WINE_HEAP_DELAY_FREE "0"
check_variables WINE_ALLOW_XIM "0"
check_variables DEBUG 0
check_variables PP_WINDOWS_VER "10"
# check_variables PP_USE_GSTREAMER "1"
# check_variables PP_USE_D3D_EXTRAS "1"
check_variables PP_USE_SHADER_CACHE "1"
check_variables PP_USE_WINE_DXGI "0"
check_variables PP_DLL_INSTALL ""
check_variables WINE_WIN_START "start /wait /high /unix"
check_variables WINE_CPU_TOPOLOGY "4"
check_variables USE_OPENGL "1"
check_variables DXVK_STABLE_VER "1.10.3-28"
check_variables DXVK_GIT_VER "2.2-164"
# check_variables DXVK_CONFIG_FILE "path/to/dxvk.conf"
check_variables VKD3D_STABLE_VER "1.1-2602"
check_variables VKD3D_GIT_VER "1.1-3556"
# check_variables VKD3D_LIMIT_TESS_FACTORS 64
# check_variables VKD3D_FEATURE_LEVEL "12_0"
if [[ "$WINEARCH" == "win32" ]] ;then
check_variables BASE_PFX "defpfx_x86_v01"
check_variables WINEPREFIX "default_x86"
else
check_variables BASE_PFX "defpfx_x64_v01"
check_variables WINEPREFIX "default_x64"
fi
export CLOUD_URL="https://cloud.linux-gaming.ru/portproton"
##### CHECK NOEXEC FOR /HOME #####
if grep "/home" /etc/fstab | grep -q "noexec" ; then
fatal "/home примонтирован в /etc/fstab с аргументом noexec.\nЗапуск портативной версии wine не возможен из домашнего каталога."
fi
##### ROOT #####
su_run () {
print_info "Для продолжения настройки введите root пароль..."
su - -c "$@"
}
##### CHECK DEPENDENCIES #####
# yad zenity cups-pdf
if rpm -q {i586-,}{wine,glibc-core,libstdc++6,glibc-pthread,glibc-nss,libOSMesa,\
libnss-mdns,libunixODBC2,ocl-icd,libfreetype,libfontconfig1,libgnutls30,libGL,\
libEGL,xorg-dri-swrast,xorg-dri-intel,xorg-dri-radeon,libvulkan1,libcups} \
winetricks ca-certificates 1>/dev/null
then : # Зависимости установлены. Пропускаем...
else
if su_run "$DATA_PATH/dependencies.sh"
then print_info "Зависимости успешно установлены. Продолжаем работу $0"
else fatal "Не удалось установить зависимости. Работа $0 прервана."
fi
fi
##### HELPER FUNCTIONS #####
check_command () {
if command -v "$1" &>/dev/null ; then
return 0
else
print_warning "command: $1 - not found!"
return 1
fi
}
add_to_var () {
if ! echo ${!1} | grep "$2" &>/dev/null
then export $1="${!1} $2"
fi
}
rm_from_var () {
if echo ${!1} | grep "$2" &>/dev/null
then export $1="$(echo "${!1//$2/}" | tr -s " ")"
fi
}
try_remove_file () {
if [[ -f "$1" ]] || [[ ! -e "$1" ]] ; then
rm -f "$1"
[[ "$?" == 0 ]] && return 0 || return 1
fi
}
try_remove_dir () {
if [[ -d "$1" ]] ; then
rm -fr "$1"
[[ "$?" == 0 ]] && return 0 || return 1
fi
}
try_copy_file () {
if [[ ! -f "$1" ]] ; then print_info "file $1 not found for copy" && return 1
elif [[ -z "$2" ]] ; then print_error "no way to copy file $1" && return 1
elif [[ -L "$2" ]] ; then print_warning "$2 is a file with a symbolic link"
try_remove_file "$2"
cp -f "$1" "$2" && return 0 || return 1
else
[[ -e "$2/$(basename "$1")" ]] && rm -f "$2/$(basename "$1")"
cp -f "$1" "$2" && return 0 || return 1
fi
}
try_copy_dir () {
if [[ ! -d "$1" ]] ; then print_info "directory $1 not found for copy"
elif [[ -z "$2" ]] ; then print_error "no way to copy directory $1"
else
cp -fr "$1" "$2"
[[ "$?" != 0 ]] && print_error "failed to copy directory $1 to $2" || return 0
fi
return 1
}
try_force_link_file () {
if [[ ! -f "$1" ]] ; then
print_warning "file not found for link: $1"
if [[ -f "$2" ]] ; then
try_remove_file "$2"
print_warning "removed old link: $2"
fi
return 1
elif [[ -z "$2" ]] ; then print_error "no way to link file $1" && return 1
else
try_remove_file "$2"
ln -s -f -r "$1" "$2"
return 0
fi
return 1
}
check_symlink () {
local CHK_SYMLINK_FILE="$(file "$1")"
if [[ -n "$(echo "$CHK_SYMLINK_FILE" | grep -v "broken" | grep "symbolic link to" | awk '{print $1}')" ]] ; then
return 0
elif [[ -n "$(echo "$CHK_SYMLINK_FILE" | grep "broken symbolic link to" | awk '{print $1}')" ]] ; then
print_error "remove broken symlink: $CHK_SYMLINK_FILE"
rm -fr "$CHK_SYMLINK_FILE"
return 1
else
return 1
fi
}
try_force_link_dir () {
if [[ ! -d "$1" ]] ; then print_info "directory $1 not found for link"
elif [[ -z "$2" ]] ; then print_error "no way to link directory $1"
else
ln -s -f -r "$1" "$2"
[[ "$?" != 0 ]] && print_error "failed to link directory $1 to $2" || return 0
fi
return 1
}
create_new_dir () {
if [[ ! -d "$1" ]] ; then
mkdir -p "$1"
fi
return 0
}
unpack () {
case $1 in
*.tar.xz) local command="tar -Jxhf";;
*.tar.gz) local command="tar -xhzf" ;;
*.tar.zst) local command="tar -I zstd -xhf" ;;
*.tar) local command="tar -xhf" ;;
esac
if $command "$1" -C "$2" ; then
print_ok "Архив $1 распакован."
return 0
else
print_error "Распаковать архив $1 не удалось!"
return 1
fi
}
try_download () {
local DOWNLOAD_FILE_URL="$1"
local OUTPUT_FILE="$2"
local OUTPUT_FILE_NAME="$(basename "$OUTPUT_FILE")"
print_info "Скачивание файла $OUTPUT_FILE_NAME..."
if curl -f --progress-bar -A "Mozilla/5.0 (compatible; Konqueror/2.1.1; X11)" \
-L "$DOWNLOAD_FILE_URL" -o "$OUTPUT_FILE"
then
print_ok "Скачивание файла $OUTPUT_FILE_NAME прошло успешно."
if [[ "$3" == check256sum ]] ; then
SHA256SUM_EXT=$(sha256sum "$OUTPUT_FILE" | awk '{print $1}')
SHA256SUM_INT="$(grep "$OUTPUT_FILE_NAME" "$DATA_PATH/sha256sum.list" | awk '{print $1}')"
if [[ "$SHA256SUM_EXT" == "$SHA256SUM_INT" ]] ; then
print_ok "Хэш-сумма файла $OUTPUT_FILE_NAME успешно проверенна."
return 0
else
fatal "Хэш-сумма файла $OUTPUT_FILE_NAME не совподает!"
return 1
fi
fi
return 0
else
fatal "Скачивание файла: $OUTPUT_FILE_NAME завершилось с ошибкой!"
return 1
fi
}
try_copy_other_dll_to_pfx_64 () {
if [[ "$WINEARCH" == "win64" ]] ; then
cmp -s "$1" "${WINEPREFIX}/drive_c/windows/system32/$(basename $1)" && return 0
try_copy_file "$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
try_copy_other_dll_to_pfx_32() {
if [[ "$WINEARCH" == "win64" ]] ; then
cmp -s "$1" "${WINEPREFIX}/drive_c/windows/syswow64/$(basename $1)" && return 0
try_copy_file "$1" "${WINEPREFIX}/drive_c/windows/syswow64/" && return 0 || return 1
else
cmp -s "$1" "${WINEPREFIX}/drive_c/windows/system32/$(basename $1)" && return 0
try_copy_file "$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
try_copy_wine_dll_to_pfx_64 () {
if [[ "$WINEARCH" == "win64" ]] ; then
if [[ -d "${WINEDIR}/lib64/wine/x86_64-windows" ]]
then WINE_BUILD_DLL_64="${WINEDIR}/lib64/wine/x86_64-windows"
else WINE_BUILD_DLL_64="${WINEDIR}/lib64/wine"
fi
cmp -s "$WINE_BUILD_DLL_64/$1" "${WINEPREFIX}/drive_c/windows/system32/$(basename $1)" && return 0
try_copy_file "$WINE_BUILD_DLL_64/$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
try_copy_wine_dll_to_pfx_32() {
if [[ -d "${WINEDIR}/lib/wine/i386-windows" ]]
then WINE_BUILD_DLL_32="${WINEDIR}/lib/wine/i386-windows"
else WINE_BUILD_DLL_32="${WINEDIR}/lib/wine"
fi
if [[ "$WINEARCH" == "win64" ]] ; then
cmp -s "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/syswow64/$1" && return 0
try_copy_file "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/syswow64/" && return 0 || return 1
else
cmp -s "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/system32/$1" && return 0
try_copy_file "$WINE_BUILD_DLL_32/$1" "${WINEPREFIX}/drive_c/windows/system32/" && return 0 || return 1
fi
}
##### OVERRIDE VARIABLES FUNCTIONS #####
var_winedlloverride_update () {
if [[ -n "${WINEDLLOVERRIDES}" ]]
then export WINEDLLOVERRIDES="${1};${WINEDLLOVERRIDES}"
else export WINEDLLOVERRIDES="${1}"
fi
}
var_vkd3d_config_update () {
if [[ -n "${DXVK_CONFIG}" ]]
then export DXVK_CONFIG="${1}; ${DXVK_CONFIG}"
else export DXVK_CONFIG="${1}"
fi
}
var_vkd3d_config_update () {
if [[ -n "${VKD3D_CONFIG}" ]]
then export VKD3D_CONFIG="${1};${VKD3D_CONFIG}"
else export VKD3D_CONFIG="${1}"
fi
}
var_radv_perftest_config_update () {
if [[ -n "${RADV_PERFTEST}" ]]
then export RADV_PERFTEST="${1};${RADV_PERFTEST}"
else export RADV_PERFTEST="${1}"
fi
}
var_vk_istance_layers_config_update () {
if [[ -n "${VK_INSTANCE_LAYERS}" ]]
then export VK_INSTANCE_LAYERS="${1}:${VK_INSTANCE_LAYERS}"
else export VK_INSTANCE_LAYERS="${1}"
fi
}
var_ld_library_path_update () {
if echo "$LD_LIBRARY_PATH" | grep "$1"
then return 0
elif [[ -n "$LD_LIBRARY_PATH" ]]
then export LD_LIBRARY_PATH="$1:$LD_LIBRARY_PATH"
else export LD_LIBRARY_PATH="$1"
fi
return 0
}
create_desktop () {
local name_desktop="$1"
local exe_file="$2"
local icon_file="$PP_IMAGE_PATH/$3.png"
if [[ -z "$name_desktop" ]] || [[ -z "$exe_file" ]] ; then
fatal "Used: $0 --desktop \"desktop_name\" \"path_to_exe\" \"name_png_from_image\""
fi
[[ ! -f "$exe_file" ]] && fatal "Для создания ярлыка не найден исполняемый файл: $exe_file"
[[ ! -f "$icon_file" ]] && icon_file=wine
{
echo "[Desktop Entry]"
echo "Name=$name_desktop"
echo "Exec=env \"$RUN_SCRIPT\" \"$exe_file\" %F"
echo "Type=Application"
echo "Categories=Other;"
echo "StartupNotify=true"
echo "Path=$DATA_PATH"
echo "Icon=$icon_file"
} > "$USER_WORK_PATH/$name_desktop.desktop"
chmod +x "$USER_WORK_PATH/$name_desktop.desktop"
create_new_dir "$HOME/.local/share/applications/"
# cp -f "$USER_WORK_PATH/$name_desktop.desktop" "$HOME/.local/share/applications/"
cp -f "$USER_WORK_PATH/$name_desktop.desktop" "$(xdg-user-dir DESKTOP)"
print_info "На рабочем столе создан $name_desktop.desktop"
if [[ "$USE_AI_SCRIPTS" == "1" ]] \
&& [[ -f "$exe_file" ]]
then
grep -e "#!" -e "export" -e "var_" "$PP_AUTOINSTALL_DIR/$AI_SCRIPT" \
| grep -vE "LAUNCH_PARAMETERS|AUTOINSTALL|WIN_FILE_EXEC|echo" \
| awk '{$1=$1;print}' > "$exe_file".ppdb
print_info "Создан файл настроек для $exe_file"
fi
}
##### USED WINED3D LIBRARY #####
init_opengl () {
if [[ "$USE_OPENGL" == 1 ]] ; then
WINED3D_FILES="d3d8 d3d9 d3d10_1 d3d10 d3d10core d3d11 dxgi d3d12" # d3d12core
for wined3dfiles in $WINED3D_FILES ; do
try_copy_wine_dll_to_pfx_64 "$wined3dfiles.dll"
try_copy_wine_dll_to_pfx_32 "$wined3dfiles.dll"
done
# check_variables WINE_D3D_CONFIG "renderer="
return 0
else
return 1
fi
}
##### CHECK VULKAN LIBRARY #####
init_dxvk () {
check_variables USE_DXVK_VER "$DXVK_STABLE_VER"
get_dxvk () {
DXVK_URL="$1"
DXVK_PACKAGE="${PP_VULKAN_LIBDIR}/dxvk-${DXVK_VAR_VER}.tar.$(echo ${DXVK_URL#*.tar.})"
if try_download "$DXVK_URL" "$DXVK_PACKAGE" check256sum \
&& unpack "$DXVK_PACKAGE" "$PP_VULKAN_LIBDIR"
then
try_remove_file "$DXVK_PACKAGE"
return 0
fi
return 1
}
for DXVK_VAR_VER in "$USE_DXVK_VER" $@ ; do
if [[ ! -d "${PP_VULKAN_LIBDIR}/dxvk-$DXVK_VAR_VER" ]] ; then
get_dxvk "$CLOUD_URL/dxvk-${DXVK_VAR_VER}.tar.gz"
fi
done
if [[ "${PP_USE_WINE_DXGI}" == 1 ]] ; then
DXVK_FILES="d3d9 d3d10_1 d3d10 d3d11" # dxvk_config openvr_api_dxvk"
try_copy_wine_dll_to_pfx_64 "dxgi.dll"
try_copy_wine_dll_to_pfx_32 "dxgi.dll"
else
DXVK_FILES="d3d9 d3d10_1 d3d10 d3d11 dxgi" # dxvk_config openvr_api_dxvk"
fi
for dxvkfiles in $DXVK_FILES ; do
try_copy_other_dll_to_pfx_64 "${PP_VULKAN_LIBDIR}/dxvk-$USE_DXVK_VER/x64/$dxvkfiles.dll"
if try_copy_other_dll_to_pfx_32 "${PP_VULKAN_LIBDIR}/dxvk-$USE_DXVK_VER/x32/$dxvkfiles.dll"
then var_winedlloverride_update "$dxvkfiles=n"
fi
done
}
init_vkd3d () {
check_variables USE_VKD3D_VER "$VKD3D_STABLE_VER"
get_vkd3d () {
VKD3D_URL="$1"
VKD3D_PACKAGE="${PP_VULKAN_LIBDIR}/vkd3d-proton-${VKD3D_VAR_VER}.tar.$(echo ${VKD3D_URL#*.tar.})"
if try_download "$VKD3D_URL" "$VKD3D_PACKAGE" check256sum \
&& unpack "$VKD3D_PACKAGE" "$PP_VULKAN_LIBDIR"
then
try_remove_file "$VKD3D_PACKAGE"
return 0
fi
return 1
}
for VKD3D_VAR_VER in "$USE_VKD3D_VER" $@ ; do
if [[ ! -d "${PP_VULKAN_LIBDIR}/vkd3d-proton-$VKD3D_VAR_VER" ]] ; then
get_vkd3d "$CLOUD_URL/vkd3d-proton-${VKD3D_VAR_VER}.tar.xz"
fi
done
VKD3D_FILES="d3d12 d3d12core libvkd3d-shader-1 libvkd3d-1" # libvkd3d-proton-utils-3
for vkd3dfiles in $VKD3D_FILES ; do
try_copy_other_dll_to_pfx_64 "${PP_VULKAN_LIBDIR}/vkd3d-proton-$USE_VKD3D_VER/x64/$vkd3dfiles.dll"
if try_copy_other_dll_to_pfx_32 "${PP_VULKAN_LIBDIR}/vkd3d-proton-$USE_VKD3D_VER/x86/$vkd3dfiles.dll"
then var_winedlloverride_update "$vkd3dfiles=n"
fi
done
}
##### DOWNLOAD WINE #####
download_wine () {
if [[ ! -d "$PP_DIST_DIR/$PP_WINE_USE" ]] ; then
WINE_URL="$CLOUD_URL/$PP_WINE_USE.tar.xz"
local WINE_PACKAGE="$PP_TMP_DIR/${PP_WINE_USE}.tar.xz"
if try_download "$WINE_URL" "$WINE_PACKAGE" check256sum ; then
if unpack "$WINE_PACKAGE" "$PP_DIST_DIR/" ; then
echo "$PP_WINE_USE" > "$PP_DIST_DIR/$PP_WINE_USE/version"
try_remove_file "$WINE_PACKAGE"
fi
fi
fi
}
##### INITIAL WINE SETTINGS #####
init_wine_ver () {
if [[ "$PP_WINE_USE" != system* ]] ; then
export WINEDIR="$PP_DIST_DIR/$PP_WINE_USE"
if [[ ! -d "$WINEDIR" ]] ; then
download_wine
fi
export WINE="${WINEDIR}/bin/wine"
export WINELOADER="${WINEDIR}/bin/wine"
export WINESERVER="${WINEDIR}/bin/wineserver"
if [[ -n "${PATH}" ]]
then export PATH="${WINEDIR}/bin:${PATH}"
else export PATH="${WINEDIR}/bin"
fi
if [[ -n "${LD_LIBRARY_PATH}" ]]
then export LD_LIBRARY_PATH="${WINEDIR}/lib:${LD_LIBRARY_PATH}"
else export LD_LIBRARY_PATH="${WINEDIR}/lib"
fi
export WINEDLLPATH="${WINEDIR}/lib/wine"
if [[ -d "${WINEDIR}/lib/gstreamer-1.0" ]] ; then
export GST_PLUGIN_SYSTEM_PATH_1_0="${WINEDIR}/lib/gstreamer-1.0"
fi
if [[ "${WINEARCH}" == "win64" ]] ; then
export LD_LIBRARY_PATH+=":${WINEDIR}/lib64"
export WINEDLLPATH+=":${WINEDIR}/lib64/wine"
if [[ -d "${WINEDIR}/lib64/gstreamer-1.0" ]] ; then
export GST_PLUGIN_SYSTEM_PATH_1_0+=":${WINEDIR}/lib64/gstreamer-1.0"
fi
fi
[[ ! -f "${WINEDIR}/version" ]] && echo "${PP_WINE_USE}" > "${WINEDIR}/version"
if [[ ! -d "${WINEDIR}/lib64/" ]] && [[ -d "${WINEDIR}/lib/wine/x86_64-unix" ]] ; then
create_new_dir "${WINEDIR}/lib64/wine"
mv -f "${WINEDIR}/lib/wine/x86_64-unix" "${WINEDIR}/lib64/wine/"
mv -f "${WINEDIR}/lib/wine/x86_64-windows" "${WINEDIR}/lib64/wine/"
fi
else
# use system WINE
if ! command -v "wine" &>/dev/null ; then
fatal "system WINE - not found."
fi
export WINEDIR="/usr"
export WINELOADER="wine"
export WINESERVER="wineserver"
fi
if [[ $DEBUG != 1 ]] ; then
check_variables WINEDEBUG "-all"
check_variables DXVK_LOG_LEVEL "none"
check_variables VKD3D_SHADER_DEBUG "none"
check_variables VKD3D_DEBUG "none"
check_variables DXVK_LOG_PATH "none"
check_variables VKBASALT_LOG_LEVEL "none"
check_variables DXVK_NVAPI_LOG_LEVEL "none"
export PP_WDBG='2>/dev/null'
else
# check_variables WINEDEBUG "fixme-all,err+loaddll,err+dll,err+file,err+reg,warn+file"
check_variables WINEDEBUG "+loaddll,+seh"
check_variables DXVK_LOG_LEVEL "error"
check_variables VKD3D_DEBUG "error"
check_variables WINE_MONO_TRACE "E:System.NotImplementedException"
check_variables VK_LOADER_DEBUG "error"
check_variables VKBASALT_LOG_LEVEL "error"
check_variables DXVK_NVAPI_LOG_LEVEL "error"
export PP_WDBG=""
fi
print_info "Используется версия wine: $PP_WINE_USE"
}
##### INITIAL WINEPREFIX SETTINGS #####
wait_wineserver () {
# while [[ -n "$(ls -l /proc/*/exe 2>/dev/null | grep -ie portproton | grep -E 'wine(64)?-preloader|wineserver' | awk -F/ '{print $3}')" ]] ; do
# sleep 1
# done
"$WINESERVER" -w
}
get_base_pfx () {
local FILE_NAME_PFX="$1"
local PFX_URL="$CLOUD_URL/${FILE_NAME_PFX}.tar.xz"
local PFX_TMP="$PP_TMP_DIR/pfx"
create_new_dir "$PFX_TMP"
if [[ ! -f "$PFX_TMP/$FILE_NAME_PFX.tar.xz" ]] ; then
print_info "Загрузка базового префикса: ${FILE_NAME_PFX}"
if try_download "$PFX_URL" "$PFX_TMP/$FILE_NAME_PFX.tar.xz" check256sum
then unpack "$PFX_TMP/$FILE_NAME_PFX.tar.xz" "$WINEPREFIX/"
else try_remove_file "$PFX_TMP/$FILE_NAME_PFX.tar.xz"
fi
else
if ! unpack "$PFX_TMP/$FILE_NAME_PFX.tar.xz" "$WINEPREFIX/" ; then
try_remove_file "${PFX_TMP}/${FILE_NAME_PFX}.tar.xz"
get_base_pfx "$FILE_NAME_PFX"
fi
fi
}
init_wineprefix () {
if [[ -z "$WINEPREFIX" ]] ; then
export WINEPREFIX="$PP_PREFIXES_DIR/default"
else
if echo "$WINEPREFIX" | grep -v '/' ; then
export WINEPREFIX="$PP_PREFIXES_DIR/$WINEPREFIX"
fi
fi
export DRIVE_C="$WINEPREFIX/drive_c"
# export WINEDLLPATH+=":$DRIVE_C/widows/system32:$DRIVE_C/windows/syswow64"
if [[ ! -f "$WINEPREFIX/.firstboot" ]] ; then
create_new_dir "$WINEPREFIX"
if [[ "$CLEAR_PREFIX" == "1" ]]
then print_warning "Используется переменная \"CLEAR_PREFIX=1\" что принудительно создает чистый префикс с установкой компонентов с помощью winetricks."
elif [[ "$BASE_PFX" != "none" ]]
then get_base_pfx "$BASE_PFX"
fi
print_info "Обновление префикса $WINEPREFIX."
if [[ -d "$WINEPREFIX/drive_c/windows" ]]
then env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" wineboot -u
else env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" wineboot -i
fi
touch "$WINEPREFIX/.firstboot"
wait_wineserver
fi
if [[ -f "$WINEPREFIX/system.reg" ]] \
&& [[ -z $(grep "Windows $PP_WINDOWS_VER" "$WINEPREFIX/system.reg") ]]
then
if [[ $(echo "$PP_WINDOWS_VER" | sed 's/.*/\L&/') == "xp" ]] \
&& [[ "$WINEARCH" != "win32" ]]
then export PP_WINDOWS_VER="xp64"
fi
env WINEDLLOVERRIDES="winegstreamer=" "$WINELOADER" winecfg -v $(echo "win${PP_WINDOWS_VER}" | sed 's/.*/\L&/')
wait_wineserver
print_info "Windows версия изменена на win${PP_WINDOWS_VER}"
fi
if [[ -d "$DRIVE_C/users/xuser" ]] && [[ ! -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$DRIVE_C/users/xuser" "$DRIVE_C/users/$USER"
elif [[ ! -d "$DRIVE_C/users/xuser" ]] && [[ -d "$DRIVE_C/users/$USER" ]]
then try_force_link_dir "$DRIVE_C/users/$USER" "$DRIVE_C/users/xuser"
fi
}
update_winetricks () {
W_TRX_URL="https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks"
W_TRX_EXT_VER="$(curl -s --list-only "$W_TRX_URL" | grep -i 'WINETRICKS_VERSION=' | sed 's/WINETRICKS_VERSION=//')"
print_info "Актуальная версия winetricks: $W_TRX_EXT_VER"
if [[ -f "$PP_TMP_DIR/winetricks" ]] ; then
W_TRX_INT_VER="$(cat "$PP_TMP_DIR/winetricks" | grep -i 'WINETRICKS_VERSION=' | sed 's/WINETRICKS_VERSION=//')"
print_info "Установленная портативная версия winetricks: $W_TRX_INT_VER"
fi
if [[ -n "$W_TRX_EXT_VER" ]] && [[ "$W_TRX_INT_VER" != "$W_TRX_EXT_VER" ]] ; then
if try_download "$W_TRX_URL" "$PP_TMP_DIR/winetricks_new" ; then
mv -f "$PP_TMP_DIR/winetricks_new" "$PP_TMP_DIR/winetricks"
W_TRX_INT_VER="$(cat "$PP_TMP_DIR/winetricks" | grep -i 'WINETRICKS_VERSION=' | sed 's/_VERSION=//')"
print_info "Портативная версия winetricks обновлена до (${W_TRX_INT_VER})"
chmod u+x "$PP_TMP_DIR/winetricks"
fi
fi
export WINETRICKS="$PP_TMP_DIR/winetricks"
}
use_winetricks () {
if [[ -n "$INSTALL_DLL" ]] ; then
PP_DLL_INSTALL="$(echo "$INSTALL_DLL $PP_DLL_INSTALL" | awk '{ for(i=1;i<=NF;i++){a[$i]++} }END{ for(i in a){printf("%s ",i)} }' )"
fi
if [[ -n "$PP_DLL_INSTALL" ]] ; then
PP_DLL_NEED_INSTALL=""
USE_WT_FROM_DB=0
[[ ! -f "$WINEPREFIX/winetricks.log" ]] && touch "$WINEPREFIX/winetricks.log"
for need_install_dll_to_pfx in $PP_DLL_INSTALL "isolate_home" ; do
if [[ "$need_install_dll_to_pfx" == vcrun201[5-9] ]] ; then
sed -i "/${need_install_dll_to_pfx}/d" "$WINEPREFIX/winetricks.log"
need_install_dll_to_pfx="vcrun2022"
fi
if ! grep "$need_install_dll_to_pfx" "$WINEPREFIX/winetricks.log" &>/dev/null ; then
if [[ -z "$PP_DLL_NEED_INSTALL" ]]
then PP_DLL_NEED_INSTALL="$need_install_dll_to_pfx"
else PP_DLL_NEED_INSTALL="$need_install_dll_to_pfx $PP_DLL_NEED_INSTALL"
fi
USE_WT_FROM_DB=1
fi
done
if [[ "$USE_WT_FROM_DB" == "1" ]] ; then
if update_winetricks ; then
print_info "Пробуем установить библиотеки: ${PP_DLL_NEED_INSTALL}"
print_info "Запускаем WINETRICKS..."
export WINETRICKS_DOWNLOADER="curl"
env WINEDLLOVERRIDES="winegstreamer=" "$PP_TMP_DIR/winetricks" -q ${PP_DLL_NEED_INSTALL}
wait_wineserver
fi
fi
fi
}
kill_wine () {
wine_pids=$(ls -l /proc/*/exe 2>/dev/null | grep -E 'wine(64)?-preloader|wineserver' | awk -F/ '{print $3}')
for pw_kill_pids in ${wine_pids}; do
if ps cax | grep "${pw_kill_pids}" ; then
kill -n 9 "${pw_kill_pids}" &>/dev/null
fi
done
}
init_database () {
if [[ -f "$WIN_FILE_EXEC" ]] ; then
PPDB="$(basename "$WIN_FILE_EXEC" .exe)"
if [[ -f "$WIN_FILE_EXEC".ppdb ]] ; then
PPDB_FILE="$WIN_FILE_EXEC".ppdb
else
orig_IFS="$IFS"
IFS=$'\n'
PP_FIND_DB_FILE="$(grep -ilw "#$PPDB.exe" "$PP_DB_DIR"/* )"
if [[ $(echo "$PP_FIND_DB_FILE" | wc -l) -gt 1 ]] ; then
print_error "Найдено более одного файла настроек: $PPDB.exe"
PPDB_FILE="$(echo "$PP_FIND_DB_FILE" | head -n1)"
else
PPDB_FILE="$PP_FIND_DB_FILE"
fi
IFS="$orig_IFS"
fi
if [[ "$PPDB_FILE" ]] ; then
print_info "Используется файл настроек: $PPDB_FILE"
. "$PPDB_FILE"
else
print_warning "Файл настроек не найден. Пропускаем."
fi
fi
}
prepair_wine () {
var_winedlloverride_update "winemenubuilder.exe="
init_database
init_wine_ver
init_wineprefix
use_winetricks
unset MANGOHUD_RUN
if init_opengl ; then
[[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud --dlsym"
else
init_dxvk
init_vkd3d
[[ "$MANGOHUD" == 1 ]] && MANGOHUD_RUN="mangohud"
fi
}
wine_run () {
print_var WINEPREFIX WINEDLLOVERRIDES PP_WINDOWS_VER
WIN_FILE_PATH="$(dirname "$WIN_FILE_EXEC")"
[[ -d "$WIN_FILE_PATH" ]] && cd "$WIN_FILE_PATH"
$MANGOHUD_RUN "$WINELOADER" "$@" $LAUNCH_PARAMETERS
wait_wineserver
}
wine_run_install () {
case "${1,,}" in
*.exe) wine_run $WINE_WIN_START "$@" ;;
*.msi) wine_run msiexec /i "$@" ;;
*.bat|*.cmd) wine_run "$@" ;;
*) fatal "Unknown file extension." ;;
esac
wait_wineserver
}
run_autoinstall () {
AI_SCRIPT="${1,,}"
if [[ $AI_SCRIPT == "list" ]] || [[ -z "$AI_SCRIPT" ]] ; then
print_info "Список программ с возможностью автоматической установки:"
for list in $(ls "$PP_AUTOINSTALL_DIR") ; do
AI_INFO="$(grep "info_ru:" "$PP_AUTOINSTALL_DIR/$list" | awk -F"info_ru: " '{print $2}')"
AI_PROGNAME="$(grep "PROG_NAME=" "$PP_AUTOINSTALL_DIR/$list" | awk -F"PROG_NAME=" '{print $2}')"
printf "\E[36m%s $SCRIPT_NAME install $list - $AI_PROGNAME %s\e[0m\n"
echo -e "$AI_INFO\n"
done
echo
elif [[ -f "$PP_AUTOINSTALL_DIR/$AI_SCRIPT" ]] ; then
export USE_AI_SCRIPTS="1"
source "$PP_AUTOINSTALL_DIR/$AI_SCRIPT"
print_info "Завершена установка $AI_SCRIPT"
else
fatal "Скрипт автоматической установки для $AI_SCRIPT не найден!"
fi
}
##### MAIN #####
create_new_dir "$PP_TMP_DIR"
create_new_dir "$PP_DIST_DIR"
create_new_dir "$PP_PREFIXES_DIR"
create_new_dir "$PP_VULKAN_LIBDIR"
case "${1,,}" in
killall) kill_wine ;;
winecfg) prepair_wine ; wine_run "winecfg" ;;
winereg|regedit) prepair_wine ; wine_run "regedit" ;;
winefile|explorer) prepair_wine ; wine_run "winefile" ;;
wineconsole|cmd) prepair_wine ; wine_run "wineconsole" ;;
winetricks) shift ; update_winetricks ; prepair_wine ; "$WINETRICKS" -q "$@" ;;
desktop) shift ; create_desktop "$@" ; exit 0 ;;
install|autoinstall|-ai) shift ; run_autoinstall "$1" ;;
*)
if [[ -f "$1" ]] ; then
WIN_FILE_EXEC="$(readlink -f "$1")"
WIN_FILE_NAME="$(basename "$WIN_FILE_EXEC")"
shift
case "${WIN_FILE_NAME,,}" in
*.exe) prepair_wine ; wine_run $WINE_WIN_START "$WIN_FILE_EXEC" "$@" ;;
*.msi) prepair_wine ; wine_run msiexec /i "$WIN_FILE_EXEC" "$@" ;;
*.bat|*.cmd) prepair_wine ; wine_run start "$WIN_FILE_EXEC" "$@" ;;
*) fatal "Тип файла не поддерживается." ;;
esac
else
print_info "Делать нечего... Выходим."
exit 0
fi
;;
esac