From 66c3caa5491deea762993f3f4f05f968d5d1d4d6 Mon Sep 17 00:00:00 2001 From: Roman Zhuravlev Date: Mon, 25 Aug 2025 17:04:57 +0500 Subject: [PATCH] Add processing `.in` files and configure only and skip configure options --- mca.sh | 317 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 183 insertions(+), 134 deletions(-) diff --git a/mca.sh b/mca.sh index 9b04e93..ed819a6 100755 --- a/mca.sh +++ b/mca.sh @@ -4,15 +4,16 @@ set -e EXEC_NAME="$(basename -- "$0")" -USAGE="Usage: $EXEC_NAME [OPTION]... [MCA_NAME|MCA_JAR|MCA_DIR] [INPUT]..." +USAGE="Usage: $EXEC_NAME [OPTION]... [NAME|JAR|DIR] [INPUT]..." VERSION="mca 1.0.0" -OPTION="$(getopt -n "$EXEC_NAME" -s sh -o hvfdxrs -l help -l version -- "$@")" +OPTION="$(getopt -n "$EXEC_NAME" -s sh -o hvfdxrsc -l help -l version -- "$@")" eval set -- "$OPTION" SCREEN_OPTS= REATTACH_ONLY=0 SKIP_CONFIGURE=0 +CONFIGURE_ONLY=0 while :; do case "$1" in @@ -39,6 +40,9 @@ while :; do -s) SKIP_CONFIGURE=1 ;; + -c) + CONFIGURE_ONLY=1 + ;; --) shift break @@ -46,13 +50,19 @@ while :; do shift done +if [ "$SKIP_CONFIGURE" -eq 1 ] && [ "$CONFIGURE_ONLY" -eq 1 ]; then + echo "$EXEC_NAME: can't skip configuration and only configure at \ +the same time" >&2 + exit 2 +fi + MCA_NAME=$1 if [ -z "$MCA_NAME" ]; then MCA_DIR="$PWD" MCA_NAME="$(basename -- "$MCA_DIR")" -elif echo "$MCA_NAME" | grep -qE '^\.{,2}/' && \ - MCA_NAME="$(readlink -f -- "$MCA_NAME")"; then +elif echo "$MCA_NAME" | grep -qE '^\.{,2}/' \ + && MCA_NAME="$(readlink -f -- "$MCA_NAME")"; then if [ -d "$MCA_NAME" ]; then MCA_DIR="$MCA_NAME" MCA_NAME="$(basename -- "$MCA_DIR")" @@ -64,155 +74,191 @@ else MCA_DIR="$HOME/mca/$MCA_NAME" fi -if ! command -v screen > /dev/null; then - echo "$EXEC_NAME: screen not found" >&2 - exit 2 -fi - -if [ -n "$2" ]; then - shift - INPUT="$(echo "$*" | sed 's/"/\\\0/g')" - if screen -S "$MCA_NAME" -X eval "stuff \"$INPUT\"\\015" > /dev/null; then - exit 0 - else - echo "$EXEC_NAME: $MCA_NAME: no such screen found" >&2 +if [ "$CONFIGURE_ONLY" -eq 0 ]; then + if ! command -v screen > /dev/null; then + echo "$EXEC_NAME: screen not found" >&2 exit 2 fi -fi -MCA_SCREENRC_FILE="/etc/mca/screenrc" -if [ ! -r "$MCA_SCREENRC_FILE" ]; then - echo "$EXEC_NAME: can't read $MCA_SCREENRC_FILE" >&2 - exit 2 -fi + SCREEN_NAME="$(echo "$MCA_NAME" | tr / -)" -if screen -c "$MCA_SCREENRC_FILE" "-$SCREEN_OPTS"rS \ - "$MCA_NAME" > /dev/null 2>&1; then - exit 0 -elif screen -S "$MCA_NAME" -X select . > /dev/null 2>&1; then - echo "$EXEC_NAME: this screen has already been attached to someone" >&2 - exit 2 -fi + if [ -n "$2" ]; then + shift + INPUT="$(echo "$*" | sed 's/"/\\\0/g')" + if screen -S "$SCREEN_NAME" \ + -X eval "stuff \"$INPUT\"\\015" > /dev/null; then + exit 0 + else + echo "$EXEC_NAME: $SCREEN_NAME: no such screen found" >&2 + exit 2 + fi + fi -if [ "$REATTACH_ONLY" -eq 1 ]; then - echo "$EXEC_NAME: $MCA_NAME: no such screen found" >&2 - exit 2 -fi + SCREEN_RC_FILE= + for i in "$HOME/.config" /etc; do + j="$i/mca/screenrc" + if [ -r "$j" ]; then + SCREEN_RC_FILE=$j + break + fi + done -if [ ! -d "$MCA_DIR" ]; then - echo "$EXEC_NAME: $MCA_DIR: such directory not found" >&2 - exit 2 + if [ -z "$SCREEN_RC_FILE" ]; then + echo "$EXEC_NAME: can't find screenrc" >&2 + exit 2 + fi + + if screen -c "$SCREEN_RC_FILE" "-$SCREEN_OPTS"rS \ + "$SCREEN_NAME" > /dev/null 2>&1; then + exit 0 + elif screen -S "$SCREEN_NAME" -X select . > /dev/null 2>&1; then + echo "$EXEC_NAME: this screen has already been attached to someone" >&2 + exit 2 + fi + + if [ "$REATTACH_ONLY" -eq 1 ]; then + echo "$EXEC_NAME: $SCREEN_NAME: no such screen found" >&2 + exit 2 + fi + + if [ ! -d "$MCA_DIR" ]; then + echo "$EXEC_NAME: $MCA_DIR: such directory not found" >&2 + exit 2 + fi fi cd "$MCA_DIR" MCA_RC_FILE="$MCA_DIR/.mcarc" -# this file is taken from a dynamic variable, so we cannot specify an explicit -# path to the file. -# shellcheck disable=SC1090 -# `--` is supported in dash. -# shellcheck disable=SC2240 if [ -e "$MCA_RC_FILE" ]; then - set -a - . -- "$MCA_RC_FILE" - set +a + # don't use `-p` in `read` for line breaks to avoid long lines. + # shellcheck disable=SC2162 + while IFS= read line; do + # skip lines starting with '#' + case "$line" in + ''|\#*) + continue + ;; + esac + # to get `$1` and `$2` as key and value. + # shellcheck disable=SC2086 + set $line + + if echo "$1" | grep -i '[^a-zA-Z0-9_]'; then + echo "$EXEC_NAME: $1: option key contains invalid characters" >&2 + else + KEY="MCA_$(echo "$1" | tr '[:lower:]' '[:upper:]')" + if [ -n "$2" ]; then + shift + VALUE=$* + fi + export "$KEY"="$VALUE" + fi + done < "$MCA_RC_FILE" MCA_RC_FILE_READ=1 else MCA_RC_FILE_READ=0 fi -if [ -z "$PLATFORM" ]; then - if [ -z "$MCA_JAR" ]; then - MCA_JAR="$(find "$MCA_DIR" -maxdepth 1 \ - -type f -name \*.jar | head -1)" - [ -z "$MCA_JAR" ] && { - echo "$EXEC_NAME: no jar found in $MCA_DIR" >&2 +if [ "$CONFIGURE_ONLY" -eq 0 ]; then + if [ -z "$MCA_PLATFORM" ]; then + if [ -z "$MCA_JAR" ]; then + MCA_JAR="$(find "$MCA_DIR" -maxdepth 1 -type f -name \*.jar \ + | head -1)" + [ -z "$MCA_JAR" ] && { + echo "$EXEC_NAME: no jar found in $MCA_DIR" >&2 + exit 2 + } + fi + + if [ -e "$MCA_JAR" ]; then + MCA_PLATFORM="$(basename -- "$MCA_JAR")" + MCA_PLATFORM="$(echo "$MCA_PLATFORM" \ + | tr '[:upper:]' '[:lower:]' | grep -oE '[a-z]+' | head -1)" + else + echo "$EXEC_NAME: $MCA_JAR: no such file" >&2 exit 2 - } - fi - - if [ -e "$MCA_JAR" ]; then - PLATFORM="$(basename -- "$MCA_JAR")" - PLATFORM="$(echo "$PLATFORM" | tr '[:upper:]' '[:lower:]' | \ - grep -oE '[a-z]+' | head -1)" + fi else - echo "$EXEC_NAME: $MCA_JAR: no such file" >&2 + [ -z "$MCA_JAR" ] && MCA_JAR="$MCA_DIR/$MCA_PLATFORM.jar" + if [ ! -e "$MCA_JAR" ]; then + echo "$EXEC_NAME: $MCA_JAR: no such file" >&2 + exit 2 + fi + fi + + [ -n "$MCA_JVM_FLAGS" ] && MCA_JVM_FLAGS="$MCA_JVM_FLAGS " + MCA_JVM_FLAGS="$MCA_JVM_FLAGS-Dfile.encoding=UTF-8 \ +-Djava.awt.headless=true" + + case "$MCA_PLATFORM" in + bungee) + ;; + waterfall|velocity) + [ "$MCA_PLATFORM" = "bungee" ] || MCA_JVM_FLAGS="$MCA_JVM_FLAGS \ + -XX:+UseG1GC \ + -XX:G1HeapRegionSize=4M \ + -XX:+UnlockExperimentalVMOptions \ + -XX:+ParallelRefProcEnabled \ + -XX:+AlwaysPreTouch \ + -DIReallyKnowWhatIAmDoingISwear=true" + ;; + minecraft|bukkit|craftbukkit|spigot|paper) + MCA_JVM_FLAGS="$MCA_JVM_FLAGS -Dcom.mojang.eula.agree=true \ + -DIReallyKnowWhatIAmDoingISwear=true" + [ "$MCA_PLATFORM" = "paper" ] && MCA_JVM_FLAGS="$MCA_JVM_FLAGS \ + -XX:+UseG1GC \ + -XX:+ParallelRefProcEnabled \ + -XX:MaxGCPauseMillis=200 \ + -XX:+UnlockExperimentalVMOptions \ + -XX:+DisableExplicitGC \ + -XX:+AlwaysPreTouch \ + -XX:G1NewSizePercent=30 \ + -XX:G1MaxNewSizePercent=40 \ + -XX:G1HeapRegionSize=8M \ + -XX:G1ReservePercent=20 \ + -XX:G1HeapWastePercent=5 \ + -XX:G1MixedGCCountTarget=4 \ + -XX:InitiatingHeapOccupancyPercent=15 \ + -XX:G1MixedGCLiveThresholdPercent=90 \ + -XX:G1RSetUpdatingPauseTimePercent=5 \ + -XX:SurvivorRatio=32 \ + -XX:+PerfDisableSharedMem \ + -XX:MaxTenuringThreshold=1 \ + -Dusing.aikars.flags=https://mcflags.emc.gs \ + -Daikars.new.flags=true" + ;; + custom) + ;; + *) + echo "$EXEC_NAME: invalid platform: $MCA_PLATFORM. Valid: bungee, \ + waterfall, velocity, minecraft, bukkit, craftbukkit, spigot, \ + paper, custom" >&2 + exit 2 + ;; + esac + + if [ -n "$MCA_OPT_JAVA_HOME" ] && [ -d "$MCA_OPT_JAVA_HOME/bin" ]; then + PATH="$MCA_OPT_JAVA_HOME/bin:$PATH" + fi + + if ! command -v java > /dev/null; then + echo "$EXEC_NAME: unable to get Java version (is Java installed?)" >&2 exit 2 fi -else - [ -z "$MCA_JAR" ] && MCA_JAR="$MCA_DIR/$PLATFORM.jar" - [ ! -e "$MCA_JAR" ] && { - echo "$EXEC_NAME: $MCA_JAR: no such file" >&2 - exit 2 - } + + [ -n "$MCA_OPT_MAX_MEMORY" ] \ + && MCA_JVM_FLAGS="-Xmx$MCA_OPT_MAX_MEMORY $MCA_JVM_FLAGS" + [ -n "$MCA_OPT_MIN_MEMORY" ] \ + && MCA_JVM_FLAGS="-Xms$MCA_OPT_MIN_MEMORY $MCA_JVM_FLAGS" + + SCREEN_CMD="$(which java) -server $MCA_JVM_FLAGS -jar $MCA_JAR" fi -[ -n "$JVM_FLAGS" ] && JVM_FLAGS="$JVM_FLAGS " -JVM_FLAGS="$JVM_FLAGS-Dfile.encoding=UTF-8 -Djava.awt.headless=true" - -case "$PLATFORM" in - bungee) - ;; - waterfall|velocity) - [ "$PLATFORM" = "bungee" ] || JVM_FLAGS="$JVM_FLAGS -XX:+UseG1GC \ --XX:G1HeapRegionSize=4M \ --XX:+UnlockExperimentalVMOptions \ --XX:+ParallelRefProcEnabled \ --XX:+AlwaysPreTouch \ --DIReallyKnowWhatIAmDoingISwear=true" - ;; - minecraft|bukkit|craftbukkit|spigot|paper) - JVM_FLAGS="$JVM_FLAGS -Dcom.mojang.eula.agree=true \ --DIReallyKnowWhatIAmDoingISwear=true" - [ "$PLATFORM" = "paper" ] && JVM_FLAGS="$JVM_FLAGS -XX:+UseG1GC \ --XX:+ParallelRefProcEnabled \ --XX:MaxGCPauseMillis=200 \ --XX:+UnlockExperimentalVMOptions \ --XX:+DisableExplicitGC \ --XX:+AlwaysPreTouch \ --XX:G1NewSizePercent=30 \ --XX:G1MaxNewSizePercent=40 \ --XX:G1HeapRegionSize=8M \ --XX:G1ReservePercent=20 \ --XX:G1HeapWastePercent=5 \ --XX:G1MixedGCCountTarget=4 \ --XX:InitiatingHeapOccupancyPercent=15 \ --XX:G1MixedGCLiveThresholdPercent=90 \ --XX:G1RSetUpdatingPauseTimePercent=5 \ --XX:SurvivorRatio=32 \ --XX:+PerfDisableSharedMem \ --XX:MaxTenuringThreshold=1 \ --Dusing.aikars.flags=https://mcflags.emc.gs \ --Daikars.new.flags=true" - ;; - custom) - ;; - *) - echo "$EXEC_NAME: invalid platform: $PLATFORM. Valid: bungee, \ - waterfall, velocity, minecraft, bukkit, craftbukkit, spigot, \ - paper, custom" >&2 - exit 2 - ;; -esac - -if [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME/bin" ]; then - PATH="$JAVA_HOME/bin:$PATH" -fi - -if ! command -v java > /dev/null; then - echo "$EXEC_NAME: unable to get Java version (is Java installed?)" >&2 - exit 2 -fi - -[ -n "$MAX_MEMORY" ] && JVM_FLAGS="-Xmx$MAX_MEMORY $JVM_FLAGS" -[ -n "$MIN_MEMORY" ] && JVM_FLAGS="-Xms$MIN_MEMORY $JVM_FLAGS" - -MCA_CMD="$(which java) -server $JVM_FLAGS -jar $MCA_JAR" - if [ "$SKIP_CONFIGURE" -eq 0 ] && [ "$MCA_RC_FILE_READ" -eq 1 ]; then - ENV_LIST="$(cut -d= -f1 < "$MCA_RC_FILE" | sed 's/^/$/g'))" + ENV_LIST="$(env | grep ^MCA_ | cut -d= -f1 | sed 's/^/$/g')" FILE_LIST="$(find . -name '*.in' -type f)" [ -z "$FILE_LIST" ] || echo "$FILE_LIST" | while read -r line; do @@ -220,11 +266,14 @@ if [ "$SKIP_CONFIGURE" -eq 0 ] && [ "$MCA_RC_FILE_READ" -eq 1 ]; then done fi -# papermc prints uncolored text if the COLORTERM variable is set to -# `truecolor`. -export COLORTERM= +if [ "$CONFIGURE_ONLY" -eq 0 ]; then + # papermc prints uncolored text if the COLORTERM variable is set to + # `truecolor`. + export COLORTERM= -# we don't quote $MCA_CMD because screen treats arguments after the second one -# as a command. -# shellcheck disable=SC2086 -exec screen -c "$MCA_SCREENRC_FILE" "-$SCREEN_OPTS"S "$MCA_NAME" -- $MCA_CMD + # we don't quote $SCREEN_CMD because screen treats arguments after the + # second one as a command. + # shellcheck disable=SC2086 + exec screen -c "$SCREEN_RC_FILE" "-$SCREEN_OPTS"S "$SCREEN_NAME" \ + -- $SCREEN_CMD +fi