=================================================================== RCS file: /cvs/mtctl/mtctl_default.sh,v retrieving revision 1.1 retrieving revision 1.6 diff -u -p -r1.1 -r1.6 --- mtctl/mtctl_default.sh 2021/08/31 17:00:08 1.1 +++ mtctl/mtctl_default.sh 2022/05/29 14:33:42 1.6 @@ -3,6 +3,9 @@ # Purpose: Minetest server Control # License: Copyright (C) 2021 by Miniontoby #--------------------------------------------------------------------- +VERSION="1.4" +config=[] +config[0]="no"; config[1]="/usr/local/share/minetest/" #--------------------------------------------------------------------- # Alias @@ -12,24 +15,66 @@ mtinfo() { echo -e "mtctl: $MSG" | sed -e 's/\\n/\\nmtctl: /' } mthelp() { - echo -e "usage: mtctl start|stop|restart|status|create worldname\n mtctl list|help|version|check_updates"; exit 1 + echo -e "usage: mtctl start|stop|restart|status|create|backup worldname\n mtctl list|help|version|check_updates" } +if [ "x$1" == "x" ]; then mthelp; exit 0; fi #--------------------------------------------------------------------- -# Variables -if [ "x$1" == "x" ]; then mthelp; exit 1; fi -ACTION="$1" -EXITDIR=$MTDIR/tmp -if [ "$MTBUILD" == "yes" ]; then SERVEREXE="$MTDIR/bin/minetestserver"; else SERVEREXE="`which minetestserver`"; fi -WORLDBASE=$MTDIR/worlds -LOGDIR=$MTDIR/log -EXITFLAGALL=$EXITDIR/minestop.all -WHOAMI=`whoami` -OK=0 -VERSION="1.0" +# Setup +if [[ "`id -u`" -eq 0 ]]; then CONFDIR=/etc/mtctl; else CONFDIR=$HOME/.mtctl; fi +if [ \! -d $CONFDIR ]; then mkdir -p $CONFDIR || exit 1; fi +if [ \! -f $CONFDIR/config ]; then + mtinfo "\nNo configfile found!\nCreating it now!\n\n" + echo -n 'Use custom build minetest folder (yes/no): '; read MTBUILD + case $MTBUILD in + YES|yes) MTBUILD='yes' + EXAMPLEDIR="$HOME/minetest" + ;; + NO|no) MTBUILD='no' + EXAMPLEDIR="$HOME/.minetest" + ;; + *) mtinfo "Error, not a valid option!" + exit 1 + ;; + esac + echo -n "Insert the path to the minetest folder(eg. $EXAMPLEDIR): "; read MTLOCATION + echo -e "builded=$MTBUILD\nlocation=$MTLOCATION" > $CONFDIR/config + unset MTBUILD MTLOCATION EXAMPLEDIR + mtinfo "Configfile created!!\n\n" +fi + +while read line; do + linea="`echo $line | grep -F = 2> /dev/null`" + if [ "x$linea" \!= "x" ]; then + varname=$(echo "$line" | cut -d '=' -f 1) + case $varname in + builded) indexnumber=0 + ;; + location) indexnumber=1 + ;; + esac + config[$indexnumber]=$(echo "$line" | cut -d '=' -f 2-) + fi +done < $CONFDIR/config + +mtsetup() { + EXITDIR=${config[1]}/tmp + if [ "${config[0]}" == "yes" ]; then SERVEREXE="${config[1]}/bin/minetestserver"; else SERVEREXE="`which minetestserver`"; fi + WORLDBASE=${config[1]}/worlds + LOGDIR=${config[1]}/log + OK=0; cd ${config[1]} || exit 1 + touch temp.test && OK=1; if [ "@$OK" == "@0" ]; then mtinfo "Error: Directory tree should be owned by the MT user:\n${config[1]}"; exit 1; fi + rm temp.test || exit 1 + if [ \! -f $SERVEREXE ]; then mtinfo "Error: Couldn't determine SERVEREXE setting\n$SERVEREXE"; exit 1; fi + + mkdir -p $EXITDIR || exit 1 + mkdir -p $WORLDBASE || exit 1 + mkdir -p $LOGDIR || exit 1 +} + #--------------------------------------------------------------------- # Normal Functions @@ -53,27 +98,13 @@ mtstatus() { CHECK="Offline" fi EXTRA="\n" - else if [ "$CHECK" == "Failed" ]; then EXTRA=" \n"; fi; fi + elif [ "$CHECK" == "Failed" ]; then EXTRA=" \n"; + elif [ "$CHECK" == "Backup failed" ]; then EXTRA=" \n"; + elif [ "$CHECK" == "Backup success" ]; then EXTRA=" \n"; fi echo -ne "\r$NAME($CHECK)$EXTRA" } - #--------------------------------------------------------------------- -# Pre start - -if [ "$ACTION" == "version" ]; then mtinfo "Version: $VERSION"; exit 0; fi -if [ "@$WHOAMI" \!= "@$MTUSER" ]; then mtinfo "Please switch to $MTUSER"; exit 0; fi -cd $MTDIR || exit 1 -touch temp.test && OK=1; if [ "@$OK" == "@0" ]; then mtinfo "Error: Directory tree should be owned by the MT user:\n$MTDIR"; exit 1; fi -rm temp.test || exit 1 -if [ \! -f $SERVEREXE ]; then mtinfo "Error: Couldn't determine SERVEREXE setting\n$SERVEREXE"; exit 1; fi - -mkdir -p $EXITDIR || exit 1 -mkdir -p $WORLDBASE || exit 1 -mkdir -p $LOGDIR || exit 1 - - -#--------------------------------------------------------------------- # Functions for executing the actions startMT() { @@ -86,11 +117,11 @@ startMT() { exit 1 fi - EXITFLAGWORLD=$EXITDIR/minestop.$NAME - MINETEST_SUBGAME_PATH=$MTDIR/games + EXITFLAGWORLD=$EXITDIR/mtctlstop.$NAME + MINETEST_SUBGAME_PATH=${config[1]}/games # MAYBE Export if linux doesnt work - rm -f $EXITFLAGALL $EXITFLAGWORLD + rm -f $EXITFLAGALL sleep 1; DIR=`pwd` || exit 1; cd $WORLDDIR || exit 1 F1=env_meta.txt; F2=env_meta.old; if [ -s $F1 ]; then N=`grep EnvArgsEnd $F1 | wc -l` || exit 1; if [ "x$N" == "x0" ]; then rm -f $F1 || exit 1; fi; fi; if [ -s $F1 ]; then rm -f $F2; cp -p $F1 $F2 || exit 1; else if [ -s $F2 ]; then rm -f $F1; cp -p $F2 $F1 || exit 1; else rm -f $F1 || exit 1; fi; fi cd $DIR || exit 1 @@ -98,7 +129,7 @@ startMT() { ( while true; do $SERVEREXE --config $WORLDDIR/world.conf --port $PORT --logfile $LOGDIR/debug-$NAME.log --map-dir $WORLDDIR >> $LOGDIR/$NAME.log 2>&1 - if [ -f $EXITFLAGALL ]; then exit 0; fi; if [ -f $EXITFLAGWORLD ]; then exit 0; fi; sleep 10 + if [ -f $EXITFLAGWORLD ]; then exit 0; fi; sleep 10 done ) > $LOGDIR/start-$NAME.txt & mtstatus "Ok" @@ -108,20 +139,24 @@ stopMT() { SetWorld "$1"; mtstatus GetPIDS "$WORLDDIR" "$NAME" if [ "x$FOO$BAR" == "x" ]; then mtstatus "Failed"; mtinfo "$NAME seems to be stopped already"; exit 0; fi - if [ "x$FOO" \!= "x" ]; then kill -SIGINT $FOO 2> /dev/null ; sleep 1; kill -SIGINT $FOO 2> /dev/null ; sleep 1; kill -SIGINT $FOO 2> /dev/null ; sleep 1; kill -SIGINT $FOO 2> /dev/null ; fi - if [ "x$BAR" \!= "x" ]; then kill -9 $BAR; fi + touch $EXITDIR/mtctlstop.$NAME + if [ "x$FOO" \!= "x" ]; then + kill -SIGINT $FOO + else + if [ "x$BAR" \!= "x" ]; then + kill -9 $BAR + fi + fi + mtstatus "Waiting" - sleep 15; GetPIDS "$WORLDDIR" "$NAME" + sleep 5; GetPIDS "$WORLDDIR" "$NAME" if [ "x$FOO$BAR" == "x" ]; then mtstatus "Ok" else - kill -9 $FOO; kill -9 $FOO; kill -9 $FOO; kill -9 $FOO; - if [ "x$BAR" \!= "x" ]; then kill -9 $BAR; fi - mtstatus "Waiting." - sleep 15; GetPIDS "$WORLDDIR" "$NAME" + sleep 5; GetPIDS "$WORLDDIR" "$NAME" if [ "x$FOO$BAR" == "x" ]; then mtstatus "Ok" else @@ -137,8 +172,15 @@ restartMT() { } statusMT() { - SetWorld "$1"; - mtstatus "Ok" + SetWorld "$1" + GetPIDS "$WORLDDIR" "$NAME" + if [ "x$FOO$BAR" \!= "x" ]; then + STATUS="Online" + else + STATUS="Offline" + fi + LASTLOG="`tail -n 5 $LOGDIR/$NAME.log`" + echo -e "mtctl.$1 - The Minetest Server Control\n Active: $STATUS\n Process: $FOO\n Main PID: $BAR\n\n$LASTLOG" } listMT() { @@ -161,33 +203,97 @@ createMT() { echo -ne "\nUsername: "; read USERNAME cd $WORLDBASE; mkdir $NAME; cd $NAME - echo -e "server_name = $NAME\nserver_description = $SERVER_DESCRIPTION\nport = $PORT\nmotd = $MOTD\nfixed_map_seed = $SEED\ncreative_mode = $CREATIVE_MODE\nenable_damage = $ENABLE_DAMAGE\nenable_pvp = $ENABLE_PVP\nname = $USERNAME\nserver_announce = true\nserverlist_url = servers.minetest.net" > world.conf - echo -e "creative_mode = $CREATIVE_MODE\nenable_damage = $ENABLE_DAMAGE\nauth_backend = sqlite3\nbackend = sqlite3\nplayer_backend = sqlite3\ngameid = minetest\nworld_name = $NAME" > world.mt + echo -e "server_name = $NAME\nserver_description = $SERVER_DESCRIPTION\nport = $PORT\nmotd = $MOTD\nfixed_map_seed = $SEED\ncreative_mode = $CREATIVE_MODE\nenable_damage = $ENABLE_DAMAGE\nenable_pvp = $ENABLE_PVP\nname = $USERNAME\nserver_announce = true\nserverlist_url = servers.minetest.net\nsqlite_synchronous = 0\nserver_unload_unused_data_timeout = 900\nserver_map_save_interval = 900.0" > world.conf + echo -e "creative_mode = $CREATIVE_MODE\nenable_damage = $ENABLE_DAMAGE\nbackend = SQLite3\nplayer_backend = SQLite3\nmod_storage_backend = SQLite3\nauth_backend = SQLite3\ngameid = minetest\nworld_name = $NAME" > world.mt echo -ne "\nWorld created!\nWant to start the world?(yes/no): "; read startit if [[ "$startit" == "yes" ]]; then /usr/bin/mtctl start $NAME; fi echo -e "\nSuccess: \033[1;32mDone \033[m\nFeel free to join your new server at port $PORT" } +backupMT() { + SetWorld "$1" + # Backup script from mtlbak by Minix + # Copyright (C) 2021 Minix from FreedomTest (freedomtest@protonmail.com) + + BACKUP_DIR="$CONFDIR/backups/$NAME" + LOG_FILE="$LOGDIR/backup_$NAME.log" + mkdir -p $BACKUP_DIR + echo -ne "" >> $LOG_FILE + + if [ -f /tmp/$(basename $WORLDDIR)_local_backup_in_progress ]; then + echo "\nBackup for $(basename $WORLDDIR) on $(date) aborted because another backup is already in progress, this may be caused by a backup that is taking longer than expected" >> $LOG_FILE + mtinfo "Backup for $(basename $WORLDDIR) on $(date) aborted because another backup is already in progress, this may be caused by a backup that is taking longer than expected" + exit 1 + fi + + touch /tmp/$(basename $WORLDDIR)_local_backup_in_progress + rm $BACKUP_DIR/map.sqlite.tmp* 2> /dev/null #Cleaning in case of crashed attempts + + echo -e "\n$(date) backup started" >> $LOG_FILE + mtstatus "Backup started" + + try=0 + while [ $try -lt 5 ]; do + echo "Starting backup attempt #$(expr $try + 1) on $(date)" >> $LOG_FILE + sqlite3 $WORLDDIR/map.sqlite ".backup $BACKUP_DIR/map.sqlite.tmp" 2> /dev/null + if [ $? -eq 0 ]; then + mv $BACKUP_DIR/{map.sqlite.tmp,map.sqlite} + #Backup auth.sqlite and players.sqlite files properly + until sqlite3 $WORLDDIR/auth.sqlite ".backup $BACKUP_DIR/auth.sqlite" 2> /dev/null; do + continue + done + until sqlite3 $WORLDDIR/players.sqlite ".backup $BACKUP_DIR/players.sqlite" 2> /dev/null; do + continue + done + rsync -ptrW --delete --exclude "*.sqlite" $WORLDDIR/ $BACKUP_DIR/ + echo "Backup finished succesfully on $(date)" >> $LOG_FILE + mtstatus "Backup success" + rm /tmp/$(basename $WORLDDIR)_local_backup_in_progress 2> /dev/null + exit 0 + else + rm $BACKUP_DIR/map.sqlite.tmp 2> /dev/null + try=$(expr $try + 1) + if [ $try -eq 5 ]; then + echo "Backup failed 5 times, aborting on $(date)" >> $LOG_FILE + mtstatus "Backup failed" + rm /tmp/$(basename $WORLDDIR)_local_backup_in_progress 2> /dev/null + exit 1 + else + echo "map.sqlite backup attempt #$try failed, retrying in 60 seconds" >> $LOG_FILE + sleep 60 + fi + fi + done +} + + #--------------------------------------------------------------------- # Handle the actions +ACTION="$1" case $ACTION in start) + mtsetup startMT "$2" ;; stop) + mtsetup stopMT "$2" ;; restart) + mtsetup restartMT "$2" ;; status) + mtsetup statusMT "$2" ;; list) + mtsetup listMT ;; create) + mtsetup createMT "$2" ;; version) @@ -197,8 +303,9 @@ case $ACTION in NEWESTVERSION=$(curl https://cvsweb.planetofnix.com/cgi-bin/cvsweb/~checkout~/mtctl/version.txt?content-type=text/plain 2> /dev/null) if [ "$NEWESTVERSION" \!= "$VERSION" ]; then mtinfo "Update avaible!\n\nInstalling update NOW!" - curl 'https://cvsweb.planetofnix.com/cgi-bin/cvsweb/~checkout~/mtctl/installer.sh?content-type=text/plain' 2> /dev/null | $SHELL + curl -sSL https://ircforever.org/mtctl.php | $SHELL fi + ;; help) mthelp ;;