Add connless info (inf3)

This commit is contained in:
ChillerDragon 2023-05-12 17:17:07 +02:00
parent e60cd00735
commit 8c13ce6c2b
6 changed files with 193 additions and 25 deletions

View file

@ -125,7 +125,7 @@ def match_connless7(msg_id: bytes, data: bytes) -> ConnlessMessage:
name_camel = name_to_camel(msg['name'])
match_code += \
f"""
{if_} msg_id == twnet_parser.msg7.{name_snake.upper()}:
{if_} msg_id == twnet_parser.msg7.CONNLESS_{name_snake.upper()}:
msg = connless_{name_snake}.Msg{name_camel}()"""
if_ = 'elif'
@ -226,6 +226,15 @@ def gen_unpack_members_connless7(msg: NetConnlessJson) -> str:
unpacker = 'be_uint16()'
elif member['type']['kind'] == 'uint8':
unpacker = 'uint8()'
elif member['type']['kind'] == 'int32':
unpacker = 'int()'
elif member['type']['kind'] == 'string':
if member['type']['disallow_cc']:
unpacker = 'str(SANITIZE_CC)'
else:
unpacker = 'str()'
elif member['type']['kind'] == 'serverinfo_client': # TODO: serverinfo_client
unpacker = 'raw()'
elif member['type']['kind'] == 'packed_addresses':
unpacker = 'packed_addresses()'
else:
@ -326,6 +335,14 @@ def get_dependencies_connless7(msg: NetConnlessJson) -> str:
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:
@ -481,6 +498,12 @@ def pack_field_connless7(member: NetConnlessMemberJson) -> str:
packer = 'be_uint16'
elif member['type']['kind'] == 'uint8':
packer = 'uint8'
elif member['type']['kind'] == 'string':
packer = 'str'
elif member['type']['kind'] == 'int32':
packer = 'int'
elif member['type']['kind'] == 'serverinfo_client': # TODO: serverinfo_client
return f'self.{name}'
else:
raise ValueError(f"Error: unknown type {member['type']}")
return f'pack_{packer}({field})'
@ -554,12 +577,21 @@ class CodeGenerator():
if member['type']['kind'] == 'packed_addresses': # TODO: packed_addreses default value
ftype = 'list[MastersrvAddr]'
default = '[]'
elif member['type']['kind'] == 'be_uint16': # TODO: be_uint16
elif member['type']['kind'] == 'serverinfo_client': # TODO: serverinfo_client
ftype = 'bytes'
default = "b''"
elif member['type']['kind'] == 'be_uint16':
ftype = 'int'
default = '0'
elif member['type']['kind'] == 'uint8': # TODO: uint8
elif member['type']['kind'] == 'uint8':
ftype = 'int'
default = '0'
elif member['type']['kind'] == 'int32':
ftype = 'int'
default = '0'
elif member['type']['kind'] == 'string':
ftype = 'str'
default = "'default'"
else:
raise ValueError(f"Error: unknown type {member['type']}")
name = name_to_snake(member["name"])
@ -711,6 +743,12 @@ class CodeGenerator():
ftype = 'int'
elif member['type']['kind'] == 'uint8': # TODO: uint8
ftype = 'int'
elif member['type']['kind'] == 'int32':
ftype = 'int'
elif member['type']['kind'] == 'string':
ftype = 'str'
elif member['type']['kind'] == 'serverinfo_client': # TODO: serverinfo_client
ftype = 'bytes'
else:
raise ValueError(f"Error: unknown connless type {member['type']}")
name = name_to_snake(member["name"])

View file

