Browse Source

parse message body only when there are listeners

pull/202/head
Rossen Georgiev 6 years ago
parent
commit
e356933aa0
  1. 9
      steam/client/__init__.py
  2. 13
      steam/core/cm.py
  3. 69
      steam/core/msg/__init__.py

9
steam/client/__init__.py

@ -109,10 +109,15 @@ class SteamClient(CMClient, BuiltinBase):
jobid = msg.header.targetJobID
if jobid not in (-1, 18446744073709551615):
self.emit("job_%d" % jobid, msg)
jobid = "job_%d" % jobid
if msg.body is None and self.count_listeners(jobid):
msg.parse()
self.emit(jobid, msg)
# emit UMs
if emsg in (EMsg.ServiceMethodResponse, EMsg.ServiceMethodSendToClient):
if emsg in (EMsg.ServiceMethod, EMsg.ServiceMethodResponse, EMsg.ServiceMethodSendToClient):
if msg.body is None and self.count_listeners(msg.header.target_job_name):
msg.parse()
self.emit(msg.header.target_job_name, msg)
def _bootstrap_cm_list_from_file(self):

13
steam/core/cm.py

@ -247,6 +247,10 @@ class CMClient(EventEmitter):
emsg = EMsg(clear_proto_bit(emsg_id))
if not self.connected and emsg != EMsg.ClientLogOnResponse:
self._LOG.debug("Dropped unexpected message: %s (is_proto: %s)",
repr(emsg),
is_proto(emsg_id),
)
return
if emsg in (EMsg.ChannelEncryptRequest,
@ -254,13 +258,13 @@ class CMClient(EventEmitter):
EMsg.ChannelEncryptResult,
):
msg = Msg(emsg, message)
msg = Msg(emsg, message, parse=False)
else:
try:
if is_proto(emsg_id):
msg = MsgProto(emsg, message)
msg = MsgProto(emsg, message, parse=False)
else:
msg = Msg(emsg, message, extended=True)
msg = Msg(emsg, message, extended=True, parse=False)
except Exception as e:
self._LOG.fatal("Failed to deserialize message: %s (is_proto: %s)",
repr(emsg),
@ -269,6 +273,9 @@ class CMClient(EventEmitter):
self._LOG.exception(e)
return
if self.count_listeners(emsg) or self.verbose_debug:
msg.parse()
if self.verbose_debug:
self._LOG.debug("Incoming: %s\n%s" % (repr(msg), str(msg)))
else:

69
steam/core/msg/__init__.py

@ -62,23 +62,30 @@ def get_cmsg(emsg):
class Msg(object):
proto = False
body = '!!! Unknown message body !!!' #: message instance
body = None #: message instance
payload = None #: Will contain body payload, if we fail to find correct message class
def __init__(self, msg, data=None, extended=False):
def __init__(self, msg, data=None, extended=False, parse=True):
self.extended = extended
self.header = ExtendedMsgHdr(data) if extended else MsgHdr(data)
self.msg = msg
if data:
data = data[self.header._size:]
self.payload = data[self.header._size:]
deserializer = get_struct(msg)
if parse:
self.parse()
if deserializer:
self.body = deserializer(data)
else:
self.payload = data
def parse(self):
"""Parses :attr:`payload` into :attr:`body` instance"""
if self.body is None:
deserializer = get_struct(self.msg)
if deserializer:
self.body = deserializer(self.payload)
self.payload = None
else:
self.body = '!!! Failed to resolve message !!!'
@property
def msg(self):
@ -116,7 +123,10 @@ class Msg(object):
self.header.sessionID = value
def __repr__(self):
return "<Msg %s>" % repr(self.msg)
return "<Msg %s%s>" % (
repr(self.msg),
' (No Body)' if isinstance(self.body, str) else '',
)
def __str__(self):
rows = ["Msg"]
@ -138,32 +148,36 @@ class Msg(object):
class MsgProto(object):
proto = True
body = '!!! Unknown message body !!!' #: protobuf message instance
body = None #: protobuf message instance
payload = None #: Will contain body payload, if we fail to find correct proto message
def __init__(self, msg, data=None):
def __init__(self, msg, data=None, parse=True):
self._header = MsgHdrProtoBuf(data)
self.header = self._header.proto
self.msg = msg
if msg in (EMsg.ServiceMethodResponse, EMsg.ServiceMethodSendToClient):
proto = get_um(self.header.target_job_name, response=True)
if proto:
self.body = proto()
else:
self.body = '!! Failed to resolve UM: %s !!' % repr(self.header.target_job_name)
else:
proto = get_cmsg(msg)
if data:
self.payload = data[self._header._fullsize:]
if proto:
self.body = proto()
if parse:
self.parse()
def parse(self):
"""Parses :attr:`payload` into :attr:`body` instance"""
if self.body is None:
if self.msg in (EMsg.ServiceMethod, EMsg.ServiceMethodResponse, EMsg.ServiceMethodSendToClient):
is_resp = False if self.msg == EMsg.ServiceMethod else True
proto = get_um(self.header.target_job_name, response=is_resp)
else:
proto = get_cmsg(self.msg)
if data:
data = data[self._header._fullsize:]
if proto:
self.body.ParseFromString(data)
self.body = proto()
if self.payload:
self.body.ParseFromString(self.payload)
self.payload = None
else:
self.payload = data
self.body = '!!! Failed to resolve message !!!'
@property
def msg(self):
@ -193,7 +207,10 @@ class MsgProto(object):
self.header.client_sessionid = value
def __repr__(self):
return "<MsgProto %s>" % repr(self.msg)
return "<MsgProto %s%s>" % (
repr(self.msg),
' (No Body)' if isinstance(self.body, str) else '',
)
def __str__(self):
rows = ["MsgProto %s" % repr(self.msg)]

Loading…
Cancel
Save