Pick type for packed_addresses (pack not working yet)

This commit is contained in:
ChillerDragon 2023-05-10 09:45:06 +02:00
parent 1b445c3a12
commit f7ab25ab78
14 changed files with 76 additions and 42 deletions

View file

@ -96,7 +96,7 @@ class SpecJson(TypedDict):
connless_messages: list[NetConnlessJson]
def gen_match_file_connless7(
messages: list[NetMessageJson]
messages: list[NetConnlessJson]
):
match_code: str = """# generated by scripts/generate_messages.py
from typing import Optional
@ -115,7 +115,7 @@ from twnet_parser.connless_message import ConnlessMessage
f" connless_{name_snake}\n"
match_code += f"""
def match_connless7(msg_id: list[int], data: bytes) -> ConnlessMessage:
def match_connless7(msg_id: bytes, data: bytes) -> ConnlessMessage:
msg: Optional[ConnlessMessage] = None
"""
@ -131,9 +131,11 @@ f"""
match_code += '\n\n if msg is None:\n'
match_code += ' '
match_code += 'raise ValueError('
match_code += 'raise ValueError(\n'
match_code += ' '
match_code += 'f"Error: unknown conless ' \
' message id={msg_id} data={data[0]}")\n'
' 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'
@ -224,8 +226,8 @@ def gen_unpack_members_connless7(msg: NetConnlessJson) -> str:
unpacker = 'be_uint16()'
elif member['type']['kind'] == 'uint8':
unpacker = 'uint8()'
elif member['type']['kind'] == 'packed_addresses': # TODO: packed_addresses
unpacker = 'int()'
elif member['type']['kind'] == 'packed_addresses':
unpacker = 'packed_addresses()'
else:
raise ValueError(f"Error: unknown type {member['type']}")
name = name_to_snake(member["name"])
@ -315,16 +317,17 @@ def gen_unpack_members(msg: NetMessageJson) -> str:
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': # TODO: packed_addresses
packer_deps.append('pack_int')
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')
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'
@ -472,8 +475,8 @@ def pack_field_connless7(member: NetConnlessMemberJson) -> str:
name: str = name_to_snake(member["name"])
field: str = f'self.{name}'
packer = 'int'
if member['type']['kind'] == 'packed_addresses': # TODO: packed
packer = 'int'
if member['type']['kind'] == 'packed_addresses':
packer = 'packed_addresses'
elif member['type']['kind'] == 'be_uint16':
packer = 'be_uint16'
elif member['type']['kind'] == 'uint8':
@ -549,8 +552,8 @@ class CodeGenerator():
ftype = 'int'
default = '-1'
if member['type']['kind'] == 'packed_addresses': # TODO: packed_addreses default value
ftype = 'int'
default = '0'
ftype = 'list[MastersrvAddr]'
default = '[]'
elif member['type']['kind'] == 'be_uint16': # TODO: be_uint16
ftype = 'int'
default = '0'
@ -689,7 +692,6 @@ class CodeGenerator():
print(f"Generating {file_path} ...")
out_file.write('# generated by scripts/generate_messages.py\n')
out_file.write('\n')
out_file.write('from typing import Literal\n\n')
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')
@ -704,7 +706,7 @@ class CodeGenerator():
for member in msg['members']:
ftype = 'int'
if member['type']['kind'] == 'packed_addresses': # TODO: packed_addreses default value
ftype = 'int'
ftype = 'list[MastersrvAddr]'
elif member['type']['kind'] == 'be_uint16': # TODO: be_uint16
ftype = 'int'
elif member['type']['kind'] == 'uint8': # TODO: uint8
@ -901,8 +903,8 @@ class CodeGenerator():
self.generate_msg(msg, 'game')
for msg in system_messages:
self.generate_msg(msg, 'system')
for msg in connless_messages:
self.generate_msg_connless(msg)
for connless_msg in connless_messages:
self.generate_msg_connless(connless_msg)
def main() -> None:
dirname = os.path.dirname(__file__)

