/minecraft

http://github.com/Ahtenus/minecraft-init · #! · 983 lines · 917 code · 66 blank · 0 comment · 0 complexity · b633176adeab746dcda65a0cd72d98ca MD5 · raw file

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