Minecraft服务器的世界边界修剪脚本

时间:2012-08-12 09:31:02

标签: bash

我正在尝试创建一个脚本,每天凌晨5点修剪一个Minecraft服务器的世界。到目前为止,它运行命令/ wb $ NAME trim,其中$ NAME是世界的名称,然后它运行命令/ wb trim confirm,以初始化修剪过程。

#!/bin/bash
# /usr/local/bin/trim
# Title: World Border Trim Automator
# Author: Jonathan Bondhus

######### CONFIG STARTS HERE #########

# Location of the init script
INIT_SCRIPT="/etc/init.d/minecraft"

# Name to use for the screen instance
SCREEN="minecraft"

# User that should run the server
USERNAME="minecraft"

# Path to minecraft server directory 
MCPATH="/home/${USERNAME}/minecraft"

# Where the worlds are located on the disk
WORLDSTORAGE="${MCPATH}/worlds"

######### CONFIG ENDS HERE #########

## Start of script, don't edit anything below this line unless you know what you are doing

as_user() {
    if [ $ME == $USERNAME ] ; then
        bash -c "$1"
    else
        su $USERNAME -s /bin/bash -c "$1"
    fi
}

my_trim() {
    a=1
    for NAME in $(ls $WORLDSTORAGE)
    do
        if [ -d $WORLDSTORAGE/$NAME ]
        then
            WORLDNAME[$a]=$NAME
            a=$a+1
            # Run the /wb trim command
            echo "Running /wb $NAME trim..."
            as_user "screen -p 0 -S $SCREEN -X eval 'stuff \"wb $NAME trim\"\015'"
            sleep 2     # Wait 2 seconds
            echo "Running /wb trim confirm..."
            as_user "screen -p 0 -S $SCREEN -X eval 'stuff \"wb trim confirm\"\015'"
            echo "Waiting 10 minutes for trim to complete"
            sleep 600   # Wait 10 minutes (600 seconds)
        fi
    done
}

my_is_running(){
    # Checks for the minecraft servers screen session
    # returns true if it exists.
    if ps ax | grep -v grep | grep "$SCREEN $INVOCATION" > /dev/null
    then
        return 0
    fi
    return 1
}

my_main(){
    ME=`whoami`     # Sets $ME to equal the current user's username
    my_is_running
    if my_is_running
        then
            my_trim
        else
            echo "Server is not running... Starting..."
            my_as_user "$INIT_SCRIPT start"
            wait 100
    fi
}

my_as_user() {
    if [ $me == $username ] ; then
        bash -c "$1"
    else
        su $USERNAME -s /bin/bash -c "$1"
    fi
}

my_main
exit 0

有一个问题。如果在修剪过程仍在进行时尝试再次运行它,则服务器将忽略该请求,并且脚本将继续运行,就好像什么都没有出错一样。我想要它做的是检查日志,直到它发现修剪完成。修剪中的日志文件如下所示:

2012-08-12 03:58:08 [INFO] World trimming task is ready for world "world", trimming the map past 208 blocks beyond the border (default 208), and the task will try to process up to 5000 chunks per second (default 5000).
2012-08-12 03:58:08 [INFO] This process can take a while depending on the world's overall size. Also, depending on the chunk processing rate, players may experience lag for the duration.
2012-08-12 03:58:08 [INFO] You should now use wb trim confirm to start the process.
2012-08-12 03:58:08 [INFO] You can cancel at any time with wb trim cancel, or pause/unpause with wb trim pause.
2012-08-12 03:58:10 [INFO] WorldBorder map trimming task started.
2012-08-12 03:58:35 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 216 individual chunk(s) trimmed so far (11.8% done)
2012-08-12 04:00:04 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 1016 individual chunk(s) trimmed so far (25.5% done)
2012-08-12 04:01:55 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 1975 individual chunk(s) trimmed so far (36.6% done)
2012-08-12 04:03:18 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 2718 individual chunk(s) trimmed so far (45.2% done)
2012-08-12 04:03:58 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 3084 individual chunk(s) trimmed so far (52.7% done)
2012-08-12 04:04:12 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 3203 individual chunk(s) trimmed so far (61.1% done)
2012-08-12 04:05:07 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 3690 individual chunk(s) trimmed so far (73.5% done)
2012-08-12 04:05:53 [INFO] [WorldBorder] [Trim] 0 entire region(s) and 4080 individual chunk(s) trimmed so far (100.0% done)
2012-08-12 04:05:53 [INFO] [WorldBorder] [Trim] task successfully completed!

当然,日志不仅包含世界边界信息,还包含人们的聊天记录,以及记录发生的所有其他内容。因此,我不能只拖尾日志的最后10行并检查,因为一旦10行已经过去(例如,在检查最后10行之前脚本等待的间隔中打印超过10行的错误) ,它永远不会找到任何会导致它意识到它完成的东西,所以它会永远等待,耗尽宝贵的资源并阻止世界被削减,直到我注意到某些东西是错的,这可能自从它自动化以来需要几天甚至几周。

它不仅必须在它完成时停止,仅限于那个世界,但它必须记录它开始修剪世界的时间和分钟,并且只在那之后检查,因为如果我修剪了同一个世界之前它会导致问题,因为在该日志的日志中已经存在“任务成功完成”,这将导致脚本几乎立即停止。有没有人看到这个解决方案?这让我头疼,只是想着它......:P

1 个答案:

答案 0 :(得分:1)

你会发现在脚本/函数运行时使用'.lock'文件有什么好处,并在任何完成时删除它(错误或其他)?

锁定文件是一个0字节(空)文件,具有唯一名称(通常与文件名相同,末尾附加'.lock')。运行脚本时,请检查该文件是否存在。如果它不存在,则创建它(即touch $MCPATH.lock),然后运行修剪命令。

当该锁定文件 存在时,只需wait()几秒钟(或更长时间,如您所愿),然后再次轮询。

修剪功能完成后(即使它因错误而完成),删除.lock文件。然后像往常一样简单地处理错误(或成功)。