Move tgread_object() outside specific msg processing calls

This commit is contained in:
Lonami Exo 2017-12-20 17:45:40 +01:00
parent 5842d3741b
commit c848ae0ace

View File

@ -220,41 +220,52 @@ class MtProtoSender:
code = reader.read_int(signed=False)
reader.seek(-4)
__log__.debug('Processing server message with ID %s', hex(code))
# These are a bit of special case, not yet generated by the code gen
if code == 0xf35c6d01: # rpc_result, (response of an RPC call)
__log__.debug('Processing Remote Procedure Call result')
return self._handle_rpc_result(msg_id, sequence, reader)
if code == Pong.CONSTRUCTOR_ID:
return self._handle_pong(msg_id, sequence, reader)
if code == MessageContainer.CONSTRUCTOR_ID:
__log__.debug('Processing container result')
return self._handle_container(msg_id, sequence, reader, state)
if code == GzipPacked.CONSTRUCTOR_ID:
__log__.debug('Processing gzipped result')
return self._handle_gzip_packed(msg_id, sequence, reader, state)
if code == BadServerSalt.CONSTRUCTOR_ID:
return self._handle_bad_server_salt(msg_id, sequence, reader)
if code not in tlobjects:
__log__.warning(
'Unknown message with ID %d, data left in the buffer %s',
hex(code), repr(reader.get_bytes()[reader.tell_position():])
)
return False
if code == BadMsgNotification.CONSTRUCTOR_ID:
return self._handle_bad_msg_notification(msg_id, sequence, reader)
obj = reader.tgread_object()
__log__.debug('Processing %s result', type(obj).__name__)
if code == MsgDetailedInfo.CONSTRUCTOR_ID:
return self._handle_msg_detailed_info(msg_id, sequence, reader)
if isinstance(obj, Pong):
return self._handle_pong(msg_id, sequence, obj)
if code == MsgNewDetailedInfo.CONSTRUCTOR_ID:
return self._handle_msg_new_detailed_info(msg_id, sequence, reader)
if isinstance(obj, BadServerSalt):
return self._handle_bad_server_salt(msg_id, sequence, obj)
if code == NewSessionCreated.CONSTRUCTOR_ID:
return self._handle_new_session_created(msg_id, sequence, reader)
if isinstance(obj, BadMsgNotification):
return self._handle_bad_msg_notification(msg_id, sequence, obj)
if code == MsgsAck.CONSTRUCTOR_ID: # may handle the request we wanted
ack = reader.tgread_object()
assert isinstance(ack, MsgsAck)
if isinstance(obj, MsgDetailedInfo):
return self._handle_msg_detailed_info(msg_id, sequence, obj)
if isinstance(obj, MsgNewDetailedInfo):
return self._handle_msg_new_detailed_info(msg_id, sequence, obj)
if isinstance(obj, NewSessionCreated):
return self._handle_new_session_created(msg_id, sequence, obj)
if isinstance(obj, MsgsAck): # may handle the request we wanted
# Ignore every ack request *unless* when logging out, when it's
# when it seems to only make sense. We also need to set a non-None
# result since Telegram doesn't send the response for these.
for msg_id in ack.msg_ids:
for msg_id in obj.msg_ids:
r = self._pop_request_of_type(msg_id, LogOutRequest)
if r:
r.result = True # Telegram won't send this value
@ -262,20 +273,12 @@ class MtProtoSender:
return True
# If the code is not parsed manually then it should be a TLObject.
if code in tlobjects:
result = reader.tgread_object()
self.session.process_entities(result)
if state:
state.process(result)
# If the object isn't any of the above, then it should be an Update.
self.session.process_entities(obj)
if state:
state.process(obj)
return True
__log__.warning(
'Unknown message with ID %d, data left in the buffer %s',
hex(code), repr(reader.get_bytes()[reader.tell_position():])
)
return False
return True
# endregion
@ -341,7 +344,7 @@ class MtProtoSender:
if requests:
return self.send(*requests)
def _handle_pong(self, msg_id, sequence, reader):
def _handle_pong(self, msg_id, sequence, pong):
"""
Handles a Pong response.
@ -350,9 +353,6 @@ class MtProtoSender:
:param reader: the reader containing the Pong.
:return: true, as it always succeeds.
"""
pong = reader.tgread_object()
assert isinstance(pong, Pong)
request = self._pop_request(pong.msg_id)
if request:
request.result = pong
@ -384,7 +384,7 @@ class MtProtoSender:
return True
def _handle_bad_server_salt(self, msg_id, sequence, reader):
def _handle_bad_server_salt(self, msg_id, sequence, bad_salt):
"""
Handles a BadServerSalt response.
@ -393,9 +393,6 @@ class MtProtoSender:
:param reader: the reader containing the BadServerSalt.
:return: true, as it always succeeds.
"""
bad_salt = reader.tgread_object()
assert isinstance(bad_salt, BadServerSalt)
self.session.salt = bad_salt.new_server_salt
self.session.save()
@ -404,7 +401,7 @@ class MtProtoSender:
self._resend_request(bad_salt.bad_msg_id)
return True
def _handle_bad_msg_notification(self, msg_id, sequence, reader):
def _handle_bad_msg_notification(self, msg_id, sequence, bad_msg):
"""
Handles a BadMessageError response.
@ -413,9 +410,6 @@ class MtProtoSender:
:param reader: the reader containing the BadMessageError.
:return: true, as it always succeeds.
"""
bad_msg = reader.tgread_object()
assert isinstance(bad_msg, BadMsgNotification)
error = BadMessageError(bad_msg.error_code)
__log__.warning('Read bad msg notification %s: %s', bad_msg, error)
if bad_msg.error_code in (16, 17):
@ -441,7 +435,7 @@ class MtProtoSender:
else:
raise error
def _handle_msg_detailed_info(self, msg_id, sequence, reader):
def _handle_msg_detailed_info(self, msg_id, sequence, msg_new):
"""
Handles a MsgDetailedInfo response.
@ -450,15 +444,12 @@ class MtProtoSender:
:param reader: the reader containing the MsgDetailedInfo.
:return: true, as it always succeeds.
"""
msg_new = reader.tgread_object()
assert isinstance(msg_new, MsgDetailedInfo)
# TODO For now, simply ack msg_new.answer_msg_id
# Relevant tdesktop source code: https://goo.gl/VvpCC6
self._send_acknowledge(msg_new.answer_msg_id)
return True
def _handle_msg_new_detailed_info(self, msg_id, sequence, reader):
def _handle_msg_new_detailed_info(self, msg_id, sequence, msg_new):
"""
Handles a MsgNewDetailedInfo response.
@ -467,15 +458,12 @@ class MtProtoSender:
:param reader: the reader containing the MsgNewDetailedInfo.
:return: true, as it always succeeds.
"""
msg_new = reader.tgread_object()
assert isinstance(msg_new, MsgNewDetailedInfo)
# TODO For now, simply ack msg_new.answer_msg_id
# Relevant tdesktop source code: https://goo.gl/G7DPsR
self._send_acknowledge(msg_new.answer_msg_id)
return True
def _handle_new_session_created(self, msg_id, sequence, reader):
def _handle_new_session_created(self, msg_id, sequence, new_session):
"""
Handles a NewSessionCreated response.
@ -484,8 +472,6 @@ class MtProtoSender:
:param reader: the reader containing the NewSessionCreated.
:return: true, as it always succeeds.
"""
new_session = reader.tgread_object()
assert isinstance(new_session, NewSessionCreated)
self.session.salt = new_session.server_salt
# TODO https://goo.gl/LMyN7A
return True