giants-maps-gui/lib/enumresponse.py

118 lines
5.1 KiB
Python

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