#!/usr/bin/env bash
# cs16ctl - CS 1.6 szerver üzemeltetési CLI
set -euo pipefail

SELF=$(readlink -f -- "${BASH_SOURCE[0]}" 2>/dev/null || printf '%s' "${BASH_SOURCE[0]}")
TOOLS_DIR=$(cd -- "$(dirname -- "$SELF")" && pwd)
if [[ -d $TOOLS_DIR/installer/lib ]]; then
    INSTALLER_DIR="$TOOLS_DIR/installer"
else
    INSTALLER_DIR="$TOOLS_DIR"
fi
SCRIPT_DIR="$INSTALLER_DIR"
CONFIG_FILE=${CS16CTL_CONFIG:-/etc/cs16/cs16.conf}

# shellcheck source=lib/common.sh
source "$INSTALLER_DIR/lib/common.sh"

[[ -r $CONFIG_FILE ]] || die "Nem található a konfiguráció: $CONFIG_FILE (root/sudo?)"
# shellcheck disable=SC1090
source "$CONFIG_FILE"

CS16_SERVER_DIR=${CS16_SERVER_DIR:-/opt/cs16/server}
CS16_TOOLS_DIR=${CS16_TOOLS_DIR:-/opt/cs16/tools}
CS16_USER=${CS16_USER:-cs16}
CS16_GROUP=${CS16_GROUP:-cs16}
CS16_RCON_PASSWORD=${CS16_RCON_PASSWORD:-}
CS16_NET_PROFILE=${CS16_NET_PROFILE:-competitive}
CS16_SYS_TICRATE=${CS16_SYS_TICRATE:-1000}
CS16_MINRATE=${CS16_MINRATE:-25000}
CS16_MAXRATE=${CS16_MAXRATE:-100000}
CS16_MINUPDATERATE=${CS16_MINUPDATERATE:-30}
CS16_MAXUPDATERATE=${CS16_MAXUPDATERATE:-101}
CS16_CLIENTTRACE=${CS16_CLIENTTRACE:-1}
CS16_UNLAG=${CS16_UNLAG:-1}
CS16_MAXUNLAG=${CS16_MAXUNLAG:-0.5}
CS16_UNLAGSAMPLES=${CS16_UNLAGSAMPLES:-1}
CS16_UNLAGPUSH=${CS16_UNLAGPUSH:-0}
CS16_TIMEOUT=${CS16_TIMEOUT:-30}
CS16_VOICE_ENABLE=${CS16_VOICE_ENABLE:-1}
AMXX_DIR="$CS16_SERVER_DIR/cstrike/addons/amxmodx"
USERS_INI="$AMXX_DIR/configs/users.ini"
PLUGINS_INI="$AMXX_DIR/configs/plugins.ini"
ADMIN_BEGIN="; >>> cs16ctl managed admins >>>"
ADMIN_END="; <<< cs16ctl managed admins <<<"
PLUGIN_BEGIN="; >>> cs16 managed plugins >>>"
PLUGIN_END="; <<< cs16 managed plugins <<<"

rcon_cmd() {
    if [[ -z $CS16_RCON_PASSWORD ]]; then
        warn "Hiányzó RCON jelszó a konfigurációban."
        return 1
    fi
    CS16_RCON_PASSWORD="$CS16_RCON_PASSWORD" \
        python3 "$INSTALLER_DIR/tools/rcon.py" \
        --host 127.0.0.1 --port "${CS16_PORT:-27015}" --timeout "${RCON_TIMEOUT:-4}" "$@"
}

require_control() {
    require_root
    command_exists systemctl || die "systemctl nem elérhető."
}

