Add clear-ground-items-hourly.sh script for hourly item cleanup on Minecraft server via RCON. Update .gitignore to include the new script.

This commit is contained in:
Leonid Pershin
2026-05-09 22:23:54 +03:00
parent 6401472a42
commit 26757e96e2
2 changed files with 132 additions and 0 deletions
+1
View File
@@ -42,6 +42,7 @@
!/Server/extract-missing-ru-translations.ps1 !/Server/extract-missing-ru-translations.ps1
!/Server/install-service.sh !/Server/install-service.sh
!/Server/restart-scheduled.sh !/Server/restart-scheduled.sh
!/Server/clear-ground-items-hourly.sh
!/Server/README.md !/Server/README.md
!/Server/start.sh !/Server/start.sh
!/Server/variables.txt !/Server/variables.txt
+131
View File
@@ -0,0 +1,131 @@
#!/usr/bin/env bash
# Почасовая очистка выброшенных на земле предметов (сущность minecraft:item) через RCON
# с тем же графиком предупреждений, что и restart-scheduled.sh (10 / 5 / 1 мин, 30 с, 5…1).
#
# Требования: RCON как в restart-scheduled.sh (mcrcon или rcon), server.properties,
# сервер в systemd active (по умолчанию unit minecraft).
#
# Расписание — каждый час, например в начале часа:
# 0 * * * * /usr/bin/bash /opt/PupaMLupa/Server/clear-ground-items-hourly.sh >>/var/log/mc-clear-items.log 2>&1
# Чтобы не пересекаться по времени с перезапуском в 00:00 / 06:00 / 12:00 / 18:00, можно сместить:
# 30 * * * * .../clear-ground-items-hourly.sh ...
#
# Переменные окружения (необязательно):
# MINECRAFT_SERVICE — unit systemd (по умолчанию: minecraft)
# RCON_HOST, RCON_PORT, RCON_PASSWORD, RCON_TIMEOUT — как в restart-scheduled.sh
# CLEAR_ITEMS_RCON_CMD — команда консоли без ведущего / (по умолчанию:
# kill @e[type=minecraft:item])
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=minecraft: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 "Готово."