#!/bin/bash
#
# name:        minecraft_server
# description: Starts the minecraft_server on Fedora/RedHat systems. \
#              If needed, downloads and installs the minecraft_server.jar. \
#              To install init-script, run 'sh minecraft_server-1.0.sh install'
#
# platforms:   Tested on Fedora 13 and RHEL/CentOS 5.4.
#
# chkconfig:   2345 98 05
# pidname:     /var/run/minecraft_server.pid
# author:      Lott Caskey <lottcaskey@gmail.com>
# license:     GPLv2
# version:     1.0
# 
#
# Sysconfig:   /etc/sysconfig/minecraft_server
#              MINECRAFT_HOME=/usr/local/share/minecraft_server
#              MINECRAFT_JAVAHOME=/usr/bin
#              MINECRAFT_PIDFILE=/var/run/minecraft_server
#              MINECRAFT_STOPFILE=/usr/local/share/minecraft_server/minecraft_server.STOP
#              MINECRAFT_DOWNLOAD_URL=http://minecraft.net/download/minecraft_server.jar
#
 
# Source function library.
. /etc/rc.d/init.d/functions

prog="minecraft_server"

# Include overrides
if [ -f "/etc/sysconfig/${prog}" ]; then
	. /etc/sysconfig/${prog}
fi

