Created
October 10, 2013 04:12
-
-
Save ChadSki/6912939 to your computer and use it in GitHub Desktop.
load_map_common proposal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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