Пример #1
0
    def _try_load_ai_data(self):
        self._loaded = True
        open_files_service = locator.get_scoped("OpenFilesService")
        try:
            bin_archive = open_files_service.open(_AI_DATA_PATH)
            reader = BinArchiveReader(bin_archive)
            ac_ptr = reader.read_internal_pointer()
            mi_ptr = reader.read_internal_pointer()
            at_ptr = reader.read_internal_pointer()
            mv_ptr = reader.read_internal_pointer()
            ac_table = self._read_null_terminated_list(reader, ac_ptr)
            mi_table = self._read_null_terminated_list(reader, mi_ptr)
            at_table = self._read_null_terminated_list(reader, at_ptr)
            mv_table = self._read_null_terminated_list(reader, mv_ptr)

            ac_labels = self._read_mapped_pointers(reader, ac_table)
            mi_labels = self._read_mapped_pointers(reader, mi_table)
            at_labels = self._read_mapped_pointers(reader, at_table)
            mv_labels = self._read_mapped_pointers(reader, mv_table)

            self.ac = ac_labels
            self.mi = mi_labels
            self.at = at_labels
            self.mv = mv_labels
        except:
            logging.exception("Unable to load AI data.")
Пример #2
0
 def _read_supports_from_table(cls, reader: BinArchiveReader):
     reader.seek(reader.tell() + 2)  # Don't care about the owner here.
     count = reader.read_u16()
     supports = []
     for _ in range(0, count):
         support = cls._read_support(reader)
         supports.append(support)
     return supports
Пример #3
0
 def _read_mapped_pointers(reader: BinArchiveReader,
                           addresses: List[int]) -> List[str]:
     result = []
     for address in addresses:
         reader.seek(address)
         label = reader.read_mapped()
         if label:
             result.append(label)
     return result
Пример #4
0
 def _read_null_terminated_list(reader: BinArchiveReader,
                                address: int) -> List[int]:
     result = []
     reader.seek(address)
     next_pointer = reader.read_internal_pointer()
     while next_pointer:
         result.append(next_pointer)
         next_pointer = reader.read_internal_pointer()
     return result
Пример #5
0
 def read_count(self, archive) -> int:
     base_address = self.location_strategy.read_base_address(archive)
     reader = BinArchiveReader(archive, base_address)
     next_bytes = reader.read_bytes(self.entry_size)
     count = 0
     while any(next_bytes):
         count += 1
         next_bytes = reader.read_bytes(self.entry_size)
     return count
Пример #6
0
 def read_count(self, archive) -> int:
     count_address = self.location_strategy.read_base_address(archive)
     reader = BinArchiveReader(archive, count_address)
     if self.width == 1:
         return reader.read_u8()
     elif self.width == 2:
         return reader.read_u16()
     else:
         return reader.read_u32()
Пример #7
0
 def get_property_address(self):
     if issubclass(type(self.parent.owner), Module):
         property_address = self.parent.owner.find_base_address_for_element(
             self.parent) + self.offset
         return property_address, self.parent.owner.archive
     else:
         parent_property_address, archive = self.parent.owner.get_property_address(
         )
         reader = BinArchiveReader(archive, parent_property_address)
         return (reader.read_internal_pointer() + self.offset), archive
Пример #8
0
 def write(self, writer):
     if self.value is None:
         writer.write_pointer(None)
     else:
         reader = BinArchiveReader(writer.get_archive(), writer.tell())
         target_address = reader.read_internal_pointer()
         end_address = writer.tell() + 4
         writer.seek(target_address)
         for prop in self.value.values():
             prop.write(writer)
         writer.seek(end_address)
Пример #9
0
    def _load(self):
        open_files_service = locator.get_scoped("OpenFilesService")
        self.archive = open_files_service.open("sound/IndirectSound.bin.lz")

        address = self._location_strategy.read_base_address(self.archive)
        count = self._count_strategy.read_count(self.archive)
        reader = BinArchiveReader(self.archive, address)
        for i in range(0, count):
            self.voice_set_labels.append(reader.read_mapped())

            # Skip to the next set.
            reader.seek(reader.tell() + 8)
            set_count = reader.read_u32()
            reader.seek(reader.tell() + set_count * 8 + 4)
Пример #10
0
 def check_support_id_validity(self):
     module_service = locator.get_scoped("ModuleService")
     characters = module_service.get_module("Characters").entries
     reader = BinArchiveReader(self.archive,
                               self._get_master_support_table_address())
     table_count = reader.read_u32()
     encountered_ids = set()
     for character in characters:
         support_id = character["Support ID"].value
         if support_id == 0xFFFF:
             continue
         if support_id in encountered_ids:
             raise SupportIDInUseException(support_id)
         elif support_id >= table_count:
             raise OutOfBoundsSupportIDException(support_id)
         encountered_ids.add(support_id)
Пример #11
0
 def read(self, reader: BinArchiveReader):
     self.name = reader.read_string()
     spawn_address = reader.read_internal_pointer()
     spawn_count = reader.read_u32()
     end_address = reader.tell()
     self.spawns = []
     reader.seek(spawn_address)
     for _ in range(0, spawn_count):
         self.spawns.append(self._read_spawn(reader))
     reader.seek(end_address)
Пример #12
0
    def _add_support_to_table(self, character1, character2, support_type):
        # Jump to the target support table.
        master_support_table_address = self._get_master_support_table_address()
        reader = BinArchiveReader(self.archive, master_support_table_address)
        target_support_id = character1["Support ID"].value
        reader.seek(reader.tell() + target_support_id * 4 + 4)
        reader.seek(reader.read_internal_pointer() + 2)  # Skip the owner id.

        # Update the support count.
        writer = BinArchiveWriter(self.archive, reader.tell())
        old_count = reader.read_u16()
        writer.write_u16(old_count + 1)

        # Create the new support.
        new_support_address = writer.tell() + old_count * 0xC
        self.archive.allocate(new_support_address, 0xC, False)
        writer.seek(new_support_address)
        writer.write_u16(character2["ID"].value)
        writer.write_u16(old_count)
        writer.write_u32(support_type)
        writer.write_u32(0x1)  # Support tag. Still figuring this part out.
