Compare commits

...

10 commits

156 changed files with 1641 additions and 24 deletions

View file

@ -25,6 +25,29 @@ print(packet.header) # => <class: 'Header'>: {'flags': <class: 'PacketFlags7, 's
print(packet.header.flags) # => <class: 'PacketFlags7'>: {'control': True, 'resend': False, 'compression': False, 'connless': False}
for msg in packet.messages:
print(msg.message_name) # => close
print(packet.to_json())
# {
# "version": "0.7",
# "payload_raw": "04",
# "payload_decompressed": "04",
# "header": {
# "flags": [
# "control"
# ],
# "ack": 10,
# "token": "cf2ede1d",
# "num_chunks": 0
# },
# "messages": [
# {
# "message_type": "control",
# "message_name": "close",
# "message_id": 4,
# "reason": null
# }
# ]
# }
```
More examples can be found in the [examples/](./examples/) folder:

View file

@ -115,6 +115,35 @@ def name_to_snake(name_list: list[str]) -> str:
name = '_'.join(name_list)
return fix_name_conflict(name)
def gen_yield(messages: list[NetMessageMemberJson]) -> list[str]:
lines = []
if len(messages) > 0:
lines.append("")
for msg in messages:
name = name_to_snake(msg['name'])
lines.append(f" yield '{name}', self.{name}")
return lines
def gen_iter(messages: list[NetMessageMemberJson]) -> str:
lines: list[str] = []
lines.append(' def __iter__(self):')
lines.append(" yield 'message_type', self.message_type")
lines.append(" yield 'message_name', self.message_name")
lines.append(" yield 'system_message', self.system_message")
lines.append(" yield 'message_id', self.message_id")
lines.append(" yield 'header', dict(self.header)")
lines += gen_yield(messages)
return '\n'.join(lines)
def gen_iter_connless(messages: list[NetMessageMemberJson]) -> str:
lines: list[str] = []
lines.append(' def __iter__(self):')
lines.append(" yield 'message_type', self.message_type")
lines.append(" yield 'message_name', self.message_name")
lines.append(" yield 'message_id', self.message_id")
lines += gen_yield(messages)
return '\n'.join(lines)
def gen_unpack_members_connless7(msg: NetConnlessJson) -> str:
res: str = ''
for member in msg['members']:
@ -915,6 +944,9 @@ def match_connless{self.protocol_version}(msg_id: bytes, data: bytes) -> Connles
else:
out_file.write(f" self.{name}{ftype} = {name}\n")
out_file.write('\n')
out_file.write(gen_iter_connless(msg['members']))
out_file.write('\n')
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')
@ -1040,6 +1072,9 @@ def match_connless{self.protocol_version}(msg_id: bytes, data: bytes) -> Connles
out_file.write('\n')
self.generate_field_assignments_in_initialize(msg, out_file)
out_file.write('\n')
out_file.write(gen_iter(msg['members']))
out_file.write('\n')
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')

View file

@ -1,6 +1,6 @@
[metadata]
name = twnet_parser
version = 0.9.0
version = 0.10.0
author = ChillerDragon
author_email = chillerdragon@gmail.com
description = A teeworlds network protocol library, designed according to sans I/O (http://sans-io.readthedocs.io/) principles

73
tests/dict_cast_test.py Normal file
View file

@ -0,0 +1,73 @@
from typing import cast
from twnet_parser.messages6.game.cl_change_info import MsgClChangeInfo
from twnet_parser.packet import TwPacket, NetMessage
def test_change_info() -> None:
change_info = dict(MsgClChangeInfo())
assert change_info['message_type'] == 'game'
assert change_info['message_name'] == 'cl_change_info'
assert change_info['system_message'] == False
assert change_info['message_id'] == 21
assert change_info['header'] == {'flags': [], 'seq': -1, 'size': None, 'version': '0.6'}
assert change_info['name'] == 'default'
assert change_info['clan'] == 'default'
assert change_info['country'] == 0
assert change_info['skin'] == 'default'
assert change_info['use_custom_color'] == False
assert change_info['color_body'] == 0
assert change_info['color_feet'] == 0
def test_empty_packet() -> None:
packet = dict(TwPacket())
assert packet == {
'header': {
'ack': 0,
'flags': [],
'num_chunks': None,
'token': b'\xff\xff\xff\xff'
},
'payload_decompressed': b'',
'payload_raw': b'',
'version': '0.7',
'messages': []
}
def test_change_info_packet() -> None:
packet = TwPacket()
packet.messages.append(cast(NetMessage, MsgClChangeInfo()))
packet = dict(packet)
assert packet == {
'header': {
'ack': 0,
'flags': [],
'num_chunks': None,
'token': b'\xff\xff\xff\xff'
},
'payload_decompressed': b'',
'payload_raw': b'',
'version': '0.7',
'messages': [
{
'clan': 'default',
'color_body': 0,
'color_feet': 0,
'country': 0,
'header': {
'flags': [],
'seq': -1,
'size': None,
'version': '0.6'
},
'message_id': 21,
'message_name': 'cl_change_info',
'message_type': 'game',
'name': 'default',
'skin': 'default',
'system_message': False,
'use_custom_color': False
}
]
}

44
tests/json_test.py Normal file
View file

@ -0,0 +1,44 @@
from typing import cast
import textwrap
from twnet_parser.messages6.game.cl_change_info import MsgClChangeInfo
from twnet_parser.packet import TwPacket, NetMessage
def test_change_info_packet() -> None:
packet = TwPacket()
packet.messages.append(cast(NetMessage, MsgClChangeInfo()))
packet = packet.to_json()
expected = textwrap.dedent("""\
{
"version": "0.7",
"payload_raw": "",
"payload_decompressed": "",
"header": {
"flags": [],
"ack": 0,
"token": "ffffffff",
"num_chunks": null
},
"messages": [
{
"message_type": "game",
"message_name": "cl_change_info",
"system_message": false,
"message_id": 21,
"header": {
"version": "0.6",
"flags": [],
"size": null,
"seq": -1
},
"name": "default",
"clan": "default",
"country": 0,
"skin": "default",
"use_custom_color": false,
"color_body": 0,
"color_feet": 0
}
]
}""")
assert packet == expected

View file

@ -1,5 +1,5 @@
from twnet_parser.packet import \
PacketHeaderParser6, PacketHeader, PacketFlags6
PacketHeaderParser6, PacketHeader7, PacketFlags6
def test_parse_flags() -> None:
parser = PacketHeaderParser6()
@ -19,7 +19,7 @@ def test_parse_flags() -> None:
def test_packet_header_no_token_unpack() -> None:
parser = PacketHeaderParser6()
header: PacketHeader = parser.parse_header(b'\x10\x00\x00')
header: PacketHeader7 = parser.parse_header(b'\x10\x00\x00')
assert header.ack == 0
assert header.num_chunks == 0

View file

@ -1,5 +1,5 @@
from twnet_parser.packet import \
parse7, PacketHeaderParser7, PacketHeader, TwPacket
parse7, PacketHeaderParser7, PacketHeader7, TwPacket
def test_packet_header_unpack() -> None:
# TODO: change api to
@ -7,7 +7,7 @@ def test_packet_header_unpack() -> None:
# PacketHeader.unpack(bytes)
parser = PacketHeaderParser7()
header: PacketHeader = parser.parse_header(b'\x04\x0a\x00\xcf\x2e\xde\x1d')
header: PacketHeader7 = parser.parse_header(b'\x04\x0a\x00\xcf\x2e\xde\x1d')
assert header.ack == 10
assert header.token == b'\xcf.\xde\x1d'
@ -19,7 +19,7 @@ def test_packet_header_unpack() -> None:
assert header.flags.connless is False
def test_packet_header_pack_flags() -> None:
header: PacketHeader = PacketHeader()
header: PacketHeader7 = PacketHeader7()
header.ack = 0
header.flags.control = True
@ -35,7 +35,7 @@ def test_packet_header_pack_flags() -> None:
assert header.pack()[0:1] == b'\x10'
def test_packet_header_pack_ack() -> None:
header: PacketHeader = PacketHeader()
header: PacketHeader7 = PacketHeader7()
header.flags.control = False
header.flags.resend = False
header.flags.compression = False
@ -51,7 +51,7 @@ def test_packet_header_pack_ack() -> None:
assert header.pack()[1:2] == b'\x0b'
def test_packet_header_repack_overflowing_ack() -> None:
header: PacketHeader = PacketHeader()
header: PacketHeader7 = PacketHeader7()
header.flags.control = False
header.flags.resend = False
header.flags.compression = False
@ -73,7 +73,7 @@ def test_packet_header_repack_overflowing_ack() -> None:
assert header.ack == 976
def test_packet_header_repack_ack_overlapping_into_flags_byte() -> None:
header: PacketHeader = PacketHeader()
header: PacketHeader7 = PacketHeader7()
header.flags.control = False
header.flags.resend = False
header.flags.compression = False
@ -133,7 +133,7 @@ def test_packet_header_repack_ack_overlapping_into_flags_byte() -> None:
assert header.ack == 511
def test_packet_header_pack_num_chunks() -> None:
header = PacketHeader()
header = PacketHeader7()
header.num_chunks = 0
assert header.pack()[2:3] == b'\x00'
@ -145,7 +145,7 @@ def test_packet_header_pack_num_chunks() -> None:
assert header.pack()[2:3] == b'\x06'
def test_packet_header_pack_token() -> None:
header = PacketHeader()
header = PacketHeader7()
header.token = b'\x11\x22\x33\xff'
assert header.pack()[3:] == b'\x11\x22\x33\xff'
@ -162,7 +162,7 @@ def test_packet_header_pack_token() -> None:
assert header.pack()[3:] == b'tekn'
def test_packet_header_pack_full() -> None:
header: PacketHeader = PacketHeader()
header: PacketHeader7 = PacketHeader7()
header.ack = 10
header.token = b'\xcf.\xde\x1d'
@ -176,7 +176,7 @@ def test_packet_header_pack_full() -> None:
assert header.pack() == b'\x04\x0a\x00\xcf\x2e\xde\x1d'
def test_packet_header_repack_all_set() -> None:
header: PacketHeader = PacketHeader()
header: PacketHeader7 = PacketHeader7()
header.ack = 1023
header.token = b'\xff\xff\xff\xff'
@ -235,7 +235,7 @@ def test_packet_header_repack_all_set() -> None:
assert header.flags.connless is False
def test_packet_header_repack_none_set() -> None:
header: PacketHeader = PacketHeader()
header: PacketHeader7 = PacketHeader7()
header.ack = 0
header.token = b'\x00\x00\x00\x00'

View file

@ -3,6 +3,13 @@ from twnet_parser.packer import \
from twnet_parser.packer import \
NO_SANITIZE, SANITIZE, SANITIZE_CC, SKIP_START_WHITESPACES
def test_unpack_simple_ints() -> None:
u = Unpacker(b'\x01\x02\x03\x0F')
assert u.get_int() == 1
assert u.get_int() == 2
assert u.get_int() == 3
assert u.get_int() == 15
def test_unpack_eol() -> None:
u = Unpacker(b'\x01\x02\x03\x01foo\x00bar\x00')
assert u.get_int() == 1

View file

@ -6,9 +6,18 @@ class ChunkFlags(PrettyPrint):
def __init__(self):
self.resend = False
self.vital = False
def __repr__(self):
return "<class: '" + str(self.__class__.__name__) + "'>: " + str(self.__dict__)
def __iter__(self):
flags = []
if self.resend:
flags.append('resend')
if self.vital:
flags.append('vital')
return iter(flags)
# same fields for 0.6 and 0.7
# different bit layout tho
class ChunkHeader(PrettyPrint):
@ -32,6 +41,12 @@ class ChunkHeader(PrettyPrint):
# if unset
self.seq: int = -1
def __iter__(self):
yield 'version', self.version
yield 'flags', list(self.flags)
yield 'size', self.size
yield 'seq', self.seq
def pack(self) -> bytes:
flags: int = 0
if self.flags.resend:
@ -60,3 +75,7 @@ class ChunkHeader(PrettyPrint):
data[1] |= (self.seq >> 2) & 0xc0
data += bytes([self.seq & 0xff])
return bytes(data)
def __repr__(self):
return "<class: '" + str(self.__class__.__name__) + "'>: " + str(dict(self))

View file

@ -1,4 +1,4 @@
from typing import Protocol, Literal, Annotated
from typing import Protocol, Literal, Annotated, Iterator, Any
class ConnlessMessage(Protocol):
message_type: Literal['connless']
@ -8,3 +8,5 @@ class ConnlessMessage(Protocol):
...
def pack(self) -> bytes:
...
def __iter__(self) -> Iterator[tuple[str, Any]]:
...

View file

@ -1,4 +1,4 @@
from typing import Protocol, Literal
from typing import Protocol, Literal, Iterator, Any
class CtrlMessage(Protocol):
message_type: Literal['control']
@ -8,3 +8,5 @@ class CtrlMessage(Protocol):
...
def pack(self, we_are_a_client: bool = True) -> bytes:
...
def __iter__(self) -> Iterator[tuple[str, Any]]:
...

View file

@ -19,6 +19,15 @@ class MsgDDNetUuid(PrettyPrint):
self.payload: bytes = payload
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'payload', self.payload
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -16,6 +16,13 @@ class MsgCount(PrettyPrint):
self.count: int = count
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'count', self.count
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardCheck(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 63, 63]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardError(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 101, 114]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardOk(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 111, 107]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardResponse(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 33, 33]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -16,6 +16,13 @@ class MsgHeartbeat(PrettyPrint):
self.alt_port: int = alt_port
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'alt_port', self.alt_port
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -36,6 +36,23 @@ class MsgInfo(PrettyPrint):
self.max_clients: int = max_clients
self.clients: bytes = clients
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'token', self.token
yield 'version', self.version
yield 'name', self.name
yield 'map', self.map
yield 'game_type', self.game_type
yield 'flags', self.flags
yield 'num_players', self.num_players
yield 'max_players', self.max_players
yield 'num_clients', self.num_clients
yield 'max_clients', self.max_clients
yield 'clients', self.clients
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -17,6 +17,13 @@ class MsgList(PrettyPrint):
self.servers: list[MastersrvAddr] = servers
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'servers', self.servers
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgRequestCount(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 99, 111, 117, 50]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -16,6 +16,13 @@ class MsgRequestInfo(PrettyPrint):
self.token: int = token
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'token', self.token
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgRequestList(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 114, 101, 113, 50]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -7,6 +7,11 @@ class CtrlAccept(PrettyPrint):
self.message_name: str = 'accept'
self.message_id: int = 3
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
return False

View file

@ -15,6 +15,13 @@ class CtrlClose(PrettyPrint):
self.reason: Optional[str] = reason
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'reason', self.reason
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -19,6 +19,13 @@ class CtrlConnect(PrettyPrint):
self.response_token: bytes = response_token
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'response_token', self.response_token
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
# anti reflection attack
if len(data) < 512:

View file

@ -18,6 +18,13 @@ class CtrlConnectAccept(PrettyPrint):
self.response_token: bytes = response_token
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'response_token', self.response_token
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
self.response_token = data[0:4]
return True

View file

@ -7,6 +7,11 @@ class CtrlKeepAlive(PrettyPrint):
self.message_name: str = 'keep_alive'
self.message_id: int = 0
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
return False

View file

@ -12,6 +12,14 @@ class CtrlToken(PrettyPrint):
self.response_token: bytes = response_token
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'response_token', self.response_token
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
if not we_are_a_client:
# anti reflection attack

View file

@ -26,6 +26,17 @@ class MsgClCallVote(PrettyPrint):
self.value: str = value
self.reason: str = reason
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'type', self.type
yield 'value', self.value
yield 'reason', self.reason
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -34,6 +34,21 @@ class MsgClChangeInfo(PrettyPrint):
self.color_body: int = color_body
self.color_feet: int = color_feet
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'name', self.name
yield 'clan', self.clan
yield 'country', self.country
yield 'skin', self.skin
yield 'use_custom_color', self.use_custom_color
yield 'color_body', self.color_body
yield 'color_feet', self.color_feet
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -23,6 +23,15 @@ class MsgClEmoticon(PrettyPrint):
self.emoticon: int = emoticon
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'emoticon', self.emoticon
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgClKill(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -24,6 +24,16 @@ class MsgClSay(PrettyPrint):
self.team: bool = team
self.message: str = message
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'team', self.team
yield 'message', self.message
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgClSetSpectatorMode(PrettyPrint):
self.spectator_id: int = spectator_id
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'spectator_id', self.spectator_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -23,6 +23,15 @@ class MsgClSetTeam(PrettyPrint):
self.team: int = team
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'team', self.team
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -34,6 +34,21 @@ class MsgClStartInfo(PrettyPrint):
self.color_body: int = color_body
self.color_feet: int = color_feet
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'name', self.name
yield 'clan', self.clan
yield 'country', self.country
yield 'skin', self.skin
yield 'use_custom_color', self.use_custom_color
yield 'color_body', self.color_body
yield 'color_feet', self.color_feet
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgClVote(PrettyPrint):
self.vote: int = vote
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'vote', self.vote
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgSvBroadcast(PrettyPrint):
self.message: str = message
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'message', self.message
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -26,6 +26,17 @@ class MsgSvChat(PrettyPrint):
self.client_id: int = client_id
self.message: str = message
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'team', self.team
yield 'client_id', self.client_id
yield 'message', self.message
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -25,6 +25,16 @@ class MsgSvEmoticon(PrettyPrint):
self.client_id: int = client_id
self.emoticon: int = emoticon
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'client_id', self.client_id
yield 'emoticon', self.emoticon
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -24,6 +24,15 @@ class MsgSvExtraProjectile(PrettyPrint):
projectile = ObjProjectile()
self.projectile: ObjProjectile = projectile
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'projectile', self.projectile
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -28,6 +28,18 @@ class MsgSvKillMsg(PrettyPrint):
self.weapon: int = weapon
self.mode_special: int = mode_special
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'killer', self.killer
yield 'victim', self.victim
yield 'weapon', self.weapon
yield 'mode_special', self.mode_special
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgSvMotd(PrettyPrint):
self.message: str = message
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'message', self.message
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgSvReadyToEnter(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -23,6 +23,15 @@ class MsgSvSoundGlobal(PrettyPrint):
self.sound_id: int = sound_id
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'sound_id', self.sound_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -86,6 +86,47 @@ class MsgSvTuneParams(PrettyPrint):
self.player_collision: float = player_collision
self.player_hooking: float = player_hooking
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'ground_control_speed', self.ground_control_speed
yield 'ground_control_accel', self.ground_control_accel
yield 'ground_friction', self.ground_friction
yield 'ground_jump_impulse', self.ground_jump_impulse
yield 'air_jump_impulse', self.air_jump_impulse
yield 'air_control_speed', self.air_control_speed
yield 'air_control_accel', self.air_control_accel
yield 'air_friction', self.air_friction
yield 'hook_length', self.hook_length
yield 'hook_fire_speed', self.hook_fire_speed
yield 'hook_drag_accel', self.hook_drag_accel
yield 'hook_drag_speed', self.hook_drag_speed
yield 'gravity', self.gravity
yield 'velramp_start', self.velramp_start
yield 'velramp_range', self.velramp_range
yield 'velramp_curvature', self.velramp_curvature
yield 'gun_curvature', self.gun_curvature
yield 'gun_speed', self.gun_speed
yield 'gun_lifetime', self.gun_lifetime
yield 'shotgun_curvature', self.shotgun_curvature
yield 'shotgun_speed', self.shotgun_speed
yield 'shotgun_speeddiff', self.shotgun_speeddiff
yield 'shotgun_lifetime', self.shotgun_lifetime
yield 'grenade_curvature', self.grenade_curvature
yield 'grenade_speed', self.grenade_speed
yield 'grenade_lifetime', self.grenade_lifetime
yield 'laser_reach', self.laser_reach
yield 'laser_bounce_delay', self.laser_bounce_delay
yield 'laser_bounce_num', self.laser_bounce_num
yield 'laser_bounce_cost', self.laser_bounce_cost
yield 'laser_damage', self.laser_damage
yield 'player_collision', self.player_collision
yield 'player_hooking', self.player_hooking
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgSvVoteClearOptions(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgSvVoteOptionAdd(PrettyPrint):
self.description: str = description
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'description', self.description
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -25,6 +25,16 @@ class MsgSvVoteOptionListAdd(PrettyPrint):
self.num_options: int = num_options
self.description = description
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'num_options', self.num_options
yield 'description', self.description
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgSvVoteOptionRemove(PrettyPrint):
self.description: str = description
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'description', self.description
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -26,6 +26,17 @@ class MsgSvVoteSet(PrettyPrint):
self.description: str = description
self.reason: str = reason
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'timeout', self.timeout
yield 'description', self.description
yield 'reason', self.reason
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -28,6 +28,18 @@ class MsgSvVoteStatus(PrettyPrint):
self.pass_: int = pass_
self.total: int = total
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'yes', self.yes
yield 'no', self.no
yield 'pass_', self.pass_
yield 'total', self.total
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -23,6 +23,15 @@ class MsgSvWeaponPickup(PrettyPrint):
self.weapon: int = weapon
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'weapon', self.weapon
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgConReady(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgEnterGame(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -24,6 +24,16 @@ class MsgInfo(PrettyPrint):
self.version: str = version
self.password: Optional[str] = password
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'version', self.version
yield 'password', self.password
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -31,6 +31,18 @@ class MsgInput(PrettyPrint):
input = ObjPlayerInput()
self.input: ObjPlayerInput = input
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'ack_snapshot', self.ack_snapshot
yield 'intended_tick', self.intended_tick
yield 'input_size', self.input_size
yield 'input', self.input
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -24,6 +24,16 @@ class MsgInputTiming(PrettyPrint):
self.input_pred_tick: int = input_pred_tick
self.time_left: int = time_left
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'input_pred_tick', self.input_pred_tick
yield 'time_left', self.time_left
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -26,6 +26,17 @@ class MsgMapChange(PrettyPrint):
self.crc: int = crc
self.size: int = size
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'name', self.name
yield 'crc', self.crc
yield 'size', self.size
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -30,6 +30,18 @@ class MsgMapData(PrettyPrint):
self.data_size: int = data_size if data_size else len(data)
self.data: bytes = data
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'last', self.last
yield 'crc', self.crc
yield 'chunk', self.chunk
yield 'data', self.data
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgPing(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgPingReply(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -26,6 +26,17 @@ class MsgRconAuth(PrettyPrint):
self.password: str = password
self.request_commands: Optional[int] = request_commands
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield '_unused', self._unused
yield 'password', self.password
yield 'request_commands', self.request_commands
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -24,6 +24,16 @@ class MsgRconAuthStatus(PrettyPrint):
self.auth_level: Optional[int] = auth_level
self.receive_commands: Optional[int] = receive_commands
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'auth_level', self.auth_level
yield 'receive_commands', self.receive_commands
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgRconCmd(PrettyPrint):
self.cmd: str = cmd
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'cmd', self.cmd
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -26,6 +26,17 @@ class MsgRconCmdAdd(PrettyPrint):
self.help: str = help
self.params: str = params
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'name', self.name
yield 'help', self.help
yield 'params', self.params
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgRconCmdRemove(PrettyPrint):
self.name: str = name
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'name', self.name
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgRconLine(PrettyPrint):
self.line: str = line
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'line', self.line
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgReady(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -22,6 +22,15 @@ class MsgRequestMapData(PrettyPrint):
self.chunk: int = chunk
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'chunk', self.chunk
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -35,6 +35,24 @@ class MsgSnap(PrettyPrint):
self.data: bytes = data
self.snapshot = Snapshot()
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'tick', self.tick
yield 'delta_tick', self.delta_tick
yield 'num_parts', self.num_parts
yield 'part', self.part
yield 'crc', self.crc
yield 'data_size', self.data_size
yield 'data', self.data
# TODO: dict snapshot
# yield 'snapshot', 'TODO'
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -24,6 +24,16 @@ class MsgSnapEmpty(PrettyPrint):
self.tick: int = tick
self.delta_tick: int = delta_tick
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'tick', self.tick
yield 'delta_tick', self.delta_tick
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -30,6 +30,18 @@ class MsgSnapSingle(PrettyPrint):
self.data_size: int = data_size if data_size else len(data)
self.data: bytes = data
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'tick', self.tick
yield 'delta_tick', self.delta_tick
yield 'crc', self.crc
yield 'data', self.data
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -16,6 +16,13 @@ class MsgCount(PrettyPrint):
self.count: int = count
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'count', self.count
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardCheck(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 63, 63]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardError(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 101, 114]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardOk(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 111, 107]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgForwardResponse(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 102, 119, 33, 33]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -16,6 +16,13 @@ class MsgHeartbeat(PrettyPrint):
self.alt_port: int = alt_port
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'alt_port', self.alt_port
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -40,6 +40,25 @@ class MsgInfo(PrettyPrint):
self.max_clients: int = max_clients
self.clients: bytes = clients
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'token', self.token
yield 'version', self.version
yield 'name', self.name
yield 'hostname', self.hostname
yield 'map', self.map
yield 'game_type', self.game_type
yield 'flags', self.flags
yield 'skill_level', self.skill_level
yield 'num_players', self.num_players
yield 'max_players', self.max_players
yield 'num_clients', self.num_clients
yield 'max_clients', self.max_clients
yield 'clients', self.clients
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -17,6 +17,13 @@ class MsgList(PrettyPrint):
self.servers: list[MastersrvAddr] = servers
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'servers', self.servers
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgRequestCount(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 99, 111, 117, 50]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -16,6 +16,13 @@ class MsgRequestInfo(PrettyPrint):
self.token: int = token
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'token', self.token
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,11 @@ class MsgRequestList(PrettyPrint):
self.message_id: list[int] = [255, 255, 255, 255, 114, 101, 113, 50]
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -7,6 +7,11 @@ class CtrlAccept(PrettyPrint):
self.message_name: str = 'accept'
self.message_id: int = 2
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
return False

View file

@ -15,6 +15,13 @@ class CtrlClose(PrettyPrint):
self.reason: Optional[str] = reason
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'reason', self.reason
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -12,6 +12,13 @@ class CtrlConnect(PrettyPrint):
self.response_token: bytes = response_token
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'response_token', self.response_token
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
# anti reflection attack
if len(data) < 512:

View file

@ -7,6 +7,11 @@ class CtrlKeepAlive(PrettyPrint):
self.message_name: str = 'keep_alive'
self.message_id: int = 0
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
return False

View file

@ -12,6 +12,13 @@ class CtrlToken(PrettyPrint):
self.response_token: bytes = response_token
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'message_id', self.message_id
yield 'response_token', self.response_token
def unpack(self, data: bytes, we_are_a_client: bool = True) -> bool:
if not we_are_a_client:
# anti reflection attack

View file

@ -28,6 +28,18 @@ class MsgClCallVote(PrettyPrint):
self.reason: str = reason
self.force: bool = force
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'type', self.type
yield 'value', self.value
yield 'reason', self.reason
yield 'force', self.force
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -24,6 +24,16 @@ class MsgClCommand(PrettyPrint):
self.name: str = name
self.arguments: str = arguments
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'name', self.name
yield 'arguments', self.arguments
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -23,6 +23,15 @@ class MsgClEmoticon(PrettyPrint):
self.emoticon: int = emoticon
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'emoticon', self.emoticon
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgClKill(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -18,6 +18,13 @@ class MsgClReadyChange(PrettyPrint):
self.header: ChunkHeader = chunk_header
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -27,6 +27,17 @@ class MsgClSay(PrettyPrint):
self.target: int = target
self.message: str = message
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'mode', self.mode
yield 'target', self.target
yield 'message', self.message
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -25,6 +25,16 @@ class MsgClSetSpectatorMode(PrettyPrint):
self.spec_mode: int = spec_mode
self.spectator_id: int = spectator_id
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'spec_mode', self.spec_mode
yield 'spectator_id', self.spectator_id
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -23,6 +23,15 @@ class MsgClSetTeam(PrettyPrint):
self.team: int = team
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'team', self.team
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -29,6 +29,17 @@ class MsgClSkinChange(PrettyPrint):
self.use_custom_colors = use_custom_colors
self.skin_part_colors = skin_part_colors
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'skin_part_names', self.skin_part_names
yield 'use_custom_colors', self.use_custom_colors
yield 'skin_part_colors', self.skin_part_colors
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

View file

@ -35,6 +35,20 @@ class MsgClStartInfo(PrettyPrint):
self.use_custom_colors = use_custom_colors
self.skin_part_colors = skin_part_colors
def __iter__(self):
yield 'message_type', self.message_type
yield 'message_name', self.message_name
yield 'system_message', self.system_message
yield 'message_id', self.message_id
yield 'header', dict(self.header)
yield 'name', self.name
yield 'clan', self.clan
yield 'country', self.country
yield 'skin_part_names', self.skin_part_names
yield 'use_custom_colors', self.use_custom_colors
yield 'skin_part_colors', self.skin_part_colors
# first byte of data
# has to be the first byte of the message payload
# NOT the chunk header and NOT the message id

Some files were not shown because too many files have changed in this diff Show more