View file

@ -1,4 +1,6 @@
from twnet_parser.packet import parse7
from twnet_parser.messages7.connless.list import MsgList
from twnet_parser.master_server import MastersrvAddr
def test_lis2_connless7():
data = b'\x21\xc2\xc7\x28\x7a\xa5' \
@ -100,3 +102,24 @@ def test_lis2_connless7():
assert packet.header.flags.compression is False
assert packet.header.flags.resend is False
assert packet.header.flags.connless is True
assert len(packet.messages) == 1
msg: MsgList = packet.messages[0]
assert len(msg.servers) == 74 # no idea if this is correct
server: MastersrvAddr
# TODO: those ports seem wrong for sure
server = msg.servers[0]
assert server.port == 27136
server = msg.servers[1]
assert server.port == 27648
server = msg.servers[2]
assert server.port == 28416
server = msg.servers[3]
assert server.port == 28672
server = msg.servers[4]
assert server.port == 28928

View file

@ -0,0 +1,11 @@
from typing import Annotated
class MastersrvAddr():
def __init__(
self,
ipaddr: Annotated[bytes, 16] = bytes(16),
port: int = 0
) -> None:
self.ipaddr: Annotated[bytes, 16] = ipaddr
self.port: int = port

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from twnet_parser.packer import Unpacker
from twnet_parser.packer import pack_be_uint16

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from typing import Literal

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from typing import Literal

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from typing import Literal

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from typing import Literal

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from twnet_parser.packer import Unpacker
from twnet_parser.packer import pack_be_uint16

View file

@ -1,30 +1,29 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from twnet_parser.packer import Unpacker
from twnet_parser.packer import pack_int
from twnet_parser.master_server import MastersrvAddr
from twnet_parser.packer import pack_packed_addresses
from typing import Literal
class MsgList(PrettyPrint):
def __init__(
self,
servers: int = 0
servers: list[MastersrvAddr] = []
) -> None:
self.message_type: Literal['connless'] = 'connless'
self.message_name: str = 'connless.list'
self.message_id: list[int] = [255, 255, 255, 255, 108, 105, 115, 50]
self.servers: int = servers
self.servers: list[MastersrvAddr] = servers
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id
def unpack(self, data: bytes) -> bool:
unpacker = Unpacker(data)
self.servers = unpacker.get_int()
self.servers = unpacker.get_packed_addresses()
return True
def pack(self) -> bytes:
return pack_int(self.servers)
return pack_packed_addresses(self.servers)

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from typing import Literal

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from twnet_parser.packer import Unpacker
from twnet_parser.packer import pack_uint8

View file

@ -1,7 +1,5 @@
# generated by scripts/generate_messages.py
from typing import Literal
from twnet_parser.pretty_print import PrettyPrint
from typing import Literal

View file

@ -2,6 +2,8 @@
from typing import Final
from twnet_parser.master_server import MastersrvAddr
# Before chaning the current packer code to extend it
# Consider having two packers
#
@ -40,6 +42,14 @@ class Unpacker():
self.idx = end
return data
def get_packed_addresses(self) -> list[MastersrvAddr]:
servers: list[MastersrvAddr] = []
while len(self.data()) >= 18:
ipaddr = self.get_raw(16)
port = self.get_be_uint16() # TODO: i randomly assumed this would work
servers.append(MastersrvAddr(ipaddr, int(port)))
return servers
def get_uint8(self) -> int:
res = self.byte()
self.idx += 1
@ -141,6 +151,13 @@ def pack_be_uint16(num: int) -> bytes:
def pack_uint8(num: int) -> bytes:
return bytes([num])
def pack_packed_addresses(servers: list[MastersrvAddr]) -> bytes:
res: bytes = b''
for server in servers:
res += server.ipaddr
res += pack_be_uint16(server.port)
return res
def pack_str(data: str) -> bytes:
return data.encode('utf-8') + b'\x00'