@ -0,0 +1,50 @@
from typing import cast
from twnet_parser.packet import parse7
from twnet_parser.messages7.connless.count import MsgCount
def test_count_connless7() -> None:
data = b'\x21\xaa\xf5\x91\x59\xba\xf2\xfd\x31' \
b'\xff\xff\xff\xff\x69\x6e\x66\x33\x93\x93\xf0\xe0\x0e' \
b'\x30\x2e\x37\xe2\x86\x94\x30\x2e\x36\x2e\x34\x2c\x20\x31\x36\x2e' \
b'\x39\x00\x43\x68\x69\x6c\x6c\x65\x72\x44\x72\x61\x67\x6f\x6e\x27' \
b'\x73\x20\x43\x68\x69\x6c\x6c\x42\x6c\x6f\x63\x6b\x20\x53\x65\x72' \
b'\x76\x65\x72\x20\x5b\x43\x68\x69\x6c\x6c\x69\x2e\x2a\x5d\x00\x00' \
b'\x43\x68\x69\x6c\x6c\x42\x6c\x6f\x63\x6b\x35\x00\x44\x44\x72\x61' \
b'\x63\x65\x4e\x65\x74\x77\x6f\x72\x6b\x00\x02\x01\x06\x80\x01\x06' \
b'\x80\x01'
packet = parse7(data)
assert packet.version == '0.7'
assert packet.header.token == b'\xaa\xf5\x91\x59'
assert packet.header.response_token == b'\xba\xf2\xfd\x31'
assert packet.header.flags.control is False
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: MsgCount = cast(MsgCount, packet.messages[0])
assert msg.message_name == 'connless.info'
assert msg.token == 1980630227
assert msg.version == '0.7↔0.6.4, 16.9'
assert msg.name == "ChillerDragon's ChillBlock Server [Chilli.*]"
assert msg.hostname == ""
assert msg.map == "ChillBlock5"
assert msg.game_type == "DDraceNetwork"
assert msg.flags == 2
assert msg.skill_level == 1
assert msg.num_players == 6
assert msg.max_players == 64
assert msg.num_clients == 6
assert msg.max_clients == 64
repack: bytes = packet.pack()
assert repack == data

View file

@ -0,0 +1,76 @@
# generated by scripts/generate_messages.py
from twnet_parser.pretty_print import PrettyPrint
from twnet_parser.packer import Unpacker
from twnet_parser.packer import SANITIZE_CC, pack_int, pack_str
from typing import Literal
class MsgInfo(PrettyPrint):
def __init__(
self,
token: int = 0,
version: str = 'default',
name: str = 'default',
hostname: str = 'default',
map: str = 'default',
game_type: str = 'default',
flags: int = 0,
skill_level: int = 0,
num_players: int = 0,
max_players: int = 0,
num_clients: int = 0,
max_clients: int = 0,
clients: bytes = b''
) -> None:
self.message_type: Literal['connless'] = 'connless'
self.message_name: str = 'connless.info'
self.message_id: list[int] = [255, 255, 255, 255, 105, 110, 102, 51]
self.token: int = token
self.version: str = version
self.name: str = name
self.hostname: str = hostname
self.map: str = map
self.game_type: str = game_type
self.flags: int = flags
self.skill_level: int = skill_level
self.num_players: int = num_players
self.max_players: int = max_players
self.num_clients: int = num_clients
self.max_clients: int = max_clients
self.clients: bytes = clients
# 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.token = unpacker.get_int()
self.version = unpacker.get_str(SANITIZE_CC)
self.name = unpacker.get_str(SANITIZE_CC)
self.hostname = unpacker.get_str(SANITIZE_CC)
self.map = unpacker.get_str(SANITIZE_CC)
self.game_type = unpacker.get_str(SANITIZE_CC)
self.flags = unpacker.get_int()
self.skill_level = unpacker.get_int()
self.num_players = unpacker.get_int()
self.max_players = unpacker.get_int()
self.num_clients = unpacker.get_int()
self.max_clients = unpacker.get_int()
self.clients = unpacker.get_raw()
return True
def pack(self) -> bytes:
return pack_int(self.token) + \
pack_str(self.version) + \
pack_str(self.name) + \
pack_str(self.hostname) + \
pack_str(self.map) + \
pack_str(self.game_type) + \
pack_int(self.flags) + \
pack_int(self.skill_level) + \
pack_int(self.num_players) + \
pack_int(self.max_players) + \
pack_int(self.num_clients) + \
pack_int(self.max_clients) + \
self.clients

View file

@ -26,4 +26,4 @@ class MsgList(PrettyPrint):
return True
def pack(self) -> bytes:
return pack_packed_addresses(self.servers)
return pack_packed_addresses(self.servers)

View file