minecraft_home=${MINECRAFT_HOME-/usr/local/share/${prog}}
minecraft_javahome=${MINECRAFT_JAVAHOME-/usr/bin}
minecraft_pidfile=${MINECRAFE_PIDFILE-/var/run/${prog}.pid}
minecraft_stopfile=${MINECRAFT_STOPFILE-${minecraft_home}/${prog}.STOP}
minecraft_download_url=${MINECRAFT_DOWNLOAD_URL-http://minecraft.net/download/minecraft_server.jar}

RETVAL=0

curuid=`/usr/bin/id -u`
if [ "${curuid}" != "0" ]; then
	echo "ERROR:  Script must be run as the 'root' user."
	exit 1
fi


# Validate that needed components are installed.
runvalidate() {
	echo -n "Validate ${prog}: "
	mcvalidate=1
	if [ ! -f "/usr/bin/screen" ]; then mcvalidate=0; fi
	if [ ! -f "/etc/init.d/${prog}" ]; then mcvalidate=0; fi
	if [ -f "${minecraft_javahome}/bin/java" ]; then minecraft_javahome="${minecraft_javahome}/bin"; fi
	if [ ! -f "${minecraft_javahome}/java" ]; then mcvalidate=0; fi
	if [ ! -f "${minecraft_home}/${prog}.jar" ]; then mcvalidate=0; fi
	if [ ${mcvalidate} -eq 1 ]; then
		success
		echo
	else
		echo -n "(missing component) "
		warning
		echo

		echo -n "  Locate screen: "
		if [ ! -f "/usr/bin/screen" ]; then
			failure
			echo
			echo "ERROR:   The 'screen' utility is required for this script to work."
			echo "         You can try to install it by running 'yum install screen'"
			echo "         as root from the command-line"
			echo
			exit 1
		else
			success
			echo
		fi

		echo -n "  Check Startup Script: "
		if [ ! -f "/etc/init.d/${prog}" ]; then
			failure
			echo
			echo "ERROR:   This script must be copied to '/etc/init.d/${prog}'."
			echo "         Once done, you should run 'chkconfig --add ${prog}' as root."
			echo
			exit 1
		else
			success
			echo
		fi

		echo -n "  Java Check: "
		if [ ! -f "${minecraft_javahome}/java" ]; then
			failure
			echo
			echo "ERROR:   Java was not found!"
			echo "         To install it, run 'yum install java-1.6.0-openjdk'"
			echo "         Or, define a specific javahome path in '/etc/sysconfig/${prog}'."
			echo "            MINECRAFT_JAVAHOME=/usr/java/jre1.6.0_24/bin"
			echo
			exit 1
		else
			success
			echo
		fi

		echo -n "  Locate ${prog}.jar: "
		if [ ! -f "${minecraft_home}/${prog}.jar" ]; then
			echo -n "(missing, must download) "
			warning
			echo
			mcmkdir=0
			if [ ! -d "${minecraft_home}" ]; then
				echo -n "  Create Directory ${minecraft_home}: "
				mkdir -p ${minecraft_home} > /dev/null 2>&1
				RETVAL=$?
				if [ ${RETVAL} -eq 0 ]; then
					success
				else
					failure
					mcmkdir=1
				fi
				echo
			fi
			if [ ${mcmkdir} -eq 0 ]; then
				echo -n "  Locate wget: "
				if [ -f "/usr/bin/wget" ]; then
					success
					echo
					cd ${minecraft_home} > /dev/null 2>&1
					echo -n "  Download ${prog}.jar: "
					/usr/bin/wget ${minecraft_download_url} > /dev/null 2>&1
					RETVAL=$?
					if [ ${RETVAL} -eq 0 ]; then
						success
						echo
					else
						failure
						echo
					fi
				else
					failure
					echo
				fi
			fi
			if [ ! -f "${minecraft_home}/${prog}.jar" ]; then
				echo
				echo "ERROR:   Please manually download ${minecraft_download_url}"
				echo "         and install at '${minecraft_home}/${prog}.jar'."
				echo
				exit 1
			fi
		else
			success
			echo
		fi

	fi
}


# Runs the minecraft_server in a screen session.
runservice() {
	minecraft_pid=0
	minecraft_pidcnt=0
	cd ${minecraft_home}
	while [ ! -f "${minecraft_stopfile}" ]; do
		echo "Checking if ${prog} is running."
		minecraft_pidcnt=`pgrep -f ${prog}.jar | wc -l`
		if [ ${minecraft_pidcnt} -gt 0 ]; then
			minecraft_pid=`pgrep -f ${prog}.jar`
			kill -1 ${minecraft_pid}
			sleep 2
			minecraft_pidcnt=`pgrep -f ${prog}.jar | wc -l`
			if [ ${minecraft_pidcnt} -gt 0 ]; then
				minecraft_pid=`pgrep -f ${prog}.jar`
				kill -9 ${minecraft_pid}
			fi
			minecraft_pid=0
			minecraft_pidcnt=0
		fi
		if [ -f "${minecraft_pidfile}" ]; then rm -f ${minecraft_pidfile}; fi

		echo "Starting ${prog}."
		${minecraft_javahome}/java -Xmx1024M -Xms1024M -jar ${prog}.jar nogui <&0 &
		sleep 1

		minecraft_pidcnt=`pgrep -f ${prog}.jar | wc -l`
		if [ ${minecraft_pidcnt} -gt 0 ]; then
			minecraft_pid=`pgrep -f ${prog}.jar`
			echo "Writing ${minecraft_pid} to ${minecraft_pidfile}"
			echo ${minecraft_pid} > ${minecraft_pidfile}
			echo
			echo "To detach from your console session, type: CTRL-a,d"
			echo
			wait ${minecraft_pid}
		else
			echo "ERROR: ${prog} did not start!"
			if [ -f "${minecraft_stopfile}" ]; then rm -f ${minecraft_stopfile}; fi
			if [ -f "${minecraft_pidfile}" ]; then rm -f ${minecraft_pidfile}; fi
			exit 1
		fi
		if [ ! -f "${minecraft_stopfile}" ]; then
			read -t 10 -n 1 -p "Press any key within 10 seconds to stop restarting ${prog}."
			RETVAL=$?
			echo
			if [ ${RETVAL} -gt 0 ]; then
				echo "Restarting ${prog}."
			else
				echo "Stopping ${prog}."
				echo `date` > ${minecraft_stopfile}
			fi
		fi
	done
	if [ -f "${minecraft_stopfile}" ]; then rm -f ${minecraft_stopfile}; fi
	if [ -f "${minecraft_pidfile}" ]; then rm -f ${minecraft_pidfile}; fi
}


# Starts the minecraft_server service
start() {
	minecraft_pid=`pgrep -f ${prog}.jar`
	pgrep -f ${prog}.jar 2>&1 > /dev/null
	RETVAL=$?
	echo -n "Starting ${prog}: "
	if [ $RETVAL -ne 0 ]; then
 
		# this call actually starts minecraft_server.
		/usr/bin/screen -S minecraft -t "test123" -d -m /etc/init.d/${prog} runservice
		LOOP=0
		while [ ${LOOP} -lt 11 ]; do
			pgrep -f ${prog}.jar 2>&1 > /dev/null
			RETVAL=$?
			if [ $RETVAL -eq 0 ]; then
				let LOOP=11
			else
				let LOOP+=1
				echo -n "."
				sleep 1
			fi
		done
		if [ $RETVAL -eq 0 ]; then
			success
		else
			failure
		fi
		echo
		return $RETVAL
	else
		echo -n "(already running)"
		failure
		echo
		return 1
	fi
}
 

# Stops the minecraft_server service
stop() {
	pgrep -f ${prog}.jar 2>&1 > /dev/null
	RETVAL=$?
	echo -n "Stopping ${prog}: "
	if [ $RETVAL -eq 0 ]; then
		LOOP=0
		while [ ${LOOP} -lt 11 ]; do
			echo `date` > ${minecraft_stopfile}
			pkill -f ${prog}.jar 2>&1 > /dev/null
			RETVAL=$?
			if [ $RETVAL -eq 0 ]; then
				let LOOP=11
			else
				let LOOP+=1
				echo -n "."
				sleep 1
			fi
		done
		if [ $RETVAL -eq 0 ]; then
			success
		else
			failure
		fi
		echo
	else
		echo -n "(not running)"
		failure
		echo
	fi
	return $RETVAL
}


# Restarts the minecraft_server service
restart() {
	pgrep -f ${prog}.jar 2>&1 > /dev/null
	RETVAL=$?
	if [ $RETVAL -eq 0 ]; then
		echo -n "Restarting ${prog}: "
		pkill -f ${prog}.jar 2>&1 > /dev/null
		LOOP=0
		while [ ${LOOP} -lt 10 ]; do
			sleep 2
			pgrep -f ${prog}.jar 2>&1 > /dev/null
			RETVAL=$?
			if [ $RETVAL -eq 0 ]; then
				let LOOP=11
			else
				let LOOP+=1
				echo -n "."
			fi
		done
		if [ $RETVAL -eq 0 ]; then
			success
		else
			failure
		fi
		echo
	else
		echo -n "(not running)"
		failure
		echo
	fi
	return $RETVAL
}
 
# See how we were called.
if [ -f "/etc/init.d/${prog}" ]; then
	case "$1" in
		runservice)
			runservice
			;;
		validate)
			runvalidate
			;;
		start)
			runvalidate
			start
			;;
		stop)
			stop
			;;
		restart|reload)
			restart
			;;
		console)
			if [ -f "${minecraft_pidfile}" ]; then
				minecraft_pid=`pgrep -of ${prog}`
				/usr/bin/screen -Ax ${minecraft_pid}
			else
				echo "ERROR: ${prog} not running."
			fi
			;;
		*)
			echo "Usage: $0 {start|stop|restart|console}"
			exit 1
	esac
else
	case "$1" in
		install)
			echo -n "Installing ${prog}: "
			cp $0 /etc/init.d/${prog}
			RETVAL=$?
			if [ $RETVAL -eq 0 ]; then
				chmod 755 /etc/init.d/${prog}
				success
				echo
				echo -n "Adding ${prog} Service: "
				/sbin/chkconfig --add ${prog}
				RETVAL=$?
				if [ $RETVAL -eq 0 ]; then
					success
					echo
					/sbin/chkconfig ${prog} on
					/etc/init.d/${prog} validate
					RETVAL=$?
					if [ $RETVAL -eq 0 ]; then
						echo
						echo "Installation Successful!!!"
						echo
						echo "  To start the service, run 'service minecraft_server start' as root."
						echo "  Once service has started, you can run 'service minecraft_server console'"
						echo "  as root to access the minecraft_server console menu."
						echo
						exit 0
					fi
				else
					failure
					echo
					rm -f /etc/init.d/${prog}
					exit 1
				fi
			else
				failure
				echo
				rm -f /etc/init.d/${prog}
				exit 1
			fi
			;;
		*)
			echo "Usage: $0 {install}"
			exit 1
	esac
fi
exit $RETVAL