Пример #13
0
 def read(self, archive):
     self.factions.clear()
     reader = BinArchiveReader(archive)
     next_bytes = reader.read_bytes(12)
     while any(next_bytes):
         reader.seek(reader.tell() - 12)
         faction = Faction()
         faction.read(reader)
         self.factions.append(faction)
         next_bytes = reader.read_bytes(12)
Пример #14
0
    def _create_support_table(self, character):
        # First, increment master support table count.
        master_support_table_address = self._get_master_support_table_address()
        writer = BinArchiveWriter(self.archive, master_support_table_address)
        reader = BinArchiveReader(self.archive, master_support_table_address)
        old_count = reader.read_u32()
        writer.write_u32(old_count + 1)

        # Next, create a pointer to the new table.
        pointer_address = master_support_table_address + old_count * 4 + 4
        self.archive.allocate(pointer_address, 4, False)
        destination = self.archive.size()
        self.archive.set_internal_pointer(pointer_address, destination)

        # Generate and assign a support ID for the character
        support_id = self._find_next_support_id()
        character["Support ID"].value = support_id

        # Allocate and format the new table.
        writer.seek(destination)
        self.archive.allocate_at_end(4)
        writer.write_u16(support_id)
Пример #15
0
    def read(self, archive):
        reader = BinArchiveReader(archive)
        tile_table_address = reader.read_internal_pointer()
        tile_count = reader.read_u32()
        self.map_model.read(reader)
        grid_address = reader.read_internal_pointer()

        self.tiles.clear()
        reader.seek(tile_table_address)
        for _ in range(0, tile_count):
            tile = self._read_tile(reader)
            self.tiles.append(tile)

        reader.seek(grid_address)
        self.map_size_x.read(reader)
        self.map_size_y.read(reader)
        self.border_size_x.read(reader)
        self.border_size_y.read(reader)
        self.trimmed_size_x.read(reader)
        self.trimmed_size_y.read(reader)
        for r in range(0, 32):
            for c in range(0, 32):
                self.grid[r][c] = reader.read_u8()
Пример #16
0
    def _read_support(reader: BinArchiveReader):
        module_service = locator.get_scoped("ModuleService")
        characters = module_service.get_module("Characters").entries

        character = characters[reader.read_u16()]
        reader.seek(reader.tell() + 2)  # The ID is not needed when editing.
        raw_type = reader.read_u32()
        tag = reader.read_bytes(4)
        return Support(character, raw_type, tag)
Пример #17
0
 def attach_to(self, archive):
     self.entries.clear()
     location = self.location_strategy.read_base_address(archive)
     count = self.count_strategy.read_count(archive)
     reader = BinArchiveReader(archive)
     for i in range(0, count):
         reader.seek(location + i * self.entry_size)
         base = reader.tell()
         elem = self.element_template.duplicate(new_owner=self)
         self.entries.append(elem)
         for (name, prop) in elem.items():
             self.element_template[name].offset = reader.tell() - base
             prop.offset = reader.tell() - base
             prop.read(reader)
     self.archive = archive
     self._resolve_references(archive)
Пример #18
0
    def _get_reader_at_voice_set_table(self, voice_set_label: str) -> (BinArchiveReader, int):
        # Seek to the voice set's address.
        address = self.archive.addr_of_mapped_pointer(voice_set_label)
        if not address:
            raise Exception

        # Read the count and perform sanity checks.
        reader = BinArchiveReader(self.archive, address)
        if reader.read_u32() != 0xFFFF0002 or reader.read_string() != voice_set_label:
            raise Exception
        set_count = reader.read_u32()
        if reader.read_u32() != set_count:
            raise Exception
        return reader, set_count
Пример #19
0
 def _get_master_support_table_address(self):
     reader = BinArchiveReader(self.archive, 8)
     reader.seek(reader.read_internal_pointer() + 8)
     return reader.read_internal_pointer()
Пример #20
0
 def read_base_address(self, archive) -> int:
     reader = BinArchiveReader(archive, self.address)
     return reader.read_internal_pointer() + self.offset
Пример #21
0
 def _open_reader_at_table(self, table_number):
     addr = self._get_master_support_table_address() + table_number * 4 + 4
     reader = BinArchiveReader(self.archive, addr)
     reader.seek(reader.read_internal_pointer())
     return reader
Пример #22
0
 def read_base_address(self, archive) -> int:
     reader = BinArchiveReader(archive)
     num_fields = reader.read_u32()
     return num_fields * 0x14 + self.offset + 4
Пример #23
0
 def read_base_address(self, archive) -> int:
     reader = BinArchiveReader(archive)
     num_fields = reader.read_u32()
     reader.seek(num_fields * 0x14 + self.offset_to_pointer + 4)
     return reader.read_internal_pointer() + self.offset_to_pointer
Пример #24
0
 def read_base_address(self, archive) -> int:
     ptr = self.offsets[0]
     for off in self.offsets[1:]:
         reader = BinArchiveReader(archive, ptr)
         ptr = reader.read_internal_pointer() + off
     return ptr
Пример #25
0
 def attach_to(self, archive):
     location = self.location_strategy.read_base_address(archive)
     reader = BinArchiveReader(archive, location)
     for prop in self.element.values():
         prop.read(reader)
     self.archive = archive