diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..c149b4f --- /dev/null +++ b/.env.example @@ -0,0 +1,29 @@ +# Garry's Mod PropHunt Server Configuration +# Copy this file to .env and configure your settings +# ================================================= + +# Required: Steam Game Server Token +# Get yours at: https://steamcommunity.com/dev/managegameservers +# App ID for Garry's Mod is 4000 +SRCDS_TOKEN= + +# Server Identity +SERVER_NAME=PropHunt Server +RCON_PASSWORD=changeme + +# Server Settings +MAX_PLAYERS=24 +MAP=gm_construct +PORT=27015 +GAMEMODE=prop_hunt +TICKRATE=66 + +# Workshop Collection ID (optional) +# Create a collection at Steam Workshop and paste the ID here +WORKSHOP_COLLECTION= + +# Timezone +TZ=America/Los_Angeles + +# Auto-update on container start (Docker only) +AUTO_UPDATE=false diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89c2280 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Environment files with secrets +.env +*.env.local + +# Server data (should not be in version control) +serverfiles/ +steamcmd/ +backups/ + +# Logs +*.log +logs/ + +# Temporary files +*.tmp +*.temp +/tmp/ + +# OS files +.DS_Store +Thumbs.db + +# IDE files +.idea/ +.vscode/ +*.swp +*.swo + +# Build artifacts +*.tar.gz +*.zip diff --git a/README.md b/README.md index 38f1da8..b1659db 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,146 @@ -# gmod-prophunt-server +# 🎮 Garry's Mod PropHunt Server -Garry's Mod PropHunt Server Setup - Complete with MetaMod, SourceMod, plugins, Docker & bare metal installers \ No newline at end of file +A complete, production-ready PropHunt server setup with automated installation, updates, and Docker support. + +## 🚀 Quick Start + +### One-Liner Docker Install +```bash +curl -fsSL https://git.vish.gg/Vish/gmod-prophunt-server/raw/branch/main/install-docker.sh | bash +``` + +### Bare Metal Install +```bash +curl -fsSL https://git.vish.gg/Vish/gmod-prophunt-server/raw/branch/main/install.sh | bash +``` + +## 📦 What's Included + +- **Garry's Mod Server** (via SteamCMD) +- **MetaMod:Source** - Latest stable version +- **SourceMod** - Latest stable version +- **PropHunt Gamemode** - Pre-configured +- **Essential Plugins**: + - ULX Admin Mod + - ULib + - PropHunt Enhanced + - Anti-Cheat basics + - Workshop Collection Downloader + +## 📁 Directory Structure + +``` +gmod-prophunt-server/ +├── cfg/ # Server configuration files +│ ├── server.cfg # Main server config +│ ├── autoexec.cfg # Auto-execute commands +│ └── mount.cfg # Content mounting +├── scripts/ # Management scripts +│ ├── install.sh # Full installation +│ ├── update.sh # Update server & addons +│ ├── start.sh # Start server +│ └── backup.sh # Backup script +├── docker/ # Docker files +│ ├── Dockerfile # Container definition +│ └── docker-compose.yml # Compose setup +├── sourcemod/ # SourceMod configuration +├── workshop/ # Workshop collection config +└── metamod/ # MetaMod configuration +``` + +## ⚙️ Configuration + +### Server Settings +Edit `cfg/server.cfg` to customize: +- Server name +- RCON password +- Max players +- Map rotation +- Workshop collection ID + +### Workshop Collection +The default workshop collection includes essential PropHunt content. To use your own: +1. Create a collection on Steam Workshop +2. Update `WORKSHOP_COLLECTION_ID` in `cfg/server.cfg` +3. Run `./scripts/update.sh` + +## 🔧 Management Commands + +```bash +# Start server +./scripts/start.sh + +# Update everything (server, addons, plugins) +./scripts/update.sh + +# Backup server data +./scripts/backup.sh + +# View logs +tail -f /home/gmod/serverfiles/garrysmod/logs/console.log +``` + +## 🐳 Docker Management + +```bash +# Start with Docker Compose +docker-compose up -d + +# View logs +docker-compose logs -f + +# Stop +docker-compose down + +# Update +docker-compose pull && docker-compose up -d +``` + +## 🔒 Default Ports + +| Port | Protocol | Purpose | +|------|----------|---------| +| 27015 | UDP/TCP | Game server | +| 27005 | UDP | Client port | +| 27020 | UDP | SourceTV | + +## 📝 Environment Variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `SRCDS_TOKEN` | - | Steam Game Server Token (required) | +| `SERVER_NAME` | PropHunt Server | Server name | +| `RCON_PASSWORD` | changeme | RCON password | +| `MAX_PLAYERS` | 24 | Maximum players | +| `MAP` | ph_office | Starting map | +| `WORKSHOP_COLLECTION` | - | Workshop collection ID | + +## 🔑 Getting a Server Token + +1. Go to https://steamcommunity.com/dev/managegameservers +2. Create a new game server account for App ID `4000` (Garry's Mod) +3. Copy the token and set it as `SRCDS_TOKEN` + +## 🛠️ Troubleshooting + +### Server won't start +- Check that `SRCDS_TOKEN` is set +- Verify ports 27015-27020 are open +- Check logs in `garrysmod/logs/` + +### Workshop content not downloading +- Verify collection is public +- Check `WORKSHOP_COLLECTION` is set correctly +- Ensure server has internet access + +### Players can't connect +- Ensure firewall allows UDP/TCP 27015 +- Verify server is properly registered with Steam + +## 📜 License + +MIT License - Free to use and modify. + +## 🤝 Contributing + +Pull requests welcome! Please read the contribution guidelines first. \ No newline at end of file diff --git a/cfg/autoexec.cfg b/cfg/autoexec.cfg new file mode 100644 index 0000000..5078e6a --- /dev/null +++ b/cfg/autoexec.cfg @@ -0,0 +1,9 @@ +// ============================================ +// Garry's Mod PropHunt Server - Autoexec +// This file is executed automatically on server start +// ============================================ + +// Execute the main server configuration +exec server.cfg + +// You can add additional commands here that should run on every server start diff --git a/cfg/mapcycle.txt b/cfg/mapcycle.txt new file mode 100644 index 0000000..eaafb52 --- /dev/null +++ b/cfg/mapcycle.txt @@ -0,0 +1,32 @@ +// PropHunt Map Cycle +// Add your PropHunt maps here + +// Default GMod maps (some work for PropHunt) +gm_construct +gm_flatgrass + +// Classic PropHunt Maps (require workshop downloads) +// ph_office +// ph_restaurant +// ph_restaurant_v2 +// ph_hotel +// ph_motel +// ph_house +// ph_mansion +// ph_apartment +// ph_warehouse +// ph_school +// ph_westwood +// ph_skyscraper +// ph_docks +// ph_library +// ph_bank +// ph_gas_station +// ph_pizzeria +// ph_cruise +// ph_luigis_mansion +// ph_minecraft_b4 +// ph_starship +// ph_nightclub +// ph_bowling +// ph_watchtower diff --git a/cfg/mount.cfg b/cfg/mount.cfg new file mode 100644 index 0000000..5618eb5 --- /dev/null +++ b/cfg/mount.cfg @@ -0,0 +1,40 @@ +// ============================================ +// Garry's Mod Content Mounting Configuration +// ============================================ +// This file controls which Source games' content is available on the server. +// +// To mount content, uncomment the appropriate lines and ensure the game +// is installed on the server at the specified path. +// +// Note: Players will need the games installed to see the content properly, +// or you can set up FastDL/Workshop to provide the content. + +"mountcfg" +{ + // Counter-Strike: Source (Most common for PropHunt maps) + // "cstrike" "/home/gmod/css/cstrike" + + // Team Fortress 2 + // "tf" "/home/gmod/tf2/tf" + + // Half-Life 2 + // "hl2" "/home/gmod/hl2/hl2" + + // Half-Life 2: Episode 1 + // "episodic" "/home/gmod/hl2ep1/episodic" + + // Half-Life 2: Episode 2 + // "ep2" "/home/gmod/hl2ep2/ep2" + + // Day of Defeat: Source + // "dod" "/home/gmod/dods/dod" + + // Left 4 Dead + // "left4dead" "/home/gmod/l4d/left4dead" + + // Left 4 Dead 2 + // "left4dead2" "/home/gmod/l4d2/left4dead2" + + // Portal + // "portal" "/home/gmod/portal/portal" +} diff --git a/cfg/server.cfg b/cfg/server.cfg new file mode 100644 index 0000000..57aa089 --- /dev/null +++ b/cfg/server.cfg @@ -0,0 +1,156 @@ +// ============================================ +// Garry's Mod PropHunt Server Configuration +// Repository: https://git.vish.gg/Vish/gmod-prophunt-server +// ============================================ + +// =================== +// Server Identity +// =================== +hostname "PropHunt Server" +sv_password "" +rcon_password "changeme" + +// Loading screen URL (optional) +// sv_loadingurl "https://your-loading-screen.com" + +// =================== +// Network Settings +// =================== +sv_maxrate 0 +sv_minrate 0 +sv_maxupdaterate 66 +sv_minupdaterate 33 +net_maxfilesize 64 + +// Region (0=US East, 1=US West, 2=South America, 3=Europe, 4=Asia, 5=Australia, 6=Middle East, 7=Africa) +sv_region 0 + +// =================== +// Server Settings +// =================== +sv_allowcslua 0 +sv_allowdownload 1 +sv_allowupload 0 +sv_timeout 120 +sv_kickerrornum 0 + +// Disable cheats +sv_cheats 0 + +// =================== +// Gamemode Settings +// =================== +sv_defaultgamemode "prop_hunt" +sv_gamemode "prop_hunt" + +// =================== +// Workshop Collection +// =================== +// Set your workshop collection ID here +// Example: host_workshop_collection "123456789" +// host_workshop_collection "" + +// =================== +// Map Settings +// =================== +sv_map_min_players 0 +sv_hibernate_think 1 + +// Map download settings +sv_downloadurl "" +sv_allowdownload 1 + +// =================== +// Bandwidth & Performance +// =================== +sv_maxcmdrate 66 +sv_mincmdrate 33 +fps_max 0 + +// Tick rate (set in start command, but good to have) +// Note: GMod typically runs at 66 tick + +// =================== +// Logging +// =================== +log on +sv_logbans 1 +sv_logecho 1 +sv_logfile 1 +sv_log_onefile 0 + +// =================== +// PropHunt Settings +// =================== +// These are typical PropHunt cvars - may vary by PropHunt version + +// Round settings +ph_round_time 300 +ph_swap_teams_every_round 1 + +// Blindlock time for hunters (seconds) +ph_hunter_blindlock_time 30 + +// Speed settings +ph_hunter_speed 240 +ph_prop_speed 250 + +// Taunt settings +ph_prop_taunt_delay 5 + +// Hunter settings +ph_hunter_fire_penalty 5 +ph_hunter_kill_bonus 30 + +// Props settings +ph_prop_disguise 1 + +// =================== +// Voice Settings +// =================== +sv_voiceenable 1 +sv_alltalk 0 + +// =================== +// Anti-Cheat Settings +// =================== +// Block workshop downloading exploits +sv_workshop_bypass 0 + +// =================== +// Misc Settings +// =================== +// Gravity +sv_gravity 600 + +// Physics settings +gmod_physiterations 4 + +// Prop protection +sbox_godmode 0 +sbox_plpldamage 1 + +// Limits (for sandbox, but good to have set) +sbox_maxprops 0 +sbox_maxragdolls 0 +sbox_maxnpcs 0 +sbox_maxballoons 0 +sbox_maxeffects 0 +sbox_maxdynamite 0 +sbox_maxlamps 0 +sbox_maxthrusters 0 +sbox_maxwheels 0 +sbox_maxhoverballs 0 +sbox_maxvehicles 0 +sbox_maxbuttons 0 +sbox_maxemitters 0 + +// =================== +// Execute Additional Configs +// =================== +exec banned_user.cfg +exec banned_ip.cfg + +echo "============================================" +echo "PropHunt Server Configuration Loaded!" +echo "============================================" diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..765fccc --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,119 @@ +#=============================================================================== +# Garry's Mod PropHunt Server - Docker Image +# Repository: https://git.vish.gg/Vish/gmod-prophunt-server +#=============================================================================== + +FROM debian:bookworm-slim + +LABEL maintainer="Vish " +LABEL description="Garry's Mod PropHunt Dedicated Server" +LABEL version="1.0" + +# Environment variables +ENV DEBIAN_FRONTEND=noninteractive \ + GMOD_INSTALL_DIR=/home/gmod \ + SERVER_DIR=/home/gmod/serverfiles \ + STEAMCMD_DIR=/home/gmod/steamcmd \ + SRCDS_TOKEN="" \ + SERVER_NAME="PropHunt Server" \ + RCON_PASSWORD="changeme" \ + MAX_PLAYERS="24" \ + MAP="gm_construct" \ + PORT="27015" \ + GAMEMODE="prop_hunt" \ + WORKSHOP_COLLECTION="" \ + TICKRATE="66" \ + TZ="America/Los_Angeles" + +# Install dependencies +RUN dpkg --add-architecture i386 && \ + apt-get update && \ + apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + wget \ + tar \ + unzip \ + lib32gcc-s1 \ + lib32stdc++6 \ + libsdl2-2.0-0:i386 \ + locales \ + tzdata && \ + sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ + locale-gen && \ + apt-get clean && \ + rm -rf /var/lib/apt/lists/* + +ENV LANG=en_US.UTF-8 \ + LANGUAGE=en_US:en \ + LC_ALL=en_US.UTF-8 + +# Create user and directories +RUN useradd -m -s /bin/bash gmod && \ + mkdir -p ${SERVER_DIR} ${STEAMCMD_DIR} && \ + chown -R gmod:gmod /home/gmod + +# Switch to gmod user +USER gmod +WORKDIR /home/gmod + +# Install SteamCMD +RUN cd ${STEAMCMD_DIR} && \ + curl -sqL "https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz" | tar zxvf - + +# Install Garry's Mod server +RUN cd ${STEAMCMD_DIR} && \ + ./steamcmd.sh +force_install_dir ${SERVER_DIR} \ + +login anonymous \ + +app_update 4020 validate \ + +quit + +# Install MetaMod:Source +RUN cd /tmp && \ + METAMOD_VER=$(curl -s "https://mms.alliedmods.net/mmsdrop/1.11/" | grep -oP 'mmsource-[\d.]+-git\d+-linux\.tar\.gz' | tail -1) && \ + wget -q "https://mms.alliedmods.net/mmsdrop/1.11/${METAMOD_VER}" -O metamod.tar.gz && \ + tar -xzf metamod.tar.gz -C ${SERVER_DIR}/garrysmod/ && \ + rm metamod.tar.gz + +# Install SourceMod +RUN cd /tmp && \ + SOURCEMOD_VER=$(curl -s "https://sm.alliedmods.net/smdrop/1.11/" | grep -oP 'sourcemod-[\d.]+-git\d+-linux\.tar\.gz' | tail -1) && \ + wget -q "https://sm.alliedmods.net/smdrop/1.11/${SOURCEMOD_VER}" -O sourcemod.tar.gz && \ + tar -xzf sourcemod.tar.gz -C ${SERVER_DIR}/garrysmod/ && \ + rm sourcemod.tar.gz + +# Install ULib and ULX +RUN cd /tmp && \ + 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 + +# Copy configuration files +COPY --chown=gmod:gmod cfg/ ${SERVER_DIR}/garrysmod/cfg/ +COPY --chown=gmod:gmod scripts/docker-entrypoint.sh /home/gmod/entrypoint.sh + +# Make scripts executable +USER root +RUN chmod +x /home/gmod/entrypoint.sh ${SERVER_DIR}/srcds_run ${SERVER_DIR}/srcds_linux 2>/dev/null || true +USER gmod + +# Expose ports +EXPOSE 27015/tcp 27015/udp 27005/udp 27020/udp + +# Volumes for persistent data +VOLUME ["/home/gmod/serverfiles/garrysmod/data", \ + "/home/gmod/serverfiles/garrysmod/cfg", \ + "/home/gmod/serverfiles/garrysmod/addons"] + +# Health check +HEALTHCHECK --interval=30s --timeout=10s --start-period=120s --retries=3 \ + CMD curl -f http://localhost:27015/ 2>/dev/null || exit 1 + +WORKDIR ${SERVER_DIR} + +ENTRYPOINT ["/home/gmod/entrypoint.sh"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..2137acd --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,62 @@ +version: '3.8' + +services: + gmod-prophunt: + build: + context: .. + dockerfile: docker/Dockerfile + container_name: gmod-prophunt + restart: unless-stopped + + environment: + - SRCDS_TOKEN=${SRCDS_TOKEN:-} + - SERVER_NAME=${SERVER_NAME:-PropHunt Server} + - RCON_PASSWORD=${RCON_PASSWORD:-changeme} + - MAX_PLAYERS=${MAX_PLAYERS:-24} + - MAP=${MAP:-gm_construct} + - PORT=${PORT:-27015} + - GAMEMODE=${GAMEMODE:-prop_hunt} + - WORKSHOP_COLLECTION=${WORKSHOP_COLLECTION:-} + - TICKRATE=${TICKRATE:-66} + - TZ=${TZ:-America/Los_Angeles} + + ports: + - "${PORT:-27015}:27015/tcp" + - "${PORT:-27015}:27015/udp" + - "27005:27005/udp" + - "27020:27020/udp" + + volumes: + # Persistent data + - gmod-data:/home/gmod/serverfiles/garrysmod/data + - gmod-addons:/home/gmod/serverfiles/garrysmod/addons + # Config can be bind-mounted for easy editing + - ./cfg:/home/gmod/serverfiles/garrysmod/cfg:ro + + networks: + - gmod-network + + # Resource limits (optional, adjust as needed) + deploy: + resources: + limits: + cpus: '4' + memory: 4G + reservations: + cpus: '1' + memory: 1G + + # Logging configuration + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + +networks: + gmod-network: + driver: bridge + +volumes: + gmod-data: + gmod-addons: diff --git a/install-docker.sh b/install-docker.sh new file mode 100755 index 0000000..6a60bed --- /dev/null +++ b/install-docker.sh @@ -0,0 +1,109 @@ +#!/bin/bash +#=============================================================================== +# Garry's Mod PropHunt Server - Docker One-Liner Installer +# Repository: https://git.vish.gg/Vish/gmod-prophunt-server +#=============================================================================== + +set -o pipefail + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +BLUE='\033[0;34m' +NC='\033[0m' + +INSTALL_DIR="${GMOD_DOCKER_DIR:-/opt/gmod-prophunt}" +REPO_URL="https://git.vish.gg/Vish/gmod-prophunt-server.git" + +log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } +log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +echo -e "${GREEN}" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ 🐳 Garry's Mod PropHunt Docker Installer 🐳 ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" + +# Check for Docker +if ! command -v docker &> /dev/null; then + log_info "Docker not found. Installing Docker..." + curl -fsSL https://get.docker.com | sh + systemctl enable docker + systemctl start docker +fi + +# Check for Docker Compose +if ! command -v docker-compose &> /dev/null && ! docker compose version &> /dev/null; then + log_info "Installing Docker Compose..." + curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose +fi + +# Create installation directory +log_info "Creating installation directory..." +mkdir -p "$INSTALL_DIR" +cd "$INSTALL_DIR" + +# Clone or update repository +if [[ -d ".git" ]]; then + log_info "Updating repository..." + git pull +else + log_info "Cloning repository..." + git clone "$REPO_URL" . +fi + +# Create environment file if it doesn't exist +if [[ ! -f ".env" ]]; then + log_info "Creating environment file..." + cat > .env << 'EOF' +# Garry's Mod PropHunt Server Configuration +# Get your token at: https://steamcommunity.com/dev/managegameservers + +# Required: Steam Game Server Token +SRCDS_TOKEN= + +# Server Settings +SERVER_NAME=PropHunt Server +RCON_PASSWORD=changeme +MAX_PLAYERS=24 +MAP=gm_construct +PORT=27015 + +# Optional: Workshop Collection ID +WORKSHOP_COLLECTION= + +# Timezone +TZ=America/Los_Angeles +EOF + + log_info "Please edit .env file with your settings:" + echo " nano $INSTALL_DIR/.env" + echo "" +fi + +# Start the server +log_info "Building and starting Docker containers..." +if command -v docker-compose &> /dev/null; then + docker-compose -f docker/docker-compose.yml up -d --build +else + docker compose -f docker/docker-compose.yml up -d --build +fi + +echo "" +echo -e "${GREEN}" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ ✅ Docker Installation Complete! ✅ ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" +echo "" +echo -e "${YELLOW}Important:${NC} Edit the configuration file:" +echo " nano $INSTALL_DIR/.env" +echo "" +echo -e "${BLUE}Commands:${NC}" +echo " View logs: cd $INSTALL_DIR && docker-compose -f docker/docker-compose.yml logs -f" +echo " Stop server: cd $INSTALL_DIR && docker-compose -f docker/docker-compose.yml down" +echo " Restart: cd $INSTALL_DIR && docker-compose -f docker/docker-compose.yml restart" +echo " Update: cd $INSTALL_DIR && git pull && docker-compose -f docker/docker-compose.yml up -d --build" +echo "" diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..a2b4550 --- /dev/null +++ b/install.sh @@ -0,0 +1,609 @@ +#!/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 "$@" diff --git a/scripts/backup.sh b/scripts/backup.sh new file mode 100755 index 0000000..df012f2 --- /dev/null +++ b/scripts/backup.sh @@ -0,0 +1,76 @@ +#!/bin/bash +#=============================================================================== +# Garry's Mod PropHunt Server - Backup Script +#=============================================================================== + +INSTALL_DIR="${GMOD_INSTALL_DIR:-/home/gmod}" +SERVER_DIR="${INSTALL_DIR}/serverfiles" +BACKUP_DIR="${BACKUP_DIR:-/home/gmod/backups}" +DATE=$(date +%Y%m%d_%H%M%S) +BACKUP_NAME="gmod_prophunt_backup_${DATE}.tar.gz" + +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"; } + +echo -e "${GREEN}" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ 💾 Garry's Mod PropHunt Backup Script 💾 ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" + +# Create backup directory +mkdir -p "$BACKUP_DIR" + +log_info "Creating backup..." + +# Items to backup +BACKUP_ITEMS=( + "$SERVER_DIR/garrysmod/cfg" + "$SERVER_DIR/garrysmod/data" + "$SERVER_DIR/garrysmod/addons/ulib" + "$SERVER_DIR/garrysmod/addons/ulx" + "$SERVER_DIR/garrysmod/addons/sourcemod/configs" + "$SERVER_DIR/garrysmod/addons/sourcemod/data" +) + +# Create temporary directory for backup +TEMP_BACKUP="/tmp/gmod_backup_${DATE}" +mkdir -p "$TEMP_BACKUP" + +# Copy files to temp directory +for item in "${BACKUP_ITEMS[@]}"; do + if [[ -e "$item" ]]; then + cp -r "$item" "$TEMP_BACKUP/" 2>/dev/null + fi +done + +# Create compressed archive +cd /tmp +tar -czf "$BACKUP_DIR/$BACKUP_NAME" "gmod_backup_${DATE}" + +# Cleanup temp directory +rm -rf "$TEMP_BACKUP" + +# Keep only last 7 backups +cd "$BACKUP_DIR" +ls -t gmod_prophunt_backup_*.tar.gz | tail -n +8 | xargs -r rm + +log_success "Backup created: $BACKUP_DIR/$BACKUP_NAME" + +# Show backup size +BACKUP_SIZE=$(du -h "$BACKUP_DIR/$BACKUP_NAME" | cut -f1) +echo "" +echo -e "${BLUE}Backup Details:${NC}" +echo " • Location: $BACKUP_DIR/$BACKUP_NAME" +echo " • Size: $BACKUP_SIZE" +echo "" + +# List recent backups +echo -e "${BLUE}Recent Backups:${NC}" +ls -lh "$BACKUP_DIR"/*.tar.gz 2>/dev/null | tail -5 diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh new file mode 100755 index 0000000..e881277 --- /dev/null +++ b/scripts/docker-entrypoint.sh @@ -0,0 +1,88 @@ +#!/bin/bash +#=============================================================================== +# Garry's Mod PropHunt Server - Docker Entrypoint +#=============================================================================== + +SERVER_DIR="${GMOD_INSTALL_DIR:-/home/gmod}/serverfiles" +STEAMCMD_DIR="${GMOD_INSTALL_DIR:-/home/gmod}/steamcmd" + +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 "║ 🎮 Garry's Mod PropHunt Server Starting 🎮 ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" + +# Update server if AUTO_UPDATE is set +if [[ "${AUTO_UPDATE:-false}" == "true" ]]; then + log_info "Checking for server updates..." + cd "$STEAMCMD_DIR" + ./steamcmd.sh +force_install_dir "$SERVER_DIR" \ + +login anonymous \ + +app_update 4020 \ + +quit +fi + +cd "$SERVER_DIR" + +# Build command line arguments +ARGS="-game garrysmod" +ARGS="$ARGS -console" +ARGS="$ARGS -port ${PORT:-27015}" +ARGS="$ARGS +maxplayers ${MAX_PLAYERS:-24}" +ARGS="$ARGS +map ${MAP:-gm_construct}" +ARGS="$ARGS +gamemode ${GAMEMODE:-prop_hunt}" +ARGS="$ARGS -tickrate ${TICKRATE:-66}" +ARGS="$ARGS +hostname \"${SERVER_NAME:-PropHunt Server}\"" + +# Add Steam token if provided +if [[ -n "$SRCDS_TOKEN" ]]; then + ARGS="$ARGS +sv_setsteamaccount $SRCDS_TOKEN" + log_success "Steam token configured." +else + log_warning "No SRCDS_TOKEN set. Server won't be listed publicly." + log_warning "Get a token at: https://steamcommunity.com/dev/managegameservers" +fi + +# Add RCON password +if [[ -n "$RCON_PASSWORD" && "$RCON_PASSWORD" != "changeme" ]]; then + ARGS="$ARGS +rcon_password \"$RCON_PASSWORD\"" +fi + +# Add workshop collection if provided +if [[ -n "$WORKSHOP_COLLECTION" ]]; then + ARGS="$ARGS +host_workshop_collection $WORKSHOP_COLLECTION" + log_info "Workshop collection: $WORKSHOP_COLLECTION" +fi + +# Display configuration +echo "" +log_info "Server Configuration:" +echo " • Server Name: ${SERVER_NAME:-PropHunt Server}" +echo " • Map: ${MAP:-gm_construct}" +echo " • Max Players: ${MAX_PLAYERS:-24}" +echo " • Port: ${PORT:-27015}" +echo " • Gamemode: ${GAMEMODE:-prop_hunt}" +echo " • Tickrate: ${TICKRATE:-66}" +echo "" + +log_info "Starting server..." + +# Handle shutdown signals +trap 'log_info "Shutting down server..."; kill -SIGTERM $SERVER_PID; wait $SERVER_PID' SIGTERM SIGINT + +# Start the server +exec ./srcds_run $ARGS & +SERVER_PID=$! + +# Wait for the server process +wait $SERVER_PID diff --git a/scripts/start.sh b/scripts/start.sh new file mode 100755 index 0000000..b4dd06a --- /dev/null +++ b/scripts/start.sh @@ -0,0 +1,76 @@ +#!/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' +BLUE='\033[0;34m' +NC='\033[0m' + +echo -e "${GREEN}" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ 🎮 Garry's Mod PropHunt Server Starting 🎮 ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" + +cd "$SERVER_DIR" + +# Check if server files exist +if [[ ! -f "srcds_run" ]]; then + echo -e "${RED}[ERROR]${NC} Server files not found. Run install.sh first." + exit 1 +fi + +# 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" + echo -e "${GREEN}[OK]${NC} Steam token configured." +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" + echo -e "${BLUE}[INFO]${NC} Workshop collection: $WORKSHOP_COLLECTION" +fi + +echo "" +echo -e "${BLUE}[INFO]${NC} Server Configuration:" +echo " • Map: $MAP" +echo " • Max Players: $MAX_PLAYERS" +echo " • Port: $PORT" +echo " • Gamemode: $GAMEMODE" +echo "" + +echo -e "${GREEN}Starting server...${NC}" + +# Start the server +./srcds_run $ARGS diff --git a/scripts/update.sh b/scripts/update.sh new file mode 100755 index 0000000..48f0ff9 --- /dev/null +++ b/scripts/update.sh @@ -0,0 +1,153 @@ +#!/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"; } +log_error() { echo -e "${RED}[ERROR]${NC} $1"; } + +echo -e "${GREEN}" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ 🔄 Garry's Mod PropHunt Update Script 🔄 ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" + +# Check for running server +if pgrep -f "srcds_linux.*garrysmod" > /dev/null; then + log_warning "Server appears to be running. Stop it before updating." + read -p "Stop server and continue? (y/N): " confirm + if [[ "$confirm" =~ ^[Yy]$ ]]; then + pkill -f "srcds_linux.*garrysmod" + sleep 5 + else + log_info "Update cancelled." + exit 0 + fi +fi + +# Update Garry's Mod Server +log_info "Updating Garry's Mod server..." +cd "$STEAMCMD_DIR" +./steamcmd.sh +force_install_dir "$SERVER_DIR" \ + +login anonymous \ + +app_update 4020 validate \ + +quit + +if [[ $? -eq 0 ]]; then + log_success "Garry's Mod server updated." +else + log_error "Failed to update Garry's Mod server." +fi + +# Update configuration repository +log_info "Updating configuration repository..." +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 updated." + +# 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 + if [[ -f metamod.tar.gz ]]; then + tar -xzf metamod.tar.gz -C "$SERVER_DIR/garrysmod/" + rm metamod.tar.gz + log_success "MetaMod updated: $METAMOD_LATEST" + fi +else + log_warning "Could not determine latest MetaMod version." +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 + if [[ -f sourcemod.tar.gz ]]; then + tar -xzf sourcemod.tar.gz -C "$SERVER_DIR/garrysmod/" + rm sourcemod.tar.gz + log_success "SourceMod updated: $SOURCEMOD_LATEST" + fi +else + log_warning "Could not determine latest SourceMod version." +fi + +# Update ULib and ULX +log_info "Updating ULX Admin System..." +cd /tmp + +# Backup existing ULX data +if [[ -d "$SERVER_DIR/garrysmod/addons/ulx/data" ]]; then + cp -r "$SERVER_DIR/garrysmod/addons/ulx/data" /tmp/ulx_data_backup +fi +if [[ -d "$SERVER_DIR/garrysmod/addons/ulib/data" ]]; then + cp -r "$SERVER_DIR/garrysmod/addons/ulib/data" /tmp/ulib_data_backup +fi + +# Update ULib +rm -rf "$SERVER_DIR/garrysmod/addons/ulib" +wget -q "https://github.com/TeamUlysses/ulib/archive/refs/heads/master.zip" -O ulib.zip +if [[ -f ulib.zip ]]; then + unzip -q ulib.zip -d "$SERVER_DIR/garrysmod/addons/" + mv "$SERVER_DIR/garrysmod/addons/ulib-master" "$SERVER_DIR/garrysmod/addons/ulib" + rm ulib.zip +fi + +# Update ULX +rm -rf "$SERVER_DIR/garrysmod/addons/ulx" +wget -q "https://github.com/TeamUlysses/ulx/archive/refs/heads/master.zip" -O ulx.zip +if [[ -f ulx.zip ]]; then + unzip -q ulx.zip -d "$SERVER_DIR/garrysmod/addons/" + mv "$SERVER_DIR/garrysmod/addons/ulx-master" "$SERVER_DIR/garrysmod/addons/ulx" + rm ulx.zip +fi + +# Restore ULX data +if [[ -d /tmp/ulx_data_backup ]]; then + cp -r /tmp/ulx_data_backup/* "$SERVER_DIR/garrysmod/addons/ulx/data/" 2>/dev/null || true + rm -rf /tmp/ulx_data_backup +fi +if [[ -d /tmp/ulib_data_backup ]]; then + cp -r /tmp/ulib_data_backup/* "$SERVER_DIR/garrysmod/addons/ulib/data/" 2>/dev/null || true + rm -rf /tmp/ulib_data_backup +fi + +log_success "ULX Admin System updated." + +# Apply updated configs (optional - commented to preserve user changes) +# log_info "Applying configuration updates..." +# if [[ -d "$REPO_DIR/cfg" ]]; then +# cp -r "$REPO_DIR/cfg/"* "$SERVER_DIR/garrysmod/cfg/" +# fi + +echo "" +echo -e "${GREEN}" +echo "╔═══════════════════════════════════════════════════════════════╗" +echo "║ ✅ Update Complete! ✅ ║" +echo "╚═══════════════════════════════════════════════════════════════╝" +echo -e "${NC}" +echo "" +echo "Restart the server to apply changes:" +echo " $INSTALL_DIR/start.sh" +echo "" diff --git a/sourcemod/addons/sourcemod/configs/admins_simple.ini b/sourcemod/addons/sourcemod/configs/admins_simple.ini new file mode 100644 index 0000000..661632b --- /dev/null +++ b/sourcemod/addons/sourcemod/configs/admins_simple.ini @@ -0,0 +1,35 @@ +// SourceMod Admin Configuration +// =========================================== +// Add your admins here using their Steam ID +// +// Format: "STEAM_X:X:XXXXXX" "flags" +// +// Common flags: +// z - Full admin (root access) +// b - Ban players +// c - Kick players +// d - Slay/harm players +// e - Map changing +// f - Cvars (change server settings) +// g - Chat (special chat commands) +// h - Vote (start votes) +// i - Password (set server password) +// j - RCON (execute rcon commands) +// k - Cheats (sv_cheats commands) +// l - Custom1 +// m - Custom2 +// n - Custom3 +// o - Custom4 +// p - Custom5 +// q - Custom6 +// r - Reserved slot +// s - Remove admins +// t - Change level +// +// =========================================== +// Examples: +// "STEAM_0:1:12345678" "z" // Full admin +// "STEAM_0:0:87654321" "bce" // Ban, kick, map change only +// +// Add your admins below: +// "STEAM_0:X:XXXXXXX" "z" diff --git a/workshop/README.md b/workshop/README.md new file mode 100644 index 0000000..04ca89b --- /dev/null +++ b/workshop/README.md @@ -0,0 +1,70 @@ +# Workshop Collections for PropHunt + +## Recommended Workshop Collections + +Here are some popular PropHunt workshop collections you can use: + +### How to Use Workshop Collections + +1. Go to Steam Workshop: https://steamcommunity.com/app/4000/workshop/ +2. Create a new collection or find an existing PropHunt collection +3. Copy the collection ID from the URL (the number at the end) +4. Set the `WORKSHOP_COLLECTION` environment variable or add to server.cfg: + ``` + host_workshop_collection "YOUR_COLLECTION_ID" + ``` + +### Essential Content to Include + +Your workshop collection should include: + +#### Maps +- ph_office +- ph_restaurant +- ph_hotel +- ph_motel +- ph_warehouse +- ph_house +- ph_apartment +- ph_school +- ph_bank +- ph_gas_station + +#### Required Content (if not using CSS mount) +- Counter-Strike: Source Content Pack +- Half-Life 2 Content Pack + +#### PropHunt Gamemode +- PropHunt Enhanced +- PropHunt X (alternative) + +### Creating Your Own Collection + +1. Go to https://steamcommunity.com/workshop/browse/?appid=4000 +2. Click "Create Collection" +3. Name it (e.g., "My PropHunt Server") +4. Add items by browsing the workshop and clicking "Add to Collection" +5. Make sure the collection is **PUBLIC** +6. Copy the collection ID and use it in your server config + +### Popular Pre-made Collections + +Search for "PropHunt" on the GMod Workshop to find community collections. + +### Workshop Download Location + +Downloaded workshop content is stored in: +``` +garrysmod/cache/srcds/ +``` + +### Troubleshooting + +**Content not downloading:** +- Ensure collection is public +- Check server has internet access +- Verify collection ID is correct + +**Missing textures/errors:** +- Mount CSS content or include CSS content pack in collection +- Check that all dependencies are in the collection