6811caeab1
entrypoint.sh validates/selects among lsx blaze roster utas pow and skips unselected responders (errors if none). docker-compose threads the env through; .env.example documents it. Retained pre-existing WIP verified.
127 lines
5.8 KiB
Bash
127 lines
5.8 KiB
Bash
#!/usr/bin/env bash
|
|
# ============================================================================
|
|
# OpenFUT FIFA-17 FUT backend — in-CONTAINER orchestrator.
|
|
#
|
|
# Runs the 5 network responders that the game dials. Unlike the host-based
|
|
# openfut-fut.sh, this does NO host arming (no pkexec / iptables / /etc/hosts /
|
|
# ptrace) — those are client-side concerns handled on the game machine (105).
|
|
# autopatch.py is NOT run here: it patches the FIFA17.exe process memory and must
|
|
# run on the box the game runs on.
|
|
#
|
|
# Address behaviour is driven by two env vars (see each responder):
|
|
# OPENFUT_BIND bind address for every listener (container: 0.0.0.0)
|
|
# OPENFUT_ADVERTISE address handed to the client for the next hop
|
|
# (the server's LAN IP, e.g. 203.0.113.10)
|
|
# ============================================================================
|
|
set -uo pipefail
|
|
cd "$(dirname "$(readlink -f "$0")")/tools"
|
|
|
|
BIND="${OPENFUT_BIND:-0.0.0.0}"
|
|
ADV="${OPENFUT_ADVERTISE:?OPENFUT_ADVERTISE must be set to the server LAN IP (e.g. 203.0.113.10)}"
|
|
export OPENFUT_BIND="$BIND"
|
|
export OPENFUT_ADVERTISE="$ADV"
|
|
# POW keys advertised by blaze must also point at the server, not loopback.
|
|
export POW_HOST="${POW_HOST:-$ADV:8094}"
|
|
export POW_CONTENT_HOST="${POW_CONTENT_HOST:-$ADV:8080}"
|
|
export POW_ADDR="${POW_ADDR:-$BIND:8094}"
|
|
export POW_CONTENT_ADDR="${POW_CONTENT_ADDR:-$BIND:8080}"
|
|
|
|
echo "[openfut] bind=$BIND advertise=$ADV"
|
|
|
|
# The TLS cert every responder serves must carry the ADVERTISED IP in its SAN.
|
|
# The client dials the roster (:8081) and redirector by that IP, and that path
|
|
# validates the cert's SAN against the dialed address — it is NOT covered by the
|
|
# two client-side ProtoSSL gates autopatch patches, so a cert lacking IP:$ADV is
|
|
# rejected with fatal certificate_unknown and the FUT hub fails with "An error
|
|
# occurred downloading the FUT Squad Update" (docs/FIFA17_FUT_SQUAD_UPDATE_TLS.md).
|
|
# The advertised IP is unknown at image-build time, so reconcile it here: reissue
|
|
# only when the current cert does not already carry it, so a restart reuses the
|
|
# same cert (no per-start fingerprint churn) and this self-heals if $ADV changes.
|
|
CERT=redir_cert.pem KEY=redir_key.pem
|
|
if ! openssl x509 -in "$CERT" -noout -ext subjectAltName 2>/dev/null | grep -qF "IP Address:$ADV"; then
|
|
echo "[openfut] reissuing TLS cert with SAN IP:$ADV (was missing it)"
|
|
openssl req -x509 -newkey rsa:2048 -nodes -keyout "$KEY" -out "$CERT" -days 3650 \
|
|
-subj "/CN=winter15.gosredirector.ea.com" \
|
|
-addext "subjectAltName=DNS:winter15.gosredirector.ea.com,DNS:*.gosredirector.ea.com,DNS:*.ea.com,IP:$ADV,IP:127.0.0.1" \
|
|
>/dev/null 2>&1 \
|
|
&& echo "[openfut] cert SAN now: $(openssl x509 -in "$CERT" -noout -ext subjectAltName 2>/dev/null | tail -1 | tr -s ' ')" \
|
|
|| { echo "[openfut] FATAL: could not reissue TLS cert" >&2; exit 1; }
|
|
fi
|
|
|
|
# name script extra-env
|
|
declare -a SERVERS=(
|
|
"lsx|lsx_responder_v2.py|OPENFUT_LSX_EVENT_COUNT=100000"
|
|
"blaze|blaze_responder_v3b.py|-"
|
|
"roster|roster_server.py|-"
|
|
"utas|utas_server.py|FUT_TRADING=1 FUT_PILESIZES=1 FUT_TRADEABLE=1 FUT_DISCARD_TABLE=1 FUT_DISCARD_SEND=1"
|
|
"pow|pow_server.py|-"
|
|
)
|
|
|
|
# ── Component selection ──────────────────────────────────────────────────────
|
|
# OPENFUT_SERVERS picks which Python responders run (space- or comma-separated).
|
|
# This container is the SERVER side (.120). It serves ONLY components that have
|
|
# NOT been migrated to a Rust host — as each moves to Rust (which runs OUTSIDE
|
|
# Docker during migration), drop its name so the two never serve the same role.
|
|
# blaze Blaze redirector + main + nucleus (bundled) :42127 :42130 :42131
|
|
# roster FUT roster-update XML :8081
|
|
# utas FUT/UTAS RS4 API :8099
|
|
# (the Rust utas-host currently reverse-proxies its non-/club routes
|
|
# back here, so keep this enabled until UTAS is fully migrated)
|
|
# pow POW / EASFC :8094 (+ content :8080)
|
|
# lsx Origin LSX bootstrap :4216
|
|
# CLIENT-SIDE — LSX runs on the game machine (.105) with autopatch,
|
|
# NOT on the server. Excluded by default; enable ONLY for an
|
|
# all-on-one-box dev setup where client and server share a host.
|
|
OPENFUT_SERVERS="${OPENFUT_SERVERS:-blaze roster utas pow}"
|
|
want=" ${OPENFUT_SERVERS//,/ } "
|
|
known=" lsx blaze roster utas pow "
|
|
for w in $want; do
|
|
case "$known" in
|
|
*" $w "*) ;;
|
|
*) echo "[openfut] unknown component '$w' in OPENFUT_SERVERS (valid: lsx blaze roster utas pow)" >&2; exit 2 ;;
|
|
esac
|
|
done
|
|
echo "[openfut] servers=$OPENFUT_SERVERS"
|
|
|
|
pids=()
|
|
names=()
|
|
for entry in "${SERVERS[@]}"; do
|
|
IFS='|' read -r name script env <<<"$entry"
|
|
case "$want" in
|
|
*" $name "*) ;;
|
|
*) echo "[openfut] skipping $name (not in OPENFUT_SERVERS)"; continue ;;
|
|
esac
|
|
envprefix=""; [ "$env" != "-" ] && envprefix="env $env"
|
|
echo "[openfut] starting $name ($script)"
|
|
# shellcheck disable=SC2086
|
|
$envprefix python3 -u "$script" &
|
|
pids+=($!)
|
|
names+=("$name")
|
|
done
|
|
|
|
if [ "${#pids[@]}" -eq 0 ]; then
|
|
echo "[openfut] OPENFUT_SERVERS selected no components; nothing to run" >&2
|
|
exit 2
|
|
fi
|
|
|
|
# Propagate SIGTERM/SIGINT to children so `docker stop` is clean.
|
|
term() {
|
|
echo "[openfut] shutting down…"
|
|
for p in "${pids[@]}"; do kill "$p" 2>/dev/null || true; done
|
|
wait
|
|
exit 0
|
|
}
|
|
trap term TERM INT
|
|
|
|
# If ANY responder dies, take the whole container down so the failure is visible
|
|
# (they all bind ports the game needs — a partial stack is a broken stack).
|
|
while true; do
|
|
for i in "${!pids[@]}"; do
|
|
if ! kill -0 "${pids[$i]}" 2>/dev/null; then
|
|
echo "[openfut] responder ${names[$i]} (pid ${pids[$i]}) exited - bringing container down"
|
|
term
|
|
fi
|
|
done
|
|
sleep 2
|
|
done
|