SHARE
TWEET

Untitled

a guest Jan 16th, 2011 265 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #! /bin/sh
  2. ### BEGIN INIT INFO
  3. # Provides:          minecraft_server
  4. # Required-Start:    $remote_fs $syslog
  5. # Required-Stop:     $remote_fs $syslog
  6. # Default-Start:     2 3 4 5
  7. # Default-Stop:      0 1 6
  8. # Short-Description: Minecraft Server control script.
  9. # Description:       Minecraft Server control script.
  10. #   Options
  11. #     start <world>          - Start the Minecraft world server.  Starts all world servers by default.
  12. #     stop <world>           - Stop the Minecraft world server.  Stops all world servers by default.
  13. #     force-stop <world>     - Forcibly stop the Minecraft world server.  Forcibly stops all world servers by default.
  14. #     restart <world>        - Restart the Minecraft world server.  Restarts all world servers by default.
  15. #     force-restart <world>  - Forcibly restart the Minecraft world server.  Forcibly restarts all world servers by default.
  16. #     status <world>         - Display the status of the Minecraft world server.  Displays the status of all world servers by default.
  17. #     send <world> <command> - Send a command to a Minecraft world server.
  18. #     backup <world>         - Backup the Minecraft world.  Backup all worlds by default.
  19. #     c10t <world>           - Run the c10t mapping software on the Minecraft world.  Maps all worlds by default.
  20. #     update <software>      - Update a software package.  Update the server software and all addons by default.
  21. #                                Available software options
  22. #                                  server - Minecraft server software.
  23. #                                  c10t - Mapping software.
  24. ### END INIT INFO
  25.  
  26.  
  27. USER_NAME=minecraft
  28.  
  29. LOCATION="/home/$USER_NAME"
  30.  
  31.  
  32. ## Minecraft software options.
  33.  
  34. # Software packages, used for updating.
  35. PACKAGES="server c10t"
  36.  
  37. # Minecraft server.
  38. SERVER_URL="http://www.minecraft.net/download/minecraft_server.jar"
  39. SERVER_LOCATION="$LOCATION/minecraft_server"
  40. SERVER_JAR="$SERVER_LOCATION/minecraft_server.jar"
  41. SERVER_ARGS="nogui"
  42. INITIAL_MEMORY="1024M"
  43. MAXIMUM_MEMORY="1024M"
  44.  
  45. # c10t mapping software.
  46. ARCH=$(uname -m)
  47. C10T_URL="http://toolchain.eu/hudson/job/c10t%20HEAD%20Linux%20$ARCH/lastStableBuild/artifact/build/c10t-HEAD-linux-$ARCH.tar.gz"
  48. C10T_LOCATION="$LOCATION/c10t"
  49. C10T_BIN="$C10T_LOCATION/c10t"
  50.  
  51. # Location to place map images, and the URL displayed to users for map access.
  52. MAPS_URL="http://minecraft.server.com/maps"
  53. MAPS_LOCATION="$LOCATION/maps"
  54.  
  55.  
  56. ## World configuration.
  57.  
  58. WORLDS_LOCATION="$LOCATION/worlds"
  59.  
  60. # List of worlds and the ports they are running on.  This file will
  61. # be generated if missing.
  62. # Note: World name should not contain a space, at least for now.
  63. # ie:
  64. #   alpha       25565
  65. #   beta        25566
  66. WORLDS_CONF="$LOCATION/worlds.conf"
  67.  
  68. # Default world name and port if worlds.conf is missing.
  69. DEFAULT_WORLD="world"
  70. DEFAULT_PORT="25565"
  71.  
  72.  
  73. ## Backup configuration.
  74.  
  75. BACKUP_LOCATION="$LOCATION/backups"
  76.  
  77. # Length in days that backups survive.
  78. BACKUP_FULL_DURATION=31
  79.  
  80.  
  81. ## Internal Methods.
  82.  
  83. getProcessIDs() {
  84.         # Get the PIDs of the Screen and Java process for the world server.
  85.         # ARGS: world
  86.         local SCREEN_PID JAVA_PID
  87.         SCREEN_PID=$(su -c "$SCREEN -ls" $USER_NAME | $PERL -ne 'if ($_ =~ /^\t(\d+)\.minecraft-'$1'/) { print $1; }')
  88.         JAVA_PID=$(ps -a -u $USER_NAME -o pid,ppid,comm | $PERL -ne 'if ($_ =~ /^\s*(\d+)\s+'$SCREEN_PID'\s+java/) { print $1; }')
  89.         echo "$SCREEN_PID $JAVA_PID"
  90. }
  91.  
  92. serverRunning() {
  93.         # Check to see if the world server is running.
  94.         # ARGS: world
  95.         local PIDS
  96.         PIDS=$(getProcessIDs $1)
  97.         # Try to determine if the world is running.
  98.         if [ -n "$(echo $PIDS | cut -d ' ' -f1)" ] && [ -n "$(echo $PIDS | cut -d ' ' -f2)" ]; then
  99.                 echo 1
  100.         else
  101.                 echo 0
  102.         fi
  103. }
  104.  
  105. sendCommand() {
  106.         # Send a command to the world server.
  107.         # ARGS: world command
  108.         local COMMAND
  109.         COMMAND=$(printf "$2\r")
  110.         su -c "$SCREEN -S minecraft-$1 -p 0 -X stuff \"$COMMAND\"" $USER_NAME
  111.         if [ ! $? = 0 ]; then
  112.                 printf "Error sending command to server.\n"
  113.                 exit 1
  114.         fi
  115.  
  116. }
  117.  
  118. listContains() {
  119.         # Check whether a list contains something that matches the pattern.
  120.         # ARGS: pattern list
  121.         local MATCH
  122.         MATCH=$(echo \"$2\" | $PERL -ne 'if ($_ =~ /('$1')/) { print "$1"; }')
  123.         if [ -n "$MATCH" ]; then
  124.                 echo 1
  125.         else
  126.                 echo 0
  127.         fi
  128. }
  129.  
  130. start() {
  131.         # Start the world server.
  132.         # ARGS: world
  133.         local SERVER_PORT
  134.         # Make sure that the server directory exists.
  135.         su -c "mkdir -p $WORLDS_LOCATION/$1" $USER_NAME
  136.         cd $WORLDS_LOCATION/$1
  137.         # Make sure that the server properties file exists.
  138.         if [ ! -e server.properties ]; then
  139.                 SERVER_PORT=$(grep $1 $WORLDS_CONF | cut -f2)
  140.                 su -c "printf \"# Minecraft server properties\n\" > server.properties" $USER_NAME
  141.                 su -c "printf \"level-name=world\n\" >> server.properties" $USER_NAME
  142.                 su -c "printf \"server-port=$SERVER_PORT\n\" >> server.properties" $USER_NAME
  143.         fi
  144.         # Start the server.
  145.         su -c "$SCREEN -dmS minecraft-$1 $JAVA -Xms$INITIAL_MEMORY -Xmx$MAXIMUM_MEMORY -jar $SERVER_JAR $SERVER_ARGS" $USER_NAME
  146.         if [ ! $? = 0 ]; then
  147.                 printf "Error starting the server.\n"
  148.                 exit 1
  149.         fi
  150. }
  151.  
  152. forceStop() {
  153.         # Forcibly stop the world server.
  154.         # ARGS: world
  155.         local PIDS
  156.         PIDS=$(getProcessIDs $1)
  157.         # Try to stop the server cleanly first.
  158.         sendCommand $1 "stop"
  159.         sleep 5
  160.         # Kill the process ids of the world server.
  161.         kill -9 $PIDS > /dev/null 2>&1
  162. }
  163.  
  164. fullBackup() {
  165.         # Backup the world server.
  166.         # ARGS: world
  167.         # Grab the date and time.
  168.         local DATE_TIME
  169.         DATE_TIME=$(date +%Y-%m-%d-%H:%M:%S)
  170.         su -c "mkdir -p $BACKUP_LOCATION" $USER_NAME
  171.         cd $WORLDS_LOCATION
  172.         su -c "tar -czf $BACKUP_LOCATION/fullBackup-$1-$DATE_TIME.tar.gz $1" $USER_NAME
  173.         # Cleanup old backups.
  174.         su -c "find $BACKUP_LOCATION -name fullBackup-$1-* -type f -mtime +$BACKUP_FULL_DURATION -delete" $USER_NAME
  175. }
  176.  
  177. update() {
  178.         # Update software package.
  179.         # ARGS: package
  180.         case "$1" in
  181.                 server)
  182.                         su -c "mkdir -p $SERVER_LOCATION" $USER_NAME
  183.                         # Backup the old server jar.
  184.                         if [ -e $SERVER_JAR ]; then
  185.                                 su -c "mv -f $SERVER_JAR $SERVER_JAR.old" $USER_NAME
  186.                         fi
  187.                         # Download the new server software.
  188.                         su -c "$WGET -qO $SERVER_JAR $SERVER_URL" $USER_NAME
  189.                         # Check for error and restore backup if found.
  190.                         if [ ! $? = 0 ]; then
  191.                                 printf "Error updating server software.\n"
  192.                                 if [ -e "$SERVER_JAR.old" ]; then
  193.                                         su -c "mv -f $SERVER_JAR.old $SERVER_JAR" $USER_NAME
  194.                                 fi
  195.                                 exit 1
  196.                         fi
  197.                 ;;
  198.                 c10t)
  199.                         su -c "mkdir -p $C10T_LOCATION" $USER_NAME
  200.                         # Download the new c10t mapping software.
  201.                         cd $C10T_LOCATION
  202.                         su -c "$WGET -qO c10t.tar.gz $C10T_URL" $USER_NAME
  203.                         if [ ! $? = 0 ]; then
  204.                                 printf "Error updating c10t.\n"
  205.                                 exit 1
  206.                         fi
  207.                         su -c "tar xzf c10t.tar.gz" $USER_NAME
  208.                         su -c "cp -R c10t-HEAD/* ." $USER_NAME
  209.                         su -c "rm -R c10t-HEAD" $USER_NAME
  210.                 ;;
  211.                 *)
  212.                         printf "Unknown software package: $1\n"
  213.                         exit 1
  214.                 ;;
  215.         esac
  216. }
  217.  
  218. c10t() {
  219.         # Run c10t mapping software on the server.
  220.         # ARGS: world
  221.         su -c "mkdir -p $MAPS_LOCATION/$1" $USER_NAME
  222.         # Make sure that the world files are actually there before mapping.
  223.         if [ -e "$WORLDS_LOCATION/$1/server.properties" ]; then
  224.                 su -c "$C10T_BIN -s -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/surface.png" $USER_NAME
  225.                 su -c "$C10T_BIN -s -c -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/caves.png" $USER_NAME
  226.                 su -c "$C10T_BIN -s -c -H -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/caves_heightmap.png" $USER_NAME
  227.                 su -c "$C10T_BIN -s -a -i 56 -H -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/diamonds_heightmap.png" $USER_NAME
  228.                 su -c "$C10T_BIN -s -a -i 4 -H -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/cobble_heightmap.png" $USER_NAME
  229.                 su -c "$C10T_BIN -s -q -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/surface_oblique.png" $USER_NAME
  230.                 su -c "$C10T_BIN -s -q -c -w $WORLDS_LOCATION/$1/$1 -o $MAPS_LOCATION/$1/caves_oblique.png" $USER_NAME
  231.         fi
  232. }
  233.  
  234. ## Begin.
  235.  
  236. # Make sure that Java, Perl, GNU Screen, and GNU Wget are installed.
  237. JAVA=$(which java)
  238. PERL=$(which perl)
  239. SCREEN=$(which screen)
  240. WGET=$(which wget)
  241. if [ ! -e $JAVA ]; then
  242.         printf "Java not found!\n"
  243.         printf "Try installing this with:\n"
  244.         printf "sudo apt-get install openjdk-6-jre\n"
  245.         exit 1
  246. fi
  247. if [ ! -e $PERL ]; then
  248.         printf "Perl not found!\n"
  249.         printf "Try installing this with:\n"
  250.         printf "sudo apt-get install perl\n"
  251.         exit 1
  252. fi
  253. if [ ! -e $SCREEN ]; then
  254.         printf "GNU Screen not found!\n"
  255.         printf "Try installing this with:\n"
  256.         printf "sudo apt-get install screen\n"
  257.         exit 1
  258. fi
  259. if [ ! -e $WGET ]; then
  260.         printf "GNU Wget not found!\n"
  261.         printf "Try installing this with:\n"
  262.         printf "sudo apt-get install wget\n"
  263.         exit 1
  264. fi
  265.  
  266. # Make sure that the minecraft user exists, print a sane error if not.
  267. if [ ! -n "$(grep $USER_NAME /etc/passwd)" ]; then
  268.         printf "This script requires that a user account named $USER_NAME exist on this system.\n"
  269.         printf "Try adding this user:\n"
  270.         printf "sudo adduser $USER_NAME\n"
  271.         exit 1
  272. fi
  273.  
  274. # From here on out the script needs to be run as root, print a sane error if running as a user.
  275. WHOAMI=$(whoami)
  276. if [ ! "$WHOAMI" = "root" ]; then
  277.         printf "This script needs to be run as root, you seem to be $WHOAMI.\n"
  278.         printf "Try running this with sudo:\n"
  279.         printf "sudo $0 start\n"
  280.         exit 1
  281. fi
  282.  
  283. # Make sure that the worlds.conf file exists.
  284. if [ ! -e $WORLDS_CONF ]; then
  285.         su -c "printf \"$DEFAULT_WORLD\t$DEFAULT_PORT\n\" > $WORLDS_CONF" $USER_NAME
  286. fi
  287.  
  288. # Grab the list of worlds.
  289. WORLDS=$(cut -f1 $WORLDS_CONF)
  290.  
  291. # Respond to the command line arguments.
  292. case "$1" in
  293.         start)
  294.                 printf "Starting Minecraft Server:"
  295.                 # Make sure that the server software exists.
  296.                 if [ ! -e $SERVER_JAR ]; then
  297.                         printf "Server software not found, downloading it...\n"
  298.                         update "server"
  299.                 fi
  300.                 # Check for the optional world command line argument.
  301.                 if [ -n "$2"  ] && [ $(listContains $2 "$WORLDS") = 1 ]; then
  302.                         WORLDS="$2"
  303.                 elif [ -n "$2" ]; then
  304.                         printf "Minecraft world $2 not found!\n"
  305.                         printf "  Usage:  $0 $1 <world>\n"
  306.                         exit 1
  307.                 fi
  308.                 # Start each world requested, if not already running.
  309.                 for WORLD in $WORLDS; do
  310.                         if [ $(serverRunning $WORLD) = 0 ]; then
  311.                                 printf " $WORLD"
  312.                                 start $WORLD
  313.                         fi
  314.                 done
  315.                 printf "\n"
  316.         ;;
  317.         stop|force-stop)
  318.                 printf "Stopping Minecraft Server:"
  319.                 # Check for the optional world command line argument.
  320.                 if [ -n "$2"  ] && [ $(listContains $2 "$WORLDS") = 1 ]; then
  321.                         WORLDS="$2"
  322.                 elif [ -n "$2" ]; then
  323.                         printf "Minecraft world $2 not found!\n"
  324.                         printf "  Usage:  $0 $1 <world>\n"
  325.                         exit 1
  326.                 fi
  327.                 # Stop each world requested, if running.
  328.                 for WORLD in $WORLDS; do
  329.                         # Try to stop the world cleanly.
  330.                         if [ $(serverRunning $WORLD) = 1 ]; then
  331.                                 printf " $WORLD"
  332.                                 sendCommand $WORLD "say The server is about to go down."
  333.                                 sendCommand $WORLD "save-all"
  334.                                 sendCommand $WORLD "save-off"
  335.                                 sendCommand $WORLD "say The server is going down in 5 seconds..."
  336.                                 sleep 5
  337.                                 if [ "$1" = "force-stop" ]; then
  338.                                         forceStop $WORLD
  339.                                 else
  340.                                         sendCommand $WORLD "stop"
  341.                                 fi
  342.                                 sleep 5
  343.                         fi
  344.                 done
  345.                 printf "\n"
  346.         ;;
  347.         restart|reload|force-restart|force-reload)
  348.                 printf "Restarting Minecraft Server:"
  349.                 # Check for the optional world command line argument.
  350.                 if [ -n "$2"  ] && [ $(listContains $2 "$WORLDS") = 1 ]; then
  351.                         WORLDS="$2"
  352.                 elif [ -n "$2" ]; then
  353.                         printf "Minecraft world $2 not found!\n"
  354.                         printf "  Usage:  $0 $1 <world>\n"
  355.                         exit 1
  356.                 fi
  357.                 # Restart each world requested, start those not already running.
  358.                 for WORLD in $WORLDS; do
  359.                         printf " $WORLD"
  360.                         if [ $(serverRunning $WORLD) = 1 ]; then
  361.                                 sendCommand $WORLD "say The server is about to restart."
  362.                                 sendCommand $WORLD "save-all"
  363.                                 sendCommand $WORLD "save-off"
  364.                                 sendCommand $WORLD "say Restarting in 5 seconds..."
  365.                                 sleep 5
  366.                                 if [ "$(echo $1 | cut -d '-' -f1)" = "force" ]; then
  367.                                         forceStop $WORLD
  368.                                 else
  369.                                         sendCommand $WORLD "stop"
  370.                                 fi
  371.                                 sleep 5
  372.                         fi;
  373.                         start $WORLD
  374.                 done
  375.                 printf "\n"
  376.         ;;
  377.         status|show)
  378.                 printf "Minecraft Server Status:\n"
  379.                 # Check for the optional world command line argument.
  380.                 if [ -n "$2"  ] && [ $(listContains $2 "$WORLDS") = 1 ]; then
  381.                         WORLDS="$2"
  382.                 elif [ -n "$2" ]; then
  383.                         printf "Minecraft world $2 not found!\n"
  384.                         printf "  Usage:  $0 $1 <world>\n"
  385.                         exit 1
  386.                 fi
  387.                 # Show the status of each world requested.
  388.                 for WORLD in $WORLDS; do
  389.                         printf "  $WORLD: "
  390.                         if [ $(serverRunning $WORLD) = 1 ]; then
  391.                                 printf "running.\n"
  392.                         else
  393.                                 printf "not running.\n"
  394.                         fi
  395.                 done
  396.         ;;
  397.         send)
  398.                 WORLD=$2
  399.                 if [ -n "$WORLD" ] && [ $(listContains $WORLD "$WORLDS") = 1 ]; then
  400.                         shift 2
  401.                         printf "Send command to world $WORLD: $*\n"
  402.                         sendCommand $WORLD "$*"
  403.                 else
  404.                         printf "Minecraft world $WORLD not found!\n"
  405.                         printf "  Usage:  $0 $1 <world> <command>\n"
  406.                         printf "     ie:  $0 $1 world say \"Hello World!\"\n"
  407.                         exit 1
  408.                 fi
  409.         ;;
  410.         backup)
  411.                 printf "Backing up Minecraft Server:"
  412.                 # Check for the optional world command line argument.
  413.                 if [ -n "$2"  ] && [ $(listContains $2 "$WORLDS") = 1 ]; then
  414.                         WORLDS="$2"
  415.                 elif [ -n "$2" ]; then
  416.                         printf "Minecraft world $2 not found!\n"
  417.                         printf "  Usage:  $0 $1 <world>\n"
  418.                         exit 1
  419.                 fi
  420.                 # Backup each world requested.
  421.                 for WORLD in $WORLDS; do
  422.                         printf " $WORLD"
  423.                         if [ $(serverRunning $WORLD) = 1 ]; then
  424.                                 sendCommand $WORLD "say Backing up the world."
  425.                                 sendCommand $WORLD "save-all"
  426.                                 sendCommand $WORLD "save-off"
  427.                                 sleep 20
  428.                                 fullBackup $WORLD
  429.                                 sendCommand $WORLD "save-on"
  430.                                 sendCommand $WORLD "say Backup complete."
  431.                         else
  432.                                 fullBackup $WORLD
  433.                         fi
  434.                 done
  435.                 printf "\n"
  436.         ;;
  437.         update)
  438.                 printf "Updating the Minecraft Server software...\n"
  439.                 # Check for the optional package command line argument.
  440.                 if [ -n "$2"  ] && [ $(listContains $2 "$PACKAGES") = 1 ]; then
  441.                         PACKAGES="$2"
  442.                 elif [ -n "$2" ]; then
  443.                         printf "Minecraft software package $2 not found!\n"
  444.                         printf "  Usage:  $0 $1 <software package>\n"
  445.                         exit 1
  446.                 fi
  447.                 if [ -n "$(echo $PACKAGES | grep server)" ]; then
  448.                         printf "Stopping Minecraft Server:"
  449.                         for WORLD in $WORLDS; do
  450.                                 printf " $WORLD"
  451.                                 if [ $(serverRunning $WORLD) = 1 ]; then
  452.                                         sendCommand $WORLD "say The server software is being updated."
  453.                                         sendCommand $WORLD "say Server restart is imminent."
  454.                                         sendCommand $WORLD "save-all"
  455.                                         sendCommand $WORLD "save-off"
  456.                                         sleep 20
  457.                                         fullBackup $WORLD
  458.                                         sendCommand $WORLD "say Restarting in 5 seconds."
  459.                                         sleep 5
  460.                                         sendCommand $WORLD "stop"
  461.                                 else
  462.                                         fullBackup $WORLD
  463.                                 fi
  464.                         done
  465.                         printf "\n"
  466.                 fi
  467.                 # Update each software package requested.
  468.                 printf "Updating software package:"
  469.                 for PACKAGE in $PACKAGES; do
  470.                         printf " $PACKAGE"
  471.                         update $PACKAGE
  472.                 done
  473.                 printf "\n"
  474.                 if [ -n "$(echo $PACKAGES | grep server)" ]; then
  475.                         printf "Starting Minecraft Server:"
  476.                         for WORLD in $WORLDS; do
  477.                                 printf " $WORLD"
  478.                                 start $WORLD
  479.                         done
  480.                         printf "\n"
  481.                 fi
  482.         ;;
  483.         c10t|map)
  484.                 # Make sure that the c10t software exists.
  485.                 if [ ! -e $C10T_BIN ]; then
  486.                         printf "c10t software not found, downloading it...\n"
  487.                         update "c10t"
  488.                 fi
  489.                 # Check for the optional world command line argument.
  490.                 if [ -n "$2"  ] && [ $(listContains $2 "$WORLDS") = 1 ]; then
  491.                         WORLDS="$2"
  492.                 elif [ -n "$2" ]; then
  493.                         printf "Minecraft world $2 not found!\n"
  494.                         printf "  Usage:  $0 $1 <world>\n"
  495.                         exit 1
  496.                 fi
  497.                 # Run c10t on each world requested.
  498.                 printf "Running c10t mapping:"
  499.                 for WORLD in $WORLDS; do
  500.                         printf " $WORLD"
  501.                         if [ $(serverRunning $WORLD) = 1 ]; then
  502.                                 sendCommand $WORLD "say The world is about to be mapped with c10t."
  503.                                 sendCommand $WORLD "save-all"
  504.                                 sendCommand $WORLD "save-off"
  505.                                 sleep 20
  506.                                 fullBackup $WORLD
  507.                                 c10t $WORLD
  508.                                 sendCommand $WORLD "save-on"
  509.                                 sendCommand $WORLD "say Mapping is complete.  You can access the maps at:"
  510.                                 sendCommand $WORLD "say $MAPS_URL/$WORLD"
  511.                         else
  512.                                 fullBackup $WORLD
  513.                                 c10t $WORLD
  514.                         fi
  515.                 done
  516.                 printf "\n"
  517.         ;;
  518.         *)
  519.                 printf "Usage: $0 {start|stop|force-stop|restart|force-restart|status|send|backup|update|c10t} {Optional: world or software package}\n"
  520.                 exit 1
  521.         ;;
  522. esac
  523. exit 0
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top