Generate pack() code for messages
This commit is contained in:
parent
992a855a57
commit
5f76de93a9
|
@ -66,6 +66,7 @@ def generate_msg(msg: GameMessageJson) -> None:
|
||||||
out_file.write('\n')
|
out_file.write('\n')
|
||||||
out_file.write('from twnet_parser.pretty_print import PrettyPrint\n')
|
out_file.write('from twnet_parser.pretty_print import PrettyPrint\n')
|
||||||
out_file.write('from twnet_parser.packer import Unpacker\n')
|
out_file.write('from twnet_parser.packer import Unpacker\n')
|
||||||
|
out_file.write(get_dependencies(msg))
|
||||||
out_file.write('\n')
|
out_file.write('\n')
|
||||||
out_file.write(f'class {name_camel}(PrettyPrint):\n')
|
out_file.write(f'class {name_camel}(PrettyPrint):\n')
|
||||||
out_file.write(' def __init__(\n')
|
out_file.write(' def __init__(\n')
|
||||||
|
@ -113,6 +114,8 @@ def generate_msg(msg: GameMessageJson) -> None:
|
||||||
out_file.write(',\n'.join(args) + '\n')
|
out_file.write(',\n'.join(args) + '\n')
|
||||||
out_file.write(' ) -> None:\n')
|
out_file.write(' ) -> None:\n')
|
||||||
out_file.write(f" self.message_name = '{name_snake}'\n")
|
out_file.write(f" self.message_name = '{name_snake}'\n")
|
||||||
|
out_file.write(" self.system_message = False\n")
|
||||||
|
out_file.write('\n')
|
||||||
for member in msg['members']:
|
for member in msg['members']:
|
||||||
# {'name': ['message'], 'type': {'kind': 'string', 'disallow_cc': False}}
|
# {'name': ['message'], 'type': {'kind': 'string', 'disallow_cc': False}}
|
||||||
ftype = 'int'
|
ftype = 'int'
|
||||||
|
@ -178,8 +181,77 @@ def generate_msg(msg: GameMessageJson) -> None:
|
||||||
out_file.write(' return True\n')
|
out_file.write(' return True\n')
|
||||||
out_file.write('\n')
|
out_file.write('\n')
|
||||||
out_file.write(' def pack(self) -> bytes:\n')
|
out_file.write(' def pack(self) -> bytes:\n')
|
||||||
out_file.write(" return b'todo'\n")
|
out_file.write(gen_pack_return(msg))
|
||||||
|
|
||||||
|
def get_dependencies(msg: GameMessageJson) -> str:
|
||||||
|
packer_deps: list[str] = []
|
||||||
|
for member in msg['members']:
|
||||||
|
if member['type']['kind'] == 'string': # TODO: sanitize cc
|
||||||
|
packer_deps.append('pack_str')
|
||||||
|
elif member['type']['kind'] == 'raw':
|
||||||
|
pass
|
||||||
|
# {"name": ["mode"], "type": {"kind": "enum", "enum": ["chat"]}},
|
||||||
|
elif member['type']['kind'] == 'enum':
|
||||||
|
packer_deps.append('pack_int')
|
||||||
|
elif member['type']['kind'] in ('int32', 'tick'):
|
||||||
|
packer_deps.append('pack_int')
|
||||||
|
elif member['type']['kind'] == 'boolean':
|
||||||
|
packer_deps.append('pack_int')
|
||||||
|
elif member['type']['kind'] == 'tune_param': # TODO: think about tune params
|
||||||
|
packer_deps.append('pack_int')
|
||||||
|
elif member['type']['kind'] == 'snapshot_object':
|
||||||
|
# TODO: think about snapshot_object
|
||||||
|
packer_deps.append('pack_int')
|
||||||
|
elif member['type']['kind'] == 'array': # TODO: think about array
|
||||||
|
packer_deps.append('pack_int')
|
||||||
|
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
||||||
|
packer_deps.append('pack_int')
|
||||||
|
else:
|
||||||
|
print(f"Error: unknown type {member['type']}")
|
||||||
|
exit(1)
|
||||||
|
if len(packer_deps) == 0:
|
||||||
|
return ''
|
||||||
|
return 'from twnet_parser.packer import ' + \
|
||||||
|
', '.join(set(packer_deps)) + '\n'
|
||||||
|
|
||||||
|
def pack_field(member: GameMessageMemberJson) -> str:
|
||||||
|
name: str = name_to_snake(member["name"])
|
||||||
|
packer = 'int'
|
||||||
|
if member['type']['kind'] == 'string': # TODO: sanitize cc
|
||||||
|
packer = 'str'
|
||||||
|
elif member['type']['kind'] == 'raw':
|
||||||
|
return f'self.{name}'
|
||||||
|
# {"name": ["mode"], "type": {"kind": "enum", "enum": ["chat"]}},
|
||||||
|
elif member['type']['kind'] == 'enum':
|
||||||
|
packer = 'int'
|
||||||
|
elif member['type']['kind'] in ('int32', 'tick'):
|
||||||
|
packer = 'int'
|
||||||
|
elif member['type']['kind'] == 'boolean':
|
||||||
|
packer = 'int'
|
||||||
|
elif member['type']['kind'] == 'tune_param': # TODO: think about tune params
|
||||||
|
packer = 'int'
|
||||||
|
elif member['type']['kind'] == 'snapshot_object':
|
||||||
|
# TODO: think about snapshot_object
|
||||||
|
packer = 'int'
|
||||||
|
elif member['type']['kind'] == 'array': # TODO: think about array
|
||||||
|
packer = 'int'
|
||||||
|
elif member['type']['kind'] == 'flags': # TODO: think about flags
|
||||||
|
packer = 'int'
|
||||||
|
else:
|
||||||
|
print(f"Error: unknown type {member['type']}")
|
||||||
|
exit(1)
|
||||||
|
return f'pack_{packer}(self.{name})'
|
||||||
|
|
||||||
|
def gen_pack_return(msg: GameMessageJson) -> str:
|
||||||
|
members: list[GameMessageMemberJson] = msg['members']
|
||||||
|
if len(members) == 0:
|
||||||
|
return " return b''"
|
||||||
|
if len(members) == 1:
|
||||||
|
return f' return {pack_field(members[0])}'
|
||||||
|
mem_strs: list[str] = [
|
||||||
|
f' {pack_field(member)}' for member in members[1:]]
|
||||||
|
return f" return {pack_field(members[0])} + \\\n" + \
|
||||||
|
' + \\\n'.join(mem_strs)
|
||||||
|
|
||||||
def generate(spec: str) -> None:
|
def generate(spec: str) -> None:
|
||||||
print(f"generating classes from {spec} ...")
|
print(f"generating classes from {spec} ...")
|
||||||
|
|
|
@ -10,6 +10,7 @@ from twnet_parser.chunk_header import ChunkHeader
|
||||||
class TodoMessage():
|
class TodoMessage():
|
||||||
def __init__(self, name: str) -> None:
|
def __init__(self, name: str) -> None:
|
||||||
self.message_name = name
|
self.message_name = name
|
||||||
|
self.system_message = False
|
||||||
self.header: ChunkHeader
|
self.header: ChunkHeader
|
||||||
def unpack(self, data: bytes) -> bool:
|
def unpack(self, data: bytes) -> bool:
|
||||||
return len(data) > 0
|
return len(data) > 0
|
||||||
|
|
|
@ -4,6 +4,7 @@ from twnet_parser.chunk_header import ChunkHeader
|
||||||
|
|
||||||
class NetMessage(Protocol):
|
class NetMessage(Protocol):
|
||||||
message_name: str
|
message_name: str
|
||||||
|
system_message: bool
|
||||||
header: ChunkHeader
|
header: ChunkHeader
|
||||||
def unpack(self, data: bytes) -> bool:
|
def unpack(self, data: bytes) -> bool:
|
||||||
...
|
...
|
||||||
|
|
Loading…
Reference in a new issue