from importlib import import_module import re 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 cmsg_lookup_predefined = { EMsg.Multi: steammessages_base_pb2.CMsgMulti, EMsg.ClientToGC: steammessages_clientserver_2_pb2.CMsgGCClient, EMsg.ClientFromGC: steammessages_clientserver_2_pb2.CMsgGCClient, EMsg.ServiceMethod: steammessages_clientserver_2_pb2.CMsgClientServiceMethod, EMsg.ServiceMethodResponse: steammessages_clientserver_2_pb2.CMsgClientServiceMethodResponse, EMsg.ClientGetNumberOfCurrentPlayersDP: steammessages_clientserver_2_pb2.CMsgDPGetNumberOfCurrentPlayers, EMsg.ClientGetNumberOfCurrentPlayersDPResponse: steammessages_clientserver_2_pb2.CMsgDPGetNumberOfCurrentPlayersResponse, } def get_cmsg(emsg): """Get protobuf for a given EMsg :param emsg: EMsg :type emsg: :class:`steam.enums.emsg.EMsg`, :class:`int` :return: protobuf message """ global cmsg_lookup, cmsg_lookup2 if not isinstance(emsg, EMsg): emsg = EMsg(emsg) if emsg in cmsg_lookup_predefined: return cmsg_lookup_predefined[emsg] else: enum_name = emsg.name.lower() if enum_name.startswith("econ"): # special case for 'EconTrading_' enum_name = enum_name[4:] cmsg_name = "cmsg" + enum_name 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): proto = True body = "!!! NO BODY !!!" def __init__(self, msg, data=None): self._header = MsgHdrProtoBuf(data) self.msg = self._header.msg = msg self.header = self._header.proto if msg == EMsg.ServiceMethod: proto = get_um(self.header.target_job_name) if proto: self.body = proto() else: self.body = '!! Can\'t resolve ServiceMethod: %s !!' % repr(self.header.target_job_name) else: proto = get_cmsg(msg) if proto: self.body = proto() if data: 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: protocolVersion = 1 universe = EUniverse.Invalid challenge = b'' def __init__(self, data=None): if data: self.load(data) def serialize(self): return struct.pack(" 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: protocolVersion = 1 keySize = 128 key = '' crc = 0 def __init__(self, data=None): if data: self.load(data) def serialize(self): return struct.pack("