| #!/bin/sh |
| |
| # Copyright 2015-2020 Rivoreo |
| |
| # Permission is hereby granted, free of charge, to any person obtaining |
| # a copy of this software and associated documentation files (the |
| # "Software"), to deal in the Software without restriction, including |
| # without limitation the rights to use, copy, modify, merge, publish, |
| # distribute, sublicense, and/or sell copies of the Software, and to |
| # permit persons to whom the Software is furnished to do so, subject to |
| # the following conditions: |
| |
| # The above copyright notice and this permission notice shall be |
| # included in all copies or substantial portions of the Software. |
| |
| # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| # NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE |
| # FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
| # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| # PROVIDE: minecraft |
| # REQUIRE: LOGIN FILESYSTEMS |
| # KEYWORD: shutdown |
| |
| . /etc/rc.subr |
| |
| name="minecraft" |
| desc="The Minecraft server" |
| rcvar="${name}_enable" |
| start_cmd="minecraft_start" |
| stop_cmd="minecraft_stop" |
| status_cmd="minecraft_status" |
| |
| load_rc_config ${name} |
| |
| [ -z "${minecraft_enable}" ] && minecraft_enable="NO" |
| |
| if [ -n "${minecraft_user}" ]; then |
| minecraft_user_name="${minecraft_user}" |
| elif [ -z "${minecraft_user_name}" ]; then |
| minecraft_user_name="minecraft" |
| fi |
| [ -z "${minecraft_home}" ] && minecraft_home="`pw user show -7 -n ${minecraft_user_name} | cut -d : -f 6`" |
| |
| if [ -z "${minecraft_servers}" ]; then |
| echo "No server defined, exiting" 1>&2 |
| exit 255 |
| fi |
| |
| case "${minecraft_use_tmux}" in |
| [Oo][Nn]|[Yy][Ee][Ss]|Y|[Tt][Rr][Uu][Ee]|1) |
| minecraft_use_tmux=1 |
| [ -z "${minecraft_session_name}" ] && minecraft_session_name=minecraft |
| ;; |
| [Oo][Ff][Ff]|[Nn][Oo]|N|[Ff][Aa][Ll][Ss][Ee]|0|"") |
| minecraft_use_tmux=0 |
| [ -z "${minecraft_alternative_log_file}" ] && minecraft_alternative_log_file=/dev/null |
| ;; |
| *) |
| echo "Unrecognized value of minecraft_use_tmux" 1>&2 |
| exit 1 |
| esac |
| |
| # Workaround to enable the 'status' action |
| procname="java" |
| pidfile= |
| for i in ${minecraft_servers}; do |
| pidfile="${pidfile}${minecraft_home}/$i/server.pid |
| " |
| done |
| |
| export PATH=/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin |
| |
| PID= |
| |
| is_running() { |
| if [ $# != 1 ]; then |
| printf "Internal error: is_running: # (%s) != 1\\n" $# 1>&2 |
| exit 2 |
| fi |
| pid_file="${minecraft_home}/$1/server.pid" |
| [ -f "$pid_file" ] && PID="`cat \"$pid_file\"`" && [ -n "$PID" ] && [ "$PID" != 0 ] && [ "`ps -o comm= -p $PID`" = java ] && return 0 |
| rm -f "$pid_file" |
| return 1 |
| } |
| |
| minecraft_start() { |
| local command_line |
| r=0 |
| for i in ${minecraft_servers}; do |
| if is_running "$i"; then |
| printf "Server %s is already running\\n" "$i" |
| continue |
| fi |
| #echo Starting Minecraft server... |
| cd "${minecraft_home}/$i" || continue |
| if [ -n "${minecraft_start_command}" ]; then |
| command_line="${minecraft_start_command}" |
| elif [ -n run.sh ]; then |
| command_line="exec sh run.sh" |
| [ -f start.sh ] && printf "Warning: deprecated startup script '%s/start.sh' exists\\n" "$MINECRAFT_HOME/$i" 1>&2 |
| elif [ -f start.sh ]; then |
| printf "Warning: using deprecated startup script '%s/start.sh'\\n" "$MINECRAFT_HOME/$i" 1>&2 |
| command_line="exec sh start.sh" |
| else |
| printf "Startup script '%s/run.sh' not found\\n" "$MINECRAFT_HOME/$i" 1>&2 |
| continue |
| fi |
| if [ "$minecraft_use_tmux" = 1 ]; then |
| su "${minecraft_user_name}" -c "exec tmux -L \"${minecraft_session_name}-$i\" new-session -d \"${minecraft_start_command}\"" |
| else |
| su "${minecraft_user_name}" -c "${minecraft_start_command}" < /dev/null >> "${minecraft_alternative_log_file}" 2>&1 & sh_pid=$! |
| fi |
| sleep 1 |
| if is_running "$i"; then |
| if [ "${minecraft_use_tmux}" = 1 ] || [ $PID = $sh_pid ]; then |
| printf "Minecraft server %s started\\n" "$i" |
| else |
| printf "Minecraft server %s appeared to be started, but PID mismatch (%s!=%s)\\n" "$i" $PID $sh_pid |
| fi |
| else |
| printf "Failed to start Minecraft server %s\\n" "$i" |
| r=$((r+1)) |
| fi |
| done |
| return $r |
| } |
| |
| minecraft_stop() { |
| for i in ${minecraft_servers}; do |
| if ! is_running "$i"; then |
| printf "Server %s is not running\\n" "$i" 1>&2 |
| continue |
| fi |
| #echo Stopping Minecraft server... |
| if [ "${minecraft_use_tmux}" = 1 ]; then |
| su -m "${minecraft_user_name}" -c "tmux -L \"${minecraft_session_name}-$i\" send-keys -t 0 C-u stop ENTER" |
| j=8 |
| while [ $j -gt 0 ]; do |
| j=$((j-1)) |
| sleep 0.5 |
| printf . |
| if ! is_running "$i"; then |
| printf " %s stopped\\n" "$i" 1>&2 |
| continue 2 |
| fi |
| done |
| echo |
| fi |
| echo "Sending SIGINT..." 1>&2 |
| kill -s INT "$PID" |
| j=4 |
| if while [ $j -gt 0 ]; do |
| j=$((j-1)) |
| sleep 0.5 |
| if ! is_running "$i"; then |
| j=0 |
| false |
| fi |
| done; then |
| echo "Sending SIGTERM..." 1>&2 |
| kill "$PID" |
| j=8 |
| if while [ $j -gt 0 ]; do |
| j=$((j-1)) |
| sleep 0.5 |
| if ! is_running "$i"; then |
| j=0 |
| false |
| fi |
| done; then |
| echo "Sending SIGKILL..." 1>&2 |
| kill -s KILL $PID |
| fi |
| fi |
| printf "%s stopped\\n" "$i" 1>&2 |
| done |
| } |
| |
| minecraft_status() { |
| r=0 |
| for i in ${minecraft_servers}; do |
| if is_running "$i"; then |
| printf "%s is running (pid %s)\\n" "$i" "$PID" |
| else |
| printf "%s is not running\\n" "$i" |
| r=$((r+1)) |
| fi |
| done |
| return $r |
| } |
| |
| run_rc_command "$1" |