Beispiel #1
0
def test_read_write_one_player():
    """
    Read/rewrite info for an individual player
    """
    original_data = b'\t\x00Player 1\x00\x00\x00\xaaB\x00\x00lBH\x00H\x00\x00\t\x00\x01\x01\x03\x03\x03\x03\x03\x03\x03\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    reader = ScnDataReader(original_data)
    structure = UnknownPlayerDataStructure.read(reader)
    # try to write it back
    writer = ScnDataWriter()
    structure.write(writer)
    new_data = writer.done()
    assert original_data == new_data
Beispiel #2
0
def test_default():
    """
    Write then read back the default version of this data
    """
    writer = ScnDataWriter()
    scn_unknown_data_structure.default().write(writer)
    default_structure_binary = writer.done()
    assert len(default_structure_binary) == 708
    # try to read it back
    reader = ScnDataReader(default_structure_binary)
    structure = UnknownDataStructure.read(reader)
    assert structure.player_count == 9
    assert structure.unknown_player_data_structure[7].field1 == 'Player 8'
Beispiel #3
0
def test_read_write():
    """
    Read/write entire 508 byte data structure found at the end of a blank scenario file.
    """
    original_data = b'\t\x00\x00\x00\t\x00Player 1\x00\x00\x00\xaaB\x00\x00lBH\x00H\x00\x00\t\x00\x01\x01\x03\x03\x03\x03\x03\x03\x03\x00\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00Player 2\x00\x00\x00\x90B\x00\x00\x90BH\x00H\x00\x00\t\x00\x01\x03\x01\x03\x03\x03\x03\x03\x03\x00\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00Player 3\x00\x00\x00\x90B\x00\x00\x90BH\x00H\x00\x00\t\x00\x01\x03\x03\x01\x03\x03\x03\x03\x03\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00Player 4\x00\x00\x00\x90B\x00\x00\x90BH\x00H\x00\x00\t\x00\x01\x03\x03\x03\x01\x03\x03\x03\x03\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00Player 5\x00\x00\x00\x90B\x00\x00\x90BH\x00H\x00\x00\t\x00\x01\x03\x03\x03\x03\x01\x03\x03\x03\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00Player 6\x00\x00\x00\x90B\x00\x00\x90BH\x00H\x00\x00\t\x00\x01\x03\x03\x03\x03\x03\x01\x03\x03\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00Player 7\x00\x00\x00\x90B\x00\x00\x90BH\x00H\x00\x00\t\x00\x01\x03\x03\x03\x03\x03\x03\x01\x03\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x04\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\t\x00Player 8\x00\x00\x00\x90B\x00\x00\x90BH\x00H\x00\x00\t\x00\x01\x03\x03\x03\x03\x03\x03\x03\x01\x00\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00\x00\x80?\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    # try to read it
    reader = ScnDataReader(original_data)
    structure = UnknownDataStructure.read(reader)
    assert structure.player_count == 9
    assert structure.unknown_player_data_structure[7].field1 == 'Player 8'
    # try to write it back
    writer = ScnDataWriter()
    structure.write(writer)
    # check it was the same
    new_data = writer.done()
    assert original_data == new_data
Beispiel #4
0
 def write(self, data: ScnDataWriter):
     self.header.write(data)
     data.uint32(self.next_object_id)
     if self.header.header_version >= 3:
         # Assume DE scenario
         raise Exception("Not implemented")
     else:
         self.tribe_scen.write_classic(data)
         self.map_scen.write(data)
         num_players = len(self.world_players) + 1
         data.uint32(num_players)
         player_version = 1.12  # TODO map from header version.
         for player in self.world_players:
             player.write_classic(data, player_version)
         for player_objects in self.objects:
             data.uint32(len(player_objects))
             for player_object in player_objects:
                 player_object.write_classic(data, self.header.file_version)
         scn_unknown_data_structure.default().write(data)
Beispiel #5
0
 def write_classic(self, data: ScnDataWriter, player_version: float):
     if player_version > 1.06:
         data.float32(self.food)
         data.float32(self.wood)
         data.float32(self.gold)
         data.float32(self.stone)
     if player_version > 1.12:
         data.float32(self.ore)
         data.float32(self.goods)
         data.float32(self.population)
