Expand local_machine docs and automation for connectivity, games, and ops.
Add proxy/VPN/telegram launchd and emergency runbooks; reorganize apps docs; document JA3 CrossOver runbook and Wine troubleshooting; add GOG/HoMM game scripts, disk cleanup guides, and gitea push-via-proxy helper. Ignore temp/. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
186
scripts/games/run-wine-exe.sh
Executable file
186
scripts/games/run-wine-exe.sh
Executable file
@@ -0,0 +1,186 @@
|
||||
#!/usr/bin/env bash
|
||||
# Универсальный запуск .exe в Whisky-bottle. См. docs/games/WINE_APPS_LAUNCH_RUNBOOK.md
|
||||
set -euo pipefail
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
# shellcheck source=config.sh
|
||||
source "${SCRIPT_DIR}/config.sh"
|
||||
|
||||
BOTTLE_NAME="${WINE_BOTTLE_NAME:-}"
|
||||
BOTTLE_ID="${WINE_BOTTLE_ID:-}"
|
||||
GOG_BOTTLE_MODE="${GOG_BOTTLE:-0}"
|
||||
PROFILE="plain"
|
||||
BACKGROUND=0
|
||||
LOG=""
|
||||
EXE_ARG=""
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Использование: run-wine-exe.sh [опции] <exe или путь Wine>
|
||||
|
||||
Опции:
|
||||
--bottle NAME Имя bottle в Whisky (напр. HoMM-OldenEra)
|
||||
--bottle-id UUID UUID bottle (приоритет над --bottle)
|
||||
--gog-bottle Bottle из scripts/games/gog/bottle.env
|
||||
--profile PROF plain | steam | gog | game | ja3 (по умолчанию plain)
|
||||
--background nohup, не ждать
|
||||
--log FILE лог при --background
|
||||
-h, --help
|
||||
|
||||
Примеры:
|
||||
run-wine-exe.sh --profile steam 'C:\Program Files (x86)\Steam\Steam.exe'
|
||||
run-wine-exe.sh --gog-bottle --profile gog ~/Downloads/setup.exe
|
||||
run-wine-exe.sh --bottle HoMM-OldenEra --profile game 'C:\...\game.exe'
|
||||
|
||||
Документация: docs/games/WINE_APPS_LAUNCH_RUNBOOK.md
|
||||
EOF
|
||||
}
|
||||
|
||||
resolve_bottle_dir() {
|
||||
if [[ "${GOG_BOTTLE_MODE}" != "1" && -z "${BOTTLE_ID}" && -z "${BOTTLE_NAME}" ]]; then
|
||||
# config.sh: HoMM-OldenEra по умолчанию
|
||||
return 0
|
||||
fi
|
||||
if [[ "${GOG_BOTTLE_MODE}" == "1" ]]; then
|
||||
local gog_cfg="${SCRIPT_DIR}/gog/bottle.env"
|
||||
if [[ ! -f "${gog_cfg}" ]]; then
|
||||
echo "❌ Нет gog/bottle.env — bash ${SCRIPT_DIR}/gog/use-bottle.sh <UUID>"
|
||||
exit 1
|
||||
fi
|
||||
# shellcheck source=/dev/null
|
||||
source "${gog_cfg}"
|
||||
BOTTLE_ID="${BOTTLE_ID:?}"
|
||||
BOTTLE_NAME="${BOTTLE_NAME:-GOG-Install}"
|
||||
fi
|
||||
if [[ -n "${BOTTLE_ID}" ]]; then
|
||||
local _f="${HOME}/Library/Containers/com.franke.Whisky/Bottles/${BOTTLE_ID}"
|
||||
local _i="${HOME}/Library/Containers/com.isaacmarovitz.Whisky/Bottles/${BOTTLE_ID}"
|
||||
if [[ -d "${_f}/drive_c" ]]; then
|
||||
BOTTLE_DIR="${_f}"
|
||||
WHISKY_LIBS="${HOME}/Library/Application Support/com.franke.Whisky"
|
||||
elif [[ -d "${_i}/drive_c" ]]; then
|
||||
BOTTLE_DIR="${_i}"
|
||||
WHISKY_LIBS="${HOME}/Library/Application Support/com.isaacmarovitz.Whisky"
|
||||
else
|
||||
echo "❌ Bottle не найден: ${BOTTLE_ID}"
|
||||
exit 1
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
if [[ -n "${BOTTLE_NAME}" ]]; then
|
||||
local d
|
||||
for d in "${HOME}/Library/Containers/com.franke.Whisky/Bottles"/* \
|
||||
"${HOME}/Library/Containers/com.isaacmarovitz.Whisky/Bottles"/*; do
|
||||
[[ -d "${d}/drive_c" ]] || continue
|
||||
if [[ "$(basename "${d}")" == "${BOTTLE_NAME}" ]] || \
|
||||
grep -q "BOTTLE_NAME=${BOTTLE_NAME}" "${d}/Metadata.plist" 2>/dev/null; then
|
||||
BOTTLE_DIR="${d}"
|
||||
if [[ "${d}" == *com.franke* ]]; then
|
||||
WHISKY_LIBS="${HOME}/Library/Application Support/com.franke.Whisky"
|
||||
else
|
||||
WHISKY_LIBS="${HOME}/Library/Application Support/com.isaacmarovitz.Whisky"
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "❌ Bottle по имени не найден: ${BOTTLE_NAME}"
|
||||
exit 1
|
||||
fi
|
||||
# default: HoMM from config.sh (already sourced)
|
||||
}
|
||||
|
||||
to_win_path() {
|
||||
local arg="$1"
|
||||
if [[ "${arg}" =~ ^[A-Za-z]:\\ ]]; then
|
||||
echo "${arg}"
|
||||
return 0
|
||||
fi
|
||||
if [[ ! -f "${arg}" ]]; then
|
||||
echo "❌ Нет файла: ${arg}" >&2
|
||||
exit 1
|
||||
fi
|
||||
local base dest
|
||||
base="$(basename "${arg}")"
|
||||
dest="${BOTTLE_DIR}/drive_c/${base}"
|
||||
cp -f "${arg}" "${dest}"
|
||||
echo "C:\\${base}"
|
||||
}
|
||||
|
||||
apply_profile() {
|
||||
case "${PROFILE}" in
|
||||
plain)
|
||||
export WINEPREFIX="${BOTTLE_DIR}"
|
||||
export WINEMSYNC=1 WINEESYNC=1
|
||||
export DYLD_LIBRARY_PATH="${WINE_LIB}:${DYLD_LIBRARY_PATH:-}"
|
||||
unset WINEDLLOVERRIDES 2>/dev/null || true
|
||||
;;
|
||||
steam)
|
||||
export_wine_env_steam
|
||||
;;
|
||||
gog)
|
||||
if [[ -f "${SCRIPT_DIR}/gog/config.sh" ]]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${SCRIPT_DIR}/gog/config.sh"
|
||||
export_wine_env_gog
|
||||
else
|
||||
export_wine_env_steam
|
||||
export WINEDLLOVERRIDES="gdiplus=n,b"
|
||||
fi
|
||||
;;
|
||||
game)
|
||||
export_wine_env_game
|
||||
;;
|
||||
ja3)
|
||||
if [[ -f "${SCRIPT_DIR}/gog/config.sh" ]]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${SCRIPT_DIR}/gog/config.sh"
|
||||
export_wine_env_ja3
|
||||
else
|
||||
export_wine_env_game
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "❌ Неизвестный профиль: ${PROFILE}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
export WINEDEBUG="${WINEDEBUG:--all}"
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--bottle) BOTTLE_NAME="$2"; shift 2 ;;
|
||||
--bottle-id) BOTTLE_ID="$2"; shift 2 ;;
|
||||
--gog-bottle) GOG_BOTTLE_MODE=1; shift ;;
|
||||
--profile) PROFILE="$2"; shift 2 ;;
|
||||
--background) BACKGROUND=1; shift ;;
|
||||
--log) LOG="$2"; shift 2 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
-*) echo "Неизвестная опция: $1"; usage; exit 1 ;;
|
||||
*) EXE_ARG="$1"; shift ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -n "${EXE_ARG}" ]] || { usage; exit 1; }
|
||||
|
||||
resolve_bottle_dir
|
||||
WINE64="${WHISKY_LIBS}/Libraries/Wine/bin/wine64"
|
||||
WINE_LIB="${WHISKY_LIBS}/Libraries/Wine/lib"
|
||||
[[ -x "${WINE64}" ]] || { echo "❌ Нет Wine: install-whiskywine-manual.sh"; exit 1; }
|
||||
[[ -d "${BOTTLE_DIR}/drive_c" ]] || { echo "❌ Нет drive_c в ${BOTTLE_DIR}"; exit 1; }
|
||||
|
||||
WIN_EXE="$(to_win_path "${EXE_ARG}")"
|
||||
apply_profile
|
||||
|
||||
echo "Bottle: ${BOTTLE_DIR##*/}"
|
||||
echo "Профиль: ${PROFILE}"
|
||||
echo "Запуск: ${WIN_EXE}"
|
||||
|
||||
if [[ "${BACKGROUND}" -eq 1 ]]; then
|
||||
LOG="${LOG:-/tmp/wine-exe-$(basename "${BOTTLE_DIR}").log}"
|
||||
: >"${LOG}"
|
||||
nohup "${WINE64}" "${WIN_EXE}" >>"${LOG}" 2>&1 &
|
||||
echo "Фон (PID $!), лог: ${LOG}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
exec "${WINE64}" "${WIN_EXE}"
|
||||
Reference in New Issue
Block a user