- docs/ghost-multiplayer.md: the full beta guide - player usage, cvars, relay deployment (VPS build/install, free-tunnel option, verification), logging/troubleshooting and security notes. - tools/ghost_relay.service: hardened systemd unit for the public relay (Restart=on-failure, NoNewPrivileges, PrivateTmp, ProtectSystem). - tools/ghost_relay_deploy.sh: one-shot build + install + enable script for the VPS (GHOST_RELAY_PORT / GHOST_RELAY_VERBOSE overrides; opens the UDP port via ufw). Verified: the exact build line compiles and runs. - README: multiplayer pointer under 'How Do I Play?'.
86 lines
No EOL
2.7 KiB
Bash
Executable file
86 lines
No EOL
2.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Build, install and register the ghost_relay server as a systemd service.
|
|
#
|
|
# Run on the VPS from the repo root (or after copying tools/ and
|
|
# src/native/skate3_native_ghost_* to the server). The relay is
|
|
# dependency-free: it needs only a C++23 compiler (g++/clang), no CMake or
|
|
# rexglue.
|
|
#
|
|
# Usage:
|
|
# ./tools/ghost_relay_deploy.sh
|
|
# GHOST_RELAY_PORT=40002 ./tools/ghost_relay_deploy.sh
|
|
# GHOST_RELAY_VERBOSE=1 ./tools/ghost_relay_deploy.sh
|
|
#
|
|
# Afterwards: systemctl status ghost-relay, journalctl -u ghost-relay -f.
|
|
# Open the UDP port (the script tries `ufw allow <port>/udp`).
|
|
|
|
set -euo pipefail
|
|
|
|
PORT="${GHOST_RELAY_PORT:-40001}"
|
|
VERBOSE_FLAG=""
|
|
if [[ "${GHOST_RELAY_VERBOSE:-0}" == "1" ]]; then
|
|
VERBOSE_FLAG="--verbose"
|
|
fi
|
|
SERVICE_NAME="ghost-relay"
|
|
BIN_PATH="/usr/local/bin/ghost_relay"
|
|
SERVICE_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
|
|
echo "==> Building ghost_relay"
|
|
g++ -std=c++23 -O2 -DSKATE3_RELAY_STANDALONE \
|
|
-I"${REPO_ROOT}/src/native" \
|
|
"${REPO_ROOT}/tools/ghost_relay_main.cpp" \
|
|
"${REPO_ROOT}/src/native/skate3_native_ghost_relay.cpp" \
|
|
-o /tmp/ghost_relay
|
|
/tmp/ghost_relay --help >/dev/null 2>&1 || {
|
|
echo "ERROR: build produced a binary that does not run (missing C++23?)" >&2
|
|
exit 1
|
|
}
|
|
|
|
echo "==> Installing to ${BIN_PATH}"
|
|
sudo install -m 0755 /tmp/ghost_relay "${BIN_PATH}"
|
|
rm -f /tmp/ghost_relay
|
|
|
|
echo "==> Writing ${SERVICE_PATH}"
|
|
sudo tee "${SERVICE_PATH}" >/dev/null <<EOF
|
|
[Unit]
|
|
Description=Skate 3 recomp ghost multiplayer relay
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
ExecStart=${BIN_PATH} --port ${PORT} --max-clients 64 ${VERBOSE_FLAG}
|
|
Restart=on-failure
|
|
RestartSec=2
|
|
NoNewPrivileges=true
|
|
PrivateTmp=true
|
|
ProtectSystem=full
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
echo "==> Enabling + starting ${SERVICE_NAME}"
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable "${SERVICE_NAME}" >/dev/null
|
|
sudo systemctl restart "${SERVICE_NAME}"
|
|
|
|
echo "==> Opening UDP ${PORT}"
|
|
sudo ufw allow "${PORT}/udp" >/dev/null 2>&1 || \
|
|
echo " (ufw not available or not permitted; open UDP ${PORT} yourself)"
|
|
|
|
echo "==> Status"
|
|
sleep 1
|
|
sudo systemctl status "${SERVICE_NAME}" --no-pager || true
|
|
|
|
IP="$(hostname -I 2>/dev/null | awk '{print $1}')"
|
|
if [[ -z "${IP}" ]]; then IP="<this-server-ip>"; fi
|
|
echo
|
|
echo "Done. Clients connect to ${IP}:${PORT}"
|
|
echo "Logs: journalctl -u ${SERVICE_NAME} -f"
|
|
echo "Set the compiled-in default in src/native/skate3_native_ghost_proto.h"
|
|
echo " (kGhostDefaultServer / kGhostDefaultServerPort), or tell players to"
|
|
echo " set skate3_ghost_server=${IP}:${PORT} in the M menu." |