param( [string]$GameRoot = "D:\SteamLibrary\steamapps\common\ProjectZomboid" ) $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent $PSScriptRoot $toolsDir = Join-Path $repoRoot ".tools" $classPatchDir = Join-Path $toolsDir "classpatch" $buildDir = Join-Path $toolsDir "patcher-build" New-Item -ItemType Directory -Force -Path $toolsDir | Out-Null New-Item -ItemType Directory -Force -Path $classPatchDir | Out-Null New-Item -ItemType Directory -Force -Path $buildDir | Out-Null $javaExe = Join-Path $GameRoot "jre64\bin\java.exe" $gameJar = Join-Path $GameRoot "projectzomboid.jar" if (-not (Test-Path $javaExe)) { throw "java.exe not found at $javaExe" } if (-not (Test-Path $gameJar)) { throw "projectzomboid.jar not found at $gameJar" } $ecjJar = Join-Path $toolsDir "ecj.jar" $asmJar = Join-Path $toolsDir "asm.jar" $asmTreeJar = Join-Path $toolsDir "asm-tree.jar" if (-not (Test-Path $ecjJar)) { Invoke-WebRequest -Uri "https://repo1.maven.org/maven2/org/eclipse/jdt/ecj/3.38.0/ecj-3.38.0.jar" -OutFile $ecjJar } if (-not (Test-Path $asmJar)) { Invoke-WebRequest -Uri "https://repo1.maven.org/maven2/org/ow2/asm/asm/9.9/asm-9.9.jar" -OutFile $asmJar } if (-not (Test-Path $asmTreeJar)) { Invoke-WebRequest -Uri "https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/9.9/asm-tree-9.9.jar" -OutFile $asmTreeJar } $patcherSource = Join-Path $PSScriptRoot "java\BaseVehicleConstraintPatch.java" if (-not (Test-Path $patcherSource)) { throw "Missing patcher source: $patcherSource" } & $javaExe -jar $ecjJar -17 -cp "$asmJar;$asmTreeJar" -d $buildDir $patcherSource if ($LASTEXITCODE -ne 0) { throw "Failed to compile BaseVehicleConstraintPatch.java" } $inputClass = Join-Path $classPatchDir "BaseVehicle.original.class" $patchedClass = Join-Path $classPatchDir "BaseVehicle.patched.class" Add-Type -AssemblyName System.IO.Compression.FileSystem $zip = [System.IO.Compression.ZipFile]::OpenRead($gameJar) try { $entry = $zip.GetEntry("zombie/vehicles/BaseVehicle.class") if ($null -eq $entry) { throw "zombie/vehicles/BaseVehicle.class not found in $gameJar" } $entryStream = $entry.Open() $fileStream = [System.IO.File]::Create($inputClass) try { $entryStream.CopyTo($fileStream) } finally { $fileStream.Close() $entryStream.Close() } } finally { $zip.Dispose() } & $javaExe -cp "$buildDir;$asmJar;$asmTreeJar" BaseVehicleConstraintPatch $inputClass $patchedClass if ($LASTEXITCODE -ne 0) { throw "BaseVehicle class patch failed" } $targetDir = Join-Path $GameRoot "zombie\vehicles" $targetClass = Join-Path $targetDir "BaseVehicle.class" $backupClass = "$targetClass.landtrain.original" New-Item -ItemType Directory -Force -Path $targetDir | Out-Null if (-not (Test-Path $backupClass)) { if (Test-Path $targetClass) { Copy-Item $targetClass $backupClass -Force } else { Copy-Item $inputClass $backupClass -Force } } Copy-Item $patchedClass $targetClass -Force Write-Output "Patched BaseVehicle.class deployed to $targetClass" Write-Output "Backup stored at $backupClass" $distDir = Join-Path $repoRoot "zombie\vehicles" $distClass = Join-Path $distDir "BaseVehicle.class" New-Item -ItemType Directory -Force -Path $distDir | Out-Null Copy-Item $patchedClass $distClass -Force Write-Output "Distribution class updated at $distClass"