Esempio n. 1
0
def warp_action(name='warp_action'):
    return Struct(
        name, Byte('warp_type'),
        Switch('warp_action_type',
               lambda ctx: ctx['warp_type'], {
                   1: LazyBound('next', lambda: WARP_WORLD),
                   2: HexAdapter(Field('uuid', 16)),
                   3: SBInt32('alias')
               },
               default=Pass))
Esempio n. 2
0
    "data" / Switch(
        lambda ctx: ctx.fxMagic,
        {
            'FXP_PARAMS':
            "data" / Struct(
                "prgName" / String(28, padchar='\0'),
                Array(lambda ctx: ctx['_']['count'], "params" / Float32b),
            ),
            'FXP_OPAQUE_CHUNK':
            "data" / Struct(
                "prgName" / String(28, padchar='\0'),
                "size" / Int32ub,
                "chunk" / Bytes(lambda ctx: ctx['size']),
            ),
            'FXB_REGULAR':
            "data" / Struct(
                "future" / Bytes(128),  # zeros
                # Array of FXP_PARAMS vst2preset
                Array(lambda ctx: ctx['_']['count'],
                      "presets" / LazyBound(lambda: vst2preset)),
            ),
            'FXB_OPAQUE_CHUNK':
            "data" / Struct(
                "future" / Bytes(128),  # zeros
                "size" / Int32ub,
                # Unknown format of internal chunk
                "chunk" / Bytes(lambda ctx: ctx['size']),
            ),
        }),
)
Esempio n. 3
0

class HexAdapter(Adapter):
    def _encode(self, obj, context):
        # The code seems backward, but I assure you it's correct.
        return obj.decode('hex')

    def _decode(self, obj, context):
        return obj.encode('hex')


WARP_WORLD = Struct(
    'to_world', Byte('world_id'),
    Switch('world_type',
           lambda ctx: ctx['world_id'], {
               1: LazyBound('next', lambda: WARP_WORLD_CELESTIAL),
               2: LazyBound('next', lambda: WARP_WORLD_PLAYER),
               3: LazyBound('next', lambda: WARP_WORLD_MISSION)
           },
           default=Pass))

WARP_WORLD_CELESTIAL = Struct(
    'celestial_world', SBInt32('x'), SBInt32('y'), SBInt32('z'),
    SBInt32('planet'), SBInt32('satellite'), Optional(Byte('has_position')),
    If(lambda ctx: ctx['has_position'],
       Struct('position', SBInt32('x'), SBInt32('y'))))

WARP_WORLD_PLAYER = Struct(
    'player_world', HexAdapter(Field('uuid', 16)),
    Optional(Byte('has_position')),
    If(lambda ctx: ctx['has_position'],
Esempio n. 4
0
    OP_TEST=26,
    OP_TESTSET=27,
    OP_CALL=28,
    OP_TAILCALL=29,
    OP_RETURN=30,
    OP_FORLOOP=31,
    OP_FORPREP=32,
    OP_TFORLOOP=33,
    OP_SETLIST=34,
    OP_CLOSE=35,
    OP_CLOSURE=36,
    OP_VARARG=37,
)

# String = PascalString(LazyBound(lambda: LuaSize_t), "ascii")
String = Struct("size" / LazyBound(lambda: LuaSize_t),
                "str" / Bytes(this.size))

GlobalHead = Struct(
    "signature" / Const(b"\x1bLua"),
    "version" / Version,
    "format" / Format,
    "endian" / Endian,
    "size_int" / Int8ul,
    "size_size_t" / Int8ul,
    "size_instruction" / Int8ul,
    "size_lua_number" / Int8ul,
    "lua_num_valid" / Byte,
)

ProtoHead = Struct("source" / String, "linedefined" / Int32ul,
Esempio n. 5
0
)
thread_group_snapshot = Struct(
    predefined_name_substruct,
    'obj' / Struct('tgs_id' / Int64ul, 'tgs_name' /
                   Padded(16, CString('utf8')), 'tgs_flags' / Int64ul),
)
type_array_pad0 = Struct(
    'flags_type' / Computed(lambda ctx: (ctx._.flags >> 32) & 0xffffffff),
    'type' /
    Computed(lambda ctx: kcdata_types_enum.decmapping[ctx.flags_type]),
    'count' / Computed(lambda ctx: ctx._.flags & 0xffffffff),
    'name' / Computed(lambda ctx: predefined_names[ctx.type]),
    'obj' / Array(
        this.count,
        LazyBound(lambda: Switch(lambda ctx: ctx.type,
                                 kcdata_types_structures,
                                 default=GreedyBytes))),
)
type_array_pad4 = Struct(
    'flags_type' / Computed(lambda ctx: (ctx._.flags >> 32) & 0xffffffff),
    'type' /
    Computed(lambda ctx: kcdata_types_enum.decmapping[ctx.flags_type]),
    'count' / Computed(lambda ctx: ctx._.flags & 0xffffffff),
    'name' / Computed(lambda ctx: predefined_names[ctx.type]),
    'obj' / Array(
        this.count,
        LazyBound(lambda: Switch(lambda ctx: ctx.type,
                                 kcdata_types_structures,
                                 default=GreedyBytes))),
    Padding(4),
)
Esempio n. 6
0
    "was_same_owner" / Int16ul, "indirect_fire_flag" / Byte,
    "move_sprite_id" / Int16ul, "fight_sprite_id" / Int16ul,
    "wait_sprite_id" / Int16ul, "last_target_position" / vector)

