#!/usr/bin/env bash
set -Eeuo pipefail
umask 077
trap 'echo "[FEHLER] Zeile $LINENO: Installation abgebrochen." >&2' ERR
GOLD='\033[1;33m'; RESET='\033[0m'; GREEN='\033[1;32m'
header(){ printf '\n%bFonics FiveM Server Install | FonicsScriptsDE%b\n' "$GOLD" "$RESET"; }
choose(){ local answer; while true; do read -rp "$1 " answer; [[ "$answer" =~ ^[$2]$ ]] && { REPLY="$answer"; return; }; echo 'Ungültige Auswahl.'; done; }
[[ $EUID -eq 0 ]] || { echo 'Bitte mit sudo starten.'; exit 1; }
[[ -f /etc/os-release ]] && . /etc/os-release
[[ "${ID:-}" == ubuntu || "${ID:-}" == debian ]] || { echo 'Nur Debian/Ubuntu unterstützt.'; exit 1; }
command -v apt-get >/dev/null || exit 1
header
echo '1. Mit PHP & Apache (SQL)'; echo '2. Ohne PHP & Apache (SQL)'; choose 'Auswahl [1-2]:' '12'; WEB="$REPLY"
echo; echo '[FiveM Server Installieren]'; echo '1. Über Artifacts'; echo '2. Über hochgeladene Dateien'; choose 'Auswahl [1-2]:' '12'; SOURCE="$REPLY"
VERSION='hochgeladen'; URL=''
if [[ $SOURCE == 1 ]]; then
 echo; echo '[FX Server]'; echo '1. Neueste FX Version'; echo '2. FX Version auswählen'; choose 'Auswahl [1-2]:' '12'; MODE="$REPLY"
 if [[ $MODE == 1 ]]; then URL='https://runtime.fivem.net/artifacts/fivem/build_proot_linux/master/latest/fx.tar.xz'; VERSION='latest'; else
  read -rp 'Vollständige HTTPS-Download-URL des Linux-FXServer-Artifacts: ' URL
  [[ "$URL" =~ ^https://(runtime\.fivem\.net|[^/]*\.fivem\.net)/ ]] || { echo 'Nur offizielle FiveM Artifact-URLs erlaubt.'; exit 1; }
  VERSION="$URL"
 fi
else
 read -rp 'Absoluter Pfad zur hochgeladenen .tar.xz-Datei: ' UPLOAD
 [[ "$UPLOAD" = /* && -f "$UPLOAD" && "$UPLOAD" == *.tar.xz ]] || { echo 'Datei nicht gefunden oder falsches Format.'; exit 1; }
fi
read -rp 'Installationsordner [/opt/fonics-fivem]: ' BASE; BASE="${BASE:-/opt/fonics-fivem}"
[[ "$BASE" = /* && "$BASE" != / && "$BASE" != /etc && "$BASE" != /usr && "$BASE" != /opt ]] || { echo 'Unsicherer Installationspfad.'; exit 1; }
[[ ! -e "$BASE" ]] || { echo 'Ziel existiert bereits. Abbruch zum Schutz vorhandener Daten.'; exit 1; }
read -rp 'Servername [Fonics FiveM]: ' NAME; NAME="${NAME:-Fonics FiveM}"
[[ "$NAME" != *'"'* && "$NAME" != *$'\n'* ]] || { echo 'Ungültiger Servername'; exit 1; }
read -rp 'Öffentliche IP oder Domain für Abschlussanzeige: ' HOST
[[ "$HOST" =~ ^[a-zA-Z0-9.:-]+$ ]] || { echo 'Ungültiger Host.'; exit 1; }
read -rp 'Installation jetzt starten? [ja/NEIN]: ' CONFIRM; [[ "$CONFIRM" == ja ]] || exit 0
export DEBIAN_FRONTEND=noninteractive
apt-get update
apt-get install -y ca-certificates curl xz-utils tar openssl mariadb-server
if [[ "$WEB" == 1 ]]; then
 apt-get install -y apache2 php libapache2-mod-php php-mysql php-mbstring php-xml php-curl php-zip phpmyadmin
 systemctl enable --now apache2
fi
systemctl enable --now mariadb
mkdir -p "$BASE/server" "$BASE/server-data"
TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT
if [[ "$SOURCE" == 1 ]]; then curl -fL --retry 3 --connect-timeout 20 "$URL" -o "$TMP/fx.tar.xz"; else cp -- "$UPLOAD" "$TMP/fx.tar.xz"; fi
xz -t "$TMP/fx.tar.xz"
# Keine absoluten Pfade, Symlinks oder Traversal-Einträge aus fremden Archiven zulassen.
python3 - "$TMP/fx.tar.xz" <<'PY'
import sys,tarfile,pathlib
with tarfile.open(sys.argv[1], 'r:xz') as tf:
 for m in tf:
  p=pathlib.PurePosixPath(m.name)
  if p.is_absolute() or '..' in p.parts or not (m.isfile() or m.isdir()):
   raise SystemExit('Unsicherer Archiveintrag: '+m.name)
PY
tar -xJf "$TMP/fx.tar.xz" -C "$BASE/server" --no-same-owner --no-same-permissions
[[ -f "$BASE/server/run.sh" ]] || { echo 'run.sh fehlt im Archiv'; exit 1; }
chmod +x "$BASE/server/run.sh"
DB='fonics_fivem'; DBUSER='fonics_user'; DBPASS=$(openssl rand -hex 24)
mysql <<SQL
CREATE DATABASE IF NOT EXISTS \`$DB\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS '$DBUSER'@'localhost' IDENTIFIED BY '$DBPASS';
ALTER USER '$DBUSER'@'localhost' IDENTIFIED BY '$DBPASS';
GRANT ALL PRIVILEGES ON \`$DB\`.* TO '$DBUSER'@'localhost';
SQL
# Eigenen unprivilegierten Account verwenden
id -u fonicsfivem >/dev/null 2>&1 || useradd --system --home-dir "$BASE" --shell /usr/sbin/nologin fonicsfivem
chown -R fonicsfivem:fonicsfivem "$BASE"
cat > /etc/systemd/system/fonics-fivem.service <<SERVICE
[Unit]
Description=Fonics FiveM FXServer txAdmin
After=network-online.target mariadb.service
Wants=network-online.target
[Service]
Type=simple
User=fonicsfivem
Group=fonicsfivem
WorkingDirectory=$BASE/server
ExecStart=/bin/bash $BASE/server/run.sh
Restart=on-failure
RestartSec=10
LimitNOFILE=65535
NoNewPrivileges=true
[Install]
WantedBy=multi-user.target
SERVICE
systemctl daemon-reload
systemctl enable fonics-fivem.service
cat > "$BASE/zugangsdaten.txt" <<DATA
FonicsScriptsDE FiveM Installation
Servername: $NAME
Host: $HOST
FX-Version: $VERSION
txAdmin: http://$HOST:40120
FiveM Port: 30120 TCP/UDP
SQL Host: localhost
SQL Port: 3306
SQL Datenbank: $DB
SQL Benutzer: $DBUSER
SQL Passwort: $DBPASS
SQL Connection String: mysql://$DBUSER:$DBPASS@localhost/$DB?charset=utf8mb4
Systemdienst: fonics-fivem
Start: sudo systemctl start fonics-fivem
Stop: sudo systemctl stop fonics-fivem
Logs/PIN: sudo journalctl -u fonics-fivem -f
Cfx.re Lizenzschlüssel: https://portal.cfx.re/
DATA
chown root:root "$BASE/zugangsdaten.txt"; chmod 600 "$BASE/zugangsdaten.txt"
header
printf '%bInstallation abgeschlossen.%b\n' "$GREEN" "$RESET"
cat "$BASE/zugangsdaten.txt"
echo; echo 'Zum Start: sudo systemctl start fonics-fivem'
echo 'Anschließend den txAdmin-PIN in den Logs ablesen.'
echo 'Hinweis: Serverdaten/ESX und Lizenzschlüssel werden im txAdmin-Assistenten eingerichtet.'
