SHARE
TWEET

minecraft_server with additional server types

a guest Nov 24th, 2012 138 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:  3 4 5
  7. # Default-Stop:   0 1 2 6
  8. # chkconfig:      345 50 50
  9. # Description:    Minecraft Server control script.
  10. ### END INIT INFO
  11.  
  12. # Minecraft Server control script.
  13. #
  14. # Options:
  15. #   start <world>         - Start the Minecraft world server.  Start all world
  16. #                           servers by default.
  17. #   stop <world>          - Stop the Minecraft world server.  Stop all world
  18. #                           servers by default.
  19. #   force-stop <world>    - Forcibly stop the Minecraft world server.  Forcibly
  20. #                           stop all world servers by default.
  21. #   restart <world>       - Restart the Minecraft world server.  Restart all
  22. #                           world servers by default.
  23. #   force-restart <world> - Forcibly restart the Minecraft world server.
  24. #                           Forcibly restart all world servers by default.
  25. #   status <world>        - Display the status of the Minecraft world server.
  26. #                           Display the status of all world servers by default.
  27. #   sync <world>          - Synchronize the data stored in the mirror images of
  28. #                           the Minecraft world server.  Synchronizes all of
  29. #                           the world servers by default.  This option is only
  30. #                           available when the mirror image option is enabled.
  31. #   send <world> <cmd>    - Send a command to a Minecraft world server.
  32. #   screen <world>        - Display the Screen for the Minecraft world server.
  33. #   watch <world>         - Watch the log file for the Minecraft world server.
  34. #   backup <world>        - Backup the Minecraft world.  Backup all worlds by
  35. #                           default.
  36. #   c10t <world>          - Run the c10t mapping software on the Minecraft
  37. #                           world.  Map all worlds by default.
  38. #   pigmap <world>        - Run the pigmap mapping software on the Mincraft
  39. #                           world.  Map all worlds by default.
  40. #   update <software>     - Update a software package.  Update the server
  41. #                           software and all add-ons by default.
  42. #
  43. #   Available software packages for update option:
  44. #     server        - Minecraft server software.
  45. #     c10t          - c10t mapping software.
  46. #     pigmap        - Pigmap mapping software.
  47.  
  48.  
  49. # User name used to run all commands.
  50. USER_NAME="minecraft"
  51.  
  52. # The location of server software and data.
  53. LOCATION="/home/$USER_NAME"
  54.  
  55.  
  56. ## Required software.
  57.  
  58. JAVA=$(which java)
  59. JAR=$(which jar)
  60. PERL=$(which perl)
  61. RSYNC=$(which rsync)
  62. SCREEN=$(which screen)
  63. WGET=$(which wget)
  64. RDIFF_BACKUP=$(which rdiff-backup)
  65.  
  66.  
  67. ## Generic options.
  68.  
  69. # Automatically restart the Minecraft server when a SEVERE error is caught.
  70. #   0 - Do not auto restart.
  71. #   1 - Auto restart.
  72. AUTO_RESTART_ON_ERROR=0
  73.  
  74. # Software packages updated with the update command.
  75. #   server        - Minecraft server software.
  76. #   c10t          - c10t mapping software.
  77. #   pigmap        - Pigmap mapping software.
  78. UPDATE_PACKAGES="server c10t pigmap"
  79.  
  80.  
  81. ## Minecraft server options.
  82. SERVER_TYPES="mojang bukkit tekkit"
  83.  
  84. ## Some extra Java Options
  85. #JAVA_OPTS="-Xmx1536M -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=2 -XX:+AggressiveOpts"
  86.  
  87. # Default Mojang server distribution.
  88. SERVER_MOJANG_URL="https://s3.amazonaws.com/MinecraftDownload/launcher/Minecraft_Server.exe"
  89. SERVER_MOJANG_JAR="minecraft_server.jar"
  90. SERVER_MOJANG_ARGS="nogui"
  91. SERVER_MOJANG_JAVA_OPTS="-Xms512M -Xmx1G"
  92.  
  93. # CraftBukkit server distribution.
  94. SERVER_BUKKIT_URL="http://cbukk.it/craftbukkit.jar"
  95. SERVER_BUKKIT_JAR="craftbukkit.jar"
  96. SERVER_BUKKIT_JAVA_OPTS="-Xms512M -Xmx1G"
  97. SERVER_BUKKIT_ARGS=""
  98.  
  99. # Tekkit server distribution.
  100. SERVER_TEKKIT_URL="http://mirror.technicpack.net/Technic/servers/tekkit/Tekkit_Server_3.1.3.zip"
  101. SERVER_TEKKIT_JAR="Tekkit.jar"
  102. SERVER_TEKKIT_JAVA_OPTS="-Xms512M -Xmx1G"
  103. SERVER_TEKKIT_ARGS="nogui"
  104.  
  105. # Feed the Beast server distribution.
  106. SERVER_FTB_URL="http://repo.creeperhost.net/direct/FTB2/71a030a9197ede2920757ecdc59cd6c1/FTBBetaA_Server.zip"
  107. SERVER_FTB_JAR="FTB-Beta-A.jar"
  108. SERVER_FTB_JAVA_OPTS="-Xms512M -Xmx1G"
  109. SERVER_FTB_ARGS="nogui"
  110.  
  111. # Generic server options.
  112. SERVER_LOCATION="$LOCATION/minecraft_server"
  113.  
  114.  
  115. ## World configuration.
  116.  
  117. # The location to store files for each world server.
  118. WORLDS_LOCATION="$LOCATION/worlds"
  119.  
  120. # List of worlds and the ports they are running on.  This file will
  121. # be generated if missing.
  122. #
  123. # Note: The world name should not contain a space.  Leave the ip
  124. # address blank if not needed.
  125. #
  126. # # Minecraft world configuration file
  127. # # <world>     <server>        <port>  <ip>
  128. #   alpha       mojang  25565
  129. #   beta        mojang  25566
  130. #   gamma       bukkit  25567
  131. #   delta       tekkit  25568
  132. #   epsilon     ftb     25569
  133. WORLDS_CONF="$LOCATION/worlds.conf"
  134.  
  135. # Default world name, server type, port, and IP address if the worlds.conf file is missing.
  136. # Supported server types are ( mojang bukkit tekkit )
  137. DEFAULT_WORLD="world"
  138. DEFAULT_SERVER="mojang"
  139. DEFAULT_PORT="25565"
  140. DEFAULT_IP=""
  141.  
  142.  
  143. ## Global Message Of The Day file (MOTD).
  144.  
  145. # Location of the file to display to users on login and when the /motd command
  146. # is used on any world.  Nothing will be done if this file does not exist.
  147. MOTD="$LOCATION/motd.txt"
  148.  
  149.  
  150. ## Help file.
  151.  
  152. # Location of the file to display to users when the /help command is used. A
  153. # basic file will be generated on the first run if it does not exist.
  154. HELP="$LOCATION/help.txt"
  155.  
  156.  
  157. ## MOTD and help files can contain color codes as follows:
  158. #  §0 - black
  159. #  §1 - blue
  160. #  §2 - dark green
  161. #  §3 - aqua
  162. #  §4 - dark red
  163. #  §5 - purple
  164. #  §6 - gold
  165. #  §7 - gray
  166. #  §8 - dark gray
  167. #  §9 - light blue
  168. #  §a - green
  169. #  §b - teal
  170. #  §c - red
  171. #  §d - magenta
  172. #  §e - yellow
  173. #  §f - white
  174.  
  175.  
  176. ## Backup configuration.
  177.  
  178. # Location to store backups.
  179. BACKUP_LOCATION="$LOCATION/backups"
  180.  
  181. # Location of the backup log file.
  182. BACKUP_LOG="$BACKUP_LOCATION/backup.log"
  183.  
  184. # Length in days that backups survive.
  185. BACKUP_DURATION=31
  186.  
  187.  
  188. ## Mirror image options.
  189.  
  190. # Create a mirror image of the world data on system startup, and
  191. # update that mirror image on system shutdown.
  192. #
  193. # IMPORTANT: If using this option, the admin should schedule
  194. # periodic synchronizations of the mirror image using cron
  195. # to avoid data loss.
  196. #
  197. # 0 - Do not use a mirror image, default.
  198. # 1 - Use a mirror image.
  199. ENABLE_MIRROR=0
  200.  
  201. # The location to store the mirror image.
  202. #
  203. # NOTE: This is usually a ramdisk.
  204. MIRROR_PATH="/dev/shm/minecraft"
  205.  
  206.  
  207. ## c10t mapping software options.
  208. C10T_URL="http://toolchain.eu/minecraft/c10t/releases"
  209. C10T_LOCATION="$LOCATION/c10t"
  210. C10T_BIN="$C10T_LOCATION/c10t"
  211. C10T_MAPS_URL="http://minecraft.server.com/maps/c10t"
  212. C10T_MAPS_LOCATION="$LOCATION/maps/c10t"
  213.  
  214.  
  215. ## Pigmap mapping software options.
  216. MINECRAFT_CLIENT_URL="https://s3.amazonaws.com/MinecraftDownload/minecraft.jar"
  217. PIGMAP_URL="https://github.com/equalpants/pigmap/tarball/master"
  218. PIGMAP_LOCATION="$LOCATION/pigmap"
  219. PIGMAP_BIN="$PIGMAP_LOCATION/pigmap"
  220. PIGMAP_MAPS_URL="http://minecraft.server.com/maps/pigmap"
  221. PIGMAP_MAPS_LOCATION="$LOCATION/maps/pigmap"
  222.  
  223.  
  224. ## Lib-notify configuration.
  225.  
  226. # Use lib-notify to print a message on your desktop of important server events.
  227. # 0 - Do not use lib-notify.
  228. # 1 - Display server events using lib-notify.
  229. USE_LIBNOTIFY=0
  230.  
  231. # The username and display that messages will be routed to.
  232. LIBNOTIFY_USER_NAME=$USER_NAME
  233. LIBNOTIFY_DISPLAY=":0.0"
  234.  
  235.  
  236. ## Internal Methods.
  237.  
  238. # Execute the given command.
  239. #
  240. # @param 1 The command to execute.
  241. # @param 2 The user name to execute the command with.
  242. execute() {
  243.         if [ $(id -u) -eq 0 ]; then
  244.                 # Script is running as root, switch user and execute
  245.                 # the command.
  246.                 su -c "$1" $2
  247.         else
  248.                 # Script is running as a user, just execute the command.
  249.                 sh -c "$1"
  250.         fi
  251. }
  252.  
  253. # Get the PIDs of the Screen and Java process for the world server.
  254. #
  255. # @param 1 The world server of interest.
  256. # @return The Screen and Java PIDs
  257. getProcessIDs() {
  258.         local SCREEN_PID JAVA_PID
  259.         SCREEN_PID=$(execute "$SCREEN -ls" $USER_NAME | $PERL -ne 'if ($_ =~ /^\t(\d+)\.minecraft-'$1'\s+/) { print $1; }')
  260.         JAVA_PID=$(ps -a -u $USER_NAME -o pid,ppid,comm | $PERL -ne 'if ($_ =~ /^\s*(\d+)\s+'$SCREEN_PID'\s+java/) { print $1; }')
  261.         echo "$SCREEN_PID $JAVA_PID"
  262. }
  263.  
  264. # Check to see if the world server is running.
  265. #
  266. # @param 1 The world server of interest.
  267. # @return A 1 if the server is thought to be running, a 0 otherwise.
  268. serverRunning() {
  269.         local PIDS
  270.         PIDS=$(getProcessIDs $1)
  271.         # Try to determine if the world is running.
  272.         if [ -n "$(echo $PIDS | cut -d ' ' -f1)" ] && [ -n "$(echo $PIDS | cut -d ' ' -f2)" ]; then
  273.                 echo 1
  274.         else
  275.                 echo 0
  276.         fi
  277. }
  278.  
  279. # Send a command to the world server.
  280. #
  281. # @param 1 The world server of interest.
  282. # @param 2 The command to send.
  283. sendCommand() {
  284.         local COMMAND PID
  285.         COMMAND=$(printf "$2\r")
  286.         PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f1)
  287.         execute "$SCREEN -S $PID.minecraft-$1 -p 0 -X stuff \"$COMMAND\"" $USER_NAME
  288.         if [ $? -ne 0 ]; then
  289.                 printf "Error sending command to server $1.\n"
  290.                 exit 1
  291.         fi
  292. }
  293.  
  294. # Connect to the Screen of a world server.
  295. #
  296. # @param 1 The world server of interest.
  297. displayScreen() {
  298.         local PID
  299.         PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f1)
  300.         printf "About to load the screen for world $1.\n"
  301.         printf "To exit the screen, hit Ctrl+A then type the letter d.\n"
  302.         sleep 5
  303.         execute "$SCREEN -x $PID.minecraft-$1" $USER_NAME
  304.         if [ $? -ne 0 ]; then
  305.                 printf "Error connecting to Screen.\n"
  306.                 exit 1
  307.         fi
  308. }
  309.  
  310. # Check whether the item is in the list.
  311. #
  312. # @param 1 The item being searched for.
  313. # @param 2 The list being searched.
  314. # @return A 1 if the list contains the item, a 0 otherwise.
  315. listContains() {
  316.         local MATCH ITEM
  317.         MATCH=0
  318.         for ITEM in $2; do
  319.                 if [ "$ITEM" = "$1" ]; then
  320.                         MATCH=1
  321.                 fi
  322.         done
  323.         echo $MATCH
  324. }
  325.  
  326. # Grab the port for the given world.
  327. #
  328. # @param 1 The world server of interest.
  329. # @return The port that the world is configured to use.
  330. getPort() {
  331.         local PORT
  332.         PORT=$(execute "cat $WORLDS_CONF" $USER_NAME | $PERL -ne 'if ($_ =~ /^'$1'\s+[\w\d]+\s+(\d+)/) { print "$1"; }')
  333.         echo $PORT
  334. }
  335.  
  336. # Grab the IP address for the given world.
  337. #
  338. # @param 1 The world server of interest.
  339. # @return The IP address that the world is configured to run on.
  340. getIP() {
  341.         local IP
  342.         IP=$(execute "cat $WORLDS_CONF" $USER_NAME | $PERL -ne 'if ($_ =~ /^'$1'\s+[\w\d]+\s+\d+\s+([\d\.]+)/) { print "$1"; }')
  343.         echo $IP
  344. }
  345.  
  346. # Grab the server type for the given world.
  347. #
  348. # @param 1 The world server of interest.
  349. # @return The server type that the world is configured to run on.
  350. getServerType() {
  351.         local SERVER
  352.         SERVER=$(execute "cat $WORLDS_CONF" $USER_NAME | $PERL -ne 'if ($_ =~ /^'$1'\s+([\w\d]+)/) { print "$1"; }')
  353.         echo $SERVER
  354. }
  355.  
  356. # Grab the first line of the Message of the Day file as a summary, and strip
  357. # any color codes from it.
  358. getMOTD() {
  359.         local MOTD_SUMMARY
  360.         MOTD_SUMMARY=""
  361.         if [ -e $MOTD ]; then
  362.                 MOTD_SUMMARY=$(head -n 1 $MOTD | $PERL -ne '$_ =~ s/§[0-9a-fA-F]//g; print;')
  363.         fi
  364.         echo $MOTD_SUMMARY
  365. }
  366.  
  367. # Grab the list of worlds.
  368. #
  369. # @return The list of worlds.
  370. getWorlds() {
  371.         local WORLDS
  372.         WORLDS=$(execute "cat $WORLDS_CONF" $USER_NAME | $PERL -ne 'if ($_ =~ /^([\w\d]+)\s+[\w\d]+\s+\d+/) { print "$1 "; }')
  373.         echo $WORLDS
  374. }
  375.  
  376. # Modify the value of a key/value combo in a properties file.
  377. #
  378. # @param 1 The properties file of interest.
  379. # @param 2 The key to modify.
  380. # @param 3 The value to assign to the key.
  381. setPropertiesValue() {
  382.         local KEY_VALUE
  383.         # Make sure that the properties file exists.
  384.         execute "touch $1" $USER_NAME
  385.         # Replace the key/value combo if it already exists, otherwise just
  386.         # append it to the end of the file.
  387.         KEY_VALUE=$($PERL -ne 'if ($_ =~ /^('$2'=.*)$/) { print "$1"; }' $1)
  388.         if [ -n "$KEY_VALUE" ]; then
  389.                 execute "$PERL -i -ne 'if (\$_ =~ /^$2=.*$/) { print \"$2=$3\\n\"; } else { print; }' $1" $USER_NAME
  390.         else
  391.                 execute "printf \"$2=$3\\n\" >> $1" $USER_NAME
  392.         fi
  393. }
  394.  
  395. # Send a message to the desktop using lib-notify, if it is available.
  396. #
  397. # @param 1 The summary of the message to send.
  398. # @param 2 The body of the message to send.
  399. libNotify() {
  400.         local NOTIFY
  401.         NOTIFY=$(which notify-send)
  402.         if [ -e $NOTIFY ]; then
  403.                 execute "DISPLAY=$LIBNOTIFY_DISPLAY $NOTIFY \"$1\" \"$2\"" $LIBNOTIFY_USER_NAME > /dev/null 2>&1
  404.         fi
  405. }
  406.  
  407. # Send the contents of the Message Of The Day (MOTD) to the user.
  408. #
  409. # @param 1 The world server of interest.
  410. # @param 2 The user being told the contents of the motd file.
  411. tellMOTD() {
  412.         local LINE
  413.         if [ -e $MOTD ]; then
  414.                 while read LINE; do
  415.                         sendCommand $1 "tell $2 $LINE"
  416.                 done < $MOTD
  417.         fi
  418. }
  419.  
  420. # Check to see if the user is in the ops.txt file of the specified world.
  421. #
  422. # @param 1 The world server of interest.
  423. # @param 2 The user being checked.
  424. checkUserIsAdmin() {
  425.         local IS_ADMIN
  426.         IS_ADMIN=$(cat $WORLDS_LOCATION/$1/ops.txt | $PERL -ne 'if ($_ =~ /^'$2'$/i) { print "1"; }')
  427.         echo $IS_ADMIN
  428. }
  429.  
  430. # Check for the optional argument.  If the argument is not supplied, return
  431. # the original list.  If the argument is supplied, verify that it is a member
  432. # of the list, then modify the list to just contain that member.
  433. #
  434. # @param 1 The original list.
  435. # @param 2 The name of the script.
  436. # @param 3 The command line argument used.
  437. # @param 4 The optional command line argument.
  438. # @return Either the original list, or the optional command line argument.
  439. checkOptionalArgument() {
  440.         local LIST
  441.         LIST="$1"
  442.         # Check for the optional command line argument.
  443.         if [ -n "$4"  ] && [ $(listContains $4 "$1") -eq 1 ]; then
  444.                 LIST="$4"
  445.         elif [ -n "$4" ]; then
  446.                         printf "Optional argument '$4' not recognized.\n"
  447.                         printf "  Usage:  $2 $3 <optional argument>\n"
  448.                 exit 1
  449.         fi
  450.         echo "$LIST"
  451. }
  452.  
  453. # Check for users logging into a world.  If a user logs in, perform
  454. # login functions.
  455. #
  456. # @param 1 The world server of interest.
  457. # @param 2 The message to check for users logging in.
  458. checkForLogin() {
  459.         local LOGIN PLAYER_NAME
  460.         LOGIN=$(echo "$2" | $PERL -ne 'if ($_ =~ /(\w+)\s*\[\/([0-9\.]+)\:(\d+)\] logged in with entity id (\d+)/) { print "$1\t$2\t$3\t$4"; }')
  461.         if [ -n "$LOGIN" ]; then
  462.                 PLAYER_NAME=$(printf "$LOGIN" | cut -f1)
  463.                 # Add the user to the world.users file.
  464.                 execute "printf \"$LOGIN\n\" >> \"$WORLDS_LOCATION/$1.users\"" $USER_NAME
  465.                 # Announce the user logging in via lib-notify.
  466.                 if [ $USE_LIBNOTIFY ]; then
  467.                         libNotify "Minecraft - $1" "$PLAYER_NAME has logged into world."
  468.                 fi
  469.                 # Whisper the MOTD to the user logging in.
  470.                 tellMOTD $1 $PLAYER_NAME
  471.         fi
  472. }
  473.  
  474. # Check for users logging out of a world.  If a user logs out, perform the
  475. # logout functions.
  476. #
  477. # @param 1 The world server of interest.
  478. # @param 2 The message to check for users logging out.
  479. checkForLogout() {
  480.         local LOGOUT PLAYER_NAME
  481.         LOGOUT=$(echo "$2" | $PERL -ne 'if ($_ =~ /(\w+) lost connection\: (.+)/) { print "$1\t$2"; }')
  482.         if [ -n "$LOGOUT" ]; then
  483.                 PLAYER_NAME=$(printf "$LOGOUT" | cut -f1)
  484.                 # Remove the user from the world.users file.
  485.                 execute "$PERL -i -ne 'print unless /^$PLAYER_NAME\t[0-9\.]+\t\d+\d+/;' $WORLDS_LOCATION/$1.users" $USER_NAME
  486.                 # Announce the user logging out via lib-notify.
  487.                 if [ $USE_LIBNOTIFY ]; then
  488.                         libNotify "Minecraft - $1" "$PLAYER_NAME has logged out of world."
  489.                 fi
  490.         fi
  491. }
  492.  
  493. # Parse through the log file for the given world.  Uses checkFor methods to
  494. # find events such as users logging in or out.
  495. #
  496. # @param 1 The world server generating the log to parse.
  497. parseLog() {
  498.         local LINE DATE TIME TYPE MESSAGE
  499.         while read LINE; do
  500.                 LINE=$(echo "$LINE" | $PERL -ne 'if ($_ =~ /(.+) (.+) \[(\w+)\] (.+)/) { print "$1\t$2\t$3\t$4"; }')
  501.                 DATE=$(echo "$LINE" | cut -f1)
  502.                 TIME=$(echo "$LINE" | cut -f2)
  503.                 TYPE=$(echo "$LINE" | cut -f3)
  504.                 MESSAGE=$(echo "$LINE" | cut -f4)
  505.                 case "$TYPE" in
  506.                         INFO)
  507.                                 checkForLogin $1 "$MESSAGE"
  508.                                 checkForLogout $1 "$MESSAGE"
  509.                         ;;
  510.                         SEVERE)
  511.                                 if [ $AUTO_RESTART_ON_ERROR -eq 1 ]; then
  512.                                         sendCommand $1 "say The server is experiencing issues, restarting in 5 seconds..."
  513.                                         sleep 5
  514.                                         stop $1
  515.                                         sleep 5
  516.                                         start $1
  517.                                 fi
  518.                         ;;
  519.                         WARNING)
  520.                         ;;
  521.                         *)
  522.                         ;;
  523.                 esac
  524.         done
  525. }
  526.  
  527. # Watch the world server log file.
  528. #
  529. # @param 1 The world server generating the log to watch.
  530. watchLog() {
  531.         local PID WORLD_DIR
  532.         WORLD_DIR="$WORLDS_LOCATION/$1"
  533.         # Use the mirror copy of the world directory if enabled.
  534.         if [ $ENABLE_MIRROR -eq 1 ] && [ -d $MIRROR_PATH ]; then
  535.                 WORLD_DIR="$MIRROR_PATH/$1"
  536.         fi
  537.         # Make sure that the server.log file exists.
  538.         if [ -e "$WORLD_DIR/server.log" ]; then
  539.                 # Watch the log.
  540.                 PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f2)
  541.                 tail -n0 -f --pid=$PID $WORLD_DIR/server.log
  542.         fi
  543. }
  544.  
  545. # Synchronizes the data stored in the mirror images.
  546. #
  547. # @param 1 The world server to sync.
  548. syncMirrorImage() {
  549.         # Sync the world server.
  550.         execute "$RSYNC -rt $MIRROR_PATH/$1/* $WORLDS_LOCATION/$1" $USER_NAME
  551.         if [ $? -ne 0 ]; then
  552.                 printf "Error synchronizing mirror images for world $1.\n"
  553.                 exit 1
  554.         fi
  555. }
  556.  
  557. # Start the world server and the log processor.  Generate the appropriate
  558. # environment for the server if it doesn't already exist.
  559. #
  560. # @param 1 The world server to start.
  561. start() {
  562.         local PID WORLD_DIR SERVER_TYPE SERVER_JAR SERVER_ARGS JAVA_OPTS
  563.  
  564.         # Make sure that the world's directory exists.
  565.         WORLD_DIR="$WORLDS_LOCATION/$1"
  566.         if [ ! -d "$WORLDS_LOCATION/$1" ]; then
  567.                 execute "mkdir -p $WORLD_DIR" $USER_NAME
  568.         fi
  569.  
  570.         # Get the world server type
  571.         SERVER_TYPE=$(getServerType "$1")
  572.  
  573.         # Set the server location, and args
  574.         if [ $SERVER_TYPE = "mojang" ]; then
  575.                 SERVER_JAR=$SERVER_MOJANG_JAR
  576.                 SERVER_ARGS=$SERVER_MOJANG_ARGS
  577.                 JAVA_OPTS=$SERVER_MOJANG_JAVA_OPTS
  578.         elif [ $SERVER_TYPE = "bukkit" ]; then
  579.                 SERVER_JAR=$SERVER_BUKKIT_JAR
  580.                 SERVER_ARGS=$SERVER_BUKKIT_ARGS
  581.                 JAVA_OPTS=$SERVER_BUKKIT_JAVA_OPTS
  582.         elif [ $SERVER_TYPE = "tekkit" ]; then
  583.                 SERVER_JAR=$SERVER_TEKKIT_JAR
  584.                 SERVER_ARGS=$SERVER_TEKKIT_ARGS
  585.                 JAVA_OPTS=$SERVER_TEKKIT_JAVA_OPTS
  586.         elif [ $SERVER_TYPE = "ftb" ]; then
  587.                 SERVER_JAR=$SERVER_FTB_JAR
  588.                 SERVER_ARGS=$SERVER_FTB_ARGS
  589.                 JAVA_OPTS=$SERVER_FTB_JAVA_OPTS
  590.         else
  591.                 SERVER_JAR=$SERVER_MOJANG_JAR
  592.                 SERVER_ARGS=$SERVER_MOJANG_ARGS
  593.                 JAVA_OPTS=$SERVER_MOJANG_JAVA_OPTS
  594.         fi
  595.  
  596.         # Make sure that the server software exists.
  597.         if [ ! -e $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR ]; then
  598.                 printf "\nServer software not found, downloading it...\n"
  599.                 update "server"
  600.         fi
  601.  
  602.         # Custom actions for tekkit
  603.         if [ $SERVER_TYPE = "tekkit" ] && [ ! -e "$WORLDS_LOCATION/$1/$SERVER_TEKKIT_JAR" ]; then
  604.                 execute "cp -Rp $SERVER_LOCATION/$SERVER_TYPE/* $WORLDS_LOCATION/$1/" $USER_NAME
  605.         fi
  606.  
  607.         # Custom actions for feed-the-beast
  608.         if [ $SERVER_TYPE = "ftb" ] && [ ! -e "$WORLDS_LOCATION/$1/$SERVER_FTB_JAR" ]; then
  609.                 execute "cp -Rp $SERVER_LOCATION/$SERVER_TYPE/* $WORLDS_LOCATION/$1/" $USER_NAME
  610.         fi
  611.  
  612.         # Make sure that the server.properties file holds the same values as
  613.         # the worlds.conf and motd.txt files.
  614.         setPropertiesValue $WORLDS_LOCATION/$1/server.properties "level-name" $1
  615.         setPropertiesValue $WORLDS_LOCATION/$1/server.properties "server-port" $(getPort $1)
  616.         setPropertiesValue $WORLDS_LOCATION/$1/server.properties "server-ip" $(getIP $1)
  617.         setPropertiesValue $WORLDS_LOCATION/$1/server.properties "motd" "$(getMOTD $1)"
  618.  
  619.         # Make a mirror image of the world directory if requested.
  620.         if [ $ENABLE_MIRROR -eq 1 ] && [ -d $MIRROR_PATH ]; then
  621.                 execute "mkdir -p $MIRROR_PATH/$1" $USER_NAME
  622.                 execute "cp -R $WORLDS_LOCATION/$1/* $MIRROR_PATH/$1" $USER_NAME
  623.                 WORLD_DIR="$MIRROR_PATH/$1"
  624.         elif [ $ENABLE_MIRROR -eq 1 ]; then
  625.                 printf "Error copying the world data to the mirror location, path not found.\n"
  626.                 exit 1
  627.         fi
  628.         # Change to the world's directory.
  629.         cd $WORLD_DIR
  630.         # Make sure that the server.log file exists.
  631.         execute "touch server.log" $USER_NAME
  632.         # Erase the world's users file before starting up the world, in
  633.         # case it is not already empty for some reason.
  634.         execute "printf \"\" > \"$WORLDS_LOCATION/$1.users\"" $USER_NAME
  635.         # Start the server.
  636.         execute "$SCREEN -dmS minecraft-$1 $JAVA $JAVA_OPTS -jar $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR $SERVER_ARGS" $USER_NAME
  637.         if [ $? -ne 0 ]; then
  638.                 printf "Error starting the server.\n"
  639.                 exit 1
  640.         fi
  641.         # Grab the Process ID of the world server.
  642.         PID=$(echo $(getProcessIDs $1) | cut -d ' ' -f2)
  643.         if [ ! -n "$PID" ]; then
  644.                 printf "Error starting the server, the Process ID was not found.\n"
  645.                 exit 1
  646.         fi
  647.         # Start the log processor.
  648.         tail -n0 -f --pid=$PID $WORLD_DIR/server.log | parseLog $1 &
  649.         # Create a lock file on RedHat and derivatives.
  650.         if [ -d "/var/lock/subsys" ]; then
  651.                 touch /var/lock/subsys/minecraft_server
  652.         fi
  653. }
  654.  
  655. # Stop the world server.
  656. #
  657. # @param 1 The world server to stop.
  658. stop() {
  659.         local WORLD NUM
  660.         sendCommand $1 "stop"
  661.         # Erase the world's users file since we won't be able to catch
  662.         # anyone logging off.
  663.         execute "printf \"\" > \"$WORLDS_LOCATION/$1.users\"" $USER_NAME
  664.         # Synchronize the mirror image of the world prior to closing, if required.
  665.         if [ $ENABLE_MIRROR -eq 1 ] && [ -d $MIRROR_PATH ]; then
  666.                 syncMirrorImage $1
  667.         fi
  668.         # Remove the lock file on Redhat and derivatives if all world servers are stopped.
  669.         if [ -e "/var/lock/subsys/minecraft_server" ]; then
  670.                 NUM=0
  671.                 for WORLD in $ALL_WORLDS; do
  672.                         if [ "$1" != "$WORLD" ] && [ $(serverRunning $WORLD) -eq 1 ]; then
  673.                                 NUM=$(($NUM + 1))
  674.                         fi
  675.                 done
  676.                 if [ $NUM -eq 0 ]; then
  677.                         rm -f /var/lock/subsys/minecraft_server
  678.                 fi
  679.         fi
  680. }
  681.  
  682. # Forcibly stop the world server.
  683. #
  684. # @param 1 The world server to forcibly stop.
  685. forceStop() {
  686.         local PIDS
  687.         PIDS=$(getProcessIDs $1)
  688.         # Try to stop the server cleanly first.
  689.         stop $1
  690.         sleep 5
  691.         # Kill the process ids of the world server.
  692.         kill -9 $PIDS > /dev/null 2>&1
  693.         # Remove the lock file on Redhat and derivatives if it is still around.
  694.         rm -f /var/lock/subsys/minecraft_server
  695. }
  696.  
  697. # Backup the world server.
  698. #
  699. # @param 1 The world server to backup.
  700. worldBackup() {
  701.         # Make sure that the backup location exists.
  702.         execute "mkdir -p $BACKUP_LOCATION" $USER_NAME
  703.         # Create the backup.
  704.         execute "$RDIFF_BACKUP -v5 --print-statistics $WORLDS_LOCATION/$1 $BACKUP_LOCATION/$1 >> $BACKUP_LOG" $USER_NAME
  705.         # Cleanup old backups.
  706.         if [ $BACKUP_DURATION > 0 ]; then
  707.                 execute "$RDIFF_BACKUP --remove-older-than ${BACKUP_DURATION}D --force $BACKUP_LOCATION/$1 >> $BACKUP_LOG" $USER_NAME
  708.         fi
  709. }
  710.  
  711. # Update the server software.
  712. updateServerSoftware() {
  713.         local SERVER_JAR SERVER_URL
  714.  
  715.         for SERVER_TYPE in $SERVER_TYPES; do
  716.                 # Set the server location, and args
  717.                 if [ $SERVER_TYPE = "mojang" ]; then
  718.                         SERVER_URL=$SERVER_MOJANG_URL
  719.                         SERVER_JAR=$SERVER_MOJANG_JAR
  720.                 elif [ $SERVER_TYPE = "bukkit" ]; then
  721.                         SERVER_URL=$SERVER_BUKKIT_URL
  722.                         SERVER_JAR=$SERVER_BUKKIT_JAR
  723.                 elif [ $SERVER_TYPE = "tekkit" ]; then
  724.                         SERVER_URL=$SERVER_TEKKIT_URL
  725.                         SERVER_JAR=$SERVER_TEKKIT_JAR
  726.                 elif [ $SERVER_TYPE = "ftb" ]; then
  727.                         SERVER_URL=$SERVER_FTB_URL
  728.                         SERVER_JAR=$SERVER_FTB_JAR
  729.                 fi
  730.  
  731.                 execute "mkdir -p $SERVER_LOCATION/$SERVER_TYPE" $USER_NAME
  732.  
  733.                 # Custom actions for tekkit
  734.                 if [ $SERVER_TYPE = "tekkit" ]; then
  735.                         printf "\nTekkit must be updated manually.\n"
  736.                         # Backup the old server package.
  737.                         # if [ -e "$SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR" ]; then
  738.                         #       execute "tar zcf $SERVER_LOCATION/$SERVER_TYPE.old.tar.gz $SERVER_LOCATION/$SERVER_TYPE/" $USER_NAME
  739.                         #       execute "rm -rf $SERVER_LOCATION/$SERVER_TYPE/" $USER_NAME
  740.                         #       execute "rm $SERVER_LOCATION/$SERVER_TYPE.zip" $USER_NAME
  741.                         # fi
  742.  
  743.                         # Download the new server software.
  744.                         # execute "$WGET -qO $SERVER_LOCATION/$SERVER_TYPE.zip $SERVER_URL" $USER_NAME
  745.  
  746.                         # Check for error and restore backup if found.
  747.                         # if [ $? -ne 0 ]; then
  748.                         #       printf "\nError updating server software.\n"
  749.                         #       if [ -e "$SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR.old.tar.gz" ]; then
  750.                         #               execute "tar xzf $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR.old.tar.gz" $USER_NAME
  751.                         #       fi
  752.                         #       exit 1
  753.                         # else
  754.                         #       execute "unzip -qq $SERVER_LOCATION/$SERVER_TYPE.zip -d $SERVER_LOCATION/$SERVER_TYPE/" $USER_NAME
  755.                                 #TODO - copy new update to all tekkit servers
  756.                         #fi
  757.                 # Custom actions for feed-the-beast
  758.                 elif [ $SERVER_TYPE = "ftb" ]; then
  759.                         printf "\nFeed the Beast must be updated manually.\n"
  760.                 else
  761.                         # Backup the old server jar.
  762.                         if [ -e "$SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR" ]; then
  763.                                 execute "mv -f $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR.old" $USER_NAME
  764.                         fi
  765.  
  766.                         # Download the new server software.
  767.                         execute "$WGET -qO $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR $SERVER_URL" $USER_NAME
  768.  
  769.                         # Check for error and restore backup if found.
  770.                         if [ $? -ne 0 ]; then
  771.                                 printf "\nError updating server software.\n"
  772.                                 if [ -e "$SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR.old" ]; then
  773.                                         execute "mv -f $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR.old $SERVER_LOCATION/$SERVER_TYPE/$SERVER_JAR" $USER_NAME
  774.                                 fi
  775.                                 exit 1
  776.                         fi
  777.                 fi
  778.         done
  779. }
  780.  
  781. # Update the c10t mapping software.  If already installed, compare version
  782. # numbers to avoid downloading the same version again.  Verify the sha1sum
  783. # of the downloaded .tar.gz file with that provided upstream.
  784. updateC10T() {
  785.         local ARCH VERSION OLD_VERSION SHA1SUM SHA1 SHA1_EXPECT
  786.         # Make sure the directory exists.
  787.         execute "mkdir -p $C10T_LOCATION" $USER_NAME
  788.         cd $C10T_LOCATION
  789.         # See what version of c10t is currently installed.
  790.         execute "touch CURRENT" $USER_NAME
  791.         OLD_VERSION=$(cat CURRENT)
  792.         # Determine the current upstream version number of c10t.
  793.         execute "$WGET -qO CURRENT \"$C10T_URL/CURRENT\"" $USER_NAME
  794.         if [ $? -ne 0 ]; then
  795.                 printf "\nError determining the current version of c10t.\n"
  796.                 exit 1
  797.         fi
  798.         VERSION=$(cat CURRENT)
  799.         # Compare upstream version number to the version installed, perform the
  800.         # update if necessary.
  801.         if [ "$VERSION" != "$OLD_VERSION" ]; then
  802.                 # Determine the architecture of the system.
  803.                 if [ $(getconf LONG_BIT) -eq 64 ]; then
  804.                         ARCH="x86_64"
  805.                 else
  806.                         ARCH="x86"
  807.                 fi
  808.                 # Download the new version of c10t.
  809.                 execute "$WGET -qO c10t.tar.gz \"$C10T_URL/c10t-$VERSION-linux-$ARCH.tar.gz\"" $USER_NAME
  810.                 if [ $? -ne 0 ]; then
  811.                         printf "\nError downloading c10t.\n"
  812.                         exit 1
  813.                 fi
  814.                 # Verify the sha1 hash of the file.
  815.                 SHA1SUM=$(which sha1sum)
  816.                 if [ -e $SHA1SUM ]; then
  817.                         # Download the sha1 hash file.
  818.                         execute "$WGET -qO c10t.tar.gz.sha1 \"$C10T_URL/c10t-$VERSION-linux-$ARCH.tar.gz.sha1\"" $USER_NAME
  819.                         if [ $? -ne 0 ]; then
  820.                                 printf "\nError downloading the c10t sha1 hash file.\n"
  821.                                 exit 1
  822.                         fi
  823.                         # Compare the sha1sum of the c10t archive with the
  824.                         # expected value from the downloaded hash file.
  825.                         SHA1=$($SHA1SUM c10t.tar.gz | cut -d ' ' -f 1)
  826.                         SHA1_EXPECT=$(cat c10t.tar.gz.sha1 | cut -d ' ' -f 1)
  827.                         if [ "$SHA1" != "$SHA1_EXPECT" ]; then
  828.                                 printf "\nError downloading c10t, the sha1 hash does not match.\n"
  829.                                 exit 1
  830.                         fi
  831.                 fi
  832.                 # Uncompress the archive.
  833.                 execute "tar xzf c10t.tar.gz --strip 1" $USER_NAME
  834.         fi
  835. }
  836.  
  837. # Update the pigmap mapping software.
  838. updatePigmap() {
  839.         # Remove old builds of pigmap.
  840.         rm -Rf $PIGMAP_LOCATION/build
  841.         # Make sure the pigmap build directory exists.
  842.         execute "mkdir -p $PIGMAP_LOCATION/build" $USER_NAME
  843.         cd $PIGMAP_LOCATION
  844.         # Download the new version of pigmap.
  845.         execute "$WGET -qO pigmap.tar.gz \"$PIGMAP_URL\"" $USER_NAME
  846.         if [ $? -ne 0 ]; then
  847.                 printf "\nError downloading pigmap.\n"
  848.                 exit 1
  849.         fi
  850.         # Uncompress the pigmap archive.
  851.         execute "tar xzf pigmap.tar.gz --strip 1 -C build" $USER_NAME
  852.         # Build the pigmap executable.
  853.         cd $PIGMAP_LOCATION/build
  854.         execute "make" $USER_NAME > /dev/null 2>&1
  855.         if [ $? -ne 0 ]; then
  856.                 printf "\nError building pigmap.\n"
  857.                 exit 1
  858.         fi
  859.         # Copy the resulting binary to the correct location.
  860.         execute "cp pigmap $PIGMAP_BIN" $USER_NAME
  861.         # Make sure the pigmap images directory exists.
  862.         execute "mkdir -p $PIGMAP_LOCATION/images" $USER_NAME
  863.         # Copy the pigmap images to the correct location.
  864.         execute "cp *.png $PIGMAP_LOCATION/images" $USER_NAME
  865.         # Make sure the pigmap template directory exists.
  866.         execute "mkdir -p $PIGMAP_LOCATION/template" $USER_NAME
  867.         # Copy the template files to the correct location.
  868.         execute "cp template.html style.css $PIGMAP_LOCATION/template" $USER_NAME
  869.         cd $PIGMAP_LOCATION
  870.         # Download the minecraft client so that we can extract the default skin.
  871.         execute "$WGET -qO minecraft.jar \"$MINECRAFT_CLIENT_URL\"" $USER_NAME
  872.         if [ $? -ne 0 ]; then
  873.                 printf "\nError downloading the minecraft client.\n"
  874.                 exit 1
  875.         fi
  876.         # Extract the images from the mincraft client.
  877.         execute "$JAR xf minecraft.jar terrain.png item/chest.png item/largechest.png item/enderchest.png" $USER_NAME
  878.         if [ $? -ne 0 ]; then
  879.                 printf "\nError extracting the images from the minecraft client.\n"
  880.                 exit 1
  881.         fi
  882.         # Move the minecraft client images to the correct location.
  883.         execute "mv terrain.png item/chest.png item/largechest.png item/enderchest.png $PIGMAP_LOCATION/images" $USER_NAME
  884.         execute "rmdir item"
  885. }
  886.  
  887. # Update a software package.  Uses the other update functions to actually
  888. # perform the update.
  889. #
  890. # @param 1 The package to update.
  891. update() {
  892.         case "$1" in
  893.                 server)
  894.                         updateServerSoftware
  895.                 ;;
  896.                 c10t)
  897.                         updateC10T
  898.                 ;;
  899.                 pigmap)
  900.                         updatePigmap
  901.                 ;;
  902.                 *)
  903.                         printf "Unknown software package: $1\n"
  904.                         exit 1
  905.                 ;;
  906.         esac
  907. }
  908.  
  909. # Run c10t mapping software on the world.  Generates multiple image files in
  910. # the specified maps location.
  911. #
  912. # @param 1 The world server to map with c10t.
  913. c10t() {
  914.         local WORLD_DIR
  915.         WORLD_DIR="$WORLDS_LOCATION/$1"
  916.         # Use the mirror copy of the world directory if enabled.
  917.         if [ $ENABLE_MIRROR -eq 1 ] && [ -d $MIRROR_PATH ]; then
  918.                 WORLD_DIR="$MIRROR_PATH/$1"
  919.         fi
  920.         # Make sure the maps directory exists.
  921.         execute "mkdir -p $C10T_MAPS_LOCATION/$1" $USER_NAME
  922.         # Make sure that the world files are actually there before mapping.
  923.         if [ -e "$WORLD_DIR/server.properties" ]; then
  924.                 # Create various maps for the main world.
  925.                 execute "LC_ALL='C' $C10T_BIN -s -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/surface.png" $USER_NAME
  926.                 execute "LC_ALL='C' $C10T_BIN -s -c -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/caves.png" $USER_NAME
  927.                 execute "LC_ALL='C' $C10T_BIN -s -c -H -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/caves_heightmap.png" $USER_NAME
  928.                 execute "LC_ALL='C' $C10T_BIN -s -a -i 21 -H -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/lapis_heightmap.png" $USER_NAME
  929.                 execute "LC_ALL='C' $C10T_BIN -s -a -i 56 -H -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/diamonds_heightmap.png" $USER_NAME
  930.                 execute "LC_ALL='C' $C10T_BIN -s -a -i 4 -H -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/cobble_heightmap.png" $USER_NAME
  931.                 execute "LC_ALL='C' $C10T_BIN -s -q -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/surface_oblique.png" $USER_NAME
  932.                 execute "LC_ALL='C' $C10T_BIN -s -q -c -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/caves_oblique.png" $USER_NAME
  933.                 execute "LC_ALL='C' $C10T_BIN -s -z -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/surface_isometric.png" $USER_NAME
  934.                 execute "LC_ALL='C' $C10T_BIN -s -z -c -w $WORLD_DIR/$1 -o $C10T_MAPS_LOCATION/$1/caves_isometric.png" $USER_NAME
  935.                 # Create various maps for the nether world if it exists.
  936.                 if [ -d "$WORLD_DIR/$1/DIM-1" ]; then
  937.                         execute "LC_ALL='C' $C10T_BIN -s -N --hell-mode -w $WORLD_DIR/$1/DIM-1 -o $C10T_MAPS_LOCATION/$1/nether_surface.png" $USER_NAME
  938.                         execute "LC_ALL='C' $C10T_BIN -s -N --hell-mode -q -w $WORLD_DIR/$1/DIM-1 -o $C10T_MAPS_LOCATION/$1/nether_surface_oblique.png" $USER_NAME
  939.                         execute "LC_ALL='C' $C10T_BIN -s -N --hell-mode -z -w $WORLD_DIR/$1/DIM-1 -o $C10T_MAPS_LOCATION/$1/nether_surface_isometric.png" $USER_NAME
  940.                 elif [ -d "$WORLD_DIR/$1_nether/DIM-1" ]; then
  941.                         execute "LC_ALL='C' $C10T_BIN -s -N --hell-mode -w $WORLD_DIR/$1_nether/DIM-1 -o $C10T_MAPS_LOCATION/$1/nether_surface.png" $USER_NAME
  942.                         execute "LC_ALL='C' $C10T_BIN -s -N --hell-mode -q -w $WORLD_DIR/$1_nether/DIM-1 -o $C10T_MAPS_LOCATION/$1/nether_surface_oblique.png" $USER_NAME
  943.                         execute "LC_ALL='C' $C10T_BIN -s -N --hell-mode -z -w $WORLD_DIR/$1_nether/DIM-1 -o $C10T_MAPS_LOCATION/$1/nether_surface_isometric.png" $USER_NAME
  944.                 fi
  945.         fi
  946. }
  947.  
  948. # Run pigmap mapping software on the world.  Generates an index.html file using the Google Maps API.
  949. #
  950. # @param 1 The world server to map with c10t.
  951. pigmap() {
  952.         # Make sure the maps directory exists.
  953.         execute "mkdir -p $PIGMAP_MAPS_LOCATION/$1" $USER_NAME
  954.         # Make sure that the world files are actually there before mapping.
  955.         if [ -e "$WORLDS_LOCATION/$1/server.properties" ]; then
  956.                 execute "$PIGMAP_BIN -i $WORLDS_LOCATION/$1/$1 -o $PIGMAP_MAPS_LOCATION/$1 -g $PIGMAP_LOCATION/images -m $PIGMAP_LOCATION/template -B 5 -T 5" $USER_NAME > /dev/null 2>&1
  957.                 # Copy pigmap-default.html to index.html if the index.html file does not exist.
  958.                 if [ ! -e "$PIGMAP_MAPS_LOCATION/$1/index.html" ]; then
  959.                         execute "cp $PIGMAP_MAPS_LOCATION/$1/pigmap-default.html $PIGMAP_MAPS_LOCATION/$1/index.html" $USER_NAME
  960.                 fi
  961.         fi
  962. }
  963.  
  964.  
  965. ## Begin.
  966.  
  967.  
  968. # Make sure that Java, Perl, Rsync, GNU Screen, and GNU Wget are installed.
  969. if [ ! -e $JAVA ] || [ ! -e $JAR ]; then
  970.         printf "ERROR: Java not found!\n"
  971.         printf "Try installing this with:\n"
  972.         printf "sudo apt-get install openjdk-7-jre\n"
  973.         exit 1
  974. fi
  975. if [ ! -e $PERL ]; then
  976.         printf "ERROR: Perl not found!\n"
  977.         printf "Try installing this with:\n"
  978.         printf "sudo apt-get install perl\n"
  979.         exit 1
  980. fi
  981. if [ $ENABLE_MIRROR -eq 1 ] && [ ! -e $RSYNC ]; then
  982.         printf "ERROR: Rsync not found!\n"
  983.         printf "Try installing this with:\n"
  984.         printf "sudo apt-get install rsync\n"
  985.         exit 1
  986. fi
  987. if [ ! -e $SCREEN ]; then
  988.         printf "ERROR: GNU Screen not found!\n"
  989.         printf "Try installing this with:\n"
  990.         printf "sudo apt-get install screen\n"
  991.         exit 1
  992. fi
  993. if [ ! -e $WGET ]; then
  994.         printf "ERROR: GNU Wget not found!\n"
  995.         printf "Try installing this with:\n"
  996.         printf "sudo apt-get install wget\n"
  997.         exit 1
  998. fi
  999. if [ ! -e $RDIFF_BACKUP ]; then
  1000.         printf "ERROR: rdiff-backup not found!\n"
  1001.         printf "Try installing this with:\n"
  1002.         printf "sudo apt-get install rdiff-backup\n"
  1003.         exit 1
  1004. fi
  1005.  
  1006. # Make sure that the minecraft user exists.
  1007. if [ ! -n "$(grep $USER_NAME /etc/passwd)" ]; then
  1008.         printf "ERROR: This script requires that a user account named $USER_NAME exist on this system.\n"
  1009.         printf "Either modify the USER_NAME variable in this script, or try adding this user:\n"
  1010.         printf "sudo adduser $USER_NAME\n"
  1011.         exit 1
  1012. fi
  1013.  
  1014. # Warn if the script is running with the wrong user.
  1015. if [ $(id -u) -ne 0 ] && [ "$(whoami)" != "$USER_NAME" ]; then
  1016.         printf "WARNING: This script appears to have been started by the wrong user.\n"
  1017.         printf "Expected to find the user: $USER_NAME.  You can try to log on to this user:\n"
  1018.         printf "su $USER_NAME\n"
  1019.         exit 1
  1020. fi
  1021.  
  1022. # Generate a default worlds.conf file if it does not already exist.
  1023. if [ ! -e $WORLDS_CONF ]; then
  1024.         execute "printf \"# Minecraft world configuration file\n\" > $WORLDS_CONF" $USER_NAME
  1025.         execute "printf \"# <world>\t<server>\t<port>\t<ip>\n\" >> $WORLDS_CONF" $USER_NAME
  1026.         execute "printf \"$DEFAULT_WORLD\t$DEFAULT_SERVER\t$DEFAULT_PORT\t$DEFAULT_IP\n\" >> $WORLDS_CONF" $USER_NAME
  1027. fi
  1028.  
  1029. # Make sure that the server software exists.
  1030. if [ ! -e $SERVER_LOCATION/$SERVER_JAR ]; then
  1031.         printf "Server software not found, downloading it...\n"
  1032.         update "server"
  1033. fi
  1034.  
  1035. # Update old worlds.conf files.
  1036. if [ -e $WORLDS_CONF ] && [ "$(grep '<eport>' $WORLDS_CONF)" != ""  ]; then
  1037.         execute "cp $WORLDS_CONF $WORLDS_CONF.old" $USER_NAME
  1038.         execute "$PERL -i -ne 'if (\$_ =~ /#\s*<world>\s+<eport>\s+<iport>\s+<ip>/) { print \"# <world>\t<port>\t<ip>\n\"; } else { print; }' $WORLDS_CONF" $USER_NAME
  1039.         execute "$PERL -i -ne 'if (\$_ =~ /(\w+)\s+(\d+)\s+\d+\s*([\d\.]*)/) { printf \"%s\t%d\t%s\n\",\$1,\$2,\$3; } else { print; }' $WORLDS_CONF" $USER_NAME
  1040. fi
  1041.  
  1042. # Grab the list of worlds.
  1043. ALL_WORLDS=$(getWorlds)
  1044.  
  1045. # Respond to the command line arguments.
  1046. case "$1" in
  1047.         start)
  1048.                 # Figure out which worlds to start.
  1049.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1050.                 # Start each world requested, if not already running.
  1051.                 printf "Starting Minecraft Server:"
  1052.                 for WORLD in $WORLDS; do
  1053.                         if [ $(serverRunning $WORLD) -eq 0 ]; then
  1054.                                 printf " $WORLD"
  1055.                                 start $WORLD
  1056.                         fi
  1057.                 done
  1058.                 printf "\n"
  1059.         ;;
  1060.         stop|force-stop)
  1061.                 # Figure out which worlds to stop.
  1062.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1063.                 # Stop each world requested, if running.
  1064.                 printf "Stopping Minecraft Server:"
  1065.                 for WORLD in $WORLDS; do
  1066.                         # Try to stop the world cleanly.
  1067.                         if [ $(serverRunning $WORLD) -eq 1 ]; then
  1068.                                 printf " $WORLD"
  1069.                                 sendCommand $WORLD "say The server is about to go down."
  1070.                                 sendCommand $WORLD "save-all"
  1071.                                 sendCommand $WORLD "save-off"
  1072.                                 sendCommand $WORLD "say The server is going down in 5 seconds..."
  1073.                                 sleep 5
  1074.                                 if [ "$1" = "force-stop" ]; then
  1075.                                         forceStop $WORLD
  1076.                                 else
  1077.                                         stop $WORLD
  1078.                                 fi
  1079.                                 sleep 5
  1080.                         fi
  1081.                 done
  1082.                 printf "\n"
  1083.         ;;
  1084.         restart|reload|force-restart|force-reload)
  1085.                 # Figure out which worlds to restart.
  1086.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1087.                 # Restart each world requested, start those not already running.
  1088.                 printf "Restarting Minecraft Server:"
  1089.                 for WORLD in $WORLDS; do
  1090.                         printf " $WORLD"
  1091.                         if [ $(serverRunning $WORLD) -eq 1 ]; then
  1092.                                 sendCommand $WORLD "say The server is about to restart."
  1093.                                 sendCommand $WORLD "save-all"
  1094.                                 sendCommand $WORLD "save-off"
  1095.                                 sendCommand $WORLD "say Restarting in 5 seconds..."
  1096.                                 sleep 5
  1097.                                 if [ "$(echo \"$1\" | cut -d '-' -f1)" = "force" ]; then
  1098.                                         forceStop $WORLD
  1099.                                 else
  1100.                                         stop $WORLD
  1101.                                 fi
  1102.                                 sleep 5
  1103.                         fi
  1104.                         start $WORLD
  1105.                 done
  1106.                 printf "\n"
  1107.         ;;
  1108.         status|show)
  1109.                 # Figure out which worlds to show the status for.
  1110.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1111.                 # Show the status of each world requested.
  1112.                 printf "Minecraft Server Status:\n"
  1113.                 for WORLD in $WORLDS; do
  1114.                         printf "  $WORLD: "
  1115.                         if [ $(serverRunning $WORLD) -eq 1 ]; then
  1116.                                 printf "running (%d users online).\n" $(cat $WORLDS_LOCATION/$WORLD.users | wc -l)
  1117.                         else
  1118.                                 printf "not running.\n"
  1119.                         fi
  1120.                 done
  1121.         ;;
  1122.         sync|synchronize)
  1123.                 # Make sure the Mirror image option is enabled.
  1124.                 if [ $ENABLE_MIRROR -ne 1 ]; then
  1125.                         printf "Mirror image option not enabled, unable to synchronize.\n";
  1126.                         exit 1
  1127.                 fi
  1128.                 # Figure out which worlds to synchronize.
  1129.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1130.                 # Synchronize the images for each world.
  1131.                 printf "Synchronizing Minecraft Server:"
  1132.                 for WORLD in $WORLDS; do
  1133.                         if [ $(serverRunning $WORLD) -eq 1 ]; then
  1134.                                 printf " $WORLD"
  1135.                                 sendCommand $WORLD "save-off"
  1136.                                 syncMirrorImage $WORLD
  1137.                                 sendCommand $WORLD "save-on"
  1138.                         fi
  1139.                 done
  1140.                 printf "\n"
  1141.         ;;
  1142.         send)
  1143.                 # Check for the world command line argument.
  1144.                 if [ -n "$2" ] && [ $(listContains $2 "$ALL_WORLDS") -eq 1 ] && [ -n "$3" ]; then
  1145.                         WORLD=$2
  1146.                         shift 2
  1147.                         printf "Send command to world $WORLD: $*\n"
  1148.                         sendCommand $WORLD "$*"
  1149.                 else
  1150.                         printf "Usage:  $0 $1 <world> <command>\n"
  1151.                         printf "   ie:  $0 $1 world say Hello World!\n"
  1152.                         exit 1
  1153.                 fi
  1154.         ;;
  1155.         screen)
  1156.                 # Check for the world command line argument.
  1157.                 if [ -n "$2" ] && [ $(listContains $2 "$ALL_WORLDS") -eq 1 ]; then
  1158.                         displayScreen $2
  1159.                 else
  1160.                         if [ -n "$2" ]; then
  1161.                                 printf "Minecraft world $2 not found!\n"
  1162.                         else
  1163.                                 printf "Minecraft world not provided!\n"
  1164.                         fi
  1165.                         printf "  Usage:  $0 $1 <world>\n"
  1166.                         exit 1
  1167.                 fi
  1168.         ;;
  1169.         watch)
  1170.                 # Check for the world command line argument.
  1171.                 if [ -n "$2" ] && [ $(listContains $2 "$ALL_WORLDS") -eq 1 ]; then
  1172.                         watchLog $2
  1173.                 else
  1174.                         if [ -n "$2" ]; then
  1175.                                 printf "Minecraft world $2 not found!\n"
  1176.                         else
  1177.                                 printf "Minecraft world not provided!\n"
  1178.                         fi
  1179.                         printf "  Usage:  $0 $1 <world>\n"
  1180.                         exit 1
  1181.                 fi
  1182.         ;;
  1183.         backup)
  1184.                 # Figure out which worlds to backup.
  1185.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1186.                 # Backup each world requested.
  1187.                 printf "Backing up Minecraft Server:"
  1188.                 for WORLD in $WORLDS; do
  1189.                         printf " $WORLD"
  1190.                         if [ $(serverRunning $WORLD) -eq 1 ]; then
  1191.                                 sendCommand $WORLD "say Backing up the world."
  1192.                                 sendCommand $WORLD "save-all"
  1193.                                 sendCommand $WORLD "save-off"
  1194.                                 sleep 20
  1195.                                 worldBackup $WORLD
  1196.                                 sendCommand $WORLD "save-on"
  1197.                                 sendCommand $WORLD "say Backup complete."
  1198.                         else
  1199.                                 worldBackup $WORLD
  1200.                         fi
  1201.                 done
  1202.                 printf "\n"
  1203.         ;;
  1204.         update)
  1205.                 printf "Updating the Minecraft Server software...\n"
  1206.                 # Figure out which packages to update.
  1207.                 UPDATE_PACKAGES=$(checkOptionalArgument "$UPDATE_PACKAGES" $0 $1 $2)
  1208.                 # If the server software is being updated, stop all of
  1209.                 # the world servers and backup the worlds.
  1210.                 if [ $(listContains "server" "$UPDATE_PACKAGES") -eq 1 ]; then
  1211.                         printf "Stopping Minecraft Server:"
  1212.                         for WORLD in $ALL_WORLDS; do
  1213.                                 if [ $(serverRunning $WORLD) -eq 1 ]; then
  1214.                                         printf " $WORLD"
  1215.                                         sendCommand $WORLD "say The server software is being updated."
  1216.                                         sendCommand $WORLD "say Server restart is imminent."
  1217.                                         sendCommand $WORLD "save-all"
  1218.                                         sendCommand $WORLD "save-off"
  1219.                                         sendCommand $WORLD "say Restarting in 5 seconds."
  1220.                                         sleep 5
  1221.                                         stop $WORLD
  1222.                                 fi
  1223.                         done
  1224.                         printf "\n"
  1225.                         printf "Backing up Minecraft Server:"
  1226.                         for WORLD in $ALL_WORLDS; do
  1227.                                 printf " $WORLD"
  1228.                                 worldBackup $WORLD
  1229.                         done
  1230.                         printf "\n"
  1231.                 fi
  1232.                 # Update each software package requested.
  1233.                 printf "Updating software package:"
  1234.                 for PACKAGE in $UPDATE_PACKAGES; do
  1235.                         printf " $PACKAGE"
  1236.                         update $PACKAGE
  1237.                 done
  1238.                 printf "\n"
  1239.                 if [ $(listContains "server" "$UPDATE_PACKAGES") -eq 1 ]; then
  1240.                         printf "Starting Minecraft Server:"
  1241.                         for WORLD in $ALL_WORLDS; do
  1242.                                 printf " $WORLD"
  1243.                                 start $WORLD
  1244.                         done
  1245.                         printf "\n"
  1246.                 fi
  1247.         ;;
  1248.         c10t)
  1249.                 # Make sure that the c10t software exists.
  1250.                 if [ ! -e $C10T_BIN ]; then
  1251.                         printf "c10t software not found, downloading it...\n"
  1252.                         update "c10t"
  1253.                 fi
  1254.                 # Figure out which worlds to map.
  1255.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1256.                 # Run c10t on each world requested.
  1257.                 printf "Running c10t mapping:"
  1258.                 for WORLD in $WORLDS; do
  1259.                         printf " $WORLD"
  1260.                         if [ $(serverRunning $WORLD) -eq 1 ]; then
  1261.                                 sendCommand $WORLD "say The world is about to be mapped with c10t."
  1262.                                 sendCommand $WORLD "save-all"
  1263.                                 sendCommand $WORLD "save-off"
  1264.                                 sleep 20
  1265.                                 worldBackup $WORLD
  1266.                                 c10t $WORLD
  1267.                                 sendCommand $WORLD "save-on"
  1268.                                 sendCommand $WORLD "say Mapping is complete.  You can access the maps at:"
  1269.                                 sendCommand $WORLD "say $C10T_MAPS_URL/$WORLD"
  1270.                         else
  1271.                                 worldBackup $WORLD
  1272.                                 c10t $WORLD
  1273.                         fi
  1274.                 done
  1275.                 printf "\n"
  1276.         ;;
  1277.         map|pigmap)
  1278.                 # Make sure that the pigmap software exists.
  1279.                 if [ ! -e $PIGMAP_BIN ]; then
  1280.                         printf "pigmap software not found, downloading it...\n"
  1281.                         update "pigmap"
  1282.                 fi
  1283.                 # Figure out which worlds to map.
  1284.                 WORLDS=$(checkOptionalArgument "$ALL_WORLDS" $0 $1 $2)
  1285.                 # Run pigmap on each world requested.
  1286.                 printf "Running pigmap mapping:"
  1287.                 for WORLD in $WORLDS; do
  1288.                         printf " $WORLD"
  1289.                         if [ $(serverRunning $WORLD) -eq 1 ]; then
  1290.                                 sendCommand $WORLD "say The world is about to be mapped with pigmap."
  1291.                                 sendCommand $WORLD "save-all"
  1292.                                 sendCommand $WORLD "save-off"
  1293.                                 sleep 20
  1294.                                 worldBackup $WORLD
  1295.                                 pigmap $WORLD
  1296.                                 sendCommand $WORLD "save-on"
  1297.                                 sendCommand $WORLD "say Mapping is complete.  You can access the maps at:"
  1298.                                 sendCommand $WORLD "say $PIGMAP_MAPS_URL/$WORLD"
  1299.                         else
  1300.                                 worldBackup $WORLD
  1301.                                 pigmap $WORLD
  1302.                         fi
  1303.                 done
  1304.                 printf "\n"
  1305.         ;;
  1306.         *)
  1307.                 printf "Usage: $0 {start|stop|force-stop|restart|force-restart|status|sync|send|screen|watch|backup|update|map} {Optional: world or software package}\n"
  1308.                 exit 1
  1309.         ;;
  1310. esac
  1311. 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