Created
August 1, 2015 00:33
-
-
Save fernandofig/7ecc8591bea467cc2005 to your computer and use it in GitHub Desktop.
Init.d script for starting multiple and concurrent Terraria Server instances
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
### BEGIN INIT INFO | |
# Provides: terraria_server | |
# Required-Start: $local_fs $remote_fs $network | |
# Required-Stop: $local_fs $remote_fs $network | |
# Default-Start: 2 3 4 5 | |
# Default-Stop: 0 1 6 | |
# X-Interactive: true | |
# Short-Description: Start/stop terraria_server | |
### END INIT INFO | |
DESC="TShock Terraria Server" | |
USERID=terraria | |
BINDIR=/home/terraria | |
SCREENDAEMON=$(which screen) | |
#MONODAEMON=$(which mono) | |
MONODAEMON=$(which mono-sgen) # an experimental version of mono with a more efficient memory handler: apt-get install mono-sgen | |
#MONODAEMON=$(which mono-boehm) # an experimental version of mono with a more efficient memory handler: apt-get install mono-sgen | |
WORLDS="World1" | |
. /etc/default/terraria-server | |
# All important args for TerrariaServer.exe | |
DAEMONARGS="-ip 0.0.0.0 -maxplayers 8" | |
# Command sent to server to exit, try just "exit" to save world before exit. You WILL need to increase EXIT_TIMEOUT (try 30+) | |
#EXIT_COMMAND="exit-nosave" | |
EXIT_COMMAND="exit" | |
# wait X seconds for terraria to exit | |
#EXIT_TIMEOUT=5 | |
EXIT_TIMEOUT=30 | |
# Exit if not lib functions | |
[ -r /lib/lsb/init-functions ] || exit 0 | |
. /lib/lsb/init-functions | |
# Exit if screen cant be found | |
[ -x "${SCREENDAEMON}" ] || exit 0 | |
# Exit if mono cant be found | |
[ -x "${MONODAEMON}" ] || exit 0 | |
# Exit if base directory for instances cant be found | |
[ -d "${BINDIR}" ] || exit 0 | |
# Exit if no Worlds specified | |
[ -n "${WORLDS}" ] || exit 0 | |
checkScreen() { | |
#INST_NAME=${NAME} | |
if [ -e /var/run/screen/S-${USERID}/*.${INST_NAME} ]; then return 0; fi | |
return 1 | |
} | |
checkPID() { | |
#INST_PATH=${BINDIR} | |
PIDFILE=${INST_PATH}/tshock/tshock.pid | |
if [ -e ${PIDFILE} ] && kill -0 $(cat ${PIDFILE} 2>/dev/null) > /dev/null 2>&1; then return 0; fi | |
return 1 | |
} | |
cd ${BINDIR} | |
case "$1" in | |
start) | |
OIFS=$IFS | |
IFS="," | |
for WLD in $WORLDS; do | |
INST_PATH=$BINDIR/$WLD | |
INST_NAME="Terraria_Inst_${WLD}" | |
rm -f $INST_PATH/ServerLog.txt | |
find $INST_PATH/tshock/ -maxdepth 1 -iname "*.log" -exec mv {} $INST_PATH/tshock/oldlogs/ \; | |
log_daemon_msg "Starting TShock instance ${WLD} ... " | |
EC=1 | |
if [ ! -d "${INST_PATH}" ]; then | |
log_progress_msg "ERR: Instance folder not found."; | |
elif [ ! -r "${INST_PATH}/TerrariaServer.exe" ]; then | |
log_progress_msg "ERR: Instance Daemon not found."; | |
elif checkScreen || checkPID; then | |
log_progress_msg "(already running)"; | |
else | |
su ${USERID} -c "cd ${INST_PATH}; ${SCREENDAEMON} -dmS ${INST_NAME} ${MONODAEMON} ${INST_PATH}/TerrariaServer.exe ${DAEMONARGS} -world ${INST_PATH}/Terraria/Worlds/${WLD}.wld"; | |
# Wait up to 5 seconds for it to start | |
for i in {0..5}; do | |
if checkPID; then EC=0; break; fi # found running PID | |
sleep 1 | |
done | |
fi | |
log_end_msg $EC | |
done | |
IFS=$OIFS | |
;; | |
debug) | |
OIFS=$IFS | |
IFS="," | |
if [ -n "$2" ]; then | |
WLD=$2 | |
INST_PATH=$BINDIR/$WLD | |
rm -f $INST_PATH/ServerLog.txt | |
find $INST_PATH/tshock/ -maxdepth 1 -iname "*.log" -exec mv {} $INST_PATH/tshock/oldlogs/ \; | |
if [ ! -d "${INST_PATH}" ]; then | |
echo "ERR: Instance folder not found."; | |
elif [ ! -r "${INST_PATH}/TerrariaServer.exe" ]; then | |
echo "ERR: Instance Daemon not found."; | |
elif checkPID; then | |
echo "Server instance for this world already running on background!"; | |
else | |
su ${USERID} -c "cd ${INST_PATH}; ${INST_NAME} ${MONODAEMON} ${INST_PATH}/TerrariaServer.exe ${DAEMONARGS} -world ${INST_PATH}/Terraria/Worlds/${WLD}.wld"; | |
fi | |
else | |
echo "You should provide an instance name (according to the WORLDS config variable)" | |
fi | |
IFS=$OIFS | |
;; | |
stop) | |
OIFS=$IFS | |
IFS="," | |
for WLD in $WORLDS; do | |
INST_PATH=$BINDIR/$WLD | |
INST_NAME="Terraria_Inst_${WLD}" | |
log_daemon_msg "Stopping TShock instance ${WLD} ... " | |
EC=1 | |
if [ ! -d "${INST_PATH}" ]; then | |
log_progress_msg "ERR: Instance folder not found."; | |
elif [ ! -r "${INST_PATH}/TerrariaServer.exe" ]; then | |
log_progress_msg "ERR: Instance Daemon not found."; | |
elif ! checkScreen || ! checkPID; then | |
log_progress_msg "(not running, or stale pidfile)"; | |
else | |
# Use screen to stuff text to console | |
su "${USERID}" -c 'screen -dr '${INST_NAME}' -X stuff "'${EXIT_COMMAND}'$(printf \\r)"' | |
# Wait for the process to end | |
n=${EXIT_TIMEOUT} | |
for (( i=0; i<n; i++ )); do | |
if ! checkScreen; then EC=0; break; fi; | |
sleep 1; | |
done | |
fi | |
log_end_msg $EC | |
done | |
IFS=$OIFS | |
;; | |
restart) | |
$0 stop | |
$0 start | |
;; | |
connect) | |
if [ -n "$2" ]; then | |
INST_NAME="Terraria_Inst_$2" | |
if checkScreen; then | |
# Use script to bypass TTY issues | |
su "${USERID}" -c "script -qc \"screen -dr ${INST_NAME}\" /dev/null" | |
else | |
echo "${INST_NAME}: Connect failed. (screen not running or no instance with that name found)" | |
fi | |
else | |
echo "You should provide an instance name (according to the WORLDS config variable)" | |
fi | |
;; | |
*) | |
echo "Usage: $0 {start|stop|restart|connect <inst>}" 2>&1 | |
;; | |
esac |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment