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:
238
scripts/games/gog/config.sh
Executable file
238
scripts/games/gog/config.sh
Executable file
@@ -0,0 +1,238 @@
|
||||
# GOG-only Wine/Whisky — без Steam, HoMM, export_wine_env_steam.
|
||||
GOG_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
GAMES_DIR="$(cd "${GOG_DIR}/.." && pwd)"
|
||||
GAMES_CACHE_DIR="${GAMES_DIR}/cache"
|
||||
|
||||
_env_file="${GOG_DIR}/bottle.env"
|
||||
if [[ -f "${_env_file}" ]]; then
|
||||
# shellcheck source=/dev/null
|
||||
source "${_env_file}"
|
||||
elif [[ -n "${GOG_BOTTLE_ID:-}" ]]; then
|
||||
BOTTLE_ID="${GOG_BOTTLE_ID}"
|
||||
BOTTLE_NAME="${GOG_BOTTLE_NAME:-GOG-Install}"
|
||||
else
|
||||
echo "❌ Нет bottle для GOG."
|
||||
echo " 1) Whisky → New Bottle (Windows 10 64-bit), имя GOG-Install"
|
||||
echo " 2) bash ${GOG_DIR}/list-bottles.sh"
|
||||
echo " 3) bash ${GOG_DIR}/use-bottle.sh <UUID>"
|
||||
echo ""
|
||||
echo " Не используйте bottle HoMM-OldenEra — там Steam, дампы и winedbg."
|
||||
exit 1
|
||||
fi
|
||||
unset _env_file
|
||||
|
||||
_FRANKE="${HOME}/Library/Containers/com.franke.Whisky/Bottles/${BOTTLE_ID}"
|
||||
_ISAAC="${HOME}/Library/Containers/com.isaacmarovitz.Whisky/Bottles/${BOTTLE_ID}"
|
||||
if [[ -d "${_FRANKE}/drive_c" ]]; then
|
||||
BOTTLE_DIR="${_FRANKE}"
|
||||
WHISKY_LIBS="${HOME}/Library/Application Support/com.franke.Whisky"
|
||||
elif [[ -d "${_ISAAC}/drive_c" ]]; then
|
||||
BOTTLE_DIR="${_ISAAC}"
|
||||
WHISKY_LIBS="${HOME}/Library/Application Support/com.isaacmarovitz.Whisky"
|
||||
else
|
||||
echo "❌ Bottle не найден: ${BOTTLE_NAME} (${BOTTLE_ID})"
|
||||
echo " Проверьте UUID: bash ${GOG_DIR}/list-bottles.sh"
|
||||
exit 1
|
||||
fi
|
||||
unset _FRANKE _ISAAC
|
||||
|
||||
WINE64="${WHISKY_LIBS}/Libraries/Wine/bin/wine64"
|
||||
WINE_LIB="${WHISKY_LIBS}/Libraries/Wine/lib"
|
||||
WINEPATH_BIN="${WHISKY_LIBS}/Libraries/Wine/bin/winepath"
|
||||
|
||||
gog_data_volume_path() {
|
||||
if [[ -d /System/Volumes/Data ]]; then
|
||||
echo /System/Volumes/Data
|
||||
else
|
||||
echo "${HOME}"
|
||||
fi
|
||||
}
|
||||
|
||||
gog_disk_free_kb() {
|
||||
df -k "$(gog_data_volume_path)" | awk 'NR==2 {print $4}'
|
||||
}
|
||||
|
||||
gog_disk_guard() {
|
||||
local min_gb="${1:-5}"
|
||||
local min_kb free_kb
|
||||
min_kb=$((min_gb * 1024 * 1024))
|
||||
free_kb="$(gog_disk_free_kb)"
|
||||
if [[ "${free_kb}" -lt "${min_kb}" ]]; then
|
||||
echo "❌ Мало места (<${min_gb} GB на Data)."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
gog_swap_used_mb() {
|
||||
local used
|
||||
used="$(sysctl vm.swapusage 2>/dev/null | sed -n 's/.*used = \([0-9.]*\)M.*/\1/p')"
|
||||
[[ -n "${used}" ]] || return 1
|
||||
printf '%.0f' "${used}"
|
||||
}
|
||||
|
||||
gog_swap_guard() {
|
||||
local max_mb="${1:-400}"
|
||||
local used
|
||||
used="$(gog_swap_used_mb)" || return 0
|
||||
if awk -v u="${used}" -v m="${max_mb}" 'BEGIN{exit !(u>=m)}'; then
|
||||
echo "❌ Swap уже ~${used}MB (лимит ${max_mb}MB) — запуск GOG/Wine запрещён."
|
||||
echo " bash ${GOG_DIR}/emergency-stop.sh"
|
||||
echo " затем перезагрузка Mac (swap macOS отдаёт медленно)"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# JA3/CrossOver: жёсткий стоп только если swap высокий И Wine/JA3 ещё живы.
|
||||
# «Залипший» swap после закрытия (macOS не отдал) — предупреждение, запуск разрешён.
|
||||
gog_wine_or_ja3_active() {
|
||||
pgrep -f 'JA3\.exe|wineserver|wine64-preloader|winedbg|wine64\.exe|CrossOver.*wine' >/dev/null 2>&1
|
||||
}
|
||||
|
||||
gog_swap_guard_ja3_launch() {
|
||||
local soft_mb="${1:-1200}"
|
||||
local hard_mb="${2:-4096}"
|
||||
local used
|
||||
used="$(gog_swap_used_mb)" || return 0
|
||||
if [[ "${JA3_IGNORE_SWAP:-0}" == "1" ]]; then
|
||||
echo "⚠️ JA3_IGNORE_SWAP=1 — swap ~${used}MB"
|
||||
return 0
|
||||
fi
|
||||
if gog_wine_or_ja3_active; then
|
||||
if awk -v u="${used}" -v m="${soft_mb}" 'BEGIN{exit !(u>=m)}'; then
|
||||
echo "❌ Swap ~${used}MB и Wine/JA3 ещё работают (лимит ${soft_mb}MB)."
|
||||
echo " bash ${GOG_DIR}/reset-ja3-crossover.sh или bash ${GOG_DIR}/emergency-stop.sh"
|
||||
echo " затем reboot Mac. Или: JA3_IGNORE_SWAP=1 bash …/run-ja3-crossover.sh"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
if awk -v u="${used}" -v m="${hard_mb}" 'BEGIN{exit !(u>=m)}'; then
|
||||
echo "❌ Swap ~${used}MB (лимит ${hard_mb}MB) — reboot Mac."
|
||||
echo " Или: JA3_IGNORE_SWAP=1 bash …/run-ja3-crossover.sh"
|
||||
return 1
|
||||
fi
|
||||
if awk -v u="${used}" -v m="${soft_mb}" 'BEGIN{exit !(u>=m)}'; then
|
||||
echo "⚠️ Swap ~${used}MB — залип после прошлых сессий (Wine не запущен). Запуск JA3…"
|
||||
echo " (reboot снизит swap; JA3_IGNORE_SWAP=1 — принудительный игнор)"
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Виртуальный стол Wine — окно CEF часто «есть в логах», но не видно на macOS без /desktop.
|
||||
GOG_VDESKTOP="${GOG_VDESKTOP:-1280x800}"
|
||||
# 0 = прямой GalaxyClient (рекомендуется; vdesktop — в Whisky Metadata или launch-galaxy-ui.sh).
|
||||
GOG_USE_WINEVDESKTOP="${GOG_USE_WINEVDESKTOP:-0}"
|
||||
# GOG_LAUNCH_FG=1 — exec в текущем терминале (лучше для видимости окна, блокирует shell).
|
||||
GOG_LAUNCH_FG="${GOG_LAUNCH_FG:-0}"
|
||||
# GOG_CEF_PROFILE=steam — добавить -cef-in-process-gpu (A/B если login пустой).
|
||||
# /deelevated — обязательно в Wine (иначе DeelevateStrategy + exit -31, см. WineHQ #41584).
|
||||
GOG_GALAXY_BASE_ARGS="${GOG_GALAXY_BASE_ARGS:-/runWithoutUpdating /deelevated}"
|
||||
GOG_GALAXY_CEF_ARGS="${GOG_GALAXY_CEF_ARGS:--allosarches -cef-force-32bit -no-cef-sandbox -cef-disable-gpu}"
|
||||
|
||||
gog_galaxy_cef_args_array() {
|
||||
local -a a=(${GOG_GALAXY_BASE_ARGS} ${GOG_GALAXY_CEF_ARGS})
|
||||
if [[ "${GOG_CEF_PROFILE:-}" == "steam" ]]; then
|
||||
a+=(-cef-in-process-gpu)
|
||||
fi
|
||||
printf '%s\n' "${a[@]}"
|
||||
}
|
||||
|
||||
export_wine_env_gog() {
|
||||
export WINEPREFIX="${BOTTLE_DIR}"
|
||||
export WINEMSYNC=1
|
||||
unset WINEESYNC 2>/dev/null || true
|
||||
local _wine_ext="${WHISKY_LIBS}/Libraries/Wine/lib/external"
|
||||
if [[ -d "${_wine_ext}/D3DMetal.framework" ]]; then
|
||||
export DYLD_FRAMEWORK_PATH="${_wine_ext}:${DYLD_FRAMEWORK_PATH:-}"
|
||||
export DYLD_LIBRARY_PATH="${_wine_ext}:${WINE_LIB}:${DYLD_LIBRARY_PATH:-}"
|
||||
else
|
||||
export DYLD_LIBRARY_PATH="${WINE_LIB}:${DYLD_LIBRARY_PATH:-}"
|
||||
fi
|
||||
unset _wine_ext
|
||||
export WINEDLLOVERRIDES="gdiplus=n,b"
|
||||
unset DXVK_ASYNC DXVK_HUD 2>/dev/null || true
|
||||
export WINEDEBUG=-all
|
||||
export MVK_CONFIG_LOG_LEVEL=0
|
||||
}
|
||||
|
||||
ja3_gptk_available() {
|
||||
[[ -d "${WHISKY_LIBS}/Libraries/Wine/lib/external/D3DMetal.framework" ]] && return 0
|
||||
[[ -f "${WHISKY_LIBS}/Libraries/.gptk_installed" ]] && return 0
|
||||
[[ -d "${WHISKY_LIBS}/D3DMetal" ]] && return 0
|
||||
[[ -d "${WHISKY_LIBS}/GPTK" ]] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
ja3_bottle_uses_d3dmetal() {
|
||||
local meta="${BOTTLE_DIR}/Metadata.plist"
|
||||
[[ -f "${meta}" ]] || return 1
|
||||
plutil -extract graphicsConfig.backend raw -o - "${meta}" 2>/dev/null | grep -q d3dMetal
|
||||
}
|
||||
|
||||
ja3_dxmt_installed() {
|
||||
[[ -f "${BOTTLE_DIR}/.ja3_dxmt_installed" ]]
|
||||
}
|
||||
|
||||
# JA3 = D3D12 (Porting Kit / GPTK). Без GPTK — best-effort D3D11+DXVK (d3d12=d).
|
||||
export_wine_env_ja3() {
|
||||
export_wine_env_gog
|
||||
if ja3_gptk_available || ja3_bottle_uses_d3dmetal; then
|
||||
export WINED3DMETAL=1
|
||||
unset DXVK_ASYNC DXVK_HUD DXVK_CONFIG_FILE 2>/dev/null || true
|
||||
# builtin d3d12/dxgi + libd3dshared.so; без n,b на GPTK PE
|
||||
export WINEDLLOVERRIDES="libxess,xess,dxcompiler,dxil,nvngx_dlss,XeFX,XeFX_Loader=d;gdiplus=n,b"
|
||||
return 0
|
||||
fi
|
||||
if ja3_dxmt_installed; then
|
||||
# DXMT builtin: не ставить dxgi/d3d11=n,b (ломает загрузку, c000007b).
|
||||
export WINEDLLOVERRIDES="d3d12=d;libxess,xess,dxcompiler,dxil,nvngx_dlss,XeFX,XeFX_Loader=d;gdiplus=n,b"
|
||||
else
|
||||
export WINEDLLOVERRIDES="d3d11,d3d10core=n,b;d3d12=d;libxess,xess,dxcompiler,dxil,nvngx_dlss,XeFX,XeFX_Loader=d;gdiplus=n,b"
|
||||
fi
|
||||
unset DXVK_ASYNC DXVK_HUD DXVK_CONFIG_FILE 2>/dev/null || true
|
||||
export SDL_VIDEO_MAC_FULLSCREEN_SPACES="${SDL_VIDEO_MAC_FULLSCREEN_SPACES:-0}"
|
||||
export MVK_CONFIG_RESUME_LOST_DEVICE=1
|
||||
}
|
||||
|
||||
export_wine_env_ja3_d3dmetal() {
|
||||
export_wine_env_gog
|
||||
export WINED3DMETAL=1
|
||||
export WINEDLLOVERRIDES="libxess,xess,dxcompiler,dxil,nvngx_dlss,XeFX,XeFX_Loader=d;gdiplus=n,b"
|
||||
unset DXVK_ASYNC DXVK_HUD 2>/dev/null || true
|
||||
}
|
||||
|
||||
gog_steam_client_in_bottle() {
|
||||
local f
|
||||
[[ -d "${BOTTLE_DIR}/drive_c/Program Files (x86)/Steam" ]] && return 0
|
||||
[[ -f "${BOTTLE_DIR}/drive_c/Program Files (x86)/Steam/steam.exe" ]] && return 0
|
||||
f="$(find "${BOTTLE_DIR}/drive_c" -maxdepth 4 -iname 'steam.exe' -print -quit 2>/dev/null || true)"
|
||||
[[ -n "${f}" ]]
|
||||
}
|
||||
|
||||
gog_assert_no_steam_client() {
|
||||
if gog_steam_client_in_bottle; then
|
||||
echo "❌ В bottle ${BOTTLE_NAME} найден Steam client — контур GOG/JA3 без Steam."
|
||||
echo " bash ${GOG_DIR}/purge-steam-from-bottle.sh"
|
||||
return 1
|
||||
fi
|
||||
if [[ "${BOTTLE_ID}" == "38412122-AAE1-4831-9F2E-6A0EB364B3F9" ]]; then
|
||||
echo "❌ Это bottle HoMM-OldenEra (Steam). JA3 только в GOG-Install:"
|
||||
echo " bash ${GOG_DIR}/use-bottle.sh <UUID-GOG-Install>"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
gog_wine_check() {
|
||||
if [[ ! -x "${WINE64}" ]]; then
|
||||
echo "Нет Wine: bash ${GAMES_DIR}/install-whiskywine-manual.sh"
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -d "${BOTTLE_DIR}/drive_c" ]]; then
|
||||
echo "❌ Нет drive_c в ${BOTTLE_DIR}"
|
||||
echo " Откройте bottle «${BOTTLE_NAME}» в Whisky один раз."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
Reference in New Issue
Block a user