usage() {
    cat <<'EOF'
cs16ctl - CS 1.6 szerver kezelése

Használat:
  sudo cs16ctl <parancs> [argumentumok]

Parancsok:
  status                  Szolgáltatás, port és játékosok állapota
  start | stop | restart  Szerver indítása/leállítása/újraindítása
  console                 Élő journal log követése
  logs [N]                Utolsó N naplósor (alap: 100)
  rcon <parancs>          RCON parancs küldése
  say <üzenet>            Üzenet a játékosoknak
  map <mapnév>            Map váltása
  hostname <név>          Szervernév azonnali átállítása
  network [show|apply]    Hálózati beállítások megtekintése/újratöltése
  network set <kulcs> <érték>  Pl. network set sys_ticrate 500
  stats [info|reset]      StatsX adatok megtekintése/törlése
  admin list              Adminok listázása
  admin add <steamid> [név] [owner|admin|moderator]
  admin remove <steamid>
  admin reload            Adminok újratöltése
  plugin list             Pluginok listázása
  plugin enable <név>     Plugin engedélyezése
  plugin disable <név>    Plugin letiltása
  plugin install <fájl>   .amxx plugin telepítése
  fastdl sync             FastDL fájlok szinkronizálása
  backup [címke]          Mentés készítése
  restore <fájl>          Mentés visszaállítása
  update --check          Telepített és elérhető verziók
  update --apply          Telepítő újrafuttatása (javítás/újratelepítés)
  doctor                  Részletes állapotellenőrzés
  version                 Telepített verziók
  config                  Konfiguráció (RCON nélkül)
  help                    Ez a súgó
EOF
}

cmd_status() {
    systemctl status cs16 --no-pager -l 2>/dev/null || true
    printf '\nPort: '
    if ss -H -lun 2>/dev/null | awk '{print $4}' | sed 's/.*://' | grep -qx "${CS16_PORT:-27015}"; then
        printf '%s/UDP figyel\n' "${CS16_PORT:-27015}"
    else
        printf '%s/UDP NEM figyel\n' "${CS16_PORT:-27015}"
    fi
    if [[ ${EUID:-$(id -u)} -eq 0 && -n $CS16_RCON_PASSWORD ]]; then
        printf '\nRCON status:\n'
        rcon_cmd status 2>&1 || true
    fi
}

cmd_admin() {
    local sub=${1:-list}
    shift || true
    require_root
    [[ -f $USERS_INI ]] || die "Nem található: $USERS_INI"
    case "$sub" in
        list)
            printf 'SteamID                  Jogok                          Megjegyzés\n'
            grep -E '^"STEAM_[0-9]:[0-9]:[0-9]+"' "$USERS_INI" 2>/dev/null | while IFS= read -r line; do
                local id flags comment
                id=$(awk -F'"' '{print $2}' <<<"$line")
                flags=$(awk -F'"' '{print $6}' <<<"$line")
                comment=$(sed -n 's/.*;[[:space:]]*//p' <<<"$line")
                printf '%-24s %-30s %s\n' "$id" "${flags:-?}" "${comment:-}"
            done
            ;;
        add)
            local id=${1:?SteamID kell} name=${2:-Admin} level=${3:-admin} flags line
            [[ $id =~ ^STEAM_[0-9]:[0-9]:[0-9]+$ ]] || die "Érvénytelen SteamID: $id"
            name=${name//\"/}
            name=${name//$'\n'/ }
            case "$level" in
                owner) flags="abcdefghijklmnopqrstuv" ;;
                admin) flags="bcdefghijklmnopqrstuv" ;;
                moderator) flags="bcdefijkuv" ;;
                *) die "Szint: owner, admin vagy moderator." ;;
            esac
            line="\"${id}\" \"\" \"${flags}\" \"ce\" ; ${name}"
            if ! grep -qxF "$ADMIN_BEGIN" "$USERS_INI"; then
                ensure_block "$USERS_INI" "$ADMIN_BEGIN" "$ADMIN_END" ""
            fi
            # Ha már létezik, előbb kivesszük, hogy ne legyen duplikált.
            awk -v id="\"${id}\"" 'index($0, id) == 0 { print }' "$USERS_INI" >"$USERS_INI.tmp"
            mv "$USERS_INI.tmp" "$USERS_INI"
            awk -v line="$line" -v end="$ADMIN_END" '
                $0 == end && !done { print line; done = 1 }
                { print }
            ' "$USERS_INI" >"$USERS_INI.tmp"
            mv "$USERS_INI.tmp" "$USERS_INI"
            chown "$CS16_USER:$CS16_GROUP" "$USERS_INI"
            info "Admin hozzáadva: $id ($level)"
            rcon_cmd amx_reloadadmins >/dev/null 2>&1 || warn "Az adminok újratöltése RCON-nal nem sikerült."
            ;;
        remove)
            local id=${1:?SteamID kell}
            grep -qF "\"${id}\"" "$USERS_INI" || die "Nincs ilyen admin: $id"
            awk -v id="\"${id}\"" 'index($0, id) == 0 { print }' "$USERS_INI" >"$USERS_INI.tmp"
            mv "$USERS_INI.tmp" "$USERS_INI"
            chown "$CS16_USER:$CS16_GROUP" "$USERS_INI"
            info "Admin eltávolítva: $id"
            rcon_cmd amx_reloadadmins >/dev/null 2>&1 || warn "Az adminok újratöltése RCON-nal nem sikerült."
            ;;
        reload)
            rcon_cmd amx_reloadadmins
            ;;
        *) die "Ismeretlen admin parancs: $sub" ;;
    esac
}