unit_action = Struct(
    "type" / Int16ul, "data" / If(
        lambda ctx: ctx.type > 0,
        Struct(
            "state" / IfThenElse(
                lambda ctx: find_version(ctx) in [Version.AOK, Version.AOC],
                Byte, Int32ul), "target_object_pointer" / Int32sl,
            "target_object_pointer2" / Int32sl, "target_object_id" / Int32sl,
            "target_object_id_2" / Int32sl, "position" / vector,
            "timer" / Float32l, "target_moved_state" / Byte,
            "task_id" / Int16ul, "sub_action_value" / Byte, "sub_actions" /
            LazyBound(lambda x: action_list), "sprite_id" / Int16sl,
            Embedded("additional" / Switch(lambda ctx: ctx._.type, {
                1: move_to,
                3: enter,
                9: attack,
                21: make
            },
                                           default=Pass)))))

action_list = "action_list" / Struct("actions" / RepeatUntil(
    lambda x, lst, ctx: lst[-1].type == 0, unit_action))

action = "action" / Struct(
    Embedded(base_moving), "waiting" / Byte, "command_flag" / Byte,
    "selected_group_info" / If(lambda ctx: find_version(ctx) != Version.AOK,
                               Int16ul), "actions" / action_list)
Esempio n. 7
0
        l = []
        key = evaluate(self.key, context)
        for i in obj:
            l.append(i ^ key)
        return bytes(l)

    def _encode(self, obj, context, path):
        l = []
        key = evaluate(self.key, context)
        for i in obj:
            l.append(i ^ key)
        return bytes(l)


String = Struct(
    "size" / LazyBound(lambda: LuaSize_t), "str" / StrAdapter(
        (this.size * 13 + 55) & 0xff, Bytes(this.size)))

GlobalHead = Struct("signature" / Const(b"\x1bFate/Z\x1b"),
                    "version" / Version, "format" / Format, "endian" / Endian,
                    "size_int" / Int8ul, "size_size_t" / Int8ul,
                    "size_instruction" / Int8ul, "size_lua_number" / Int8ul,
                    "lua_num_valid" / Byte)

ProtoHead = Struct("numparams" / Int8ul, "source" / String, "nups" / Int8ul,
                   "linedefined" / Int32ul, "is_vararg" / Int8ul,
                   "lastlinedefined" / Int32ul, "maxstacksize" / Int8ul)


class InstrctionAdapter(Adapter):
    def _decode(self, obj, context, path):
Esempio n. 8
0
)

unit_action = Struct(
    "type"/Int16ul,
    "data"/If(lambda ctx: ctx.type > 0, Struct(
        "state"/IfThenElse(lambda ctx: find_version(ctx) in [Version.AOK, Version.AOC, Version.HD], Byte, Int32ul),
        "target_object_pointer"/Int32sl,
        "target_object_pointer2"/Int32sl,
        "target_object_id"/Int32sl,
        "target_object_id_2"/Int32sl,
        "position"/vector,
        "timer"/Float32l,
        "target_moved_state"/Byte,
        "task_id"/Int16ul,
        "sub_action_value"/Byte,
        "sub_actions"/LazyBound(lambda x: action_list),
        "sprite_id"/Int16sl,
        Embedded("additional"/Switch(lambda ctx: ctx._.type, {
            1: move_to,
            3: enter,
            9: attack,
            21: make
        }, default=Pass))
    ))
)

