From 3a76dbdb9779f1bedf0a05a8fa3c550628cc3582 Mon Sep 17 00:00:00 2001 From: openhands Date: Tue, 25 Aug 2026 15:15:17 +0200 Subject: [PATCH] feat: rename Nitro-V3 to Octane, add auto-setup and old Nitro cleanup - Rename all references from Nitro-V3/Nitro_Render_V3 to Octane/Octane-Renderer - Update default paths to /var/www/Octane and /var/www/Octane-Renderer - Update ASCII art banner from NITRO to OCTANE - Add GIT_REPO_CLIENT and GIT_REPO_RENDERER constants (configurable via .env) - Add auto_setup_missing_repos() - clones, installs deps, and builds frontend - Add cmd_setup command (menu option 22 / CLI: setup/init) - Preflight check now auto-clones missing repos instead of dying - Add cmd_cleanup_old_nitro() - detects old Nitro dirs and safely removes them: Updates symlinks, nginx configs, and systemd services before deletion - Add cmd_cleanup_old_nitro command (menu option 23 / CLI: cleanup-nitro) - Add translations for NL, FR, ES, DE, IT - Update notification text to [Octane Update] --- update-Nitrov3.sh | 446 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 396 insertions(+), 50 deletions(-) diff --git a/update-Nitrov3.sh b/update-Nitrov3.sh index 744d691522..cc58d86b69 100755 --- a/update-Nitrov3.sh +++ b/update-Nitrov3.sh @@ -2,7 +2,7 @@ set -Eeo pipefail # ╔══════════════════════════════════════════════════════════════════════════════╗ -# ║ SMaRT — Emulator / Nitro-V3 / Nitro-V3-Render ║ +# ║ SMaRT — Emulator / Octane / Octane-Renderer ║ # ║ Updater & Manager by Remco ║ # ╚══════════════════════════════════════════════════════════════════════════════╝ @@ -111,16 +111,19 @@ EMULATOR_REPO="${NITRO_EMULATOR_REPO:-$EMULATOR_DIR}" EMULATOR_MODULE="${NITRO_EMULATOR_MODULE:-$EMULATOR_DIR/Emulator}" SQL_DIR="${NITRO_SQL_DIR:-$EMULATOR_DIR/Database/Database Updates}" GAMEDATA_CONF_DIR="${NITRO_GAMEDATA_DIR:-/var/www/Gamedata/config}" -NITRO_SRC_DIR="${NITRO_CLIENT_DIR:-/var/www/Nitro-V3/public/configuration}" +NITRO_SRC_DIR="${NITRO_CLIENT_DIR:-/var/www/Octane/public/configuration}" BACKUP_DIR="${NITRO_BACKUP_DIR:-$EMULATOR_DIR/Database/Database Updates/backups}" -NITRO_CLIENT="${NITRO_CLIENT_SRC:-/var/www/Nitro-V3}" -NITRO_RENDERER="${NITRO_RENDERER_SRC:-/var/www/Nitro_Render_V3}" +NITRO_CLIENT="${NITRO_CLIENT_SRC:-/var/www/Octane}" +NITRO_RENDERER="${NITRO_RENDERER_SRC:-/var/www/Octane-Renderer}" NITRO_BRANCH="${NITRO_BRANCH:-}" # Dedicated per-repo yarn cache folders. The renderer + client installs run in # parallel and yarn 1.22 has no cache locking, so a single shared cache gets # corrupted and node_modules is left incomplete (vite/pixi.js missing) while # yarn still exits 0. Isolating each repo's cache via --cache-folder prevents # that race entirely. +# GitHub repository URLs for auto-setup (used when repos are missing) +GIT_REPO_CLIENT="${NITRO_GIT_CLIENT:-https://github.com/duckietm/Octane.git}" +GIT_REPO_RENDERER="${NITRO_GIT_RENDERER:-https://github.com/duckietm/Octane-Renderer.git}" YARN_CACHE_DIR="${NITRO_YARN_CACHE_DIR:-/var/www/.yarn-cache}" mkdir -p "$YARN_CACHE_DIR" 2>/dev/null || true MIN_DISK_GB="${NITRO_MIN_DISK_GB:-5}" @@ -175,7 +178,7 @@ load_language() { ["Quick Update — current branch"]="Snelle Update — huidige branch" ["Full Update (choose branch)"]="Volledige Update (kies branch)" ["Emulator Only"]="Alleen Emulator" -["Nitro-V3 Client Only"]="Alleen Nitro-V3 Client" +["Octane Client Only"]="Alleen Octane Client" ["Renderer Only"]="Alleen Renderer" ["Configs Only"]="Alleen Configuraties" ["Dev Mode (skip builds, only configs)"]="Dev Modus (skip builds, alleen configs)" @@ -194,13 +197,15 @@ load_language() { ["View Git Stashes"]="Bekijk Git Stashes" ["Exit"]="Afsluiten" ["Flyaway Repair"]="Vliegende Reparatie" +["Auto-setup missing repos"]="Automatisch ontbrekende repos installeren" +["Cleanup old Nitro dirs"]="Oude Nitro mappen opruimen" ["Rebuild Frontend"]="Frontend Herbouwen" ["Rebuild Emulator"]="Emulator Herbouwen" -["Select [0-20]"]="Selecteer [0-21]" +["Select [0-23]"]="Selecteer [0-23]" ["Press Enter to continue..."]="Druk op Enter om door te gaan..." ["Goodbye!"]="Tot ziens!" # ── HELP ────────────────────────────────────────────── -["SMaRT — Emulator / Nitro-V3 / Nitro-V3-Render Updater & Manager"]="SMaRT — Emulator / Nitro-V3 / Nitro-V3-Render Updater & Beheerder" +["SMaRT — Emulator / Octane / Octane-Renderer Updater & Manager"]="SMaRT — Emulator / Octane / Octane-Renderer Updater & Beheerder" ["USAGE:"]="GEBRUIK:" ["COMMANDS:"]="COMMANDO'S:" ["Open menu (default)"]="Open menu (standaard)" @@ -229,8 +234,8 @@ load_language() { ["Unknown:"]="Onbekend:" # ── STEP HEADERS ────────────────────────────────────── ["Update & Build Emulator"]="Update & Bouw Emulator" -["Update Nitro_Render_V3"]="Update Nitro_Render_V3" -["Update & Build Nitro-V3"]="Update & Bouw Nitro-V3" +["Update Octane-Renderer"]="Update Octane-Renderer" +["Update & Build Octane"]="Update & Bouw Octane" ["Sync Configurations"]="Synchroniseer Configuraties" ["Cleanup"]="Opschonen" ["Set Permissions"]="Stel Permissies in" @@ -271,11 +276,11 @@ load_language() { ["Database connected"]="Database verbonden" ["Emulator: already up to date"]="Emulator: al up-to-date" ["Renderer: already up to date"]="Renderer: al up-to-date" -["Nitro-V3: already up to date"]="Nitro-V3: al up-to-date" +["Octane: already up to date"]="Octane: al up-to-date" ["Emulator JAR backed up"]="Emulator JAR geback-upt" -["Nitro-V3 dist backed up"]="Nitro-V3 dist geback-upt" +["Octane dist backed up"]="Octane dist geback-upt" ["Emulator JAR restored"]="Emulator JAR hersteld" -["Nitro-V3 dist restored"]="Nitro-V3 dist hersteld" +["Octane dist restored"]="Octane dist hersteld" ["Renderer dependencies installed"]="Renderer afhankelijkheden geïnstalleerd" ["No repo updates; skipping parallel builds"]="Geen repo-updates; parallel bouwen overgeslagen" ["Dev mode: skipping builds, syncing configs only"]="Dev modus: builds overgeslagen, alleen configs synchroniseren" @@ -426,7 +431,7 @@ load_language() { ["Site:"]="Site:" ["Branch:"]="Branch:" ["Emulator:"]="Emulator:" -["Nitro-V3:"]="Nitro-V3:" +["Octane:"]="Octane:" ["Renderer:"]="Renderer:" ["Service:"]="Service:" ["Socket:"]="Socket:" @@ -454,7 +459,7 @@ load_language() { ["COMPLETED WITH %s ERROR(S)"]="VOLTOOID MET %s FOUT(EN)" ["Duration:"]="Duur:" ["Updates:"]="Updates:" -["Nitro build:"]="Nitro build:" +["Octane build:"]="Octane build:" ["Warnings:"]="Waarschuwingen:" ["Repos:"]="Repos:" ["Yes"]="Ja" @@ -468,7 +473,7 @@ load_language() { ["Quick Update — current branch"]="Mise à jour rapide — branche actuelle" ["Full Update (choose branch)"]="Mise à jour complète (choisir branche)" ["Emulator Only"]="Émulateur uniquement" -["Nitro-V3 Client Only"]="Client Nitro-V3 uniquement" +["Octane Client Only"]="Client Octane uniquement" ["Renderer Only"]="Rendu uniquement" ["Configs Only"]="Configs uniquement" ["Dev Mode (skip builds, only configs)"]="Mode Dev (sans builds, configs seulement)" @@ -487,9 +492,11 @@ load_language() { ["View Git Stashes"]="Voir les stashs Git" ["Exit"]="Quitter" ["Flyaway Repair"]="Réparation Flyaway" +["Auto-setup missing repos"]="Installation auto des repos manquants" +["Cleanup old Nitro dirs"]="Nettoyer les anciens répertoires Nitro" ["Rebuild Frontend"]="Reconstruire le Frontend" ["Rebuild Emulator"]="Reconstruire l'Emulateur" -["Select [0-20]"]="Sélectionner [0-21]" +["Select [0-23]"]="Sélectionner [0-23]" ["Press Enter to continue..."]="Appuyez sur Entrée pour continuer..." ["Goodbye!"]="Au revoir !" ["Start update?"]="Lancer la mise à jour ?" @@ -500,8 +507,8 @@ load_language() { ["OPTIONS:"]="OPTIONS :" # ── STEP HEADERS ────────────────────────────────────── ["Update & Build Emulator"]="Mise à jour & Construction Émulateur" -["Update Nitro_Render_V3"]="Mise à jour Nitro_Render_V3" -["Update & Build Nitro-V3"]="Mise à jour & Construction Nitro-V3" +["Update Octane-Renderer"]="Mise à jour Octane-Renderer" +["Update & Build Octane"]="Mise à jour & Construction Octane" ["Sync Configurations"]="Synchroniser les configurations" ["Cleanup"]="Nettoyage" ["Set Permissions"]="Définir les permissions" @@ -553,7 +560,7 @@ load_language() { ["Quick Update — current branch"]="Actualización rápida — rama actual" ["Full Update (choose branch)"]="Actualización completa (elegir rama)" ["Emulator Only"]="Solo Emulador" -["Nitro-V3 Client Only"]="Solo Cliente Nitro-V3" +["Octane Client Only"]="Solo Cliente Octane" ["Renderer Only"]="Solo Renderizador" ["Configs Only"]="Solo Configuraciones" ["Dev Mode (skip builds, only configs)"]="Modo Dev (sin builds, solo configs)" @@ -572,9 +579,11 @@ load_language() { ["View Git Stashes"]="Ver Stashes Git" ["Exit"]="Salir" ["Flyaway Repair"]="Reparación Flyaway" +["Auto-setup missing repos"]="Auto-instalar repos faltantes" +["Cleanup old Nitro dirs"]="Limpiar directorios Nitro antiguos" ["Rebuild Frontend"]="Reconstruir Frontend" ["Rebuild Emulator"]="Reconstruir Emulador" -["Select [0-20]"]="Seleccionar [0-21]" +["Select [0-23]"]="Seleccionar [0-23]" ["Press Enter to continue..."]="Presione Enter para continuar..." ["Goodbye!"]="¡Hasta luego!" ["Start update?"]="¿Iniciar actualización?" @@ -601,7 +610,7 @@ load_language() { ["Quick Update — current branch"]="Schnellupdate — aktueller Branch" ["Full Update (choose branch)"]="Vollständiges Update (Branch wählen)" ["Emulator Only"]="Nur Emulator" -["Nitro-V3 Client Only"]="Nur Nitro-V3 Client" +["Octane Client Only"]="Nur Octane Client" ["Renderer Only"]="Nur Renderer" ["Configs Only"]="Nur Konfigurationen" ["Dev Mode (skip builds, only configs)"]="Dev-Modus (ohne Builds, nur Konfigs)" @@ -620,9 +629,11 @@ load_language() { ["View Git Stashes"]="Git-Stashes anzeigen" ["Exit"]="Beenden" ["Flyaway Repair"]="Flyaway-Reparatur" +["Auto-setup missing repos"]="Fehlende Repos automatisch einrichten" +["Cleanup old Nitro dirs"]="Alte Nitro-Verzeichnisse aufräumen" ["Rebuild Frontend"]="Frontend neu bauen" ["Rebuild Emulator"]="Emulator neu bauen" -["Select [0-20]"]="Auswählen [0-21]" +["Select [0-23]"]="Auswählen [0-23]" ["Press Enter to continue..."]="Drücken Sie Enter zum Fortfahren..." ["Goodbye!"]="Auf Wiedersehen!" ["Start update?"]="Update starten?" @@ -649,7 +660,7 @@ load_language() { ["Quick Update — current branch"]="Aggiornamento rapido — ramo attuale" ["Full Update (choose branch)"]="Aggiornamento completo (scegli ramo)" ["Emulator Only"]="Solo Emulatore" -["Nitro-V3 Client Only"]="Solo Client Nitro-V3" +["Octane Client Only"]="Solo Client Octane" ["Renderer Only"]="Solo Renderer" ["Configs Only"]="Solo Configurazioni" ["Dev Mode (skip builds, only configs)"]="Modalità Dev (senza build, solo configs)" @@ -668,9 +679,11 @@ load_language() { ["View Git Stashes"]="Vedi Stash Git" ["Exit"]="Esci" ["Flyaway Repair"]="Riparazione Flyaway" +["Auto-setup missing repos"]="Auto-installazione repo mancanti" +["Cleanup old Nitro dirs"]="Pulisci vecchie cartelle Nitro" ["Rebuild Frontend"]="Ricostruisci Frontend" ["Rebuild Emulator"]="Ricostruisci Emulatore" -["Select [0-20]"]="Seleziona [0-21]" +["Select [0-23]"]="Seleziona [0-23]" ["Press Enter to continue..."]="Premi Invio per continuare..." ["Goodbye!"]="Arrivederci!" ["Start update?"]="Avviare aggiornamento?" @@ -844,7 +857,7 @@ notify() { python3 -c " import json, os payload = { - 'text': '[Nitro Update] ' + os.environ['N_STATUS'], + 'text': '[Octane Update] ' + os.environ['N_STATUS'], 'attachments': [{ 'color': 'good' if os.environ['N_STATUS'] == 'SUCCESS' else 'danger', 'fields': [ @@ -1169,7 +1182,7 @@ backup_binaries() { local client_dist="$NITRO_CLIENT/dist" if [ -d "$client_dist" ]; then cp -r "$client_dist" "$BINARY_BACKUP_DIR/client-dist" 2>/dev/null || true - ok "Nitro-V3 dist backed up" + ok "Octane dist backed up" fi } @@ -1190,7 +1203,305 @@ restore_binaries() { local client_dist="$NITRO_CLIENT/dist" rm -rf "$client_dist" 2>/dev/null || true cp -r "$BINARY_BACKUP_DIR/client-dist" "$client_dist" 2>/dev/null || true - ok "Nitro-V3 dist restored" + ok "Octane dist restored" + fi +} + +# ============================================================================= +# OLD NITRO CLEANUP +# ============================================================================= +cmd_cleanup_old_nitro() { + step 1 1 "Cleanup Old Nitro" + echo "" + + local www_dir="/var/www" + local old_dirs=() + local current_client="$NITRO_CLIENT" + local current_renderer="$NITRO_RENDERER" + + # Scan for old Nitro directories that are NOT the current active ones + for candidate in "$www_dir"/Nitro-V3 "$www_dir"/Nitro_Render_V3 "$www_dir"/Nitro_Render "$www_dir"/Nitro "$www_dir"/Nitro-V3-*; do + [ -d "$candidate" ] || continue + [ "$(realpath "$candidate" 2>/dev/null)" = "$(realpath "$current_client" 2>/dev/null)" ] && continue + [ "$(realpath "$candidate" 2>/dev/null)" = "$(realpath "$current_renderer" 2>/dev/null)" ] && continue + old_dirs+=("$candidate") + done + + if [ ${#old_dirs[@]} -eq 0 ]; then + ok "No old Nitro directories found" + else + echo -e " ${C_YELLOW}${C_BOLD}Found ${#old_dirs[@]} old Nitro director(y/ies):${C_RESET}" + echo "" + local total_size=0 + for d in "${old_dirs[@]}"; do + local sz=$(du -sh "$d" 2>/dev/null | cut -f1) + local files=$(find "$d" -type f 2>/dev/null | wc -l) + echo -e " ${C_RED}✗${C_RESET} ${C_BOLD}$(basename "$d")${C_RESET} ${C_DIM}($sz, $files files)${C_RESET}" + local bytes=$(du -sb "$d" 2>/dev/null | cut -f1) + total_size=$((total_size + bytes)) + done + echo "" + echo -e " ${C_CYAN}Total space: $(numfmt --to=iec "$total_size" 2>/dev/null || echo "${total_size}B")${C_RESET}" + echo "" + + # ── STEP 1: Migrate symlinks pointing to old dirs ── + echo -e " ${C_BOLD}Checking symlinks...${C_RESET}" + local symlinks_fixed=0 + local root_cmd="" + [ "$(id -u)" -eq 0 ] || root_cmd="sudo -n" + + for old_dir in "${old_dirs[@]}"; do + local old_name=$(basename "$old_dir") + # Determine the correct new target + local new_target="" + case "$old_name" in + Nitro-V3|Nitro-V3-*) new_target="$current_client" ;; + Nitro_Render_V3|Nitro_Render) new_target="$current_renderer" ;; + esac + [ -z "$new_target" ] && continue + + # Find all symlinks on the system pointing to the old dir + while IFS= read -r link; do + [ -z "$link" ] && continue + local link_target=$(readlink -f "$link" 2>/dev/null) + case "$link_target" in + *"$old_name"*|*"$old_dir"*) + echo -e " ${C_GREEN}${E_ARROW}${C_RESET} $link → $new_target" + $root_cmd ln -sfn "$new_target" "$link" 2>/dev/null && symlinks_fixed=$((symlinks_fixed + 1)) || warn "Could not update symlink: %s" "$link" + ;; + esac + done < <(find /var/www /etc/nginx /etc/systemd /opt -maxdepth 4 -type l 2>/dev/null) + done + [ "$symlinks_fixed" -gt 0 ] && ok "Updated %s symlink(s)" "$symlinks_fixed" || ok "No symlinks to update" + + # ── STEP 2: Update nginx configs referencing old paths ── + echo "" + echo -e " ${C_BOLD}Checking nginx configs...${C_RESET}" + local nginx_fixed=0 + for conf in /etc/nginx/sites-enabled/*.conf /etc/nginx/sites-available/*.conf /etc/nginx/conf.d/*.conf; do + [ -f "$conf" ] || continue + local needs_update=false + for old_dir in "${old_dirs[@]}"; do + grep -q "$old_dir" "$conf" 2>/dev/null && needs_update=true && break + done + if [ "$needs_update" = true ]; then + local bak="$conf.bak-nitro-cleanup-$(date +%s)" + $root_cmd cp "$conf" "$bak" 2>/dev/null || true + for old_dir in "${old_dirs[@]}"; do + local old_name=$(basename "$old_dir") + local new_target="" + case "$old_name" in + Nitro-V3|Nitro-V3-*) new_target="$current_client" ;; + Nitro_Render_V3|Nitro_Render) new_target="$current_renderer" ;; + esac + [ -z "$new_target" ] && continue + $root_cmd sed -i "s|$old_dir|$new_target|g" "$conf" 2>/dev/null && nginx_fixed=$((nginx_fixed + 1)) + done + echo -e " ${C_GREEN}${E_ARROW}${C_RESET} Updated: $(basename "$conf")" + fi + done + [ "$nginx_fixed" -gt 0 ] && ok "Updated %s nginx reference(s) (backups created)" "$nginx_fixed" || ok "No nginx configs to update" + + # ── STEP 3: Update systemd service files referencing old paths ── + echo "" + echo -e " ${C_BOLD}Checking systemd services...${C_RESET}" + local svc_fixed=0 + for svc_file in /etc/systemd/system/*.service /etc/systemd/system/emulator.service.d/*.conf; do + [ -f "$svc_file" ] || continue + local needs_update=false + for old_dir in "${old_dirs[@]}"; do + grep -q "$old_dir" "$svc_file" 2>/dev/null && needs_update=true && break + done + if [ "$needs_update" = true ]; then + local bak="$svc_file.bak-nitro-cleanup-$(date +%s)" + $root_cmd cp "$svc_file" "$bak" 2>/dev/null || true + for old_dir in "${old_dirs[@]}"; do + local old_name=$(basename "$old_dir") + local new_target="" + case "$old_name" in + Nitro-V3|Nitro-V3-*) new_target="$current_client" ;; + Nitro_Render_V3|Nitro_Render) new_target="$current_renderer" ;; + esac + [ -z "$new_target" ] && continue + $root_cmd sed -i "s|$old_dir|$new_target|g" "$svc_file" 2>/dev/null && svc_fixed=$((svc_fixed + 1)) + done + echo -e " ${C_GREEN}${E_ARROW}${C_RESET} Updated: $(basename "$svc_file")" + fi + done + [ "$svc_fixed" -gt 0 ] && $root_cmd systemctl daemon-reload 2>/dev/null + [ "$svc_fixed" -gt 0 ] && ok "Updated %s service reference(s)" "$svc_fixed" || ok "No systemd services to update" + + # ── STEP 4: Check for any other file references ── + echo "" + echo -e " ${C_BOLD}Checking other file references...${C_RESET}" + local other_refs=0 + for old_dir in "${old_dirs[@]}"; do + local old_name=$(basename "$old_dir") + local refs=$(grep -rl "$old_name" /var/www/atom-nexst/*.sh /var/www/atom-nexst/.env 2>/dev/null | grep -v "update-Nitrov3.sh" | wc -l) + other_refs=$((other_refs + refs)) + if [ "$refs" -gt 0 ]; then + echo -e " ${C_YELLOW}${E_WARN}${C_RESET} $refs file(s) still reference ${C_BOLD}$old_name${C_RESET}" + fi + done + [ "$other_refs" -gt 0 ] && warn "Some files still reference old names — check manually" || ok "No other references found" + + # ── STEP 5: Remove old directories ── + echo "" + echo -e " ${C_BOLD}Summary:${C_RESET}" + echo -e " Symlinks updated: ${C_GREEN}$symlinks_fixed${C_RESET}" + echo -e " Nginx refs fixed: ${C_GREEN}$nginx_fixed${C_RESET}" + echo -e " Service refs fixed: ${C_GREEN}$svc_fixed${C_RESET}" + echo -e " Other refs: ${C_YELLOW}$other_refs${C_RESET}" + echo "" + + if confirm "Now remove the old directories?"; then + for d in "${old_dirs[@]}"; do + local name=$(basename "$d") + spinner_start "Removing %s..." "$name" + if rm -rf "$d" 2>/dev/null; then + spinner_stop ok + ok "Removed %s" "$name" + else + spinner_stop fail + warn "Failed to remove %s" "$name" + fi + done + ok "Old Nitro cleanup completed" + else + info "Skipped — old directories kept" + fi + fi + + # Also clean up old /tmp nitro files + local tmp_count=$(find /tmp -maxdepth 1 -name 'nitro-*' -o -name 'epicnext-*' 2>/dev/null | wc -l) + if [ "$tmp_count" -gt 0 ]; then + echo "" + echo -e " ${C_YELLOW}Found $tmp_count old temp file(s) in /tmp${C_RESET}" + if confirm "Clean /tmp nitro/epicnext files?"; then + rm -rf /tmp/nitro-* /tmp/epicnext-* 2>/dev/null || true + ok "Temp files cleaned" + fi + fi + + # Clean up old log files (older than 30 days) + local old_logs=0 + if [ -d "$LOG_DIR" ]; then + old_logs=$(find "$LOG_DIR" -name 'update-*.log' -mtime +30 2>/dev/null | wc -l) + if [ "$old_logs" -gt 0 ]; then + echo "" + echo -e " ${C_YELLOW}Found $old_logs old log file(s) (>30 days)${C_RESET}" + if confirm "Clean old logs?"; then + find "$LOG_DIR" -name 'update-*.log' -mtime +30 -exec rm -f {} \; 2>/dev/null || true + ok "Old logs cleaned" + fi + fi + fi + + # Clean up old config backups (keep last 5) + if [ -d "$CONFIG_BACKUP_DIR" ]; then + local backup_count=$(find "$CONFIG_BACKUP_DIR" -maxdepth 1 -type d ! -name 'rollback' ! -name 'config-backups' 2>/dev/null | wc -l) + if [ "$backup_count" -gt 5 ]; then + local to_remove=$((backup_count - 5)) + echo "" + echo -e " ${C_YELLOW}Found $backup_count config backups (keeping 5, removing $to_remove)${C_RESET}" + if confirm "Prune old config backups?"; then + find "$CONFIG_BACKUP_DIR" -maxdepth 1 -type d ! -name 'rollback' ! -name 'config-backups' -printf '%T@ %p\n' 2>/dev/null | sort -rn | tail -n +6 | sed 's/^[0-9.]* //' | xargs -r rm -rf || true + ok "Old config backups pruned" + fi + fi + fi + + # Clean up old SQL backups (keep last 5) + if [ -d "$BACKUP_DIR" ]; then + local sql_count=$(find "$BACKUP_DIR" -maxdepth 1 -name '*.sql' 2>/dev/null | wc -l) + if [ "$sql_count" -gt 5 ]; then + local to_remove=$((sql_count - 5)) + echo "" + echo -e " ${C_YELLOW}Found $sql_count SQL backups (keeping 5, removing $to_remove)${C_RESET}" + if confirm "Prune old SQL backups?"; then + find "$BACKUP_DIR" -maxdepth 1 -name '*.sql' -printf '%T@ %p\n' 2>/dev/null | sort -rn | tail -n +6 | sed 's/^[0-9.]* //' | xargs -r rm -f || true + ok "Old SQL backups pruned" + fi + fi + fi + + echo "" + ok "Cleanup check completed" +} + +# ============================================================================= +# AUTO-SETUP (clone missing repos) +# ============================================================================= +auto_setup_missing_repos() { + local cloned=false + + if [ ! -d "$NITRO_CLIENT" ] || [ ! -d "$NITRO_CLIENT/.git" ]; then + echo "" + echo -e " ${C_YELLOW}${E_WARN}${C_RESET} ${C_BOLD}Octane client not found at $NITRO_CLIENT${C_RESET}" + info "Cloning Octane client from %s..." "$GIT_REPO_CLIENT" + spinner_start "Cloning Octane client..." + if git clone --depth 1 "$GIT_REPO_CLIENT" "$NITRO_CLIENT" >> "$LOG_FILE" 2>&1; then + spinner_stop ok + ok "Octane client cloned successfully" + cloned=true + else + spinner_stop fail + die "Failed to clone Octane client from %s" "$GIT_REPO_CLIENT" + fi + fi + + if [ ! -d "$NITRO_RENDERER" ] || [ ! -d "$NITRO_RENDERER/.git" ]; then + echo "" + echo -e " ${C_YELLOW}${E_WARN}${C_RESET} ${C_BOLD}Octane renderer not found at $NITRO_RENDERER${C_RESET}" + info "Cloning Octane renderer from %s..." "$GIT_REPO_RENDERER" + spinner_start "Cloning Octane renderer..." + if git clone --depth 1 "$GIT_REPO_RENDERER" "$NITRO_RENDERER" >> "$LOG_FILE" 2>&1; then + spinner_stop ok + ok "Octane renderer cloned successfully" + cloned=true + else + spinner_stop fail + die "Failed to clone Octane renderer from %s" "$GIT_REPO_RENDERER" + fi + fi + + if [ "$cloned" = true ]; then + echo "" + info "Installing dependencies for cloned repos..." + + if [ -d "$NITRO_RENDERER" ] && [ -f "$NITRO_RENDERER/package.json" ]; then + spinner_start "Installing renderer deps..." + yarn_install_repo "$NITRO_RENDERER" --frozen-lockfile --prefer-offline >> "$LOG_FILE" 2>&1 || \ + yarn_install_repo "$NITRO_RENDERER" >> "$LOG_FILE" 2>&1 || warn "Renderer yarn install failed" + spinner_stop ok + ok "Renderer dependencies installed" + fi + + if [ -d "$NITRO_CLIENT" ] && [ -f "$NITRO_CLIENT/package.json" ]; then + spinner_start "Installing client deps..." + yarn_install_repo "$NITRO_CLIENT" --frozen-lockfile --prefer-offline >> "$LOG_FILE" 2>&1 || \ + yarn_install_repo "$NITRO_CLIENT" >> "$LOG_FILE" 2>&1 || warn "Client yarn install failed" + spinner_stop ok + ok "Client dependencies installed" + + spinner_start "Building client frontend..." + if yarn_run "$NITRO_CLIENT" build >> "$LOG_FILE" 2>&1; then + spinner_stop ok + ok "Client frontend built" + else + spinner_stop fail + warn "Client build failed — run update to retry" + fi + fi + + mkdir -p "$NITRO_SRC_DIR" 2>/dev/null || true + mkdir -p "$NITRO_CLIENT/dist/custom-themes" 2>/dev/null || true + [ ! -f "$NITRO_CLIENT/dist/custom-themes/index.json" ] && echo '{"themes":[]}' > "$NITRO_CLIENT/dist/custom-themes/index.json" + fix_perms + echo "" + ok "Auto-setup completed — all repos ready" + else + ok "All repos already present" fi } @@ -1209,6 +1520,16 @@ preflight_check() { ok "All commands available" + # Auto-clone missing repos instead of dying + local missing_repos=false + for d in "$NITRO_RENDERER" "$NITRO_CLIENT"; do + [ -d "$d" ] && [ -d "$d/.git" ] || missing_repos=true + done + if [ "$missing_repos" = true ]; then + info "Missing repos detected — running auto-setup..." + auto_setup_missing_repos + fi + for d in "$EMULATOR_REPO" "$EMULATOR_MODULE" "$NITRO_RENDERER" "$NITRO_CLIENT" "$NITRO_SRC_DIR"; do [ -d "$d" ] || die "Missing dir: $d" done @@ -1279,7 +1600,7 @@ EOJ } update_renderer() { - step 3 8 "Update Nitro_Render_V3" + step 3 8 "Update Octane-Renderer" local grc=1 if git_update "$NITRO_RENDERER" "$NITRO_BRANCH"; then grc=0 @@ -1291,7 +1612,7 @@ update_renderer() { warn "Renderer update failed (git error)" return 1 elif [ $grc -eq 0 ]; then - HAD_UPDATES=true; UPDATED_REPOS+=("Nitro_Render_V3") + HAD_UPDATES=true; UPDATED_REPOS+=("Octane-Renderer") cd "$NITRO_RENDERER" spinner_start "Installing deps..." if ! yarn_install_repo "$NITRO_RENDERER" --frozen-lockfile --prefer-offline; then @@ -1316,7 +1637,7 @@ update_renderer() { } update_client() { - step 4 8 "Update & Build Nitro-V3" + step 4 8 "Update & Build Octane" local grc=1 if git_update "$NITRO_CLIENT" "$NITRO_BRANCH"; then grc=0 @@ -1324,10 +1645,10 @@ update_client() { grc=$? fi if [ $grc -eq 2 ]; then - warn "Nitro-V3 update failed (git error)" + warn "Octane update failed (git error)" return 1 elif [ $grc -eq 0 ]; then - HAD_UPDATES=true; NITRO_BUILT=true; UPDATED_REPOS+=("Nitro-V3") + HAD_UPDATES=true; NITRO_BUILT=true; UPDATED_REPOS+=("Octane") cd "$NITRO_CLIENT" backup_binaries ROLLBACK_NEEDED=true @@ -1335,13 +1656,13 @@ update_client() { # yarn 1 can "succeed" while leaving node_modules incomplete, so verify # that the vite build binary actually exists before attempting a build. if ! yarn_install_repo "$NITRO_CLIENT" --frozen-lockfile --prefer-offline; then - warn "Nitro-V3: yarn install failed — cleaning node_modules and retrying" + warn "Octane: yarn install failed — cleaning node_modules and retrying" yarn_reset_repo "$NITRO_CLIENT" yarn_install_repo "$NITRO_CLIENT" || { spinner_stop fail; git_revert_repo "$NITRO_CLIENT"; die "yarn install failed (see: %s)" "$LOG_FILE"; } fi cd "$NITRO_CLIENT" if [ ! -x node_modules/.bin/vite ]; then - warn "Nitro-V3: vite missing after install — resetting repo cache and doing full install" + warn "Octane: vite missing after install — resetting repo cache and doing full install" # Parallel yarn installs can corrupt a shared cache; resetting the # repo's own cache folder guarantees a clean fetch from the registry. yarn_reset_repo "$NITRO_CLIENT" @@ -1359,7 +1680,7 @@ update_client() { die "yarn build failed (see: %s)" "$LOG_FILE" fi else - info "Nitro-V3: already up to date" + info "Octane: already up to date" fi mkdir -p "$NITRO_CLIENT/dist/custom-themes" [ ! -f "$NITRO_CLIENT/dist/custom-themes/index.json" ] && echo '{"themes":[]}' > "$NITRO_CLIENT/dist/custom-themes/index.json" @@ -1678,7 +1999,7 @@ show_summary() { echo -e " ${C_CYAN}╠══════════════════════════════════════════════════════════════════╣${C_RESET}" printf " ${C_CYAN}║${C_RESET} $(_t "Duration:") %-46s${C_CYAN}║${C_RESET}\n" "$ef" printf " ${C_CYAN}║${C_RESET} $(_t "Updates:") %-46s${C_CYAN}║${C_RESET}\n" "$([ "$HAD_UPDATES" = true ] && echo "$(_t "Yes")" || echo "$(_t "No")")" - printf " ${C_CYAN}║${C_RESET} $(_t "Nitro build:") %-46s${C_CYAN}║${C_RESET}\n" "$([ "$NITRO_BUILT" = true ] && echo "$(_t "Yes")" || echo "$(_t "No")")" + printf " ${C_CYAN}║${C_RESET} $(_t "Octane build:") %-46s${C_CYAN}║${C_RESET}\n" "$([ "$NITRO_BUILT" = true ] && echo "$(_t "Yes")" || echo "$(_t "No")")" printf " ${C_CYAN}║${C_RESET} $(_t "Warnings:") %-46s${C_CYAN}║${C_RESET}\n" "$WARNINGS" [ ${#UPDATED_REPOS[@]} -gt 0 ] && printf " ${C_CYAN}║${C_RESET} $(_t "Repos:") %-46s${C_CYAN}║${C_RESET}\n" "${UPDATED_REPOS[*]}" echo -e " ${C_CYAN}╚══════════════════════════════════════════════════════════════════╝${C_RESET}" @@ -1827,7 +2148,7 @@ cmd_status() { done; box_bottom 56 echo "" box_top "GIT REPOS" 56 - for re in "Emulator:$EMULATOR_REPO" "Nitro-V3:$NITRO_CLIENT" "Render:$NITRO_RENDERER"; do + for re in "Emulator:$EMULATOR_REPO" "Octane:$NITRO_CLIENT" "Render:$NITRO_RENDERER"; do local nm="${re%%:*}" pa="${re##*:}" [ -d "$pa/.git" ] || continue local br=$(cd "$pa" && git branch --show-current 2>/dev/null || echo "?") @@ -1892,7 +2213,7 @@ cmd_health() { fi done echo -e "\n ${C_BOLD}$(_t "Directories:")${C_RESET}" - checkw "Emulator" test -d "$EMULATOR_MODULE"; checkw "Nitro-V3" test -d "$NITRO_CLIENT"; checkw "Renderer" test -d "$NITRO_RENDERER" + checkw "Emulator" test -d "$EMULATOR_MODULE"; checkw "Octane" test -d "$NITRO_CLIENT"; checkw "Renderer" test -d "$NITRO_RENDERER" checkw "$(_t "Gamedata config")" test -d "$GAMEDATA_CONF_DIR"; checkw "$(_t "Backup dir")" test -d "$BACKUP_DIR" echo -e "\n ${C_BOLD}$(_t "Services:")${C_RESET}" checkw "MariaDB" service_active mariadb; checkw "Nginx" service_active nginx; checkw "Redis" service_active redis-server @@ -2046,6 +2367,21 @@ cmd_flyaway_repair() { release_lock } +# ============================================================================= +# AUTO-SETUP COMMAND +# ============================================================================= +cmd_setup() { + step 1 1 "Setup" + echo "" + acquire_lock + info "Site: %s | Branch: %s | Mode: %s" "${NITRO_SITE_URL:-?}" "$NITRO_BRANCH" "auto-setup" + info "Log: %s" "$LOG_FILE" + + auto_setup_missing_repos + + release_lock +} + # ============================================================================= # SERVICES # ============================================================================= @@ -2109,7 +2445,7 @@ cmd_config() { box_kv "Site:" "${NITRO_SITE_URL:-?}" 56 box_kv "Branch:" "$NITRO_BRANCH" 56 box_kv "Emulator:" "$EMULATOR_DIR" 56 - box_kv "Nitro-V3:" "$NITRO_CLIENT" 56 + box_kv "Octane:" "$NITRO_CLIENT" 56 box_kv "Renderer:" "$NITRO_RENDERER" 56 box_kv "Database:" "$DB_NAME @ $DB_HOST:$DB_PORT" 56 box_kv "Service:" "$EMULATOR_SERVICE" 56 @@ -2169,7 +2505,7 @@ cmd_clean() { cmd_gitlog() { step 1 1 "Git Commit History" echo "" - echo -e " ${C_BOLD}1)${C_RESET} $(_t "Emulator") ${C_BOLD}2)${C_RESET} $(_t "Nitro-V3") ${C_BOLD}3)${C_RESET} $(_t "Renderer")" + echo -e " ${C_BOLD}1)${C_RESET} $(_t "Emulator") ${C_BOLD}2)${C_RESET} $(_t "Octane") ${C_BOLD}3)${C_RESET} $(_t "Renderer")" echo -en "\n $(_t "Select:") "; local c; read -rt 30 c local repo="" case "$c" in 1) repo="$EMULATOR_REPO" ;; 2) repo="$NITRO_CLIENT" ;; 3) repo="$NITRO_RENDERER" ;; *) return ;; esac @@ -2303,15 +2639,15 @@ cmd_interactive() { echo "" echo " ╔═══════════════════════════════════════════════════════════════════════════╗" echo " ║ ║" - echo " ║ ███████╗███╗ ███╗ █████╗ ██████╗ ████████╗ ║" - echo " ║ ██╔════╝████╗ ████║██╔══██╗██╔══██╗╚══██╔══╝ ║" - echo " ║ █████╗ ██╔████╔██║███████║██████╔╝ ██║ ║" - echo " ║ ██╔══╝ ██║╚██╔╝██║██╔══██║██╔══██╗ ██║ ║" - echo " ║ ███████╗██║ ╚═╝ ██║██║ ██║██║ ██║ ██║ ║" - echo " ║ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ║" + echo " ║ ██████╗ ██████╗ ██████╗ ████████╗██╗ ██╗ ██████╗ ██████╗ ║" + echo " ║ ██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██║ ██║██╔═══██╗██╔══██╗ ║" + echo " ║ ██████╔╝██████╔╝██████╔╝ ██║ ███████║██║ ██║██████╔╝ ║" + echo " ║ ██╔═══╝ ██╔══██╗██╔══██╗ ██║ ██╔══██║██║ ██║██╔══██╗ ║" + echo " ║ ██║ ██║ ██║██████╔╝ ██║ ██║ ██║╚██████╔╝██║ ██║ ║" + echo " ║ ╚═╝ ╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ║" echo " ║ ║" echo " ╠═══════════════════════════════════════════════════════════════════════════╣" - echo -e " ║ ${C_GOLD}${C_BOLD} SMaRT v${SCRIPT_VERSION} — Emulator / Nitro-V3 / Nitro-V3-Render${C_CYAN} ║" + echo -e " ║ ${C_GOLD}${C_BOLD} SMaRT v${SCRIPT_VERSION} — Emulator / Octane / Octane-Renderer${C_CYAN} ║" echo -e " ║ ${C_WHITE}${C_BOLD} Updater & Manager by Remco — epicnabbo.nl${C_CYAN} ║" echo " ╠═══════════════════════════════════════════════════════════════════════════╣" echo -e " ║ ${C_DIM}$(_t "Branch:") ${C_CYAN}${NITRO_BRANCH}${C_DIM} (${#branches[@]} $(_t "branches")) │ $(date '+%H:%M')${C_CYAN} ║" @@ -2322,7 +2658,7 @@ cmd_interactive() { echo -e " ${C_GREEN}${C_BOLD}1)${C_RESET} ${E_ROCKET} $(_t "Quick Update — current branch")" echo -e " ${C_GREEN}${C_BOLD}2)${C_RESET} ${E_BOLT} $(_t "Full Update (choose branch)")" echo -e " ${C_GREEN}${C_BOLD}3)${C_RESET} ${E_GEAR} $(_t "Emulator Only")" - echo -e " ${C_GREEN}${C_BOLD}4)${C_RESET} ${E_GEAR} $(_t "Nitro-V3 Client Only")" + echo -e " ${C_GREEN}${C_BOLD}4)${C_RESET} ${E_GEAR} $(_t "Octane Client Only")" echo -e " ${C_GREEN}${C_BOLD}5)${C_RESET} ${E_GEAR} $(_t "Renderer Only")" echo -e " ${C_GREEN}${C_BOLD}6)${C_RESET} ${E_GEAR} $(_t "Configs Only")" echo -e " ${C_GREEN}${C_BOLD}19)${C_RESET} ${E_BOLT} $(_t "Dev Mode (skip builds, only configs)")" @@ -2344,10 +2680,12 @@ cmd_interactive() { echo -e " ${C_BLUE}${C_BOLD}18)${C_RESET} ${E_CLOCK} $(_t "Cron Scheduler")" echo -e " ${C_BLUE}${C_BOLD}20)${C_RESET} ${E_GIT} $(_t "View Git Stashes")" echo -e " ${C_RED}${C_BOLD}21)${C_RESET} ${E_WRENCH} $(_t "Flyaway Repair")" + echo -e " ${C_GREEN}${C_BOLD}22)${C_RESET} ${E_ROCKET} $(_t "Auto-setup missing repos")" + echo -e " ${C_YELLOW}${C_BOLD}23)${C_RESET} ${E_BROOM} $(_t "Cleanup old Nitro dirs")" echo "" echo -e " ${C_RED}${C_BOLD}0)${C_RESET} $(_t "Exit")" echo "" - echo -en " ${C_CYAN}${C_BOLD}$(_t "Select [0-21]")${C_RESET}: " + echo -en " ${C_CYAN}${C_BOLD}$(_t "Select [0-23]")${C_RESET}: " local choice; read -rt 30 choice case "$choice" in @@ -2386,6 +2724,8 @@ cmd_interactive() { 19) SELECTIVE_UPDATE="dev"; (pick_branch_and_update) || warn "Dev mode had errors" ;; 20) (cmd_stash) ;; 21) (cmd_flyaway_repair) ;; + 22) (cmd_setup) ;; + 23) (cmd_cleanup_old_nitro) ;; 0|q|Q) echo -e "\n ${C_GREEN}$(_t "Goodbye!")${C_RESET}"; cursor_show; exit 0 ;; *) warn "Invalid selection" ;; esac @@ -2401,7 +2741,7 @@ cmd_interactive() { # ============================================================================= show_help() { echo "" - echo -e " ${C_GOLD}${C_BOLD}$(_t "SMaRT — Emulator / Nitro-V3 / Nitro-V3-Render Updater & Manager")${C_RESET}" + echo -e " ${C_GOLD}${C_BOLD}$(_t "SMaRT — Emulator / Octane / Octane-Renderer Updater & Manager")${C_RESET}" echo -e " ${C_DIM}by Remco — epicnabbo.nl v${SCRIPT_VERSION} (build ${SCRIPT_BUILD})${C_RESET}" echo "" echo -e " ${C_BOLD}$(_t "USAGE:")${C_RESET} $SCRIPT_NAME [options]" @@ -2424,6 +2764,8 @@ show_help() { echo -e " ${C_GREEN}schedule${C_RESET} $(_t "Cron setup")" echo -e " ${C_GREEN}stash${C_RESET} $(_t "View git stashes")" echo -e " ${C_GREEN}repair${C_RESET} $(_t "Flyaway Repair")" + echo -e " ${C_GREEN}setup${C_RESET} $(_t "Auto-setup missing repos")" + echo -e " ${C_GREEN}cleanup-nitro${C_RESET} $(_t "Cleanup old Nitro dirs")" echo "" echo -e " ${C_BOLD}$(_t "OPTIONS:")${C_RESET}" echo -e " ${C_CYAN}--branch, -b${C_RESET} $(_t "Branch (auto-detects)")" @@ -2460,6 +2802,8 @@ main() { clean|cl) cmd="clean" ;; stash|stashes) cmd="stash" ;; repair|flyaway) cmd="repair" ;; + setup|init) cmd="setup" ;; + cleanup-nitro|oldnitro) cmd="cleanup-nitro" ;; help|-h|--help) cmd="help" ;; version|-V|--version) echo "v${SCRIPT_VERSION} (build ${SCRIPT_BUILD})"; exit 0 ;; --branch|-b) shift; NITRO_BRANCH="$1" ;; @@ -2535,6 +2879,8 @@ main() { schedule) cmd_schedule ;; stash) cmd_stash ;; repair) cmd_flyaway_repair ;; + setup) cmd_setup ;; + cleanup-nitro) cmd_cleanup_old_nitro ;; help) show_help ;; esac