You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

242 lines
6.6 KiB

"""Classes to (de)serialize various struct messages"""
import struct
import six
from steam.enums import EResult, EUniverse
from steam.enums.emsg import EMsg
_emsg_map = {}
def get_struct(emsg):
return _emsg_map.get(emsg, None)
class StructMessageMeta(type):
"""Automatically maps subclasses of :class:`StructMessage` to ``EMsg``"""
def __new__(metacls, name, bases, classdict):
cls = type.__new__(metacls, name, bases, classdict)
if name != 'StructMessage':
try:
_emsg_map[EMsg[name]] = cls
except KeyError:
pass
return cls
@six.add_metaclass(StructMessageMeta)
class StructMessage:
def __init__(self, data=None):
if data: self.load(data)
def serialize(self):
return b''
def load(self, data):
pass
class ChannelEncryptRequest(StructMessage):
protocolVersion = 1
universe = EUniverse.Invalid
challenge = b''
def serialize(self):
return struct.pack("<II", self.protocolVersion, self.universe) + self.challenge
def load(self, data):
(self.protocolVersion,
universe,
) = struct.unpack_from("<II", data)
self.universe = EUniverse(universe)
if len(data) > 8:
self.challenge = data[8:]
def __str__(self):
return '\n'.join(["protocolVersion: %s" % self.protocolVersion,
"universe: %s" % repr(self.universe),
"challenge: %s" % repr(self.challenge),
])
class ChannelEncryptResponse(StructMessage):
protocolVersion = 1
keySize = 128
key = ''
crc = 0
def __init__(self, data=None):
if data:
self.load(data)
def serialize(self):
return struct.pack("<II128sII",
self.protocolVersion,
self.keySize,
self.key,
self.crc,
0
)
def load(self, data):
(self.protocolVersion,
self.keySize,
self.key,
self.crc,
_,
) = struct.unpack_from("<II128sII", data)
def __str__(self):
return '\n'.join(["protocolVersion: %s" % self.protocolVersion,
"keySize: %s" % self.keySize,
"key: %s" % repr(self.key),
"crc: %s" % self.crc,
])
class ChannelEncryptResult(StructMessage):
eresult = EResult.Invalid
def __init__(self, data=None):
if data:
self.load(data)
def serialize(self):
return struct.pack("<I", self.eresult)
def load(self, data):
(result,) = struct.unpack_from("<I", data)
self.eresult = EResult(result)
def __str__(self):
return "result: %s" % repr(self.eresult)
class ClientLogOnResponse(StructMessage):
eresult = EResult.Invalid
def __init__(self, data=None):
if data:
self.load(data)
def serialize(self):
return struct.pack("<I", self.eresult)
def load(self, data):
(result,) = struct.unpack_from("<I", data)
self.eresult = EResult(result)
def __str__(self):
return "eresult: %s" % repr(self.eresult)
class ClientVACBanStatus(StructMessage):
numBans = 0
def __init__(self, data=None):
if data: self.load(data)
def serialize(self):
return struct.pack("<L", self.steamIdChat)
def load(self, data):
self.steamIdChat, = struct.unpack_from("<L", data)
def __str__(self):
return '\n'.join(["numBans: %d" % self.numBans,
])
class ClientChatMsg(StructMessage):
steamIdChatter = 0
steamIdChatRoom = 0
ChatMsgType = 0
text = ""
def __init__(self, data=None):
if data:
self.load(data)
def serialize(self):
rbytes = struct.pack("<QQI",
self.steamIdChatter,
self.steamIdChatRoom,
self.ChatMsgType,
)
# utf-8 encode only when unicode in py2 and str in py3
rbytes += (self.text.encode('utf-8')
if (not isinstance(self.text, str) and bytes is str)
or isinstance(self.text, str)
else self.text
) + b'\x00'
return rbytes
def load(self, data):
(self.steamIdChatter,
self.steamIdChatRoom,
self.ChatMsgType,
) = struct.unpack_from("<QQI", data)
self.text = data[struct.calcsize("<QQI"):-1].decode('utf-8')
def __str__(self):
return '\n'.join(["steamIdChatter: %d" % self.steamIdChatter,
"steamIdChatRoom: %d" % self.steamIdChatRoom,
"ChatMsgType: %d" % self.ChatMsgType,
"text: %s" % repr(self.text),
])
class ClientJoinChat(StructMessage):
steamIdChat = 0
isVoiceSpeaker = False
def __init__(self, data=None):
if data: self.load(data)
def serialize(self):
return struct.pack("<Q?",
self.steamIdChat,
self.isVoiceSpeaker
)
def load(self, data):
(self.steamIdChat,
self.isVoiceSpeaker
) = struct.unpack_from("<Q?", data)
def __str__(self):
return '\n'.join(["steamIdChat: %d" % self.steamIdChat,
"isVoiceSpeaker: %r" % self.isVoiceSpeaker,
])
class ClientChatMemberInfo(StructMessage):
steamIdChat = 0
type = 0
steamIdUserActedOn = 0
chatAction = 0
steamIdUserActedBy = 0
def __init__(self, data=None):
if data:
self.load(data)
def serialize(self):
return struct.pack("<QIQIQ",
self.steamIdChat,
self.type,
self.steamIdUserActedOn,
self.chatAction,
self.steamIdUserActedBy
)
def load(self, data):
(self.steamIdChat,
self.type,
self.steamIdUserActedOn,
self.chatAction,
self.steamIdUserActedBy
) = struct.unpack_from("<QIQIQ", data)
def __str__(self):
return '\n'.join(["steamIdChat: %d" % self.steamIdChat,
"type: %r" % self.type,
"steamIdUserActedOn: %d" % self.steamIdUserActedOn,
"chatAction: %d" % self.chatAction,
"steamIdUserActedBy: %d" % self.steamIdUserActedBy
])