#!/usr/bin/env bash # JA3: multipart GOG → innoextract в bottle (без Wine-Inno). Экономия диска: .bin удаляются по ходу. set -euo pipefail GOG_DIR="$(cd "$(dirname "$0")" && pwd)" # shellcheck source=config.sh source "${GOG_DIR}/config.sh" JA3_GAMES_DIR="${JA3_GAMES_DIR:-${HOME}/Games}" JA3_PREFIX='setup_jagged_alliance_3_1.5.2_(80730)' JA3_EXE="${JA3_GAMES_DIR}/${JA3_PREFIX}.exe" JA3_TARGET="${BOTTLE_DIR}/drive_c/GOG Games/Jagged Alliance 3" MARKER="${BOTTLE_DIR}/.ja3_installed" LOG="/tmp/ja3-innoextract-${BOTTLE_NAME}.log" JA3_MIN_FREE_MB="${JA3_MIN_FREE_MB:-800}" JA3_KEEP_BINS="${JA3_KEEP_BINS:-0}" gog_disk_free_mb() { local kb kb="$(gog_disk_free_kb)" echo $((kb / 1024)) } gog_disk_watch() { local min_mb="$1" local free free="$(gog_disk_free_mb)" if [[ "${free}" -lt "${min_mb}" ]]; then echo "❌ Мало места на диске: ${free} MB свободно (нужно ≥${min_mb} MB)" >&2 df -h "$(gog_data_volume_path)" | awk 'NR==2' >&2 return 1 fi return 0 } gog_ja3_safe_cleanup() { local freed=0 local d f for d in \ "${GAMES_CACHE_DIR}/gog-galaxy-extract-gog-bottle" \ "${GAMES_CACHE_DIR}/ja3-extract-test" \ "${GAMES_CACHE_DIR}/ja3-innoextract-staging"; do if [[ -d "${d}" ]]; then local sz sz="$(du -sk "${d}" | awk '{print $1}')" rm -rf "${d}" freed=$((freed + sz)) echo " удалён cache: ${d}" fi done if [[ -f "${GAMES_CACHE_DIR}/setup_galaxy.exe" ]] \ && [[ -f "${BOTTLE_DIR}/drive_c/Program Files (x86)/GOG Galaxy/GalaxyClient.exe" ]]; then f="${GAMES_CACHE_DIR}/setup_galaxy.exe" sz="$(du -sk "${f}" | awk '{print $1}')" rm -f "${f}" freed=$((freed + sz)) echo " удалён setup_galaxy.exe (Galaxy уже в bottle)" fi if [[ "${freed}" -gt 0 ]]; then echo "Освобождено ~$((freed / 1024)) MB (cache)" fi } ja3_bin_path() { echo "${JA3_GAMES_DIR}/${JA3_PREFIX}-$1.bin" } ja3_delete_bin() { local n="$1" local p p="$(ja3_bin_path "${n}")" if [[ -f "${p}" ]]; then rm -f "${p}" echo " 🗑 удалён $(basename "${p}") (~$(du -sh "${p}" 2>/dev/null | cut -f1 || echo '?'))" gog_disk_watch "${JA3_MIN_FREE_MB}" || true fi } ja3_delete_all_bins() { local n for n in 1 2 3 4; do ja3_delete_bin "${n}" || true done if [[ -f "${JA3_EXE}" && "${JA3_KEEP_BINS}" != "1" ]]; then rm -f "${JA3_EXE}" echo " 🗑 удалён $(basename "${JA3_EXE}")" fi } ja3_watch_bins() { local line opened=0 while IFS= read -r line; do printf '%s\n' "${line}" case "${line}" in *"Opening \"${JA3_PREFIX}-2.bin\""*) ja3_delete_bin 1 opened=2 ;; *"Opening \"${JA3_PREFIX}-3.bin\""*) ja3_delete_bin 2 opened=3 ;; *"Opening \"${JA3_PREFIX}-4.bin\""*) ja3_delete_bin 3 opened=4 ;; esac gog_disk_watch "${JA3_MIN_FREE_MB}" || return 1 done if [[ "${opened}" -ge 4 ]]; then ja3_delete_bin 4 || true fi } verify() { local n [[ -f "${JA3_EXE}" ]] || { echo "❌ Нет: ${JA3_EXE}" return 1 } for n in 1 2 3 4; do [[ -f "$(ja3_bin_path "${n}")" ]] || { echo "❌ Нет: $(ja3_bin_path "${n}")" return 1 } done command -v innoextract >/dev/null 2>&1 || { echo "❌ brew install innoextract" return 1 } } main() { verify || exit 1 gog_wine_check if [[ -f "${JA3_TARGET}/JA3.exe" ]]; then echo "JA3 уже установлен: ${JA3_TARGET}/JA3.exe" exit 0 fi bash "${GOG_DIR}/emergency-stop.sh" || true echo "=== Очистка cache (без трогания архивов игры) ===" gog_ja3_safe_cleanup gog_disk_watch "${JA3_MIN_FREE_MB}" || { echo "❌ Перед установкой нужно ≥$((JA3_MIN_FREE_MB / 1024)) GB свободно." exit 1 } echo "" echo "Свободно на Data: $(gog_disk_free_mb) MB" echo "Распаковка JA3 → ${JA3_TARGET}" echo "Лог: ${LOG}" echo "(архивы .bin удаляются по мере чтения innoextract)" echo "" rm -rf "${JA3_TARGET}" mkdir -p "${JA3_TARGET}" : >"${LOG}" cd "${JA3_GAMES_DIR}" set +e innoextract -e -m -d "${JA3_TARGET}" "$(basename "${JA3_EXE}")" 2>&1 \ | tee "${LOG}" | ja3_watch_bins local rc=${PIPESTATUS[0]} set -e if [[ "${rc}" -ne 0 ]]; then echo "" echo "❌ innoextract exit ${rc}" tail -15 "${LOG}" 2>/dev/null || true df -h "$(gog_data_volume_path)" | awk 'NR==2' if [[ "${JA3_CLEANUP_PARTIAL:-1}" == "1" ]]; then echo "Удаляю незавершённую распаковку в bottle…" rm -rf "${JA3_TARGET}" fi exit 1 fi if [[ -f "${JA3_TARGET}/JA3.exe" ]]; then bash "${GOG_DIR}/finish-ja3-layout.sh" date -u +"%Y-%m-%dT%H:%M:%SZ" >"${MARKER}" if [[ "${JA3_KEEP_BINS}" != "1" ]]; then echo "" echo "Удаляю GOG-архивы (~15 GB)…" ja3_delete_all_bins fi echo "" echo "OK: JA3 установлен." echo " Свободно: $(gog_disk_free_mb) MB" echo " Запуск: bash ${GOG_DIR}/run-ja3.sh" else echo "❌ JA3.exe не найден" find "${JA3_TARGET}" -maxdepth 2 -iname 'JA3.exe' 2>/dev/null | head -5 exit 1 fi } main "$@"