62 lines
3.8 KiB
Python
62 lines
3.8 KiB
Python
"""Four remaining enemy Studio trials; clouds run serially, Unity mutations stay serial."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
ROOT=Path(__file__).resolve().parents[1]
|
|
WORKBENCH=Path('D:/UD/AI/XModel/LLM3DGraphics/.venv/Scripts/python.exe')
|
|
|
|
def main():
|
|
ap=argparse.ArgumentParser()
|
|
ap.add_argument('--stage',choices=('cloud','finish','play','verify'),required=True)
|
|
ap.add_argument('--actors',nargs='+')
|
|
ap.add_argument('--play-check',action='store_true')
|
|
a=ap.parse_args()
|
|
config=json.loads((ROOT/'Config/Art/StudioTrials/Enemies.json').read_text(encoding='utf-8'))
|
|
rows=[r for r in config['actors'] if not a.actors or r['actor'] in a.actors]
|
|
if a.actors and set(a.actors)-{r['actor'] for r in rows}:raise ValueError('Unknown enemy')
|
|
if a.stage=='play':
|
|
from enemy_character_pipeline import unity,script,wait_editor
|
|
if a.actors:raise ValueError('The combined Play check requires all four actors')
|
|
unity('set_autotick',enable=True)
|
|
if unity('editor_status')['playMode']!='stopped':raise RuntimeError('Preserve the current Play session; run this after it stops')
|
|
unity('editor_play')
|
|
try:
|
|
wait_editor('playing');script('VerifyEnemyStudioBatch','VerifyEnemyStudioBatch.PlayAll',[])
|
|
finally:unity('editor_stop');wait_editor('stopped')
|
|
for row in rows:
|
|
folder=ROOT/'Tools/output/studio_trial'/row['actor'];path=folder/'trial.json';receipt=json.loads(path.read_text(encoding='utf-8'))
|
|
if json.loads((folder/'unity_verification.json').read_text(encoding='utf-8'))['status']!='pass':raise ValueError('Edit QA missing')
|
|
for relative,digest in receipt['originals'].items():
|
|
if hashlib.sha256((ROOT/relative).read_bytes()).hexdigest()!=digest:raise ValueError(relative+' changed')
|
|
receipt['status']='validated';path.write_text(json.dumps(receipt,indent=2),encoding='utf-8')
|
|
return
|
|
for row in rows:
|
|
actor=row['actor']
|
|
if hashlib.sha256((ROOT/row['source']).read_bytes()).hexdigest()!=row['sourceSha256']:raise ValueError(actor+' source changed')
|
|
if a.stage=='cloud':
|
|
cmd=[str(WORKBENCH),'Tools/studio_lowpoly_trial.py','--actor',actor,'--kind','Enemy','--source',row['source'],'--rig',row['rig'],'--prefab',row['prefab'],'--tris',str(config['targetTriangles']),'--size',str(config['textureSize'])]
|
|
elif a.stage=='finish':
|
|
cmd=[sys.executable,'Tools/studio_lowpoly_finish.py','--actor',actor,'--height',str(row['height']),'--recipe',row['recipe']]
|
|
if a.play_check:cmd.append('--play-check')
|
|
else:
|
|
folder=ROOT/'Tools/output/studio_trial'/actor
|
|
receipt=json.loads((folder/'trial.json').read_text(encoding='utf-8'))
|
|
if receipt['status']!='validated':raise ValueError(actor+' has not passed actual Play')
|
|
for path,digest in receipt['originals'].items():
|
|
if hashlib.sha256((ROOT/path).read_bytes()).hexdigest()!=digest:raise ValueError(path+' changed')
|
|
for name in ('unity_verification.json','play_verification.json'):
|
|
if json.loads((folder/name).read_text(encoding='utf-8'))['status']!='pass':raise ValueError(actor+' failed '+name)
|
|
print('PASS '+actor+' validated; original protected hashes unchanged',flush=True)
|
|
continue
|
|
print('BEGIN '+actor+' '+a.stage,flush=True)
|
|
child=subprocess.Popen(cmd,cwd=ROOT,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True,encoding='utf-8',errors='replace')
|
|
for line in child.stdout:print(actor+': '+line.rstrip(),flush=True)
|
|
if child.wait():raise RuntimeError(actor+' '+a.stage+' failed; completed task records are retained for resume')
|
|
print('COMPLETE '+actor+' '+a.stage,flush=True)
|
|
|
|
if __name__=='__main__':main()
|