from pathlib import Path
import zipfile,json,hashlib,uuid,struct,importlib.util,sys
from lupa.luajit21 import LuaRuntime
R=Path(__file__).resolve().parents[1]
VERSION='1.11.1';RESOURCE='mods/arena_local/mech_part_hud'
GUID=str(uuid.uuid5(uuid.NAMESPACE_URL,'https://arena.ai/workspace/mech-part-hud'))
NAME='机甲部位血量HUD v'+VERSION
def assemble():
 s='-- HD2-Addon: '+RESOURCE+'\n-- Mech Part HUD '+VERSION+'. Read-only. Native reader adapted from DRIVER HUD 1.3.5, compatibility check per DRIVER HUD 1.4.5 (MIT, FireScallion).\n'
 s+="local sr=rawget(_G,'stingray');if type(sr)~='table' then return {installed=false} end\n"
 for name,f in [('Native','native'),('Z','zones'),('make_reader','mech_reader'),('Render','render'),('ART','art'),('RenderMech','render_mech'),('config','config'),('Arms','arms'),('encode','json'),('SpatialPolicy','spatial_policy'),('MountPolicy','mount_policy'),('SpatialFactory','spatial_runtime'),('ReferenceFactory','unit_ref_bridge'),('install','hud')]:
  s+='local '+name+'=(function()\n'+(R/'src'/f'{f}.lua').read_text()+'\nend)()\n'
 s+='return install(sr,Native,make_reader(Native,Z),Render,Z,config,ART,RenderMech,Arms(Native,Z),encode,SpatialFactory(sr,Native,Z,SpatialPolicy,ReferenceFactory(sr),MountPolicy))\n'
 for w in ['WriteProcessMemory','VirtualProtect','CreateRemoteThread','OpenProcess(','LoadLibrary','SendInput','set_game_object_field','mods/driver_hud/solid','CreateFile','ffi.load("user32")']:
  assert w not in s,w
 LuaRuntime().execute('assert(loadstring(...))',s)
 return s
def main():
 src=assemble();(R/'build_out').mkdir(exist_ok=True);(R/'build_out/mech_part_hud.lua').write_text(src)
 spec=importlib.util.spec_from_file_location('w',R/'tools/archive_writer.py');a=importlib.util.module_from_spec(spec);spec.loader.exec_module(a);a.RESOURCE=RESOURCE
 data=a.archive(src.encode())
 ident,kind,off=struct.unpack_from('<QQQ',data,104);n,v=struct.unpack_from('<II',data,off)
 assert ident==a.murmur64(RESOURCE.encode()) and v==2 and data[off+8:off+8+n]==src.encode()
 desc='驾驶外骨骼机甲时，在屏幕右下角显示机体结构血条和各部位血量：驾驶舱、髋部、双腿、左右武器臂一目了然，受伤变色、损毁标记。支持 EXO-45 爱国者、EXO-49 解放者、EXO-51 伐木者、EXO-55 突破；多人同场时自动识别你自己驾驶的机甲。纯只读，不修改任何游戏数值。需要 Bingus Shared Loader。'
 manifest={'Version':1,'Guid':GUID,'Name':NAME,'Description':desc,'Options':[{'Name':'机甲部位血量 HUD','Description':desc,'Include':['HUD']}]}
 files={'manifest.json':json.dumps(manifest,ensure_ascii=False,indent=2).encode(),'HUD/9ba626afa44a3aa3.patch_0':data,'HUD/9ba626afa44a3aa3.patch_0.stream':b'','HUD/9ba626afa44a3aa3.patch_0.gpu_resources':b''}
 for name in ['README.md','CREDITS.md','LICENSE-DRIVER-HUD.txt','LICENSE-NOTO-CJK.txt','mech_hud.cfg.example']:
  files[name]=(R/name).read_bytes();files['Source/'+name]=files[name]
 files['OFL-fusion-pixel.txt']=(R/'art/fonts/OFL-fusion-pixel.txt').read_bytes()
 for folder in ['src','tools','tests','art','validation']:
  for p in sorted((R/folder).rglob('*')):
   if p.is_file() and '__pycache__' not in p.parts and p.suffix!='.ttf':files['Source/'+p.relative_to(R).as_posix()]=p.read_bytes()
 files['SHA256SUMS.txt']=''.join(hashlib.sha256(b).hexdigest()+'  '+k+'\n' for k,b in sorted(files.items())).encode()
 out=R/'releases'/f'机甲部位血量HUD-v{VERSION}.zip';out.parent.mkdir(exist_ok=True)
 with zipfile.ZipFile(out,'w') as z:
  for k,b in sorted(files.items()):
   i=zipfile.ZipInfo(k,(2026,9,24,0,0,0));i.compress_type=zipfile.ZIP_DEFLATED;i.external_attr=0o100644<<16;z.writestr(i,b)
 with zipfile.ZipFile(out) as z:
  assert z.testzip() is None
  for k,b in files.items():assert z.read(k)==b
 print(json.dumps({'path':str(out),'bytes':out.stat().st_size,'sha256':hashlib.sha256(out.read_bytes()).hexdigest(),'guid':GUID,'resource':RESOURCE},ensure_ascii=False))
if __name__=='__main__':main()
