"""Apply the fully resolved offline compatibility report to the C# implementation only."""
import hashlib,json,re
from pathlib import Path
root=Path('work/trade-live-20261023')
report=json.loads((root/'updated-build-rva-map.json').read_text())
assert not report['unresolved'] and not report['conflicts']
assert report['targets']==report['mappedTargets']
game=Path('D:/SteamLibrary/steamapps/common/Elite Dangerous/Products/elite-dangerous-odyssey-64/EliteDangerous64.exe')
assert hashlib.sha256(game.read_bytes()).hexdigest()==report['newSha256']
mapping={int(x['old'],16):int(x['new'],16) for x in report['mapping']}
paths=list(Path('native/ManagedPlugin').glob('*.cs'))+list(Path('XFEEDToolBox.Core/Native').glob('*.cs'))
paths += [Path('XFEEDToolBox.Core/Session/NativeRelogChannel.cs')]
changes=[]
for path in paths:
before=path.read_bytes();text=before.decode('utf-8')
if path.parent.name in ('ManagedPlugin','Native'):
text=re.sub(r'0x[0-9a-fA-F]+',lambda m: ('0x'+format(mapping[int(m[0],16)],'X')) if int(m[0],16) in mapping else m[0],text)
text=text.replace(report['oldSha256'],report['newSha256'])
if path.name=='Platform.cs':text=text.replace('PluginVersion = "0.5.2-dev"','PluginVersion = "0.5.3-dev"')
after=text.encode('utf-8')
if after==before:continue
backup=root/'before-053-source'/path;backup.parent.mkdir(parents=True,exist_ok=True)
if backup.exists():raise RuntimeError('Refusing to overwrite a source backup')
backup.write_bytes(before);path.write_bytes(after)
changes.append({'path':str(path),'before':hashlib.sha256(before).hexdigest(),'after':hashlib.sha256(after).hexdigest()})
# All display model payload hashes and the complete resource public key were independently checked.
resources=json.loads((root/'updated-resource-evidence.json').read_text())
assert len(resources['resources'])==86 and all(x['matches'] for x in resources['resources'])
path=Path('XFEEDToolBox.Core/Rendering/local-model-reference.json')
text=path.read_bytes().decode('utf-8');model=json.loads(text)
assert resources['keyLocations']==[model['publicKeyRva']]
before=path.read_bytes();after=text.replace(report['oldSha256'],report['newSha256']).encode('utf-8')
backup=root/'before-053-source'/path;backup.parent.mkdir(parents=True,exist_ok=True)
if backup.exists():raise RuntimeError('Refusing to overwrite model backup')
backup.write_bytes(before);path.write_bytes(after)
changes.append({'path':str(path),'before':hashlib.sha256(before).hexdigest(),'after':hashlib.sha256(after).hexdigest()})
(root/'updated-build-applied.json').write_text(json.dumps({'version':'0.5.3-dev','newGameSha256':report['newSha256'],'changes':changes,'legacyCppModified':False},indent=2))
print('Updated',len(changes),'C# implementation / resource-index files; legacy C++ untouched.')
"""Apply the fully resolved offline compatibility report to the C# implementation only."""
import hashlib,json,re
from pathlib import Path
root=Path('work/trade-live-20261023')
report=json.loads((root/'updated-build-rva-map.json').read_text())
assert not report['unresolved'] and not report['conflicts']
assert report['targets']==report['mappedTargets']
game=Path('D:/SteamLibrary/steamapps/common/Elite Dangerous/Products/elite-dangerous-odyssey-64/EliteDangerous64.exe')
assert hashlib.sha256(game.read_bytes()).hexdigest()==report['newSha256']
mapping={int(x['old'],16):int(x['new'],16) for x in report['mapping']}
paths=list(Path('native/ManagedPlugin').glob('*.cs'))+list(Path('XFEEDToolBox.Core/Native').glob('*.cs'))
paths += [Path('XFEEDToolBox.Core/Session/NativeRelogChannel.cs')]
changes=[]
for path in paths:
before=path.read_bytes();text=before.decode('utf-8')
if path.parent.name in ('ManagedPlugin','Native'):
text=re.sub(r'0x[0-9a-fA-F]+',lambda m: ('0x'+format(mapping[int(m[0],16)],'X')) if int(m[0],16) in mapping else m[0],text)
text=text.replace(report['oldSha256'],report['newSha256'])
if path.name=='Platform.cs':text=text.replace('PluginVersion = "0.5.2-dev"','PluginVersion = "0.5.3-dev"')
after=text.encode('utf-8')
if after==before:continue
backup=root/'before-053-source'/path;backup.parent.mkdir(parents=True,exist_ok=True)
if backup.exists():raise RuntimeError('Refusing to overwrite a source backup')
backup.write_bytes(before);path.write_bytes(after)
changes.append({'path':str(path),'before':hashlib.sha256(before).hexdigest(),'after':hashlib.sha256(after).hexdigest()})
# All display model payload hashes and the complete resource public key were independently checked.
resources=json.loads((root/'updated-resource-evidence.json').read_text())
assert len(resources['resources'])==86 and all(x['matches'] for x in resources['resources'])
path=Path('XFEEDToolBox.Core/Rendering/local-model-reference.json')
text=path.read_bytes().decode('utf-8');model=json.loads(text)
assert resources['keyLocations']==[model['publicKeyRva']]
before=path.read_bytes();after=text.replace(report['oldSha256'],report['newSha256']).encode('utf-8')
backup=root/'before-053-source'/path;backup.parent.mkdir(parents=True,exist_ok=True)
if backup.exists():raise RuntimeError('Refusing to overwrite model backup')
backup.write_bytes(before);path.write_bytes(after)
changes.append({'path':str(path),'before':hashlib.sha256(before).hexdigest(),'after':hashlib.sha256(after).hexdigest()})
(root/'updated-build-applied.json').write_text(json.dumps({'version':'0.5.3-dev','newGameSha256':report['newSha256'],'changes':changes,'legacyCppModified':False},indent=2))
print('Updated',len(changes),'C# implementation / resource-index files; legacy C++ untouched.')