Files
ft/CodexOutput/upserver/B3BatchMigration/M2/C2d-封存与核证.py.txt
Liubing\LB 6813da149a feat(upserver): 保存M2客户端KV迁移至本人统计写检查点
保存独立KV用户服务、固定会话存档与原业务接线,以及C3d资料缓存和C3e本人统计写。
保留原PF/AGG路线、业务公式和时序;榜单读取、好友资料、公告、匹配及首场景闸仍待完成。

验证:ServiceHost两条件各33组646断言;Unity CLI Loop编译0错误269警告。
包含相关方案、评审裁决、测试及状态文档。未操作服务器、正式账号或打包。
2026-09-30 19:19:05 +08:00

36 lines
4.7 KiB
Plaintext
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.
import json,hashlib,re
from pathlib import Path
from datetime import datetime
m=Path('CodexOutput/upserver/B3BatchMigration/M2')
def read(p):return json.loads(p.read_text(encoding='utf-8-sig'))
def item(p):
p=Path(p);raw=p.read_bytes();return {'path':p.as_posix(),'bytes':len(raw),'sha256':hashlib.sha256(raw).hexdigest().upper()}
original={x['path']:x for x in read(m/'M2-合批正式受审基线.json')['items']}
c=read(m/'M2-合批-C2c检查点与交付hash.json');prior=dict(original);prior.update({x['path']:x for x in c['items']})
current=[item(p) for p in sorted(prior)]
changed=[x for x in current if x['path'] not in original or x['sha256']!=original[x['path']]['sha256']]
delta=[x['path'] for x in current if x['sha256']!=prior[x['path']]['sha256']]
allowed={x['path'] for x in read(m/'M2-合批正式候选白名单.json')['files']}|{'AGENTS.md','Client/Assets/Scripts/Services/UserService.KVFishingValidation.cs','Client/Assets/Scripts/Services/UserService.KVFishingRewardValidation.cs'}
unexpected=[x['path'] for x in changed if x['path'] not in allowed and x['path'].endswith(('.cs','.meta','.asmdef','.csproj'))];assert not unexpected,unexpected
assert item('Client/Assets/Scripts/UI/Home/HomePanel.cs')['sha256']==original['Client/Assets/Scripts/UI/Home/HomePanel.cs']['sha256']
assert item(m/'M2-合批正式受审基线.json')['sha256']=='DBC965EDBF48FADA4C1508F2662562F4FD72C01711D8E2FE2022AC4956896EF3'
assert item(m/'M2-合批正式独立方案审查-2026-09-29.md')['sha256']=='BB02441CFFE72AF18CF3B0D78F8E581FC39549C3F77E45257B5ED16CADCF2937'
compile=read(m/'M2-C2d-final-compile.json');assert compile['Success'] and compile['ErrorCount']==0
results={}
for name in ['consume','reward']:
d=read(m/f'M2-C2d-final-{name}.json');r=json.loads(d['Result']);assert d['Success'] and r['success'] and r['formalRequests']==0
results[name]={k:r[k] for k in ['groups','assertions','formalRequests']}
d=read(m/'M2-C2d-final-modules.json');assert d['Success'];r=d['Result']
a=json.loads(re.search(r'pureResult = (\{.*?\}), moduleResult',r)[1]);b=json.loads(re.search(r'moduleResult = (\{.*?\}), playing',r)[1]);assert a['success'] and b['success'] and b['restored'] and b['realModules']==31
state=json.loads(read(m/'M2-C2d-final-state.json')['Result']);assert not any(state[k] for k in ['playing','enabled','ready','permitExists'])
for name in ['NON_ANDROID','ANDROID_AGG']:
assert 'groups=18 assertions=254 formalRequests=0' in (m/f'M2-C2d-final-ServiceHost-{name}.log').read_text(encoding='utf-8-sig')
recovered=[]
for p in [Path('CodexOutput/upserver/KVGameplayLoopTests/fishing-fixed-runs/20260930T032500_c51bfd787cac474983d7863461e379e8/result.json'),Path('CodexOutput/upserver/KVGameplayLoopTests/reward-fixed-runs/20260930T032547_cae307d3ed07409a8a3c363c460357fa/result.json')]:
assert read(p)['success'];recovered.append(item(p))
(m/'M2-C2d-合并CLI超时核对.json').write_text(json.dumps({'cliSucceeded':False,'cliError':'Request timed out after 180000ms','underlyingResults':recovered,'followup':'Final individual CLI outputs are authoritative.'},ensure_ascii=False,indent=2),encoding='utf-8')
evidencePaths=list(m.glob('M2-C2d-*.json'))+list(m.glob('M2-C2d-*.log'))+list(m.glob('C2d-*.py.txt'))+[m/'C2d修改前快照/index.json',m/'M2-纯平移用户审查确认与C2d实施边界-2026-09-30.json',m/'M2-纯平移主会话裁决与C2d实施记录-2026-09-30.md']
report={'date':datetime.now().astimezone().isoformat(),'stage':'C2d 纯平移核减与旧验证宿主注入完成;C3真实集成未验','reviewBasis':'用户明确审核完毕并继续,详见用户确认JSON;未声称收到新独立报告','originalReviewReportSha256':item(m/'M2-合批正式独立方案审查-2026-09-29.md')['sha256'],'originalManifestSha256':item(m/'M2-合批正式受审基线.json')['sha256'],'priorCheckpointSha256':item(m/'M2-合批-C2c检查点与交付hash.json')['sha256'],'combinedItemCount':len(current),'changedSinceC2c':delta,'outsideCodeWhitelist':unexpected,'unchangedOriginal':sum(x['path'] in original and x['sha256']==original[x['path']]['sha256'] for x in current),'items':changed,'homePanelUnchanged':True,'compile':{k:compile[k] for k in ['Success','ErrorCount','WarningCount']},'offlineResults':results,'modules':{'M08-M23':a,'B2-20':b},'serviceHost':{'NON_ANDROID':{'groups':18,'assertions':254},'ANDROID+AGG':{'groups':18,'assertions':254}},'evidence':[item(p) for p in sorted(set(evidencePaths)) if p.stat().st_size>0],'runtimeVerified':False,'formalRequests':0}
out=m/'M2-合批-C2d检查点与交付hash.json';out.write_text(json.dumps(report,ensure_ascii=False,indent=2),encoding='utf-8')
print(json.dumps({'combined':len(current),'cumulativeChanged':len(changed),'unchangedOriginal':report['unchangedOriginal'],'changedSinceC2c':len(delta),'outsideCodeWhitelist':unexpected,'checkpointSha256':item(out)['sha256']}))