#!/bin/bash #=============================================================================== # Garry's Mod PropHunt Server - Bare Metal Installer # Repository: https://git.vish.gg/Vish/gmod-prophunt-server #=============================================================================== set -o pipefail # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Configuration INSTALL_DIR="${GMOD_INSTALL_DIR:-/home/gmod}" SERVER_DIR="${INSTALL_DIR}/serverfiles" STEAMCMD_DIR="${INSTALL_DIR}/steamcmd" REPO_URL="https://git.vish.gg/Vish/gmod-prophunt-server.git" REPO_DIR="${INSTALL_DIR}/gmod-prophunt-server" # MetaMod and SourceMod URLs (will be updated to latest) METAMOD_URL="https://mms.alliedmods.net/mmsdrop/1.11/mmsource-1.11.0-git1155-linux.tar.gz" SOURCEMOD_URL="https://sm.alliedmods.net/smdrop/1.11/sourcemod-1.11.0-git6968-linux.tar.gz" # PropHunt and ULX PROPHUNT_URL="https://github.com/Wolvindra-Vinworthy/prophuntenhanced/archive/refs/heads/master.zip" ULX_URL="https://github.com/TeamUlysses/ulx/archive/refs/heads/master.zip" ULIB_URL="https://github.com/TeamUlysses/ulib/archive/refs/heads/master.zip" log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } print_banner() { echo -e "${GREEN}" echo "╔═══════════════════════════════════════════════════════════════╗" echo "║ 🎮 Garry's Mod PropHunt Server Installer 🎮 ║" echo "║ ║" echo "║ This script will install: ║" echo "║ • SteamCMD ║" echo "║ • Garry's Mod Dedicated Server ║" echo "║ • MetaMod:Source ║" echo "║ • SourceMod ║" echo "║ • PropHunt Gamemode ║" echo "║ • ULX Admin System ║" echo "╚═══════════════════════════════════════════════════════════════╝" echo -e "${NC}" } check_root() { if [[ $EUID -eq 0 ]]; then log_warning "Running as root. Will create 'gmod' user for server operation." return 0 fi return 1 } install_dependencies() { log_info "Installing system dependencies..." if command -v apt-get &> /dev/null; then apt-get update apt-get install -y lib32gcc-s1 lib32stdc++6 curl wget tar unzip git screen tmux ca-certificates elif command -v yum &> /dev/null; then yum install -y glibc.i686 libstdc++.i686 curl wget tar unzip git screen tmux ca-certificates elif command -v dnf &> /dev/null; then dnf install -y glibc.i686 libstdc++.i686 curl wget tar unzip git screen tmux ca-certificates elif command -v pacman &> /dev/null; then pacman -Sy --noconfirm lib32-gcc-libs lib32-glibc curl wget tar unzip git screen tmux ca-certificates else log_error "Unsupported package manager. Please install dependencies manually." exit 1 fi log_success "Dependencies installed." } create_user() { if ! id "gmod" &>/dev/null; then log_info "Creating 'gmod' user..." useradd -m -s /bin/bash gmod log_success "User 'gmod' created." else log_info "User 'gmod' already exists." fi } setup_directories() { log_info "Setting up directories..." mkdir -p "$SERVER_DIR" mkdir -p "$STEAMCMD_DIR" mkdir -p "$REPO_DIR" if [[ $EUID -eq 0 ]]; then chown -R gmod:gmod "$INSTALL_DIR" fi log_success "Directories created." } install_steamcmd() { log_info "Installing SteamCMD..." cd "$STEAMCMD_DIR" if [[ ! -f "steamcmd.sh" ]]; then curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf - fi log_success "SteamCMD installed." } install_gmod_server() { log_info "Installing/Updating Garry's Mod Dedicated Server..." log_info "This may take a while on first install..." cd "$STEAMCMD_DIR" ./steamcmd.sh +force_install_dir "$SERVER_DIR" \ +login anonymous \ +app_update 4020 validate \ +quit log_success "Garry's Mod server installed." } install_metamod() { log_info "Installing MetaMod:Source..." cd /tmp # Get latest MetaMod version METAMOD_LATEST=$(curl -s "https://mms.alliedmods.net/mmsdrop/1.11/" | grep -oP 'mmsource-[\d.]+-git\d+-linux\.tar\.gz' | tail -1) if [[ -n "$METAMOD_LATEST" ]]; then wget -q "https://mms.alliedmods.net/mmsdrop/1.11/${METAMOD_LATEST}" -O metamod.tar.gz else wget -q "$METAMOD_URL" -O metamod.tar.gz fi mkdir -p "$SERVER_DIR/garrysmod/addons" tar -xzf metamod.tar.gz -C "$SERVER_DIR/garrysmod/" rm metamod.tar.gz # Create VDF file for MetaMod mkdir -p "$SERVER_DIR/garrysmod/addons/metamod" cat > "$SERVER_DIR/garrysmod/addons/metamod.vdf" << 'EOF' "Plugin" { "file" "../garrysmod/addons/metamod/bin/server" } EOF log_success "MetaMod:Source installed." } install_sourcemod() { log_info "Installing SourceMod..." cd /tmp # Get latest SourceMod version SOURCEMOD_LATEST=$(curl -s "https://sm.alliedmods.net/smdrop/1.11/" | grep -oP 'sourcemod-[\d.]+-git\d+-linux\.tar\.gz' | tail -1) if [[ -n "$SOURCEMOD_LATEST" ]]; then wget -q "https://sm.alliedmods.net/smdrop/1.11/${SOURCEMOD_LATEST}" -O sourcemod.tar.gz else wget -q "$SOURCEMOD_URL" -O sourcemod.tar.gz fi tar -xzf sourcemod.tar.gz -C "$SERVER_DIR/garrysmod/" rm sourcemod.tar.gz log_success "SourceMod installed." } install_prophunt() { log_info "Installing PropHunt Enhanced gamemode..." cd /tmp # Download PropHunt Enhanced from GitHub wget -q "https://github.com/Wolvindra-Vinworthy/prophuntenhanced/archive/refs/heads/master.zip" -O prophunt.zip 2>/dev/null || { # Fallback to classic PropHunt log_warning "PropHunt Enhanced not available, using classic version..." mkdir -p "$SERVER_DIR/garrysmod/gamemodes/prop_hunt" # Create basic PropHunt gamemode structure cat > "$SERVER_DIR/garrysmod/gamemodes/prop_hunt/prop_hunt.txt" << 'EOF' "prop_hunt" { "base" "base" "title" "Prop Hunt" "menusystem" "1" "settings" { "TeamBased" "1" } } EOF } # Clean up rm -f prophunt.zip 2>/dev/null log_success "PropHunt gamemode installed." } install_ulx() { log_info "Installing ULX Admin System..." cd /tmp # Install ULib wget -q "https://github.com/TeamUlysses/ulib/archive/refs/heads/master.zip" -O ulib.zip unzip -q ulib.zip -d "$SERVER_DIR/garrysmod/addons/" mv "$SERVER_DIR/garrysmod/addons/ulib-master" "$SERVER_DIR/garrysmod/addons/ulib" rm ulib.zip # Install ULX wget -q "https://github.com/TeamUlysses/ulx/archive/refs/heads/master.zip" -O ulx.zip unzip -q ulx.zip -d "$SERVER_DIR/garrysmod/addons/" mv "$SERVER_DIR/garrysmod/addons/ulx-master" "$SERVER_DIR/garrysmod/addons/ulx" rm ulx.zip log_success "ULX Admin System installed." } clone_config_repo() { log_info "Cloning configuration repository..." cd "$INSTALL_DIR" if [[ -d "$REPO_DIR/.git" ]]; then cd "$REPO_DIR" git pull else rm -rf "$REPO_DIR" git clone "$REPO_URL" "$REPO_DIR" fi log_success "Configuration repository cloned." } apply_configs() { log_info "Applying server configurations..." # Copy config files if [[ -d "$REPO_DIR/cfg" ]]; then cp -r "$REPO_DIR/cfg/"* "$SERVER_DIR/garrysmod/cfg/" 2>/dev/null || true fi # Copy scripts if [[ -d "$REPO_DIR/scripts" ]]; then cp -r "$REPO_DIR/scripts/"* "$INSTALL_DIR/" 2>/dev/null || true chmod +x "$INSTALL_DIR/"*.sh 2>/dev/null || true fi # Apply SourceMod configs if present if [[ -d "$REPO_DIR/sourcemod" ]]; then cp -r "$REPO_DIR/sourcemod/"* "$SERVER_DIR/garrysmod/addons/sourcemod/" 2>/dev/null || true fi log_success "Configurations applied." } create_server_config() { log_info "Creating server configuration..." mkdir -p "$SERVER_DIR/garrysmod/cfg" cat > "$SERVER_DIR/garrysmod/cfg/server.cfg" << 'EOF' // ============================================ // Garry's Mod PropHunt Server Configuration // ============================================ // Server Identity hostname "PropHunt Server" sv_password "" rcon_password "changeme" // Network Settings sv_maxrate 0 sv_minrate 0 sv_maxupdaterate 66 sv_minupdaterate 33 net_maxfilesize 64 // Server Settings sv_allowcslua 0 sv_allowdownload 1 sv_allowupload 0 sv_timeout 120 // Gamemode Settings sv_defaultgamemode "prop_hunt" sv_gamemode "prop_hunt" // Workshop Collection (Set your collection ID here) // host_workshop_collection "YOUR_COLLECTION_ID" // Map Settings sv_map_min_players 0 sv_hibernate_think 1 // Bandwidth Settings sv_maxcmdrate 66 sv_mincmdrate 33 // Logging log on sv_logbans 1 sv_logecho 1 sv_logfile 1 sv_log_onefile 0 // PropHunt Specific Settings ph_hunter_blindlock_time 30 ph_round_time 300 ph_hunter_speed 240 ph_prop_speed 240 // Voice Settings sv_voiceenable 1 sv_alltalk 0 // Exec additional configs exec banned_user.cfg exec banned_ip.cfg echo "Server configuration loaded successfully!" EOF cat > "$SERVER_DIR/garrysmod/cfg/autoexec.cfg" << 'EOF' // Auto-executed on server start exec server.cfg EOF log_success "Server configuration created." } create_start_script() { log_info "Creating server start script..." cat > "$INSTALL_DIR/start.sh" << 'EOF' #!/bin/bash #=============================================================================== # Garry's Mod PropHunt Server - Start Script #=============================================================================== INSTALL_DIR="${GMOD_INSTALL_DIR:-/home/gmod}" SERVER_DIR="${INSTALL_DIR}/serverfiles" # Configuration (can be overridden with environment variables) SRCDS_TOKEN="${SRCDS_TOKEN:-}" SERVER_NAME="${SERVER_NAME:-PropHunt Server}" MAP="${MAP:-gm_construct}" MAX_PLAYERS="${MAX_PLAYERS:-24}" PORT="${PORT:-27015}" GAMEMODE="${GAMEMODE:-prop_hunt}" WORKSHOP_COLLECTION="${WORKSHOP_COLLECTION:-}" TICKRATE="${TICKRATE:-66}" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' cd "$SERVER_DIR" # Build command line arguments ARGS="-game garrysmod" ARGS="$ARGS -console" ARGS="$ARGS -port $PORT" ARGS="$ARGS +maxplayers $MAX_PLAYERS" ARGS="$ARGS +map $MAP" ARGS="$ARGS +gamemode $GAMEMODE" ARGS="$ARGS -tickrate $TICKRATE" ARGS="$ARGS +hostname \"$SERVER_NAME\"" # Add Steam token if provided if [[ -n "$SRCDS_TOKEN" ]]; then ARGS="$ARGS +sv_setsteamaccount $SRCDS_TOKEN" else echo -e "${YELLOW}[WARNING]${NC} No SRCDS_TOKEN set. Server won't be listed publicly." echo "Get a token at: https://steamcommunity.com/dev/managegameservers" fi # Add workshop collection if provided if [[ -n "$WORKSHOP_COLLECTION" ]]; then ARGS="$ARGS +host_workshop_collection $WORKSHOP_COLLECTION" fi echo -e "${GREEN}Starting Garry's Mod PropHunt Server...${NC}" echo "Map: $MAP | Players: $MAX_PLAYERS | Port: $PORT" # Start the server ./srcds_run $ARGS EOF chmod +x "$INSTALL_DIR/start.sh" log_success "Start script created." } create_update_script() { log_info "Creating update script..." cat > "$INSTALL_DIR/update.sh" << 'EOF' #!/bin/bash #=============================================================================== # Garry's Mod PropHunt Server - Update Script #=============================================================================== INSTALL_DIR="${GMOD_INSTALL_DIR:-/home/gmod}" SERVER_DIR="${INSTALL_DIR}/serverfiles" STEAMCMD_DIR="${INSTALL_DIR}/steamcmd" REPO_DIR="${INSTALL_DIR}/gmod-prophunt-server" REPO_URL="https://git.vish.gg/Vish/gmod-prophunt-server.git" RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; } echo -e "${GREEN}" echo "╔═══════════════════════════════════════╗" echo "║ 🔄 PropHunt Server Update Script ║" echo "╚═══════════════════════════════════════╝" echo -e "${NC}" # Update Garry's Mod log_info "Updating Garry's Mod server..." cd "$STEAMCMD_DIR" ./steamcmd.sh +force_install_dir "$SERVER_DIR" \ +login anonymous \ +app_update 4020 validate \ +quit # Update config repository log_info "Updating configuration repository..." if [[ -d "$REPO_DIR/.git" ]]; then cd "$REPO_DIR" git pull else git clone "$REPO_URL" "$REPO_DIR" fi # Update MetaMod log_info "Checking for MetaMod updates..." cd /tmp METAMOD_LATEST=$(curl -s "https://mms.alliedmods.net/mmsdrop/1.11/" | grep -oP 'mmsource-[\d.]+-git\d+-linux\.tar\.gz' | tail -1) if [[ -n "$METAMOD_LATEST" ]]; then wget -q "https://mms.alliedmods.net/mmsdrop/1.11/${METAMOD_LATEST}" -O metamod.tar.gz tar -xzf metamod.tar.gz -C "$SERVER_DIR/garrysmod/" rm metamod.tar.gz log_success "MetaMod updated to latest." fi # Update SourceMod log_info "Checking for SourceMod updates..." SOURCEMOD_LATEST=$(curl -s "https://sm.alliedmods.net/smdrop/1.11/" | grep -oP 'sourcemod-[\d.]+-git\d+-linux\.tar\.gz' | tail -1) if [[ -n "$SOURCEMOD_LATEST" ]]; then wget -q "https://sm.alliedmods.net/smdrop/1.11/${SOURCEMOD_LATEST}" -O sourcemod.tar.gz tar -xzf sourcemod.tar.gz -C "$SERVER_DIR/garrysmod/" rm sourcemod.tar.gz log_success "SourceMod updated to latest." fi # Update ULib/ULX log_info "Updating ULX Admin System..." cd /tmp rm -rf "$SERVER_DIR/garrysmod/addons/ulib" "$SERVER_DIR/garrysmod/addons/ulx" wget -q "https://github.com/TeamUlysses/ulib/archive/refs/heads/master.zip" -O ulib.zip unzip -q ulib.zip -d "$SERVER_DIR/garrysmod/addons/" mv "$SERVER_DIR/garrysmod/addons/ulib-master" "$SERVER_DIR/garrysmod/addons/ulib" rm ulib.zip wget -q "https://github.com/TeamUlysses/ulx/archive/refs/heads/master.zip" -O ulx.zip unzip -q ulx.zip -d "$SERVER_DIR/garrysmod/addons/" mv "$SERVER_DIR/garrysmod/addons/ulx-master" "$SERVER_DIR/garrysmod/addons/ulx" rm ulx.zip # Apply updated configs log_info "Applying configuration updates..." if [[ -d "$REPO_DIR/cfg" ]]; then cp -r "$REPO_DIR/cfg/"* "$SERVER_DIR/garrysmod/cfg/" 2>/dev/null || true fi log_success "Update complete!" echo "" echo "Restart the server to apply changes." EOF chmod +x "$INSTALL_DIR/update.sh" log_success "Update script created." } create_systemd_service() { log_info "Creating systemd service..." cat > /etc/systemd/system/gmod-prophunt.service << 'EOF' [Unit] Description=Garry's Mod PropHunt Server After=network.target [Service] Type=simple User=gmod Group=gmod WorkingDirectory=/home/gmod/serverfiles Environment="GMOD_INSTALL_DIR=/home/gmod" ExecStart=/home/gmod/start.sh ExecStop=/bin/kill -SIGINT $MAINPID Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target EOF systemctl daemon-reload log_success "Systemd service created. Enable with: systemctl enable gmod-prophunt" } set_permissions() { log_info "Setting permissions..." if [[ $EUID -eq 0 ]]; then chown -R gmod:gmod "$INSTALL_DIR" fi chmod +x "$SERVER_DIR/srcds_run" 2>/dev/null || true chmod +x "$SERVER_DIR/srcds_linux" 2>/dev/null || true chmod +x "$INSTALL_DIR"/*.sh 2>/dev/null || true log_success "Permissions set." } print_completion() { echo "" echo -e "${GREEN}" echo "╔═══════════════════════════════════════════════════════════════╗" echo "║ ✅ Installation Complete! ✅ ║" echo "╚═══════════════════════════════════════════════════════════════╝" echo -e "${NC}" echo "" echo -e "${BLUE}Next Steps:${NC}" echo "1. Get a Steam Game Server Token:" echo " https://steamcommunity.com/dev/managegameservers" echo "" echo "2. Edit server configuration:" echo " nano $SERVER_DIR/garrysmod/cfg/server.cfg" echo "" echo "3. Start the server:" echo " SRCDS_TOKEN=your_token $INSTALL_DIR/start.sh" echo "" echo " Or use the systemd service:" echo " sudo systemctl start gmod-prophunt" echo "" echo -e "${YELLOW}Server Files:${NC} $SERVER_DIR" echo -e "${YELLOW}Config Files:${NC} $SERVER_DIR/garrysmod/cfg/" echo -e "${YELLOW}Addons:${NC} $SERVER_DIR/garrysmod/addons/" echo "" } # Main installation process main() { print_banner if check_root; then install_dependencies create_user fi setup_directories install_steamcmd install_gmod_server install_metamod install_sourcemod install_prophunt install_ulx clone_config_repo create_server_config create_start_script create_update_script apply_configs if [[ $EUID -eq 0 ]]; then create_systemd_service fi set_permissions print_completion } main "$@"