diff --git a/tools/engine-port/audit-static-writes.ps1 b/tools/engine-port/audit-static-writes.ps1 new file mode 100644 index 0000000..13b00d9 --- /dev/null +++ b/tools/engine-port/audit-static-writes.ps1 @@ -0,0 +1,33 @@ +# Multi-instancing audit: fail if any per-battle static is written directly outside its own declaring file. +$errors = @() + +# new Thread( allowlist — only LeanThreadPool's login-subsystem worker is OK. +$threadAllowlist = @('SVSim.BattleEngine/Engine/Cute/LeanThreadPool.cs') +$threadHits = Get-ChildItem -Recurse -Filter *.cs -Path SVSim.BattleEngine,SVSim.BattleNode | + Select-String -Pattern 'new\s+Thread\s*\(' | + Where-Object { + $rel = ($_.Path -replace '\\','/').Substring($PWD.Path.Length + 1) + $threadAllowlist -notcontains $rel + } +if ($threadHits) { + $errors += "Unallowed new Thread( usage:`n" + ($threadHits -join "`n") +} + +# Direct static assignments to BattleManagerBase.IsForecast / IsRandomDraw / main outside its file. +$staticWrites = Get-ChildItem -Recurse -Filter *.cs -Path SVSim.BattleEngine/Engine,SVSim.BattleNode | + Where-Object { $_.Name -ne 'BattleManagerBase.cs' } | + Select-String -Pattern 'BattleManagerBase\.(main|IsForecast|IsRandomDraw)\s*=' +if ($staticWrites) { + # OK to set IsForecast/IsRandomDraw via property setter — those route through ambient now. + # But flag any 'BattleManagerBase.main =' as the deleted field. + $bad = $staticWrites | Where-Object { $_.Line -match 'BattleManagerBase\.main\s*=' } + if ($bad) { + $errors += "Reference to deleted BattleManagerBase.main:`n" + ($bad -join "`n") + } +} + +if ($errors) { + Write-Error ($errors -join "`n`n") + exit 1 +} +Write-Host "Audit clean."