diff --git a/.gitignore b/.gitignore index 047c4dd..edc7bbf 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ !/Server/sync-mods-from-client.ps1 !/Server/extract-missing-ru-translations.ps1 !/Server/install-service.sh +!/Server/restart-scheduled.sh !/Server/README.md !/Server/start.sh !/Server/variables.txt @@ -64,3 +65,4 @@ /config/fabric/indigo-renderer.properties /options.txt shaderpacks/ComplementaryReimagined_r5.7.1 + EuphoriaPatches_1.8.6.txt +config/ars_nouveau/search_index/ \ No newline at end of file diff --git a/Server/restart-scheduled.sh b/Server/restart-scheduled.sh new file mode 100755 index 0000000..c9e1e7d --- /dev/null +++ b/Server/restart-scheduled.sh @@ -0,0 +1,132 @@ +#!/usr/bin/env bash +# Плановый перезапуск Minecraft-сервера с предупреждениями в чат (RCON) и +# корректной остановкой (save-all flush + stop). После stop unit systemd +# сам не поднимется при Restart=on-failure — скрипт делает systemctl start. +# +# Требования: +# - В server.properties: enable-rcon=true, rcon.password=..., rcon.port=... +# - Утилита mcrcon в PATH (см. README.md в этом каталоге) +# - Права на systemctl для сервиса (удобнее всего — crontab root) +# +# Расписание (каждые 6 часов: 00:00, 06:00, 12:00, 18:00): +# crontab -e +# 0 */6 * * * /opt/PupaMLupa/Server/restart-scheduled.sh >>/var/log/mc-restart.log 2>&1 +# +# Переменные окружения (необязательно): +# MINECRAFT_SERVICE — имя unit (по умолчанию: minecraft) +# RCON_HOST — хост RCON (по умолчанию: 127.0.0.1) +# STOP_WAIT_SEC — макс. ожидание выхода процесса после stop (по умолчанию: 180) + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "${SCRIPT_DIR}" + +MINECRAFT_SERVICE="${MINECRAFT_SERVICE:-minecraft}" +RCON_HOST="${RCON_HOST:-127.0.0.1}" +STOP_WAIT_SEC="${STOP_WAIT_SEC:-180}" + +LOCK_FILE="${SCRIPT_DIR}/.restart-scheduled.lock" +PROPS="${SCRIPT_DIR}/server.properties" + +log() { + echo "[$(date -Iseconds)] $*" +} + +die() { + log "ОШИБКА: $*" >&2 + exit 1 +} + +read_prop() { + local key="$1" + [[ -f "${PROPS}" ]] || die "нет файла ${PROPS}" + grep -E "^[[:space:]]*${key}[[:space:]]*=" "${PROPS}" 2>/dev/null | head -n1 \ + | cut -d= -f2- | tr -d '\r' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' +} + +systemctl_wrap() { + if [[ "${EUID:-0}" -eq 0 ]]; then + systemctl "$@" + elif command -v sudo >/dev/null 2>&1 && sudo -n true 2>/dev/null; then + sudo -n systemctl "$@" + else + systemctl "$@" + fi +} + +rcon_exec() { + local cmd="$1" + mcrcon -H "${RCON_HOST}" -P "${RCON_PORT}" -p "${RCON_PASSWORD}" "${cmd}" +} + +rcon_say() { + rcon_exec "say $1" +} + +# --- блокировка: не запускать два перезапуска одновременно --- +exec 9>"${LOCK_FILE}" +if ! flock -n 9; then + log "уже идёт другой запуск (flock ${LOCK_FILE}) — выход." + exit 0 +fi + +command -v mcrcon >/dev/null 2>&1 || die "нужна утилита mcrcon (например: apt install mcrcon или сборка с https://github.com/Tiiffi/mcrcon)" + +if ! systemctl_wrap is-active --quiet "${MINECRAFT_SERVICE}"; then + log "сервис ${MINECRAFT_SERVICE} не active — перезапуск не выполняется." + exit 0 +fi + +rc_en="$(read_prop enable-rcon)" +[[ "${rc_en,,}" == "true" ]] || die "в server.properties включите enable-rcon=true" + +RCON_PORT="$(read_prop rcon.port)" +RCON_PASSWORD="$(read_prop rcon.password)" +[[ -n "${RCON_PORT}" ]] || die "не задан rcon.port" +[[ -n "${RCON_PASSWORD}" ]] || die "не задан rcon.password" + +# Проверка RCON +rcon_exec "list" >/dev/null || die "RCON не отвечает (хост ${RCON_HOST}, порт ${RCON_PORT})" + +log "Начало планового перезапуска (${MINECRAFT_SERVICE})." + +rcon_say "[Сервер] Плановый перезапуск через 10 минут!" +sleep 300 + +rcon_say "[Сервер] Перезапуск через 5 минут!" +sleep 240 + +rcon_say "[Сервер] Перезапуск через 1 минуту!" +sleep 30 + +rcon_say "[Сервер] Перезапуск через 30 секунд!" +sleep 25 + +for n in 5 4 3 2 1; do + rcon_say "[Сервер] $n" + sleep 1 +done + +log "Сохранение мира и остановка..." +rcon_exec "save-all flush" || true +sleep 3 +rcon_exec "stop" + +_waited=0 +while systemctl_wrap is-active --quiet "${MINECRAFT_SERVICE}"; do + if ((_waited >= STOP_WAIT_SEC)); then + die "таймаут ${STOP_WAIT_SEC}s: сервис всё ещё active после stop" + fi + sleep 2 + _waited=$((_waited + 2)) +done + +log "Процесс остановлен, запускаю сервис..." +systemctl_wrap start "${MINECRAFT_SERVICE}" +sleep 2 +if systemctl_wrap is-active --quiet "${MINECRAFT_SERVICE}"; then + log "Готово: ${MINECRAFT_SERVICE} снова active." +else + die "systemctl start не поднял сервис — проверьте: systemctl status ${MINECRAFT_SERVICE}" +fi diff --git a/config/ars_nouveau/search_index/_0.cfe b/config/ars_nouveau/search_index/_0.cfe deleted file mode 100644 index 1c6e668..0000000 Binary files a/config/ars_nouveau/search_index/_0.cfe and /dev/null differ diff --git a/config/ars_nouveau/search_index/_0.cfs b/config/ars_nouveau/search_index/_0.cfs deleted file mode 100644 index ba9b7da..0000000 Binary files a/config/ars_nouveau/search_index/_0.cfs and /dev/null differ diff --git a/config/ars_nouveau/search_index/_0.si b/config/ars_nouveau/search_index/_0.si deleted file mode 100644 index ac1915e..0000000 Binary files a/config/ars_nouveau/search_index/_0.si and /dev/null differ diff --git a/config/ars_nouveau/search_index/segments_1 b/config/ars_nouveau/search_index/segments_1 deleted file mode 100644 index e53792b..0000000 Binary files a/config/ars_nouveau/search_index/segments_1 and /dev/null differ diff --git a/config/ars_nouveau/search_index/write.lock b/config/ars_nouveau/search_index/write.lock deleted file mode 100644 index e69de29..0000000