"""Verify the actual original metadata consumers and the shipped enum names."""
import hashlib
import importlib.util
import json
import re
from pathlib import Path
spec=importlib.util.spec_from_file_location('audit',Path(__file__).with_name('Audit-GalaxyClientCompatibility.py'))
audit=importlib.util.module_from_spec(spec);spec.loader.exec_module(audit)
old=audit.Image(Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe'))
new=audit.Image(Path('D:/SteamLibrary/steamapps/common/Elite Dangerous/Products/elite-dangerous-odyssey-64/EliteDangerous64.exe'))
hashes=[hashlib.sha256(i.raw).hexdigest() for i in (old,new)]
if hashes!=['6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93','ed5a8f8cd10f9a80d3bda5badd7ba1d4fcfc15996c8c7e018852cb170e264b63']:
raise ValueError('Basic metadata consumer image changed')
definitions=[('population',0x3B27FA0,0x30),('governmentId',0x3B26180,0x18),('primaryEconomyId',0x3B25D40,0x20),
('secondaryEconomyId',0x3B25D40,0x24),('factionStateId',0x3B262E0,0x1C),('allegianceId',0x3B26030,8),('securityValue',0x1C40B90,0x3A)]
functions={};fields=[]
for name,before,offset in definitions:
span=old.function(before)
if span is None or span[0]!=before:raise ValueError('Metadata consumer lost its exact function range')
length=span[1]-before
row=audit.match(old,new,before,length)
if row['status']!='unique':raise ValueError('Metadata consumer is not uniquely matched')
row['oldRva']=hex(before);functions[hex(before)]=row
reads=[dict(rva=hex(i.address-old.base),instruction=i.mnemonic+' '+i.op_str) for i in old.instructions(before,length)
if i.mnemonic.startswith('mov') and any(op.type==audit.X86_OP_MEM and op.mem.base==audit.cs.x86.X86_REG_RAX and op.mem.disp==offset for op in i.operands)]
if not reads:raise ValueError('Original descriptor read is missing: '+name)
fields.append(dict(name=name,descriptorOffset=hex(offset),consumer=hex(before),reads=reads))
code=json.loads(Path('artifacts/galaxy-query-research/palette-resources/code-tables.json').read_text(encoding='utf8'))
as_path=Path('artifacts/galaxy-marker-research/map-as/scripts/factions/consts/FactionStates.as')
states={int(value):name for name,value in re.findall(r'public static const (\w+):int = (\d+);',as_path.read_text(encoding='utf8')) if name!='Max'}
source=Path('XFEEDToolBox.Core/Galaxy/GalaxyNativeBasicSystemFacts.cs').read_text(encoding='utf8')
def array(name):
match=re.search(r'private static readonly string\[\] '+name+r'=\[(.*?)\];',source)
if not match:raise ValueError('Core original enum array missing')
return re.findall(r'"([^"]*)"',match.group(1))
for source_name,target,aliases in [('government','Governments',{}),('economy','Economies',{'Agri':'Agriculture'})]:
rows=code['enumerations'][source_name]
if [r['value'] for r in rows]!=list(range(len(rows))):raise ValueError('Original enum is no longer contiguous')
if array(target)!=[aliases.get(r['name'],r['name']) for r in rows]:raise ValueError('Core enum differs from original '+source_name)
if array('FactionStates')!=[{'Terrorism':'TerroristAttack'}.get(states[i],states[i]) for i in range(40)]:raise ValueError('Core base state differs from actual map-AS')
lookup=Path('artifacts/galaxy-query-research/account-sources/decompiled/solo-39bed80.c')
result=dict(runtimeNeutral=True,gameCalls=0,networkRequests=0,runtimeValidated=False,canInstallHooks=False,
oldImageSha256=hashes[0],newImageSha256=hashes[1],functions=list(functions.values()),fields=fields,
lookup=dict(original='39BED80',actualInterfaceOld='551A1E0',actualInterfaceNew='551A1B0',slot='28',
returnedDescriptor='hash node+10',primaryMap='interface+A8',secondaryMap='interface+C8',cSha256=hashlib.sha256(lookup.read_bytes()).hexdigest()),
enumSources=dict(codeTablesSha256=hashlib.sha256(Path('artifacts/galaxy-query-research/palette-resources/code-tables.json').read_bytes()).hexdigest(),
mapAsSha256=hashlib.sha256(as_path.read_bytes()).hexdigest(),aliases={'Agri':'Agriculture','Terrorism':'TerroristAttack'},
governmentCount=len(array('Governments')),economyCount=len(array('Economies')),baseStateCount=len(array('FactionStates'))),
limits=['Existing metadata rows or an explicitly defaulted original classifier value after both readiness gates and repeated stable missing lookups. Pending/malformed/moved remains unknown; completeness is false.',
'Allegiance is an actual uint64 definition identifier; names only come from independently verified actual definitions or the original Max sentinel None.',
'Security class keys are independently closed by original3AD0BF0; only0/2/3/4 are emitted by this base classifier.',
'Base faction state is not the separate pseudo-unpopulated/Thargoid overlay predicate.'])
path=Path('artifacts/galaxy-query-research/account-sources/basic-system-facts-evidence.json')
path.write_text(json.dumps(result,indent=2)+'\n',encoding='utf8')
print(json.dumps(dict(report=str(path),fields=len(fields),functions=len(functions),enumCounts=result['enumSources']),indent=2))
"""Verify the actual original metadata consumers and the shipped enum names."""
import hashlib
import importlib.util
import json
import re
from pathlib import Path
spec=importlib.util.spec_from_file_location('audit',Path(__file__).with_name('Audit-GalaxyClientCompatibility.py'))
audit=importlib.util.module_from_spec(spec);spec.loader.exec_module(audit)
old=audit.Image(Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe'))
new=audit.Image(Path('D:/SteamLibrary/steamapps/common/Elite Dangerous/Products/elite-dangerous-odyssey-64/EliteDangerous64.exe'))
hashes=[hashlib.sha256(i.raw).hexdigest() for i in (old,new)]
if hashes!=['6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93','ed5a8f8cd10f9a80d3bda5badd7ba1d4fcfc15996c8c7e018852cb170e264b63']:
raise ValueError('Basic metadata consumer image changed')
definitions=[('population',0x3B27FA0,0x30),('governmentId',0x3B26180,0x18),('primaryEconomyId',0x3B25D40,0x20),
('secondaryEconomyId',0x3B25D40,0x24),('factionStateId',0x3B262E0,0x1C),('allegianceId',0x3B26030,8),('securityValue',0x1C40B90,0x3A)]
functions={};fields=[]
for name,before,offset in definitions:
span=old.function(before)
if span is None or span[0]!=before:raise ValueError('Metadata consumer lost its exact function range')
length=span[1]-before
row=audit.match(old,new,before,length)
if row['status']!='unique':raise ValueError('Metadata consumer is not uniquely matched')
row['oldRva']=hex(before);functions[hex(before)]=row
reads=[dict(rva=hex(i.address-old.base),instruction=i.mnemonic+' '+i.op_str) for i in old.instructions(before,length)
if i.mnemonic.startswith('mov') and any(op.type==audit.X86_OP_MEM and op.mem.base==audit.cs.x86.X86_REG_RAX and op.mem.disp==offset for op in i.operands)]
if not reads:raise ValueError('Original descriptor read is missing: '+name)
fields.append(dict(name=name,descriptorOffset=hex(offset),consumer=hex(before),reads=reads))
code=json.loads(Path('artifacts/galaxy-query-research/palette-resources/code-tables.json').read_text(encoding='utf8'))
as_path=Path('artifacts/galaxy-marker-research/map-as/scripts/factions/consts/FactionStates.as')
states={int(value):name for name,value in re.findall(r'public static const (\w+):int = (\d+);',as_path.read_text(encoding='utf8')) if name!='Max'}
source=Path('XFEEDToolBox.Core/Galaxy/GalaxyNativeBasicSystemFacts.cs').read_text(encoding='utf8')
def array(name):
match=re.search(r'private static readonly string\[\] '+name+r'=\[(.*?)\];',source)
if not match:raise ValueError('Core original enum array missing')
return re.findall(r'"([^"]*)"',match.group(1))
for source_name,target,aliases in [('government','Governments',{}),('economy','Economies',{'Agri':'Agriculture'})]:
rows=code['enumerations'][source_name]
if [r['value'] for r in rows]!=list(range(len(rows))):raise ValueError('Original enum is no longer contiguous')
if array(target)!=[aliases.get(r['name'],r['name']) for r in rows]:raise ValueError('Core enum differs from original '+source_name)
if array('FactionStates')!=[{'Terrorism':'TerroristAttack'}.get(states[i],states[i]) for i in range(40)]:raise ValueError('Core base state differs from actual map-AS')
lookup=Path('artifacts/galaxy-query-research/account-sources/decompiled/solo-39bed80.c')
result=dict(runtimeNeutral=True,gameCalls=0,networkRequests=0,runtimeValidated=False,canInstallHooks=False,
oldImageSha256=hashes[0],newImageSha256=hashes[1],functions=list(functions.values()),fields=fields,
lookup=dict(original='39BED80',actualInterfaceOld='551A1E0',actualInterfaceNew='551A1B0',slot='28',
returnedDescriptor='hash node+10',primaryMap='interface+A8',secondaryMap='interface+C8',cSha256=hashlib.sha256(lookup.read_bytes()).hexdigest()),
enumSources=dict(codeTablesSha256=hashlib.sha256(Path('artifacts/galaxy-query-research/palette-resources/code-tables.json').read_bytes()).hexdigest(),
mapAsSha256=hashlib.sha256(as_path.read_bytes()).hexdigest(),aliases={'Agri':'Agriculture','Terrorism':'TerroristAttack'},
governmentCount=len(array('Governments')),economyCount=len(array('Economies')),baseStateCount=len(array('FactionStates'))),
limits=['Existing metadata rows or an explicitly defaulted original classifier value after both readiness gates and repeated stable missing lookups. Pending/malformed/moved remains unknown; completeness is false.',
'Allegiance is an actual uint64 definition identifier; names only come from independently verified actual definitions or the original Max sentinel None.',
'Security class keys are independently closed by original3AD0BF0; only0/2/3/4 are emitted by this base classifier.',
'Base faction state is not the separate pseudo-unpopulated/Thargoid overlay predicate.'])
path=Path('artifacts/galaxy-query-research/account-sources/basic-system-facts-evidence.json')
path.write_text(json.dumps(result,indent=2)+'\n',encoding='utf8')
print(json.dumps(dict(report=str(path),fields=len(fields),functions=len(functions),enumCounts=result['enumSources']),indent=2))