action_list = "action_list"/Struct(
    "actions"/RepeatUntil(lambda x,lst,ctx: lst[-1].type == 0, unit_action)
)

action = "action"/Struct(
Esempio n. 9
0
            Struct(
                'data',
                String('prgName', 28, padchar='\0'),
                Array(lambda ctx: ctx['_']['count'], BFloat32('params')),
            ),
            'FXP_OPAQUE_CHUNK':
            Struct(
                'data',
                String('prgName', 28, padchar='\0'),
                UBInt32('size'),
                Bytes('chunk', lambda ctx: ctx['size']),
            ),
            'FXB_REGULAR':
            Struct(
                'data',
                Bytes('future', 128),  # zeros
                # Array of FXP_PARAMS vst2preset
                Array(lambda ctx: ctx['_']['count'],
                      LazyBound('presets', lambda: vst2preset)),
            ),
            'FXB_OPAQUE_CHUNK':
            Struct(
                'data',
                Bytes('future', 128),  # zeros
                UBInt32('size'),
                # Unknown format of internal chunk
                Bytes('chunk', lambda ctx: ctx['size']),
            ),
        }),
)
Esempio n. 10
0
    HEXINT32 = 20
    HEXINT64 = 21
    COUNTEDSTRING = 22
    COUNTEDANSISTRING = 23
    STRUCT = 24
    COUNTEDBINARY = 25

    CCOUNT = 32
    VCCOUNT = 64
    CHAIN = 128


TlMetaDataField = Struct(
    "name" / CString("ascii"), "tag_in" / Int8ul,
    "tag_out" / If(lambda this: this.tag_in & TagIn.CHAIN.value,
                   LazyBound(lambda: Int8ul)))

TlMetaData = Struct("size" / Int16ul, "tag" / Int8ul,
                    "name" / CString("ascii"),
                    "fields" / GreedyRange(TlMetaDataField))


def build_tracelogging(event):
    """
    Build tracelogging based on the source event
    Check if event have an extended
    :param event: event that encompass Tracelogging data
    """
    if event.extended_data is not None:
        for extended_data in event.extended_data:
            if extended_data.ext_type == 11:
Esempio n. 11
0
    'WIPTag',
    'name' / WIPString,
    'type' / WIPTagType,
    'data_start' / Int64sl,
    'data_end' / Int64sl,
    # 'start'/Tell,
    # OneOf(Computed(this.start == this.data_start), [True]),
    'data_size' / Computed(this.data_end - this.data_start),
    'data' / If(
        this.data_end > this.data_start,
        Switch(
            this.type,
            dict(
                WIP_TAG_LIST=RepeatUntil(
                    lambda obj, ctx: obj.data_end >= ctx.data_end,
                    LazyBound(lambda: WIPTag)),
                WIP_TAG_EXTENDED=Bytes(10),
                WIP_TAG_DOUBLE=Float64l,
                WIP_TAG_FLOAT=Float32l,
                WIP_TAG_INT64=Int64sl,
                WIP_TAG_INT32=Array(this.data_size // 4, Int32sl),
                WIP_TAG_UINT32=Array(this.data_size // 4, Int32ul),
                WIP_TAG_CHAR=Array(this.data_size, Int8ul),
                WIP_TAG_BOOL=Int8ul,
                WIP_TAG_STRING=WIPString,
            ))),
    'end' / Tell,
    # pad to get to data_end
    Padding(this.data_end - this.end),
)
Esempio n. 12
0
		tuple : 105,
		etString : 107,
		list : 108,
		Binary : 109,
		long : 111,
		Fun : 112,
		MFA : 113,
		map : 116,
		BitBinary : 77,
	}
	if obj == []:
		return 106
	return mapping[obj.__class__]

# Recurrent term
term_ = LazyBound(lambda: term)

atom_cache_ref = ExprAdapter(Int8ub,
		encoder=lambda obj, ctx: obj.index,
		decoder=lambda obj, ctx: AtomCacheReference(obj))
small_integer = Int8ub
integer = Int32sb
float_ = ExprAdapter(PaddedString(31, encoding="ascii"),
		encoder=lambda obj, ctx: u"{:.20e}    ".format(obj),
		decoder=lambda obj, ctx: float(obj))
atom = PascalString(lengthfield=Int16ub, encoding="latin1")
reference = ExprAdapter(Sequence("node" / term_,
		"id" / Int32ub,
		"creation" / Int8ub),
		encoder=lambda obj, ctx: (obj.node, obj.id, obj.creation),
		decoder=lambda obj, ctx: Reference(*obj))
Esempio n. 13
0
class FNVPlugin(BasePlugin):
    """The plugin for Fallout: New Vegas.

    This plugin structure *should* handle plugins for the games:
        - Fallout 3
        - Fallout: New Vegas

    Note:
        This structure *currently* reads all data on initialization.
        This may appear as *slower* initialization times for larger plugins.
        Should be fixed by
        `lazy constructs <https://construct.readthedocs.io/en/latest/lazy.html>`_
        when they become more stable.

    **Credit:**
        - `FopDoc <https://tes5edit.github.io/fopdoc/FalloutNV/Records.html>`_
    """

    subrecord_struct = Struct(
        "type" / PaddedString(4, "utf8"),
        "data_size" / Int16ul,
        "data" / Bytes(lambda this: this.data_size),
        "parsed"
        / Computed(
            lambda this: FNVPlugin.parse_subrecord(
                this._.id, this._.type, this.type, this.data
            )
        ),
    )
    """The structure for FO3/FNV subrecords.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV subrecords
    """

    record_struct = Struct(
        "type" / PaddedString(4, "utf8"),
        "data_size" / Int32ul,
        "flags"
        / FlagsEnum(
            Int32ul,
            master=0x00000001,
            _unknown_0=0x00000002,
            _unknown_1=0x00000004,
            _unknown_2=0x00000008,
            form_initialized=0x00000010,
            deleted=0x00000020,
            constant=0x00000040,
            fire_disabled=0x00000080,
            inaccessible=0x00000100,
            casts_shadows=0x00000200,
            persistent=0x00000400,
            initially_disabled=0x00000800,
            ignored=0x00001000,
            no_voice_filter=0x00002000,
            cannot_save=0x00004000,
            visible_when_distant=0x00008000,
            random_anim_start=0x00010000,
            dangerous=0x00020000,
            compressed=0x00040000,
            cant_wait=0x00080000,
            _unknown_3=0x00100000,
            _unknown_4=0x00200000,
            _unknown_5=0x00400000,
            _unknown_6=0x00800000,
            destructible=0x01000000,
            obstacle=0x02000000,
            navmesh_filter=0x04000000,
            navmesh_box=0x08000000,
            non_pipboy=0x10000000,
            child_can_use=0x20000000,
            navmesh_ground=0x40000000,
            _unknown_7=0x80000000,
        ),
        "id" / Int32ul,
        "revision" / Int32ul,
        "version" / Int16ul,
        "_unknown_0" / Int16ul,
        # NOTE: ignores compressed data size as it is handled by GreedyBytes
        If(lambda this: this.flags.compressed, Padding(4)),
        "data"
        / IfThenElse(
            lambda this: this.flags.compressed,
            Compressed(Bytes(lambda this: this.data_size), "zlib"),
            Bytes(lambda this: this.data_size),
        ),
        "subrecords"
        / Computed(
            lambda this: GreedyRange(FNVPlugin.subrecord_struct).parse(
                this.data, id=this.id, type=this.type
            )
        ),
    )
    """The structure for FO3/FNV records.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV records
    """

    # TODO: instead of using ``GreedyRange`` to handle parsing unknown length lists,
    # should probably use other repeaters to avoid messy construct debugging
    # (will always raise exception when expects record type to exist, but gets 0 bytes)
    group_struct = Struct(
        "type" / Const(b"GRUP"),
        "group_size" / Int32ul,
        # TODO: find a better way of lazily building ``label`` in place
        # instead of computing it later
        # NOTE: deferred until group_type is determined
        "_label" / Bytes(4),
        "group_type"
        / Enum(
            Int32sl,
            top_level=0,
            world_children=1,
            interior_cell_block=2,
            interior_cell_subblock=3,
            exterior_cell_block=4,
            exterior_cell_subblock=5,
            cell_children=6,
            topic_children=7,
            cell_persistent_children=8,
            cell_temporary_children=9,
            cell_visible_distant_children=10,
        ),
        "label"
        / Computed(
            lambda this: Switch(
                this.group_type,
                {
                    "top_level": PaddedString(4, "utf8"),
                    "world_children": FNVFormID(["WRLD"]),
                    "interior_cell_block": Int32sl,
                    "interior_cell_subblock": Int32sl,
                    "exterior_cell_block": Struct("y" / Int8sl, "x" / Int8sl),
                    "exterior_cell_subblock": Struct("y" / Int8sl, "x" / Int8sl),
                    "cell_children": FNVFormID(["CELL"]),
                    "topic_children": FNVFormID(["DIAL"]),
                    "cell_persistent_children": FNVFormID(["CELL"]),
                    "cell_temporary_children": FNVFormID(["CELL"]),
                    "cell_visible_distant_children": FNVFormID(["CELL"]),
                },
                default=GreedyBytes,
            ).parse(this._label)
        ),
        "stamp" / Int16ul,
        "_unknown_0" / Bytes(6),
        "data" / Bytes(lambda this: this.group_size - 24),
        "subgroups"
        / If(
            lambda this: (len(this.data) > 4 and this.data[:4] == b"GRUP"),
            Computed(
                lambda this: GreedyRange(
                    LazyBound(lambda: FNVPlugin.group_struct)
                ).parse(this.data)
            ),
        ),
        "records"
        / If(
            lambda this: this.subgroups is None,
            Computed(
                lambda this: GreedyRange(FNVPlugin.record_struct).parse(this.data)
            ),
        ),
    )
    """The structure for FO3/FNV groups.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV groups
    """

    plugin_struct = Struct(
        "header" / record_struct * "Plugin header record",
        "groups" / GreedyRange(group_struct) * "Plugin groups",
    )
    """The structure for FO3/FNV plugins.

    Returns:
        :class:`~construct.core.Struct`: The structure of FO3/FNV plugins
    """

    # NOTE: working record is mangaled in order to protect state during
    # subrecord parsing for record state
    __working_record = {}

    @classmethod
    def can_handle(cls, filepath: str) -> bool:
        """Determines if a given file can be handled by the plugin.

        Args:
            filepath (str): The filepath to evaluate

        Raises:
            FileNotFoundError: When the given `filepath` cannot be found

        Returns:
            bool: True if file can be handled, otherwise False
        """

        if not os.path.isfile(filepath):
            raise FileNotFoundError(f"file {filepath!r} does not exist")

        header = cls.record_struct.parse_file(filepath)

        # NOTE: must clear class working record after every "full" file parse
        # otherwise, subsequent parses will have fragmented data when trying to discover
        # and parse subrecords
        cls.__working_record = {}
        return header.type == "TES4" and header.version == 15

    @classmethod
    def parse_subrecord(
        cls,
        record_id: int,
        record_type: str,
        subrecord_type: str,
        subrecord_data: bytes,
        strict: bool = True,
    ) -> Container:
        """Parses a subrecord's data.

        Args:
            record_type (str): The parent record type
            subrecord_type (str): The subrecord type
            subrecord_data (bytes): The subrecord data to parse
            strict (bool): Defaults to True, If True, enforce strict subrecord discovery

        Returns:
            Container: The resulting parsed container
        """

        (record_type, subrecord_type) = (record_type.upper(), subrecord_type.upper())

        # handle reset of working record state
        if record_id not in cls.__working_record:
            cls.__working_record[record_id] = []

        record_subrecords = RecordMapping.get(record_type)
        if record_subrecords:
            (parsed, working_record) = record_subrecords.handle_working(
                subrecord_type,
                subrecord_data,
                cls.__working_record[record_id],
                strict=strict,
            )
            cls.__working_record[record_id].extend(working_record)
            return parsed