cmd_plugin() {
    local sub=${1:-list}
    shift || true
    require_root
    case "$sub" in
        list)
            printf 'Pluginok (%s):\n' "$PLUGINS_INI"
            grep -vE '^[[:space:]]*(;|$|//)' "$PLUGINS_INI" 2>/dev/null || true
            ;;
        install)
            local file=${1:?Fájlnév kell}
            [[ -f $file ]] || die "Nem található: $file"
            [[ $file == *.amxx ]] || die "Csak .amxx plugin telepíthető."
            local name
            name=$(basename "$file")
            cp -a "$file" "$AMXX_DIR/plugins/$name"
            chown "$CS16_USER:$CS16_GROUP" "$AMXX_DIR/plugins/$name"
            if ! grep -qxF "$PLUGIN_BEGIN" "$PLUGINS_INI"; then
                ensure_block "$PLUGINS_INI" "$PLUGIN_BEGIN" "$PLUGIN_END" ""
            fi
            if ! grep -qE "^[[:space:]]*${name//./\\.}([[:space:]]|$)" "$PLUGINS_INI"; then
                awk -v line="$name" -v end="$PLUGIN_END" '
                    $0 == end && !done { print line; done = 1 }
                    { print }
                ' "$PLUGINS_INI" >"$PLUGINS_INI.tmp"
                mv "$PLUGINS_INI.tmp" "$PLUGINS_INI"
            fi
            chown "$CS16_USER:$CS16_GROUP" "$PLUGINS_INI"
            info "Plugin telepítve: $name"
            rcon_cmd "amx_loadplug $name" >/dev/null 2>&1 || warn "Az amx_loadplug nem sikerült; mapváltás/újraindítás után töltődik."
            ;;
        enable)
            local name=${1:?Plugin név kell}
            name=${name%.amxx}
            sed -i -E "s|^[[:space:]]*;[[:space:]]*(${name//./\\.}\\.amxx)([[:space:]].*)?$|\\1\\2|" "$PLUGINS_INI"
            chown "$CS16_USER:$CS16_GROUP" "$PLUGINS_INI"
            rcon_cmd "amx_loadplug ${name}.amxx" >/dev/null 2>&1 || warn "Az amx_loadplug nem sikerült."
            info "Plugin engedélyezve: $name"
            ;;
        disable)
            local name=${1:?Plugin név kell}
            name=${name%.amxx}
            awk -v n="$name" '
                $0 ~ "^[[:space:]]*" n "\\.amxx([[:space:]]|$)" { print ";" $0; next }
                { print }
            ' "$PLUGINS_INI" >"$PLUGINS_INI.tmp"
            mv "$PLUGINS_INI.tmp" "$PLUGINS_INI"
            chown "$CS16_USER:$CS16_GROUP" "$PLUGINS_INI"
            rcon_cmd "amx_unloadplug ${name}.amxx" >/dev/null 2>&1 || true
            info "Plugin letiltva: $name"
            ;;
        *) die "Ismeretlen plugin parancs: $sub" ;;
    esac
}

