diff --git a/scripts/generate_messages.py b/scripts/generate_messages.py index 0d4b06d..f901e00 100755 --- a/scripts/generate_messages.py +++ b/scripts/generate_messages.py @@ -49,6 +49,12 @@ class ArrayMemberTypeJson(TypedDict): # strings disallow_cc: bool + # array in array only for de client info + # type forward declaration or self reference is not supported + # so hack it with a string + member_type: 'ArrayMemberTypeJson' + count: int + class NetConnlessMemberTypeJson(TypedDict): kind: KINDCONLESS @@ -295,6 +301,20 @@ def gen_unpack_members(msg: NetMessageJson) -> str: unpacker = 'int() == 1' elif arr_member['kind'] in ('int32', 'tick'): unpacker = 'int()' + elif arr_member['kind'] == 'array': + sub_size: int = arr_member['count'] + sub_arr_member = arr_member['member_type'] + unpacker = 'int()' + if sub_arr_member['kind'] == 'int32': + name = name_to_snake(member["name"]) + res += f' for i in range(0, {size}):\n' + res += f' sub: list[int] = []\n' + res += f' for k in range(0, {sub_size}):\n' + res += f' sub[k] = unpacker.get_{unpacker}\n' + res += f' self.{name}[i] = sub\n' + continue + else: + raise ValueError(f"Error: unknown sub array member type {member['type']}") else: raise ValueError(f"Error: unknown array member type {member['type']}") name = name_to_snake(member["name"]) @@ -350,9 +370,11 @@ def get_dependencies_connless7(msg: NetConnlessJson) -> str: ', '.join(sorted(set(typing_deps))) + '\n' return res -def get_dependencies(msg: NetMessageJson) -> str: +def get_dependencies(msg: NetMessageJson, typing_dep: Optional[str] = 'Literal') -> str: packer_deps: list[str] = [] - typing_deps: list[str] = ['Literal'] + typing_deps: list[str] = [] + if typing_dep: + typing_deps.append(typing_dep) need_enums: bool = False for member in msg['members']: if member['type']['kind'] == 'string': @@ -396,6 +418,11 @@ def get_dependencies(msg: NetMessageJson) -> str: packer_deps.append('pack_int') elif arr_member['kind'] in ('int32', 'tick'): packer_deps.append('pack_int') + elif arr_member['kind'] == 'array': + if arr_member['member_type']['kind'] == 'int32': + packer_deps.append('pack_int') + else: + raise ValueError(f"Error: unknown sub array member type {member['type']}") else: raise ValueError(f"Error: unknown array member type {member['type']}") elif member['type']['kind'] == 'flags': # TODO: think about flags @@ -457,6 +484,12 @@ def pack_field(member: NetMessageMemberJson) -> str: packer = 'int' elif arr_member['kind'] in ('int32', 'tick'): packer = 'int' + elif arr_member['kind'] == 'array': + sub_arr_member = arr_member['member_type'] + if sub_arr_member['kind'] == 'int32': + return f"b''.join([b''.join([pack_{packer}(x) for x in sub]) for sub in {field}])" + else: + raise ValueError(f"Error: unknown sub array member type {member['type']}") else: raise ValueError(f"Error: unknown array member type {member['type']}") return f"b''.join([pack_{packer}(x) for x in {field}])" @@ -664,7 +697,7 @@ class CodeGenerator(): else: raise ValueError( \ f"Error: msg {name_to_snake(member['name'])} " \ - f"has unknown array sub member type {arr_member['type']}") + f"has unknown array sub member type {member['type']}") else: raise ValueError( \ f"Error: msg {name_to_snake(member['name'])} " \ @@ -751,6 +784,10 @@ class CodeGenerator(): out_file.write('# generated by scripts/generate_messages.py\n') out_file.write('\n') out_file.write('from twnet_parser.pretty_print import PrettyPrint\n') + if len(obj['members']) > 0: + out_file.write('from twnet_parser.packer import Unpacker\n') + out_file.write(get_dependencies(obj, None)) + out_file.write('\n') out_file.write(f'class Obj{name_camel}(PrettyPrint):\n') comma: str = '' if len(obj['members']) > 0: @@ -771,6 +808,17 @@ class CodeGenerator(): out_file.write('\n') self.generate_field_assignments_in_initialize(obj, out_file) out_file.write('\n') + out_file.write(' # first byte of data\n') + out_file.write(' # has to be the first byte of the message payload\n') + out_file.write(' # NOT the chunk header and NOT the message id\n') + out_file.write(' def unpack(self, data: bytes) -> bool:\n') + if len(obj['members']) > 0: + out_file.write(' unpacker = Unpacker(data)\n') + out_file.write(gen_unpack_members(obj)) + out_file.write(' return True\n') + out_file.write('\n') + out_file.write(' def pack(self) -> bytes:\n') + out_file.write(gen_pack_return(obj)) def generate_msg_connless( self,