"""Bounded original FocusBillboard geometry/material proof; no process access."""
from pathlib import Path
import hashlib,importlib.util,json,struct
spec=importlib.util.spec_from_file_location('audit','research/Audit-GalaxyClientCompatibility.py')
audit=importlib.util.module_from_spec(spec);spec.loader.exec_module(audit)
image=audit.Image(Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe'))
sha=hashlib.sha256(image.raw).hexdigest()
if sha!='6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93':raise ValueError('Pinned billboard image changed')
folder=Path('artifacts/galaxy-query-research/power-outer-sources')
material=next(m for m in json.loads((folder/'material/original-materials.json').read_text())['materials'] if m['name']=='focusbillboard')
state=next(m for m in json.loads((folder/'material-slots/original-blend-application.json').read_text())['materials'] if m['material']=='focusbillboard')
if not state['resolved'] or state['originalEnums']['rgbSource']!=1 or state['originalEnums']['rgbDestination']!=5:raise ValueError('Original contour blend changed')
parameters={p['name']:p.get('floatValues',[p.get('integerValue')])[0] for p in material['parameters']}
for name,expected in [('pCoreCircleRadius',.9),('pInteriorFadeRadius',.75),('pExteriorFadeRadius',.92),('pFadeIntensity',.175),('pHighlightIntensity',1.5),('pHighlightBandWidth',.005),('pEmissiveRescalingEVOffset',1)]:
if abs(parameters[name]-expected)>1e-7:raise ValueError('Original contour material changed')
if struct.unpack('<Q',image.data(0x551F838+8,8))[0]!=image.base+0x3A1E730:raise ValueError('Original contour callback changed')
if image.data(0x3A1E730,4)!=bytes.fromhex('488b4910'):raise ValueError('Original contour callback receiver changed')
branch=image.instructions(0x3A1E734,5)[0]
if branch.mnemonic!='jmp' or branch.operands[0].imm-image.base!=0x3C05840:raise ValueError('Original contour append changed')
if image.data(0x3C05858,4)!=bytes.fromhex('49c1e006'):raise ValueError('Original contour record is not64bytes')
if struct.unpack('<Q',image.data(0x5538210+0x20,8))[0]!=image.base+0x3C16230:raise ValueError('Original contour draw slot changed')
draw=image.instructions(0x3C16230,image.function(0x3C16230)[1]-0x3C16230)
if not any(x.mnemonic=='mov' and x.op_str=='edx, 5' for x in draw) or not any(x.mnemonic=='lea' and x.op_str=='r8d, [rdx - 3]' for x in draw):raise ValueError('Original contour topology/primitive count changed')
if image.data(0x4E2DE48+5*2,2)!=bytes([1,2]) or struct.unpack('<I',image.data(0x4E2DE78+5*4,4))[0]!=5:raise ValueError('Original contour vertex-count/topology mapping changed')
appearance=json.loads(Path('artifacts/galaxy-query-research/palette-resources/original-appearance.json').read_text())
colour=[appearance['unknownFields'][hex(n)] for n in (0x13C,0x140,0x144)]+[0]
if struct.pack('<4f',*colour).hex()!='1b2fdd3c7368713f0000803f00000000':raise ValueError('Original contour colour changed')
allocation=struct.unpack('<f',image.data(0x5537240,4))[0]
if allocation!=2.222222328186035:raise ValueError('Original contour tangent allocation changed')
functions=[]
for rva in [0x3AF6C40,0x1418810,0x3B33690,0x3B064F0,0x3A441A0,0x3C022F0,0x3C16230]:
bounds=image.function(rva)
if bounds is None or bounds[0]!=rva:raise ValueError('Original contour body missing')
raw=image.data(rva,bounds[1]-rva);functions.append(dict(rva=hex(rva),bytes=len(raw),sha256=hashlib.sha256(raw).hexdigest()))
shaders={stage:dict(path=str(path),sha256=hashlib.sha256(path.read_bytes()).hexdigest()) for stage in ['vs','ps'] for path in [folder/f'effects/{stage}_GalaxyMapFocusBillboard_Forward_0_Win64_SM50.dxbc']}
effects=Path(state['archiveSource']).read_bytes();cursor=state['effectArchiveOffset']+8;objects=[]
for _ in range(2):
marker=effects.index(b'\0\1voMrtP',cursor);size,relocations=struct.unpack_from('<2I',effects,marker+8)
objects.append(effects[marker+16:marker+16+size]);cursor=marker+16+size+relocations*4
variables=objects[1];pointer,count=struct.unpack_from('<2Q',variables,0x48);reflection={}
for n in range(count):
at=pointer+n*32;name_ptr=struct.unpack_from('<Q',variables,at)[0];name=variables[name_ptr:variables.index(b'\0',name_ptr)].decode('ascii')
if name not in ['gCameraPos','gScreenSize']:continue
packed=struct.unpack_from('<H',variables,at+10)[0];reflection[name]=dict(dataOffset=(packed>>1)&0x7FFC,raw=variables[at:at+32].hex())
anchor=reflection['gCameraPos']['dataOffset']-275*16
if anchor!=272 or reflection['gScreenSize']['dataOffset']-anchor!=332*16:raise ValueError('Original contour screen-size antialias binding changed')
result=dict(imageSha256=sha,gameProcessAccess=False,gameCalls=0,functions=functions,recordBytes=64,vertices=4,topology='TriangleStrip',
material=material,blend=state['originalEnums'],sourceColour=colour,allocationMultiplier=allocation,shaders=shaders,
screenAntialias=dict(reflection=reflection,sharedDataOffset=anchor,actualRegister='cb1[332].xy = gScreenSize.xy'),
source='actual cached centre metadata and owner/state definition extent; never the independent radius',
limits=['per-system influence links are independent','runtime material/global overrides are not copied','whole original pipeline remains partial'])
out=folder/'focus-billboard/original-billboard.json';out.parent.mkdir(parents=True,exist_ok=True);out.write_text(json.dumps(result,indent=2)+'\n')
print(json.dumps(dict(path=str(out),vertices=4,recordBytes=64,sourceColour=colour)))
"""Bounded original FocusBillboard geometry/material proof; no process access."""
from pathlib import Path
import hashlib,importlib.util,json,struct
spec=importlib.util.spec_from_file_location('audit','research/Audit-GalaxyClientCompatibility.py')
audit=importlib.util.module_from_spec(spec);spec.loader.exec_module(audit)
image=audit.Image(Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe'))
sha=hashlib.sha256(image.raw).hexdigest()
if sha!='6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93':raise ValueError('Pinned billboard image changed')
folder=Path('artifacts/galaxy-query-research/power-outer-sources')
material=next(m for m in json.loads((folder/'material/original-materials.json').read_text())['materials'] if m['name']=='focusbillboard')
state=next(m for m in json.loads((folder/'material-slots/original-blend-application.json').read_text())['materials'] if m['material']=='focusbillboard')
if not state['resolved'] or state['originalEnums']['rgbSource']!=1 or state['originalEnums']['rgbDestination']!=5:raise ValueError('Original contour blend changed')
parameters={p['name']:p.get('floatValues',[p.get('integerValue')])[0] for p in material['parameters']}
for name,expected in [('pCoreCircleRadius',.9),('pInteriorFadeRadius',.75),('pExteriorFadeRadius',.92),('pFadeIntensity',.175),('pHighlightIntensity',1.5),('pHighlightBandWidth',.005),('pEmissiveRescalingEVOffset',1)]:
if abs(parameters[name]-expected)>1e-7:raise ValueError('Original contour material changed')
if struct.unpack('<Q',image.data(0x551F838+8,8))[0]!=image.base+0x3A1E730:raise ValueError('Original contour callback changed')
if image.data(0x3A1E730,4)!=bytes.fromhex('488b4910'):raise ValueError('Original contour callback receiver changed')
branch=image.instructions(0x3A1E734,5)[0]
if branch.mnemonic!='jmp' or branch.operands[0].imm-image.base!=0x3C05840:raise ValueError('Original contour append changed')
if image.data(0x3C05858,4)!=bytes.fromhex('49c1e006'):raise ValueError('Original contour record is not64bytes')
if struct.unpack('<Q',image.data(0x5538210+0x20,8))[0]!=image.base+0x3C16230:raise ValueError('Original contour draw slot changed')
draw=image.instructions(0x3C16230,image.function(0x3C16230)[1]-0x3C16230)
if not any(x.mnemonic=='mov' and x.op_str=='edx, 5' for x in draw) or not any(x.mnemonic=='lea' and x.op_str=='r8d, [rdx - 3]' for x in draw):raise ValueError('Original contour topology/primitive count changed')
if image.data(0x4E2DE48+5*2,2)!=bytes([1,2]) or struct.unpack('<I',image.data(0x4E2DE78+5*4,4))[0]!=5:raise ValueError('Original contour vertex-count/topology mapping changed')
appearance=json.loads(Path('artifacts/galaxy-query-research/palette-resources/original-appearance.json').read_text())
colour=[appearance['unknownFields'][hex(n)] for n in (0x13C,0x140,0x144)]+[0]
if struct.pack('<4f',*colour).hex()!='1b2fdd3c7368713f0000803f00000000':raise ValueError('Original contour colour changed')
allocation=struct.unpack('<f',image.data(0x5537240,4))[0]
if allocation!=2.222222328186035:raise ValueError('Original contour tangent allocation changed')
functions=[]
for rva in [0x3AF6C40,0x1418810,0x3B33690,0x3B064F0,0x3A441A0,0x3C022F0,0x3C16230]:
bounds=image.function(rva)
if bounds is None or bounds[0]!=rva:raise ValueError('Original contour body missing')
raw=image.data(rva,bounds[1]-rva);functions.append(dict(rva=hex(rva),bytes=len(raw),sha256=hashlib.sha256(raw).hexdigest()))
shaders={stage:dict(path=str(path),sha256=hashlib.sha256(path.read_bytes()).hexdigest()) for stage in ['vs','ps'] for path in [folder/f'effects/{stage}_GalaxyMapFocusBillboard_Forward_0_Win64_SM50.dxbc']}
effects=Path(state['archiveSource']).read_bytes();cursor=state['effectArchiveOffset']+8;objects=[]
for _ in range(2):
marker=effects.index(b'\0\1voMrtP',cursor);size,relocations=struct.unpack_from('<2I',effects,marker+8)
objects.append(effects[marker+16:marker+16+size]);cursor=marker+16+size+relocations*4
variables=objects[1];pointer,count=struct.unpack_from('<2Q',variables,0x48);reflection={}
for n in range(count):
at=pointer+n*32;name_ptr=struct.unpack_from('<Q',variables,at)[0];name=variables[name_ptr:variables.index(b'\0',name_ptr)].decode('ascii')
if name not in ['gCameraPos','gScreenSize']:continue
packed=struct.unpack_from('<H',variables,at+10)[0];reflection[name]=dict(dataOffset=(packed>>1)&0x7FFC,raw=variables[at:at+32].hex())
anchor=reflection['gCameraPos']['dataOffset']-275*16
if anchor!=272 or reflection['gScreenSize']['dataOffset']-anchor!=332*16:raise ValueError('Original contour screen-size antialias binding changed')
result=dict(imageSha256=sha,gameProcessAccess=False,gameCalls=0,functions=functions,recordBytes=64,vertices=4,topology='TriangleStrip',
material=material,blend=state['originalEnums'],sourceColour=colour,allocationMultiplier=allocation,shaders=shaders,
screenAntialias=dict(reflection=reflection,sharedDataOffset=anchor,actualRegister='cb1[332].xy = gScreenSize.xy'),
source='actual cached centre metadata and owner/state definition extent; never the independent radius',
limits=['per-system influence links are independent','runtime material/global overrides are not copied','whole original pipeline remains partial'])
out=folder/'focus-billboard/original-billboard.json';out.parent.mkdir(parents=True,exist_ok=True);out.write_text(json.dumps(result,indent=2)+'\n')
print(json.dumps(dict(path=str(out),vertices=4,recordBytes=64,sourceColour=colour)))