Skip to content

Instantly share code, notes, and snippets.

@bashtech
Last active December 10, 2015 05:08
Show Gist options
  • Save bashtech/4385766 to your computer and use it in GitHub Desktop.
Save bashtech/4385766 to your computer and use it in GitHub Desktop.
#!/bin/bash
# original author : Relliktsohg
# Huge thanks to Maine for his incremental backup
# Modified by bGeorge for use on the ATB Minecraft servers
. /lib/lsb/init-functions
# Configuration
MC_PATH=/home/gaming/minecraft
SCREEN_NAME="mc"
MEMALOCMAX=3000
MEMALOCSTART=100
MC_JAR=minecraft_server.jar;
MC_LOCK=server.log.lck;
WORLD_NAME="world1"
WORLDS_TO_BACKUP="world1"
BKUP_PATH=/home/gaming/minecraft/backups
BKUP_DAYS_INCR=1
BKUP_DAYS_FULL=3
WORLDS_TO_CARTO="world1"
CARTO_PATH=/home/gaming/minecraft/mcmap
MAPS_PATH=/home/gaming/minecraft/cartographs
CARTO_DAYS_TO_KEEP=3
USAGE="Usage : minecraft < start | stop | restart | backup | backup-full | cartography-day | screen>"
ID=`which id`;
KILL=`which kill`;
# End of configuration
if [ -e $MC_PATH/server.log.lck ]
then
# ps -e | grep java | wc -l
ONLINE=1
else
ONLINE=0
fi
display() {
screen -R $SCREEN_NAME
}
start_minecraft() {
log_action_begin_msg "Starting minecraft-server"
# Make sure old minecraft isn't running because they fight for same ip:port
#if [ -f $MC_PATH/$MC_LOCK ]; then
# log_action_end_msg 1 # Fail
# log_failure_msg "Lock file exists. (Is minecraft-server already running?)"
# return
#fi
# Check for existing screen session
if [ ! "`screen -ls | grep $SCREEN_NAME | wc -l`" == "0" ]; then
log_action_end_msg 1 # Fail
log_failure_msg "Screen session exists. (Is minecraft-server already running?)"
return
fi
# Allow full core dumps for debugging purposes
ulimit -c unlimited
#cd $MC_PATH; screen -m -d -S $SCREEN_NAME nice -n 0 java -Xincgc -Xms${MEMALOC}M -Xmx${MEMALOC}M -Djava.net.preferIPv4Stack=true -jar $MC_JAR nogui
cd $MC_PATH; screen -m -d -S $SCREEN_NAME nice -n 0 java -Xms${MEMALOCSTART}M -Xmx${MEMALOCMAX}M -Djava.net.preferIPv4Stack=true -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=2 -XX:+AggressiveOpts -server -jar $MC_JAR nogui
log_action_end_msg $?
}
stop_minecraft() {
log_action_begin_msg "Stopping minecraft-server (nicely)"
# Verify session exists
if [ "`screen -ls | grep $SCREEN_NAME | wc -l`" == "0" ]; then
log_action_end_msg 1 # Fail
log_failure_msg "Screen session not found. (Is minecraft-server running?)"
if [ ! "$FORCE" == "TRUE" ]; then
return
fi
else # Screen reports a session..
SCREEN_PID=`screen -ls | grep $SCREEN_NAME | cut -f2 | cut -d. -f1`;
screen -S $SCREEN_NAME -p 0 -X stuff $'say Shutdown requested by console.\n' &>/dev/null
screen -S $SCREEN_NAME -p 0 -X stuff $'save-all\n' &>/dev/null; sleep 15
screen -S $SCREEN_NAME -p 0 -X stuff $'stop\n' &>/dev/null; RET=$?; sleep 15
log_action_end_msg $RET
if [ ! "$FORCE" == "TRUE" ]; then
return
fi
fi
if [ "$FORCE" == "TRUE" ]; then
log_action_begin_msg "Stopping minecraft-server (forced)"
# Use the PID returned by screen, if possible
if [ -h /proc/${SCREEN_PID-UNSET}/exe ]; then
$KILL -TERM $SCREEN_PID; sleep 1 # Try to be nice
$KILL -KILL $SCREEN_PID &>/dev/null # Use more force
fi
# Brute force killing
OTHER_PIDS=`ps ax | grep java | grep $MC_JAR | grep -v grep | cut -d' ' -f2`
if [ -n "$OTHER_PIDS" ]; then
$KILL -TERM $OTHER_PIDS; sleep 1 # Try to be nice
$KILL -KILL $OTHER_PIDS &>/dev/null # Use more force
fi
# Remove the lock file
if [ -f $MC_PATH/$MC_LOCK ]; then
rm -f $MC_PATH/$MC_LOCK
fi
log_action_end_msg 0 # Success
fi
}
if [ $# -gt 0 ]
then
case $1 in
#################################################################
"start")
start_minecraft
;;
#################################################################
"stop")
stop_minecraft
;;
#################################################################
"screen")
screen -r $SCREEN_NAME
;;
#################################################################
"restart")
stop_minecraft
log_action_begin_msg "Sleeping"
sleep 20
log_action_end_msg $?
start_minecraft
;;
#################################################################
"backup")
mkdir -p $BKUP_PATH
echo "Server running, warning players : backup in 10s."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Backing up the map in 10s\r"`"; sleep 10
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Now backing up the map...\r"`"
echo "Issuing save-all command, wait 5s..."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-all\r"`"; sleep 5
echo "Issuing save-off command..."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-off\r"`"; sleep 1
for world in $WORLDS_TO_BACKUP
do
WORLD_NAME=$world
BACKUP_FULL_LINK=${BKUP_PATH}/${WORLD_NAME}_full.tgz
BACKUP_INCR_LINK=${BKUP_PATH}/${WORLD_NAME}_incr.tgz
if [ -e $MC_PATH/$WORLD_NAME ]
then
cd $BKUP_PATH
DATE=$(date +%Y-%m-%d-%Hh%M)
FILENAME=$WORLD_NAME-$DATE
BACKUP_FILES=$BKUP_PATH/list.$DATE
if test `date +%H` -eq 0 -o ! -f $BACKUP_FULL_LINK
then
# Make full backup, and remove old incrementals
FILENAME=$FILENAME-full.tgz
# Remove incrementals older than $BKUP_DAYS_INCR
# Remove full archives older than $BKUP_DAYS_FULL
echo "Removing old files..."
find ./$WORLD_NAME-*-incr.tgz -type f -mtime +$BKUP_DAYS_INCR -print >> purgelist
find ./$WORLD_NAME-*-full.tgz -type f -mtime +$BKUP_DAYS_FULL -print >> purgelist
echo `cat purgelist`
rm -f `cat purgelist`
rm -f purgelist
#find ./$WORLD_NAME-*-incr.tgz -type f -mtime +$BKUP_DAYS_INCR -exec rm {} \;
#find ./$WORLD_NAME-*-full.tgz -type f -mtime +$BKUP_DAYS_FULL -exec rm {} \;
# Now make our full backup
pushd $MC_PATH
find $WORLD_NAME -type f -print > $BACKUP_FILES
tar -zcvf $BKUP_PATH/$FILENAME --files-from=$BACKUP_FILES
popd
rm -f $BACKUP_FULL_LINK $BACKUP_INCR_LINK
ln -s $FILENAME $BACKUP_FULL_LINK
else
# Make incremental backup
FILENAME=$FILENAME-incr.tgz
pushd $MC_PATH
find $WORLD_NAME -newer $BACKUP_FULL_LINK -type f -print > $BACKUP_FILES
tar -zcvf $BKUP_PATH/$FILENAME --files-from=$BACKUP_FILES
popd
rm -f $BACKUP_INCR_LINK
ln -s $FILENAME $BACKUP_INCR_LINK
fi
rm -f $BACKUP_FILES
echo "Backup process is over."
else
echo "The world \"$WORLD_NAME\" does not exist.";
fi
done
echo "Issuing save-on command..."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-on\r"`"; sleep 1
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Backup is done, have fun !\r"`"
;;
###############################################################################################
"backup-full")
mkdir -p $BKUP_PATH
echo "Server running, warning players : backup in 10s."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Backing up the map in 10s\r"`"; sleep 10
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Now backing up the map...\r"`"
echo "Issuing save-all command, wait 5s..."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-all\r"`"; sleep 5
echo "Issuing save-off command..."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-off\r"`"; sleep 1
for world in $WORLDS_TO_BACKUP
do
WORLD_NAME=$world
BACKUP_FULL_LINK=${BKUP_PATH}/${WORLD_NAME}_full.tgz
BACKUP_INCR_LINK=${BKUP_PATH}/${WORLD_NAME}_incr.tgz
if [ -e $MC_PATH/$WORLD_NAME ]
then
cd $BKUP_PATH
DATE=$(date +%Y-%m-%d-%Hh%M)
FILENAME=$WORLD_NAME-$DATE
BACKUP_FILES=$BKUP_PATH/list.$DATE
# Make full backup, and remove old incrementals
FILENAME=$FILENAME-full.tgz
pushd $MC_PATH
find $WORLD_NAME -type f -print > $BACKUP_FILES
tar -zcvf $BKUP_PATH/$FILENAME --files-from=$BACKUP_FILES
popd
rm -f $BACKUP_FULL_LINK $BACKUP_INCR_LINK
ln -s $FILENAME $BACKUP_FULL_LINK
rm -f $BACKUP_FILES
echo "Backup process is over."
else
echo "The world \"$WORLD_NAME\" does not exist.";
fi
done
echo "Issuing save-on command..."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-on\r"`"; sleep 1
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Backup is done, have fun !\r"`"
;;
#################################################################
"backup-clean")
mkdir -p $BKUP_PATH
for world in $WORLDS_TO_BACKUP
do
WORLD_NAME=$world
BACKUP_FULL_LINK=${BKUP_PATH}/${WORLD_NAME}_full.tgz
BACKUP_INCR_LINK=${BKUP_PATH}/${WORLD_NAME}_incr.tgz
if [ -e $MC_PATH/$WORLD_NAME ]
then
cd $BKUP_PATH
# Remove incrementals older than $BKUP_DAYS_INCR
# Remove full archives older than $BKUP_DAYS_FULL
echo "Removing old files..."
find ./$WORLD_NAME-*-incr.tgz -type f -mtime +$BKUP_DAYS_INCR -print >> purgelist
find ./$WORLD_NAME-*-full.tgz -type f -mtime +$BKUP_DAYS_FULL -print >> purgelist
echo `cat purgelist`
rm -f `cat purgelist`
rm -f purgelist
echo "Old files removed."
else
echo "The world \"$WORLD_NAME\" does not exist.";
fi
done
;;
#################################################################
"cartography")
echo "Issuing save-all command, wait 5s...";
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-all\r"`"; sleep 5
echo "Issuing save-off command...";
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-off\r"`"; sleep 1
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Map cartography has begun.\r"`"
if [ $# -gt 1 ]
then
WORLDS_TO_CARTO=$2
fi
echo "Cartographing worlds $WORLDS_TO_CARTO";
for world in $WORLDS_TO_CARTO
do
WORLD_NAME=$world
if [ -e $CARTO_PATH ]
then
if [ -e $MC_PATH/$WORLD_NAME ]
then
mkdir -p $MAPS_PATH
DATE=$(date +%d-%m-%Y-%Hh%M)
FILENAME=$WORLD_NAME-map-$DATE
cd $CARTO_PATH
echo "Cartography in progress..."
./mcmap -file $FILENAME.png -north -texture terrain.png -mem 1500 $MC_PATH/$WORLD_NAME/
mv $FILENAME.png $MAPS_PATH
#Write latest filename to file
echo "$FILENAME" > $MAPS_PATH/$WORLD_NAME-day.txt
#Create "latest" sym link
rm -f $MAPS_PATH/$WORLD_NAME-latest.png
ln -s $MAPS_PATH/$FILENAME.png $MAPS_PATH/$WORLD_NAME-latest.png
#Create thumbnail
#rm -f $MAPS_PATH/$WORLD_NAME-latest-thumbnail.png
#convert $MAPS_PATH/$WORLD_NAME-latest.png -resize 600x600 $MAPS_PATH/$WORLD_NAME-latest-thumbnail.png
echo "Cartography is done."
cd $MAPS_PATH
echo "Removing old files..."
find ./$WORLD_NAME-map-*.png -type f -mtime +$CARTO_DAYS_TO_KEEP -print >> purgelist
echo `cat purgelist`
rm -f `cat purgelist`
rm -f purgelist
echo "Old files removed."
cd $MC_PATH
else
echo "The world \"$WORLD_NAME\" does not exist.";
fi
else
echo "The path to cartographier seems to be wrong."
fi
done
echo "Issuing save-on command..."
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "save-on\r"`"; sleep 1
screen -S $SCREEN_NAME -p 0 -X stuff "`printf "say Map cartography is done.\r"`"
;;
#################################################################
*)
echo $USAGE;
esac
else
echo $USAGE;
fi
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment