Files
ft/CodexOutput/upserver/KVFishingRewardTests/reconcile-fourth.ps1

76 lines
5.3 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
$ErrorActionPreference='Stop'
$root='C:/projects/ft/CodexOutput/upserver'
function Read-Backup($stamp) { Get-Content -Raw -LiteralPath "$root/KVGameplayLoopTests/backups/$stamp/102.json" | ConvertFrom-Json }
function Changed-Keys($left,$right) {
@(@($left.PSObject.Properties.Name)+@($right.PSObject.Properties.Name) | Sort-Object -Unique | Where-Object { $left.$_ -cne $right.$_ })
}
function Hash-Value([string]$value) {
$sha=[Security.Cryptography.SHA256]::Create()
try { [BitConverter]::ToString($sha.ComputeHash([Text.Encoding]::UTF8.GetBytes($value))).Replace('-','') } finally { $sha.Dispose() }
}
$before=Read-Backup '20260928T024346Z'
$reward=Read-Backup '20260928T024903Z'
$closed=Read-Backup '20260928T025001Z'
$final=Read-Backup '20260928T025514Z'
$events=@(Get-Content -LiteralPath "$root/KVGameplayLoopTests/runs/44848_639261601944579366/events.jsonl" | ForEach-Object { $_ | ConvertFrom-Json })
$recoveryEvents=@(Get-Content -LiteralPath "$root/KVGameplayLoopTests/runs/103828_639261606481142886/events.jsonl" | ForEach-Object { $_ | ConvertFrom-Json })
$recovered=(Get-Content -Raw -LiteralPath "$root/KVFishingRewardTests/fourth-recovered-values.json" | ConvertFrom-Json).Result | ConvertFrom-Json
$preMain=$before.data.NewPlayerDataDic | ConvertFrom-Json
$postMain=$final.data.NewPlayerDataDic | ConvertFrom-Json
$preMap=$before.data.Map_5_102 | ConvertFrom-Json
$postMap=$final.data.Map_5_102 | ConvertFrom-Json
$rewardConfirmation=@($events | Where-Object kind -EQ 'fishing-reward-confirmed')[0]
$presentation=@($events | Where-Object kind -EQ 'fishing-reward-presented')[0]
$ticketMatches=@($rewardConfirmation.detail.tickets | ForEach-Object { [pscustomobject]@{key=$_.key;sequence=$_.sequence;matchesFinalServer=((Hash-Value $final.data.($_.key)) -ceq $_.valueHash)} })
$cacheResults=@('44848_639261601944579366','103828_639261606481142886' | ForEach-Object {
$cacheFile=Get-ChildItem -LiteralPath "$root/KVGameplayLoopTests/runs/$_/cache" -Recurse -Filter state.json
$cache=Get-Content -Raw -LiteralPath $cacheFile.FullName | ConvertFrom-Json
[pscustomobject]@{run=$_;pending=@($cache.pending).Count;unknown=($null -ne $cache.unknownBatch);active=($null -ne $cache.activeBatch);baselineChangedKeys=@(Changed-Keys $cache.baseline $final.data)}
})
$report=[ordered]@{
phase='4C2-fourth-real-run-and-fresh-process-recovery-awaiting-independent-review'
api=$recovered.api
backups=@('20260928T024346Z','20260928T024903Z','20260928T025001Z','20260928T025514Z')
countBefore=@($before.data.PSObject.Properties).Count;countAfter=@($final.data.PSObject.Properties).Count
changedKeys=@(Changed-Keys $before.data $final.data)
changedFishIds=@(Changed-Keys $preMap $postMap)
fishBefore=$preMap.'10223';fishAfter=$postMap.'10223'
mainBefore=$preMain;mainAfter=$postMain
rewardToQuitChangedKeys=@(Changed-Keys $reward.data $closed.data)
quitToRecoveryFinalChangedKeys=@(Changed-Keys $closed.data $final.data)
consumeCount=@($events | Where-Object kind -EQ 'fishing-energy-applied').Count
rewardConfirmedCount=@($events | Where-Object kind -EQ 'fishing-reward-confirmed').Count
rewardPresentedCount=@($events | Where-Object kind -EQ 'fishing-reward-presented').Count
confirmedBeforePresented=([DateTime]$rewardConfirmation.at -lt [DateTime]$presentation.at)
rewardTickets=$ticketMatches
faults=@($events | Where-Object kind -EQ 'fault').Count
recoveryFishingEvents=@($recoveryEvents | Where-Object kind -Like 'fishing-*').Count
recoveryWrites=@($recoveryEvents | Where-Object kind -EQ 'accepted').Count
recovered=$recovered
recoveredCoreEqualsFinalServer=($recovered.core -ceq $postMain.newData)
recoveredFishRawEqualsFinalServer=($recovered.fishRaw -ceq $postMap.'10223')
cacheResults=$cacheResults
signupGold=16200;fishingGold=2516;totalGold=18716
independentFormulaRecomputed=$false
precastIndependentBackupCaptured=$false
boundary='用户在主会话尚未完成动作前快照时手动签到并抛竿;precast/live-gates实际采样晚于扣费,不能充当动作前基线。保存完整审计和服务器前后值,交独立复核裁决证据是否充分,不自动重跑。鱼TotalNum由新进程KV有效值读回验证;活对象直接验证重量/等级/NewFish,未通过私有反射读取TotalNum。'
}
$report | ConvertTo-Json -Depth 20 | Set-Content -LiteralPath "$root/KVFishingRewardTests/fourth-reconciliation.json" -Encoding utf8
$checks=@(
$report.api -ceq 'http://s101.local:18080/'
$report.consumeCount -eq 1
$report.rewardConfirmedCount -eq 1
$report.rewardPresentedCount -eq 1
$report.confirmedBeforePresented
$report.faults -eq 0
$report.recoveryFishingEvents -eq 0
$report.rewardToQuitChangedKeys.Count -eq 0
$report.quitToRecoveryFinalChangedKeys.Count -eq 0
$report.recoveredCoreEqualsFinalServer
$report.recoveredFishRawEqualsFinalServer
@($ticketMatches | Where-Object { -not $_.matchesFinalServer }).Count -eq 0
@($cacheResults | Where-Object { $_.pending -ne 0 -or $_.unknown -or $_.active -or $_.baselineChangedKeys.Count -ne 0 }).Count -eq 0
)
if($checks -contains $false) { throw 'Reconciliation assertion failed; inspect fourth-reconciliation.json' }
[pscustomobject]@{checks=$checks.Count;passed=$true;changedKeys=$report.changedKeys;changedFishIds=$report.changedFishIds;recoveryUnchanged=$true} | ConvertTo-Json -Depth 4