Esempio n. 14
0
    "BinaryArrayTypeEnum" / BinaryArrayTypeEnumeration,
    "Rank" / Int32ul,
    "Lengths" / Array(this.Rank, Int32ul),
    "LowerBounds" / If(this.BinaryArrayTypeEnum == BinaryArrayTypeEnumeration.SingleOffset or this.BinaryArrayTypeEnum == BinaryArrayTypeEnumeration.JaggedOffset or this.BinaryArrayTypeEnum == BinaryArrayTypeEnumeration.RectangularOffset, Array(this.Rank, Int32sl)),
    "TypeEnum" / BinaryTypeEnumeration,
    "Infos" / Switch(this.TypeEnum, {
        BinaryTypeEnumeration.Primitive: PrimitiveTypeEnumeration,
        BinaryTypeEnumeration.SystemClass: LengthPrefixedString,
        BinaryTypeEnumeration.Class: ClassTypeInfo,
        BinaryTypeEnumeration.PrimitiveArray: PrimitiveTypeEnumeration},
        default=None),
    "CountElts" / Computed(lambda ctx: functools.reduce(operator.mul, ctx.Lengths, 1)),
    "Values" / Array(this.CountElts, Switch(this.TypeEnum, {
            BinaryTypeEnumeration.Primitive: Switch(this.Infos, PrimitiveTypeParsers),
            BinaryTypeEnumeration.String: LengthPrefixedString,
            BinaryTypeEnumeration.PrimitiveArray: LazyBound(lambda: Record),
            BinaryTypeEnumeration.Class: LazyBound(lambda: Record),
            BinaryTypeEnumeration.SystemClass: LazyBound(lambda: Record),
        })))


