
15 changed files with 129 additions and 72 deletions
@ -0,0 +1,37 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
# Check if server is started |
||||
|
status=$(systemctl show mcbe -p ActiveState --value) |
||||
|
if [[ $status != active ]]; then |
||||
|
echo "mcbe.service is inactive. Exiting." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
# get time |
||||
|
hour=$(date +%H) |
||||
|
day=$(date +%d) |
||||
|
month=$(date +%m) |
||||
|
year=$(date +%Y) |
||||
|
# check if any players are currently logged in |
||||
|
players=$(mcbe-exec list | cut -d ' ' -f 3 | cut -d '/' -f 1) |
||||
|
|
||||
|
# cd to backup dir |
||||
|
cd /vol/data |
||||
|
|
||||
|
# hourly backup |
||||
|
mcbe-exec say "Autosaving..." |
||||
|
mcbe-backup worlds-hourly-$hour |
||||
|
|
||||
|
if [[ $hour -eq 1 ]]; then |
||||
|
# if no players are present, restart the server |
||||
|
# should help deal with any memory leaks |
||||
|
if [[ $players -eq 0 ]]; then |
||||
|
mcbe-shutdown |
||||
|
systemctl start mcbe |
||||
|
fi |
||||
|
# save daily and longterm backups |
||||
|
rsync -a worlds-hourly-$hour/ worlds-daily-$day/ |
||||
|
if [[ $day -eq 1 ]]; then |
||||
|
rsync -a worlds-daily-$day/ worlds-$year-$month-$day/ |
||||
|
fi |
||||
|
fi |
@ -0,0 +1,79 @@ |
|||||
|
#!/bin/bash |
||||
|
|
||||
|
if [[ -z $1 ]]; then |
||||
|
echo "Usage: $0 backup_dir" |
||||
|
exit 2 |
||||
|
fi |
||||
|
backup_dir=$1 |
||||
|
|
||||
|
# get name of world loaded into server |
||||
|
world=$(grep ^level-name= "/home/mcadmin/server.properties" | cut -d = -f 2- -s) |
||||
|
# check if world name is empty |
||||
|
if [[ -z $world ]]; then |
||||
|
echo "Error: world-name field seems to be empty. Check server.properties file." |
||||
|
exit 1 |
||||
|
fi |
||||
|
worlds_dir="/home/mcadmin/worlds" |
||||
|
if [[ ! -d "$worlds_dir/$world" ]]; then |
||||
|
echo "Error: world \"$world\" not found in $worlds_dir. Check server.properties file as well." |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
# Check if server is active |
||||
|
status=$(systemctl show mcbe -p ActiveState --value) |
||||
|
# if service is not active, just rsync folder directly. |
||||
|
if [[ $status != active ]]; then |
||||
|
echo "Service is inactive: running rsync directly." |
||||
|
rsync -a "$worlds_dir/" "$backup_dir/" |
||||
|
exit |
||||
|
fi |
||||
|
|
||||
|
# check if save is currently in progress |
||||
|
if [[ $(mcbe-exec save query) != "A previous save has not been completed." ]]; then |
||||
|
echo "Error: a save seems to be currently in progress. Did the previous save run correctly?" |
||||
|
exit 1 |
||||
|
fi |
||||
|
|
||||
|
# create backup dir |
||||
|
if [[ ! -d "$backup_dir" ]]; then |
||||
|
echo "Creating directory \"$backup_dir\" ..." |
||||
|
mkdir -p "$backup_dir" |
||||
|
fi |
||||
|
cd "$backup_dir" |
||||
|
|
||||
|
# prepare backup of active world |
||||
|
mcbe-exec save hold |
||||
|
timeout=0 |
||||
|
buffer=$(mcbe-exec save query) |
||||
|
until echo "$buffer" | grep -q 'Data saved'; do |
||||
|
# 1 minute timeout |
||||
|
if [[ "$timeout" -eq 60 ]]; then |
||||
|
echo "Error: save timed out." |
||||
|
mcbe-exec save resume |
||||
|
exit 1 |
||||
|
fi |
||||
|
sleep 1 |
||||
|
timeout=$(( ++timeout )) |
||||
|
buffer=$(mcbe-exec save query) |
||||
|
done |
||||
|
files=$(echo "$buffer" | grep -Eo "${world}[^:]+:[0-9]+") |
||||
|
|
||||
|
# copy files for active world |
||||
|
echo "$files" | while read -r line; do |
||||
|
file=${line%:*} |
||||
|
size=${line#*:} |
||||
|
mkdir -p "$(dirname "$file")" |
||||
|
rsync -a "$worlds_dir/$file" "$file" |
||||
|
truncate --size="$size" "$file" |
||||
|
done |
||||
|
|
||||
|
# tell minecraft it can resume |
||||
|
mcbe-exec save resume |
||||
|
|
||||
|
# copy inactive worlds |
||||
|
ls -w 1 "$worlds_dir" | grep -v "$world" | while read -r line; do |
||||
|
rsync -a "$worlds_dir/$line" ./ |
||||
|
done |
||||
|
|
||||
|
# make sure everything is owned by worlds owner |
||||
|
chown -R "$(stat -c %U:%G $worlds_dir)" ./ |
@ -1,10 +1,10 @@ |
|||||
[Unit] |
[Unit] |
||||
After=mcbe.service |
After=mcbe.service |
||||
Description=Backup Minecraft Bedrock Edition Server |
Description=Minecraft Bedrock Edition Server Auto-backup |
||||
Requisite=mcbe.service |
Requisite=mcbe.service |
||||
|
|
||||
[Service] |
[Service] |
||||
ExecStart=/usr/local/bin/mcbe-backup |
ExecStart=/usr/local/bin/maint |
||||
StandardOutput=journal |
StandardOutput=journal |
||||
StandardError=journal |
StandardError=journal |
||||
KillMode=none |
KillMode=none |
@ -0,0 +1,8 @@ |
|||||
|
[Unit] |
||||
|
Description=Backup Minecraft Bedrock Edition Server every hour |
||||
|
|
||||
|
[Timer] |
||||
|
OnCalendar=0/1:00:00 |
||||
|
|
||||
|
[Install] |
||||
|
WantedBy=timers.target |
@ -1,59 +0,0 @@ |
|||||
#!/bin/bash |
|
||||
|
|
||||
do_stop() { |
|
||||
echo "Shutting down server for scheduled daily backup." |
|
||||
mcbe-shutdown 10 "Shutting down server for scheduled daily backup." |
|
||||
} |
|
||||
|
|
||||
do_start() { |
|
||||
sleep 5 |
|
||||
echo "Restarting server after backup." |
|
||||
service mcbe start |
|
||||
} |
|
||||
|
|
||||
do_backup() { |
|
||||
day=$(date +%d) |
|
||||
cd /vol/data |
|
||||
mkdir -p worlds-daily-$day/ |
|
||||
rsync -vaSH /home/mcadmin/worlds/ worlds-daily-$day/ |
|
||||
if [[ $day == 1 ]]; then |
|
||||
month=$(date +%m) |
|
||||
year=$(date +%Y) |
|
||||
mkdir -p worlds-$year-$month-$day/ |
|
||||
rsync -vaSH worlds-daily-$day/ worlds-$year-$month-$day/ |
|
||||
fi |
|
||||
} |
|
||||
|
|
||||
# Check if server is started |
|
||||
status=$(systemctl show mcbe -p ActiveState --value) |
|
||||
# Check if any players present |
|
||||
players=$(mcbe-exec list | cut -d ' ' -f 3 | cut -d '/' -f 1) |
|
||||
# check when mcbe-backup was last triggered |
|
||||
last=$(date -d "$(systemctl show mcbe-backup.timer -p LastTriggerUSec --value)" +%s) |
|
||||
# get current time |
|
||||
now=$(date +%s) |
|
||||
|
|
||||
# if service is not active, do backup immediately and exit |
|
||||
if [[ $status != active ]]; then |
|
||||
echo "Service is inactive: copying worlds immediately without restarting service." |
|
||||
do_backup |
|
||||
|
|
||||
# if no players are present, do backup immediately and exit |
|
||||
elif [[ $players == 0 ]]; then |
|
||||
echo "No players detected: running backup immediately." |
|
||||
do_stop |
|
||||
do_backup |
|
||||
do_start |
|
||||
|
|
||||
# if 12 or more hours have passed since backup was triggered, go ahead and force a shutdown anyways |
|
||||
elif [[ $(( $now - $last )) -ge 43200 ]]; then |
|
||||
echo "Backup was triggered more than 12 hours ago: forcing backup now." |
|
||||
do_stop |
|
||||
do_backup |
|
||||
do_start |
|
||||
|
|
||||
# otherwise, schedule another attempt in an hour |
|
||||
else |
|
||||
echo "Players present in server: rescheduling backup to one hour from now." |
|
||||
systemd-run --on-active=1h $0 |
|
||||
fi |
|
@ -1,9 +0,0 @@ |
|||||
[Unit] |
|
||||
Description=Backup Minecraft Bedrock Edition Server daily at 4:05 AM |
|
||||
|
|
||||
[Timer] |
|
||||
# Every 2 hours: OnCalendar=0/2:00:00 |
|
||||
OnCalendar=*-*-* 04:05 |
|
||||
|
|
||||
[Install] |
|
||||
WantedBy=timers.target |
|
Loading…
Reference in new issue