diff --git a/src/minecraft_be/Containerfile b/src/mcbe/Containerfile similarity index 100% rename from src/minecraft_be/Containerfile rename to src/mcbe/Containerfile diff --git a/src/mcbe/assets/bin/maint b/src/mcbe/assets/bin/maint new file mode 100755 index 0000000..68b8905 --- /dev/null +++ b/src/mcbe/assets/bin/maint @@ -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 diff --git a/src/mcbe/assets/bin/mcbe-backup b/src/mcbe/assets/bin/mcbe-backup new file mode 100755 index 0000000..9c8866d --- /dev/null +++ b/src/mcbe/assets/bin/mcbe-backup @@ -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)" ./ diff --git a/src/minecraft_be/assets/bin/mcbe-exec b/src/mcbe/assets/bin/mcbe-exec similarity index 100% rename from src/minecraft_be/assets/bin/mcbe-exec rename to src/mcbe/assets/bin/mcbe-exec diff --git a/src/minecraft_be/assets/bin/mcbe-shutdown b/src/mcbe/assets/bin/mcbe-shutdown similarity index 100% rename from src/minecraft_be/assets/bin/mcbe-shutdown rename to src/mcbe/assets/bin/mcbe-shutdown diff --git a/src/minecraft_be/assets/minecraft/permissions.json b/src/mcbe/assets/minecraft/permissions.json similarity index 100% rename from src/minecraft_be/assets/minecraft/permissions.json rename to src/mcbe/assets/minecraft/permissions.json diff --git a/src/minecraft_be/assets/minecraft/server.properties b/src/mcbe/assets/minecraft/server.properties similarity index 100% rename from src/minecraft_be/assets/minecraft/server.properties rename to src/mcbe/assets/minecraft/server.properties diff --git a/src/minecraft_be/assets/minecraft/whitelist.json b/src/mcbe/assets/minecraft/whitelist.json similarity index 100% rename from src/minecraft_be/assets/minecraft/whitelist.json rename to src/mcbe/assets/minecraft/whitelist.json diff --git a/src/minecraft_be/assets/systemd/mcbe-backup.service b/src/mcbe/assets/systemd/mcbe-backup.service similarity index 54% rename from src/minecraft_be/assets/systemd/mcbe-backup.service rename to src/mcbe/assets/systemd/mcbe-backup.service index b1b0535..212818c 100644 --- a/src/minecraft_be/assets/systemd/mcbe-backup.service +++ b/src/mcbe/assets/systemd/mcbe-backup.service @@ -1,11 +1,11 @@ [Unit] After=mcbe.service -Description=Backup Minecraft Bedrock Edition Server +Description=Minecraft Bedrock Edition Server Auto-backup Requisite=mcbe.service [Service] -ExecStart=/usr/local/bin/mcbe-backup +ExecStart=/usr/local/bin/maint StandardOutput=journal StandardError=journal KillMode=none -Type=oneshot \ No newline at end of file +Type=oneshot diff --git a/src/mcbe/assets/systemd/mcbe-backup.timer b/src/mcbe/assets/systemd/mcbe-backup.timer new file mode 100644 index 0000000..212defc --- /dev/null +++ b/src/mcbe/assets/systemd/mcbe-backup.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Backup Minecraft Bedrock Edition Server every hour + +[Timer] +OnCalendar=0/1:00:00 + +[Install] +WantedBy=timers.target diff --git a/src/minecraft_be/assets/systemd/mcbe.service b/src/mcbe/assets/systemd/mcbe.service similarity index 90% rename from src/minecraft_be/assets/systemd/mcbe.service rename to src/mcbe/assets/systemd/mcbe.service index e0c003c..316c37d 100644 --- a/src/minecraft_be/assets/systemd/mcbe.service +++ b/src/mcbe/assets/systemd/mcbe.service @@ -6,8 +6,9 @@ Description=Minecraft Bedrock Edition server [Service] ExecReload=/bin/bash -c "echo reload > /run/mcb" -ExecStop=/bin/bash -c "echo stop > /run/mcb" +ExecStop=-/bin/bash -c "echo stop > /run/mcb" ExecStart=/bin/bash -c "LD_LIBRARY_PATH=. ./bedrock_server" +SuccessExitStatus=1 User=mcadmin WorkingDirectory=/home/mcadmin Restart=on-failure diff --git a/src/minecraft_be/assets/systemd/mcbe.socket b/src/mcbe/assets/systemd/mcbe.socket similarity index 100% rename from src/minecraft_be/assets/systemd/mcbe.socket rename to src/mcbe/assets/systemd/mcbe.socket diff --git a/src/minecraft_be/docs/resources.md b/src/mcbe/docs/resources.md similarity index 100% rename from src/minecraft_be/docs/resources.md rename to src/mcbe/docs/resources.md diff --git a/src/minecraft_be/assets/bin/mcbe-backup b/src/minecraft_be/assets/bin/mcbe-backup deleted file mode 100755 index a94da84..0000000 --- a/src/minecraft_be/assets/bin/mcbe-backup +++ /dev/null @@ -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 diff --git a/src/minecraft_be/assets/systemd/mcbe-backup.timer b/src/minecraft_be/assets/systemd/mcbe-backup.timer deleted file mode 100644 index 7ae447a..0000000 --- a/src/minecraft_be/assets/systemd/mcbe-backup.timer +++ /dev/null @@ -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