<# Install gateway + CDN as Windows services via NSSM (auto-start + restart on crash). Plain console apps cannot be Windows services directly, so NSSM wraps them. Download NSSM: https://nssm.cc/download and pass nssm.exe path via -NssmPath. Usage (admin PowerShell): powershell -ExecutionPolicy Bypass -File deploy\windows\install-services.ps1 ` -NssmPath C:\nssm\nssm.exe ` -OutRoot C:\xworld\app ` -GamesRoot C:\xworld\games ` -CdnRoot C:\xworld\cdn #> param( [string]$NssmPath = "C:\nssm\nssm.exe", [string]$OutRoot = "$PSScriptRoot\out", [string]$GamesRoot = "C:\xworld\games", # server-side minigame modules: games\\\*.dll [string]$CdnRoot = "C:\xworld\cdn", # client publish root: contains XWorld\\ and minigame\\\ [string]$AuthDbPath = "C:\xworld\accounts.db", # account SQLite db; auth.key auto-generated next to it on first run (back it up) [string]$LogDir = "C:\xworld\logs", [int] $GatewayPort = 5005, [int] $CdnPort = 15081 ) $ErrorActionPreference = "Stop" if (-not (Test-Path $NssmPath)) { throw "nssm.exe not found: $NssmPath (download from https://nssm.cc/download)" } $gwExe = Join-Path $OutRoot "gateway\XWorld.Server.Gateway.Runner.exe" $cdnExe = Join-Path $OutRoot "cdn\XWorld.Server.Cdn.Runner.exe" if (-not (Test-Path $gwExe)) { throw "gateway exe not found, run publish.ps1 first: $gwExe" } if (-not (Test-Path $cdnExe)) { throw "cdn exe not found, run publish.ps1 first: $cdnExe" } New-Item -ItemType Directory -Force -Path $LogDir | Out-Null # Gateway: no --lan => binds 127.0.0.1 (only Caddy reaches it); no --devToken => DevDiscovery off. # --authDbPath => enable account auth (/register, /login, /ws?token=); auth.key auto-generated next to the db on first run. & $NssmPath install XWorldGateway $gwExe & $NssmPath set XWorldGateway AppParameters "--gamesRoot `"$GamesRoot`" --port $GatewayPort --authDbPath `"$AuthDbPath`"" & $NssmPath set XWorldGateway AppDirectory (Split-Path $gwExe) & $NssmPath set XWorldGateway Start SERVICE_AUTO_START & $NssmPath set XWorldGateway AppStdout (Join-Path $LogDir "gateway.out.log") & $NssmPath set XWorldGateway AppStderr (Join-Path $LogDir "gateway.err.log") & $NssmPath set XWorldGateway AppRotateFiles 1 & $NssmPath install XWorldCdn $cdnExe & $NssmPath set XWorldCdn AppParameters "--root `"$CdnRoot`" --port $CdnPort" & $NssmPath set XWorldCdn AppDirectory (Split-Path $cdnExe) & $NssmPath set XWorldCdn Start SERVICE_AUTO_START & $NssmPath set XWorldCdn AppStdout (Join-Path $LogDir "cdn.out.log") & $NssmPath set XWorldCdn AppStderr (Join-Path $LogDir "cdn.err.log") & $NssmPath set XWorldCdn AppRotateFiles 1 & $NssmPath start XWorldGateway & $NssmPath start XWorldCdn Write-Host "" Write-Host "Installed and started: XWorldGateway(127.0.0.1:$GatewayPort), XWorldCdn(127.0.0.1:$CdnPort)" -ForegroundColor Green Write-Host "Self-check: curl http://127.0.0.1:$CdnPort/XWorld/android/updatever.txt (expect 200 once CDN content is in place)" Write-Host "Logs: $LogDir" Write-Host "Next: configure and start Caddy (see README), then verify WSS/HTTPS via your domain."