#!/usr/bin/env bash DIR=$(pwd) # Function to display a progress bar progress_bar() { local PROG_BAR='####################' local BLANK_BAR=' ' local PROGRESS=$1 printf "\r[%.*s%.*s] %d%%" $PROGRESS "$PROG_BAR" $((20-PROGRESS)) "$BLANK_BAR" $((PROGRESS*5)) } # Function to find a library find_library() { SEARCH=$1 LIBRARY=$(ldconfig -p | grep -F $SEARCH -m 1 | awk '{print $1}') if [ -z "$LIBRARY" ]; then return 1 fi printf '%s' "$LIBRARY" } ROOT='' echo "Checking for superuser privileges..." if [ "$(whoami)" != "root" ]; then if ! command -v sudo 2>&1 >/dev/null; then echo "Not running as root and sudo is not available." exit 1 fi if ! sudo -v; then echo "Failed to acquire superuser privileges." exit 1 fi ROOT='sudo' fi # Refresh system library cache $ROOT ldconfig declare -a PACKAGES_DEBIAN=( 'git' 'cmake' 'ninja-build' 'clang' 'systemtap-sdt-dev' 'libbsd-dev' 'linux-libc-dev' 'curl' 'tar' 'grep' 'mawk' 'patchelf' '^libgnustep-base1\.[0-9]*$' 'libobjc4' '^libgnutls[0-9]*$' '^libgcrypt[0-9]*$' 'libxml2' '^libffi[0-9]*$' '^libnsl[0-9]*$' 'zlib1g' '^libicu[0-9]*$' 'libicu-dev' 'libstdc++6' 'libgcc-s1' ) declare -a PACKAGES_ARCH=( 'base-devel' 'git' 'cmake' 'ninja' 'clang' 'systemtap' 'libbsd' 'curl' 'tar' 'grep' 'gawk' 'patchelf' 'gnustep-base' 'gcc-libs' 'gnutls' 'libgcrypt' 'libxml2' 'libffi' 'libnsl' 'zlib' 'icu' 'libdispatch' ) build_libdispatch() { if [ -d "${DIR}/swift-corelibs-libdispatch/build" ]; then rm -rf 'swift-corelibs-libdispatch' fi git clone --depth 1 'https://github.com/swiftlang/swift-corelibs-libdispatch.git' "${DIR}/swift-corelibs-libdispatch" || exit 1 mkdir -p "${DIR}/swift-corelibs-libdispatch/build" || exit 1 cd "${DIR}/swift-corelibs-libdispatch/build" || exit 1 cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .. || exit 1 ninja "-j$(nproc)" || exit 1 $ROOT ninja install || exit 1 cd "${DIR}" || exit 1 # Refresh system library cache $ROOT ldconfig } install_packages_debian() { echo "Installing packages for Debian/Ubuntu..." $ROOT apt-get update || exit 1 $ROOT apt-get install -y "${PACKAGES_DEBIAN[@]}" || exit 1 if ! find_library 'libdispatch.so'; then echo "libdispatch.so not found, building libdispatch..." build_libdispatch fi } install_packages_arch() { echo "Installing packages for Arch Linux..." $ROOT pacman -Sy --noconfirm --needed "${PACKAGES_ARCH[@]}" || exit 1 } install_packages() { if [ ! -f /etc/os-release ]; then echo "Could not detect the operating system because /etc/os-release does not exist." exit 1 fi source /etc/os-release case $ID in debian|ubuntu|pop) install_packages_debian ;; arch) install_packages_arch ;; *) echo "Unsupported operating system: $ID" exit 1 ;; esac } install_packages # Download the file with progress bar echo "Downloading blockheads_server171.tar.gz..." curl -#L https://majicdave.com/share/blockheads_server171.tar.gz --insecure -o blockheads_server171.tar.gz if [ $? -ne 0 ]; then echo "Failed to download from majicdave.com, trying archive.org..." curl -#L https://archive.org/download/BHSv171/blockheads_server171.tar.gz -o blockheads_server171.tar.gz if [ $? -ne 0 ]; then echo "Failed to download from both sources." exit 1 fi fi # Extract the file echo "Extracting blockheads_server171.tar.gz..." tar xzvf blockheads_server171.tar.gz chmod +x blockheads_server171 # Unlink tarball rm -v blockheads_server171.tar.gz # Define variables FILE="blockheads_server171" declare -A LIBS=( ["libgnustep-base.so.1.24"]="$(find_library 'libgnustep-base.so')" ["libobjc.so.4.6"]="$(find_library 'libobjc.so')" ["libgnutls.so.26"]="$(find_library 'libgnutls.so')" ["libgcrypt.so.11"]="$(find_library 'libgcrypt.so')" ["libxml2.so.2"]="$(find_library 'libxml2.so')" ["libffi.so.6"]="$(find_library 'libffi.so')" ["libnsl.so.1"]="$(find_library 'libnsl.so')" ["librt.so.1"]="$(find_library 'librt.so')" ["libdl.so.2"]="$(find_library 'libdl.so')" ["libpthread.so.0"]="$(find_library 'libpthread.so')" ["libz.so.1"]="$(find_library 'libz.so')" ["libicui18n.so.48"]="$(find_library 'libicui18n.so')" ["libicuuc.so.48"]="$(find_library 'libicuuc.so')" ["libicudata.so.48"]="$(find_library 'libicudata.so')" ["libdispatch.so"]="$(find_library 'libdispatch.so')" ["libm.so.6"]="$(find_library 'libm.so')" ["libstdc++.so.6"]="$(find_library 'libstdc++.so')" ["libgcc_s.so.1"]="$(find_library 'libgcc_s.so')" ["libc.so.6"]="$(find_library 'libc.so')" ) # Replace needed libraries with progress feedback TOTAL_LIBS=${#LIBS[@]} COUNT=0 for LIB in "${!LIBS[@]}"; do if [ -z "${LIBS[$LIB]}" ]; then echo "Failed to locate up-to-date matching library for $LIB" exit 1 fi COUNT=$((COUNT+1)) PERCENTAGE=$((COUNT * 100 / TOTAL_LIBS / 5)) echo -n "Patching $LIB -> ${LIBS[$LIB]} " progress_bar $PERCENTAGE patchelf --replace-needed $LIB ${LIBS[$LIB]} $FILE || { echo "Failed to patch the BHS for $LIB"; exit 1; } done echo -e "\nThe BHS has been patched successfully!" # Create run.sh with the specified content cat <<EOF > run.sh #!/bin/bash world_id="83cad395edb8d0f1912fec89508d8a1d" server_port=15151 # Function to safely shut down the server function shutdown { echo "Shutting down the server..." | tee -a bhs-server-log.txt pkill -SIGINT -f './blockheads_server171 -o' # Command to stop the server exit 0 } # Trap to handle script termination and execute the shutdown function trap shutdown SIGTERM SIGINT while true; do ./blockheads_server171 --no-exit -o "$world_id" -p "$server_port" 2>&1 | tee -a bhs-server-log.txt echo "Server restarted at $(date)" | tee -a bhs-server-log.txt sleep 1 done EOF # Make run.sh executable chmod +x run.sh echo -e "\nThe run.sh script has been created and made executable." # Refresh system library cache $ROOT ldconfig # Execute the help command ./blockheads_server171 --help