Beispiel #6
0
 def write(self, data: ScnDataWriter):
     data.string_fixed("{:.2f}".format(self.file_version), size=4)
     if self.header_version >= 3 and self.player_count > 0:
         header_size = 12 + len(self.description) + 1
     else:
         header_size = 20 + len(self.description) + 1
     data.uint32(header_size)
     data.uint32(self.header_version)
     if self.header_version >= 3:
         data.uint32(self.timestamp)
         data.uint16(2656)  # string marker
         data.string16(self.description)
         if self.player_count > 0:
             # Last 8 bytes not always seen for DE scenarios
             data.boolean32(self.has_singleplayer_victory_condition)
             data.uint32(self.player_count)
     else:
         data.uint32(self.timestamp)
         data.string32(self.description)
         data.boolean32(self.has_singleplayer_victory_condition)
         data.uint32(self.player_count)
     data.compress()
Beispiel #7
0
 def write(self, data: ScnDataWriter):
     data.uint32(self.width)
     data.uint32(self.height)
     for tile in self.tiles:
         tile.write(data)
Beispiel #8
0
 def write(self, data: ScnDataWriter):
     data.uint8(self.terrain)
     data.uint8(self.elevation)
     data.uint8(self.zone)
Beispiel #9
0
def save(scenario: ScenarioFile, file_name: str):
    data = ScnDataWriter()
    scenario.write(data)
    result_bytes = data.done()
    with open(file_name, 'wb') as f:
        f.write(result_bytes)
 def write(self, data: ScnDataWriter):
     data.string16(self.field1)
     data.float32(self.field2)
     data.float32(self.field3)
     data.uint16(self.field4)
     data.uint16(self.field5)
     data.uint8(self.field6)
     data.uint16(self.field7)
     for j in range(0, 9):
         data.uint8(self.field8[j])
     for j in range(0, 9):
         data.uint32(self.field9[j])
     data.float32(self.field10)  # 1.00
     data.float32(self.field11)
     for j in range(0, 9):
         data.uint8(self.field12[j])
    def write_classic(self, data: ScnDataWriter):
        # TODO actually use stored values for this stuff
        data.float32(self.rge_version)
        if self.rge_version > 1.13:
            for i in range(0, 16):
                # player names
                data.string_fixed('', size=256)

        if self.rge_version > 1.16:
            raise Exception("Not implemented: player string table not understood")

        if self.rge_version > 1.13:
            for i in range(0, 16):
                player_active = 1 if i < 2 else 0
                player_type = 1 if i == 0 else 0
                player_civ_id = i + 1
                player_base = ScnPlayerBaseProperties(
                    active=player_active,
                    player_type=player_type,
                    civilization=player_civ_id,
                    posture=4)
                player_base.write(data)

        if self.rge_version > 1.07:
            is_conquest = True
            data.boolean8(is_conquest)

        # Some check values?
        data.uint16(0)
        data.uint16(0)
        data.float32(0)

        filename = 'scenario.scx'
        data.string16(filename)

        if self.rge_version > 1.16:
             raise Exception("Not implemented: scenario instruction string table not understood")

        if self.rge_version > 1.22:
             raise Exception("Not implemented: scout string table not understood")

        description = "description"
        data.string16(description)

        if self.rge_version >= 1.11:
            hints_message = ""
            data.string16(hints_message)
            win_message = ""
            data.string16(win_message)
            loss_message = ""
            data.string16(loss_message)
            history_message = ""
            data.string16(history_message)

        if self.rge_version > 1.22:
            raise Exception("Not implemented: scout data not understood")

        pregame_cinematic = ' <None> '
        data.string16(pregame_cinematic)
        victory_cinematic = ' <None> '
        data.string16(victory_cinematic)
        loss_cinematic = ' <None> '
        data.string16(loss_cinematic)

        if self.rge_version >= 1.09:
            mission_bmp = ' <None> '
            data.string16(mission_bmp)

        if self.rge_version >= 1.10:
             mission_image = 0
             data.uint32(mission_image)
             width = 0
             data.uint32(width)
             height = 0
             data.uint32(height)
             orientation = 1
             data.uint16(orientation)

        for i in range(0, 16):
            player_build_list = "Random"
            data.string16(player_build_list)

        for i in range(0, 16):
            player_city_plan = ' <None> '
            data.string16(player_city_plan)

        if self.rge_version >= 1.08:
            for i in range(0, 16):
                player_personality = "Random"
                data.string16(player_personality)

        for i in range(0, 16):
            """ Embedded files """
            build_list_length = 0
            data.uint32(build_list_length)
            city_plan_length = 0
            data.uint32(city_plan_length)
            if self.rge_version >= 1.08:
                ai_rules_length = 0
                data.uint32(ai_rules_length)
            else:
                data.uint32(0)
            # Would write build_list, city plan, AI rules if len() wasn't 0

        if self.rge_version >= 1.20:
            raise Exception("Not implemented: AI rules not understood")

        if self.rge_version >= 1.02:
            data.int32(-99)  # Check value
