Ejemplo n.º 1
0
def client_context_update(name='client_context'):
    return Struct(
        name, VLQ('length'), Peek(Byte('a')),
        If(
            lambda ctx: ctx['a'] == 0,
            Struct('junk', Padding(1), Peek(Byte('b')),
                   If(lambda ctx: ctx['b'] == 0, Padding(1)),
                   VLQ('extra_length'))),
        If(lambda ctx: ctx['a'] > 8, Struct('junk2', VLQ('extra_length'))),
        VLQ('subpackets'),
        Array(lambda ctx: ctx.subpackets, Variant('subpacket')))
Ejemplo n.º 2
0
                   "value" / Bytes(lambda ctx: ctx.length))

separator = Const(b"\xa3_\x02\x00")

de = "de" / Struct(
    "version" / Float32l,
    "interval_version" / Int32ul,
    "game_options_version" / Int32ul,
    "dlc_count" / Int32ul,
    "dlc_ids" / Array(lambda ctx: ctx.dlc_count, Int32ul),
    "dataset_ref" / Int32ul,
    "difficulty" / DifficultyEnum(Int32ul),
    "selected_map_id" / Int32ul,
    "resolved_map_id" / Int32ul,
    "reveal_map" / Int32ul,
    Peek("victory_type_id" / Int32ul),
    VictoryEnum("victory_type" / Int32ul),
    Peek("starting_resources_id" / Int32ul),
    ResourceLevelEnum("starting_resources" / Int32ul),
    Peek("starting_age_id" / Int32ul),
    AgeEnum("starting_age" / Int32ul),
    Peek("ending_age_id" / Int32ul),
    AgeEnum("ending_age" / Int32ul),
    "game_type" / Int32ul,
    separator,
    separator,
    "speed" / Float32l,
    "treaty_length" / Int32ul,
    "population_limit" / Int32ul,
    "num_players" / Int32ul,
    "unused_player_color" / Int32ul,
Ejemplo n.º 3
0
    Array(lambda ctx: ctx.selected, "unit_ids" / Int32ul),
    Array(lambda ctx: ctx.waypoint_count, "x_more" / Byte),
    Array(lambda ctx: ctx.waypoint_count, "y_more" / Byte))

backtowork = "backtowork" / Struct(Padding(3), "towncenter_id" / Int32ul)

ai_command = "ai_command" / Struct(Padding(lambda ctx: ctx._._.length - 1))

postgame = "achievements" / Struct(
    Padding(3),
    "scenario_filename" /
    String(32, padchar=b'\x00', trimdir='right', encoding='latin1'),
    "player_num" / Byte,
    "computer_num" / Byte,
    Padding(2),
    Peek("duration_int" / Int32ul),
    TimeSecAdapter("duration" / Int32ul),
    "cheats" / Flag,
    "complete" / Flag,
    Padding(14),
    "map_size" / Byte,
    MapAdapter("map_id" / Byte),
    "population" / Byte,
    Padding(1),
    VictoryEnum("victory_type" / Byte),
    StartingAgeEnum("starting_age" / Byte),
    ResourceLevelEnum("resource_level" / Byte),
    "all_techs" / Flag,
    "team_together" / Flag,  #(truth = 0, falsehood = 1),
    RevealMapEnum("reveal_map" / Byte),
    "is_deathmatch" / Flag,
Ejemplo n.º 4
0
)

# Objects that exist on the map at the start of the recorded game
existing_object = "objects"/Struct(
    ObjectTypeEnum("type"/Byte),
    "player_id"/Byte,
    Embedded("properties"/Switch(lambda ctx: ctx.type, {
        "gaia": gaia,
        "unit": unit,
        "building": building,
        "fish": fish,
        "other": other
    })),
    # These boundary bytes can occur in the middle of a set of objects, and at the end
    # There is probably a better way to check these
    Peek("extension1"/Int16ub),
    Peek("extension2"/Int32ub),
    If(lambda ctx: ctx.extension1 == 11 and ctx.extension2 > 720898, Padding(
        10
    ))
)

