"""Offline, reproducible GalaxyMapCamera resource/consumer evidence.
No game process is opened. All RVA labels refer to the pinned 6891 image.
The FRES type record is checked against its owning entity's actual component
vector; allocator pools alone are never interpreted as runtime type IDs.
"""
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
import struct
import pefile
ROOT = Path(__file__).resolve().parents[1]
KEY = '86ec03fba621526059fc6812faca6f10adcb63cb'
DIRECTORY = ROOT / 'artifacts/galaxy-query-research/palette-resources'
OUTPUT = ROOT / 'artifacts/galaxy-query-research/constellations/original-camera-config.json'
OLD = ROOT / 'artifacts/ship-model-reference/client-copy/EliteDangerous64.exe'
def sha(data):
return hashlib.sha256(data).hexdigest()
def extract():
f = (DIRECTORY / (KEY + '.fres')).read_bytes()
b = (DIRECTORY / (KEY + '.indexed1')).read_bytes()
assert sha(f) == '20339ca4f57ea23dc8002e04d8a04bed45d64345d87e4c3f6ae4cc3fc071ca60'
assert sha(b) == '5135b3d55e5239b3d11f79a76adeda954eb78be5101b6a516fd25df257affa77'
pool_count = struct.unpack_from('<I', f, 0x34)[0]
buffer_count = struct.unpack_from('<I', f, 0x38)[0] - struct.unpack_from('<I', f, 0x40)[0]
root_count = struct.unpack_from('<I', f, 0x20)[0]
cursor = total = 0
while total < pool_count:
kind, count = struct.unpack_from('<HH', b, cursor)
assert kind in (2, 3, 4)
cursor += 4
total += count
assert total == pool_count
pools = [struct.unpack_from('<II', b, cursor + index * 32 + 8) for index in range(pool_count)]
cursor += pool_count * 32
buffers = [struct.unpack_from('<IIHHIQQ', b, cursor + index * 32) for index in range(buffer_count)]
cursor += buffer_count * 32 + sum(row[3] for row in buffers) * 8
roots = [struct.unpack_from('<IIII', b, cursor + index * 16) for index in range(root_count)]
cursor += root_count * 16
references = {}
while cursor + 16 <= len(b):
source, offset, target, target_offset = struct.unpack_from('<IIII', b, cursor)
if source >= pool_count or target >= pool_count or offset >= pools[source][0] or target_offset >= pools[target][0]:
break
assert (source, offset) not in references
references[source, offset] = target, target_offset
cursor += 16
assert b[cursor:cursor + 16] == bytes.fromhex('0000000000000000ffbf7f3f08040201')
data_start = cursor + 16
def at(pointer):
pool, offset = pointer
assert 0 <= pool < pool_count and 0 <= offset < pools[pool][0]
return data_start + pools[pool][1] + offset
type_hash = 5381
for value in b'GalaxyMapCamera'.lower():
type_hash = (type_hash * 33 + value) & 0xFFFFFFFF
assert type_hash == 0xEC6A0092
record = struct.unpack_from('<IIIII', f, 0x1E5B40)
assert record == (type_hash, 10, 1490, 423, 14672)
assert roots[1490] == (0xB9B564A9, 0x7C9C6DAE, 466, 8480)
entity = roots[1490][2:]
vector = references[entity[0], entity[1] + 0x10]
count = struct.unpack_from('<I', b, at(entity) + 0x18)[0]
assert count == 17
assert references[vector[0], vector[1] + 9 * 8] == (423, 14672)
config = (423, 14672)
fields = {f'{offset:02X}': struct.unpack_from('<f', b, at(config) + offset)[0] for offset in range(0x10, 0x68, 4)}
assert fields['30'] == 6 and fields['34'] == 25000 and fields['38'] == 17.75
assert fields['20'] == -80 and fields['24'] == 80 and fields['28'] == 45 and fields['44'] == 30
assert fields['3C'] == fields['40'] == struct.unpack('<f', struct.pack('<f', .2))[0]
assert fields['48'] == struct.unpack('<f', struct.pack('<f', .3))[0]
raw = OLD.read_bytes()
assert sha(raw) == '6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93'
pe = pefile.PE(data=raw, fast_load=True)
degree = struct.unpack('<f', pe.get_data(0x4E32730, 4))[0]
compact_scale = struct.unpack('<f', pe.get_data(0x5192F68, 4))[0]
assert degree == struct.unpack('<f', struct.pack('<f', .01745329238474369))[0]
assert compact_scale == 1 / 32
source_metadata = json.loads((DIRECTORY / (KEY + '.json')).read_text(encoding='utf-8-sig'))
assert source_metadata['sha256'] == '29a90189d0bb238c88d09dcc0f15ff751ea29aa208b1a90894ef3b47f8942e5f'
c_directory = ROOT / 'artifacts/galaxy-query-research/constellations/decompiled'
functions = {}
for rva, meaning in (
('3ba0610', 'Lowercase ASCII DJB2 type-name hash, seed5381, multiplier33'),
('3b40630', 'Copy camera configuration, convert degree fields to radians'),
('3a2b800', 'Four-channel normal per-tick smoothing; separate cinematic phase'),
('3a3b630', 'Build basis and Eye=Focus-distance*Forward from actual pose'),
('3b3e8c0', 'Initialize focus from compact raw coordinates times1/32, choose saved or fallback pose'),
('3a30140', 'Clamp target focus, pitch and distance'),
('3b507d0', 'Input updates target; settle only idle target floor height')):
path = c_directory / ('solo-' + rva + '.c')
if not path.is_file():
path = ROOT / 'artifacts/galaxy-query-research/power-outer-sources/decompiled' / path.name
assert path.is_file(), path
functions['0x' + rva.upper()] = dict(path=str(path.relative_to(ROOT)), sha256=sha(path.read_bytes()), meaning=meaning)
return dict(sourceResource=KEY, sourceSha256=source_metadata['sha256'], fresSha256=sha(f), frozenSha256=sha(b),
imageSha256=sha(raw), gameProcessAccess=False, gameCalls=0, networkRequests=0,
binding=dict(name='GalaxyMapCamera', hash=hex(type_hash), nativeHashRoutine='0x3BA0610',
nativeRegistration='0x3C12700', nativeNameRva='0x5538428', recordFileOffset='0x1E5B40',
record=list(record), rootOrdinal=1490, rootName='galaxymap', root=list(roots[1490]),
componentVector=list(vector), componentCount=count, componentIndex=9, configuration=list(config),
configurationFileOffset=at(config)),
rawFloatFields=fields,
controls=dict(focusFactor=fields['48'], pitchFactor=fields['3C'], yawFactor=fields['40'],
log2DistanceFactor=fields['3C'], perTick=True, multiplyByDeltaTime=False,
minimumDistanceLy=fields['30'], maximumDistanceLy=fields['34'],
pitchInputGain=fields['10'], yawInputGain=fields['14'], zoomInputGain=fields['18'], translationGain=fields['1C'],
minimumPitchDegrees=fields['20'], maximumPitchDegrees=fields['24'], originalDegreesToRadians=degree,
fallbackDistanceLy=fields['38'], fallbackPitchDegrees=fields['28'], fallbackYawDegrees=fields['44'],
fallbackQualifier='Used by3B3E8C0 only if respective saved setting optional flag is absent'),
coordinateUnits=dict(compactRawToLightYears=compact_scale, constantRva='0x5192F68',
consumer='0x3B3E8C0', targetFocusComponentOffset='0x150', targetFocusOrbitSubobjectOffset='0xE0',
matrixConsumer='0x3A3B630', distanceSharesFocusUnits=True),
stopThresholds=dict(availableOffline=False, runtimeGlobals=['0x5FD85A0', '0x5FD8620'],
policy='Application tolerances must be explicitly labelled; unchanged arithmetic is original fallback'),
functions=functions,
projectionEvidence='Trace-OriginalGalaxyProjection.py / original-projection-binding.json; root lens and final matrix recovered separately',
unconfirmed=['Runtime parent lens/HMD/view/capture overrides', 'Transition source for each user recenter action',
'Runtime stop epsilon values', 'Current-version live frame cadence'])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--verify', action='store_true')
args = parser.parse_args()
result = extract()
text = json.dumps(result, indent=2, ensure_ascii=False) + '\n'
if args.verify:
assert OUTPUT.read_text(encoding='utf-8') == text, 'Camera evidence differs; inspect and regenerate'
print('PASS: original camera binding, fields, units and consumer source hashes')
else:
OUTPUT.parent.mkdir(parents=True, exist_ok=True)
OUTPUT.write_text(text, encoding='utf-8')
print(OUTPUT)
"""Offline, reproducible GalaxyMapCamera resource/consumer evidence.
No game process is opened. All RVA labels refer to the pinned 6891 image.
The FRES type record is checked against its owning entity's actual component
vector; allocator pools alone are never interpreted as runtime type IDs.
"""
from __future__ import annotations
import argparse
import hashlib
import json
from pathlib import Path
import struct
import pefile
ROOT = Path(__file__).resolve().parents[1]
KEY = '86ec03fba621526059fc6812faca6f10adcb63cb'
DIRECTORY = ROOT / 'artifacts/galaxy-query-research/palette-resources'
OUTPUT = ROOT / 'artifacts/galaxy-query-research/constellations/original-camera-config.json'
OLD = ROOT / 'artifacts/ship-model-reference/client-copy/EliteDangerous64.exe'
def sha(data):
return hashlib.sha256(data).hexdigest()
def extract():
f = (DIRECTORY / (KEY + '.fres')).read_bytes()
b = (DIRECTORY / (KEY + '.indexed1')).read_bytes()
assert sha(f) == '20339ca4f57ea23dc8002e04d8a04bed45d64345d87e4c3f6ae4cc3fc071ca60'
assert sha(b) == '5135b3d55e5239b3d11f79a76adeda954eb78be5101b6a516fd25df257affa77'
pool_count = struct.unpack_from('<I', f, 0x34)[0]
buffer_count = struct.unpack_from('<I', f, 0x38)[0] - struct.unpack_from('<I', f, 0x40)[0]
root_count = struct.unpack_from('<I', f, 0x20)[0]
cursor = total = 0
while total < pool_count:
kind, count = struct.unpack_from('<HH', b, cursor)
assert kind in (2, 3, 4)
cursor += 4
total += count
assert total == pool_count
pools = [struct.unpack_from('<II', b, cursor + index * 32 + 8) for index in range(pool_count)]
cursor += pool_count * 32
buffers = [struct.unpack_from('<IIHHIQQ', b, cursor + index * 32) for index in range(buffer_count)]
cursor += buffer_count * 32 + sum(row[3] for row in buffers) * 8
roots = [struct.unpack_from('<IIII', b, cursor + index * 16) for index in range(root_count)]
cursor += root_count * 16
references = {}
while cursor + 16 <= len(b):
source, offset, target, target_offset = struct.unpack_from('<IIII', b, cursor)
if source >= pool_count or target >= pool_count or offset >= pools[source][0] or target_offset >= pools[target][0]:
break
assert (source, offset) not in references
references[source, offset] = target, target_offset
cursor += 16
assert b[cursor:cursor + 16] == bytes.fromhex('0000000000000000ffbf7f3f08040201')
data_start = cursor + 16
def at(pointer):
pool, offset = pointer
assert 0 <= pool < pool_count and 0 <= offset < pools[pool][0]
return data_start + pools[pool][1] + offset
type_hash = 5381
for value in b'GalaxyMapCamera'.lower():
type_hash = (type_hash * 33 + value) & 0xFFFFFFFF
assert type_hash == 0xEC6A0092
record = struct.unpack_from('<IIIII', f, 0x1E5B40)
assert record == (type_hash, 10, 1490, 423, 14672)
assert roots[1490] == (0xB9B564A9, 0x7C9C6DAE, 466, 8480)
entity = roots[1490][2:]
vector = references[entity[0], entity[1] + 0x10]
count = struct.unpack_from('<I', b, at(entity) + 0x18)[0]
assert count == 17
assert references[vector[0], vector[1] + 9 * 8] == (423, 14672)
config = (423, 14672)
fields = {f'{offset:02X}': struct.unpack_from('<f', b, at(config) + offset)[0] for offset in range(0x10, 0x68, 4)}
assert fields['30'] == 6 and fields['34'] == 25000 and fields['38'] == 17.75
assert fields['20'] == -80 and fields['24'] == 80 and fields['28'] == 45 and fields['44'] == 30
assert fields['3C'] == fields['40'] == struct.unpack('<f', struct.pack('<f', .2))[0]
assert fields['48'] == struct.unpack('<f', struct.pack('<f', .3))[0]
raw = OLD.read_bytes()
assert sha(raw) == '6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93'
pe = pefile.PE(data=raw, fast_load=True)
degree = struct.unpack('<f', pe.get_data(0x4E32730, 4))[0]
compact_scale = struct.unpack('<f', pe.get_data(0x5192F68, 4))[0]
assert degree == struct.unpack('<f', struct.pack('<f', .01745329238474369))[0]
assert compact_scale == 1 / 32
source_metadata = json.loads((DIRECTORY / (KEY + '.json')).read_text(encoding='utf-8-sig'))
assert source_metadata['sha256'] == '29a90189d0bb238c88d09dcc0f15ff751ea29aa208b1a90894ef3b47f8942e5f'
c_directory = ROOT / 'artifacts/galaxy-query-research/constellations/decompiled'
functions = {}
for rva, meaning in (
('3ba0610', 'Lowercase ASCII DJB2 type-name hash, seed5381, multiplier33'),
('3b40630', 'Copy camera configuration, convert degree fields to radians'),
('3a2b800', 'Four-channel normal per-tick smoothing; separate cinematic phase'),
('3a3b630', 'Build basis and Eye=Focus-distance*Forward from actual pose'),
('3b3e8c0', 'Initialize focus from compact raw coordinates times1/32, choose saved or fallback pose'),
('3a30140', 'Clamp target focus, pitch and distance'),
('3b507d0', 'Input updates target; settle only idle target floor height')):
path = c_directory / ('solo-' + rva + '.c')
if not path.is_file():
path = ROOT / 'artifacts/galaxy-query-research/power-outer-sources/decompiled' / path.name
assert path.is_file(), path
functions['0x' + rva.upper()] = dict(path=str(path.relative_to(ROOT)), sha256=sha(path.read_bytes()), meaning=meaning)
return dict(sourceResource=KEY, sourceSha256=source_metadata['sha256'], fresSha256=sha(f), frozenSha256=sha(b),
imageSha256=sha(raw), gameProcessAccess=False, gameCalls=0, networkRequests=0,
binding=dict(name='GalaxyMapCamera', hash=hex(type_hash), nativeHashRoutine='0x3BA0610',
nativeRegistration='0x3C12700', nativeNameRva='0x5538428', recordFileOffset='0x1E5B40',
record=list(record), rootOrdinal=1490, rootName='galaxymap', root=list(roots[1490]),
componentVector=list(vector), componentCount=count, componentIndex=9, configuration=list(config),
configurationFileOffset=at(config)),
rawFloatFields=fields,
controls=dict(focusFactor=fields['48'], pitchFactor=fields['3C'], yawFactor=fields['40'],
log2DistanceFactor=fields['3C'], perTick=True, multiplyByDeltaTime=False,
minimumDistanceLy=fields['30'], maximumDistanceLy=fields['34'],
pitchInputGain=fields['10'], yawInputGain=fields['14'], zoomInputGain=fields['18'], translationGain=fields['1C'],
minimumPitchDegrees=fields['20'], maximumPitchDegrees=fields['24'], originalDegreesToRadians=degree,
fallbackDistanceLy=fields['38'], fallbackPitchDegrees=fields['28'], fallbackYawDegrees=fields['44'],
fallbackQualifier='Used by3B3E8C0 only if respective saved setting optional flag is absent'),
coordinateUnits=dict(compactRawToLightYears=compact_scale, constantRva='0x5192F68',
consumer='0x3B3E8C0', targetFocusComponentOffset='0x150', targetFocusOrbitSubobjectOffset='0xE0',
matrixConsumer='0x3A3B630', distanceSharesFocusUnits=True),
stopThresholds=dict(availableOffline=False, runtimeGlobals=['0x5FD85A0', '0x5FD8620'],
policy='Application tolerances must be explicitly labelled; unchanged arithmetic is original fallback'),
functions=functions,
projectionEvidence='Trace-OriginalGalaxyProjection.py / original-projection-binding.json; root lens and final matrix recovered separately',
unconfirmed=['Runtime parent lens/HMD/view/capture overrides', 'Transition source for each user recenter action',
'Runtime stop epsilon values', 'Current-version live frame cadence'])
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--verify', action='store_true')
args = parser.parse_args()
result = extract()
text = json.dumps(result, indent=2, ensure_ascii=False) + '\n'
if args.verify:
assert OUTPUT.read_text(encoding='utf-8') == text, 'Camera evidence differs; inspect and regenerate'
print('PASS: original camera binding, fields, units and consumer source hashes')
else:
OUTPUT.parent.mkdir(parents=True, exist_ok=True)
OUTPUT.write_text(text, encoding='utf-8')
print(OUTPUT)