Skip to content

Instantly share code, notes, and snippets.

@ChadSki
Created October 10, 2013 04:12
Show Gist options
  • Save ChadSki/6912939 to your computer and use it in GitHub Desktop.
Save ChadSki/6912939 to your computer and use it in GitHub Desktop.
load_map_common proposal
def load_map_common(access_type, map_path=None):
# access_type is either 'file' or 'mem'
halomap = {
'file': lambda: HaloMap(open(map_path, 'r+b')),
'mem': lambda: HaloMap(None)
}[access_type]()
# class for reading/writing bytes to a delineated area
ByteAccess = {
'file': lambda: access_over_file(halomap.file),
'mem': lambda: access_over_process('halo.exe')
}[access_type]()
# ensure plugins are loaded
if len(plugin_classes) == 0:
load_plugins()
MapHeader = plugin_classes['map_header']
IndexHeader = plugin_classes['index_header']
IndexEntry = plugin_classes['index_entry']
map_header = MapHeader(
ByteAccess(
{'file': 0, 'mem': 0x6A8154}[access_type],
MapHeader.struct_size),
0,
halomap)
index_header = IndexHeader(
ByteAccess(
{'file': map_header.index_offset, 'mem': 0x40440000}[access_type],
IndexHeader.struct_size),
0,
halomap)
# Usually the tag index directly follows the index header. However,
# some forms of map protection move the tag index to other locations.
index_location = {
'file': map_header.index_offset + index_header.primary_magic - 0x40440000,
'mem': index_header.primary_magic
}[access_type]
# In memory everything is just pointers. On disk, we need to use a magic value
# to convert these pointers to file offsets. The magic value is based on the index location.
map_magic = {
'file': index_header.primary_magic - index_location,
'mem': 0
}[access_type]
index_entries = [IndexEntry(
ByteAccess(
IndexEntry.struct_size * i + index_location,
IndexEntry.struct_size),
map_magic,
halomap) for i in range(index_header.tag_count)]
meta_offsets = [ie.meta_offset_raw for ie in index_entries]
meta_offsets.sort()
meta_offsets.append(meta_offsets[0] + map_header.metadata_size) # to calculate sizes, we need the offset to the end
# [00, 10, 40, 55, 80] from offsets,
# [10, 30, 15, 25] calculate sizes...
# but instead of an ordered list, key based on the start offset
meta_sizes = {start: (end - start) for start, end in zip(meta_offsets[:-1], meta_offsets[1:])}
tags = [HaloTag(
index_entry,
ByteAccess( # name
index_entry.name_offset_raw - map_magic,
256),
ByteAccess( # metadata
index_entry.meta_offset_raw - map_magic,
meta_sizes[index_entry.meta_offset_raw]),
map_magic,
halomap) for index_entry in index_entries]
halomap.init(map_header, index_header, tags, map_magic)
return halomap
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment