# SPDX-License-Identifier: GPL-3.0-or-later [CmdletBinding()] param( [string]$Destination = "" ) $ErrorActionPreference = "Stop" $root = Split-Path -Parent $PSScriptRoot if ([string]::IsNullOrWhiteSpace($Destination)) { $Destination = Join-Path $root "work/toolchains/ps5-payload-sdk-v0.41" } $cache = Join-Path $root "work/cache" $archive = Join-Path $cache "ps5-payload-sdk-v0.41.zip" $url = "https://github.com/ps5-payload-dev/sdk/releases/download/v0.41/ps5-payload-sdk.zip" $expectedHash = "ebfb0acb5260511951a80e17db41650c62d20a8caf8659a230b928dc85005984" $expectedSize = 8810966 New-Item -ItemType Directory -Force -Path $cache | Out-Null if (-not (Test-Path -LiteralPath $archive)) { & curl.exe -fL --retry 3 --output $archive $url if ($LASTEXITCODE -ne 0) { throw "SDK download failed" } } $file = Get-Item -LiteralPath $archive if ($file.Length -ne $expectedSize) { throw "SDK size mismatch: expected $expectedSize, got $($file.Length)" } $actualHash = (Get-FileHash -Algorithm SHA256 -LiteralPath $archive).Hash.ToLowerInvariant() if ($actualHash -ne $expectedHash) { throw "SDK SHA-256 mismatch" } if (-not (Test-Path -LiteralPath $Destination)) { $temporary = Join-Path $root "work/toolchains/sdk-extract" $resolvedRoot = [System.IO.Path]::GetFullPath($root).TrimEnd('\') + '\' $resolvedTemporary = [System.IO.Path]::GetFullPath($temporary) if (-not $resolvedTemporary.StartsWith($resolvedRoot, [System.StringComparison]::OrdinalIgnoreCase)) { throw "Refusing temporary cleanup outside the workspace" } New-Item -ItemType Directory -Force -Path $temporary | Out-Null Expand-Archive -LiteralPath $archive -DestinationPath $temporary -Force $extracted = Join-Path $temporary "ps5-payload-sdk" New-Item -ItemType Directory -Force -Path (Split-Path -Parent $Destination) | Out-Null Move-Item -LiteralPath $extracted -Destination $Destination Remove-Item -LiteralPath $temporary -Recurse -Force } Write-Output "Verified PS5 Payload SDK v0.41 at $Destination"