mirror of
https://github.com/blackbearreloaded/ps5-homebrew-dev-protocol.git
synced 2026-10-26 16:36:39 +01:00
86 lines
2.9 KiB
PowerShell
86 lines
2.9 KiB
PowerShell
# ps5-homebrew-dev-protocol - Download-data evidence retrieval.
|
|
# Copyright (C) 2026 BlackBearReloaded
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
#
|
|
# Retrieves one title's download0.dat while holding the shared console lock.
|
|
|
|
[CmdletBinding()]
|
|
param(
|
|
[Parameter(Mandatory)]
|
|
[ValidatePattern('^PPSA\d{5}$')]
|
|
[string]$TitleId,
|
|
[Parameter(Mandatory)]
|
|
[string]$OutputPath,
|
|
[Alias('Ps5Address')]
|
|
[string]$Ps5Host = $env:PS5_HOST,
|
|
[int]$FtpPort = 2121,
|
|
[string]$FtpCredential = 'anonymous:anonymous',
|
|
[string]$LockPath = [IO.Path]::Combine(
|
|
[Environment]::GetFolderPath('MyDocuments'), 'PS5', 'lock.txt')
|
|
)
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
if (-not $Ps5Host) { throw 'Set -Ps5Host or the PS5_HOST environment variable.' }
|
|
$ps5Lock = [IO.Path]::GetFullPath($LockPath)
|
|
$lockToken = '{0}|pid={1}|utc={2:o}' -f 'iptv-receipt', $PID, [DateTime]::UtcNow
|
|
$resolvedOutput = [IO.Path]::GetFullPath($OutputPath)
|
|
if (Test-Path -LiteralPath $resolvedOutput) {
|
|
throw "Refusing to replace existing receipt image: $resolvedOutput"
|
|
}
|
|
$outputDirectory = Split-Path -Parent $resolvedOutput
|
|
if (-not (Test-Path -LiteralPath $outputDirectory -PathType Container)) {
|
|
throw "Receipt output directory does not exist: $outputDirectory"
|
|
}
|
|
|
|
while ($true) {
|
|
try {
|
|
$handle = [IO.File]::Open(
|
|
$ps5Lock,
|
|
[IO.FileMode]::CreateNew,
|
|
[IO.FileAccess]::Write,
|
|
[IO.FileShare]::None)
|
|
try {
|
|
$bytes = [Text.Encoding]::UTF8.GetBytes($lockToken)
|
|
$handle.Write($bytes, 0, $bytes.Length)
|
|
} finally {
|
|
$handle.Dispose()
|
|
}
|
|
break
|
|
} catch [IO.IOException] {
|
|
if (-not (Test-Path -LiteralPath $ps5Lock)) { throw }
|
|
Start-Sleep -Seconds 15
|
|
}
|
|
}
|
|
|
|
try {
|
|
Write-Host "LOCK_ACQUIRED $lockToken"
|
|
$remote = "ftp://${Ps5Host}:${FtpPort}/user/download/$TitleId/download0.dat"
|
|
& curl.exe --fail --silent --show-error --disable-epsv `
|
|
-u $FtpCredential $remote --output $resolvedOutput
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Could not retrieve download0.dat for $TitleId"
|
|
}
|
|
$file = Get-Item -LiteralPath $resolvedOutput
|
|
if ($file.Length -eq 0) {
|
|
Remove-Item -LiteralPath $resolvedOutput -Force
|
|
throw "Retrieved an empty download0.dat for $TitleId"
|
|
}
|
|
$hash = Get-FileHash -LiteralPath $resolvedOutput -Algorithm SHA256
|
|
Write-Host "DOWNLOAD_DATA_RETRIEVED $TitleId bytes=$($file.Length) sha256=$($hash.Hash)"
|
|
} catch {
|
|
if (Test-Path -LiteralPath $resolvedOutput) {
|
|
Remove-Item -LiteralPath $resolvedOutput -Force
|
|
}
|
|
throw
|
|
} finally {
|
|
if (Test-Path -LiteralPath $ps5Lock) {
|
|
$currentToken = Get-Content -LiteralPath $ps5Lock -Raw
|
|
if ($currentToken -eq $lockToken) {
|
|
Remove-Item -LiteralPath $ps5Lock -Force
|
|
Write-Host 'LOCK_RELEASED'
|
|
} else {
|
|
Write-Warning 'Lock ownership changed; refusing to remove it.'
|
|
}
|
|
}
|
|
}
|