import struct import fnmatch from steam.enums import EResult, EUniverse from steam.enums.emsg import EMsg from steam.protobufs import steammessages_base_pb2 from steam.protobufs import steammessages_clientserver_pb2 from steam.protobufs import steammessages_clientserver_2_pb2 from steam.protobufs import gc_pb2 from steam.util import set_proto_bit, clear_proto_bit class MsgHdr: _size = struct.calcsize("" % repr(self.msg) def __str__(self): rows = ["Msg"] header = str(self.header) if header: rows.append("-------------- header --") rows.append(header) body = str(self.body) if body: rows.append("---------------- body --") rows.append(body) if len(rows) == 1: rows[0] += " (empty)" return '\n'.join(rows) cmsg_lookup = None cmsg_lookup2 = None def get_cmsg(emsg): global cmsg_lookup, cmsg_lookup2 if emsg == EMsg.Multi: return steammessages_base_pb2.CMsgMulti elif emsg in (EMsg.ClientToGC, EMsg.ClientFromGC): return steammessages_clientserver_2_pb2.CMsgGCClient else: cmsg_name = "cmsg" + str(emsg).split('.', 1)[1].lower() if not cmsg_lookup: cmsg_list = steammessages_clientserver_pb2.__dict__ cmsg_list = fnmatch.filter(cmsg_list, 'CMsg*') cmsg_lookup = dict(zip(map(lambda x: x.lower(), cmsg_list), cmsg_list)) name = cmsg_lookup.get(cmsg_name, None) if name: return getattr(steammessages_clientserver_pb2, name) if not cmsg_lookup2: cmsg_list = steammessages_clientserver_2_pb2.__dict__ cmsg_list = fnmatch.filter(cmsg_list, 'CMsg*') cmsg_lookup2 = dict(zip(map(lambda x: x.lower(), cmsg_list), cmsg_list)) name = cmsg_lookup2.get(cmsg_name, None) if name: return getattr(steammessages_clientserver_2_pb2, name) return None class MsgProto(object): def __init__(self, msg, data=None): self._header = MsgHdrProtoBuf(data) self._header.msg = msg self.msg = msg self.header = self._header.proto proto = get_cmsg(msg) if msg == EMsg.ServiceMethod: self.body = "!!NOT IMPLEMENTED!!" else: self.body = proto() if data and proto is not None: data = data[self._header._fullsize:] self.body.ParseFromString(data) def serialize(self): return self._header.serialize() + self.body.SerializeToString() @property def steamID(self): return self.header.steamid @steamID.setter def steamID(self, value): self.header.steamid = value @property def sessionID(self): return self.header.client_sessionid @sessionID.setter def sessionID(self, value): self.header.client_sessionid = value def __repr__(self): return "" % repr(self.msg) def __str__(self): rows = ["MsgProto"] header = str(self.header).rstrip() if header: rows.append("-------------- header --") rows.append(header) body = str(self.body).rstrip() if body: rows.append("---------------- body --") rows.append(body) if len(rows) == 1: rows[0] += " (empty)" return '\n'.join(rows) class ChannelEncryptRequest: def __init__(self, data=None): if data: self.load(data) else: self.protocolVersion = 1 self.universe = EUniverse.Invalid self.challenge = '' def serialize(self): return struct.pack("= 16: 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: def __init__(self, data=None): if data: self.load(data) else: self.protocolVersion = 1 self.keySize = 128 self.key = '' self.crc = 0 def serialize(self): return struct.pack("