"""Disassemble only original RouteInstances effects from already-pinned offline archives."""
import ctypes
import hashlib
import json
import re
import struct
from pathlib import Path
source=Path('artifacts/galaxy-query-research/power-outer-sources/effects')
output=Path('artifacts/galaxy-query-research/current-trade/effects');output.mkdir(parents=True,exist_ok=True)
manifest=json.loads((source/'original-effects.json').read_text())
compiler=ctypes.WinDLL('d3dcompiler_47.dll')
disassemble=compiler.D3DDisassemble
disassemble.argtypes=[ctypes.c_void_p,ctypes.c_size_t,ctypes.c_uint,ctypes.c_char_p,ctypes.POINTER(ctypes.c_void_p)]
disassemble.restype=ctypes.c_int32
archives=[]
for archived in manifest['archives']:
data=(source/(archived['name']+'.raw')).read_bytes()
if hashlib.sha256(data).hexdigest()!=archived['inflatedSha256']:
raise ValueError('Pinned original raw effects archive changed')
selected=[]
for match in re.finditer(b'DXBC',data):
offset=match.start();size,chunks=struct.unpack_from('<II',data,offset+24)
if not 32<=size<=1048576 or not 1<=chunks<=16 or offset+size>len(data):continue
name=re.search(rb'(?:vs|ps|gs|cs)_(?:RouteInstances|RouteHotspotInstances)_[A-Za-z0-9_]+_Win64_SM50\0',data[offset+size:offset+size+256])
if name is None:continue
name=name.group()[:-1].decode('ascii');blob=data[offset:offset+size]
destination=output/(name+'.dxbc')
if destination.exists() and destination.read_bytes()!=blob:raise ValueError('Duplicate original shader name has different bytes')
destination.write_bytes(blob)
buffer=ctypes.create_string_buffer(blob);result=ctypes.c_void_p()
if disassemble(buffer,len(blob),0,None,ctypes.byref(result))<0:raise ValueError('Original DXBC disassembly failed')
table=ctypes.cast(result,ctypes.POINTER(ctypes.POINTER(ctypes.c_void_p)))[0]
try:
pointer=ctypes.WINFUNCTYPE(ctypes.c_void_p,ctypes.c_void_p)(table[3])(result)
length=ctypes.WINFUNCTYPE(ctypes.c_size_t,ctypes.c_void_p)(table[4])(result)
text=ctypes.string_at(pointer,length).decode().rstrip('\0')
finally:ctypes.WINFUNCTYPE(ctypes.c_uint,ctypes.c_void_p)(table[2])(result)
(output/(name+'.txt')).write_text(text,encoding='utf-8')
selected.append(dict(name=name,offset=offset,bytes=size,sha256=hashlib.sha256(blob).hexdigest()))
archives.append(dict(name=archived['name'],inflatedSha256=archived['inflatedSha256'],selected=selected))
if not any(a['selected'] for a in archives):raise ValueError('No original trade effects found')
(output/'original-trade-effects.json').write_text(json.dumps(dict(gameProcessAccess=False,gameCalls=0,shaderExecution=False,archives=archives),indent=2)+'\n',encoding='utf-8')
print(json.dumps({a['name']:[s['name'] for s in a['selected']] for a in archives},indent=2))
"""Disassemble only original RouteInstances effects from already-pinned offline archives."""
import ctypes
import hashlib
import json
import re
import struct
from pathlib import Path
source=Path('artifacts/galaxy-query-research/power-outer-sources/effects')
output=Path('artifacts/galaxy-query-research/current-trade/effects');output.mkdir(parents=True,exist_ok=True)
manifest=json.loads((source/'original-effects.json').read_text())
compiler=ctypes.WinDLL('d3dcompiler_47.dll')
disassemble=compiler.D3DDisassemble
disassemble.argtypes=[ctypes.c_void_p,ctypes.c_size_t,ctypes.c_uint,ctypes.c_char_p,ctypes.POINTER(ctypes.c_void_p)]
disassemble.restype=ctypes.c_int32
archives=[]
for archived in manifest['archives']:
data=(source/(archived['name']+'.raw')).read_bytes()
if hashlib.sha256(data).hexdigest()!=archived['inflatedSha256']:
raise ValueError('Pinned original raw effects archive changed')
selected=[]
for match in re.finditer(b'DXBC',data):
offset=match.start();size,chunks=struct.unpack_from('<II',data,offset+24)
if not 32<=size<=1048576 or not 1<=chunks<=16 or offset+size>len(data):continue
name=re.search(rb'(?:vs|ps|gs|cs)_(?:RouteInstances|RouteHotspotInstances)_[A-Za-z0-9_]+_Win64_SM50\0',data[offset+size:offset+size+256])
if name is None:continue
name=name.group()[:-1].decode('ascii');blob=data[offset:offset+size]
destination=output/(name+'.dxbc')
if destination.exists() and destination.read_bytes()!=blob:raise ValueError('Duplicate original shader name has different bytes')
destination.write_bytes(blob)
buffer=ctypes.create_string_buffer(blob);result=ctypes.c_void_p()
if disassemble(buffer,len(blob),0,None,ctypes.byref(result))<0:raise ValueError('Original DXBC disassembly failed')
table=ctypes.cast(result,ctypes.POINTER(ctypes.POINTER(ctypes.c_void_p)))[0]
try:
pointer=ctypes.WINFUNCTYPE(ctypes.c_void_p,ctypes.c_void_p)(table[3])(result)
length=ctypes.WINFUNCTYPE(ctypes.c_size_t,ctypes.c_void_p)(table[4])(result)
text=ctypes.string_at(pointer,length).decode().rstrip('\0')
finally:ctypes.WINFUNCTYPE(ctypes.c_uint,ctypes.c_void_p)(table[2])(result)
(output/(name+'.txt')).write_text(text,encoding='utf-8')
selected.append(dict(name=name,offset=offset,bytes=size,sha256=hashlib.sha256(blob).hexdigest()))
archives.append(dict(name=archived['name'],inflatedSha256=archived['inflatedSha256'],selected=selected))
if not any(a['selected'] for a in archives):raise ValueError('No original trade effects found')
(output/'original-trade-effects.json').write_text(json.dumps(dict(gameProcessAccess=False,gameCalls=0,shaderExecution=False,archives=archives),indent=2)+'\n',encoding='utf-8')
print(json.dumps({a['name']:[s['name'] for s in a['selected']] for a in archives},indent=2))