PageRenderTime 148ms CodeModel.GetById 99ms app.highlight 44ms RepoModel.GetById 1ms app.codeStats 0ms

/minecraft

http://github.com/Ahtenus/minecraft-init
#! | 983 lines | 917 code | 66 blank | 0 comment | 0 complexity | b633176adeab746dcda65a0cd72d98ca MD5 | raw file
  1#!/bin/bash
  2# /etc/init.d/minecraft
  3
  4### BEGIN INIT INFO
  5# Provides:   minecraft
  6# Required-Start: $local_fs $remote_fs
  7# Required-Stop:  $local_fs $remote_fs
  8# Should-Start:   $network
  9# Should-Stop:    $network
 10# Default-Start:  2 3 4 5
 11# Default-Stop:   0 1 6
 12# Short-Description:    Minecraft server
 13# Description:    Init script for minecraft/bukkit server, with rolling logs and use of ramdisk for less lag.
 14### END INIT INFO
 15
 16# Created by Ahtenus
 17
 18# Based on http://www.minecraftwiki.net/wiki/Server_startup_script
 19# Support for multiworld by Benni-chan
 20# Log rolls without needing restarts by Solorvox
 21# Option for killing server in an emergency by jbondhus
 22
 23# Loads config file
 24
 25if [ -L $0 ]
 26then
 27	source `readlink -e $0 | sed "s:[^/]*$:config:"`
 28else
 29	source `echo $0 | sed "s:[^/]*$:config:"`
 30fi
 31
 32if [ "$SERVICE" == "" ]
 33then
 34	echo "Couldn't load config file, please edit config.example and rename it to config"
 35	logger -t minecraft-init "Couldn't load config file, please edit config.example and rename it to config"
 36	exit
 37fi
 38
 39ME=`whoami`
 40as_user() {
 41	if [ $ME == $USERNAME ] ; then
 42		bash -c "$1"
 43	else
 44		su $USERNAME -s /bin/bash -c "$1"
 45	fi
 46}
 47
 48is_running() {
 49	# Checks for the minecraft servers screen session
 50	# returns true if it exists.
 51	pidfile=${MCPATH}/${SCREEN}.pid
 52
 53	if [ -f "$pidfile" ]
 54	then
 55		pid=$(head -1 $pidfile)
 56		if ps ax | grep -v grep | grep ${pid} | grep "${SCREEN}" > /dev/null
 57		then
 58			return 0
 59		else
 60			if [ -z "$isInStop" ]
 61			then
 62				if [ -z "$roguePrinted" ]
 63				then
 64					roguePrinted=1
 65					echo "Rogue pidfile found!"
 66				fi
 67			fi
 68			return 1
 69		fi
 70	else
 71		if ps ax | grep -v grep | grep "${SCREEN} ${INVOCATION}" > /dev/null
 72		then
 73			echo "No pidfile found, but server's running."
 74			echo "Re-creating the pidfile."
 75
 76			pid=$(ps ax | grep -v grep | grep "${SCREEN} ${INVOCATION}" | cut -f1 -d' ')
 77			check_permissions
 78			as_user "echo $pid > $pidfile"
 79
 80			return 0
 81		else
 82			return 1
 83		fi
 84	fi
 85}
 86
 87datepath() {
 88	# datepath path filending-to-check returned-filending
 89
 90	# Returns an file path with added date between the filename and file ending.
 91	# $1 filepath (not including file ending)
 92	# $2 file ending to check for uniqueness
 93	# $3 file ending to return
 94
 95	if [ -e $1`date +%F`$2 ]
 96	then
 97		echo $1`date +%FT%T`$3
 98	else
 99		echo $1`date +%F`$3
100	fi
101}
102
103mc_start() {
104	servicejar=$MCPATH/$SERVICE
105	if [ ! -f "$servicejar" ]
106	then
107		echo "Failed to start: Can't find the specified Minecraft jar under $servicejar. Please check your config!"
108		exit 1
109	fi
110
111	pidfile=${MCPATH}/${SCREEN}.pid
112	check_permissions
113
114	as_user "cd $MCPATH && screen -dmS $SCREEN $INVOCATION"
115	as_user "screen -list | grep "\.$SCREEN" | cut -f1 -d'.' | head -n 1 | tr -d -c 0-9 > $pidfile"
116
117	#
118	# Waiting for the server to start
119	#
120	seconds=0
121	until is_running
122	do
123		sleep 1
124		seconds=$seconds+1
125		if [[ $seconds -eq 5 ]]
126		then
127			echo "Still not running, waiting a while longer..."
128		fi
129		if [[ $seconds -ge 120 ]]
130		then
131			echo "Failed to start, aborting."
132			exit 1
133		fi
134	done
135	echo "$SERVICE is running."
136}
137
138mc_command() {
139	if is_running
140	then
141			as_user "screen -p 0 -S $SCREEN -X eval 'stuff \"$(eval echo $FORMAT)\"\015'"
142	else
143			echo "$SERVICE was not running. Not able to run command."
144	fi
145}
146
147mc_saveoff() {
148	if is_running
149	then
150		echo "$SERVICE is running... suspending saves"
151		mc_command save-off
152		mc_command save-all
153		sync
154		sleep 10
155	else
156		echo "$SERVICE was not running. Not suspending saves."
157	fi
158}
159
160mc_saveon() {
161	if is_running
162	then
163		echo "$SERVICE is running... re-enabling saves"
164		mc_command save-on
165	else
166		echo "$SERVICE was not running. Not resuming saves."
167	fi
168}
169
170mc_say() {
171	if is_running
172	then
173		echo "Said: $1"
174		mc_command "say $1"
175	else
176		echo "$SERVICE was not running. Not able to say anything."
177	fi
178}
179
180mc_stop() {
181	pidfile=${MCPATH}/${SCREEN}.pid
182	#
183	# Stops the server
184	#
185	echo "Saving worlds..."
186	mc_command save-all
187	sleep 10
188	echo "Stopping server..."
189	mc_command stop
190	sleep 0.5
191	#
192	# Waiting for the server to shut down
193	#
194	seconds=0
195	isInStop=1
196	while is_running
197	do
198		sleep 1
199		seconds=$seconds+1
200		if [[ $seconds -eq 5 ]]
201		then
202			echo "Still not shut down, waiting a while longer..."
203		fi
204		if [[ $seconds -ge 120 ]]
205		then
206			logger -t minecraft-init "Failed to shut down server, aborting."
207			echo "Failed to shut down, aborting."
208			exit 1
209		fi
210	done
211	as_user "rm $pidfile"
212	unset isInStop
213	is_running
214	echo "$SERVICE is now shut down."
215}
216
217mc_reload() {
218        echo "$SERVICE is running... reloading."
219        mc_command reload
220}
221
222check_backup_settings() {
223	case "$BACKUPFORMAT" in
224		tar)
225			COMPRESSCMD="tar -hcjf"
226			STORECMD="tar -cpf"
227			ARCHIVEENDING=".tar.bz2"
228			STOREDENDING=".tar"
229			EXCLUDEARG="-X "
230			;;
231		zip)
232			COMPRESSCMD="zip -rq"
233			STORECMD="zip -rq -0"
234			ARCHIVEENDING=".zip"
235			STOREDENDING=".zip"
236			EXCLUDEARG="-x@"
237			;;
238		*)
239			echo "$BACKUPFORMAT is not a supported backup format"
240			exit 1
241			;;
242	esac
243}
244
245log_roll() {
246	# Moves the logfiles and compresses that backup directory
247	check_backup_settings
248	path=`datepath $LOGPATH/logs_ $ARCHIVEENDING`
249	as_user "mkdir -p $path"
250
251	shopt -s extglob
252	for FILE in $(ls $MCPATH/*.log)
253	do
254		as_user "cp $FILE $path"
255		# only if previous command was successful
256		if [ $? -eq 0 ]; then
257			if [[ "$FILE" = @(*-+([0-9]).log) && "$FILE" = !(*-0.log) ]]
258			# some mods already roll logs. remove all but the most recent file
259			# which ends with -0.log
260			then
261				as_user "rm $FILE"
262			else
263			# truncate the existing log without restarting server
264				as_user "cp /dev/null $FILE"
265				as_user "echo \"Previous logs rolled to $path\" > $FILE"
266			fi
267		else
268			echo "Failed to rotate log from $FILE into $path"
269		fi
270	done
271
272	as_user "$COMPRESSCMD $path$ARCHIVEENDING $path"
273	if [ $? -eq 0 ]; then
274		as_user "rm -r $path"
275	fi
276}
277
278get_worlds() {
279	SAVEIFS=$IFS
280	IFS=$(echo -en "\n\b")
281
282	a=1
283	for NAME in $(ls $WORLDSTORAGE)
284	do
285		if [ -d $WORLDSTORAGE/$NAME ]
286		then
287			WORLDNAME[$a]=$NAME
288			if [ -e $WORLDSTORAGE/$NAME/ramdisk ]
289			then
290				WORLDRAM[$a]=true
291			else
292				WORLDRAM[$a]=false
293			fi
294			a=$a+1
295		fi
296	done
297
298	IFS=$SAVEIFS
299}
300
301mc_whole_backup() {
302	check_backup_settings
303	echo "backing up entire setup into $WHOLEBACKUP"
304	path=`datepath $WHOLEBACKUP/mine_`
305	locationOfScript=$(dirname "$(readlink -e "$0")")
306	as_user "mkdir -p $path"
307
308	if [ -r "$locationOfScript/exclude.list" ]
309	then
310		echo "...except the following files and/or dirs:"
311		cat $locationOfScript/exclude.list
312		exclude="$EXCLUDEARG$locationOfScript/exclude.list"
313	fi
314	if [ "$COMPRESS_WHOLEBACKUP" ]
315	then
316		as_user "$COMPRESSCMD $path/whole-backup$ARCHIVEENDING $MCPATH $exclude"
317	else
318		as_user "$STORECMD $path/whole-backup$STOREDENDING $MCPATH $exclude"
319	fi
320}
321
322mc_world_backup() {
323	#
324	# Backup the worlds and puts them in a folder for each day (unless $BACKUPSCRIPTCOMPATIBLE is set)
325	#
326
327	check_backup_settings
328	get_worlds
329	today="`date +%F`"
330	as_user "mkdir -p $BACKUPPATH"
331
332	# Check if the backup script compatibility is enabled
333	if [ "$BACKUPSCRIPTCOMPATIBLE" ]
334	then
335		# If it is enabled, then delete the old backups to prevent errors
336		echo "Detected that backup script compatibility is enabled, deleting old backups that are not necessary."
337		as_user "rm -r $BACKUPPATH/*"
338	fi
339
340	for INDEX in ${!WORLDNAME[@]}
341	do
342		echo "Backing up minecraft ${WORLDNAME[$INDEX]}"
343		if [ "$WORLDEDITCOMPATIBLE" ]
344		# If this is set tars will be created compatible to WorldEdit
345		then
346			as_user "mkdir -p $BACKUPPATH/${WORLDNAME[$INDEX]}"
347			path=`datepath $BACKUPPATH/${WORLDNAME[$INDEX]}/ $ARCHIVEENDING $ARCHIVEENDING`
348		elif [ "$BACKUPSCRIPTCOMPATIBLE" ]
349		# If is set tars will be put in $BACKUPPATH without any timestamp to be compatible with
350		# [backup rotation script](https://github.com/adamfeuer/rotate-backups)
351		then
352			path=$BACKUPPATH/${WORLDNAME[$INDEX]}$ARCHIVEENDING
353		else
354			as_user "mkdir -p $BACKUPPATH/${today}"
355			path=`datepath $BACKUPPATH/${today}/${WORLDNAME[$INDEX]}_ $ARCHIVEENDING $ARCHIVEENDING`
356		fi
357		if [ "$WORLDEDITCOMPATIBLE" ]
358		# Don't store the complete path
359		then
360			as_user "cd $MCPATH && $COMPRESSCMD $path ${WORLDNAME[$INDEX]}"
361		else
362			as_user "$COMPRESSCMD $path $MCPATH/${WORLDNAME[$INDEX]}"
363		fi
364	done
365}
366
367check_links() {
368	get_worlds
369	for INDEX in ${!WORLDNAME[@]}
370	do
371		if [[ -L $MCPATH/${WORLDNAME[$INDEX]} || ! -a $MCPATH/${WORLDNAME[$INDEX]} ]]
372		then
373			link=`ls -l $MCPATH/${WORLDNAME[$INDEX]} | awk '{print $11}'`
374			if ${WORLDRAM[$INDEX]}
375			then
376				if [ "$link" != "$RAMDISK/${WORLDNAME[$INDEX]}" ]
377				then
378					as_user "rm -f $MCPATH/${WORLDNAME[$INDEX]}"
379					as_user "ln -s $RAMDISK/${WORLDNAME[$INDEX]} $MCPATH/${WORLDNAME[$INDEX]}"
380					echo "Created link for ${WORLDNAME[$INDEX]}"
381				fi
382			else
383				if [ "$link" != "${WORLDSTORAGE}/${WORLDNAME[$INDEX]}" ]
384				then
385					as_user "rm -f $MCPATH/${WORLDNAME[$INDEX]}"
386					as_user "ln -s ${WORLDSTORAGE}/${WORLDNAME[$INDEX]} $MCPATH/${WORLDNAME[$INDEX]}"
387					echo "Created link for ${WORLDNAME[$INDEX]}"
388				fi
389			fi
390		else
391			echo "Could not process the world named '${WORLDNAME[$INDEX]}'. Please move all worlds to ${WORLDSTORAGE}."
392
393			exit 1
394		fi
395	done
396}
397
398to_ram() {
399	get_worlds
400	for INDEX in ${!WORLDNAME[@]}
401	do
402		if ${WORLDRAM[$INDEX]}
403		then
404			if [ -L $MCPATH/${WORLDNAME[$INDEX]} ]
405			then
406				as_user "mkdir -p $RAMDISK"
407				as_user "rsync -rt --exclude 'ramdisk' ${WORLDSTORAGE}/${WORLDNAME[$INDEX]}/ $RAMDISK/${WORLDNAME[$INDEX]}"
408				echo "${WORLDNAME[$INDEX]} copied to ram"
409			fi
410		fi
411	done
412}
413
414to_disk() {
415	get_worlds
416	for INDEX in ${!WORLDNAME[@]}
417	do
418		if ${WORLDRAM[$INDEX]}
419		then
420			as_user "rsync -rt --exclude 'ramdisk' $MCPATH/${WORLDNAME[$INDEX]}/ ${WORLDSTORAGE}/${WORLDNAME[$INDEX]}"
421			echo "${WORLDNAME[$INDEX]} copied to disk"
422		fi
423	done
424}
425
426check_update_vanilla() {
427	MC_SERVER_URL=`wget -q -O - http://minecraft.net/download | grep minecraft_server.jar\ | cut -d \" -f 6`
428
429	echo "Checking for update for minecraft_server.jar (Vanilla)"
430	as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update $MC_SERVER_URL"
431
432	if [ -r "$MCPATH/minecraft_server.jar.update" ]
433	then
434		if `diff $MCPATH/$MC_JAR $MCPATH/minecraft_server.jar.update >/dev/null`
435		then
436			echo "You are already running the latest version of minecraft_server.jar."
437			return 1
438		else
439			echo "Update of $MC_JAR is needed."
440			return 0
441		fi
442	else
443		echo "Something went wrong. Couldn't download minecraft_server.jar"
444	fi
445}
446
447get_cb_release_channel() {
448	CB_URL="http://dl.bukkit.org/latest-"
449
450	case $CB_RELEASE in
451		unstable|UNSTABLE|Unstable|dev|development)
452			echo $CB_URL"dev/craftbukkit.jar"
453		;;
454		beta|Beta|BETA)
455			echo $CB_URL"beta/craftbukkit.jar"
456		;;
457		*)
458			echo $CB_URL"rb/craftbukkit.jar"
459		;;
460	esac
461}
462
463check_update_craftbukkit() {
464	echo "Checking for update for craftbukkit.jar"
465	echo "You are on release channel \"$CB_RELEASE\""
466
467	as_user "cd $MCPATH && wget -q -O $MCPATH/craftbukkit.jar.update $(get_cb_release_channel)"
468	if [ -r "$MCPATH/craftbukkit.jar.update" ]
469	then
470		if `diff $MCPATH/$CB_JAR $MCPATH/craftbukkit.jar.update >/dev/null`
471		then
472			echo "You are already running the latest version of craftbukkit.jar."
473			return 1
474		else
475			echo "Update of $CB_JAR is needed."
476			return 0
477		fi
478	else
479		echo "Something went wrong. Couldn't download craftbukkit.jar"
480	fi
481}
482
483mc_update() {
484	if is_running
485	then
486		echo "$SERVICE is running! Will not start update."
487	else
488		if check_update_vanilla
489		then
490			if [ -r "$MCPATH/minecraft_server.jar.update" ]
491			then
492				as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/$MC_JAR"
493				echo "Thats it. Update of $MC_JAR done."
494			else
495				echo "Something went wrong. Couldn't replace your original $MC_JAR with minecraft_server.jar.update"
496			fi
497		else
498			echo "Not updating $MB_JAR. It's not necessary"
499			as_user "rm $MCPATH/minecraft_server.jar.update"
500		fi
501
502		if check_update_craftbukkit
503		then
504			if [ -r "$MCPATH/craftbukkit.jar.update" ]
505			then
506				as_user "mv $MCPATH/craftbukkit.jar.update $MCPATH/$CB_JAR"
507				echo "Thats it. Update of $CB_JAR done."
508			else
509				echo "Something went wrong. Couldn't replace your original $CB_JAR with craftbukkit.jar.update"
510			fi
511		else
512			echo "Not updating $CB_JAR. It's not necessary"
513			as_user "rm $MCPATH/craftbukkit.jar.update"
514		fi
515	fi
516}
517
518change_ramdisk_state() {
519	if [ ! -e $WORLDSTORAGE/$1 ]
520	then
521		echo "World \"$1\" not found."
522		exit 1
523	fi
524
525	if [ -e $WORLDSTORAGE/$1/ramdisk ]
526	then
527		rm $WORLDSTORAGE/$1/ramdisk
528		echo "Removed ramdisk flag from \"$1\""
529	else
530		touch $WORLDSTORAGE/$1/ramdisk
531		echo "Added ramdisk flag to \"$1\""
532	fi
533	echo "Changes will only take effect after server is restarted."
534}
535
536overviewer_start() {
537		if [ ! -e $OVPATH/overviewer.py ]
538		then
539				if [ ! "$OVPATH" == "apt" ]
540				then
541						echo "Minecraft-Overviewer is not installed in \"$OVPATH\""
542						exit 1
543				else
544						echo "Using APT repository installed Minecraft-Overviewer"
545				fi
546		fi
547		if [ ! -e $OUTPUTMAP ]
548		then
549				as_user "mkdir -p $OUTPUTMAP"
550		fi
551		if [ -e $OVCONFIGPATH/$OVCONFIGNAME ]
552		then
553				echo "Start generating map with Minecraft-Overviewer..."
554				if [ "$OVPATH" == "apt" ]
555				then
556						as_user "overviewer.py --config=$OVCONFIGPATH/$OVCONFIGNAME"
557				else
558						as_user "python $OVPATH/overviewer.py --config=$OVCONFIGPATH/$OVCONFIGNAME"
559				fi
560				echo "Map generated."
561		else
562				echo "No config file found. Start with default config..."
563				if [ -z $1 ] || [ ! -e $OVBACKUP/$1 ]
564				then
565						echo "World \"$1\" not found."
566				else
567						echo "Start generating map with Minecraft-Overviewer..."
568						if [ "$OVPATH" == "apt" ]
569						then
570								as_user "nice overviewer.py $OVBACKUP/$1 $OUTPUTMAP"
571						else
572								as_user "nice python $OVPATH/overviewer.py $OVBACKUP/$1 $OUTPUTMAP"
573						fi
574						echo "Map generated."
575				fi
576		fi
577}
578
579overviewer_copy_worlds() {
580	#
581	# Backup the worlds for overviewer
582	#
583
584	get_worlds
585	for INDEX in ${!WORLDNAME[@]}
586	do
587		echo "Copying minecraft ${WORLDNAME[$INDEX]}."
588		as_user "mkdir -p $OVBACKUP"
589		as_user "rsync -rt --delete $WORLDSTORAGE/${WORLDNAME[$INDEX]} $OVBACKUP/${WORLDNAME[$INDEX]}"
590	done
591}
592
593whitelist(){
594	mc_command "whitelist list"
595	sleep 1s
596	whitelist=$(tac $SERVERLOG | grep -m 1 "White-listed players:")
597
598	echo
599	echo "Currently there are the following players on your whitelist:"
600	echo
601	echo ${whitelist:49} | sed 's/, /\n/g'
602}
603
604force_exit() {  # Kill the server running (messily) in an emergency
605	echo ""
606	echo "SIGINIT CALLED - FORCE EXITING!"
607	pidfile=${MCPATH}/${SCREEN}.pid
608	rm $pidfile
609	echo "KILLING SERVER PROCESSES!!!"
610		# Display which processes are being killed
611		ps aux | grep -e 'java -Xmx' | grep -v grep | awk '{print $2}' | xargs -i echo "Killing PID: " {}
612		ps aux | grep -e 'SCREEN -dmS minecraft java' | grep -v grep | awk '{print $2}' | xargs -i echo "Killing PID: " {}
613		ps aux | grep -e '/etc/init.d/minecraft' | grep -v grep | awk '{print $2}' | xargs -i echo "Killing PID: " {}
614
615		# Kill the processes
616		ps aux | grep -e 'java -Xmx' | grep -v grep | awk '{print $2}' | xargs -i kill {}
617		ps aux | grep -e 'SCREEN -dmS minecraft java' | grep -v grep | awk '{print $2}' | xargs -i kill {}
618		ps aux | grep -e '/etc/init.d/minecraft' | grep -v grep | awk '{print $2}' | xargs -i kill {}
619
620	exit 1
621}
622
623get_script_location() {
624	echo $(dirname "$(readlink -e "$0")")
625}
626
627check_permissions() {
628	as_user "touch $pidfile"
629	if ! as_user "test -w '$pidfile'" ; then
630		echo "Check Permissions. Cannot write to $pidfile. Correct the permissions and then excute: $0 status"
631	fi
632}
633
634trap force_exit SIGINT
635
636case "$1" in
637	start)
638		# Starts the server
639		if is_running; then
640			echo "Server already running."
641		else
642			check_links
643			to_ram
644			mc_start
645		fi
646		;;
647	stop)
648		# Stops the server
649		if is_running; then
650			mc_say "SERVER SHUTTING DOWN!"
651			mc_stop
652			to_disk
653		else
654			echo "No running server."
655		fi
656		;;
657	restart)
658		# Restarts the server
659		if is_running; then
660			mc_say "SERVER REBOOT IN 10 SECONDS!"
661			mc_stop
662			to_disk
663		else
664			echo "No running server, starting it..."
665		fi
666		check_links
667		to_ram
668		mc_start
669		;;
670        reload)
671                # Reloads server configuration
672                if is_running; then
673                        mc_say "Reloading server configuration.."
674                        mc_reload
675                else
676                        echo "No running server."
677                fi
678                ;;
679	whitelist)
680		if is_running; then
681			whitelist
682		else
683			echo "Server not running."
684		fi
685		;;
686	whitelist-reload)
687		# Reloads the whitelist
688		if is_running; then
689			mc_command "whitelist reload"
690		else
691			echo "No running server."
692		fi
693		;;
694	whitelist-add)
695		# Adds a player to the whitelist
696		if is_running; then
697			mc_command "whitelist add $2"
698		else
699			echo "No running server."
700		fi
701		;;
702	backup)
703		# Backups world
704		if is_running; then
705			mc_say "Backing up world."
706			mc_saveoff
707			to_disk
708			mc_world_backup
709			mc_saveon
710			mc_say "Backup complete."
711		else
712			mc_world_backup
713		fi
714		;;
715	whole-backup)
716		# Backup everything
717		if is_running; then
718			mc_say "COMPLETE SERVER BACKUP IN 10 SECONDS.";
719			mc_say "WARNING: WILL RESTART SERVER SOFTWARE!"
720			mc_stop
721			to_disk
722			mc_whole_backup
723			check_links
724			mc_start
725		else
726			mc_whole_backup
727		fi
728		;;
729	check-update)
730		check_update_vanilla
731		check_update_craftbukkit
732		as_user "rm $MCPATH/minecraft_server.jar.update"
733		as_user "rm $MCPATH/craftbukkit.jar.update"
734		;;
735	update)
736		#update minecraft_server.jar and craftbukkit.jar (thanks karrth)
737		if is_running; then
738			mc_say "SERVER UPDATE IN 10 SECONDS."
739			mc_stop
740			to_disk
741			mc_whole_backup
742			mc_update
743			check_links
744			mc_start
745		else
746			mc_whole_backup
747			mc_update
748		fi
749		;;
750	to-disk)
751		# Writes from the ramdisk to disk, in case the server crashes.
752		mc_saveoff
753		to_disk
754		mc_saveon
755		;;
756	save-off)
757		# Flushes the state of the world to disk, and then disables
758		# saving until save-on is called (useful if you have your own
759		# backup scripts).
760		if is_running; then
761			mc_saveoff
762		else
763			echo "Server was not running, syncing from ram anyway..."
764		fi
765		to_disk
766		;;
767	save-on)
768		# Re-enables saving if it was disabled by save-off.
769		if is_running; then
770			mc_saveon
771		else
772			echo "No running server."
773		fi
774		;;
775	say)
776		# Says something to the ingame chat
777		if is_running; then
778			shift 1
779			mc_say "$*"
780		else
781			echo "No running server to say anything."
782		fi
783		;;
784	command)
785		if is_running; then
786			shift 1
787			mc_command "$*"
788			echo "Sent command: $*"
789		else
790			echo "No running server to send a command to."
791		fi
792		;;
793	connected)
794		# Lists connected users
795		if is_running; then
796			mc_command list
797			sleep 1s
798			# Get server log in reverse order, assume that response to 'list'
799			# command is already there.
800			tac $SERVERLOG | \
801				# Extract two lines. 1) containing ASCII color code and comma-separated list
802				# of  player names and 2) the line saying "[...] players online:"
803				grep --before-context 1 --max-count 1 "players online" | \
804				# Throw away the latter line.
805				head -n 1 | \
806				# Remove any escape character and the following two bytes (color code).
807				sed 's/[\x01-\x1F\x7F]..//g' | \
808				# Only pass through lines that still have content (if no player online,
809				# then nothing's left over after this grep.
810				grep . | \
811				# Replace ", " separator with newline char.
812				sed 's/, /\n/g'
813		else
814			echo "No running server."
815		fi
816		;;
817	playercount)
818		# List number of connected users.
819		if is_running; then
820			mc_command list
821			sleep 1s
822			# Same as technique as 'connected' command, but count lines.
823			tac $SERVERLOG | \
824				grep --before-context 1 --max-count 1 "players online" | \
825				head -n 1 | sed 's/[\x01-\x1F\x7F]..//g' | grep . | sed 's/, /\n/g' | wc -l
826		else
827			echo "No running server."
828		fi
829		;;
830	log-roll)
831		log_roll
832		;;
833	log)
834		# Display server log using 'cat'.
835		cat $SERVERLOG
836		;;
837	last)
838		# Greps for recently logged in users
839		echo Recently logged in users:
840		cat $SERVERLOG | awk '/entity|conn/ {sub(/lost/,"disconnected");print $1,$2,$4,$5}'
841		;;
842	status)
843		# Shows server status
844		if is_running
845		then
846			echo "$SERVICE is running."
847		else
848			echo "$SERVICE is not running."
849		fi
850		;;
851	version)
852		if is_running; then
853			mc_command version
854			tac $SERVERLOG | grep -m 1 "This server is running"
855		else
856			echo "The server needs to be running to check version."
857		fi
858		;;
859	links)
860		check_links
861		;;
862	ramdisk)
863		change_ramdisk_state $2
864		;;
865	worlds)
866		get_worlds
867		for INDEX in ${!WORLDNAME[@]}
868		do
869			if ${WORLDRAM[$INDEX]}
870			then
871				echo "${WORLDNAME[$INDEX]} (ramdisk)"
872			else
873				echo ${WORLDNAME[$INDEX]}
874			fi
875		done
876		;;
877	overviewer)
878		if is_running; then
879			mc_say "Generating overviewer map."
880			mc_saveoff
881			to_disk
882			overviewer_copy_worlds
883			mc_saveon
884			overviewer_start $2
885		else
886			overviewer_copy_worlds
887			overviewer_start $2
888		fi
889		;;
890	screen)
891		if is_running; then
892			as_user "script /dev/null -q -c \"screen -rx $SCREEN\""
893		else
894		echo "Server is not running. Do you want to start it?"
895		echo "Please put \"Yes\", or \"No\": "
896		read START_SERVER
897		case "$START_SERVER" in
898			[Yy]|[Yy][Ee][Ss])
899				check_links
900				to_ram
901				mc_start
902				as_user "script /dev/null -q -c \"screen -rx $SCREEN\""
903				;;
904			[Nn]|[Nn][Oo])
905				clear
906				echo "Aborting startup!"
907				sleep 1
908				clear
909				exit 1
910				;;
911			*)
912				clear
913				echo "Invalid input"
914				sleep 1
915				clear
916				exit 1
917				;;
918		esac
919		fi
920		;;
921	kill)
922		WIDTH=`stty size | cut -d ' ' -f 2`            # Get terminal's character width
923		pstree | grep MDSImporte | cut -c 1-${WIDTH}   # Chop output after WIDTH chars
924
925		echo "Killing the server is an EMERGENCY procedure, and should not be used to perform a normal shutdown! All changes younger than 15 minutes could be permanantly lost and WORLD CORRUPTION is possible! Are you ABSOLUTELY POSITIVE this is what you want to do?"
926		echo "Please put \"Yes\", or \"No\": "
927		read KILL_SERVER
928		case "$KILL_SERVER" in  # Determine which option was specified
929			[Yy]|[Yy][Ee][Ss])      # If yes, kill the server
930				echo "KILLING SERVER PROCESSES!!!"
931				force_exit
932				exit 1
933				;;
934			[Nn]|[Nn][Oo])  # If no, abort and exit 1
935				echo "Aborting!"
936				exit 1
937				;;
938			*)      # If anything else, exit 1
939				echo "Error: Invalid Input!"
940				exit 1
941				;;
942		esac
943		;;
944	help|--help|-h)
945		echo "Usage: $0 COMMAND"
946		echo
947		echo "Available commands:"
948		echo -e "   start \t\t Starts the server"
949		echo -e "   stop \t\t Stops the server"
950		echo -e "   kill \t\t Kills the server"
951		echo -e "   restart \t\t Restarts the server"
952		echo -e "   reload \t\t Reloads the server configuration"
953		echo -e "   backup \t\t Backups the worlds defined in the script"
954		echo -e "   whole-backup \t Backups the entire server folder"
955		echo -e "   check-update \t Checks for updates of $CB_JAR and $MC_JAR"
956		echo -e "   update \t\t Fetches the latest version of minecraft.jar server and Bukkit"
957		echo -e "   log-roll \t\t Moves and compresses the logfiles"
958		echo -e "   log \t\t\t Prints the server log"
959		echo -e "   to-disk \t\t Copies the worlds from the ramdisk to worldstorage"
960		echo -e "   save-off \t\t Flushes the world to disk and then disables saving"
961		echo -e "   save-on \t\t Re-enables saving if it was previously disabled by save-off"
962		echo -e "   say \t\t\t Prints the given string to the ingame chat"
963		echo -e "   connected \t\t Lists connected users"
964		echo -e "   playercount \t\t Prints the number of connected users"
965		echo -e "   status \t\t Displays server status"
966		echo -e "   version \t\t Displays Bukkit version and then exits"
967		echo -e "   links \t\t Creates nessesary symlinks"
968		echo -e "   last \t\t Displays recently connected users"
969		echo -e "   worlds \t\t Displays a list of available worlds"
970		echo -e "   ramdisk WORLD \t Toggles ramdisk configuration for WORLD"
971		echo -e "   overviewer WORLD \t Creates a map of the WORLD with Minecraft-Overviewer"
972		echo -e "   whitelist \t\t Prints the current whitelist"
973		echo -e "   whitelist-add NAME \t Adds the specified player to the server whitelist"
974		echo -e "   whitelist-reload \t Reloads the whitelist"
975		echo -e "   screen \t\t Shows the server screen"
976		;;
977	*)
978		echo "No such command, see $0 help"
979		exit 1
980		;;
981esac
982
983exit 0