#!/bin/bash SC_VERSION=1.4.0 SC_CODENAME="seahorse" PORT=5566 SETUP_FILE=".setup_complete" COLOR_RESET="\033[0m" COLOR_GREEN="\033[1;32m" COLOR_RED="\033[1;31m" COLOR_YELLOW="\033[1;33m" COLOR_BLUE="\033[1;34m" COLOR_CYAN="\033[1;36m" DISTRO=$(grep '^NAME=' /etc/os-release | cut -d '=' -f2 | tr -d '"') function command_exists() { command -v "$1" &> /dev/null } function install_tools() { # Perform updates if [ "$DISTRO" == "Ubuntu" ]; then echo -e "${COLOR_BLUE}Updating package lists...${COLOR_RESET}" # shellcheck disable=SC2024 sudo apt-get update >> install.log echo -e "${COLOR_GREEN}Done.${COLOR_RESET}\n" elif [ "$DISTRO" == "Arch Linux" ]; then echo -e "${COLOR_BLUE}Updating package lists...${COLOR_RESET}" # shellcheck disable=SC2024 sudo pacman -Sy >> install.log echo -e "${COLOR_GREEN}Done.${COLOR_RESET}\n" fi # Check for curl, and install if not found if ! command_exists curl; then echo -e "${COLOR_RED}curl is not installed. Installing now...${COLOR_RESET}" if [ "$DISTRO" == "Ubuntu" ]; then sudo apt-get install curl -y >> install.log elif [ "$DISTRO" == "Arch Linux" ]; then sudo pacman -S --noconfirm curl >> install.log fi echo -e "\n${COLOR_GREEN}curl installed successfully.${COLOR_RESET}\n" else echo -e "${COLOR_GREEN}curl is installed.${COLOR_RESET}" fi # Check for NodeJS, and install if not found if ! command_exists node; then echo -e "${COLOR_RED}NodeJS is not installed. Installing now...${COLOR_RESET}" curl -o .install.sh https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh >> install.log chmod +x .install.sh bash .install.sh >> install.log rm .install.sh # cleanup # shellcheck disable=SC2155 export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" nvm install 23 >> install.log echo -e "\n${COLOR_GREEN}NodeJS installed successfully.${COLOR_RESET}\n" else echo -e "${COLOR_GREEN}NodeJS is installed. Version: $(node -v)${COLOR_RESET}" fi # Check for Netcat, and install if not found if ! command_exists nc; then echo -e "${COLOR_RED}Netcat is not installed. Installing now...${COLOR_RESET}" if [ "$DISTRO" == "Ubuntu" ]; then sudo apt-get install netcat-traditional -y >> install.log elif [ "$DISTRO" == "Arch Linux" ]; then sudo pacman -S --noconfirm netcat >> install.log fi echo -e "\n${COLOR_GREEN}Netcat installed successfully.${COLOR_RESET}\n" else echo -e "${COLOR_GREEN}Netcat is installed.${COLOR_RESET}" fi # Check for lsof, and install if not found if ! command_exists lsof && [ "$DISTRO" == "Arch Linux" ]; then echo -e "${COLOR_RED}lsof is not installed. Installing now...${COLOR_RESET}" sudo pacman -S --noconfirm lsof >> install.log echo -e "\n${COLOR_GREEN}lsof installed successfully.${COLOR_RESET}\n" else echo -e "${COLOR_GREEN}lsof is installed.${COLOR_RESET}" fi # Check for NPM, and install if not found if ! command_exists npm; then echo -e "${COLOR_RED}NPM is not installed. Installing now...${COLOR_RESET}" if [ "$DISTRO" == "Ubuntu" ]; then sudo apt-get install npm -y >> install.log elif [ "$DISTRO" == "Arch Linux" ]; then sudo pacman -S --noconfirm npm >> install.log fi if [ ! -f "config.json" ]; then echo -e "${COLOR_BLUE}Copying config file...${COLOR_RESET}" if [ ! -f "config.json.example" ]; then echo "${COLOR_RED}[!] Couldn't find example config file${COLOR_RESET}" else cp config.json.example config.json fi else echo -e "${COLOR_GREEN}config file already exists, skipping.${COLOR_RESET}" fi echo -e "${COLOR_BLUE}Installing NPM deps...${COLOR_RESET}" npm install >> install.log echo -e "\n${COLOR_GREEN}NPM installed successfully.${COLOR_RESET}\n" touch $SETUP_FILE else echo -e "${COLOR_GREEN}NPM is installed. Version: $(npm -v)${COLOR_RESET}" touch $SETUP_FILE fi } # Show help message function show_help() { echo -e "${COLOR_GREEN}manage version:${COLOR_RESET} ${COLOR_BLUE}${SC_VERSION} ${SC_CODENAME}${COLOR_RESET}" echo -e "${COLOR_BLUE}Usage:${COLOR_RESET} ./manage [command]\n" echo -e "${COLOR_YELLOW}Commands:${COLOR_RESET}" echo -e " ${COLOR_CYAN}help, -h, --help${COLOR_RESET} Shows this help message." echo -e " ${COLOR_CYAN}up${COLOR_RESET} Builds the project and starts the server." echo -e " ${COLOR_CYAN}down${COLOR_RESET} Stops the server." echo -e " ${COLOR_CYAN}restart${COLOR_RESET} Restarts the server." echo -e " ${COLOR_CYAN}status, -s, --status${COLOR_RESET} Checks if the server is running.\n" } # Check if essential directories exist (mainly for server startup/shutdown), and create them if they don't already exist function check_dirs() { local action=$1 local created_count=0 local deleted_count=0 if [ "$action" == "create" ]; then for dir in "./public" "./public/js" "./public/css" "./public/pgp" "./src" "./src/css" "./src/img" "./src/js" "./src/pgp"; do if [ ! -d "$dir" ]; then echo -e "${COLOR_BLUE}Creating $dir...${COLOR_RESET}" mkdir -p "$dir" created_count=$((created_count + 1)) fi done if [ "$created_count" -gt 0 ]; then echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" else echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi elif [ "$action" == "delete" ]; then if [ -d "./public" ]; then echo -e "${COLOR_BLUE}Deleting public directory...${COLOR_RESET}" rm -rf "./public" deleted_count=$((deleted_count + 1)) fi if [ "$deleted_count" -gt 0 ]; then echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" else echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi else echo -e "${COLOR_RED}Invalid action: $action. Use 'create' or 'delete'.${COLOR_RESET}" fi } # Handles restarting of server function restart_server() { check_setup if [ -d './public' ]; then echo -e "${COLOR_BLUE}Deleting public directories...${COLOR_RESET}" check_dirs "delete" fi if [ -f './src/css/main.css' ]; then echo -e "${COLOR_BLUE}Deleting old Tailwind CSS...${COLOR_RESET}" rm ./src/css/main.css echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi PIDS=$(lsof -t -i:$PORT) if [ -n "$PIDS" ]; then echo -e "${COLOR_BLUE}Stopping server...${COLOR_RESET}" for PID in $PIDS; do kill "$PID" || echo -e "${COLOR_RED}Failed to kill PID: $PID${COLOR_RESET}" done echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" else echo -e "${COLOR_YELLOW}No process found on port $PORT.${COLOR_RESET}" fi echo -e "${COLOR_BLUE}Creating public directories...${COLOR_RESET}" check_dirs "create" echo -e "${COLOR_BLUE}Building project...${COLOR_RESET}" if ! npm run build > node.log 2>&1; then echo -e "${COLOR_RED}Build failed. Please check for errors above.${COLOR_RESET}" exit 1 else echo -e "${COLOR_GREEN}Done!${COLOR_RESET}" fi if [ -f './public/css/base.css' ]; then echo -e "${COLOR_BLUE}Cleaning up base Tailwind CSS file...${COLOR_RESET}" rm ./public/css/base.css echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi if [ -f './node.log' ]; then echo -e "${COLOR_BLUE}Deleting node log...${COLOR_RESET}" rm ./node.log echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi echo -e "${COLOR_BLUE}Starting server...${COLOR_RESET}" npm start > node.log 2>&1 & MAX_RETRIES=10 RETRY_INTERVAL=1 for ((i=1; i<=MAX_RETRIES; i++)); do PIDS=$(lsof -t -i:$PORT) if [ -n "$PIDS" ]; then echo -e "${COLOR_GREEN}\nDone. Server up and running on port $PORT!\n${COLOR_RESET}" break else echo -e "${COLOR_YELLOW}Waiting for server to start on port $PORT... Attempt $i/${MAX_RETRIES}${COLOR_RESET}" sleep $RETRY_INTERVAL fi done if [ -z "$PIDS" ]; then echo -e "${COLOR_RED}Failed to start the server on port $PORT after $MAX_RETRIES attempts.${COLOR_RESET}" fi if [ -z "$PIDS" ]; then echo -e "${COLOR_RED}Something went wrong... Check node.log for more details${COLOR_RESET} (no process on port)" fi } # Handles starting of server function start_server() { check_setup PID=$(lsof -t -i:$PORT) if [ -n "$PID" ]; then echo -e "${COLOR_GREEN}Server already running on port $PORT, opting to restart.\n${COLOR_RESET}" restart_server return fi echo -e "${COLOR_BLUE}Creating public directories...${COLOR_RESET}" check_dirs "create" if [ -f './src/css/main.css' ]; then echo -e "${COLOR_BLUE}Deleting old Tailwind CSS...${COLOR_RESET}" rm ./src/css/main.css echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi if [ -f './node.log' ]; then echo -e "${COLOR_BLUE}Deleting node log...${COLOR_RESET}" rm ./node.log echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi echo -e "${COLOR_BLUE}Building project...${COLOR_RESET}" if ! npm run build > node.log 2>&1; then echo -e "${COLOR_RED}Build failed. Please check for errors above.${COLOR_RESET}" exit 1 else echo -e "${COLOR_GREEN}Done!${COLOR_RESET}" fi if [ -f './public/css/base.css' ]; then echo -e "${COLOR_BLUE}Cleaning up base Tailwind CSS file...${COLOR_RESET}" rm ./public/css/base.css echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi echo -e "${COLOR_BLUE}Starting server...${COLOR_RESET}" npm start > node.log 2>&1 & MAX_RETRIES=10 RETRY_INTERVAL=1 for ((i=1; i<=MAX_RETRIES; i++)); do PIDS=$(lsof -t -i:$PORT) if [ -n "$PIDS" ]; then echo -e "${COLOR_GREEN}\nDone. Server up and running on port $PORT!\n${COLOR_RESET}" break else echo -e "${COLOR_YELLOW}Waiting for server to start on port $PORT... Attempt $i/${MAX_RETRIES}${COLOR_RESET}" sleep $RETRY_INTERVAL fi done if [ -z "$PIDS" ]; then echo -e "${COLOR_RED}Failed to start the server on port $PORT after $MAX_RETRIES attempts.${COLOR_RESET}" fi if [ -z "$PIDS" ]; then echo -e "${COLOR_RED}Something went wrong... Check node.log for more details${COLOR_RESET} (no process on port)" fi } # Handles stopping of server function stop_server() { check_setup PID=$(lsof -t -i:$PORT) if [ -d './public' ]; then echo -e "${COLOR_BLUE}Deleting public directories...${COLOR_RESET}" check_dirs "delete" fi if [ -f './src/css/main.css' ]; then echo -e "${COLOR_BLUE}Deleting Tailwind CSS...${COLOR_RESET}" rm ./src/css/main.css echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi if [ -f './node.log' ]; then echo -e "${COLOR_BLUE}Deleting node log...${COLOR_RESET}" rm ./node.log echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" fi PIDS=$(lsof -t -i:$PORT) if [ -n "$PIDS" ]; then echo -e "${COLOR_BLUE}Stopping server...${COLOR_RESET}" for PID in $PIDS; do kill "$PID" || echo -e "${COLOR_RED}Failed to kill PID: $PID${COLOR_RESET}" done echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" else echo -e "${COLOR_YELLOW}No process found on port $PORT.${COLOR_RESET}" fi } # Checks if server is running function check_status() { check_setup PID=$(lsof -t -i:$PORT) if [ -n "$PID" ]; then echo -e "${COLOR_GREEN}Server running with PID: $PID${COLOR_RESET}" else echo -e "${COLOR_RED}Server not running.${COLOR_RESET}" fi } # Master setup function/process function setup() { if [ "$DISTRO" != "Ubuntu" ] && [ "$DISTRO" != "Arch Linux" ]; then echo -e "${COLOR_RED}This script is only supported on Ubuntu and Arch Linux${COLOR_RESET}" exit 1 fi clear echo -e "${COLOR_BLUE}Welcome to the aidxnFUN 'manage' script setup!\n${COLOR_RESET}${COLOR_CYAN}You are running manage v${SC_VERSION} (${SC_CODENAME})${COLOR_RESET}\n" echo -e "${COLOR_GREEN}A custom script built by ihatenodejs${COLOR_RESET}" echo -e "${COLOR_YELLOW}and presented by forkers like you...${COLOR_RESET}" echo -e "\nPress any key to continue..." read -n 1 -s -r -p "" clear echo -e "${COLOR_BLUE}This script requires Node.js, NPM, curl, lsof, and Netcat to be installed on your system.${COLOR_RESET}" echo -e "${COLOR_BLUE}It will attempt to install all of the required dependencies, although this might not work every time.${COLOR_RESET}" echo -e "${COLOR_YELLOW}You may need to enter your sudo password.${COLOR_RESET}" echo -e "\nPress any key to continue with tool installation..." read -n 1 -s -r -p "" clear # Execute install tool script install_tools # Install NPM dependencies echo -e "\n${COLOR_BLUE}Installing NPM dependencies...${COLOR_RESET}" npm install >> install.log echo -e "${COLOR_GREEN}Done.${COLOR_RESET}" echo -e "\n\n${COLOR_GREEN}Dependency installation complete!${COLOR_RESET}" echo -e "${COLOR_BLUE}You can view the complete log of the installation process in the install.log file${COLOR_RESET}" echo -e "\nPress [ENTER] to continue to the next step." read -n 1 -s -r -p "" clear echo -e "${COLOR_GREEN}Now, take a look at the commands you can use with this script:${COLOR_RESET}\n" # Show the user help message show_help echo -e "\nPress any key to continue to the final step..." read -n 1 -s -r -p "" clear echo -e "${COLOR_BLUE}Now, you may start the server with this command:${COLOR_RESET}" echo -e "${COLOR_GREEN}./manage up${COLOR_RESET}\n" echo -e "\n${COLOR_BLUE}If you need help, or to get info about other commands, simply use:${COLOR_RESET}" echo -e "${COLOR_GREEN}./manage help${COLOR_RESET}" echo -e "\nPress any key to complete the setup and exit..." read -n 1 -s -r -p "" clear echo -e "${COLOR_GREEN}Thank you for using manage ${SC_VERSION} ${SC_CODENAME}!${COLOR_RESET}\n" exit 0 } function check_setup() { # Check if setup file exists if [ ! -f "$SETUP_FILE" ]; then setup fi } # Handles user commands case $1 in up) check_setup start_server ;; down) check_setup stop_server ;; restart) check_setup restart_server ;; setup) check_setup ;; -h|--help|help) check_setup show_help ;; -s|--status|status) check_setup check_status ;; *) check_setup echo -e "${COLOR_RED}Invalid command: $1\n${COLOR_RESET}" show_help ;; esac