from lib.packet import Packet class EnumResponse: LEAD = 0x00 COMMAND = 0x03 def __init__(self): self.Lead = EnumResponse.LEAD self.Command = EnumResponse.COMMAND self.Payload = b'' self.ReplyOffset = b'' self.ReplySize = b'' self.ApplicationDescSize = b'' self.ApplicationDescFlags = b'' self.MaxPlayers = b'' self.CurrentPlayers = b'' self.SessionNameOffset = b'' self.SessionNameSize = b'' self.PasswordOffset = b'' self.PasswordSize = b'' self.ReservedDataOffset = b'' self.ReservedDataSize = b'' self.ApplicationReservedDataOffset = b'' self.ApplicationReservedDataSize = b'' self.ApplicationInstanceGUID = b'' self.ApplicationGUID = b'' self.SessionName = "" self.Password = b'' self.ReservedData = b'' self.ApplicationReservedData = b'' self.ApplicationData = b'' @classmethod def parse(cls, packet: Packet): enumresponse = cls() packet.seek(0) enumresponse.Lead = packet.get_byte() if enumresponse.Lead != 0xcf: enumresponse.Command = packet.get_byte() enumresponse.Payload = packet.get_short() enumresponse.ReplyOffset = packet.get_ulong() enumresponse.ReplySize = packet.get_ulong() else: packet.get_3bytes_int() # cause we were supposed to read a full int enumresponse.ApplicationDescSize = packet.get_ulong() enumresponse.ApplicationDescFlags = packet.get_ulong() enumresponse.MaxPlayers = packet.get_ulong() enumresponse.CurrentPlayers = packet.get_ulong() enumresponse.SessionNameOffset = packet.get_ulong() enumresponse.SessionNameSize = packet.get_ulong() enumresponse.PasswordOffset = packet.get_ulong() enumresponse.PasswordSize = packet.get_ulong() enumresponse.ReservedDataOffset = packet.get_ulong() enumresponse.ReservedDataSize = packet.get_ulong() enumresponse.ApplicationReservedDataOffset = packet.get_ulong() enumresponse.ApplicationReservedDataSize = packet.get_ulong() enumresponse.ApplicationInstanceGUID = packet.get_bytes(16) enumresponse.ApplicationGUID = packet.get_bytes(16) enumresponse.SessionName = packet.getvalue()[enumresponse.SessionNameOffset+4:enumresponse.SessionNameOffset+enumresponse.SessionNameSize+1].decode("utf8").replace("\x00", "") enumresponse.ApplicationReservedData = packet.getvalue()[enumresponse.ApplicationReservedDataOffset+4:enumresponse.ApplicationReservedDataOffset+enumresponse.ApplicationReservedDataSize+4] return enumresponse def to_packet(self): varpos = 88 self.SessionNameSize = len(self.SessionName.encode("utf-16")) self.SessionNameOffset = varpos if self.SessionName else 0 varpos += self.SessionNameSize if self.SessionName else 0 self.PasswordSize = len(self.Password) self.PasswordOffset = varpos if self.Password else 0 varpos += self.PasswordSize if self.Password else 0 self.ReservedDataSize = len(self.ReservedData) self.ReservedDataOffset = varpos if self.ReservedData else 0 varpos += self.ReservedDataSize if self.ReservedData else 0 self.ApplicationReservedDataSize = len(self.ApplicationReservedData) self.ApplicationReservedDataOffset = varpos if self.ApplicationReservedData else 0 varpos += self.ApplicationReservedDataSize if self.ApplicationReservedData else 0 self.ReplySize = len(self.ApplicationData) self.ReplyOffset = varpos if self.ApplicationData else 0 varpos += self.ReplySize if self.ApplicationData else 0 packet = Packet() packet.put_byte(EnumResponse.LEAD) packet.put_byte(EnumResponse.COMMAND) packet.put_short(self.Payload) packet.put_ulong(self.ReplyOffset) packet.put_ulong(self.ReplySize) packet.put_ulong(self.ApplicationDescSize) packet.put_ulong(self.ApplicationDescFlags) packet.put_ulong(self.MaxPlayers) packet.put_ulong(self.CurrentPlayers) packet.put_ulong(self.SessionNameOffset) packet.put_ulong(self.SessionNameSize) packet.put_ulong(self.PasswordOffset) packet.put_ulong(self.PasswordSize) packet.put_ulong(self.ReservedDataOffset) packet.put_ulong(self.ReservedDataSize) packet.put_ulong(self.ApplicationReservedDataOffset) packet.put_ulong(self.ApplicationReservedDataSize) packet.put_bytes(self.ApplicationInstanceGUID) packet.put_bytes(self.ApplicationGUID) if self.SessionName: packet.put_bytes((self.SessionName+'\x00').encode("utf-16-le")) if self.Password: packet.put_bytes(self.Password) if self.ReservedData: packet.put_bytes(self.ReservedData) if self.ApplicationReservedData: packet.put_bytes(self.ApplicationReservedData) if self.ApplicationData: packet.put_bytes(self.ApplicationData) return packet