mirror of
https://github.com/barkeser2002/NOMAD-Ptero-Egg.git
synced 2026-09-25 01:50:01 +03:00
325 lines
10 KiB
Bash
325 lines
10 KiB
Bash
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# Nomad Server Pterodactyl Egg Entrypoint
|
|
# Handles installation, configuration, and server launch
|
|
|
|
cd /home/container || exit 1
|
|
|
|
# --- Helper Functions ---
|
|
check_dependencies() {
|
|
echo "[INFO] Checking for required dependencies..."
|
|
local missing=0
|
|
for cmd in curl wget aria2c unzip jq wine64 xvfb-run ip; do
|
|
if ! command -v "$cmd" &> /dev/null; then
|
|
echo "[ERROR] Dependency missing: $cmd. Please install it in your Dockerfile."
|
|
missing=1
|
|
fi
|
|
done
|
|
if [ "$missing" -eq 1 ]; then
|
|
exit 1
|
|
fi
|
|
echo "[SUCCESS] All dependencies are installed."
|
|
}
|
|
|
|
# --- Script Start ---
|
|
check_dependencies
|
|
|
|
# Print startup banner
|
|
echo "=========================================="
|
|
echo " Nomad Server - Pterodactyl Edition"
|
|
echo "=========================================="
|
|
echo ""
|
|
|
|
# Define installation paths
|
|
INSTALL_DIR="/home/container/Nomad"
|
|
WINE_PREFIX_DIR="/home/container/.wine"
|
|
INSTALLER_PATH="/home/container/nomad.zip"
|
|
SERVER_EXE="${INSTALL_DIR}/Nomad.exe"
|
|
CONFIG_DIR="/home/container/Nomad Server/Config"
|
|
|
|
# Wine environment setup
|
|
export WINEPREFIX="${WINE_PREFIX_DIR}"
|
|
export WINEARCH="win64"
|
|
export WINEDLLOVERRIDES="winemenubuilder.exe=d"
|
|
export DISPLAY=:0.0
|
|
|
|
# Set internal Docker IP for binding
|
|
INTERNAL_IP=$(ip -4 addr show eth0 | grep -oP '(?<=inet\s)\d+(\.\d+){3}' || echo "0.0.0.0")
|
|
export INTERNAL_IP
|
|
|
|
echo "Container User: ${USER}"
|
|
echo "Working Directory: $(pwd)"
|
|
echo "Internal IP: ${INTERNAL_IP}"
|
|
echo ""
|
|
|
|
# Function: Download Nomad installer
|
|
download_installer() {
|
|
echo "[INFO] Downloading Nomad installer..."
|
|
|
|
if [ -z "${NOMAD_DOWNLOAD_URL}" ]; then
|
|
echo "[ERROR] NOMAD_DOWNLOAD_URL environment variable is not set!"
|
|
echo "[ERROR] Please set this variable in your egg configuration."
|
|
exit 1
|
|
fi
|
|
|
|
echo "[INFO] Download URL: ${NOMAD_DOWNLOAD_URL}"
|
|
|
|
# Try aria2c first for faster downloads (with progress)
|
|
if command -v aria2c &> /dev/null; then
|
|
echo "[INFO] Using aria2c (multi-connection download)..."
|
|
if aria2c \
|
|
--check-certificate=false \
|
|
--max-connection-per-server=16 \
|
|
--split=16 \
|
|
--min-split-size=1M \
|
|
--file-allocation=none \
|
|
--summary-interval=1 \
|
|
--allow-overwrite=true \
|
|
--out="$(basename ${INSTALLER_PATH})" \
|
|
--dir="$(dirname ${INSTALLER_PATH})" \
|
|
"${NOMAD_DOWNLOAD_URL}"; then
|
|
echo "[SUCCESS] Download completed with aria2c."
|
|
return 0
|
|
else
|
|
echo "[WARNING] aria2c failed, trying wget..."
|
|
fi
|
|
fi
|
|
|
|
# Fallback to wget
|
|
echo "[INFO] Using wget for download..."
|
|
if wget --no-check-certificate --show-progress -q -O "${INSTALLER_PATH}" "${NOMAD_DOWNLOAD_URL}"; then
|
|
echo "[SUCCESS] Download completed with wget."
|
|
return 0
|
|
else
|
|
echo "[ERROR] Failed to download installer!"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Function: Extract installer
|
|
extract_installer() {
|
|
echo "[INFO] Extracting Nomad installer..."
|
|
|
|
if [ ! -f "${INSTALLER_PATH}" ]; then
|
|
echo "[ERROR] Installer file not found at ${INSTALLER_PATH}"
|
|
exit 1
|
|
fi
|
|
|
|
# Get file size for verification
|
|
FILE_SIZE=$(du -h "${INSTALLER_PATH}" | cut -f1)
|
|
echo "[INFO] Installer size: ${FILE_SIZE}"
|
|
|
|
mkdir -p "${INSTALL_DIR}"
|
|
|
|
if ! unzip -q -o "${INSTALLER_PATH}" -d "${INSTALL_DIR}"; then
|
|
echo "[ERROR] Failed to extract installer!"
|
|
exit 1
|
|
fi
|
|
|
|
echo "[SUCCESS] Extraction completed."
|
|
}
|
|
|
|
# Function: Initialize Wine prefix
|
|
initialize_wine() {
|
|
echo "[INFO] Initializing Wine environment..."
|
|
|
|
if [ ! -d "${WINE_PREFIX_DIR}" ]; then
|
|
echo "[INFO] Creating Wine prefix (this may take a moment)..."
|
|
WINEDLLOVERRIDES="mscoree,mshtml=" wineboot -u 2>/dev/null
|
|
wineserver -w
|
|
echo "[SUCCESS] Wine prefix created."
|
|
else
|
|
echo "[INFO] Wine prefix already exists."
|
|
fi
|
|
}
|
|
|
|
# Function: Setup configuration directory
|
|
setup_config() {
|
|
echo "[INFO] Setting up configuration directory..."
|
|
mkdir -p "${CONFIG_DIR}"
|
|
|
|
# Set permissions if possible
|
|
chmod -R 755 "${CONFIG_DIR}" 2>/dev/null || true
|
|
|
|
echo "[SUCCESS] Configuration directory ready."
|
|
}
|
|
|
|
# Function: Verify installation
|
|
verify_installation() {
|
|
echo "[INFO] Verifying installation..."
|
|
|
|
if [ ! -f "${SERVER_EXE}" ]; then
|
|
echo "[ERROR] Nomad.exe not found at ${SERVER_EXE}"
|
|
echo "[ERROR] Installation verification failed!"
|
|
return 1
|
|
fi
|
|
|
|
# Get file size for confirmation
|
|
EXE_SIZE=$(du -h "${SERVER_EXE}" | cut -f1)
|
|
echo "[SUCCESS] Found Nomad.exe (${EXE_SIZE})"
|
|
echo "[SUCCESS] Installation verified."
|
|
return 0
|
|
}
|
|
|
|
# Function: Dynamically update config.json from Pterodactyl variables
|
|
update_config() {
|
|
echo "[CONFIG] Updating config.json from environment variables..."
|
|
CONFIG_FILE="${CONFIG_DIR}/config.json"
|
|
|
|
# Create a default config if it doesn't exist
|
|
if [ ! -f "${CONFIG_FILE}" ]; then
|
|
echo "[CONFIG] config.json not found. Creating a default one."
|
|
cat > "${CONFIG_FILE}" <<-EOF
|
|
{
|
|
"serverPort": 25565,
|
|
"maxPlayers": 30,
|
|
"password": "",
|
|
"serverName": "Nomad Server",
|
|
"maxPing": 1000,
|
|
"motdTimer": 300,
|
|
"kits": false,
|
|
"RegularLoot": 150,
|
|
"MediumLoot": 40,
|
|
"HighLoot": 30,
|
|
"IndustrialLoot": 30,
|
|
"HealthLoot": 30,
|
|
"FoodLoot": 150,
|
|
"FireLoot": 30,
|
|
"SupplyDropTimer": 5400,
|
|
"MiningNodes": 200,
|
|
"BarrelSpawns": 80,
|
|
"PalletSpawns": 50,
|
|
"Zombies": 60,
|
|
"Deers": 40
|
|
}
|
|
EOF
|
|
fi
|
|
|
|
# Use jq to update values from environment variables if they are set
|
|
echo "[CONFIG] Applying panel settings..."
|
|
TEMP_JSON=$(jq \
|
|
--argjson port "${SERVER_PORT:-$(jq .serverPort ${CONFIG_FILE})}" \
|
|
--argjson players "${MAX_PLAYERS:-$(jq .maxPlayers ${CONFIG_FILE})}" \
|
|
--arg name "${SERVER_NAME:-$(jq .serverName ${CONFIG_FILE})}" \
|
|
--arg password "${SERVER_PASSWORD:-$(jq .password ${CONFIG_FILE})}" \
|
|
--argjson kits_enabled "${KITS_ENABLED:-$(jq .kits ${CONFIG_FILE})}" \
|
|
--argjson regular_loot "${REGULAR_LOOT:-$(jq .RegularLoot ${CONFIG_FILE})}" \
|
|
--argjson medium_loot "${MEDIUM_LOOT:-$(jq .MediumLoot ${CONFIG_FILE})}" \
|
|
--argjson high_loot "${HIGH_LOOT:-$(jq .HighLoot ${CONFIG_FILE})}" \
|
|
--argjson zombies "${ZOMBIES:-$(jq .Zombies ${CONFIG_FILE})}" \
|
|
--argjson deers "${DEERS:-$(jq .Deers ${CONFIG_FILE})}" \
|
|
'.serverPort = $port | .maxPlayers = $players | .serverName = $name | .password = $password | .kits = $kits_enabled | .RegularLoot = $regular_loot | .MediumLoot = $medium_loot | .HighLoot = $high_loot | .Zombies = $zombies | .Deers = $deers' \
|
|
"${CONFIG_FILE}")
|
|
|
|
echo "${TEMP_JSON}" > "${CONFIG_FILE}"
|
|
echo "[CONFIG] Successfully updated config.json."
|
|
echo "--- Current Settings ---"
|
|
# Use jq to pretty-print the JSON for readability
|
|
echo "${TEMP_JSON}" | jq .
|
|
echo "------------------------"
|
|
}
|
|
|
|
# --- Main Installation Logic ---
|
|
|
|
echo "[CHECK] Looking for Nomad installation..."
|
|
|
|
if [ -f "${SERVER_EXE}" ]; then
|
|
echo "[SUCCESS] Nomad server is already installed."
|
|
echo "[INFO] Installation directory: ${INSTALL_DIR}"
|
|
else
|
|
echo "[INSTALL] Nomad server not found. Starting installation..."
|
|
echo ""
|
|
|
|
# Download installer if not present
|
|
if [ ! -f "${INSTALLER_PATH}" ]; then
|
|
download_installer
|
|
echo ""
|
|
else
|
|
echo "[INFO] Installer file already exists, skipping download."
|
|
echo ""
|
|
fi
|
|
|
|
# Extract installer
|
|
extract_installer
|
|
echo ""
|
|
|
|
# Initialize Wine
|
|
initialize_wine
|
|
echo ""
|
|
|
|
# Verify installation
|
|
if verify_installation; then
|
|
echo ""
|
|
echo "[SUCCESS] Installation completed successfully!"
|
|
echo ""
|
|
|
|
# Clean up installer to save space (optional)
|
|
if [ -f "${INSTALLER_PATH}" ]; then
|
|
FILE_SIZE=$(du -h "${INSTALLER_PATH}" | cut -f1)
|
|
echo "[CLEANUP] Removing installer file (${FILE_SIZE})..."
|
|
rm -f "${INSTALLER_PATH}"
|
|
echo "[SUCCESS] Cleanup completed."
|
|
fi
|
|
else
|
|
echo ""
|
|
echo "[ERROR] Installation failed!"
|
|
echo "[ERROR] Please check the logs above for details."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
|
|
# Setup configuration
|
|
setup_config
|
|
|
|
# Update config.json from environment variables
|
|
update_config
|
|
|
|
# --- Startup Logic ---
|
|
|
|
echo ""
|
|
echo "=========================================="
|
|
echo " Starting Nomad Server"
|
|
echo "=========================================="
|
|
echo "[INFO] Server executable: ${SERVER_EXE}"
|
|
echo "[INFO] Config directory: ${CONFIG_DIR}"
|
|
|
|
# Pterodactyl passes the startup command as arguments to this script.
|
|
# We need to parse them correctly.
|
|
STARTUP_CMD=("$@")
|
|
|
|
# Log received arguments for debugging
|
|
echo "[DEBUG] Received arguments: ${STARTUP_CMD[*]}"
|
|
echo "[DEBUG] Argument count: ${#STARTUP_CMD[@]}"
|
|
|
|
# If no command is provided by Pterodactyl, use a default.
|
|
if [ ${#STARTUP_CMD[@]} -eq 0 ] || [ "${STARTUP_CMD[0]}" == "/entrypoint.sh" ] || [ -z "${STARTUP_CMD[0]}" ]; then
|
|
echo "[INFO] No startup command from Pterodactyl. Using default."
|
|
# Set the default command to run
|
|
STARTUP_CMD=(wine64 Nomad/Nomad.exe -batchmode -nographics)
|
|
fi
|
|
|
|
echo "[INFO] Final startup command: ${STARTUP_CMD[*]}"
|
|
echo ""
|
|
|
|
# Run the server in the background
|
|
/usr/bin/xvfb-run --auto-servernum --server-args='-screen 0 640x480x24:32' "${STARTUP_CMD[@]}" &
|
|
|
|
# Capture the Process ID (PID) of the last background command
|
|
SERVER_PID=$!
|
|
|
|
# Wait a few seconds to allow the server to initialize
|
|
echo "[INFO] Waiting for server to initialize (5 seconds)..."
|
|
sleep 5
|
|
|
|
# Echo the "done" message for Pterodactyl to detect
|
|
echo "[PTERODACTYL_DONE] Server should be running now."
|
|
|
|
# Wait for the server process to exit
|
|
# This keeps the container running as long as the server is running
|
|
wait ${SERVER_PID}
|
|
|
|
echo "[INFO] Server process with PID ${SERVER_PID} has stopped."
|
|
exit 0 |