#--------------------------------------------------------------------- # Filename: mtctl # Purpose: Minetest server Control # License: Copyright (C) 2021 by Miniontoby #--------------------------------------------------------------------- #--------------------------------------------------------------------- # Alias mtinfo() { MSG="$1" 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 } #--------------------------------------------------------------------- # 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" #--------------------------------------------------------------------- # Normal Functions GetPIDS() { FOO=`ps ax | grep $SERVEREXE | grep " $1" | grep -e "--port" | sed -e "s/^ *//" -e "s/ .*//"`; BAR=`ps ax | grep "mtctl start *$2"\$ | grep -v grep | grep -v "^ *$$ " | sed -e "s/^ *//" -e "s/ .*//"` } SetWorld() { NAME=$1; if [ "x$NAME" == "x" ]; then mthelp; exit 1; fi WORLDDIR=$WORLDBASE/$NAME; if [ \! -d $WORLDDIR ]; then mtstatus "Failed"; mtinfo "Error: World not found: $NAME"; exit 1; fi PORT=`grep '^port.*=' $WORLDDIR/world.conf | sed -e "s/^.*= *//" -e "s/ .*//"`; if [ "x$PORT" == "x" ]; then mtstatus "Failed"; mtinfo "Error: Port for $NAME not defined in cfg file"; exit 1; fi } mtstatus() { CHECK="$1" EXTRA="" if [ "$CHECK" == "Ok" ]; then GetPIDS "$WORLDDIR" "$NAME" if [ "x$FOO$BAR" \!= "x" ]; then CHECK="Online" else CHECK="Offline" fi EXTRA="\n" else if [ "$CHECK" == "Failed" ]; then EXTRA=" \n"; fi; 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() { SetWorld "$1"; mtstatus GetPIDS "$WORLDDIR" "$NAME" BAR=`echo $BAR | wc -l` if [ "x$FOO" \!= "x" ]; then mtstatus "Failed" mtinfo "Error: World seems already to be running\nIf it is not running, run $ mctl stop $NAME to be sure" exit 1 fi EXITFLAGWORLD=$EXITDIR/minestop.$NAME MINETEST_SUBGAME_PATH=$MTDIR/games # MAYBE Export if linux doesnt work rm -f $EXITFLAGALL $EXITFLAGWORLD 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 ( 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 done ) > $LOGDIR/start-$NAME.txt & mtstatus "Ok" } 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 mtstatus "Waiting" sleep 15; 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" if [ "x$FOO$BAR" == "x" ]; then mtstatus "Ok" else mtstatus "Failed"; mtinfo "Error: Stop of $NAME failed\nTry once more, then consult a sysadmin"; exit 1 fi fi } restartMT() { SetWorld "$1" /usr/bin/mtctl stop "$1"|| exit 1 /usr/bin/mtctl start "$1" || exit 1 } statusMT() { SetWorld "$1"; mtstatus "Ok" } listMT() { for WORLDNAME in `ls $WORLDBASE 2> /dev/null | grep '^[a-zA-Z0-9]*$' | sort`; do SetWorld "$WORLDNAME" mtinfo "World: $WORLDNAME Port: $PORT" done } createMT() { NAME=$1; if [ "x$NAME" == "x" ]; then mthelp; exit 1; fi if [ "x$NAME" == "x" ]; then echo -e "Failed\nError: Worlds need a name\n"; exit 1; else if [ -d $WORLDBASE/$NAME ]; then echo -e "Failed\nError: World already exist\n"; exit 1; else echo -e "Server name: Ok"; fi; fi echo -ne "\nServer Description: "; read SERVER_DESCRIPTION PortCheck () { CHECK='yes'; if [ -z "${PORT##*[!0-9]*}" ]; then CHECK='no'; ERROR="Ports are only numeric"; return; fi; for x in `ls /home/$MTUSER/minetest/worlds | sort`; do export WCFILE=$WORLDBASE/$x/world.conf; if [ -f $WCFILE ]; then export PORTF=`grep '^port.*=' $WCFILE | sed -e "s/^.*= *//" -e "s/ .*//"`; if [ "x$PORTF" == "x$1" ]; then CHECK='no'; ERROR="Port already in use"; return; fi; fi; done } while true; do echo -ne "\nPort: "; read PORT; PortCheck $PORT; if [ "$CHECK" == "no" ]; then echo -e "Failed\nError: $ERROR"; sleep 1; else echo -e "Ok"; break; fi; done echo -ne "\nMessage Of The Day [MOTD]: "; read MOTD; echo -ne "\nSeed: "; read SEED; echo -ne "\nCreative (true/false): "; read CREATIVE_MODE echo -ne "\nEnable Damage (true/false): "; read ENABLE_DAMAGE; echo -ne "\nEnable Player Versus Player [PVP] (true/false): "; read ENABLE_PVP 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 -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" } #--------------------------------------------------------------------- # Handle the actions case $ACTION in start) startMT "$2" ;; stop) stopMT "$2" ;; restart) restartMT "$2" ;; status) statusMT "$2" ;; list) listMT ;; create) createMT "$2" ;; version) mtinfo "Version: $VERSION" ;; check_updates) 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 fi help) mthelp ;; *) mthelp ;; esac #--------------------------------------------------------------------- # Final