hit-mc / hitmc

Bug tracker & RFC proposal
11 stars 0 forks source link

[Feature Request]贡献一波土法自制的非MCDR开服的自动重启&养肝脚本 #20

Closed SpiritedDragonet closed 1 year ago

SpiritedDragonet commented 1 year ago

让非MCDR开起来的服务器也能自动重启,并且同样具有300秒内开启失败三次自动停止重启的功能

#!/bin/bash
# pidof -x $(basename "$0") -o $$ >/dev/null || exit 1;
# Check if current script is already running

# Set variables
DS_DIR="$MC_DIR/Nealmc/DragonSurvival"
PROCESS_NAME="startup.jar"
RESTART_INTERVAL=300  # Restart interval in seconds
MAX_RESTART_COUNT=3  # Maximum number of restart attempts
RESTART_DELAY=1800  # Delay during which no restarts should be attempted, in seconds. This is for the interval between 1am and 7am.

# Initialize variables

last_restart_time=$(date +%s)
restart_count=0

while true; do
    hour=$(TZ=Asia/Shanghai date +%H)
    if [ $hour -ge 1 ] && [ $hour -lt 7 ]; then
        echo "Stop restarting between 1:00am and 7:00am. awa "
        sleep $RESTART_DELAY
        continue
    fi
    # Check if current time is within the restart delay period 0w0(这一段是附加的养肝脚本,可选)

    process_status=$(ps -ef | grep "${PROCESS_NAME}" | grep -v "grep")

    if [ -z "$process_status" ]; then
        # Process is not running
        echo "Process has been started! 0w0"
    cd ${DS_DIR}

        # startup command !0w0 (这里服务器启动参数,建议参考网站https://flags.sh.cn/来定制启动参数)
        java -jar -Xms10G -Xmx40G -Dfile.encoding=UTF-8 -Dfml.queryResult=confirm -Duser.timezone=Asia/Shanghai -Dlog4j2.formatMsgNoLookups=true "${PROCESS_NAME}" nogui

        current_time=$(date +%s)

        if [ "$((current_time-last_restart_time))" -gt "$RESTART_INTERVAL" ]; then
            # Time since last restart has exceeded the restart interval, so attempt a restart
            last_restart_time=$current_time
            restart_count=0
        else
            # Time since last restart is less than the restart interval, so increment restart attempt counter
            restart_count=$((restart_count+1))
            echo "Process is not running. ($restart_count//$MAX_RESTART_COUNT) xwx."
            if [ "$restart_count" -ge "$MAX_RESTART_COUNT" ]; then
                # Maximum number of restart attempts has been reached, so exit the script
                echo "Failed to start the process after $MAX_RESTART_COUNT attempts. Exiting script. xwx"
                exit 1
            fi
        fi
    else
        # Process is already running
        echo "Process is already running! xwx"
        last_restart_time=$(date +%s)
        exit 1
    fi
    sleep 1
done
# Check if the process has been down for 300 seconds and automatically restart the server

上面这一段脚本主要功能是移动到MC目录开服,300秒之内停服超3次自动退出脚本,300秒之外停服

辅助功能是养肝,这是因为自己测试这个脚本的小服一个个的都太肝了,过年那会十来个玩家天天肝到三点才睡,我一看不行,才加了这条防沉迷规则,这一部分剔除出去后不会影响主要功能的运行,可选

第二段脚本的作用是保护上一段脚本(名为autostart.sh)的运行,同时也使用了计划任务crontab和tmux插入命令的方式实现了到点自动倒计时预警&防沉迷关服的功能

#!/usr/local/bin/zsh

# define some variables
MC_DIR="/srv/minecraft"
SESSION_NAME="minecraft"
WINDOW_NAME="DragonSurvival"
MINECRAFT_COMMAND="minecraft:DragonSurvival"

# start a new session named 'minecraft' and don't attach to it
tmux new-session -ds "$SESSION_NAME"

# DS-server
if ! tmux list-windows -F "#{window_name}" | grep -q "^$WINDOW_NAME$"; then
    # start a new session named 'minecraft' and don't attach to it
    tmux new-session -ds "$SESSION_NAME"
    tmux new-window -n "$WINDOW_NAME" -t "$SESSION_NAME"
fi

cd $MC_DIR/scripts && ./autostart.sh

# say a countdown message 40 10 5 1 minutes before stop_time

stop_time=$(date -d "tomorrow 01:00" +%s)

crontab -l | grep -v "$MC_DIR/scripts/start.sh" | crontab -
echo "30 7 * * * bash $MC_DIR/scripts/start.sh" | crontab -
(crontab -l 2>/dev/null; echo "20 0 * * 1,2,3,4,5,7 tmux send-keys -t $MINECRAFT_COMMAND 'say The server will quantumize in 40 minutes.' ENTER") | crontab -
(crontab -l 2>/dev/null; echo "50 0 * * 1,2,3,4,5,7 tmux send-keys -t $MINECRAFT_COMMAND 'say The server will quantumize in 10 minutes.' ENTER") | crontab -
(crontab -l 2>/dev/null; echo "55 0 * * 1,2,3,4,5,7 tmux send-keys -t $MINECRAFT_COMMAND 'say The server will quantumize in 5 minutes.' ENTER") | crontab -
(crontab -l 2>/dev/null; echo "59 0 * * 1,2,3,4,5,7 tmux send-keys -t $MINECRAFT_COMMAND 'say The server will quantumize in 1 minute.' ENTER") | crontab -
(crontab -l 2>/dev/null; echo "59 0 * * 1,2,3,4,5,7 bash $MC_DIR/scripts/countdown.sh") | crontab -
(crontab -l 2>/dev/null; echo "0 1 * * 1,2,3,4,5,7 tmux send-keys -t $MINECRAFT_COMMAND 'stop' ENTER") | crontab -

echo "Scheduled stop and countdown messages for $(date -d @$stop_time)"

第二段脚本具体实现的功能是开启并保护第一个脚本的进程(顺便保护自己),创建指定mc服务器专属tmux窗口,以及使用计划任务的方式,在零点20,零点50,零点55,零点59自动向服务器里发送倒计时提醒,以及最后的关服指令(周六除外),开启第一个脚本后第一个脚本会在早上七点自动开服,或者除了半夜之外的任意时刻被唤醒都可以立刻开服

下面是第三段脚本,被第二段脚本引用,名为countdown.sh,用于关服前最后30秒的倒计时

#!/bin/bash
MINECRAFT_COMMAND="minecraft:DragonSurvival"
sleep 29
tmux send-keys -t $MINECRAFT_COMMAND 'say The server will quantumize in 30 seconds' ENTER
sleep 20
# Start the countdown
for (( i=10; i>=0; i-- ))
do
    tmux send-keys -t $MINECRAFT_COMMAND "say $i" ENTER
    sleep 1
done

计划任务其实还可以用at方式实现,但我测试的时候发现at命令死活读不了时间戳格式,遂放弃了 经过一段时间的测试,发现这个脚本运行很稳定,遂发出供大伙参考

CC @inclyc @Phychias

inclyc commented 1 year ago

有个问题是为什么要不用MCDR开服?

SpiritedDragonet commented 1 year ago

有个问题是为什么要不用MCDR开服?

我这里当时拿MCDR挂forge服,启动是启动了,但是里面的entity运动巨卡,严重影响游戏体验,用回forge开服就没这个问题了。