Adapt gen script to support 0.6
This commit is contained in:
parent
d491f60937
commit
e4e1c40d85
|
@ -98,115 +98,6 @@ class SpecJson(TypedDict):
|
|||
connless_messages: list[NetConnlessJson]
|
||||
snapshot_objects: list[NetMessageJson]
|
||||
|
||||
def gen_match_file_connless7(
|
||||
messages: list[NetConnlessJson]
|
||||
):
|
||||
match_code: str = """# generated by scripts/generate_messages.py
|
||||
from typing import Optional
|
||||
|
||||
import twnet_parser.msg7
|
||||
from twnet_parser.connless_message import ConnlessMessage
|
||||
|
||||
"""
|
||||
|
||||
msg: NetConnlessJson
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
match_code += f"import twnet_parser.messages7.connless" \
|
||||
f".{name_snake}" \
|
||||
" as \\\n" \
|
||||
f" connless_{name_snake}\n"
|
||||
|
||||
match_code += f"""
|
||||
def match_connless7(msg_id: bytes, data: bytes) -> ConnlessMessage:
|
||||
msg: Optional[ConnlessMessage] = None
|
||||
"""
|
||||
|
||||
if_ = 'if'
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
name_camel = name_to_camel(msg['name'])
|
||||
match_code += \
|
||||
f"""
|
||||
{if_} msg_id == twnet_parser.msg7.CONNLESS_{name_snake.upper()}:
|
||||
msg = connless_{name_snake}.Msg{name_camel}()"""
|
||||
if_ = 'elif'
|
||||
|
||||
match_code += '\n\n if msg is None:\n'
|
||||
match_code += ' '
|
||||
match_code += 'raise ValueError(\n'
|
||||
match_code += ' '
|
||||
match_code += 'f"Error: unknown conless ' \
|
||||
' message id={msg_id!r} data={data[0]}"\n'
|
||||
match_code += ' )\n'
|
||||
match_code += '\n'
|
||||
match_code += ' msg.unpack(data)\n'
|
||||
match_code += ' return msg\n'
|
||||
|
||||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
f'../twnet_parser/msg_matcher/connless7.py')
|
||||
with open(file_path, 'w') as out_file:
|
||||
print(f"Generating {file_path} ...")
|
||||
out_file.write(match_code)
|
||||
|
||||
def gen_match_file7(
|
||||
msg_type: Literal['system', 'game'],
|
||||
messages: list[NetMessageJson]
|
||||
):
|
||||
match_code: str = """# generated by scripts/generate_messages.py
|
||||
from typing import Optional
|
||||
|
||||
import twnet_parser.msg7
|
||||
from twnet_parser.net_message import NetMessage
|
||||
|
||||
"""
|
||||
|
||||
msg: NetMessageJson
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
match_code += f"import twnet_parser.messages7.{msg_type}" \
|
||||
f".{name_snake}" \
|
||||
" as \\\n" \
|
||||
f" {msg_type}7_{name_snake}\n"
|
||||
|
||||
match_code += f"""
|
||||
def match_{msg_type}7(msg_id: int, data: bytes) -> NetMessage:
|
||||
msg: Optional[NetMessage] = None
|
||||
"""
|
||||
|
||||
if_ = 'if'
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
name_camel = name_to_camel(msg['name'])
|
||||
match_code += \
|
||||
f"""
|
||||
{if_} msg_id == twnet_parser.msg7.{name_snake.upper()}:
|
||||
msg = {msg_type}7_{name_snake}.Msg{name_camel}()"""
|
||||
if_ = 'elif'
|
||||
|
||||
match_code += '\n\n if msg is None:\n'
|
||||
match_code += ' '
|
||||
match_code += 'raise ValueError('
|
||||
match_code += 'f"Error: unknown ' \
|
||||
+ msg_type + \
|
||||
' message id={msg_id} data={data[0]}")\n'
|
||||
match_code += '\n'
|
||||
match_code += ' msg.unpack(data)\n'
|
||||
match_code += ' return msg\n'
|
||||
|
||||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
f'../twnet_parser/msg_matcher/{msg_type}7.py')
|
||||
# if os.path.exists(file_path):
|
||||
# print(f"Warning: file already exists! {file_path}")
|
||||
# return
|
||||
with open(file_path, 'w') as out_file:
|
||||
print(f"Generating {file_path} ...")
|
||||
out_file.write(match_code)
|
||||
|
||||
def fix_name_conflict(name: str) -> str:
|
||||
# https://peps.python.org/pep-0008/#descriptive-naming-styles
|
||||
if name in ('pass', 'self'):
|
||||
|
@ -225,12 +116,16 @@ def gen_unpack_members_connless7(msg: NetConnlessJson) -> str:
|
|||
res: str = ''
|
||||
for member in msg['members']:
|
||||
unpacker = 'int()'
|
||||
name = name_to_snake(member["name"])
|
||||
if member['type']['kind'] == 'be_uint16':
|
||||
unpacker = 'be_uint16()'
|
||||
elif member['type']['kind'] == 'uint8':
|
||||
unpacker = 'uint8()'
|
||||
elif member['type']['kind'] == 'int32':
|
||||
unpacker = 'int()'
|
||||
elif member['type']['kind'] == 'int32_string':
|
||||
res += f' self.{name} = int(unpacker.get_str())\n'
|
||||
continue
|
||||
elif member['type']['kind'] == 'string':
|
||||
if member['type']['disallow_cc']:
|
||||
unpacker = 'str(SANITIZE_CC)'
|
||||
|
@ -242,7 +137,6 @@ def gen_unpack_members_connless7(msg: NetConnlessJson) -> str:
|
|||
unpacker = 'packed_addresses()'
|
||||
else:
|
||||
raise ValueError(f"Error: unknown type {member['type']}")
|
||||
name = name_to_snake(member["name"])
|
||||
res += f' self.{name} = unpacker.get_{unpacker}\n'
|
||||
return res
|
||||
|
||||
|
@ -308,13 +202,15 @@ def gen_unpack_members(msg: NetMessageJson) -> str:
|
|||
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 += ' 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']}")
|
||||
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"])
|
||||
|
@ -340,113 +236,6 @@ def gen_unpack_members(msg: NetMessageJson) -> str:
|
|||
res += f' self.{name} = unpacker.get_{unpacker}\n'
|
||||
return res
|
||||
|
||||
def get_dependencies_connless7(msg: NetConnlessJson) -> str:
|
||||
packer_deps: list[str] = []
|
||||
typing_deps: list[str] = ['Literal']
|
||||
res: str = ''
|
||||
for member in msg['members']:
|
||||
if member['type']['kind'] == 'packed_addresses':
|
||||
packer_deps.append('pack_packed_addresses')
|
||||
res += 'from twnet_parser.master_server import MastersrvAddr\n'
|
||||
elif member['type']['kind'] == 'uint8':
|
||||
packer_deps.append('pack_uint8')
|
||||
elif member['type']['kind'] == 'be_uint16':
|
||||
packer_deps.append('pack_be_uint16')
|
||||
elif member['type']['kind'] == 'int32':
|
||||
packer_deps.append('pack_int')
|
||||
elif member['type']['kind'] == 'serverinfo_client': # TODO: serverinfo_client
|
||||
pass # use pack raw
|
||||
elif member['type']['kind'] == 'string':
|
||||
packer_deps.append('pack_str')
|
||||
if member['type']['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
else:
|
||||
raise ValueError(f"Error: unknown type {member['type']}")
|
||||
if len(packer_deps) > 0:
|
||||
res += 'from twnet_parser.packer import ' + \
|
||||
', '.join(sorted(set(packer_deps))) + '\n'
|
||||
if len(typing_deps) > 0:
|
||||
res += 'from typing import ' + \
|
||||
', '.join(sorted(set(typing_deps))) + '\n'
|
||||
return res
|
||||
|
||||
def get_dependencies(msg: NetMessageJson, typing_dep: Optional[str] = 'Literal') -> str:
|
||||
packer_deps: list[str] = []
|
||||
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':
|
||||
packer_deps.append('pack_str')
|
||||
if member['type']['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
elif member['type']['kind'] == 'rest':
|
||||
pass
|
||||
elif member['type']['kind'] == 'sha256':
|
||||
typing_deps.append('Annotated')
|
||||
elif member['type']['kind'] == 'data':
|
||||
if member['type']['size'] == 'specified_before':
|
||||
typing_deps.append('Optional')
|
||||
else:
|
||||
raise ValueError(f"Error: unknown data size {member['type']}")
|
||||
# {"name": ["mode"], "type": {"kind": "enum", "enum": ["chat"]}},
|
||||
elif member['type']['kind'] == 'enum':
|
||||
need_enums = True
|
||||
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':
|
||||
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':
|
||||
packer_deps.append('pack_int')
|
||||
typing_deps.append('Annotated')
|
||||
arr_member: ArrayMemberTypeJson = member['type']['member_type']
|
||||
if arr_member['kind'] == 'string':
|
||||
packer_deps.append('pack_str')
|
||||
if arr_member['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
elif arr_member['kind'] == 'enum':
|
||||
need_enums = True
|
||||
packer_deps.append('pack_int')
|
||||
elif arr_member['kind'] == 'boolean':
|
||||
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
|
||||
packer_deps.append('pack_int')
|
||||
elif member['type']['kind'] == 'optional':
|
||||
if member['type']['inner']['kind'] == 'string':
|
||||
packer_deps.append('pack_str')
|
||||
if member['type']['inner']['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
elif member['type']['inner']['kind'] in ('int32', 'tick'):
|
||||
packer_deps.append('pack_int')
|
||||
else:
|
||||
raise ValueError(f"Error: unknown type {member['type']}")
|
||||
res: str = ''
|
||||
if len(packer_deps) > 0:
|
||||
res += 'from twnet_parser.packer import ' + \
|
||||
', '.join(sorted(set(packer_deps))) + '\n'
|
||||
if len(typing_deps) > 0:
|
||||
res += 'from typing import ' + \
|
||||
', '.join(sorted(set(typing_deps))) + '\n'
|
||||
if need_enums:
|
||||
res += 'import twnet_parser.enum7 as enum7\n'
|
||||
return res
|
||||
|
||||
def pack_field(member: NetMessageMemberJson) -> str:
|
||||
name: str = name_to_snake(member["name"])
|
||||
field: str = f'self.{name}'
|
||||
|
@ -532,6 +321,8 @@ def pack_field_connless7(member: NetMessageMemberJson) -> str:
|
|||
packer = 'str'
|
||||
elif member['type']['kind'] == 'int32':
|
||||
packer = 'int'
|
||||
elif member['type']['kind'] == 'int32_string':
|
||||
return f'pack_str(str({field}))'
|
||||
elif member['type']['kind'] == 'serverinfo_client': # TODO: serverinfo_client
|
||||
return f'self.{name}'
|
||||
else:
|
||||
|
@ -585,9 +376,235 @@ def get_default(field_path: str) -> Optional[str]:
|
|||
exit(1)
|
||||
|
||||
class CodeGenerator():
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, protocol_version: str) -> None:
|
||||
self.protocol_version = protocol_version
|
||||
self.game_enums: list[GameEnumJson] = []
|
||||
|
||||
def get_dependencies_connless(self, msg: NetConnlessJson) -> str:
|
||||
packer_deps: list[str] = []
|
||||
typing_deps: list[str] = ['Literal']
|
||||
res: str = ''
|
||||
for member in msg['members']:
|
||||
if member['type']['kind'] == 'packed_addresses':
|
||||
packer_deps.append('pack_packed_addresses')
|
||||
res += 'from twnet_parser.master_server import MastersrvAddr\n'
|
||||
elif member['type']['kind'] == 'uint8':
|
||||
packer_deps.append('pack_uint8')
|
||||
elif member['type']['kind'] == 'be_uint16':
|
||||
packer_deps.append('pack_be_uint16')
|
||||
elif member['type']['kind'] == 'int32':
|
||||
packer_deps.append('pack_int')
|
||||
elif member['type']['kind'] == 'int32_string':
|
||||
packer_deps.append('pack_str')
|
||||
elif member['type']['kind'] == 'serverinfo_client': # TODO: serverinfo_client
|
||||
pass # use pack raw
|
||||
elif member['type']['kind'] == 'string':
|
||||
packer_deps.append('pack_str')
|
||||
if member['type']['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
else:
|
||||
raise ValueError(f"Error: unknown type {member['type']}")
|
||||
if len(packer_deps) > 0:
|
||||
res += 'from twnet_parser.packer import ' + \
|
||||
', '.join(sorted(set(packer_deps))) + '\n'
|
||||
if len(typing_deps) > 0:
|
||||
res += 'from typing import ' + \
|
||||
', '.join(sorted(set(typing_deps))) + '\n'
|
||||
return res
|
||||
|
||||
def get_dependencies(
|
||||
self,
|
||||
msg: NetMessageJson,
|
||||
typing_dep: Optional[str] = 'Literal'
|
||||
) -> str:
|
||||
packer_deps: list[str] = []
|
||||
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':
|
||||
packer_deps.append('pack_str')
|
||||
if member['type']['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
elif member['type']['kind'] == 'rest':
|
||||
pass
|
||||
elif member['type']['kind'] == 'sha256':
|
||||
typing_deps.append('Annotated')
|
||||
elif member['type']['kind'] == 'data':
|
||||
if member['type']['size'] == 'specified_before':
|
||||
typing_deps.append('Optional')
|
||||
else:
|
||||
raise ValueError(f"Error: unknown data size {member['type']}")
|
||||
# {"name": ["mode"], "type": {"kind": "enum", "enum": ["chat"]}},
|
||||
elif member['type']['kind'] == 'enum':
|
||||
need_enums = True
|
||||
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':
|
||||
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':
|
||||
packer_deps.append('pack_int')
|
||||
typing_deps.append('Annotated')
|
||||
arr_member: ArrayMemberTypeJson = member['type']['member_type']
|
||||
if arr_member['kind'] == 'string':
|
||||
packer_deps.append('pack_str')
|
||||
if arr_member['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
elif arr_member['kind'] == 'enum':
|
||||
need_enums = True
|
||||
packer_deps.append('pack_int')
|
||||
elif arr_member['kind'] == 'boolean':
|
||||
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
|
||||
packer_deps.append('pack_int')
|
||||
elif member['type']['kind'] == 'optional':
|
||||
if member['type']['inner']['kind'] == 'string':
|
||||
packer_deps.append('pack_str')
|
||||
if member['type']['inner']['disallow_cc']:
|
||||
packer_deps.append('SANITIZE_CC')
|
||||
elif member['type']['inner']['kind'] in ('int32', 'tick'):
|
||||
packer_deps.append('pack_int')
|
||||
else:
|
||||
raise ValueError(f"Error: unknown type {member['type']}")
|
||||
res: str = ''
|
||||
if len(packer_deps) > 0:
|
||||
res += 'from twnet_parser.packer import ' + \
|
||||
', '.join(sorted(set(packer_deps))) + '\n'
|
||||
if len(typing_deps) > 0:
|
||||
res += 'from typing import ' + \
|
||||
', '.join(sorted(set(typing_deps))) + '\n'
|
||||
if need_enums:
|
||||
res += f'import twnet_parser.enum{self.protocol_version} as enum{self.protocol_version}\n'
|
||||
return res
|
||||
|
||||
def gen_match_file(
|
||||
self,
|
||||
msg_type: Literal['system', 'game'],
|
||||
messages: list[NetMessageJson]
|
||||
):
|
||||
match_code: str = f"""# generated by scripts/generate_messages.py
|
||||
from typing import Optional
|
||||
|
||||
import twnet_parser.msg{self.protocol_version}
|
||||
from twnet_parser.net_message import NetMessage
|
||||
|
||||
"""
|
||||
|
||||
msg: NetMessageJson
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
match_code += f"import twnet_parser.messages{self.protocol_version}.{msg_type}" \
|
||||
f".{name_snake}" \
|
||||
" as \\\n" \
|
||||
f" {msg_type}{self.protocol_version}_{name_snake}\n"
|
||||
|
||||
match_code += f"""
|
||||
def match_{msg_type}{self.protocol_version}(msg_id: int, data: bytes) -> NetMessage:
|
||||
msg: Optional[NetMessage] = None
|
||||
"""
|
||||
|
||||
if_ = 'if'
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
name_camel = name_to_camel(msg['name'])
|
||||
match_code += f"""
|
||||
{if_} msg_id == twnet_parser.msg{self.protocol_version}.{name_snake.upper()}:
|
||||
msg = {msg_type}{self.protocol_version}_{name_snake}.Msg{name_camel}()"""
|
||||
if_ = 'elif'
|
||||
|
||||
match_code += '\n\n if msg is None:\n'
|
||||
match_code += ' '
|
||||
match_code += 'raise ValueError('
|
||||
match_code += 'f"Error: unknown ' \
|
||||
+ msg_type + \
|
||||
' message id={msg_id} data={data[0]}")\n'
|
||||
match_code += '\n'
|
||||
match_code += ' msg.unpack(data)\n'
|
||||
match_code += ' return msg\n'
|
||||
|
||||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
f'../twnet_parser/msg_matcher/{msg_type}{self.protocol_version}.py')
|
||||
# if os.path.exists(file_path):
|
||||
# print(f"Warning: file already exists! {file_path}")
|
||||
# return
|
||||
with open(file_path, 'w') as out_file:
|
||||
print(f"Generating {file_path} ...")
|
||||
out_file.write(match_code)
|
||||
|
||||
def gen_match_file_connless(
|
||||
self,
|
||||
messages: list[NetConnlessJson]
|
||||
):
|
||||
match_code: str = f"""# generated by scripts/generate_messages.py
|
||||
from typing import Optional
|
||||
|
||||
import twnet_parser.msg{self.protocol_version}
|
||||
from twnet_parser.connless_message import ConnlessMessage
|
||||
|
||||
"""
|
||||
|
||||
msg: NetConnlessJson
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
match_code += f"import twnet_parser.messages{self.protocol_version}.connless" \
|
||||
f".{name_snake}" \
|
||||
" as \\\n" \
|
||||
f" connless_{name_snake}\n"
|
||||
|
||||
match_code += f"""
|
||||
def match_connless{self.protocol_version}(msg_id: bytes, data: bytes) -> ConnlessMessage:
|
||||
msg: Optional[ConnlessMessage] = None
|
||||
"""
|
||||
|
||||
if_ = 'if'
|
||||
for msg in messages:
|
||||
name_snake = name_to_snake(msg['name'])
|
||||
name_camel = name_to_camel(msg['name'])
|
||||
match_code += \
|
||||
f"""
|
||||
{if_} msg_id == twnet_parser.msg{self.protocol_version}.CONNLESS_{name_snake.upper()}:
|
||||
msg = connless_{name_snake}.Msg{name_camel}()"""
|
||||
if_ = 'elif'
|
||||
|
||||
match_code += '\n\n if msg is None:\n'
|
||||
match_code += ' '
|
||||
match_code += 'raise ValueError(\n'
|
||||
match_code += ' '
|
||||
match_code += 'f"Error: unknown conless ' \
|
||||
' message id={msg_id!r} data={data[0]}"\n'
|
||||
match_code += ' )\n'
|
||||
match_code += '\n'
|
||||
match_code += ' msg.unpack(data)\n'
|
||||
match_code += ' return msg\n'
|
||||
|
||||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
f'../twnet_parser/msg_matcher/connless{self.protocol_version}.py')
|
||||
with open(file_path, 'w') as out_file:
|
||||
print(f"Generating {file_path} ...")
|
||||
out_file.write(match_code)
|
||||
|
||||
def gen_init_member_header_def(
|
||||
self,
|
||||
member: NetMessageMemberJson,
|
||||
|
@ -650,9 +667,9 @@ class CodeGenerator():
|
|||
elif member['type']['kind'] == 'enum':
|
||||
enum_name: str = name_to_camel(member['type']['enum'])
|
||||
ftype = 'int'
|
||||
default = self.get_default_enum7(enum_name)
|
||||
default = f"enum7.{default}.value"
|
||||
elif member['type']['kind'] in ('int32', 'tick'):
|
||||
default = self.get_default_enum(enum_name)
|
||||
default = f"enum{self.protocol_version}.{default}.value"
|
||||
elif member['type']['kind'] in ('int32', 'tick', 'int32_string'):
|
||||
ftype = 'int'
|
||||
default = '0'
|
||||
elif member['type']['kind'] == 'boolean':
|
||||
|
@ -729,7 +746,7 @@ class CodeGenerator():
|
|||
args.append(f'{name}: {ftype} = {default}')
|
||||
return args
|
||||
|
||||
def write_init_method_header_connless7(
|
||||
def write_init_method_header_connless(
|
||||
self,
|
||||
out_file: TextIO,
|
||||
msg: NetConnlessJson,
|
||||
|
@ -777,7 +794,7 @@ class CodeGenerator():
|
|||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
f'../twnet_parser/snap/07/',
|
||||
f'../twnet_parser/snap/0{self.protocol_version}/',
|
||||
f'{name_snake}.py')
|
||||
with open(file_path, 'w') as out_file:
|
||||
print(f"Generating {file_path} ...")
|
||||
|
@ -786,7 +803,7 @@ class CodeGenerator():
|
|||
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(self.get_dependencies(obj, None))
|
||||
out_file.write('\n')
|
||||
out_file.write(f'class Obj{name_camel}(PrettyPrint):\n')
|
||||
comma: str = ''
|
||||
|
@ -804,7 +821,7 @@ class CodeGenerator():
|
|||
out_file.write(' ) -> None:\n')
|
||||
out_file.write(f" self.item_name: str = 'connless.{name_snake}'\n")
|
||||
out_file.write(f" self.type_id: int = {obj['id']}\n")
|
||||
out_file.write(f" self.id: int = 0\n")
|
||||
out_file.write( " self.id: int = 0\n")
|
||||
out_file.write('\n')
|
||||
self.generate_field_assignments_in_initialize(obj, out_file)
|
||||
out_file.write('\n')
|
||||
|
@ -829,7 +846,7 @@ class CodeGenerator():
|
|||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
f'../twnet_parser/messages7/connless/',
|
||||
f'../twnet_parser/messages{self.protocol_version}/connless/',
|
||||
f'{name_snake}.py')
|
||||
with open(file_path, 'w') as out_file:
|
||||
print(f"Generating {file_path} ...")
|
||||
|
@ -838,10 +855,10 @@ class CodeGenerator():
|
|||
out_file.write('from twnet_parser.pretty_print import PrettyPrint\n')
|
||||
if len(msg['members']) > 0:
|
||||
out_file.write('from twnet_parser.packer import Unpacker\n')
|
||||
out_file.write(get_dependencies_connless7(msg))
|
||||
out_file.write(self.get_dependencies_connless(msg))
|
||||
out_file.write('\n')
|
||||
out_file.write(f'class Msg{name_camel}(PrettyPrint):\n')
|
||||
self.write_init_method_header_connless7(out_file, msg, name_snake)
|
||||
self.write_init_method_header_connless(out_file, msg, name_snake)
|
||||
out_file.write(f" self.message_type: Literal['connless'] = 'connless'\n")
|
||||
out_file.write(f" self.message_name: str = 'connless.{name_snake}'\n")
|
||||
out_file.write(f" self.message_id: list[int] = {msg['id']}\n")
|
||||
|
@ -854,7 +871,7 @@ class CodeGenerator():
|
|||
ftype = 'int'
|
||||
elif member['type']['kind'] == 'uint8': # TODO: uint8
|
||||
ftype = 'int'
|
||||
elif member['type']['kind'] == 'int32':
|
||||
elif member['type']['kind'] in ('int32', 'int32_string'):
|
||||
ftype = 'int'
|
||||
elif member['type']['kind'] == 'string':
|
||||
ftype = 'str'
|
||||
|
@ -959,7 +976,7 @@ class CodeGenerator():
|
|||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
f'../twnet_parser/messages7/{game}/',
|
||||
f'../twnet_parser/messages{self.protocol_version}/{game}/',
|
||||
f'{name_snake}.py')
|
||||
# if os.path.exists(file_path):
|
||||
# print(f"Warning: file already exists! {file_path}")
|
||||
|
@ -972,7 +989,7 @@ class CodeGenerator():
|
|||
if len(msg['members']) > 0:
|
||||
out_file.write('from twnet_parser.packer import Unpacker\n')
|
||||
out_file.write('from twnet_parser.chunk_header import ChunkHeader\n')
|
||||
out_file.write(get_dependencies(msg))
|
||||
out_file.write(self.get_dependencies(msg))
|
||||
out_file.write('\n')
|
||||
out_file.write(f'class Msg{name_camel}(PrettyPrint):\n')
|
||||
self.write_init_method_header(out_file, msg, game, name_snake)
|
||||
|
@ -997,7 +1014,7 @@ class CodeGenerator():
|
|||
out_file.write(' def pack(self) -> bytes:\n')
|
||||
out_file.write(gen_pack_return(msg))
|
||||
|
||||
def get_default_enum7(self, enum_name: str) -> str:
|
||||
def get_default_enum(self, enum_name: str) -> str:
|
||||
"""
|
||||
enum_name has to be camel case
|
||||
|
||||
|
@ -1015,7 +1032,7 @@ class CodeGenerator():
|
|||
return f"{base}.{sub}"
|
||||
raise ValueError(f"Enum not found '{enum_name}'")
|
||||
|
||||
def gen_enum_file7(self) -> None:
|
||||
def gen_enum_file(self) -> None:
|
||||
enum_code: str = 'from enum import Enum\n\n'
|
||||
enum: GameEnumJson
|
||||
for enum in self.game_enums:
|
||||
|
@ -1034,7 +1051,7 @@ class CodeGenerator():
|
|||
dirname = os.path.dirname(__file__)
|
||||
file_path= os.path.join(
|
||||
dirname,
|
||||
'../twnet_parser/enum7.py')
|
||||
f'../twnet_parser/enum{self.protocol_version}.py')
|
||||
# if os.path.exists(file_path):
|
||||
# print(f"Warning: file already exists! {file_path}")
|
||||
# return
|
||||
|
@ -1052,10 +1069,10 @@ class CodeGenerator():
|
|||
system_messages: list[NetMessageJson] = spec_data['system_messages']
|
||||
connless_messages: list[NetConnlessJson] = spec_data['connless_messages']
|
||||
snapshot_objects: list[NetMessageJson] = spec_data['snapshot_objects']
|
||||
self.gen_enum_file7()
|
||||
gen_match_file7('game', game_messages)
|
||||
gen_match_file7('system', system_messages)
|
||||
gen_match_file_connless7(connless_messages)
|
||||
self.gen_enum_file()
|
||||
self.gen_match_file('game', game_messages)
|
||||
self.gen_match_file('system', system_messages)
|
||||
self.gen_match_file_connless(connless_messages)
|
||||
for msg in game_messages:
|
||||
self.generate_msg(msg, 'game')
|
||||
for msg in system_messages:
|
||||
|
@ -1064,22 +1081,42 @@ class CodeGenerator():
|
|||
self.generate_msg(msg, 'system')
|
||||
for connless_msg in connless_messages:
|
||||
self.generate_msg_connless(connless_msg)
|
||||
for obj in snapshot_objects:
|
||||
self.generate_snap_obj7(obj)
|
||||
# for obj in snapshot_objects:
|
||||
# self.generate_snap_obj7(obj)
|
||||
|
||||
class SpecInfo:
|
||||
def __init__(
|
||||
self,
|
||||
json_path: str,
|
||||
version_name: str
|
||||
) -> None:
|
||||
self.json_path = json_path
|
||||
self.version_name = version_name
|
||||
|
||||
def main() -> None:
|
||||
dirname = os.path.dirname(__file__)
|
||||
spec_07 = os.path.join(
|
||||
dirname,
|
||||
'../../libtw2/gamenet/generate/spec/teeworlds-0.7.5.json')
|
||||
if os.path.exists(spec_07):
|
||||
generator = CodeGenerator()
|
||||
generator.generate(spec_07)
|
||||
else:
|
||||
print(f"Error: file not found {spec_07}")
|
||||
print(" try running these commands")
|
||||
print("")
|
||||
print(" git clone git@github.com:heinrich5991/libtw2 ..")
|
||||
spec_infos: list[SpecInfo] = [
|
||||
SpecInfo(
|
||||
'../../libtw2/gamenet/generate/spec/teeworlds-0.7.5.json',
|
||||
'7'
|
||||
),
|
||||
SpecInfo(
|
||||
'../../libtw2/gamenet/generate/spec/teeworlds-0.6.json',
|
||||
'6'
|
||||
)
|
||||
]
|
||||
for spec_info in spec_infos:
|
||||
spec_file = os.path.join(
|
||||
dirname,
|
||||
spec_info.json_path)
|
||||
if os.path.exists(spec_file):
|
||||
generator = CodeGenerator(spec_info.version_name)
|
||||
generator.generate(spec_file)
|
||||
else:
|
||||
print(f"Error: file not found {spec_file}")
|
||||
print(" try running these commands")
|
||||
print("")
|
||||
print(" git clone git@github.com:heinrich5991/libtw2 ..")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
Loading…
Reference in a new issue