216 lines
7.7 KiB
PowerShell
216 lines
7.7 KiB
PowerShell
param(
|
|
[string]$Root = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
function Pass($message) {
|
|
Write-Host "[OK] $message" -ForegroundColor Green
|
|
}
|
|
|
|
function Fail($message) {
|
|
throw "[FAIL] $message"
|
|
}
|
|
|
|
function Require-File($relative) {
|
|
$path = Join-Path $Root $relative
|
|
if (!(Test-Path -LiteralPath $path -PathType Leaf)) {
|
|
Fail "Missing file: $relative"
|
|
}
|
|
Pass "Found $relative"
|
|
}
|
|
|
|
Push-Location $Root
|
|
try {
|
|
Require-File 'PokerGameSetup.exe'
|
|
Require-File 'Assembler Casino.exe'
|
|
Require-File 'Uninstall Assembler Casino.exe'
|
|
Require-File 'bin\poker.exe'
|
|
Require-File 'assets\icons\casino.ico'
|
|
Require-File 'assets\animations\hakari_dance.ans'
|
|
Require-File 'assets\animations\dbd_hook.ans'
|
|
Require-File 'tools\preview_dbd_hook.bat'
|
|
Require-File 'docs\README_RELEASE.txt'
|
|
Require-File 'docs\RELEASE_CHECKLIST.txt'
|
|
Require-File 'docs\KNOWN_LIMITATIONS.txt'
|
|
Require-File 'docs\SECURITY_NOTES.txt'
|
|
Require-File 'docs\ROADMAP.txt'
|
|
Require-File 'docs\ONLINE_RADMIN.txt'
|
|
|
|
foreach ($mambo in @(
|
|
'assets\animations\mambo1.ans',
|
|
'assets\animations\mambo2.ans',
|
|
'assets\animations\mambo3.ans',
|
|
'assets\animations\mambo4.ans'
|
|
)) {
|
|
if (Test-Path -LiteralPath (Join-Path $Root $mambo) -PathType Leaf) {
|
|
Fail "Removed MAMBO animation still exists: $mambo"
|
|
}
|
|
}
|
|
Pass 'MAMBO animation files are removed from assets'
|
|
|
|
$dbdBat = Get-Content -LiteralPath (Join-Path $Root 'tools\preview_dbd_hook.bat') -Raw
|
|
if ($dbdBat -match 'Clear-Host') {
|
|
Fail 'DBD helper still uses Clear-Host'
|
|
}
|
|
Pass 'DBD helper does not use Clear-Host'
|
|
|
|
$asmBytes = [IO.File]::ReadAllBytes((Join-Path $Root 'poker.asm'))
|
|
$cp1251 = [Text.Encoding]::GetEncoding(1251)
|
|
$asmText = $cp1251.GetString($asmBytes)
|
|
foreach ($needle in @(
|
|
'settingsCinematicText db "Cinematic -',
|
|
'settingsAdaptiveText db "Adaptive -',
|
|
'settingsStableText db "Stable -',
|
|
'AnimShouldDrawFrame PROC',
|
|
'AnimFrameDelay PROC',
|
|
'WriteAnimProfileFile PROC',
|
|
'SAVE_SIGN_SIZE equ 276',
|
|
'SAVE_FILE_SIZE equ 280',
|
|
'CalcSaveSignature PROC',
|
|
'mov DWORD PTR [saveBuffer+SAVE_SIGN_SIZE], eax',
|
|
'cmp charsRead, SAVE_FILE_SIZE',
|
|
'includelib ws2_32.lib',
|
|
'GameOnlineCasino PROC',
|
|
'OnlineRRSessionHost PROC',
|
|
'OnlineRRSessionClient PROC'
|
|
)) {
|
|
if ($asmText.IndexOf($needle) -lt 0) {
|
|
Fail "Missing source marker: $needle"
|
|
}
|
|
}
|
|
Pass 'Animation profile and save signature markers exist in poker.asm'
|
|
|
|
if ($asmText -match 'MAMBO|mambo|PlayMambo') {
|
|
Fail 'MAMBO markers still exist in poker.asm'
|
|
}
|
|
Pass 'MAMBO markers are removed from poker.asm'
|
|
|
|
$launcherSource = Join-Path $Root 'build\AssemblerCasinoLauncher.cs'
|
|
if (!(Test-Path -LiteralPath $launcherSource -PathType Leaf)) {
|
|
Fail 'Missing launcher source: build\AssemblerCasinoLauncher.cs'
|
|
}
|
|
$launcherText = Get-Content -LiteralPath $launcherSource -Raw -Encoding UTF8
|
|
$expectedPokerHash = $null
|
|
if ($launcherText -match 'ExpectedPokerSha256 = "([A-Fa-f0-9]{64})"') {
|
|
$expectedPokerHash = $matches[1].ToUpperInvariant()
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($expectedPokerHash)) {
|
|
Fail 'Launcher source does not contain a fixed poker.exe SHA-256 hash'
|
|
}
|
|
$pokerSha = [Security.Cryptography.SHA256]::Create()
|
|
try {
|
|
$actualPokerHash = [BitConverter]::ToString($pokerSha.ComputeHash([IO.File]::ReadAllBytes((Join-Path $Root 'bin\poker.exe')))).Replace('-', '').ToUpperInvariant()
|
|
}
|
|
finally {
|
|
$pokerSha.Dispose()
|
|
}
|
|
if ($actualPokerHash -ne $expectedPokerHash) {
|
|
Fail "Launcher poker.exe SHA-256 mismatch. Expected $expectedPokerHash, actual $actualPokerHash"
|
|
}
|
|
Pass 'Launcher poker.exe SHA-256 matches current bin\poker.exe'
|
|
|
|
$setupSource = Join-Path $Root 'build\PokerGameSetupGui.cs'
|
|
if (!(Test-Path -LiteralPath $setupSource -PathType Leaf)) {
|
|
Fail 'Missing installer source: build\PokerGameSetupGui.cs'
|
|
}
|
|
$setupSourceText = Get-Content -LiteralPath $setupSource -Raw -Encoding UTF8
|
|
$expectedHash = $null
|
|
if ($setupSourceText -match 'ExpectedPayloadSha256 = "([A-Fa-f0-9]{64})"') {
|
|
$expectedHash = $matches[1].ToUpperInvariant()
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($expectedHash)) {
|
|
Fail 'Installer source does not contain a fixed SHA-256 payload hash'
|
|
}
|
|
|
|
Add-Type -AssemblyName System.IO.Compression
|
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
|
|
|
$setupPath = Join-Path $Root 'PokerGameSetup.exe'
|
|
$fs = [IO.File]::OpenRead($setupPath)
|
|
try {
|
|
$head = New-Object byte[] ([Math]::Min(2097152, $fs.Length))
|
|
[void]$fs.Read($head, 0, $head.Length)
|
|
$marker = [Text.Encoding]::UTF8.GetBytes('<<POKER_GAME_GUI_PAYLOAD_ZIP>>')
|
|
$idx = -1
|
|
for ($i = 0; $i -le $head.Length - $marker.Length; $i++) {
|
|
if ($head[$i] -ne $marker[0]) { continue }
|
|
$ok = $true
|
|
for ($j = 1; $j -lt $marker.Length; $j++) {
|
|
if ($head[$i + $j] -ne $marker[$j]) { $ok = $false; break }
|
|
}
|
|
if ($ok) { $idx = $i; break }
|
|
}
|
|
if ($idx -lt 0) { Fail 'Installer payload marker not found' }
|
|
|
|
$fs.Position = $idx + $marker.Length
|
|
$zipBytes = New-Object byte[] ($fs.Length - $fs.Position)
|
|
[void]$fs.Read($zipBytes, 0, $zipBytes.Length)
|
|
}
|
|
finally {
|
|
$fs.Dispose()
|
|
}
|
|
|
|
$ms = New-Object IO.MemoryStream(,$zipBytes)
|
|
$zip = New-Object IO.Compression.ZipArchive($ms, [IO.Compression.ZipArchiveMode]::Read)
|
|
try {
|
|
$names = @($zip.Entries | ForEach-Object FullName)
|
|
foreach ($entry in @(
|
|
'Assembler Casino.exe',
|
|
'Uninstall Assembler Casino.exe',
|
|
'bin/poker.exe',
|
|
'assets/icons/casino.ico',
|
|
'tools/preview_dbd_hook.bat',
|
|
'tools/release_smoke_check.ps1',
|
|
'docs/README_RELEASE.txt',
|
|
'docs/RELEASE_CHECKLIST.txt',
|
|
'docs/KNOWN_LIMITATIONS.txt',
|
|
'docs/SECURITY_NOTES.txt',
|
|
'docs/ROADMAP.txt',
|
|
'docs/ONLINE_RADMIN.txt'
|
|
)) {
|
|
if ($names -notcontains $entry) {
|
|
Fail "Installer payload missing: $entry"
|
|
}
|
|
}
|
|
if ($names -contains 'Assembler Casino.bat') {
|
|
Fail 'Installer payload still contains old Assembler Casino.bat'
|
|
}
|
|
if ($names | Where-Object { $_ -like 'tools/generated_frames/*' }) {
|
|
Fail 'Installer payload contains generated preview frames/tools'
|
|
}
|
|
foreach ($entry in @(
|
|
'assets/animations/mambo1.ans',
|
|
'assets/animations/mambo2.ans',
|
|
'assets/animations/mambo3.ans',
|
|
'assets/animations/mambo4.ans'
|
|
)) {
|
|
if ($names -contains $entry) {
|
|
Fail "Installer payload still contains removed MAMBO animation: $entry"
|
|
}
|
|
}
|
|
Pass "Installer payload OK ($($names.Count) files)"
|
|
}
|
|
finally {
|
|
$zip.Dispose()
|
|
$ms.Dispose()
|
|
}
|
|
|
|
$sha = [Security.Cryptography.SHA256]::Create()
|
|
try {
|
|
$actualHash = [BitConverter]::ToString($sha.ComputeHash($zipBytes)).Replace('-', '').ToUpperInvariant()
|
|
}
|
|
finally {
|
|
$sha.Dispose()
|
|
}
|
|
if ($actualHash -ne $expectedHash) {
|
|
Fail "Installer payload SHA-256 mismatch. Expected $expectedHash, actual $actualHash"
|
|
}
|
|
Pass 'Installer payload SHA-256 matches embedded hash'
|
|
|
|
Write-Host ''
|
|
Write-Host 'Release smoke check passed.' -ForegroundColor Cyan
|
|
}
|
|
finally {
|
|
Pop-Location
|
|
}
|