Files

45 lines
3.5 KiB
Python

"""Validate actual packaged process evidence. Does not drive the game or infer screenshots."""
import argparse
import json
import struct
from pathlib import Path
def total(items,item):return sum(i['count'] for i in items if i['itemId']==item)
def verify(folder):
launch=json.loads((folder/'launch.json').read_text(encoding='utf-8-sig'))
checks=[]
def check(name,value):checks.append({'name':name,'passed':bool(value)})
images=[]
for path in sorted(folder.glob('*.png')):
data=path.read_bytes()
if not data.startswith(b'\x89PNG\r\n\x1a\n'):raise ValueError('Not PNG: '+str(path))
width,height=struct.unpack('>II',data[16:24]);images.append({'file':path.name,'width':width,'height':height,'environment':launch['environment']})
check('Captured real images',len(images)>=5)
expected=tuple(map(int,launch['requestedResolution'].split('x')))
check('Actual captures match requested resolution',all((i['width'],i['height'])==expected for i in images))
def load(name):return json.loads((folder/(name+'.json')).read_text(encoding='utf-8-sig'))
if launch['scenario']=='cycle':
before,deploy,pod,ready,returned,dead,final=[load(n) for n in ('before','deployed','pod-recovered','ready-still-active','returned','destroyed','final')]
check('V1 unchanged',all(p['version']==1 for p in (before,deploy,pod,ready,returned,dead,final)))
check('Deployment consumed owned starter UID once',deploy['sorties']==1 and len(deploy['run']['installed'])==4 and len(deploy['warehouse'])==0)
check('Pod bank and exact receipt',pod['run']['active'] and pod['run']['podUsed'] and total(pod['warehouse'],'alloy')==4 and pod['receipts']==[deploy['run']['id']+':cargo'])
check('Ready transport did not auto-extract',ready['run']['active'] and ready['extractions']==0 and len(ready['receipts'])==1)
check('Explicit boarding returned equipment and protected cargo',not returned['run']['active'] and returned['extractions']==1 and total(returned['warehouse'],'cells')==2 and len(returned['warehouse'])==6)
check('Death retains only safe cargo; loss cargo not banked',dead['sorties']==2 and dead['extractions']==1 and total(dead['warehouse'],'alloy')==4 and total(dead['warehouse'],'cells')==5 and len(dead['warehouse'])==2 and not dead['run']['active'])
check('Recovery receipts unique',len(final['receipts'])==len(set(final['receipts']))==4)
uids=[i['uid'] for key in ('warehouse','recoveryInbox') for i in final[key]]+[i['uid'] for key in ('cargo','safeCase','installed') for i in final['run'][key]]
check('Unique physical ownership',len(uids)==len(set(uids)))
else:
profile=load('ui-profile');check('UI sweep did not deploy or change save version',profile['version']==1 and profile['sorties']==0 and not profile['run']['active'])
check('Both languages captured',any(i['file'].startswith('hangar-zh') for i in images) and any(i['file'].startswith('hangar-en') for i in images))
result={'passed':all(c['passed'] for c in checks),'checks':checks,'screenshots':images}
(folder/'verification.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
print(json.dumps({'folder':str(folder),'passed':result['passed'],'checks':len(checks),'failed':[c['name'] for c in checks if not c['passed']],'images':len(images)},ensure_ascii=False))
return result['passed']
if __name__=='__main__':
parser=argparse.ArgumentParser();parser.add_argument('folder',type=Path);args=parser.parse_args()
raise SystemExit(0 if verify(args.folder.resolve()) else 1)