crashtest-r0ket/tools/game/r0ketrem0te/packets.py

217 lines
6.3 KiB
Python

def inttouint32(v):
return chr(v&0xff)+chr((v>>8)&0xff)+chr((v>>16)&0xff)+chr((v>>24)&0xff)
def uint32toint(v):
return (ord(v[3])<< 24) + (ord(v[2])<<16) + (ord(v[1])<<8) + (ord(v[0]))
def inttouint16(v):
return chr(v&0xff)+chr((v>>8)&0xff)
class Packet:
def __init__(self, command, id=None):
self.ctr = 0
if id == None:
message = command
command = message[2]
id = uint32toint(message[3:7])
self.ctr = uint32toint(message[7:11])
self.length = 32
self.protocol = 'G'
self.command = command
self.id = id
self.priority = 5
def toMessage(self):
message = chr(self.length)
message += self.protocol
message += self.command
message += inttouint32(self.id)
message += inttouint32(self.ctr)
return message
def headerString(self):
return "id=%d, ctr=%d"%(self.id, self.ctr)
def __str__(self):
s = "Packet with protocol=" + self.protocol
s += ", command=" + self.command
s += ", "+ self.headerString()
return s
class Button(Packet):
def __init__(self, id, button=None):
if button!= None:
Packet.__init__(self, 'B', id)
else:
message = id
Packet.__init__(self, message)
button = ord(message[11])
self.button = button
def toMessage(self):
base = Packet.toMessage(self)
return base + chr(self.button) + '\x00'*18
def __str__(self):
s = "Button packet with " + self.headerString()
s += ", button=%d"%self.button
return s
class Announce(Packet):
def __init__(self, gameMac, gameChannel, gameId, gameFlags, gameTitle, interval=5, jitter=10):
#always a broadcast
Packet.__init__(self, 'A', 0)
self.gameMac = gameMac
self.gameChannel = gameChannel
self.gameId = gameId
self.gameFlags = gameFlags
self.gameTitle = gameTitle[0:8]
self.interval = interval
self.jitter = jitter
self.priority = 3
def toMessage(self):
message = Packet.toMessage(self)
message += ''.join([chr(x) for x in self.gameMac])
message += chr(self.gameChannel)
message += inttouint16(self.gameId)
message += chr(self.gameFlags)
message += chr(self.interval)
message += chr(self.jitter)
message += self.gameTitle
if len(self.gameTitle) < 8:
message += '\x00'*(8-len(self.gameTitle))
return message
def __str__(self):
s = "Announce packet with " + self.headerString()
s += ", gameMac="+str(self.gameMac)
s += ", gameChannel=%d"%self.gameChannel
s += ", gameId=%d"%self.gameId
s += ", gameFlags=%d"%self.gameFlags
s += ", interval=%d"%self.interval
s += ", jitter=%d"%self.jitter
s += ", gameTitle="+self.gameTitle
return s
class Join(Packet):
def __init__(self, id, gameId=None):
if gameId != None:
Packet.__init__(self, 'J', id)
else:
message = id
Packet.__init__(self, message)
gameId = uint32toint(message[11:15])
self.gameId = gameId
def toMessage(self):
message = Packet.toMessage(self)
message += inttouint32(self.gameId)
message += '\x00'*15
return message
def __str__(self):
s = "Join packet with " + self.headerString()
s += ", gameId=%d"%self.gameId
return s
class Ack(Packet):
def __init__(self, id, ctr, flags=None):
if ctr != None and flags != None:
Packet.__init__(self, 'a', id)
self.ctr = ctr
else:
message = id
Packet.__init__(self, message)
flags = ord(message[11])
self.flags = flags
self.priority = 3
def toMessage(self):
message = Packet.toMessage(self)
message += chr(self.flags)
message += '\x00'*18
return message
def __str__(self):
s = "Ack packet with " + self.headerString()
s += ", flags=%d"%self.flags
return s
class Nickrequest(Packet):
def __init__(self, id):
Packet.__init__(self, 'N', id)
def __str__(self):
s = "Nickrequest packet with " + self.headerString()
return s
def toMessage(self):
message = Packet.toMessage(self)
message += '\x00'*19
return message
class Nick(Packet):
def __init__(self, id, flags=None, nick=None):
if flags != None and nick != None:
Packet.__init__(self, 'n', id)
else:
message = id
Packet.__init__(self, message)
flags = ord(message[11])
nick = message[12:30].rstrip(' \t\r\n\0')
self.flags = flags
self.nick = nick
def toMessage(self):
message = Packet.toMessage(self)
message += chr(self.flags)
message += self.nick
if len(self.nick) < 18:
message += '\x00'*(18-len(self.nick))
return message
def __str__(self):
s = "Nick packet with " + self.headerString()
s += ", flags=%d"%self.flags
s += ", nick="+self.nick
return s
class Text(Packet):
def __init__(self, id, x, y, flags, text):
Packet.__init__(self, 'T', id)
self.x = x
self.y = y
self. flags = flags
self.text = text[0:16]
def toMessage(self):
message = Packet.toMessage(self)
message += chr(self.x)
message += chr(self.y)
message += chr(self.flags)
message += self.text
if len(self.text) < 16:
message += '\x00'*(16-len(self.text))
return message
def __str__(self):
s = "Text packet with " + self.headerString()
s += ", x=%d"%self.x
s += ", y=%d"%self.y
s += ", flags=%d"%self.flags
s += ", text="+self.text
return s
def fromMessage(message):
if len(message) >= 30 and ord(message[0]) == 32 and message[1] == 'G':
if message[2] == 'B':
return Button(message)
if message[2] == 'n':
return Nick(message)
if message[2] == 'J':
return Join(message)
if message[2] == 'a':
return Ack(message)
return None