# RR3 Asset Extraction PowerShell Script # Extracts .z (ZLIB compressed) texture files from Real Racing 3 param( [Parameter(Mandatory=$true)] [string]$InputFile, [Parameter(Mandatory=$false)] [string]$OutputDir ) Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan Write-Host " RR3 Asset Extraction Tool - Windows" -ForegroundColor Yellow Write-Host "════════════════════════════════════════════════════════════" -ForegroundColor Cyan Write-Host "" # Validate input if (-not (Test-Path $InputFile)) { Write-Host "ERROR: Input file not found: $InputFile" -ForegroundColor Red exit 1 } # Default output dir if (-not $OutputDir) { $OutputDir = Split-Path -Parent $InputFile } Write-Host "Input file: $InputFile" -ForegroundColor Green Write-Host "Output directory: $OutputDir" -ForegroundColor Green Write-Host "" # Create output directory New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null # Read file Write-Host "Reading file..." -ForegroundColor Cyan $data = [System.IO.File]::ReadAllBytes($InputFile) $output = New-Object System.Collections.ArrayList $i = 0 $found = 0 Write-Host "Scanning for ZLIB blocks..." -ForegroundColor Cyan # Scan for zlib blocks (magic bytes 0x78 0x9C, 0xDA, or 0x01) while ($i -lt ($data.Length - 2)) { if ($data[$i] -eq 0x78 -and ($data[$i+1] -eq 0x9C -or $data[$i+1] -eq 0xDA -or $data[$i+1] -eq 0x01)) { try { # Try to decompress from this position $compressed = $data[$i..($data.Length-1)] $decompressed = [System.IO.Compression.DeflateStream]::new( [System.IO.MemoryStream]::new($compressed, 2, $compressed.Length - 2), [System.IO.Compression.CompressionMode]::Decompress ) $ms = New-Object System.IO.MemoryStream $decompressed.CopyTo($ms) $decompressed.Close() $block = $ms.ToArray() $ms.Close() if ($block.Length -gt 0) { $output.AddRange($block) Write-Host " [+] Block $found at 0x$($i.ToString('X'))" -ForegroundColor Gray $found++ $i += $block.Length continue } } catch { # Not a valid zlib block, continue } } $i++ } if ($found -eq 0) { Write-Host "ERROR: No valid zlib blocks found!" -ForegroundColor Red exit 1 } # Get output filename $baseName = [System.IO.Path]::GetFileName($InputFile) if ($baseName.ToLower().EndsWith(".z")) { $baseName = $baseName.Substring(0, $baseName.Length - 2) } $outputFile = Join-Path $OutputDir $baseName # Backup if exists if (Test-Path $outputFile) { $bakFile = "$outputFile.bak" if (-not (Test-Path $bakFile)) { Move-Item $outputFile $bakFile Write-Host "Backup created: $bakFile" -ForegroundColor Yellow } } # Write output [System.IO.File]::WriteAllBytes($outputFile, $output.ToArray()) Write-Host "" Write-Host "✅ Extraction complete!" -ForegroundColor Green Write-Host "Output: $outputFile" -ForegroundColor White Write-Host "Blocks found: $found" -ForegroundColor White Write-Host "Size: $($output.Count) bytes" -ForegroundColor White