9bb4f85802
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
60 lines
3.0 KiB
PowerShell
60 lines
3.0 KiB
PowerShell
<#
|
|
One-off migration: the app no longer has a built-in "Menu patch" hook. Your menu patch becomes an ordinary command hook.
|
|
|
|
- writes "<library>\hooks\menupatch\apply.ps1": copies the MenuPatch folder (and PatchMenus.bat) from this folder into the game
|
|
folder, then runs MenuPatch\patch.ps1 there, exiting with its exit code
|
|
- config.json: the hook with id "menupatch" gets Command = that apply.ps1 and loses its "Kind"
|
|
|
|
Your existing master folder (<library>\hooks\menupatch\MenuPatch and PatchMenus.bat) is not touched.
|
|
Run it OUTSIDE Claude's sandbox (a normal terminal), otherwise it edits a private copy of %APPDATA%.
|
|
Dry run by default; -Apply writes. Close CVRManager first with -Apply. config.json is backed up next to itself.
|
|
#>
|
|
[CmdletBinding()]
|
|
param(
|
|
[string]$ConfigDir = (Join-Path $env:APPDATA 'CVRManager'),
|
|
[switch]$Apply
|
|
)
|
|
$ErrorActionPreference = 'Stop'
|
|
|
|
$configPath = Join-Path $ConfigDir 'config.json'
|
|
if (-not (Test-Path $configPath)) { throw "No config at $configPath" }
|
|
if ($Apply -and (Get-Process CVRManager -ErrorAction SilentlyContinue)) { throw 'Close CVRManager first; it would overwrite the change.' }
|
|
$cfg = Get-Content $configPath -Raw | ConvertFrom-Json
|
|
$lib = if ($cfg.LibraryRoot) { $cfg.LibraryRoot } else { Join-Path $env:LOCALAPPDATA 'CVRManager' }
|
|
$master = Join-Path $lib 'hooks\menupatch'
|
|
$apply1 = Join-Path $master 'apply.ps1'
|
|
|
|
$hook = @($cfg.Hooks) | Where-Object { $_.Id -eq 'menupatch' } | Select-Object -First 1
|
|
if (-not $hook) { 'No hook with id "menupatch" in the config; nothing to migrate.'; return }
|
|
"Hook '$($hook.Name)': Kind=$($hook.Kind), Command='$($hook.Command)'"
|
|
"Master folder: $master (MenuPatch present: $(Test-Path (Join-Path $master 'MenuPatch\patch.ps1')))"
|
|
"apply.ps1 will be written to: $apply1"
|
|
|
|
$script = @'
|
|
$ErrorActionPreference = 'Stop'
|
|
$game = $env:CVR_GAME_DIR
|
|
if (-not $game) { throw 'CVR_GAME_DIR is not set; run this from CVRManager.' }
|
|
$src = Join-Path $PSScriptRoot 'MenuPatch'
|
|
if (-not (Test-Path (Join-Path $src 'patch.ps1'))) { throw "No MenuPatch\patch.ps1 in $PSScriptRoot" }
|
|
robocopy $src (Join-Path $game 'MenuPatch') /E /XD backup 'reference-*' /NFL /NDL /NJH /NJS /NP | Out-Null
|
|
if ($LASTEXITCODE -ge 8) { throw "robocopy failed ($LASTEXITCODE)" }
|
|
$bat = Join-Path $PSScriptRoot 'PatchMenus.bat'
|
|
if (Test-Path $bat) { Copy-Item $bat (Join-Path $game 'PatchMenus.bat') -Force }
|
|
& (Join-Path $game 'MenuPatch\patch.ps1')
|
|
if ($LASTEXITCODE -eq 2) { exit 0 }
|
|
exit $LASTEXITCODE
|
|
'@
|
|
|
|
if (-not $Apply) { ''; 'Dry run only. Re-run with -Apply to save.'; return }
|
|
|
|
New-Item -ItemType Directory $master -Force | Out-Null
|
|
[IO.File]::WriteAllText($apply1, $script, (New-Object Text.UTF8Encoding($false)))
|
|
$backup = "$configPath.bak-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
|
Copy-Item $configPath $backup
|
|
$hook.Command = $apply1
|
|
$hook.Arguments = ''
|
|
$hook.PSObject.Properties.Remove('Kind')
|
|
[IO.File]::WriteAllText($configPath, ($cfg | ConvertTo-Json -Depth 30), (New-Object Text.UTF8Encoding($false)))
|
|
"Config backed up to $backup"
|
|
'Done. Start CVRManager again.'
|