Beispiel #12
0
 def write_classic(self, data: ScnDataWriter, file_version: float):
     data.float32(self.position[0])
     data.float32(self.position[1])
     data.float32(self.position[2])
     data.uint32(self.id),
     data.uint16(self.type_id),
     data.uint8(self.state),
     data.float32(self.angle),
     if file_version >= 1.15:
         data.uint16(self.frame)
     if file_version > 1.13:
         data.uint32(self.garrisoned_in)
Beispiel #13
0
 def write(self, data: ScnDataWriter):
     data.uint32(self.active)
     data.uint32(self.player_type)
     data.uint32(self.civilization)
     data.uint32(self.posture)
Beispiel #14
0
 def write_de(self, data: ScnDataWriter):
     data.float32(self.food)
     data.float32(self.wood)
     data.float32(self.gold)
     data.float32(self.stone)
     data.float32(self.population)
 def write(self, data: ScnDataWriter):
     data.uint32(self.player_count)
     for i in range(1, 9):
         self.unknown_player_data_structure[i - 1].write(data)
Beispiel #16
0
    def write_classic(self, data: ScnDataWriter):
        self.base.write_classic(data)
        version = self.base.rge_version
        if version <= 1.13:
            for i in range(0, 16):
                # Not based on real info at the moment
                data.string_fixed('Player name {}'.format(i), size=256)
            raise Exception(
                "Not implemented: Don't know how to read player base properties from <1.13 file"
            )
        else:
            for i in range(0, 16):
                # Not based on real info at the moment
                res = ScnPlayerStartResources(
                    gold=0,
                    food=200,
                    wood=200,
                    stone=150,
                    ore=0,
                    goods=0,
                    color=0,
                )
                res.write(data, version)

        if version >= 1.02:
            data.int32(-99)  # check

        victory_conquest = 1
        data.uint32(victory_conquest)
        victory_ruins = 0
        data.uint32(victory_ruins)
        victory_artifacts = 0
        data.uint32(victory_artifacts)
        victory_discoveries = 0
        data.uint32(victory_discoveries)
        victory_exploration = 0
        data.uint32(victory_exploration)
        victory_gold = 0
        data.uint32(victory_gold)
        victory_all_flag = False
        data.boolean32(victory_all_flag)

        if version >= 1.13:
            mp_victory_type = 0
            data.uint32(mp_victory_type)
            victory_score = 900
            data.uint32(victory_score)
            victory_time = 9000
            data.uint32(victory_time)

        for i in range(0, 16):
            for j in range(0, 16):
                # stance from player i to j
                diplomatic_stance = 3  # 3 is enemy ?
                data.uint32(diplomatic_stance)

        # 12 victory conditions for each player
        for i in range(0, 16):
            for j in range(0, 12):
                # TODO write these ???
                # all 0's on blank map.
                data.string_fixed('', size=60)

        if version >= 1.02:
            data.int32(-99)  # check value

        # Allied victory
        for i in range(0, 16):
            allied_victory = 0
            data.uint32(allied_victory)

        if version >= 1.24:
            raise Exception(
                "Not implemented: Don't know how to read team information from >=1.24 file"
            )

        if version >= 1.18:
            # Also has disabled units and building, where are they in older versions?
            raise Exception(
                "Not implemented: Don't know how to read tech tree from >=1.18 file"
            )
        elif version > 1.03:
            for i in range(0, 16):
                for j in range(0, 20):
                    # disabled tech player i, position j
                    disabled_tech_id = 1
                    data.uint32(disabled_tech_id)

        if version > 1.04:
            data.uint32(0)  # No idea

        if version >= 1.12:
            data.uint32(0)  # No idea
            full_tech_tree = False
            data.boolean32(full_tech_tree)

        if version > 1.05:
            for i in range(0, 16):
                player_start_age = 0
                data.uint32(player_start_age)

        if version >= 1.02:
            data.int32(-99)  # check value

        if version >= 1.19:
            # 'view'??
            data.uint32(0)
            data.uint32(0)

        if version >= 1.21:
            raise Exception(
                "Not implemented: Don't know how to read map type from >=1.21 file"
            )

        if version >= 1.21:
            raise Exception(
                "Not implemented: Don't know how to read base priorities from >=1.21 file"
            )
Beispiel #17
0
 def write(self, data: ScnDataWriter, version: float):
     data.uint32(self.gold),
     data.uint32(self.wood),
     data.uint32(self.food),
     data.uint32(self.stone),
     if version >= 1.17:
         data.uint32(self.ore)
         data.uint32(self.goods)
     if version >= 1.24:
         data.uint32(self.color)