@ -1,16 +1,16 @@
# connless
HEARTBEAT = b'\xff\xff\xff\xffbea2'
REQUEST_LIST = b'\xff\xff\xff\xffreq2'
LIST = b'\xff\xff\xff\xfflis2'
REQUEST_COUNT = b'\xff\xff\xff\xffcou2'
COUNT = b'\xff\xff\xff\xffsiz2'
REQUEST_INFO = b'\xff\xff\xff\xffgie3'
# INFO = todo not in libtw2 and name conficts with sys.info
FORWARD_CHECK = b'\xff\xff\xff\xfffw??'
FORWARD_RESPONSE = b'\xff\xff\xff\xfffw!!'
FORWARD_OK = b'\xff\xff\xff\xfffwok'
FORWARD_ERROR = b'\xff\xff\xff\xfffwer'
CONNLESS_HEARTBEAT = b'\xff\xff\xff\xffbea2'
CONNLESS_REQUEST_LIST = b'\xff\xff\xff\xffreq2'
CONNLESS_LIST = b'\xff\xff\xff\xfflis2'
CONNLESS_REQUEST_COUNT = b'\xff\xff\xff\xffcou2'
CONNLESS_COUNT = b'\xff\xff\xff\xffsiz2'
CONNLESS_REQUEST_INFO = b'\xff\xff\xff\xffgie3'
CONNLESS_INFO = b'\xff\xff\xff\xffinf3'
CONNLESS_FORWARD_CHECK = b'\xff\xff\xff\xfffw??'
CONNLESS_FORWARD_RESPONSE = b'\xff\xff\xff\xfffw!!'
CONNLESS_FORWARD_OK = b'\xff\xff\xff\xfffwok'
CONNLESS_FORWARD_ERROR = b'\xff\xff\xff\xfffwer'
# control

View file

@ -14,6 +14,8 @@ import twnet_parser.messages7.connless.count as \
connless_count
import twnet_parser.messages7.connless.request_info as \
connless_request_info
import twnet_parser.messages7.connless.info as \
connless_info
import twnet_parser.messages7.connless.heartbeat as \
connless_heartbeat
import twnet_parser.messages7.connless.forward_check as \
@ -28,25 +30,27 @@ import twnet_parser.messages7.connless.forward_error as \
def match_connless7(msg_id: bytes, data: bytes) -> ConnlessMessage:
msg: Optional[ConnlessMessage] = None
if msg_id == twnet_parser.msg7.REQUEST_LIST:
if msg_id == twnet_parser.msg7.CONNLESS_REQUEST_LIST:
msg = connless_request_list.MsgRequestList()
elif msg_id == twnet_parser.msg7.LIST:
elif msg_id == twnet_parser.msg7.CONNLESS_LIST:
msg = connless_list.MsgList()
elif msg_id == twnet_parser.msg7.REQUEST_COUNT:
elif msg_id == twnet_parser.msg7.CONNLESS_REQUEST_COUNT:
msg = connless_request_count.MsgRequestCount()
elif msg_id == twnet_parser.msg7.COUNT:
elif msg_id == twnet_parser.msg7.CONNLESS_COUNT:
msg = connless_count.MsgCount()
elif msg_id == twnet_parser.msg7.REQUEST_INFO:
elif msg_id == twnet_parser.msg7.CONNLESS_REQUEST_INFO:
msg = connless_request_info.MsgRequestInfo()
elif msg_id == twnet_parser.msg7.HEARTBEAT:
elif msg_id == twnet_parser.msg7.CONNLESS_INFO:
msg = connless_info.MsgInfo()
elif msg_id == twnet_parser.msg7.CONNLESS_HEARTBEAT:
msg = connless_heartbeat.MsgHeartbeat()
elif msg_id == twnet_parser.msg7.FORWARD_CHECK:
elif msg_id == twnet_parser.msg7.CONNLESS_FORWARD_CHECK:
msg = connless_forward_check.MsgForwardCheck()
elif msg_id == twnet_parser.msg7.FORWARD_RESPONSE:
elif msg_id == twnet_parser.msg7.CONNLESS_FORWARD_RESPONSE:
msg = connless_forward_response.MsgForwardResponse()
elif msg_id == twnet_parser.msg7.FORWARD_OK:
elif msg_id == twnet_parser.msg7.CONNLESS_FORWARD_OK:
msg = connless_forward_ok.MsgForwardOk()
elif msg_id == twnet_parser.msg7.FORWARD_ERROR:
elif msg_id == twnet_parser.msg7.CONNLESS_FORWARD_ERROR:
msg = connless_forward_error.MsgForwardError()
if msg is None: