Files
PupaMLupa/Server/clear-ground-items-hourly.sh

135 lines
5.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Почасовая очистка выброшенных на земле предметов (сущность item) через RCON
# с тем же графиком предупреждений, что и restart-scheduled.sh (10 / 5 / 1 мин, 30 с, 5…1).
#
# Требования: RCON как в restart-scheduled.sh (mcrcon или rcon), server.properties,
# сервер в systemd active (по умолчанию unit minecraft).
#
# Расписание (cron достаточно, отдельная блокировка между скриптами не обязательна):
# Перезапуск обычно: 0 */6 * * * → в :00 часов 0, 6, 12, 18.
# Очистку не ставьте в те же :00 — иначе ~10 минут предупреждений пересекутся.
# Рекомендуется каждый час в половине часа (после типичного перезапуска уже всё тихо):
# 30 * * * * /usr/bin/bash /opt/PupaMLupa/Server/clear-ground-items-hourly.sh >>/var/log/mc-clear-items.log 2>&1
# Другой вариант — одна фиксированная минута, не кратная 6-часовому перезапуску, например:
# 17 * * * * … (каждый час в :17)
#
# Переменные окружения (необязательно):
# MINECRAFT_SERVICE — unit systemd (по умолчанию: minecraft)
# RCON_HOST, RCON_PORT, RCON_PASSWORD, RCON_TIMEOUT — как в restart-scheduled.sh
# CLEAR_ITEMS_RCON_CMD — команда консоли без ведущего / (по умолчанию:
# kill @e[type=item] — то же, что /kill в игре)
set -euo pipefail
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PATH:-}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "${SCRIPT_DIR}"
MINECRAFT_SERVICE="${MINECRAFT_SERVICE:-minecraft}"
RCON_HOST="${RCON_HOST:-127.0.0.1}"
RCON_TIMEOUT="${RCON_TIMEOUT:-60s}"
RCON_CLIENT=""
CLEAR_ITEMS_RCON_CMD="${CLEAR_ITEMS_RCON_CMD:-kill @e[type=item]}"
LOCK_FILE="${SCRIPT_DIR}/.clear-ground-items-hourly.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"
if [[ "${RCON_CLIENT}" == "mcrcon" ]]; then
mcrcon -H "${RCON_HOST}" -P "${RCON_PORT}" -p "${RCON_PASSWORD}" "${cmd}"
else
set -f
# shellcheck disable=SC2086
rcon -a "${RCON_HOST}:${RCON_PORT}" -p "${RCON_PASSWORD}" -T "${RCON_TIMEOUT}" ${cmd}
set +f
fi
}
rcon_say() {
rcon_exec "say $1"
}
exec 9>"${LOCK_FILE}"
if ! flock -n 9; then
log "уже идёт другой запуск (flock ${LOCK_FILE}) — выход."
exit 0
fi
if command -v mcrcon >/dev/null 2>&1; then
RCON_CLIENT="mcrcon"
elif command -v rcon >/dev/null 2>&1; then
RCON_CLIENT="rcon"
else
die "нужен mcrcon или rcon (см. restart-scheduled.sh в этом каталоге)."
fi
log "RCON-клиент: ${RCON_CLIENT}"
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"
_prop_port="$(read_prop rcon.port)"
_prop_pass="$(read_prop rcon.password)"
RCON_PORT="${RCON_PORT:-${_prop_port}}"
RCON_PASSWORD="${RCON_PASSWORD:-${_prop_pass}}"
[[ -n "${RCON_PORT}" ]] || die "не задан rcon.port (или RCON_PORT)"
[[ -n "${RCON_PASSWORD}" ]] || die "не задан rcon.password (или RCON_PASSWORD)"
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 "Выполняю: ${CLEAR_ITEMS_RCON_CMD}"
rcon_exec "${CLEAR_ITEMS_RCON_CMD}"
rcon_say "[Сервер] Лежащие предметы очищены."
log "Готово."