pythonhacktoberfeststeamauthenticationauthenticatorsteam-authenticatorsteam-clientsteam-guard-codessteam-websteamworksvalvewebapi
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.
198 lines
5.6 KiB
198 lines
5.6 KiB
import fnmatch
|
|
from steam.core.msg_unified import get_um
|
|
from steam.core.msg_structs import get_struct
|
|
from steam.core.msg_headers import MsgHdr, ExtendedMsgHdr, MsgHdrProtoBuf, GCMsgHdr, GCMsgHdrProto
|
|
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
|
|
|
|
|
|
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 Msg(object):
|
|
proto = False
|
|
body = '!!! NO BODY !!!'
|
|
|
|
def __init__(self, msg, data=None, extended=False):
|
|
self.extended = extended
|
|
self.header = ExtendedMsgHdr(data) if extended else MsgHdr(data)
|
|
self.header.msg = msg
|
|
self.msg = msg
|
|
|
|
if data:
|
|
data = data[self.header._size:]
|
|
|
|
deserializer = get_struct(msg)
|
|
|
|
if deserializer:
|
|
self.body = deserializer(data)
|
|
|
|
def serialize(self):
|
|
return self.header.serialize() + self.body.serialize()
|
|
|
|
@property
|
|
def steamID(self):
|
|
return (self.header.steamID
|
|
if isinstance(self.header, ExtendedMsgHdr)
|
|
else None
|
|
)
|
|
|
|
@steamID.setter
|
|
def steamID(self, value):
|
|
if isinstance(self.header, ExtendedMsgHdr):
|
|
self.header.steamID = value
|
|
|
|
@property
|
|
def sessionID(self):
|
|
return (self.header.sessionID
|
|
if isinstance(self.header, ExtendedMsgHdr)
|
|
else None
|
|
)
|
|
|
|
@sessionID.setter
|
|
def sessionID(self, value):
|
|
if isinstance(self.header, ExtendedMsgHdr):
|
|
self.header.sessionID = value
|
|
|
|
def __repr__(self):
|
|
return "<Msg %s>" % 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)
|
|
|
|
|
|
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 "<MsgProto %s>" % 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)
|
|
|
|
|
|
|