cmd_backup() {
    require_root
    local label=${1:-manual}
    "$CS16_TOOLS_DIR/backup.sh" "$label"
}

cmd_restore() {
    require_root
    local file=${1:?Mentés fájl kell}
    [[ -f $file ]] || die "Nem található: $file"
    tar -tzf "$file" >/dev/null 2>&1 || die "Hibás tar.gz: $file"
    confirm "Visszaállítod a mentést? A jelenlegi konfigok felülíródnak." n || die "Megszakítva."
    "$CS16_TOOLS_DIR/backup.sh" pre-restore
    systemctl stop cs16
    local tmp
    tmp=$(mktemp -d)
    tar -xzf "$file" -C "$tmp"
    [[ -d $tmp/cstrike ]] || { rm -rf "$tmp"; die "A mentés nem tartalmaz cstrike könyvtárat."; }
    cp -a "$tmp/cstrike/." "$CS16_SERVER_DIR/cstrike/"
    if [[ -f $tmp/etc/cs16.conf ]]; then
        cp -a "$tmp/etc/cs16.conf" "$CONFIG_FILE"
        chown root:"$CS16_GROUP" "$CONFIG_FILE"
        chmod 0640 "$CONFIG_FILE"
    fi
    chown -R "$CS16_USER:$CS16_GROUP" "$CS16_SERVER_DIR/cstrike"
    rm -rf "$tmp"
    systemctl start cs16
    info "Visszaállítás kész."
}

cmd_update() {
    local mode=${1:---check}
    require_root
    if [[ $mode == "--check" ]]; then
        printf 'Telepített verziók:\n'
        cat "$CS16_TOOLS_DIR/versions.installed" 2>/dev/null || true
        printf '\nLegújabb upstream kiadások:\n'
        local repo latest
        for repo in rehlds/ReHLDS rehlds/ReGameDLL_CS rehlds/Metamod-R yapb/yapb; do
            latest=$(curl -fsSL --max-time 10 "https://api.github.com/repos/$repo/releases/latest" 2>/dev/null \
                | python3 -c 'import json,sys; print(json.load(sys.stdin).get("tag_name","?"))' 2>/dev/null || printf '?')
            printf '  %-45s %s\n' "$repo" "$latest"
        done
        printf '\nCSDM: klasszikus 2.1.2 (BAILOPAN), pinelt csomag.\n'
        printf 'AMXX: a telepítőben pinelt 1.10 build (a GitHub latest a régi 1.9 stable).\n'
        printf 'Frissítés: töltsd le az új installer csomagot, majd: sudo cs16ctl update --apply\n'
    elif [[ $mode == "--apply" ]]; then
        "$INSTALLER_DIR/install.sh" --upgrade --yes --config "$CONFIG_FILE"
    else
        die "Használat: cs16ctl update --check|--apply"
    fi
}

cmd_fastdl() {
    local sub=${1:-sync}
    [[ $sub == "sync" ]] || die "Használat: cs16ctl fastdl sync"
    require_root
    # shellcheck source=lib/fastdl.sh
    source "$INSTALLER_DIR/lib/fastdl.sh"
    sync_fastdl
}