# Records
SerializationHeaderRecord = Struct(
    "RecordTypeEnum" / RecordTypeEnum,
    "RootId" / Int32ul,
    "HeaderId" / Int32ul,
    "MajorVersion" / Int32ul,
    "MinorVersion" / Int32ul)

BinaryObjectString = Struct(
    "RecordTypeEnum" / RecordTypeEnum,
Esempio n. 15
0
SystemTraceMarker = Enum(
    Int8ul,
    SYSTEM_TRACE_MARKER_32=0x01,
    SYSTEM_TRACE_MARKER_64=0x02,
    COMPACT_TRACE_MARKER_32=0x03,
    COMPACT_TRACE_MARKER_64=0x04,
)

SystemTraceHeader = Struct(
    "start_mark" / Computed(lambda this: this._io.tell()),
    "marker" / wmi_trace_marker(SystemTraceMarker),
    "header" / WmiTracePacket,
    "thread_id" / Int32ul,
    "process_id" / Int32ul,
    "system_time" / Int64ul,
    "kernel_time" / If(lambda this: this.marker.type.enum in [SystemTraceMarker.SYSTEM_TRACE_MARKER_32, SystemTraceMarker.SYSTEM_TRACE_MARKER_64], LazyBound(lambda: Int32ul)),
    "user_time" / If(lambda this: this.marker.type.enum in [SystemTraceMarker.SYSTEM_TRACE_MARKER_32, SystemTraceMarker.SYSTEM_TRACE_MARKER_64], LazyBound(lambda: Int32ul)),
    "sizeof" / Computed(lambda this: this._io.tell() - this.start_mark)
)


SystemTraceRecord = Struct(
    "system_header" / SystemTraceHeader,
    "mof_data" / Bytes(lambda this: this.system_header.header.size - this.system_header.sizeof)
)


class System:
    """
    A System log from Windows Kernel
    """
Esempio n. 16
0
    HEXINT32 = 20
    HEXINT64 = 21
    COUNTEDSTRING = 22
    COUNTEDANSISTRING = 23
    STRUCT = 24
    COUNTEDBINARY = 25

    CCOUNT = 32
    VCCOUNT = 64
    CHAIN = 128


TlMetaDataField = Struct(
    "name" / CString("ascii"), "tag_in" / Int8ul,
    "tag_out" / If(lambda this: this.tag_in & TagIn.CHAIN.value,
                   LazyBound(lambda: Int8ul)),
    "unknown" / If(lambda this: this.tag_out and bool(this.tag_out & 0x80),
                   LazyBound(lambda: Int32ul)))

TlMetaData = Struct(
    "size" / Int16ul, "tag" / Int8ul,
    "unknown" / If(lambda this: this.tag & 0x80, LazyBound(lambda: Int8ul)),
    "name" / CString("ascii"), "fields" / GreedyRange(TlMetaDataField))


def build_tracelogging(event):
    """
    Build tracelogging based on the source event
    Check if event have an extended
    :param event: event that encompass Tracelogging data
    """