import enum import binascii import protoparser from protoparser import Packet, unknown class HazelPacketType(bytes, enum.Enum): UNRELIABLE = bytes([0]) RELIABLE = bytes([1]) HELLO = bytes([8]) PING = bytes([12]) ACK = bytes([10]) FIN = bytes([9]) FRAGMENT = bytes([11]) # not observed yet, maybe unused in among us? def int_big_endian(data: bytes) -> int: return int.from_bytes(data, "big") Parser = protoparser.Parser() @Parser.register(HazelPacketType.PING, ("nonce", 2, int_big_endian)) class PingPacket(Packet): def __init__(self, data, nonce): self.nonce = nonce super().__init__(data) def __repr__(self): return f"Ping {self.nonce}" @Parser.register(HazelPacketType.ACK, ("nonce", 2, int_big_endian), b"\xFF") class AckPacket(Packet): def __init__(self, data, nonce): self.nonce = nonce super().__init__(data) def __repr__(self): return f"Ack {self.nonce}" @Parser.register(HazelPacketType.FIN) class FinPacket(Packet): def __repr__(self): return "Fin" @Parser.register( HazelPacketType.HELLO, unknown(7), ("name_len", 1, int_big_endian), ("name", "name_len", bytes.decode), ) class HelloPacket(Packet): def __init__(self, data, name, **kwargs): self.name = name super().__init__(data)