set_config_var() {
    local key=$1 value=$2
    python3 - "$CONFIG_FILE" "$key" "$value" <<'PY'
import shlex
import sys

path, key, value = sys.argv[1:4]
with open(path, "r", encoding="utf-8") as handle:
    lines = handle.read().splitlines()
out = []
found = False
for line in lines:
    if line.startswith(key + "="):
        out.append(f"{key}={shlex.quote(value)}")
        found = True
    else:
        out.append(line)
if not found:
    out.append(f"{key}={shlex.quote(value)}")
with open(path, "w", encoding="utf-8") as handle:
    handle.write("\n".join(out) + "\n")
PY
    chown root:"$CS16_GROUP" "$CONFIG_FILE" 2>/dev/null || true
    chmod 0640 "$CONFIG_FILE"
}

render_network_config() {
    local file="$CS16_SERVER_DIR/cstrike/cs16-network.cfg"
    require_root
    render_template "$INSTALLER_DIR/templates/cs16-network.cfg.tpl" "$file" \
        "NET_PROFILE=$CS16_NET_PROFILE" \
        "SYS_TICRATE=$CS16_SYS_TICRATE" \
        "MINRATE=$CS16_MINRATE" "MAXRATE=$CS16_MAXRATE" \
        "MINUPDATERATE=$CS16_MINUPDATERATE" "MAXUPDATERATE=$CS16_MAXUPDATERATE" \
        "CLIENTTRACE=$CS16_CLIENTTRACE" \
        "UNLAG=$CS16_UNLAG" "MAXUNLAG=$CS16_MAXUNLAG" \
        "UNLAGSAMPLES=$CS16_UNLAGSAMPLES" "UNLAGPUSH=$CS16_UNLAGPUSH" \
        "TIMEOUT=$CS16_TIMEOUT" \
        "VOICE_ENABLE=$CS16_VOICE_ENABLE"
    chown "$CS16_USER:$CS16_GROUP" "$file"
    chmod 0640 "$file"
}

cmd_hostname() {
    local name="$*" server_cfg="$CS16_SERVER_DIR/cstrike/server.cfg"
    require_root
    [[ -n $name ]] || die "Használat: cs16ctl hostname \"Új szervernév\""
    set_config_var CS16_HOSTNAME "$name"
    if [[ -f $server_cfg ]]; then
        python3 - "$server_cfg" "$name" <<'PY'
import sys

path, name = sys.argv[1:3]
safe = name.replace('"', "'").replace("\n", " ")
with open(path, "r", encoding="utf-8", errors="replace") as handle:
    lines = handle.read().splitlines()
out = []
found = False
for line in lines:
    if line.lstrip().startswith("hostname "):
        out.append(f'hostname "{safe}"')
        found = True
    else:
        out.append(line)
if not found:
    out.append(f'hostname "{safe}"')
with open(path, "w", encoding="utf-8") as handle:
    handle.write("\n".join(out) + "\n")
PY
        chown "$CS16_USER:$CS16_GROUP" "$server_cfg"
    else
        warn "Nem található a server.cfg: $server_cfg"
    fi
    CS16_HOSTNAME=$name
    local rcon_name=${name//\"/}
    rcon_cmd "hostname \"$rcon_name\"" >/dev/null 2>&1 || true
    info "Szervernév beállítva: $name"
}

network_key_var() {
    case "$1" in
        sys_ticrate) printf 'CS16_SYS_TICRATE' ;;
        minrate) printf 'CS16_MINRATE' ;;
        maxrate) printf 'CS16_MAXRATE' ;;
        minupdaterate) printf 'CS16_MINUPDATERATE' ;;
        maxupdaterate) printf 'CS16_MAXUPDATERATE' ;;
        clienttrace) printf 'CS16_CLIENTTRACE' ;;
        voiceenable) printf 'CS16_VOICE_ENABLE' ;;
        unlag) printf 'CS16_UNLAG' ;;
        maxunlag) printf 'CS16_MAXUNLAG' ;;
        unlagsamples) printf 'CS16_UNLAGSAMPLES' ;;
        unlagpush) printf 'CS16_UNLAGPUSH' ;;
        timeout) printf 'CS16_TIMEOUT' ;;
        *) return 1 ;;
    esac
}

validate_network_value() {
    local key=$1 value=$2
    case "$key" in
        sys_ticrate)
            [[ $value =~ ^[0-9]+$ ]] && ((value >= 100 && value <= 2000))
            ;;
        minrate|maxrate)
            [[ $value =~ ^[0-9]+$ ]] && ((value >= 0 && value <= 1000000))
            ;;
        minupdaterate|maxupdaterate)
            [[ $value =~ ^[0-9]+$ ]] && ((value >= 1 && value <= 101))
            ;;
        clienttrace)
            [[ $value =~ ^[0-9]+$ ]] && ((value >= 0 && value <= 2))
            ;;
        voiceenable)
            [[ $value == "0" || $value == "1" ]]
            ;;
        unlag|unlagpush)
            [[ $value == "0" || $value == "1" ]]
            ;;
        unlagsamples)
            [[ $value == "1" || $value == "2" ]]
            ;;
        maxunlag)
            [[ $value =~ ^[0-9]+([.][0-9]+)?$ ]] && awk -v v="$value" 'BEGIN { exit !(v >= 0.1 && v <= 1.0) }'
            ;;
        timeout)
            [[ $value =~ ^[0-9]+$ ]] && ((value >= 10 && value <= 120))
            ;;
        *) return 1 ;;
    esac
}

cmd_network() {
    local sub=${1:-show}
    if [[ $# -gt 0 ]]; then
        shift
    fi
    require_root
    case "$sub" in
        show|"")
            printf 'Hálózati profil: %s\n' "$CS16_NET_PROFILE"
            printf 'sys_ticrate:      %s\n' "$CS16_SYS_TICRATE"
            printf 'sv_minrate:       %s\n' "$CS16_MINRATE"
            printf 'sv_maxrate:       %s\n' "$CS16_MAXRATE"
            printf 'sv_minupdaterate: %s\n' "$CS16_MINUPDATERATE"
            printf 'sv_maxupdaterate: %s\n' "$CS16_MAXUPDATERATE"
            printf 'sv_clienttrace:   %s\n' "$CS16_CLIENTTRACE"
            printf 'sv_voiceenable:   %s\n' "$CS16_VOICE_ENABLE"
            printf 'sv_unlag:         %s\n' "$CS16_UNLAG"
            printf 'sv_maxunlag:      %s\n' "$CS16_MAXUNLAG"
            printf 'sv_unlagsamples:  %s\n' "$CS16_UNLAGSAMPLES"
            printf 'sv_unlagpush:     %s\n' "$CS16_UNLAGPUSH"
            printf 'sv_timeout:       %s\n' "$CS16_TIMEOUT"
            ;;
        apply)
            render_network_config
            rcon_cmd "exec cs16-network.cfg" >/dev/null 2>&1 || true
            info "Hálózati beállítások újragenerálva."
            ;;
        set)
            local key=${1:?Kulcs kell} value=${2:?Érték kell} var
            var=$(network_key_var "$key") || die "Ismeretlen kulcs: $key"
            validate_network_value "$key" "$value" || die "Érvénytelen érték: $key=$value"
            if [[ $key == "minrate" && $CS16_MAXRATE != "0" ]] && ((value > CS16_MAXRATE)); then
                die "A sv_minrate nem lehet nagyobb a sv_maxrate értékénél."
            fi
            if [[ $key == "maxrate" && $value != "0" ]] && ((value < CS16_MINRATE)); then
                die "A sv_maxrate nem lehet kisebb a sv_minrate értékénél."
            fi
            printf -v "$var" '%s' "$value"
            set_config_var "$var" "$value"
            CS16_NET_PROFILE="custom"
            set_config_var CS16_NET_PROFILE "custom"
            render_network_config
            rcon_cmd "exec cs16-network.cfg" >/dev/null 2>&1 || true
            info "Beállítva: $key=$value"
            ;;
        *)
            die "Használat: cs16ctl network [show|apply|set <kulcs> <érték>]"
            ;;
    esac
}

