File size: 3,662 Bytes
3ce1a40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
param(
    [Parameter(Mandatory=$true)][string]$EngineRoot,
    [string]$SourceRoot,
    [string]$Owner = 'SNAPKITTYWEST',
    [int]$Port = 38473,
    [string]$BuildPlan,
    [switch]$SkipBuild
)
$ErrorActionPreference = 'Stop'
$RepoRoot = Split-Path $PSScriptRoot -Parent
if (!$SourceRoot) { $SourceRoot = $RepoRoot }
$SourceRoot = (Resolve-Path -LiteralPath $SourceRoot).Path
$Editor = Join-Path $EngineRoot 'Engine\Binaries\Win64\UnrealEditor.exe'
if (!(Test-Path -LiteralPath $Editor)) { throw "Unreal Editor not found: $Editor" }
$Dotnet = Join-Path $env:USERPROFILE '.dotnet\dotnet.exe'
if (!(Test-Path -LiteralPath $Dotnet)) { $Dotnet = (Get-Command dotnet).Source }
$WorldDir = Join-Path $RepoRoot 'out\world3d'
New-Item -ItemType Directory -Force -Path $WorldDir | Out-Null
if (!$SkipBuild) {
    & $Dotnet build (Join-Path $RepoRoot 'Repoverse.sln') -warnaserror
    if ($LASTEXITCODE) { throw 'Core build failed' }
    & (Join-Path $RepoRoot 'unreal\Prepare-Unreal.ps1') -EngineRoot $EngineRoot
}
$Cli = Join-Path $RepoRoot 'src\Repoverse.Cli\bin\Debug\net8.0\Repoverse.Cli.dll'
$Snapshot = Join-Path $WorldDir 'snapshot.json'
$Manifest = Join-Path $WorldDir 'manifest.json'
& $Dotnet $Cli ingest-local $SourceRoot --owner $Owner --out $Snapshot
if ($LASTEXITCODE) { throw 'Local ingestion failed' }
& $Dotnet $Cli generate --snapshot $Snapshot --out $Manifest
if ($LASTEXITCODE) { throw 'World generation failed' }
$Data = Get-Content -LiteralPath $Manifest -Raw | ConvertFrom-Json
$Repo = $Data.buildings[0].repo
$Token = [Guid]::NewGuid().ToString('N') + [Guid]::NewGuid().ToString('N')
$Sidecar = Join-Path $RepoRoot 'src\Repoverse.Sidecar\bin\Debug\net8.0\Repoverse.Sidecar.dll'
$Save = Join-Path $WorldDir 'save.json'
# ArgumentList is a command-line string on Windows; quote every path with spaces.
$ServiceArgs = @(('"'+$Sidecar+'"'), '--manifest', ('"'+$Manifest+'"'), '--token', $Token, '--port', $Port, '--save', ('"'+$Save+'"'), '--source-root', ('"'+$SourceRoot+'"'), '--source-repo', $Repo)
$Service = Start-Process -FilePath $Dotnet -ArgumentList $ServiceArgs -PassThru -WindowStyle Hidden -RedirectStandardOutput (Join-Path $WorldDir 'service.log') -RedirectStandardError (Join-Path $WorldDir 'service-error.log')
try {
    $Ready = $false
    for ($i=0; $i -lt 100; $i++) {
        if ($Service.HasExited) { throw 'World service exited; inspect out/world3d/service-error.log' }
        try { $null = Invoke-RestMethod "http://127.0.0.1:$Port/v1/health" -Headers @{'X-Repoverse-Token'=$Token}; $Ready=$true; break } catch { Start-Sleep -Milliseconds 100 }
    }
    if (!$Ready) { throw 'World service did not become ready' }
    if ($BuildPlan) {
        $BuildFile = Get-Item -LiteralPath $BuildPlan
        if ($BuildFile.Length -gt 65536) { throw 'Build plan exceeds 64 KiB' }
        $Body = Get-Content -LiteralPath $BuildFile.FullName -Raw
        $Receipt = Invoke-RestMethod "http://127.0.0.1:$Port/v1/build" -Method Post -ContentType 'application/json' -Body $Body -Headers @{'X-Repoverse-Token'=$Token}
        Write-Host "Builder $($Receipt.actor) placed $($Receipt.voxels) voxels. F5 saves the build."
    }
    $Project = Join-Path $RepoRoot 'unreal\Repoverse\Repoverse.uproject'
    $GameArgs = @(('"'+$Project+'"'), '/Game/Maps/Repoverse?game=/Script/Repoverse.RepoverseWorldMode', '-game', "-RepoverseToken=$Token", "-RepoversePort=$Port", '-windowed', '-ResX=1440', '-ResY=900')
    $Game = Start-Process -FilePath $Editor -ArgumentList $GameArgs -PassThru -Wait
    if ($Game.ExitCode) { throw "Unreal exited with code $($Game.ExitCode)" }
} finally {
    if (!$Service.HasExited) { Stop-Process -Id $Service.Id }
}