新增奥日2排障记录:Wwise 线程亲和性故障定位与兼容补丁(文章4篇+补丁包+诊断脚本4个,已脱敏)

This commit is contained in:
SCHOOL
2026-09-23 15:08:27 +08:00
parent 90bcf6176e
commit 6bf9981765
21 changed files with 2815 additions and 0 deletions
@@ -0,0 +1,112 @@
#requires -Version 7.0
[CmdletBinding()]
param(
[ValidateSet('Check', 'Install', 'Restore')]
[string]$Action = 'Check',
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[string[]]$GameDirectory
)
$ErrorActionPreference = 'Stop'
$originalHash = '8F90A4A3856540CB97D03CA07B4BB10B7A08F7B4AB3C524BE2BEC1AFDD29FECA'
$patchedHash = '62B2079A988D23EB251D4E83366AC04068A6F47E0D38EFE92A76DF022826F9F0'
$offset = 0x115F0
$originalCode = [Convert]::FromHexString('4885C97403895104C3CCCCCCCCCCCCCC')
$patchedCode = [Convert]::FromHexString('4885C97407C7410400000000C3CCCCCC')
function Get-BytesHash([byte[]]$Bytes) {
[Convert]::ToHexString([Security.Cryptography.SHA256]::HashData($Bytes))
}
if ($Action -ne 'Check' -and (Get-Process -Name 'oriwotw' -ErrorAction SilentlyContinue)) {
throw '请先退出所有奥日 2 游戏窗口,再安装或还原补丁。'
}
# Preflight every selected directory before any mutation. Unknown builds,
# unrelated modifications and conflicting backups are never overwritten.
$plans = foreach ($directory in $GameDirectory) {
$root = (Resolve-Path -LiteralPath $directory).Path
$target = Join-Path $root 'oriwotw_Data\Plugins\AkSoundEngine.dll'
$backup = $target + '.before-ori-affinity-fix'
$bytes = [IO.File]::ReadAllBytes($target)
$hash = Get-BytesHash $bytes
if ($hash -notin @($originalHash, $patchedHash)) {
throw "文件版本或内容不匹配,未修改:$target;SHA256=$hash"
}
if (Test-Path -LiteralPath $backup) {
if ((Get-FileHash -LiteralPath $backup -Algorithm SHA256).Hash -ne $originalHash) {
throw "现有备份不匹配,未覆盖:$backup"
}
}
if ($Action -eq 'Restore' -and $hash -eq $patchedHash -and -not (Test-Path -LiteralPath $backup)) {
throw "找不到经过校验的原文件备份,无法还原:$backup"
}
if ($hash -eq $originalHash) {
for ($i = 0; $i -lt $originalCode.Length; $i++) {
if ($bytes[$offset + $i] -ne $originalCode[$i]) { throw '原始指令校验失败。' }
}
$candidate = [byte[]]$bytes.Clone()
[Array]::Copy($patchedCode, 0, $candidate, $offset, $patchedCode.Length)
if ((Get-BytesHash $candidate) -ne $patchedHash) { throw '补丁结果校验失败。' }
} else {
$candidate = $bytes
}
[pscustomobject]@{ Root=$root; Target=$target; Backup=$backup; Hash=$hash; Candidate=$candidate }
}
foreach ($plan in $plans) {
if ($Action -eq 'Check') {
[pscustomobject]@{
Directory=$plan.Root
State=if ($plan.Hash -eq $patchedHash) { '已安装补丁' } else { '原版,符合补丁要求' }
SHA256=$plan.Hash
BackupExists=(Test-Path -LiteralPath $plan.Backup)
}
continue
}
if ($Action -eq 'Install' -and $plan.Hash -eq $patchedHash) {
Write-Host "已安装,无需重复修改:$($plan.Root)"
continue
}
if ($Action -eq 'Restore' -and $plan.Hash -eq $originalHash) {
Write-Host "已经是原文件:$($plan.Root)"
continue
}
if ($Action -eq 'Install') {
if (-not (Test-Path -LiteralPath $plan.Backup)) {
[IO.File]::Copy($plan.Target, $plan.Backup, $false)
}
if ((Get-FileHash -LiteralPath $plan.Backup -Algorithm SHA256).Hash -ne $originalHash) {
throw '备份验证失败;未覆盖游戏 DLL。'
}
$newBytes = $plan.Candidate
$expected = $patchedHash
} else {
$newBytes = [IO.File]::ReadAllBytes($plan.Backup)
$expected = $originalHash
}
# Detect changes made by another program since preflight.
if ((Get-FileHash -LiteralPath $plan.Target -Algorithm SHA256).Hash -ne $plan.Hash) {
throw "检查后文件发生变化,停止修改:$($plan.Target)"
}
if (Get-Process -Name 'oriwotw' -ErrorAction SilentlyContinue) {
throw '游戏刚刚启动,已停止修改;请先退出游戏。'
}
$staging = $plan.Target + '.ori-fix-' + [Guid]::NewGuid().ToString('N') + '.tmp'
try {
$stream = [IO.File]::Open($staging, [IO.FileMode]::CreateNew, [IO.FileAccess]::Write, [IO.FileShare]::None)
try { $stream.Write($newBytes); $stream.Flush($true) } finally { $stream.Dispose() }
if ((Get-FileHash -LiteralPath $staging -Algorithm SHA256).Hash -ne $expected) {
throw '临时文件验证失败,未覆盖游戏 DLL。'
}
[IO.File]::Move($staging, $plan.Target, $true)
if ((Get-FileHash -LiteralPath $plan.Target -Algorithm SHA256).Hash -ne $expected) {
throw '写入后的校验失败,请保留备份并停止启动游戏。'
}
} finally {
if (Test-Path -LiteralPath $staging) { Remove-Item -LiteralPath $staging }
}
Write-Host "${Action} 成功:$($plan.Target)"
Write-Host "原文件备份:$($plan.Backup)"
}