cmd_stats() {
    local sub=${1:-info} file="$AMXX_DIR/data/csstats.dat"
    require_root
    case "$sub" in
        info|"")
            printf 'Statisztika fájl: %s\n' "$file"
            if [[ -f $file ]]; then
                ls -lh "$file"
            else
                printf 'Még nincs adat; az első játékosok után készül.\n'
            fi
            printf '\nJátékbeli parancsok: /top15, /rank, /statsme, /stats, /score, /me\n'
            ;;
        reset)
            confirm "Biztosan törlöd a statisztikákat? Ez nem visszavonható." n || die "Megszakítva."
            rcon_cmd "csstats_reset 1" >/dev/null 2>&1 || true
            info "Statisztikák törlése elküldve."
            ;;
        *)
            die "Használat: cs16ctl stats [info|reset]"
            ;;
    esac
}

cmd_doctor() {
    require_root
    # shellcheck source=lib/smoke.sh
    source "$INSTALLER_DIR/lib/smoke.sh"
    doctor
}

cmd_config() {
    printf 'Konfiguráció: %s\n' "$CONFIG_FILE"
    printf 'Szerver: %s\n' "$CS16_HOSTNAME"
    printf 'Cím: %s:%s (UDP)\n' "${CS16_PUBLIC_IP:-?}" "$CS16_PORT"
    printf 'Slotok: %s, botok: %s, mód: %s\n' "$CS16_SLOTS" "$CS16_BOTS" "$CS16_DM_MODE"
    printf 'Hálózat: %s, sys_ticrate %s, rate %s-%s\n' \
        "$CS16_NET_PROFILE" "$CS16_SYS_TICRATE" "$CS16_MINRATE" "$CS16_MAXRATE"
    printf 'FastDL: %s\n' "${CS16_FASTDL_URL:-kikapcsolva}"
    printf 'RCON jelszó: [rejtett]\n'
}

main() {
    local cmd=${1:-help}
    if [[ $# -gt 0 ]]; then
        shift
    fi
    case "$cmd" in
        help|-h|--help) usage ;;
        status) cmd_status ;;
        start|stop|restart) require_control; systemctl "$cmd" cs16 ;;
        console) journalctl -u cs16 -f -n 50 ;;
        logs) journalctl -u cs16 -n "${1:-100}" --no-pager ;;
        rcon)
            [[ $# -gt 0 ]] || die "RCON parancs kell."
            require_root
            rcon_cmd "$*" || exit 1
            ;;
        say)
            [[ $# -gt 0 ]] || die "Üzenet kell."
            require_root
            rcon_cmd "say $*" || exit 1
            ;;
        map)
            [[ $# -gt 0 ]] || die "Mapnév kell."
            require_root
            [[ -f $CS16_SERVER_DIR/cstrike/maps/$1.bsp ]] || die "Nincs ilyen map: $1"
            rcon_cmd "changelevel $1" || exit 1
            ;;
        hostname) cmd_hostname "$@" ;;
        network) cmd_network "$@" ;;
        stats) cmd_stats "$@" ;;
        admin) cmd_admin "$@" ;;
        plugin) cmd_plugin "$@" ;;
        fastdl) cmd_fastdl "$@" ;;
        backup) cmd_backup "$@" ;;
        restore) cmd_restore "$@" ;;
        update) cmd_update "$@" ;;
        doctor) cmd_doctor ;;
        version) cat "$CS16_TOOLS_DIR/versions.installed" 2>/dev/null || true ;;
        config) cmd_config ;;
        *) die "Ismeretlen parancs: $cmd (cs16ctl help)" ;;
    esac
}

main "$@"