# Default values for objects, nothing of real interest
default_object = "default_object"/Struct(
    ObjectTypeEnum("type"/Byte),
    Padding(14),
    "properties"/Switch(lambda ctx: ctx.type, {
        "gaia": Padding(24),
        "object": Padding(32),
        "fish": Padding(32),
        "other": Padding(28),
Ejemplo n.º 5
0
                          Bytes('data', lambda ctx: ctx['data_size'] - 9))

METADATA_RECORD_DATA = Struct('field_metadata', Byte('metadata_type'),
                              ULInt32('metadata_record_count'),
                              ULInt32('metadata_record_last_access'))

TABLE_DEFINITION_RECORD_DATA = Struct(
    'table_definition',
    Bytes('table_definition_bytes', lambda ctx: ctx['data_size'] - 5))

INDEX_RECORD_DATA = Struct('field_index',
                           Bytes('data', lambda ctx: ctx['data_size'] - 10),
                           ULInt32('record_number'))

RECORD_STRUCT = Struct(
    'record', ULInt16('data_size'), Peek(Byte('first_byte')),
    Embed(
        IfThenElse(
            'record_type', lambda ctx: ctx['first_byte'] == 0xFE,
            Embed(
                Struct(
                    'record',
                    RECORD_TYPE,
                    String('table_name',
                           lambda ctx: ctx['data_size'] - 5,
                           encoding=record_encoding),
                    UBInt32('table_number'),
                )),
            Embed(
                Struct(
                    'record', UBInt32('table_number'), RECORD_TYPE,
Ejemplo n.º 6
0
        ),
        MetaField("data", lambda context: context["length"]),
    ),
}

infinipackets_by_name = {
    "ping": 0,
    "disconnect": 255,
}

infinipacket_parser = Struct(
    "parser",
    OptionalGreedyRange(
        Struct(
            "packets",
            Peek(UBInt8("header")),
            Embed(
                Switch("packet", lambda context: context["header"],
                       infinipackets)),
        ), ),
    OptionalGreedyRange(UBInt8("leftovers"), ),
)


def parse_infinipackets(bytestream):
    container = infinipacket_parser.parse(bytestream)

    l = [(i.header, i.payload) for i in container.packets]
    leftovers = "".join(chr(i) for i in container.leftovers)

    if DUMP_ALL_PACKETS:
Ejemplo n.º 7
0
        'z' / Flag,
        'p' / Flag,
        'len' / IfThenElse(_this.b == 0, BitsInteger(4), BitsInteger(12)),
    ),
    # 'midi_list' / Bytes(_this.flags.len),
    'midi_list' / FixedSized(_this.flags.len, GreedyRange(Struct(
        'delta_time' / If(_this._index > 0, VarInt),

        # The "running status" technique means multiple commands may be sent under
        # the same status. This condition occurs when, after parsing the current
        # commands, we see the next byte is NOT a status byte (MSB is low).
        #
        # Below, this is accomplished by storing the most recent status byte
        # on the global context with the `* remember_last` macro; then using it
        # on the `else` branch of the `command_byte` selection.
        '__next' / Peek(Int8ub),
        'command_byte' / IfThenElse(_this.__next & 0x80,
            Byte * remember_last,
            Computed(lambda ctx: ctx._root._last_command_byte)
        ),
        'command' / If(_this.command_byte, Enum(Computed(_this.command_byte & 0xf0),
            note_on=COMMAND_NOTE_ON,
            note_off=COMMAND_NOTE_OFF,
            aftertouch=COMMAND_AFTERTOUCH,
            control_mode_change=COMMAND_CONTROL_MODE_CHANGE)),
        'channel' / If(_this.command_byte, Computed(_this.command_byte & 0x0f)),

        'params' / Switch(_this.command, {
            'note_on': Struct(
                'key' / MIDINote,
                'velocity' / Int8ub,
Ejemplo n.º 8
0
    Padding(4), Padding(64),
    IfThenElse(
        lambda ctx: ctx._._.version != 'VER 9.4',
        Struct(
            Array(16, "num_disabled_techs" / Int32ul),
            Array(16, Array(30, Padding(4))),
            Array(16, "num_disabled_units" / Int32ul),
            Array(16, Array(30, Padding(4))),
            Array(16, "num_disabled_buildings" / Int32ul),
            Array(16, Array(20, Padding(4))),
        ), Padding(196)), Padding(12))

# Game settings.
game_settings = "game_settings" / Struct(
    Array(16, AgeEnum("starting_ages" / Int32sl)), Padding(4), Padding(8),
    "map_id" / Int32ul, Peek("difficulty_id" / Int32ul),
    DifficultyEnum("difficulty" / Int32ul), "lock_teams" / Int32ul,
    If(lambda ctx: ctx._._.version == 'VER 9.4', Padding(29)),
    Array(
        9, "player_info" /
        Struct("data_ref" / Int32ul, PlayerTypeEnum("type" / Int32ul),
               "name" / PascalString(lengthfield="name_length" / Int32ul))),
    Padding(36), Padding(4),
    IfThenElse(
        lambda ctx: ctx._._.version == 'VER 9.4', "end_of_game_settings" /
        Find(b'\x9a\x99\x99\x99\x99\x99\x01\x40', None), "end_of_game_settings"
        / Find(b'\x9a\x99\x99\x99\x99\x99\xf9\x3f', None)))

# Triggers.
triggers = "triggers" / Struct(
    Padding(1),
Ejemplo n.º 9
0
# Metadata subconstruct.
entity_metadata = MetadataAdapter(
    Struct(
        "metadata",
        RepeatUntil(
            lambda obj, context: obj["peeked"] == 0x7f,
            Struct(
                "data",
                BitStruct(
                    "id",
                    BitField("data_type", 3),  # first
                    BitField("identifier", 5),  # second
                ),
                Switch("value", lambda context: context["id"]["data_type"],
                       metadata_switch),
                Peek(SBInt8("peeked")),
            ),
        ),
        Const(UBInt8("terminator"), 0x7f),
    ), )

# The actual packet list.
packets = {
    0:
    Struct(
        "keep alive",
        SBInt32("pid"),
    ),
    1:
    Struct(
        "login request ",
Ejemplo n.º 10
0
    "rec_owner"/Int32ul,
    "unk2"/Int32ul,
    "unk3"/Int32ul,
    "unk4"/Int32ul
)


# Message.
message = "message"/Struct(
    MessageEnum("subtype"/Int32ul),
    "data"/Switch(lambda ctx: ctx.subtype, {
        "start": start,
        "chat": chat
    })
)


# Operation.
operation = "operation"/Struct(
    Peek(OperationEnum("type"/Int32ul)),
    "start"/Tell,
    "op"/Int32ul,
    Embedded("data"/Switch(lambda ctx: ctx.type, {
        "action": action,
        "sync": sync,
        "message": message,
        "embedded": embedded.embedded
    })),
    "end"/Tell
)
Ejemplo n.º 11
0
 - Synchronization: Time increment and view coordinates of recording player
 - Embedded: A variety of embedded structures
"""

from construct import (Struct, Byte, Switch, Embedded, Padding, Int32ul, Peek,
                       Tell, Float32l, String, If, Array, Bytes, GreedyBytes,
                       Computed, IfThenElse, Int16ul, Probe)
from mgz.enums import ActionEnum, OperationEnum, MessageEnum
from mgz.body import actions, embedded
from mgz.util import BoolAdapter

# pylint: disable=invalid-name

# Action.
action_data = "action" / Struct(
    Peek("type_int" / Byte),
    ActionEnum("type" / Byte),
    Embedded("action" / Switch(
        lambda ctx: ctx.type,
        {
            "interact": actions.interact,
            "move": actions.move,
            "stop": actions.stop,
            "stance": actions.stance,
            "guard": actions.guard,
            "follow": actions.follow,
            "formation": actions.formation,
            "waypoint": actions.waypoint,
            "give_attribute": actions.give_attribute,
            "add_attribute": actions.add_attribute,
            "ai_waypoint": actions.ai_waypoint,
Ejemplo n.º 12
0
compressed_header = Struct(
    "game_version"/CString(encoding='latin1'),
    "save_version"/VersionAdapter(Float32l),
    "version"/Computed(lambda ctx: get_version(ctx.game_version, ctx.save_version, None)),
    "hd"/If(lambda ctx: ctx.version == Version.HD and ctx.save_version > 12.34, hd),
    "de"/If(lambda ctx: ctx.version == Version.DE, de),
    ai,
    replay,
    map_info,
    initial,
    achievements,
    scenario,
    lobby,
    Terminated
)


subheader = Struct(
    "check"/Peek(Int32ul),
    "chapter_address"/If(lambda ctx: ctx.check < 100000000, Int32ul),
    Embedded(MgzPrefixed(lambda ctx: ctx._.header_length - 4 - (4 if ctx.check < 100000000 else 0), ZlibCompressed(compressed_header)))
)

"""Header is compressed"""
header = Struct(
    "header_length"/Int32ul,
    Embedded(subheader),
    "log_version"/If(lambda ctx: ctx.save_version >= 11.76, Peek(Int32ul)),
    "version"/Computed(lambda ctx: get_version(ctx.game_version, ctx.save_version, ctx.log_version))
)
Ejemplo n.º 13
0
map_info = "map_info" / Struct(
    "size_x" / Int32ul,
    "size_y" / Int32ul,
    "tile_num" / Computed(lambda ctx: ctx.size_x * ctx.size_y),
    "zone_num" / Int32ul,
    Array(
        lambda ctx: ctx.zone_num,
        Struct(
            IfThenElse(lambda ctx: ctx._._.version == Version.DE,
                       Padding(lambda ctx: 2048 + (ctx._.tile_num * 2)),
                       Padding(lambda ctx: 1275 + ctx._.tile_num)),
            "num_floats" / Int32ul, Padding(lambda ctx: ctx.num_floats * 4),
            Padding(4))),
    "all_visible" / Flag,
    "fog_of_war" / Flag,
    "check" /
    Peek(Struct(Padding(lambda ctx: ctx._.tile_num * 7),
                "val" / Int32ul)),  # DE 12.97 fix
    Array(lambda ctx: ctx.tile_num, tile),
    "num_data" / Int32ul,
    Padding(4),
    Array(lambda ctx: ctx.num_data, Padding(4)),
    Array(
        lambda ctx: ctx.num_data, "couple" /
        Struct("num_obstructions" / Int32ul,
               Array(lambda ctx: ctx.num_obstructions, Padding(8)))),
    "size_x_2" / Int32ul,
    "size_y_2" / Int32ul,
    Padding(lambda ctx: ctx.tile_num * 4),  # visibility
)
Ejemplo n.º 14
0
    "hd_dm_elo"/If(lambda ctx: find_save_version(ctx) < 25.22, Int32ul),
    "prefer_random"/Flag,
    "custom_ai"/Flag,
    If(lambda ctx: find_save_version(ctx) >= 25.06, "handicap"/Bytes(8)),
)

de = "de"/Struct(
    "build"/If(lambda ctx: find_save_version(ctx) >= 25.22, Int32ul),
    "timestamp"/If(lambda ctx: find_save_version(ctx) >= 26.16, Int32ul),
    "version"/Float32l,
    "interval_version"/Int32ul,
    "game_options_version"/Int32ul,
    "dlc_count"/Int32ul,
    "dlc_ids"/Array(lambda ctx: ctx.dlc_count, Int32ul),
    "dataset_ref"/Int32ul,
    Peek("difficulty_id"/Int32ul),
    DifficultyEnum("difficulty"/Int32ul),
    "selected_map_id"/Int32ul,
    "resolved_map_id"/Int32ul,
    "reveal_map"/Int32ul,
    Peek("victory_type_id"/Int32ul),
    VictoryEnum("victory_type"/Int32ul),
    Peek("starting_resources_id"/Int32ul),
    ResourceLevelEnum("starting_resources"/Int32ul),
    "starting_age_id"/Int32ul,
    "starting_age"/AgeEnum(Computed(lambda ctx: ctx.starting_age_id - 2)),
    "ending_age_id"/Int32ul,
    "ending_age"/AgeEnum(Computed(lambda ctx: ctx.ending_age_id - 2)),
    "game_type"/Int32ul,
    separator,
    separator,
Ejemplo n.º 15
0
"""Definitive Edition structure."""

from construct import (Struct, Int32ul, Float32l, Array, Padding, Flag, Byte,
                       Int16ul, Bytes, Int32sl, Peek, If)

from mgz.enums import VictoryEnum, ResourceLevelEnum, AgeEnum

# pylint: disable=invalid-name, bad-continuation

de = "de" / Struct(
    "options" / Int32sl, "unk0" / Int32ul, "unk1" / Int32ul, "dlc_count" /
    Int32ul, "dlc_ids" / Array(lambda ctx: ctx.dlc_count, Int32ul), Padding(4),
    "difficulty" / Int32ul, "map_size" / Int32ul, "map_id" / Int32ul,
    "reveal_map" / Int32ul, Peek("victory_type_id" / Int32ul),
    VictoryEnum("victory_type" / Int32ul),
    Peek("starting_resources_id" / Int32ul),
    ResourceLevelEnum("starting_resources" / Int32ul),
    Peek("starting_age_id" / Int32ul), AgeEnum("starting_age" / Int32ul),
    Peek("ending_age_id" / Int32ul), AgeEnum("ending_age" / Int32ul),
    "game_type" / Int32ul, Padding(8), "speed" / Float32l,
    "treaty_length" / Int32ul, "population_limit" / Int32ul,
    "num_players" / Int32ul, "unknown2" / Int32ul, "unknown3" / Int32ul,
    Padding(4), "trade_enabled" / Flag, "team_bonus_disabled" / Flag,
    "random_positions" / Flag, "all_techs" / Flag, "num_starting_units" / Byte,
    "lock_teams" / Flag, "lock_speed" / Flag, "multiplayer" / Flag,
    "cheats" / Flag, "record_game" / Flag, "animals_enabled" / Flag,
    "predators_enabled" / Flag, Padding(6), "players" / Array(
        8,
        Struct("dat_crc" / Bytes(4), "mp_version" / Byte, "color_id" / Int32sl,
               "civ_id" / Int32sl, Padding(23), "profile_id_length" / Int16ul,
               "profile_id" / Bytes(lambda ctx: ctx.profile_id_length),
Ejemplo n.º 16
0
    "key" / Prefixed(Int32ul, GreedyString('utf-8')),
    "value" / Prefixed(
        Int32ul,
        Switch(
            this.type,
            {0x04: Int32ul,
             0x05: Int64ul,
             0x08: Flag,
             0x0C: Int32sl,
             0x0D: Int64sl,
             0x42: GreedyBytes,
             0x18: GreedyString('utf-8')
            }
        )
    ),
    "next_byte" / Peek(Byte)
)

# new dynamic dictionary structure added in KDBX4
VariantDictionary = Struct(
    "version" / Bytes(2),
    "dict" / DynamicDict(
        'key',
        RepeatUntil(
            lambda item,a,b: item.next_byte == 0x00,
            VariantDictionaryItem
        )
    ),
    Padding(1) * "null padding"
)
Ejemplo n.º 17
0
from mgz.enums import GameTypeEnum, RevealMapEnum
from mgz.util import Version, find_save_version

# pylint: disable=invalid-name, bad-continuation

# Player inputs in the lobby, and several host settings.
lobby = "lobby" / Struct(
    If(lambda ctx: find_save_version(ctx) >= 13.34, Padding(5)),
    If(lambda ctx: find_save_version(ctx) >= 20.06, Padding(9)),
    Array(8, "teams" / Byte),  # team number selected by each player
    If(
        lambda ctx: ctx._.version not in (Version.DE, Version.HD),
        Padding(1),
    ),
    Peek("reveal_map_id" / Int32ul),
    RevealMapEnum("reveal_map" / Int32ul),
    "fog_of_war" / Int32ul,
    "map_size" / Int32ul,
    "population_limit_encoded" / Int32ul,
    "population_limit" /
    Computed(lambda ctx: ctx.population_limit_encoded *
             (25 if ctx._.version in
              [Version.USERPATCH14, Version.USERPATCH15] else 1)),
    Embedded(
        If(
            lambda ctx: ctx._.version != Version.AOK,
            Struct(Peek("game_type_id" / Byte), GameTypeEnum(
                "game_type" / Byte), "lock_teams" / Flag))),
    If(
        lambda ctx: ctx._.version in (Version.DE, Version.HD),
Ejemplo n.º 18
0
combat = "combat" / Struct(
    Embedded(base_combat),
    "de" / If(lambda ctx: find_version(ctx) == Version.DE, Bytes(18)),
    "next_volley" / Byte,
    "using_special_animation" / Byte,
    "own_base" / Byte,
    "base" / If(lambda ctx: ctx.own_base > 0, unit_type),
    "attribute_amounts" / Array(6, Int16ul),
    "decay_timer" / Int16ul,
    "raider_build_countdown" / Int32ul,
    "locked_down_count" / Int32ul,
    "inside_garrison_count" /
    If(lambda ctx: find_version(ctx) != Version.AOK, Byte),
    "has_ai" / Int32ul,
    "ai" / If(lambda ctx: ctx.has_ai > 0, unit_ai),
    "peek" / Peek(Bytes(5)),  # TODO: figure out the right way to do this part
    "de_position" / If(lambda ctx: ctx.peek != b'\x00\xff\xff\xff\xff',
                       Struct(
                           "position" / vector,
                           "flag" / Byte,
                       )),
    "town_bell_flag" / Byte,
    "town_bell_target_id" / Int32sl,
    "town_bell_target_x" / Float32l,
    "town_bell_target_y" / Float32l,
    "town_bell_target_id_2" /
    If(lambda ctx: find_version(ctx) != Version.AOK, Int32sl),
    "town_bell_target_type" /
    If(lambda ctx: find_version(ctx) != Version.AOK, Int32sl),
    "town_bell_action" /
    If(lambda ctx: find_version(ctx) != Version.AOK, Int32sl),
Ejemplo n.º 19
0
    })
)
# Specialization for loading float data faster
TaggedFloat64 = ExprAdapter(
    Struct(Const(5, Int16ul), 'value'/Float64l),
    encoder=lambda obj, ctx: Container(value=obj.value),
    decoder=lambda obj, ctx: obj.value)
DataList = Struct(
    'size'/Int64ul,
    LazyField(Array(lambda ctx: ctx.size, TaggedFloat64)),
    Const('\xc0\xff\xee\x01')  # XXX: probably useful
)
# XXX: hacks
bad_strings = ('\xc0\xff\xee\x01\x00\x00', '\x01#Eg\x00\x00')
Property = Struct(
    'peek'/Peek(Bytes(6)),
    Embedded(IfThenElse(
        this.peek in bad_strings,
        Padding(6),
        Struct('label'/VBString, 'TaggedData'/TaggedData)))
)
Properties = GreedyRange(Property)
LabeledDataList = Struct(
    'label'/VBString,
    Padding(18),
    'DataList'/Embedded(DataList)
)
DataSet = Struct(
    'number'/Int64ul,
    # XXX: may have more than two. Might use ctx.number to decide?
    'LabeledDataList'/Array(2, LabeledDataList),
Ejemplo n.º 20
0
    })
)
# Specialization for loading float data faster
TaggedFloat64 = ExprAdapter(
    Struct(Const('tag'/Int16ul, 5), 'value'/Float64l),
    encoder=lambda obj, ctx: Container(tag=obj.tag, value=obj.value),
    decoder=lambda obj, ctx: obj.value)
DataList = Struct(
    'size'/Int64ul,
    OnDemand(Array(lambda ctx: ctx.size, TaggedFloat64)),
    Const('\xc0\xff\xee\x01')  # XXX: probably useful
)
# XXX: hacks
bad_strings = ('\xc0\xff\xee\x01\x00\x00', '\x01#Eg\x00\x00')
Property = Struct(
    'peek'/Peek(String(6)),
    Embedded(IfThenElse(
        this.peek in bad_strings,
        Padding(6),
        Struct('label'/VBString, 'TaggedData'/TaggedData)))
)
Properties = GreedyRange(Property)
LabeledDataList = Struct(
    'label'/VBString,
    Padding(18),
    'DataList'/Embedded(DataList)
)
DataSet = Struct(
    'number'/Int64ul,
    # XXX: may have more than two. Might use ctx.number to decide?
    'LabeledDataList'/Array(2, LabeledDataList),
Ejemplo n.º 21
0
"""Lobby."""

from construct import Array, Byte, Bytes, Flag, Int32ul, Padding, Peek, Struct, If

from mgz.enums import GameTypeEnum, RevealMapEnum

# pylint: disable=invalid-name, bad-continuation

# Player inputs in the lobby, and several host settings.
lobby = "lobby" / Struct(
    Array(8, "teams" / Byte),  # team number selected by each player
    If(
        lambda ctx: ctx._.version != 'VER 9.4',
        Padding(1),
    ),
    Peek("reveal_map_id" / Int32ul),
    RevealMapEnum("reveal_map" / Int32ul),
    Padding(4),
    "map_size" / Int32ul,
    "population_limit" / Int32ul,  # multiply by 25 for UserPatch 1.4
    Peek("game_type_id" / Byte),
    GameTypeEnum("game_type" / Byte),
    "lock_teams" / Flag,
    If(lambda ctx: ctx._.version == 'VER 9.4', Padding(5)),
    "num_chat" / Int32ul,
    Array(
        lambda ctx: ctx.num_chat,  # pre-game chat messages
        "messages" / Struct(
            "message_length" / Int32ul,
            "message" / Bytes(lambda ctx: ctx.message_length -
                              (1 if ctx.message_length > 0 else 0)),
Ejemplo n.º 22
0
                        padchar=b'\x00',
                        trimdir='right',
                        encoding='latin1'),
    ))

# Embedded header (aka saved chapter)
header = Struct(
    "subtype" / Computed("savedchapter"), "data" / Struct(
        "header_length" / Computed(lambda ctx: ctx._._._.op - ctx._._._.start),
        Embedded(subheader)))

# Unknown embedded structure - looks like a partial action?
other = Struct(
    "subtype" / Computed("unknown"), "data" / Struct(
        Padding(4), "num_ints" / Int32ul,
        If(lambda ctx: ctx.num_ints < 0xff,
           Array(lambda ctx: ctx.num_ints, Int32ul)), Padding(12)))

# Anything we don't recognize - just consume the remainder
default = Struct("subtype" / Computed("default"), GreedyBytes)

# Embedded structures identified by first byte (for now)
embedded = "embedded" / Struct(
    "marker" / Peek(Int16ul),
    Embedded("data" / Switch(lambda ctx: ctx.marker, {
        0: header,
        9024: chat,
        65535: other
    },
                             default=default)))
Ejemplo n.º 23
0
                       Struct, this, Bytes, Embedded, IfThenElse)

from mgz.body.achievements import achievements
from mgz.enums import (DiplomacyStanceEnum, FormationEnum, GameActionModeEnum,
                       OrderTypeEnum, ReleaseTypeEnum, ResourceEnum,
                       ResourceLevelEnum, RevealMapEnum, StanceEnum, AgeEnum,
                       VictoryEnum)
from mgz.util import TimeSecAdapter, check_flags

# pylint: disable=invalid-name, bad-continuation

# Not all actions are defined, not all actions are complete.

interact = "interact" / Struct(
    "player_id" / Byte, Const(b"\x00\x00"), "target_id" / Int32ul, "selected" /
    Int32ul, "x" / Float32l, "y" / Float32l, "next" / Peek(Bytes(8)),
    "flags" / If(lambda ctx: check_flags(ctx.next), Bytes(8)),
    "unit_ids" / If(lambda ctx: ctx.selected < 0xff,
                    Array(lambda ctx: ctx.selected, "unit_ids" / Int32ul)))

give_attribute = "give_attribute" / Struct(
    "player_id" / Byte, "target_id" / Byte, "attribute" / Byte,
    "amount" / Float32l)

add_attribute = "add_attribute" / Struct(
    "player_id" / Byte, "attribute" / Byte, Padding(1), "amount" / Float32l)

create = "create" / Struct(Padding(1), "unit_type" / Int16ul,
                           "player_id" / Byte, Padding(1), "x" / Float32l,
                           "y" / Float32l, "z" / Float32l)
Ejemplo n.º 24
0
"""

from construct import (Struct, Byte, Switch, Embedded, Padding,
                       Int32ul, Peek, Tell, Float32l, String, If, Array, Bytes,
                       GreedyBytes, Computed, IfThenElse, Int16ul, Int64ul)
from mgz.enums import ActionEnum, OperationEnum, MessageEnum
from mgz.body import actions, embedded
from mgz.util import BoolAdapter


# pylint: disable=invalid-name, bad-continuation


# Action.
action_data = "action"/Struct(
    Peek("type_int"/Byte),
    ActionEnum("type"/Byte),
    Embedded("action"/Switch(lambda ctx: ctx.type, {
        "interact": actions.interact,
        "move": actions.move,
        "stop": actions.stop,
        "stance": actions.stance,
        "guard": actions.guard,
        "follow": actions.follow,
        "formation": actions.formation,
        "waypoint": actions.waypoint,
        "give_attribute": actions.give_attribute,
        "add_attribute": actions.add_attribute,
        "ai_waypoint": actions.ai_waypoint,
        "ai_interact": actions.ai_interact,
        "ai_move": actions.ai_move,
Ejemplo n.º 25
0
# --------------- KDF Params / Plugin Data ----------------
VariantDictionaryItem = Struct(
    "type" / Byte, "key" / Prefixed(Int32ul, GreedyString('utf-8')),
    "value" / Prefixed(
        Int32ul,
        Switch(
            this.type, {
                0x04: Int32ul,
                0x05: Int64ul,
                0x08: Flag,
                0x0C: Int32sl,
                0x0D: Int64sl,
                0x42: GreedyBytes,
                0x18: GreedyString('utf-8')
            })), "next_byte" / Peek(Byte))

# new dynamic dictionary structure added in KDBX4
VariantDictionary = Struct(
    "version" / Bytes(2), "dict" / DynamicDict(
        'key',
        RepeatUntil(lambda item, a, b: item.next_byte == 0x00,
                    VariantDictionaryItem)),
    Padding(1) * "null padding")

# -------------------- Dynamic Header --------------------

# https://github.com/dlech/KeePass2.x/blob/dbb9d60095ef39e6abc95d708fb7d03ce5ae865e/KeePassLib/Serialization/KdbxFile.cs#L234-L246

DynamicHeaderItem = Struct(
    "id" / Mapping(
Ejemplo n.º 26
0
# Metadata subconstruct.
metadata = MetadataAdapter(
    Struct(
        "metadata",
        RepeatUntil(
            lambda obj, context: obj["peeked"] == 0x7f,
            Struct(
                "data",
                BitStruct(
                    "id",
                    BitField("first", 3),
                    BitField("second", 5),
                ),
                Switch("value", lambda context: context["id"]["first"],
                       metadata_switch),
                Peek(UBInt8("peeked")),
            ),
        ),
        Const(UBInt8("terminator"), 0x7f),
    ), )

# Build faces, used during dig and build.
faces = {
    "noop": -1,
    "-y": 0,
    "+y": 1,
    "-z": 2,
    "+z": 3,
    "-x": 4,
    "+x": 5,
}
Ejemplo n.º 27
0
    IfThenElse(
        lambda ctx: ctx._._.version != Version.DE,
        Struct(
            Array(16, "num_disabled_techs" / Int32ul),
            Array(16, Array(30, Padding(4))),
            Array(16, "num_disabled_units" / Int32ul),
            Array(16, Array(30, Padding(4))),
            Array(16, "num_disabled_buildings" / Int32ul),
            Array(16, Array(20, Padding(4))),
        ), Padding(196)), Padding(12))

# Game settings.
game_settings = "game_settings" / Struct(
    Array(16, AgeEnum("starting_ages" / Int32sl)), Padding(4), Padding(8),
    "map_id" / If(lambda ctx: ctx._._.version != Version.AOK, Int32ul),
    Peek("difficulty_id" / Int32ul), DifficultyEnum(
        "difficulty" / Int32ul), "lock_teams" / Int32ul,
    If(lambda ctx: ctx._._.version == Version.DE, Padding(29)),
    Array(
        9, "player_info" /
        Struct("data_ref" / Int32ul, PlayerTypeEnum("type" / Int32ul),
               "name" / PascalString(lengthfield="name_length" / Int32ul))),
    Padding(36), Padding(4),
    IfThenElse(
        lambda ctx: ctx._._.version == Version.DE, "end_of_game_settings" /
        Find(b'\x9a\x99\x99\x99\x99\x99\x01\x40', None), "end_of_game_settings"
        / Find(b'\x9a\x99\x99\x99\x99\x99\xf9\x3f', None)))

# Triggers.
triggers = "triggers" / Struct(
    Padding(1),
Ejemplo n.º 28
0
    "ai_civ_name_index" / Byte,
    "ai_name" / If(lambda ctx: ctx._._.version >= 1005, hd_string),
    "name" / hd_string, "type" / PlayerTypeEnum(Int32ul), "steam_id" / Int64ul,
    "player_number" / Int32sl,
    Embedded(
        If(lambda ctx: ctx._._.version >= 1006 and not ctx._.test_57.is_57,
           Struct(
               "hd_rm_rating" / Int32ul,
               "hd_dm_rating" / Int32ul,
           ))))

hd = "hd" / Struct(
    "version" / Float32l, "interval_version" / Int32ul,
    "game_options_version" / Int32ul, "dlc_count" / Int32ul,
    "dlc_ids" / Array(lambda ctx: ctx.dlc_count, Int32ul),
    "dataset_ref" / Int32ul, Peek("difficulty_id" / Int32ul),
    DifficultyEnum("difficulty" / Int32ul), "selected_map_id" / Int32ul,
    "resolved_map_id" / Int32ul, "reveal_map" / Int32ul,
    Peek("victory_type_id" / Int32ul), VictoryEnum("victory_type" / Int32ul),
    Peek("starting_resources_id" / Int32ul),
    ResourceLevelEnum("starting_resources" / Int32ul),
    "starting_age_id" / Int32ul, "starting_age" /
    AgeEnum(Computed(lambda ctx: ctx.starting_age_id)), "ending_age_id" /
    Int32ul, "ending_age" / AgeEnum(Computed(lambda ctx: ctx.ending_age_id)),
    "game_type" / If(lambda ctx: ctx.version >= 1006, Int32ul), separator,
    "ver1000" / If(lambda ctx: ctx.version == 1000,
                   Struct("map_name" / hd_string, "unk" / hd_string)),
    separator, "speed" / Float32l, "treaty_length" / Int32ul,
    "population_limit" / Int32ul, "num_players" / Int32ul,
    "unused_player_color" / Int32ul, "victory_amount" / Int32ul, separator,
    "trade_enabled" / Flag, "team_bonus_disabled" / Flag,
Ejemplo n.º 29
0
                       AgeEnum, VictoryEnum)
from mgz.util import TimeSecAdapter, check_flags

# pylint: disable=invalid-name, bad-continuation

# Not all actions are defined, not all actions are complete.


interact = "interact"/Struct(
    "player_id"/Byte,
    Const(b"\x00\x00"),
    "target_id"/Int32ul,
    "selected"/Int32ul,
    "x"/Float32l,
    "y"/Float32l,
    "next"/Peek(Bytes(8)),
    "flags"/If(lambda ctx: check_flags(ctx.next), Bytes(8)),
    "unit_ids"/If(lambda ctx: ctx.selected < 0xff, Array(
        lambda ctx: ctx.selected, "unit_ids"/Int32ul
    ))
)

give_attribute = "give_attribute"/Struct(
    "player_id"/Byte,
    "target_id"/Byte,
    "attribute"/Byte,
    "amount"/Float32l
)

add_attribute = "add_attribute"/Struct(
    "player_id"/Byte,
Ejemplo n.º 30
0
#                 RECORD_TYPE,
#             ),
#             this.type,
#             {
#                 "DATA": (DATA_RECORD_DATA),
#                 "METADATA": (METADATA_RECORD_DATA),
#                 "TABLE_DEFINITION": (TABLE_DEFINITION_RECORD_DATA),
#                 "INDEX": (INDEX_RECORD_DATA),
#             },
#         ),
#     },
# )

RECORD_STRUCT = "record" / Struct(
    "data_size" / Int16ul,
    "first_byte" / Peek(Byte),
    "hh"
    / IfThenElse(
        this.first_byte == 0xFE,
        Struct(
            "type" / RECORD_TYPE,
            "table_name" / PaddedString(this._.data_size - 5, encoding=record_encoding),
            "table_number" / Int32ub,
            # Probe(),
        ),
        Struct(
            "table_number" / Int32ub,
            RECORD_TYPE,
            # Probe(),
            "h2"
            / Switch(